diff --git a/Changes b/Changes index 57428ac..2bdf199 100644 --- a/Changes +++ b/Changes @@ -1,5 +1,10 @@ Revision history for Perl extension NetAddr::IP +4.066 Mon Oct 29 13:30:14 PDT 2012 + update Lite.pm v1.47 to support bracketed IPv6 URI notation + as described in RFC-3986 + Thanks to Quanah Gibson-Mount mishikal@yahoo.com + 4.065 Tue Oct 2 12:36:11 PDT 2012 correct format for IPv6 embedded IPv4 addresses in InetBase v0.8 diff --git a/IP.pm b/IP.pm index e6c1c08..f19c229 100644 --- a/IP.pm +++ b/IP.pm @@ -4,7 +4,7 @@ use strict; #use diagnostics; -use NetAddr::IP::Lite 1.46 qw(Zero Zeros Ones V4mask V4net); +use NetAddr::IP::Lite 1.47 qw(Zero Zeros Ones V4mask V4net); use NetAddr::IP::Util 1.48 qw( sub128 inet_aton @@ -36,7 +36,7 @@ @ISA = qw(Exporter NetAddr::IP::Lite); -$VERSION = do { sprintf " %d.%03d", (q$Revision: 4.65 $ =~ /\d+/g) }; +$VERSION = do { sprintf " %d.%03d", (q$Revision: 4.66 $ =~ /\d+/g) }; $rfc3021 = 0; diff --git a/Lite/Changes b/Lite/Changes index 2e25116..06960ff 100644 --- a/Lite/Changes +++ b/Lite/Changes @@ -1,5 +1,10 @@ Revision history for Perl extension NetAddr::IP::Lite +1.47 Mon Oct 29 13:30:14 PDT 2012 + update Lite.pm v1.47 to support bracketed IPv6 URI notation + as described in RFC-3986 + Thanks to Quanah Gibson-Mount mishikal@yahoo.com + 1.46 Tue Oct 2 12:36:11 PDT 2012 correct incorrect format for IPv6 embedded IPv4 addresses in InetBase v0.8 diff --git a/Lite/Lite.pm b/Lite/Lite.pm index efa7e59..222c411 100644 --- a/Lite/Lite.pm +++ b/Lite/Lite.pm @@ -32,7 +32,7 @@ use vars qw(@ISA @EXPORT_OK $VERSION $Accept_Binary_IP $Old_nth $AUTOLOAD *Zero); -$VERSION = do { my @r = (q$Revision: 1.46 $ =~ /\d+/g); sprintf "%d."."%02d" x $#r, @r }; +$VERSION = do { my @r = (q$Revision: 1.47 $ =~ /\d+/g); sprintf "%d."."%02d" x $#r, @r }; require Exporter; @@ -755,7 +755,8 @@ $mask = Ones; last; } - elsif ($ip =~ m!^([a-z0-9.:-]+)(?:/|\s+)([a-z0-9.:-]+)$!) { + elsif ($ip =~ m!^([a-z0-9.:-]+)(?:/|\s+)([a-z0-9.:-]+)$! || + $ip =~ m!^[\[]{1}([a-z0-9.:-]+)(?:/|\s+)([a-z0-9.:-]+)[\]]{1}$!) { $ip = $1; $mask = $2; } elsif (grep($ip eq $_,(qw(default any broadcast loopback unspecified)))) { @@ -1012,6 +1013,7 @@ ########## continuing else { # ipv6 address $isV6 = 1; + $ip = $1 if $ip =~ /\[([^\]]+)\]/; # transform URI notation if (defined ($tmp = ipv6_aton($ip))) { $ip = $tmp; last; diff --git a/Lite/MANIFEST b/Lite/MANIFEST index 8ee751c..19b544f 100644 --- a/Lite/MANIFEST +++ b/Lite/MANIFEST @@ -72,6 +72,10 @@ t/v6-old-base.t t/version.t t/within.t +t/v6-cnew-uri.t +t/v6-new-base-uri.t +t/v6-numeric-uri.t +t/v6-old-base-uri.t Util/MANIFEST Util/MANIFEST.SKIP Util/Changes diff --git a/Lite/t/v6-cnew-uri.t b/Lite/t/v6-cnew-uri.t new file mode 100644 index 0000000..7e129f6 --- /dev/null +++ b/Lite/t/v6-cnew-uri.t @@ -0,0 +1,23 @@ +use NetAddr::IP::Lite; + +my @subnets = ( + [ '[dead:beef:1234::/16]', 'DEAD:BEEF:1234:0:0:0:0:0/16' ], + [ '[::1234:BEEF:DEAD/24]', '0:0:0:0:0:1234:BEEF:DEAD/24' ], + ); +$| = 1; + +print '1..', (scalar @subnets) , "\n"; + +my $count = 1; + +for my $n (@subnets) { + my $ip = new NetAddr::IP::Lite $n->[0]; + if ($ip eq $n->[1]) { + print "ok $count\n"; + } + else { + print $ip, "\nnot ok $count\n"; + } + + ++ $count; +} diff --git a/Lite/t/v6-new-base-uri.t b/Lite/t/v6-new-base-uri.t new file mode 100644 index 0000000..3d97834 --- /dev/null +++ b/Lite/t/v6-new-base-uri.t @@ -0,0 +1,70 @@ +# This -*- perl -*- code excercises the basic v6 functionality + +sub mypass() {1} +sub myfail() {0} + +@addr = + ( + ['[::]', 3, '0:0:0:0:0:0:0:0/128',myfail], + ['[::1]', 3, '0:0:0:0:0:0:0:1/128',myfail], + ['[F34::123/40]', 2, 'F34:0:0:0:0:0:0:3/40',mypass], + ['[DEAD:BEEF::1/40]', 2, 'DEAD:BEEF:0:0:0:0:0:3/40',mypass], + ['[1000::2/40]', 0, '1000:0:0:0:0:0:0:1/40',mypass], + ['[1000::2000/40]', 0, '1000:0:0:0:0:0:0:1/40',mypass], + ['[DEAD::CAFE/40]', 0, 'DEAD:0:0:0:0:0:0:1/40',mypass], + ['[DEAD:BEEF::1/40]', 3, 'DEAD:BEEF:0:0:0:0:0:4/40',mypass], + ['[DEAD:BEEF::1/40]', 4, 'DEAD:BEEF:0:0:0:0:0:5/40',mypass], + ['[DEAD:BEEF::1/40]', 5, 'DEAD:BEEF:0:0:0:0:0:6/40',mypass], + ['[DEAD:BEEF::1/40]', 6, 'DEAD:BEEF:0:0:0:0:0:7/40',mypass], + ['[DEAD:BEEF::1/40]', 7, 'DEAD:BEEF:0:0:0:0:0:8/40',mypass], + ['[DEAD:BEEF::1/40]', 8, 'DEAD:BEEF:0:0:0:0:0:9/40',mypass], + ['[DEAD:BEEF::1/40]', 254, 'DEAD:BEEF:0:0:0:0:0:FF/40',mypass], + ['[DEAD:BEEF::1/40]', 255, 'DEAD:BEEF:0:0:0:0:0:100/40',mypass], + ['[DEAD:BEEF::1/40]', 256, 'DEAD:BEEF:0:0:0:0:0:101/40',mypass], + ['[DEAD:BEEF::1/40]', 65535, 'DEAD:BEEF:0:0:0:0:1:0/40',mypass], + ['[DEAD:BEEF::1/40]', 65536, 'DEAD:BEEF:0:0:0:0:1:1/40',mypass], + ['[2001:620:0:4::/64]', 0, '2001:620:0:4:0:0:0:1/64',mypass], + ['[3FFE:2000:0:4::/64]', 0, '3FFE:2000:0:4:0:0:0:1/64',mypass], + ['[2001:620:600::1]', 0, '2001:620:600:0:0:0:0:1/128',mypass], + ['[2001:620:600:0:1::1]', 0,'2001:620:600:0:1:0:0:1/128',mypass], + ); + +use NetAddr::IP::Lite; +use Test::More; + +my($a, $ip, $test); + +$test = 4 * @addr + 4; +plan tests => $test; + +$test = 1; + +sub tst { + for $a (@addr) { + $ip = new NetAddr::IP::Lite $a->[0]; + $a->[0] =~ s,/\d+,,; + isa_ok($ip, 'NetAddr::IP::Lite', "$a->[0] "); +# requires full NetAddr::IP +# is(uc $ip->short, $a->[0], "short returns $a->[0]"); + is($ip->bits, 128, "bits == 128"); + is($ip->version, 6, "version == 6"); + my $index = $a->[1]; + if ($a->[3]) { + is(uc $ip->nth($index), $a->[2], "nth $a->[0], $index"); + } else { + ok(!$ip->nth($index),"nth $a->[0], undef"); + } + } +} + +tst(); + + +$test = new NetAddr::IP::Lite 'f34::1'; +isa_ok($test, 'NetAddr::IP::Lite'); +ok($test->network->contains($test), "->contains"); + +$test = new NetAddr::IP::Lite 'f35::1/40'; +isa_ok($test, 'NetAddr::IP::Lite'); +ok($test->network->contains($test), "->contains"); + diff --git a/Lite/t/v6-numeric-uri.t b/Lite/t/v6-numeric-uri.t new file mode 100644 index 0000000..bacb68c --- /dev/null +++ b/Lite/t/v6-numeric-uri.t @@ -0,0 +1,91 @@ +use NetAddr::IP::Lite; +use Test::More; + +my @pairs = + ( + [ '[::/0]', '0', '0' ], + [ '[::/128]', '0', '340282366920938463463374607431768211455' ], + [ '[cafe:cafe::/64]', + '269827015721314068804783158349174669312', + '340282366920938463444927863358058659840' ], + [ '[cafe:cafe::1/64]', + '269827015721314068804783158349174669313', + '340282366920938463444927863358058659840' ], + [ '[dead:beef::/100]', + '295990755014133383690938178081940045824', + '340282366920938463463374607431499776000' ], + [ '[dead:beef::1/100]', + '295990755014133383690938178081940045825', + '340282366920938463463374607431499776000' ], + ); + +my @scale = +qw( + 0000:0000:0000:0000:0000:0000:0000:0000 + 0000:0000:0000:0000:0000:0000:0000:0001 + 0000:0000:0000:0000:0000:0000:0000:0010 + 0000:0000:0000:0000:0000:0000:0000:0100 + 0000:0000:0000:0000:0000:0000:0000:1000 + 0000:0000:0000:0000:0000:0000:0001:0000 + 0000:0000:0000:0000:0000:0001:0000:0000 + 0000:0000:0000:0000:0000:0010:0000:0000 + 0000:0000:0000:0000:0000:0100:0000:0000 + 0000:0000:0000:0000:0000:1000:0000:0000 + 0000:0000:0000:0000:0001:0000:0000:0000 + 0000:0000:0000:0001:0000:0000:0000:0000 + 0000:0000:0000:0010:0000:0000:0000:0000 + 0000:0000:0000:0100:0000:0000:0000:0000 + 0000:0000:0000:1000:0000:0000:0000:0000 + 0000:0000:0001:0000:0000:0000:0000:0000 + 0000:0001:0000:0000:0000:0000:0000:0000 + 0000:0010:0000:0000:0000:0000:0000:0000 + 0000:0100:0000:0000:0000:0000:0000:0000 + 0000:1000:0000:0000:0000:0000:0000:0000 + 0001:0000:0000:0000:0000:0000:0000:0000 + 0010:0000:0000:0000:0000:0000:0000:0000 + 0100:0000:0000:0000:0000:0000:0000:0000 + 1000:0000:0000:0000:0000:0000:0000:0000 + ); + +my $tests = 4 * @pairs + @scale ** 2; +plan tests => $tests; + +for my $p (@pairs) +{ + my $a = new NetAddr::IP::Lite $p->[0]; + isa_ok($a, 'NetAddr::IP::Lite', "$p->[0]"); + is($a->numeric, $p->[1], "$p->[0] Scalar numeric ok"); + is(($a->numeric)[0], $p->[1], "$p->[0] Array numeric ok for network"); + is(($a->numeric)[1], $p->[2], "$p->[0] Array numeric ok for mask"); +} + +@ip_scale = map { new NetAddr::IP::Lite $_ } @scale; + +isa_ok($_, 'NetAddr::IP::Lite', $_->addr) for @ip_scale; + +for my $i (0 .. $#ip_scale) +{ + for my $l (0 .. $i - 1) + { + next if $l >= $i; + unless (ok($ip_scale[$i]->numeric > $ip_scale[$l]->numeric, + "[$i, $l] $scale[$i] > $scale[$l]")) + { + diag "assertion [$i]: " . $ip_scale[$i]->numeric . + " > " . $ip_scale[$l]->numeric; + } + } + + next if $i == $#ip_scale; + + for my $l ($i + 1 .. $#ip_scale) + { + next if $l <= $i; + unless (ok($ip_scale[$i]->numeric < $ip_scale[$l]->numeric, + "[$i, $l] $scale[$i] < $scale[$l]")) + { + diag "assertion [$i]: " . $ip_scale[$i]->numeric . + " < " . $ip_scale[$l]->numeric; + } + } +} diff --git a/Lite/t/v6-old-base-uri.t b/Lite/t/v6-old-base-uri.t new file mode 100644 index 0000000..961f15c --- /dev/null +++ b/Lite/t/v6-old-base-uri.t @@ -0,0 +1,70 @@ +# This -*- perl -*- code excercises the basic v6 functionality + +sub mypass() {1} +sub myfail() {0} + +@addr = + ( + ['[::]', 3, '0:0:0:0:0:0:0:0/128',myfail], + ['[::1]', 3, '0:0:0:0:0:0:0:1/128',myfail], + ['[F34::123/40]', 3, 'F34:0:0:0:0:0:0:3/40',mypass], + ['[DEAD:BEEF::1/40]', 3, 'DEAD:BEEF:0:0:0:0:0:3/40',mypass], + ['[1000::2/40]', 1, '1000:0:0:0:0:0:0:1/40',mypass], + ['[1000::2000/40]', 1, '1000:0:0:0:0:0:0:1/40',mypass], + ['[DEAD::CAFE/40]', 1, 'DEAD:0:0:0:0:0:0:1/40',mypass], + ['[DEAD:BEEF::1/40]', 4, 'DEAD:BEEF:0:0:0:0:0:4/40',mypass], + ['[DEAD:BEEF::1/40]', 5, 'DEAD:BEEF:0:0:0:0:0:5/40',mypass], + ['[DEAD:BEEF::1/40]', 6, 'DEAD:BEEF:0:0:0:0:0:6/40',mypass], + ['[DEAD:BEEF::1/40]', 7, 'DEAD:BEEF:0:0:0:0:0:7/40',mypass], + ['[DEAD:BEEF::1/40]', 8, 'DEAD:BEEF:0:0:0:0:0:8/40',mypass], + ['[DEAD:BEEF::1/40]', 9, 'DEAD:BEEF:0:0:0:0:0:9/40',mypass], + ['[DEAD:BEEF::1/40]', 255, 'DEAD:BEEF:0:0:0:0:0:FF/40',mypass], + ['[DEAD:BEEF::1/40]', 256, 'DEAD:BEEF:0:0:0:0:0:100/40',mypass], + ['[DEAD:BEEF::1/40]', 257, 'DEAD:BEEF:0:0:0:0:0:101/40',mypass], + ['[DEAD:BEEF::1/40]', 65536, 'DEAD:BEEF:0:0:0:0:1:0/40',mypass], + ['[DEAD:BEEF::1/40]', 65537, 'DEAD:BEEF:0:0:0:0:1:1/40',mypass], + ['[2001:620:0:4::/64]', 1, '2001:620:0:4:0:0:0:1/64',mypass], + ['[3FFE:2000:0:4::/64]', 1, '3FFE:2000:0:4:0:0:0:1/64',mypass], + ['[2001:620:600::1]', 1, '2001:620:600:0:0:0:0:1/128',myfail], + ['[2001:620:600:0:1::1]', 1,'2001:620:600:0:1:0:0:1/128',myfail], + ); + +use NetAddr::IP::Lite qw(:old_nth); +use Test::More; + +my($a, $ip, $test); + +$test = 4 * @addr + 4; +plan tests => $test; + +$test = 1; + +sub tst { + for $a (@addr) { + $ip = new NetAddr::IP::Lite $a->[0]; + $a->[0] =~ s,/\d+,,; + isa_ok($ip, 'NetAddr::IP::Lite', "$a->[0] "); +# requires full NetAddr::IP +# is(uc $ip->short, $a->[0], "short returns $a->[0]"); + is($ip->bits, 128, "bits == 128"); + is($ip->version, 6, "version == 6"); + my $index = $a->[1]; + if ($a->[3]) { + is(uc $ip->nth($index), $a->[2], "nth $a->[0], $index"); + } else { + ok(!$ip->nth($index),"nth $a->[0], undef"); + } + } +} + +tst(); + + +$test = new NetAddr::IP::Lite 'f34::1'; +isa_ok($test, 'NetAddr::IP::Lite'); +ok($test->network->contains($test), "->contains"); + +$test = new NetAddr::IP::Lite 'f35::1/40'; +isa_ok($test, 'NetAddr::IP::Lite'); +ok($test->network->contains($test), "->contains"); + diff --git a/MANIFEST b/MANIFEST index d464c42..596f462 100644 --- a/MANIFEST +++ b/MANIFEST @@ -37,6 +37,7 @@ t/v6-split-bulk.t t/v6-splitplan.t t/wildcard.t +t/full6-uri.t Lite/Changes Lite/Lite.pm Lite/MANIFEST @@ -111,6 +112,10 @@ Lite/t/v6-old-base.t Lite/t/version.t Lite/t/within.t +Lite/t/v6-cnew-uri.t +Lite/t/v6-new-base-uri.t +Lite/t/v6-numeric-uri.t +Lite/t/v6-old-base-uri.t Lite/Util/Changes Lite/Util/MANIFEST Lite/Util/MANIFEST.SKIP diff --git a/META.yml b/META.yml index f74ac1e..0b7c294 100644 --- a/META.yml +++ b/META.yml @@ -1,6 +1,6 @@ --- #YAML:1.0 name: NetAddr-IP -version: 4.065 +version: 4.066 abstract: Manages IPv4 and IPv6 addresses and subnets license: ~ author: diff --git a/t/full6-uri.t b/t/full6-uri.t new file mode 100644 index 0000000..ce3d7ec --- /dev/null +++ b/t/full6-uri.t @@ -0,0 +1,25 @@ +use Test::More; + +# $Id: short.t,v 1.1.1.1 2006/08/14 15:36:06 lem Exp $ + +my %cases = +( + '127.1' => '0000:0000:0000:0000:0000:0000:7f00:0001', + '123.23.4.210' => '0000:0000:0000:0000:0000:0000:7b17:04d2', + '[DEAD:BEEF::1]' => 'dead:beef:0000:0000:0000:0000:0000:0001', + '[1:2:3:4:5:6:7:8]' => '0001:0002:0003:0004:0005:0006:0007:0008', + '[1234:5678:90AB:CDEF:0123:4567:890A:BCDE]' => '1234:5678:90ab:cdef:0123:4567:890a:bcde', +); + +my $tests = keys %cases; +plan tests => 1 + $tests; + +SKIP: { + use_ok('NetAddr::IP') or skip "Failed to load NetAddr::IP", $tests; + for my $c (sort keys %cases) + { + my $ip = new NetAddr::IP $c; + my $rv = lc $ip->full6; + is($rv, $cases{$c}, "full6($c ) returns $rv"); + } +}