Am 15.06.2016 09:12, schrieb Jonas Danielsson:
> The ICMP RFC says that identifier and sequence number may be zero.
> Having them zero for a Echo message, along with a data of zero:s
> as well will result in a Echo reply message with only zero:s.
> 
> Some NAT implementations seem to get the checksum wrong on these
> packages. Setting a checksum of 0x0 instead of 0xffff.
> 
> Through NAT:
>   Internet Control Message Protocol
>       Type: 0 (Echo (ping) reply)
>       Code: 0
>       Checksum: 0x0000 [incorrect, should be 0xffff]
>       Identifier (BE): 0 (0x0000)
>       Identifier (LE): 0 (0x0000)
>       Sequence number (BE): 0 (0x0000)
>       Sequence number (LE): 0 (0x0000)
>       Data (56 bytes)
>           Data: 000000000000000000000000000000000000000000000000...
>           [Length: 56]
> 
> Without NAT:
>   Internet Control Message Protocol
>       Type: 0 (Echo (ping) reply)
>       Code: 0
>       Checksum: 0xffff [correct]
>       Identifier (BE): 0 (0x0000)
>       Identifier (LE): 0 (0x0000)
>       Sequence number (BE): 0 (0x0000)
>       Sequence number (LE): 0 (0x0000)
>       [Request frame: 189]
>       [Response time: 0.024 ms]
>       Data (56 bytes)
>           Data: 000000000000000000000000000000000000000000000000...
>           [Length: 56]
> 
> And this in turn will make some hardware MAC checksum offloading
> engines drop the packet.
> 
> This change can be seen as a workaround for bugs in other layers.
> But just setting an identifier for the Echo message packet will
> avoid prodding the hornets nest.
> 
> Signed-off-by: Jonas Danielsson <[email protected]>
> ---
>  networking/ping.c | 6 ++++++
>  1 file changed, 6 insertions(+)
> 
> diff --git a/networking/ping.c b/networking/ping.c
> index 5d71fe8..35ceec7 100644
> --- a/networking/ping.c
> +++ b/networking/ping.c
> @@ -196,6 +196,7 @@ create_icmp_socket(void)
>  struct globals {
>       char *hostname;
>       char packet[DEFDATALEN + MAXIPLEN + MAXICMPLEN];
> +     uint16_t myid;
>  } FIX_ALIASING;
>  #define G (*(struct globals*)&bb_common_bufsiz1)
>  #define INIT_G() do { } while (0)
> @@ -214,6 +215,7 @@ static void ping4(len_and_sockaddr *lsa)
>       pkt = (struct icmp *) G.packet;
>       /*memset(pkt, 0, sizeof(G.packet)); already is */
>       pkt->icmp_type = ICMP_ECHO;
> +     pkt->icmp_id = G.myid;
>       pkt->icmp_cksum = inet_cksum((uint16_t *) pkt, sizeof(G.packet));
>  
>       xsendto(pingsock, G.packet, DEFDATALEN + ICMP_MINLEN, &lsa->u.sa, 
> lsa->len);
> @@ -238,6 +240,9 @@ static void ping4(len_and_sockaddr *lsa)
>                       struct iphdr *iphdr = (struct iphdr *) G.packet;
>  
>                       pkt = (struct icmp *) (G.packet + (iphdr->ihl << 2));   
> /* skip ip hdr */
> +                     if (pkt->icmp_id != G.myid)
> +                             continue; /* not our ping */
> +
>                       if (pkt->icmp_type == ICMP_ECHOREPLY)
>                               break;
>               }
> @@ -317,6 +322,7 @@ static int common_ping_main(sa_family_t af, char **argv)
>       if (!G.hostname)
>               bb_show_usage();
>  
> +     G.myid = (uint16_t) getpid();
>  #if ENABLE_PING6
>       lsa = xhost_and_af2sockaddr(G.hostname, 0, af);
>  #else


What happened to the idea of using a random number here ?
granted most Embedded systems are bad at those but for this application
it would be sufficient.

just my 2 cents
re,
 wh
_______________________________________________
busybox mailing list
[email protected]
http://lists.busybox.net/mailman/listinfo/busybox

Reply via email to