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
