php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #69232 inet_ntop() does not treat IPv4 mapped IPv6 addresses consistently
Submitted: 2015-03-12 19:02 UTC Modified: -
Votes:1
Avg. Score:3.0 ± 0.0
Reproduced:1 of 1 (100.0%)
Same Version:1 (100.0%)
Same OS:1 (100.0%)
From: wolfen at gmail dot com Assigned:
Status: Open Package: Network related
PHP Version: 5.5.23RC1 OS: linux
Private report: No CVE-ID: None
Have you experienced this issue?
Rate the importance of this bug to you:

 [2015-03-12 19:02 UTC] wolfen at gmail dot com
Description:
------------
I'm using PHP version 5.2.17, but using the online PHP sandbox at http://sandbox.onlinephpfunctions.com/ I see the same behavior for PHP versions up through 5.6.2:

The following works as expected:

    $x = inet_pton('::F');
    $y = inet_ntop($x);
    print "::F -> $y\n";

Output: ::F -> ::f
But the following surprised me:

    $a = inet_pton('::FEEF:1886');
    $b = inet_ntop($a);
    print "::FEEF:1886 -> $b\n";

Output: ::FEEF:1886 -> ::254.239.24.134
I would have expected the second code snippet to produce this output:

::FEEF:1886 -> ::feef:1886

My initial surprise was due to my being unaware that addresses in ::/96 (i.e. with the "high" 96 bits all set to 0) are considered "IPv4 compatible IPv6 addresses", which according to RFC 4291 are now deprecated.

But what continues to mystify me is how PHP chooses between "pure IPv6 mode" (e.g. ::ff) and "IPv4 compatible IPv6 mode" (e.g. ::254.239.24.134) when generating a printable representation for an IPv6 address in ::/96. I can find no rule explaining which addresses are supposed to be rendered in which way, which seems wrong.

IMO the "canonical representation" (as specified in RFC 5952) should be generated, or at least all the addresses in ::/96 should be rendered in the same format.


Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2015-03-15 16:15 UTC] keithm at aoeex dot com
It looks to me like the function is following RFC 5952.


RFC5952 Seciton 5 "Text Representation of Special Addresses"

"Addresses such as IPv4-Mapped IPv6 addresses, ISATAP [RFC5214], and IPv4-translatable addresses [ADDR-FORMAT] have IPv4 addresses embedded in the low-order 32 bits of the address.[...]For these addresses, mixed notation is RECOMMENDED if the following condition is met: the address can be distinguished as having IPv4 addresses embedded in the lower 32 bits solely from the address field through the use of a well-known prefix."

::FEEF:1886 meets that condition by having an all-zero prefix which is why it is formatted as an IPv4 mapped address.  ::F meets the all-zero prefix but the lower 32-bits do not form a valid IPv4 address so it sticks with the IPv6 representation.
 [2015-03-16 15:03 UTC] wolfen at gmail dot com
In response to the comment yesterday (3/15/2015): Why do you say that ::F is not a valid IPv4 address? It is reserved as a broadcast address, which means I cannot assign it to a host. But it *is* a perfectly valid address as far as I know.
 [2015-03-25 18:05 UTC] wolfen at gmail dot com
My reading of the source for inet_pton6() published at

http://www.opensource.apple.com/source/curl/curl-57/curl/lib/inet_ntop.c

convinces me that *all* 128 bit addresses in ::/96 and all addresses in ::FFFF/80 *should* be formatted as an IPv4 "dotted quad" with a double-colon prefix.

If I discover different behavior when I compile & test this code then I will add another comment with the results.
 
PHP Copyright © 2001-2019 The PHP Group
All rights reserved.
Last updated: Sat Aug 24 00:01:26 2019 UTC