On Mon, Nov 24, 2014 at 19:04 +0100, Mike Belopuhov wrote: > Hi, > > IP header is not always aligned since bpf copies out the mbuf > chain into the contigous buffer provided by the userland. I've > seen this with large packet sizes on VLANs. ip_print will then > copy the packet but the Ethernet header into the internal buffer > so that it can cast it to the IP header structure and update > global packetp and snapend pointers hence preventing the -Xx > dumping code from printing out the Ethernet header itself. > > Diff below fixes it. OK? >
better diff. the problem is that dissectors use packetp and snapend pointers themselves therefore they should be pointing to the newly allocated structure. we can restore them once we're done with the inner content and go back to the caller to see if we need to hexdump the contents. i'll see if i can cook and test the ipv6 version. OK? diff --git usr.sbin/tcpdump/print-ip.c usr.sbin/tcpdump/print-ip.c index 3f4194c..60cae4d 100644 --- usr.sbin/tcpdump/print-ip.c +++ usr.sbin/tcpdump/print-ip.c @@ -356,12 +356,12 @@ ip_print(register const u_char *bp, register u_int length) register const struct ip *ip; register u_int hlen, len, off; register const u_char *cp; + const u_char *pktp = packetp; + const u_char *send = snapend; ip = (const struct ip *)bp; /* * If the IP header is not aligned, copy into abuf. - * This will never happen with BPF. It does happen with raw packet - * dumps from -r. */ if ((intptr_t)ip & (sizeof(long)-1)) { static u_char *abuf = NULL; @@ -389,7 +389,7 @@ ip_print(register const u_char *bp, register u_int length) TCHECK(*ip); if (ip->ip_v != IPVERSION) { (void)printf("bad-ip-version %u", ip->ip_v); - return; + goto out; } len = ntohs(ip->ip_len); @@ -402,7 +402,7 @@ ip_print(register const u_char *bp, register u_int length) hlen = ip->ip_hl * 4; if (hlen < sizeof(struct ip) || hlen > len) { (void)printf("bad-hlen %d", hlen); - return; + goto out; } len -= hlen; @@ -467,7 +467,7 @@ ip_print(register const u_char *bp, register u_int length) ip_print(cp, len); if (! vflag) { printf(" (encap)"); - return; + goto out; } break; @@ -484,7 +484,7 @@ ip_print(register const u_char *bp, register u_int length) ip6_print(cp, len); if (! vflag) { printf(" (encap)"); - return; + goto out; } break; #endif /*INET6*/ @@ -501,7 +501,7 @@ ip_print(register const u_char *bp, register u_int length) gre_print(cp, len); if (! vflag) { printf(" (gre encap)"); - return; + goto out; } break; @@ -530,7 +530,7 @@ ip_print(register const u_char *bp, register u_int length) mobile_print(cp, len); if (! vflag) { printf(" (mobile encap)"); - return; + goto out; } break; @@ -655,6 +655,9 @@ ip_print(register const u_char *bp, register u_int length) } printf(")"); } +out: + packetp = pktp; + snapend = send; return; trunc: