Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Next subnet

0 views
Skip to first unread message

shawn wilson

unread,
May 24, 2013, 3:18:35 PM5/24/13
to begi...@perl.org
How do I find the next subnet? This should print 192.168.1.0 the
second time - it errors:
#!/usr/bin/env perl

use strict;
use warnings;

use Net::IP;

my $ip = Net::IP->new('192.168.0.0/24');

print "Start ip [" . $ip->ip . "]\n";
print "start mask [" . $ip->prefixlen . "]\n";

$ip->set($ip->last_ip);
$ip++;
$ip->set($ip->ip . "/" . $ip->prefixlen);

print "Start ip [" . $ip->ip . "]\n";
print "start mask [" . $ip->prefixlen . "]\n";


## ERROR
% ./t2.pl
Start ip [192.168.0.0]
start mask [24]
Can't call method "ip" on an undefined value at ./t2.pl line 15.

Dr.Ruud

unread,
May 25, 2013, 10:00:15 AM5/25/13
to begi...@perl.org
On 24/05/2013 21:18, shawn wilson wrote:

> How do I find the next subnet? This should print 192.168.1.0 the
> second time - it errors:
> #!/usr/bin/env perl
>
> use strict;
> use warnings;
>
> use Net::IP;
>
> my $ip = Net::IP->new('192.168.0.0/24');
>
> print "Start ip [" . $ip->ip . "]\n";
> print "start mask [" . $ip->prefixlen . "]\n";
>
> $ip->set($ip->last_ip);
> $ip++;
> $ip->set($ip->ip . "/" . $ip->prefixlen);
>
> print "Start ip [" . $ip->ip . "]\n";
> print "start mask [" . $ip->prefixlen . "]\n";

Or without Net::IP:

perl -Mstrict -wle'
my $subnet = $ARGV[0];

my ($ip, $bits) = $subnet =~ m{(\S+)/(\S+)}; # parse

my $ip_int = unpack "N", pack "CCCC", split /\./, $ip;
my $step = 1 << (32 - $bits);

#$ip_int &= (0xFFFFFFFF ^ ($step - 1)); # normalize
$ip_int += $step; # increment

my $next_ip = sprintf "%vd", pack "N", $ip_int;
print "$next_ip/$bits";
' 192.168.0.42/24

192.168.1.42/24

(you can activate the normalization if wanted)

--
Ruud

Michael Rasmussen

unread,
May 26, 2013, 8:06:39 AM5/26/13
to shawn wilson, begi...@perl.org
On Fri, May 24, 2013 at 03:18:35PM -0400, shawn wilson wrote:
> How do I find the next subnet? This should print 192.168.1.0 the
> second time - it errors:

[code deleted]
Why should it? The Net::IP documentation doesn't provide any information about
actions that cross the subnet boundry.

Having said that, it seems it doesn't allow that operation.
And in fact, many of the methods don't work after incrementing, which seems wrong to me:

#!/usr/bin/perl
use strict;
use warnings;
use Net::IP;

my @method_types = qw ( ip short binip intip mask last_ip prefixlen size iptype reverse_ip );

my $ip = Net::IP->new('192.168.0.0/24'); # three lines from your code
print "Start ip [" . $ip->ip . "]\n";
print "start mask [" . $ip->prefixlen . "]\n";

$ip++;
print "After incrementing by 1\n";
show_methods($ip);

$ip->set($ip->last_ip) ;
$ip++ ;
print "\nAfter incrementing past last_ip\n";
show_methods($ip);


sub show_methods {
my ($ip) = @_;

print "now at " . $ip->ip ,$/;

for my $type ( @method_types) {
if( $ip->$type ) {
print "$type : ", $ip->$type(), $/;
}
else {
print "no more $type\n";
}
}
}


__END__

michael@bivy:~/rmme$ ./tpl
Start ip [192.168.0.0]
start mask [24]
After incrementing by 1
now at 192.168.0.1
ip : 192.168.0.1
short : 192
binip : 11000000101010000000000000000001
intip : 3232235521
no more mask
last_ip : 192.168.0.255
no more prefixlen
size : 255
iptype : PRIVATE
no more reverse_ip

After incrementing past last_ip
Can't call method "ip" on an undefined value at ./tpl line 29.
michael@bivy:~/rmme$




