diff --git a/Changes b/Changes index 7194527..6a71437 100644 --- a/Changes +++ b/Changes @@ -1,5 +1,11 @@ Revision history for Perl extension NetAddr::IP +4.041 Tue Mar 8 15:18:16 PST 2011 + Updated Lite.pm v1.26, "sub num" to support usable IP ranges + greater than 2**32 + + Thanks to Jan Ploski jan@plosquare.com for finding this bug + 4.040 Sat Feb 19 10:04:00 PST 2011 correction to use of Util.pm package lexicals diff --git a/IP.pm b/IP.pm index f5d588f..faa955b 100644 --- a/IP.pm +++ b/IP.pm @@ -4,7 +4,7 @@ use strict; #use diagnostics; -use NetAddr::IP::Lite 1.25 qw(Zero Zeros Ones V4mask V4net); +use NetAddr::IP::Lite 1.26 qw(Zero Zeros Ones V4mask V4net); use NetAddr::IP::Util 1.36 qw( sub128 inet_aton @@ -34,7 +34,7 @@ @ISA = qw(Exporter NetAddr::IP::Lite); -$VERSION = do { sprintf " %d.%03d", (q$Revision: 4.40 $ =~ /\d+/g) }; +$VERSION = do { sprintf " %d.%03d", (q$Revision: 4.41 $ =~ /\d+/g) }; =pod @@ -1237,14 +1237,32 @@ =item C<-Enum()> Version 4.00 of NetAddr::IP and version 1.00 of NetAddr::IP::Lite -Returns the number of usable addresses IP addresses within the -subnet, not counting the broadcast or network address. Previous versions -returned th number of IP addresses not counting the broadcast address. +return the number of usable IP addresses within the subnet, +not counting the broadcast or network address. + +Previous versions worked only for ipV4 addresses, returned a +maximum span of 2**32 and returned the number of IP addresses +not counting the broadcast address. + (one greater than the new behavior) To use the old behavior for C<-Enth($index)> and C<-Enum()>: use NetAddr::IP::Lite qw(:old_nth); +WARNING: + +NetAddr::IP will calculate and return a numeric string for network +ranges as large as 2**128. These values are TEXT strings and perl +can treat them as integers for numeric calculations. + +Perl on 32 bit platforms only handles integer numbers up to 2**32 +and on 64 bit platforms to 2**64. + +If you wish to manipulate numeric strings returned by NetAddr::IP +that are larger than 2**32 or 2**64, respectively, you must load +additional modules such as Math::BigInt, bignum or some similar +package to do the integer math. + =item C<-Ere()> Returns a Perl regular expression that will match an IP address within diff --git a/Lite/Changes b/Lite/Changes index 822c390..3273878 100644 --- a/Lite/Changes +++ b/Lite/Changes @@ -1,5 +1,10 @@ Revision history for Perl extension NetAddr::IP::Lite +1.26 Tue Mar 8 15:18:16 PST 2011 + Updated "sub num" to support usable IP ranges greater than 2**32 + + Thanks to Jan Ploski jan@plosquare.com for finding this bug + 1.25 Sat Feb 19 10:04:00 PST 2011 correction to use of Util.pm package lexicals diff --git a/Lite/Lite.pm b/Lite/Lite.pm index 6703400..a0ae628 100644 --- a/Lite/Lite.pm +++ b/Lite/Lite.pm @@ -29,7 +29,7 @@ use vars qw(@ISA @EXPORT_OK $VERSION $Accept_Binary_IP $Old_nth $AUTOLOAD *Zero); -$VERSION = do { my @r = (q$Revision: 1.25 $ =~ /\d+/g); sprintf "%d."."%02d" x $#r, @r }; +$VERSION = do { my @r = (q$Revision: 1.26 $ =~ /\d+/g); sprintf "%d."."%02d" x $#r, @r }; require Exporter; @@ -1210,31 +1210,65 @@ =item C<-Enum()> Version 4.00 of NetAddr::IP and version 1.00 of NetAddr::IP::Lite -Returns the number of usable addresses IP addresses within the -subnet, not counting the broadcast or network address. Previous versions -returned th number of IP addresses not counting the broadcast address. +return the number of usable IP addresses within the subnet, +not counting the broadcast or network address. + +Previous versions worked only for ipV4 addresses, returned a +maximum span of 2**32 and returned the number of IP addresses +not counting the broadcast address. + (one greater than the new behavior) To use the old behavior for C<-Enth($index)> and C<-Enum()>: use NetAddr::IP::Lite qw(:old_nth); +WARNING: + +NetAddr::IP will calculate and return a numeric string for network +ranges as large as 2**128. These values are TEXT strings and perl +can treat them as integers for numeric calculations. + +Perl on 32 bit platforms only handles integer numbers up to 2**32 +and on 64 bit platforms to 2**64. + +If you wish to manipulate numeric strings returned by NetAddr::IP +that are larger than 2**32 or 2**64, respectively, you must load +additional modules such as Math::BigInt, bignum or some similar +package to do the integer math. + =cut sub num ($) { - my @net = unpack('L3N',$_[0]->{mask} ^ Ones); if ($Old_nth) { + my @net = unpack('L3N',$_[0]->{mask} ^ Ones); # number of ip's less broadcast return 0xfffffffe if $net[0] || $net[1] || $net[2]; # 2**32 -1 return $net[3] if $net[3]; } else { # returns 1 for /32 /128, 0 for /31 /127 else n-2 up to 2**32 -# number of usable IP's === number of ip's less broadcast & network addys - return 0xfffffffd if $net[0] || $net[1] || $net[2]; # 2**32 -2 - return 1 unless $net[3]; - $net[3]--; + (undef, my $net) = addconst($_[0]->{mask},1); + return 1 unless hasbits($net); # ipV4/32 or ipV6/128 + $net = $net ^ Ones; + return 0 unless hasbits($net); # ipV4/31 or ipV6/127 + return bin2bcd($net); } - return $net[3]; } +# deprecated +#sub num ($) { +# my @net = unpack('L3N',$_[0]->{mask} ^ Ones); +# if ($Old_nth) { +## number of ip's less broadcast +# return 0xfffffffe if $net[0] || $net[1] || $net[2]; # 2**32 -1 +# return $net[3] if $net[3]; +# } else { # returns 1 for /32 /128, 0 for /31 /127 else n-2 up to 2**32 +## number of usable IP's === number of ip's less broadcast & network addys +# return 0xfffffffd if $net[0] || $net[1] || $net[2]; # 2**32 -2 +# return 1 unless $net[3]; +# $net[3]--; +# } +# return $net[3]; +#} + =pod =back diff --git a/Lite/README b/Lite/README index 8f6448f..4abc560 100644 --- a/Lite/README +++ b/Lite/README @@ -409,15 +409,31 @@ "->num()" Version 4.00 of NetAddr::IP and version 1.00 of NetAddr::IP::Lite - Returns the number of usable addresses IP addresses within the - subnet, not counting the broadcast or network address. Previous - versions returned th number of IP addresses not counting the - broadcast address. + return the number of usable IP addresses within the subnet, not + counting the broadcast or network address. + + Previous versions worked only for ipV4 addresses, returned a maximum + span of 2**32 and returned the number of IP addresses not counting + the broadcast address. (one greater than the new behavior) To use the old behavior for "->nth($index)" and "->num()": use NetAddr::IP::Lite qw(:old_nth); + WARNING: + + NetAddr::IP will calculate and return a numeric string for network + ranges as large as 2**128. These values are TEXT strings and perl + can treat them as integers for numeric calculations. + + Perl on 32 bit platforms only handles integer numbers up to 2**32 + and on 64 bit platforms to 2**64. + + If you wish to manipulate numeric strings returned by NetAddr::IP + that are larger than 2**32 or 2**64, respectively, you must load + additional modules such as Math::BigInt, bignum or some similar + package to do the integer math. + EXPORT_OK Zeros Ones diff --git a/Lite/t/v6-num.t b/Lite/t/v6-num.t new file mode 100644 index 0000000..93148aa --- /dev/null +++ b/Lite/t/v6-num.t @@ -0,0 +1,55 @@ +use NetAddr::IP::Lite; + +my $nets = { + 'F0::' => [ 128, '1' ], + 'F1::' => [ 127, '0' ], + 'F2::' => [ 126, '2' ], + 'F3::' => [ 125, '6' ], + 'F4::' => [ 124, '14' ], + 'F5::' => [ 123, '30' ], + 'F6::' => [ 122, '62' ], + 'F7::' => [ 100, '268435454' ], + 'F8::' => [ 99, '536870910' ], + 'F9::' => [ 98, '1073741822' ], + 'FA::' => [ 97, '2147483646' ], + 'FB::' => [ 96, '4294967294' ], + 'FC::' => [ 95, '8589934590' ], + 'FD::' => [ 94, '17179869182' ], + 'FE::' => [ 93, '34359738366' ], + 'FF::' => [ 92, '68719476734' ], + 'F10::' => [ 64, '18446744073709551614' ], + 'F20::' => [ 32, '79228162514264337593543950334' ], + 'F30::' => [ 16, '5192296858534827628530496329220094' ], + 'F40::' => [ 8, '1329227995784915872903807060280344574' ], + 'F50::' => [ 4, '21267647932558653966460912964485513214' ], + 'F60::' => [ 2, '85070591730234615865843651857942052862' ], + 'F70::' => [ 1, '170141183460469231731687303715884105726' ], + 'F80::' => [ 0, '340282366920938463463374607431768211454' ], + '0.0.0.1' => [ 31, '0' ], + '0.0.0.2' => [ 30, '2' ], + '0.0.0.3' => [ 2, '1073741822' ], + '0.0.0.4' => [ 1, '2147483646' ], + '0.0.0.5' => [ 0, '4294967294' ], + '0.0.0.6' => [ 32, '1' ], +}; + +my $new = 1; # flag for old vs new numeric returns + +$| = 1; + +$test = keys %$nets; +print "1..", $test, "\n"; + +$test = 1; +sub tst { + foreach my $a (sort keys %$nets) { + my $nc = $nets->{$a}->[1]; # net count + my $ip = new NetAddr::IP::Lite($a, $nets->{$a}->[0]); + print "/$nets->{$a}->[0] got: $_, exp: $nc\nnot " + unless ($_ = $ip->num) eq $nc; + print "ok ", $test++, "\n"; + } +} + +tst(); + diff --git a/MANIFEST b/MANIFEST index ca1f7d1..a244f47 100644 --- a/MANIFEST +++ b/MANIFEST @@ -63,6 +63,7 @@ Lite/t/v6-new_cis6_base.t Lite/t/v6-new_cis_base.t Lite/t/v6-new-base.t +Lite/t/v6-num.t Lite/t/v6-numeric.t Lite/t/v6-old-base.t Lite/t/version.t diff --git a/META.yml b/META.yml index 1275201..aa75795 100644 --- a/META.yml +++ b/META.yml @@ -1,6 +1,6 @@ --- #YAML:1.0 name: NetAddr-IP -version: 4.040 +version: 4.041 abstract: Manages IPv4 and IPv6 addresses and subnets license: ~ author: