[PATCH 1/1] ping: Add support for IPv4-mapped IPv6 address format
Petr Vorel
petr.vorel at gmail.com
Sun Oct 20 11:51:32 UTC 2024
Hi David, all,
[ Cc Lars, the original reporter of the missing feature ]
> Hi David,
> > 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.
> BTW I suppose the same behavior is for ICMP datagram socket (aka "ping" socket),
> which busybox ping implementation does not support, some others support (e.g.
> ping from iputils or fping).
> > 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.
> Very good point. In this case I'll seriously consider to remove the support from
> iputils ping and stop implementation for fping I already started.
> > 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
> I should have asked this before including the feature in iputils. I'll ask at
> least now (Tj is also Cced).
Maybe Lars can explain the reasons.
Kind regards,
Petr
> Kind regards,
> Petr
> > > 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 <linux at iam.tj>
> > > Signed-off-by: Petr Vorel <petr.vorel at 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 at busybox.net
> > > https://lists.busybox.net/mailman/listinfo/busybox
More information about the busybox
mailing list