7

I need to convert a ipv6 address to its nibble format for use in creating ptr records dynamically. Here is the information I got from Wikipedia:

IPv6 reverse resolution

Reverse DNS lookups for IPv6 addresses use the special domain ip6.arpa. An IPv6 address appears as a name in this domain as a sequence of nibbles in reverse order, represented as hexadecimal digits as subdomains. For example, the pointer domain name corresponding to the IPv6 address 2001:db8::567:89ab is b.a.9.8.7.6.5.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.8.b.d.0.1.0.0.2.ip6.arpa.

The only thing I could find regarding nibbles was in the pack function, http://www.php.net/pack. I could not find any solutions with examples from googling the issue.

Any help is greatly appreciated.

Emre Yazici
  • 9,708
  • 6
  • 46
  • 54
Jason Brumwell
  • 3,364
  • 21
  • 16

5 Answers5

12

Given a suitably modern version of PHP (>= 5.1.0, or 5.3+ on Windows), use the inet_pton function to parse the IPv6 address into a 16 byte array, and then use standard string ops to reverse it.

$ip = '2001:db8::567:89ab';
$addr = inet_pton($ip);
$unpack = unpack('H*hex', $addr);
$hex = $unpack['hex'];
$arpa = implode('.', array_reverse(str_split($hex))) . '.ip6.arpa';
Alnitak
  • 313,276
  • 69
  • 379
  • 466
3

You can use the ipv6calc command (UNIX/Linux) line tool from here.

For example:

$ ./ipv6calc --out revnibbles.arpa 2001:db8::1
No input type specified, try autodetection...found type: ipv6addr
1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.8.b.d.0.1.0.0.2.ip6.arpa.

You could embed this is a script to eat your forward zone files and create the PTRs.

Marvin Pinto
  • 27,868
  • 7
  • 35
  • 52
tep
  • 31
  • 3
2

And this is the reverse, based on Alnitak's great code, in the form of a function:

function ptr_to_ipv6($arpa) {
    $mainptr = substr($arpa, 0, strlen($arpa)-9);
    $pieces = array_reverse(explode(".",$mainptr));  
    $hex = implode("",$pieces);
    $ipbin = pack('H*', $hex);
    $ipv6addr = inet_ntop($ipbin);

    return $ipv6addr;
}
antyrat
  • 26,266
  • 9
  • 69
  • 74
Nick
  • 21
  • 1
0

I do this:

function expand($ip){
    $hex = unpack("H*hex", inet_pton($ip));
    $ip = substr(preg_replace("/([A-f0-9]{4})/", "$1:", $hex['hex']), 0, -1);
    return $ip;
}

function ipv6_reverse_calc($address){
  $rev = chop(chunk_split(strrev(str_replace(':', '', expand($address))), 1, '.'), '.');
  return "$rev.ip6.arpa";
}
-2

Well, from that example, you can see that the nibble format is the complete ipv6 address (including 0'd fields), reversed, then split into characters and separated with periods. So personally, i would just use the string representation and manipulate it as needed.

Jim Deville
  • 10,272
  • 1
  • 33
  • 47
  • 2
    parsing an abbreviated IPv6 address is non-trivial - best to leave it to the library functions designed to do just that. – Alnitak Jul 08 '11 at 10:18