CC: | 427581 [...] rt.noris.net |
Subject: | ":aton" does not work for certain addresses |
$ perl -MSocket=inet_aton -MNetAddr::IP=:aton -le 'print $];print
NetAddr::IP->VERSION;print"$_: ".NetAddr::IP->new(inet_aton$_)for@ARGV'
172.18.3.5{7,8,9}
5.008008
4.007
172.18.3.57: 172.18.3.57/32
172.18.3.58:
172.18.3.59: 172.18.3.59/32
$ perl -MSocket=inet_aton -MNetAddr::IP=:aton -le 'print $];print
NetAddr::IP->VERSION;print"$_: ".NetAddr::IP->new(inet_aton$_)for@ARGV'
172.18.3.5{7,8,9}
5.010000
4.007
172.18.3.57: 172.18.3.57/32
172.18.3.58:
172.18.3.59: 172.18.3.59/32
In fact, this happens primarily for all IP addresses that contain a byte
with value 58 (aka char ":") and for many that include 47 (aka "/"); try
this:
$ perl -MSocket=inet_ntoa -MNetAddr::IP=:aton -le
'NetAddr::IP->new($n=pack"N",$_)or print inet_ntoa$n for 0..0xffffffff'
I think the problem is that NetAddr::IP::Lite::_xnew() thinks that
anything after a slash is a netmask...
if ($ip =~ m!^(.+)/(.+)$!) {
$ip = $1;
$mask = $2;
... and anything which contains ":" should be an IPv6 address:
if (index($ip,':') < 0) { # ipv4 address
There are other cases, of course, e.g.:
$ perl -MNetAddr::IP=:aton -MSocket -le 'print inet_ntoa("42.1");print
NetAddr::IP->new("42.1")'
52.50.46.49
42.0.0.1/32
I don't think that there is any real solution for this problem as long
as you want to support abbreviated IP addresses.
I think it would be better to check if the given string is a valid
inet_aton() representation before trying any other alternative when
":aton" is used. However, this of course would break backward
compatibility for edge cases.
If you think this is too bad, ":aton" should IMHO be deprecated and
maybe a new mode like ":aton_first" be introduced.
Regards,
fany