Skip Menu |

This queue is for tickets about the NetAddr-IP CPAN distribution.

Report information
The Basics
Id: 119999
Status: new
Priority: 0/
Queue: NetAddr-IP

People
Owner: Nobody in particular
Requestors: nerdmachine [...] gmail.com
Cc:
AdminCc:

Bug Information
Severity: (no value)
Broken in: (no value)
Fixed in: (no value)



CC: Rob Riepel <riepel [...] networking.Stanford.EDU>
Subject: short() does not follow rfc5952 for ipv6 addresses starting with 0:
Date: Thu, 26 Jan 2017 11:26:13 -0500
To: bug-NetAddr-IP [...] rt.cpan.org, bug-Net-IP [...] rt.cpan.org
From: Duane Bronson <nerdmachine [...] gmail.com>
Beloved Authors/Maintainers of Net::IP and NetAddr::IP, Here are some commands run on a linux machine: $ perl -wE 'use NetAddr::IP; my $ip = new NetAddr::IP(qq(::1:0:0:0:1));say $ip->short()' 0:0:0:1::1 $ perl -wE 'use Net::IP; my $ip = new Net::IP(qq(::1:0:0:0:1));say $ip->short()' 0:0:0:1::1 $ ip route get to ::1:0:0:0:1 ::1:0:0:0:1 via fe80::214:1bff:1:1 dev br0 proto kernel src 2600:1:1:1:20e:b6ff:fe9a:d031 metric 1024 expires 1776sec mtu 1500 advmss 1440 hoplimit 64 $ ip route get to 0:0:0:1::1 ::1:0:0:0:1 via fe80::214:1bff:1:1 dev br0 proto kernel src 2600:1:1:1:20e:b6ff:fe9a:d031 metric 1024 expires 1776sec mtu 1500 advmss 1440 hoplimit 64 (note: some ip addresses changed) Notice that linux's ip command normalizes this ip address differently than Net::IP::short and NetAddr::IP::short, so they can't be reliably used as a hash key interchangeably. It turns out there is a standard that they should be following - rfc5952. From https://www.rfc-editor.org/rfc/rfc5952.txt <https://www.rfc-editor.org/rfc/rfc5952.txt> : 4.2. "::" Usage 4.2.1. Shorten as Much as Possible The use of the symbol "::" MUST be used to its maximum capability. For example, 2001:db8:0:0:0:0:2:1 must be shortened to 2001:db8::2:1. Likewise, 2001:db8::0:1 is not acceptable, because the symbol "::" could have been used to produce a shorter representation 2001:db8::1. 4.2.2. Handling One 16-Bit 0 Field The symbol "::" MUST NOT be used to shorten just one 16-bit 0 field. For example, the representation 2001:db8:0:1:1:1:1:1 is correct, but 2001:db8::1:1:1:1:1 is not correct. 4.2.3. Choice in Placement of "::" When there is an alternative choice in the placement of a "::", the longest run of consecutive 16-bit 0 fields MUST be shortened (i.e., the sequence with three consecutive zero fields is shortened in 2001: 0:0:1:0:0:0:1). When the length of the consecutive 16-bit 0 fields are equal (i.e., 2001:db8:0:0:1:0:0:1), the first sequence of zero bits MUST be shortened. For example, 2001:db8::1:0:0:1 is correct representation. TIMTOWTDI, but a simple fix for both Net::IP and NetAddr::IP are simply to add 2 to the length calculation to prioritize the initial 0: over the embedded :0: *** ./.cpan/build/NetAddr-IP-4.079-3G2VcG/blib/lib/NetAddr/IP.pm 2016-03-25 20:55:36.000000000 -0400 --- /tmp/NetAddr/IP.pm 2017-01-26 11:08:24.000000000 -0500 *************** *** 852,858 **** sub _compV6 ($) { my $ip = shift; return $ip unless my @candidates = $ip =~ /((?:^|:)0(?::0)+(?::|$))/g; ! my $longest = (sort { length($b) <=> length($a) } @candidates)[0]; $ip =~ s/$longest/::/; return $ip; } --- 852,858 ---- sub _compV6 ($) { my $ip = shift; return $ip unless my @candidates = $ip =~ /((?:^|:)0(?::0)+(?::|$))/g; ! my $longest = (sort { (substr($b,0,1) eq ":"?0:2) + length($b) <=> (substr($a,0,1) eq ":"?0:2) + length($a) } @candidates)[0]; $ip =~ s/$longest/::/; return $ip; } and *** /System/Library/Perl/Extras/5.18/Net/IP.pm 2012-11-28 10:23:38.000000000 -0500 --- /tmp/Net/IP.pm 2017-01-26 11:06:36.000000000 -0500 *************** *** 1561,1567 **** /gx ) { ! $reg = $1 if (length($reg) < length($1)); } # Replace sequence by '::' --- 1561,1567 ---- /gx ) { ! $reg = $1 if ((substr($reg,0,1) eq ":"?0:2) + length($reg) < (substr($1,0,1) eq ":"?0:2) + length($1)); } # Replace sequence by '::' I did some simple testing and here are my results: $ perl foo.pl 0:0:0:1:0:0:1:1 NetAddr::IP old: ::1:0:0:1:1 NetAddr::IP new ::1:0:0:1:1 Net::IP old ::1:0:0:1:1 Net::IP new ::1:0:0:1:1 $ perl foo.pl 0:0:0:1:0:0:0:1 NetAddr::IP old: 0:0:0:1::1 NetAddr::IP new ::1:0:0:0:1 Net::IP old 0:0:0:1::1 Net::IP new ::1:0:0:0:1 $ perl foo.pl 0:0:1:1:0:0:0:1 NetAddr::IP old: 0:0:1:1::1 NetAddr::IP new 0:0:1:1::1 Net::IP old 0:0:1:1::1 Net::IP new 0:0:1:1::1 $ perl foo.pl 1:0:0:1:1:0:0:1 NetAddr::IP old: 1::1:1:0:0:1 NetAddr::IP new 1::1:1:0:0:1 Net::IP old 1::1:1:0:0:1 Net::IP new 1::1:1:0:0:1 $ perl foo.pl 0:0:1:0:0:1:0:0 NetAddr::IP old: 0:0:1::1:0:0 NetAddr::IP new ::1:0:0:1:0:0 Net::IP old 0:0:1::1:0:0 Net::IP new ::1:0:0:1:0:0 Other trivial details: perl 5.18.2 and 5.10.1 on OS X and Scientific Linux 6.2 NetAddr-IP-4.079 Net::IP-1.26 Thanks, Duane Duane Bronson NerdMachine@gmail.com <mailto:NerdMachine@gmail.com> http://www.nerdlogic.com/ <http://www.nerdlogic.com/> 5 Goden St. Belmont, MA 02478

Message body is not shown because it is too large.

CC: Rob Riepel <riepel [...] networking.Stanford.EDU>
Subject: Re: [rt.cpan.org #119999] AutoReply: short() does not follow rfc5952 for ipv6 addresses starting with 0:
Date: Thu, 26 Jan 2017 12:51:44 -0500
To: bug-NetAddr-IP [...] rt.cpan.org
From: Duane Bronson <nerdmachine [...] gmail.com>
Alternative patch if you think this looks prettier: *** ./.cpan/build/NetAddr-IP-4.079-3G2VcG/blib/lib/NetAddr/IP.pm 2016-03-25 20:55:36.000000000 -0400 --- /tmp/NetAddr/IP.pm 2017-01-26 12:37:08.000000000 -0500 *************** *** 853,858 **** --- 853,859 ---- my $ip = shift; return $ip unless my @candidates = $ip =~ /((?:^|:)0(?::0)+(?::|$))/g; my $longest = (sort { length($b) <=> length($a) } @candidates)[0]; + $longest=~s/^:?/:?/; $ip =~ s/$longest/::/; return $ip; } Duane