psgels
psgels

Reputation: 737

IPv6 SQL to Perl

I have a field in a mysql table as a varbinary(16), which stores binary IPv6 addresses.

While toying around with my code and testing stuff, I filled one of its records with the binary value for:

0fff0fff0fff0fff0fff0fff0fe00000

(this is the value I see in phpmyadmin)

When I call up the value with the query:

SELECT INET6_NTOA(value)
FROM table

The return value I get is

fff:fff:fff:fff:fff:fff:fe0::

In perl, when I try to put this into a Net::IP-object:

$ip = new Net::IP('fff:fff:fff:fff:fff:fff:fe0::', 6);

It returns undefined.

My questions:

Upvotes: 1

Views: 175

Answers (1)

jcaron
jcaron

Reputation: 17710

Apparently MySQL and Net::IP do not agree on the use of :: to represent a trailing :0.

As far as I understand RFC4191, fff:fff:fff:fff:fff:fff:fe0:: should be a perfectly valid IPv6 address (expanded as 0fff:0fff:0fff:0fff:0fff:0fff:0fe0:0000), but Net::IP does not seem to agree.

Net::IP seems to agree on using :: for a trailing :0:0, but not for just :0. It is also OK with :: replacing a single :0: anywhere else. Looks like a bug. It can be traced down to ip_is_ipv6 which thinks that an IPv6 address cannot have 8 :s (which is true in all cases but a single leading or trailing 0 replaced by ::).

You could do a bit of preprocessing to replace a trailing :: with :0 and a leading :: with 0: if there are 8 colons in the IP.

EDIT

It turns out that RFC5952 says that single 0 (and hence a trailing :0) should not be replaced by :: in output, so the MySQL INET6_NTOA is at fault, but it still says that RFC4191-compliant addresses should be accepted as input, so Net::IP should accept it nonetheless. Fixing the bug on either side would address the issue.

Upvotes: 2

Related Questions