psgels February 2016

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:


(this is the value I see in phpmyadmin)

When I call up the value with the query:

FROM table

The return value I get is


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:

  • Who or what is wrong here?
  • Why?
  • What can I do to make perl understand the IP address I'm giving to it?


jcaron February 2016

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.


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.

Post Status

Asked in February 2016
Viewed 1,399 times
Voted 4
Answered 1 times


Leave an answer