reassign 601601 libnetaddr-ip-perl
retitle 601601 NetAddr::IP->new6 fails to adjust netmask when mapping a v4 
address
thanks

Something within libnetaddr-ip-perl perl changed between version
4.028+dfsg-1 (currently in squeeze) and version 4.034+dfsg-1 (currently
in sid).  Consider the attached perl program.  The
_convert_ipv4_cidr_to_ipv6 function is pulled from spamassassin's
Mail::SpamAssassin::NetSet module.  On a squeeze system, the program
outputs the following:

Loopback network: 127.0.0.0/8
converted to v6 mapped: 0:0:0:0:0:FFFF:7F00:0/104
IPv6 loopback address: 0:0:0:0:0:0:0:1/128
Is 0:0:0:0:0:0:0:1/128 contained within 0:0:0:0:0:FFFF:7F00:0/104? 0

On a sid sytem, the program outputs this:
Loopback network: 127.0.0.0/8
converted to v6 mapped: 0:0:0:0:0:FFFF:7F00:0/8
IPv6 loopback address: 0:0:0:0:0:0:0:1/128
Is 0:0:0:0:0:0:0:1/128 contained within 0:0:0:0:0:FFFF:7F00:0/8? 1

Note the differences in the network mask when the loopback /8 is
mapped to a v6 address.  Note that this leads to the
NetAddr::IP->contains method returning an incorrect value.

Thanks.
noah

#!/usr/bin/perl

use NetAddr::IP;

sub _convert_ipv4_cidr_to_ipv6 {
  my ($cidr) = @_;

  # only do this for IPv4 addresses
  return undef unless ($cidr =~ /^\d+[.\/]/);

  if ($cidr !~ /\//) {      # no mask
    return NetAddr::IP->new6("::ffff:".$cidr);
  }

  # else we have a CIDR mask specified. use new6() to do this
  #
  my $ip6 = ""+(NetAddr::IP->new6($cidr));
  # 127.0.0.1 -> 0:0:0:0:0:0:7F00:0001/128
  # 127/8 -> 0:0:0:0:0:0:7F00:0/104

  # now, move that from 0:0:0:0:0:0: space to 0:0:0:0:0:ffff: space
  if (!defined $ip6 || $ip6 !~ /^0:0:0:0:0:0:(.*)$/) {
    warn "oops! unparseable IPv6 address for $cidr: $ip6";
    return undef;
  }

  return NetAddr::IP->new6("::ffff:$1");
}

my $a = NetAddr::IP->new('127.0.0.0/8');
my $b = NetAddr::IP->new('::1');
my $converted = _convert_ipv4_cidr_to_ipv6($a);

print "Loopback network: " . $a . "\n";
print "converted to v6 mapped: $converted\n";
print "IPv6 loopback address: $b\n";

print "Is $b contained within $converted? " . $converted->contains($b) . "\n";

Attachment: signature.asc
Description: Digital signature

Reply via email to