[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