--
Michael Rasmussen, Portland Oregon
Be Appropriate && Follow Your Curiosity
Other Adventures: http://www.jamhome.us/ or http://gplus.to/MichaelRpdx
A special random fortune cookie fortune:
Only the mediocre are always at their best.
~ Jean Giraudoux, French Novelist
(rephrased as "Only the mediorcre are at their best all the time."
~ G.M. Ford in "Who the hell is Wanda Fuca?")

shawn wilson

unread,
May 26, 2013, 8:40:56 AM5/26/13
to Michael Rasmussen, begi...@perl.org
Thank y'all, I got to where I want to be:
https://github.com/ag4ve/geocidr

Dr.Ruud

unread,
May 27, 2013, 1:00:30 PM5/27/13
to begi...@perl.org
On 26/05/2013 14:40, shawn wilson wrote:

> Thank y'all, I got to where I want to be:
> https://github.com/ag4ve/geocidr

> ...
> or grep { ! m%[0-9\.\/]+% } @{$opts->{ip}}
> or scalar(@{$opts->{ip}}) < 1

The '+' in the regexp is superfluous as-is.
(your regexp isn't anchored)


You probably meant it more like:

...
or !@{$opts->{ip}}
or grep m{[^0-9./]}, @{$opts->{ip}}

--
Ruud

shawn wilson

unread,
May 27, 2013, 5:55:15 PM5/27/13
to Dr. Ruud, begi...@perl.org

You don't want to grep for anything that isn't a number there. I like the !@arr vs my scalar though. And...

You're right on anchoring - I should. But as I'm lastly matching for an IP (with a possible subnet, it should probably be more like:
m(^[0-9\./]+$)
Or better:
m(^[0-9\.]+(?:/(?:[0-3])?[0-9])?$)
Or more better:
m(^(?:(?:[0-2])?[0-9]{1,2}\.){3}(?:[0-2])?[0-9]{1,2}(?:/(?:[0-3])?[0-9])?$)

I know there are some edge cases like 256 octets and 32 bit subnets but that's my 'good enough' IP matching regex (written from a phone, in bed because I'm too lazy to get up and masochistic enough to do it so I hope I didn't error any).

I'll make this part better and get ip6 in here.

Dr.Ruud

unread,
May 27, 2013, 9:04:00 PM5/27/13
to begi...@perl.org
On 27/05/2013 23:55, shawn wilson wrote:
> On May 27, 2013 1:02 PM, "Dr.Ruud" <rvtol+...@isolution.nl
> <mailto:rvtol%2Bus...@isolution.nl>> wrote:
> > On 26/05/2013 14:40, shawn wilson wrote:

> >> Thank y'all, I got to where I want to be:
> >> https://github.com/ag4ve/geocidr
> >
> > > ...
> > > or grep { ! m%[0-9\.\/]+% } @{$opts->{ip}}
> > > or scalar(@{$opts->{ip}}) < 1
> >
> > The '+' in the regexp is superfluous as-is.
> > (your regexp isn't anchored)
> >
> >
> > You probably meant it more like:
> >
> > ...
> > or !@{$opts->{ip}}
> > or grep m{[^0-9./]}, @{$opts->{ip}}
> >
>
> You don't want to grep for anything that isn't a number there.

Who is this 'You'? You clearly misunderstand m{[^0-9./]}.


> I like the !@arr vs my scalar though. And...
> You're right on anchoring - I should. But as I'm lastly matching for an
> IP (with a possible subnet, it should probably be more like:
> m(^[0-9\./]+$)
> Or better:
> m(^[0-9\.]+(?:/(?:[0-3])?[0-9])?$)
> Or more better:
> m(^(?:(?:[0-2])?[0-9]{1,2}\.){3}(?:[0-2])?[0-9]{1,2}(?:/(?:[0-3])?[0-9])?$)

There are many much clearer ways to do that, And be aware of octalness.


> I know there are some edge cases like 256 octets and 32 bit subnets but
> that's my 'good enough' IP matching regex (written from a phone, in bed
> because I'm too lazy to get up and masochistic enough to do it so I hope
> I didn't error any).
>
> I'll make this part better and get ip6 in here.

Just be properly lazy, and check Regexp::Common, Regexp::IPv6.

--
Ruud

0 new messages