Reading the RFC recommendations (RFC 5952) for how to represent IPv6 addresses in the best way, I try to implement a function in C++ that converts an array of bytes into the appropriate textual representation, i.e. std::string
.
To check my code for correctness, I compare my results with what inet_ntop
(#include <arpa/inet.h>
) returns. Note that I am actually using the Windows-equivalent #include <ws2tcpip.h>
.
For most cases, my function has the same behavior and I fully understand the underlying rules (leave out leading zeros, compress the longest block of zeros by replacnig it with "::", and so on).
But the interesting part is the following: As far as I understand, for some special addresses (IPv4-mapped, IPv4-compatible, and IPv4-translated IPv6 addresses, see RFC 2765), it is recommended to represent the otherwise hexa-decimal notation of the last 4 bytes with the dotted decimal notation that is common for IPv4 addresses.
For example, ::ffff:0:168.0.0.1
, ::ffff:168.0.0.1
and ::168.0.0.1
are all valid IPv6 addresses in their recommended textual representations and inet_ntop
comes to that conclusion as well.
And now to my question: The IPv6 address 0:0:0:0:0:ffff:0.0.1.1
is, according to inet_ntop
, shortened to ::ffff:0:101
, choosing the hexa-decimal representation again. What is the reason for this behavior? I would think that because we have a special address prefix here, the dotted decimal notation would be used regardless of the fact the the first two bytes of the last 4 byte block are zero, and therefore writing it as ::ffff:0.0.1.1
. Am I misunderstanding the RFC recommendation or is inet_ntop
not consistent in this regard? I observed that inet_ntop
is in all other of my testcases very much RFC-conform.
I hope you can help me.
Edit: After some more testing, it does seem that inet_ntop
does always choose the hexa-decimal notation over the dotted decimal one, even though the IPv6 address is actually just some of those special embedded IPv4 addresses, if the first two bytes of that last 4 byte block are zero.
::x.x.x.x/96
) has been deprecated by RFC 4291: "The "IPv4-Compatible IPv6 address" is now deprecated because the current IPv6 transition mechanisms no longer use these addresses." Only the IPv4-Mapped (::ffff:x.x.x.x/96
) and IPv4-Embedded addressing are still valid, but it is very difficult to determine embedded IPv4 addressing. – Ron Maupin