I'm not a fan of this patch because ping is a low-level diagnostic tool. On Fri, 18 Oct 2024, Petr Vorel wrote:
IP addresses with ::ffff: prefix are IPv6 addresses which are mapped to IPv4. Therefore ping resulting IPv4 address.
I can understand why anyone would think this translation is normal, because the socket API normally unmaps IPv4-mapped IPv6 addresses for compatibility: https://www.rfc-editor.org/rfc/rfc3493.html#section-3.7
Applications may use AF_INET6 sockets to open TCP connections to IPv4 nodes, or send UDP packets to IPv4 nodes, by simply encoding the destination's IPv4 address as an IPv4-mapped IPv6 address, and passing that address, within a sockaddr_in6 structure, in the connect() or sendto() call.
But this is not the case with ping because ping uses IPv6 raw sockets, and that seems to stop sendto() from performing the convenience unmapping. Sadly, this patch breaks the case where an advanced user wants ping to send a packet with an IPv4-mapped IPv6 addresses. For example, you might be testing or diagosing firewall rules in that subnet. Additionally, I can't see any combination of -4 or -6 option flags that could be used as a guard to make the unmapping behaviour expected. I was also interested in the motivation behind this patch. I followed the github reference to the associated discussion at https://github.com/iputils/iputils/pull/558 where the proposer (iam-TJ) wrote:
I wrote this because a C++ programmer complained that Debian's ping "doesn't work" in our Matrix support room; instead of complaining the time and energy is best spent on fixing.
I can only speculate on what what they were trying to do. I suspect their program accepted on an IPv6 listener socket, passed the peer's address to inet_ntop(), got "::ffff:1.2.3.4", constructed a "ping %s" for system() and found that, becoming a raw wire address, it was promptly dropped by a route table or firewall. Is this what happend? If so, then, for portability, the program might instead use getnameinfo() with flag NI_NUMERICHOST rather than inet_ntop(). This is documented to perform the unmapping, see: https://pubs.opengroup.org/onlinepubs/009604599/functions/getnameinfo.html or https://www.rfc-editor.org/rfc/rfc3493.html#section-6.2
If the socket address structure contains an IPv4-mapped IPv6 address or an IPv4-compatible IPv6 address, the implementation shall extract the embedded IPv4 address and lookup the node name for that IPv4 address.
d
Cc: Tj <li...@iam.tj> Signed-off-by: Petr Vorel <petr.vo...@gmail.com> --- Based on idea contributed to iputils. https://github.com/iputils/iputils/commit/8ed7ffc999e2a541e06ee48faf26a323dfe487c2 Kind regards, Petr networking/ping.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/networking/ping.c b/networking/ping.c index b7e6955a9..7ed58f9d6 100644 --- a/networking/ping.c +++ b/networking/ping.c @@ -986,6 +986,14 @@ static int common_ping_main(int opt, char **argv) af = AF_INET; if (opt & OPT_IPV6) af = AF_INET6; + + struct in6_addr a6; + if (inet_pton(AF_INET6, hostname, &a6) && IN6_IS_ADDR_V4MAPPED(&a6)) { + hostname = strrchr(hostname, ':') + 1; + af = AF_INET; + printf("IPv4-Mapped-in-IPv6 address, using IPv4 %s\n", hostname); + } + lsa = xhost_and_af2sockaddr(hostname, 0, af); } #else -- 2.45.2 _______________________________________________ busybox mailing list busybox@busybox.net https://lists.busybox.net/mailman/listinfo/busybox
_______________________________________________ busybox mailing list busybox@busybox.net https://lists.busybox.net/mailman/listinfo/busybox