Calculate next available IP

J

Jim

Is there a module, or a readily available algorithm, for calculating
the next available IP Address?

Let's say I have an array
('10.1.1.1','10.1.1.2','10.1.1.3','10.1.1.10'). I want to find that
the next available address is 10.1.1.4. Thanks.

J
 
J

J. Gleixner

Jim said:
Is there a module, or a readily available algorithm, for calculating
the next available IP Address?

Let's say I have an array
('10.1.1.1','10.1.1.2','10.1.1.3','10.1.1.10'). I want to find that
the next available address is 10.1.1.4. Thanks.

J

Take a look at Net::Netmask. Using a few of the methods provided,
should help.
 
S

Steffen Müller

Jim said:
Is there a module, or a readily available algorithm, for calculating
the next available IP Address?

Let's say I have an array
('10.1.1.1','10.1.1.2','10.1.1.3','10.1.1.10'). I want to find that
the next available address is 10.1.1.4. Thanks.

Hi Jim,

there may be such a module. I suggest you search CPAN for 'IP'.
Regardless, this is simple enough a task that a simple-minded approach
should do fine: (Sue me.)


use strict;
use warnings;

sub increment_ip ($) {
my $ip = shift;
my $i = 3;
while ($i >= 0) {
$ip->[$i]++;
if ($ip->[$i] > 255) {
$ip->[$i] = 0;
$i--;
}
else {
last;
}
}
return $ip;
}

sub decrement_ip ($) {
my $ip = shift;
my $i = 3;
while ($i >= 0) {
$ip->[$i]--;
if ($ip->[$i] < 0) {
$ip->[$i] = 255;
$i--;
}
else {
last;
}
}
return $ip;
}

sub compare_ips ($$) {
my $ip1 = shift;
my $ip2 = shift;
my $i = 0;
while ($i < 4) {
return -1 if $ip1->[$i] < $ip2->[$i];
return 1 if $ip1->[$i] > $ip2->[$i];
$i++;
}
return 0;
}

sub ip_iterator ($;\@) {
my $start = shift;
my $ary = shift || [];
$start = [map {0+$_} split /\./, $start];
@$ary = sort {
$a->[0] <=> $b->[0] ||
$a->[1] <=> $b->[1] ||
$a->[2] <=> $b->[2] ||
$a->[3] <=> $b->[3]
} map {
[map 0+$_, split /\./, $_]
} @$ary;

{
my $i = 0;
while (compare_ips($start, $ary->[$i]) == -1) {
shift @$ary;
$i++;
}
}

$start = decrement_ip $start;
return sub {
$start = increment_ip $start;
while (@$ary and not compare_ips $ary->[0], $start) {
$start = increment_ip $start;
shift @$ary;
}
return join '.', @$start;
};
}

# Here comes the code you need to care about:

my @ary = qw(10.1.1.1 10.1.1.2 10.1.1.3 10.1.1.10);
my $start = '10.1.1.1';

my $iter = ip_iterator $start, @ary;

foreach (1..20) {
print $iter->(), "\n";
}


The implementation should be fairly efficient once the iterator has been
generated as a closure.

Now, if I were to make this a module that lets you deal with those IP
array-refs themselves, I'd make them objects and possibly overload the
+, -, and <=> operators to look nicer than "increment_ip" and friends.

The code hasn't been thoroughly tested. (What about start values of
'0.0.0.0' or '255.255.255.255'? What about invalid input?)

If you want me to read any answers you post to comp.lang.perl.misc,
you'll need to send me a cc. I read this on comp.lang.perl.modules.

Steffen
 
B

Benjamin Goldberg

Jim said:
Is there a module, or a readily available algorithm, for calculating
the next available IP Address?

Let's say I have an array
('10.1.1.1','10.1.1.2','10.1.1.3','10.1.1.10'). I want to find that
the next available address is 10.1.1.4. Thanks.

use Socket qw(inet_aton inet_ntoa);

my @readable = qw(10.1.1.1 10.1.1.2 10.1.1.3 10.1.1.10);

my @addrs = sort map inet_aton($_), @readable;
my ($mask) = @addrs or die;
chop $mask;
for my $i ( 1 .. 255 ) {
if( !@addrs or $addrs[0] ne $mask . chr($i) ) {
print inet_ntoa( $mask . chr($i) ), "\n";
exit;
}
shift @addrs;
}
 
J

Jim

(e-mail address removed) (Jim) wrote:

: Is there a module, or a readily available algorithm, for calculating
: the next available IP Address?
:
: Let's say I have an array
: ('10.1.1.1','10.1.1.2','10.1.1.3','10.1.1.10'). I want to find that
: the next available address is 10.1.1.4. Thanks.

#!perl
use warnings;
use strict;
use Socket qw(inet_aton inet_ntoa);
use List::Util qw(min);

my @used = ('10.1.1.1', '10.1.1.2', '10.1.1.3', '10.1.1.10');
my %seen = map { unpack('N', inet_aton($_)), 1 } @used;
my $check = min( keys %seen );
$check++ while defined $seen{$check};
print inet_ntoa( pack 'N', $check ), " is available\n";


Thanks.. Where can I get the List-Util package? I found List-Utils
but it doesn't have "min" so don't believe it to be the same package.
Thanks!

Jim
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,781
Messages
2,569,615
Members
45,302
Latest member
endevsols

Latest Threads

Top