> > Based on idea contributed to iputils. > > https://github.com/iputils/iputils/commit/8ed7ffc999e2a541e06ee48faf26a323dfe487c2
> Comparing some linux ping implementations that used glibc > getaddrinfo() which already converts IPv4-mapped address string to > IPv4 struct for requested AF_INET family > In case of nothing prevents to do this conversion: > 1) Inetutils ping: > - explicit ipv4 ping: > % ping -c1 ::ffff:127.0.0.1 > PING ::ffff:127.0.0.1 (127.0.0.1): 56 data bytes > 64 bytes from 127.0.0.1: icmp_seq=0 ttl=64 time=0,100 ms > - explicit ipv6 ping: > % ping6 -c1 ::ffff:127.0.0.1 > PING ::ffff:127.0.0.1 (::ffff:127.0.0.1): 56 data bytes > ./ping/ping6: sending packet: Network is unreachable Thanks a lot for an explanation. FYI the same way behaves also BusyBox and fping implementations. Obviously ping from iputils is wrong. > 2) Iputils ping with reverted two workarounds (one related to > rewriting requested ipv4 family and the last ones with target string > manipulations): > - explicitly requested ipv4 family: > $ ping -c1 -4 ::ffff:127.0.0.1 > PING ::ffff:127.0.0.1 (127.0.0.1) 56(84) bytes of data. > 64 bytes from localhost.localdomain (127.0.0.1): icmp_seq=1 ttl=64 time=0.065 > ms > - explicitly requested ipv6 family: > $ ping -c1 -6 ::ffff:127.0.0.1 > PING ::ffff:127.0.0.1 (::ffff:127.0.0.1) 56 data bytes > --- ::ffff:127.0.0.1 ping statistics --- > 1 packets transmitted, 0 received, 100% packet loss, time 0ms FYI I added PR which reverts the old implementation and does the fix. -4 is working, -6 not. Could you please have a look? https://github.com/iputils/iputils/pull/567 If you do a review, please add your Reviewed-by: (fully reviewed) or at least Acked-by: (somehow agree with the change) tag. I added your credit as reporting it. Kind regards, Petr > So, IPv4-mapped addresses are pinged in the same way if nothing > prevents getaddrinfo() to unmap them for requested AF_INET family > > + hostname = strrchr(hostname, ':') + 1; > If do that for AF_UNSPEC, suppose it'd be better to use data already > converted by getaddrinfo() without any string handling and additional > conversion calls, something like > ``` > struct sockaddr_in6 *sa6 = (struct sockaddr_in6 *)ai->ai_addr; > int rc = IN6_IS_ADDR_V4MAPPED(&sa6->sin6_addr); > if (rc) { > struct sockaddr_in sa4 = { .sin_family = AF_INET, .sin_addr.s_addr > = ((uint32_t*)&sa6->sin6_addr)[3] }; > memcpy(ai->ai_addr, &sa4, sizeof(sa4)); > ai->ai_addrlen = sizeof(sa4); > ai->ai_family = AF_INET; > } > ``` > Implicit or auto cases (when IP family is not requested explicitly > like in case of iputils `ping ::ffff:127.0.0.1`) > are under question in this case > Kind Regards > _______________________________________________ > busybox mailing list > [email protected] > https://lists.busybox.net/mailman/listinfo/busybox _______________________________________________ busybox mailing list [email protected] https://lists.busybox.net/mailman/listinfo/busybox
