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

Reply via email to