On Mon, Dec 12, 2016 at 01:02:55PM +1000, David Gwynne wrote: > gre can do more things than tcpdump currently thinks it can. > > specifically, gre can be carried by ipv6, and it can encapsulate > more than just ip and ppp packets. > > as such, this tells tcpdump to look at gre inside ipv6 packets. > > gre uses ethertypes to represent what protocol it contains, so > instead of rolling a gre specific version of ip and ppp protocol > types, just reuse the ether ones. > > also tell tcpdump that gre can contains ipv6, ethernet, and mpls. > > NVGRE is basically a constrained gre header (ie, must be version > 0, must only have the K bit set, must be transether), so this detects > that and prints the NVGRE interpretation of the Key field. that > makes the VSID in NVGRE packets easier to see. > > theres some tweaks to output so it looks ok with and without the > -v optarg. > > ok?
ok stsp@ > > Index: print-gre.c > =================================================================== > RCS file: /cvs/src/usr.sbin/tcpdump/print-gre.c,v > retrieving revision 1.11 > diff -u -p -r1.11 print-gre.c > --- print-gre.c 5 Nov 2015 11:55:21 -0000 1.11 > +++ print-gre.c 12 Dec 2016 02:48:21 -0000 > @@ -39,6 +39,8 @@ > #include <netinet/ip.h> > #include <arpa/inet.h> > > +#include <net/ethertypes.h> > + > #include <stdio.h> > #include <string.h> > > @@ -55,13 +57,15 @@ > #define GRE_AP 0x0080 /* acknowledgment# present */ > #define GRE_VERS 0x0007 /* protocol version */ > > -#define GREPROTO_IP 0x0800 /* IP */ > -#define GREPROTO_PPP 0x880b /* PPTP */ > - > /* source route entry types */ > #define GRESRE_IP 0x0800 /* IP */ > #define GRESRE_ASN 0xfffe /* ASN */ > > +#define NVGRE_VSID_MASK 0xffffff00U > +#define NVGRE_VSID_SHIFT 8 > +#define NVGRE_FLOWID_MASK 0x000000ffU > +#define NVGRE_FLOWID_SHIFT 0 > + > void gre_print_0(const u_char *, u_int); > void gre_print_1(const u_char *, u_int); > void gre_sre_print(u_int16_t, u_int8_t, u_int8_t, const u_char *, u_int); > @@ -82,14 +86,17 @@ gre_print(const u_char *bp, u_int length > } > vers = EXTRACT_16BITS(bp) & GRE_VERS; > > - if (vers == 0) > + switch (vers) { > + case 0: > gre_print_0(bp, len); > - else if (vers == 1) > + break; > + case 1: > gre_print_1(bp, len); > - else > + break; > + default: > printf("gre-unknown-version=%u", vers); > - return; > - > + break; > + } > } > > void > @@ -114,6 +121,8 @@ gre_print_0(const u_char *bp, u_int leng > if (len < 2) > goto trunc; > prot = EXTRACT_16BITS(bp); > + printf("%s", etherproto_string(prot)); > + > len -= 2; > bp += 2; > > @@ -121,21 +130,32 @@ gre_print_0(const u_char *bp, u_int leng > if (len < 2) > goto trunc; > if (vflag) > - printf("sum 0x%x ", EXTRACT_16BITS(bp)); > + printf(" sum 0x%x", EXTRACT_16BITS(bp)); > bp += 2; > len -= 2; > > if (len < 2) > goto trunc; > - printf("off 0x%x ", EXTRACT_16BITS(bp)); > + printf(" off 0x%x", EXTRACT_16BITS(bp)); > bp += 2; > len -= 2; > } > > if (flags & GRE_KP) { > + uint32_t key, vsid; > + > if (len < 4) > goto trunc; > - printf("key=0x%x ", EXTRACT_32BITS(bp)); > + key = EXTRACT_32BITS(bp); > + > + /* maybe NVGRE? */ > + if (flags == (GRE_KP | 0) && prot == ETHERTYPE_TRANSETHER) { > + vsid = (key & NVGRE_VSID_MASK) >> NVGRE_VSID_SHIFT; > + printf(" NVGRE vsid=%u (0x%x)+flowid=0x%02x /", > + vsid, vsid, > + (key & NVGRE_FLOWID_MASK) >> NVGRE_FLOWID_SHIFT); > + } > + printf(" key=%u (0x%x)", key, key); > bp += 4; > len -= 4; > } > @@ -143,7 +163,7 @@ gre_print_0(const u_char *bp, u_int leng > if (flags & GRE_SP) { > if (len < 4) > goto trunc; > - printf("seq %u ", EXTRACT_32BITS(bp)); > + printf(" seq %u", EXTRACT_32BITS(bp)); > bp += 4; > len -= 4; > } > @@ -174,10 +194,21 @@ gre_print_0(const u_char *bp, u_int leng > } > } > > + printf(": "); > + > switch (prot) { > - case GREPROTO_IP: > + case ETHERTYPE_IP: > ip_print(bp, len); > break; > + case ETHERTYPE_IPV6: > + ip6_print(bp, len); > + break; > + case ETHERTYPE_MPLS: > + mpls_print(bp, len); > + break; > + case ETHERTYPE_TRANSETHER: > + ether_print(bp, len); > + break; > default: > printf("gre-proto-0x%x", prot); > } > @@ -198,7 +229,7 @@ gre_print_1(const u_char *bp, u_int leng > bp += 2; > > if (vflag) { > - printf("[%s%s%s%s%s%s] ", > + printf("[%s%s%s%s%s%s]", > (flags & GRE_CP) ? "C" : "", > (flags & GRE_RP) ? "R" : "", > (flags & GRE_KP) ? "K" : "", > @@ -214,19 +245,19 @@ gre_print_1(const u_char *bp, u_int leng > bp += 2; > > if (flags & GRE_CP) { > - printf("cpset!"); > + printf(" cpset!"); > return; > } > if (flags & GRE_RP) { > - printf("rpset!"); > + printf(" rpset!"); > return; > } > if ((flags & GRE_KP) == 0) { > - printf("kpunset!"); > + printf(" kpunset!"); > return; > } > if (flags & GRE_sP) { > - printf("spset!"); > + printf(" spset!"); > return; > } > > @@ -236,7 +267,7 @@ gre_print_1(const u_char *bp, u_int leng > if (len < 4) > goto trunc; > k = EXTRACT_32BITS(bp); > - printf("call %d ", k & 0xffff); > + printf(" call %d", k & 0xffff); > len -= 4; > bp += 4; > } > @@ -244,7 +275,7 @@ gre_print_1(const u_char *bp, u_int leng > if (flags & GRE_SP) { > if (len < 4) > goto trunc; > - printf("seq %u ", EXTRACT_32BITS(bp)); > + printf(" seq %u", EXTRACT_32BITS(bp)); > bp += 4; > len -= 4; > } > @@ -252,18 +283,20 @@ gre_print_1(const u_char *bp, u_int leng > if (flags & GRE_AP) { > if (len < 4) > goto trunc; > - printf("ack %u ", EXTRACT_32BITS(bp)); > + printf(" ack %u", EXTRACT_32BITS(bp)); > bp += 4; > len -= 4; > } > > if ((flags & GRE_SP) == 0) { > - printf("no-payload"); > + printf(" no-payload"); > return; > } > > + printf(": "); > + > switch (prot) { > - case GREPROTO_PPP: > + case ETHERTYPE_PPP: > printf("gre-ppp-payload"); > break; > default: > @@ -282,17 +315,17 @@ gre_sre_print(u_int16_t af, u_int8_t sre > { > switch (af) { > case GRESRE_IP: > - printf("(rtaf=ip"); > + printf(" (rtaf=ip"); > gre_sre_ip_print(sreoff, srelen, bp, len); > - printf(") "); > + printf(")"); > break; > case GRESRE_ASN: > - printf("(rtaf=asn"); > + printf(" (rtaf=asn"); > gre_sre_asn_print(sreoff, srelen, bp, len); > - printf(") "); > + printf(")"); > break; > default: > - printf("(rtaf=0x%x) ", af); > + printf(" (rtaf=0x%x)", af); > } > } > void > Index: print-ip6.c > =================================================================== > RCS file: /cvs/src/usr.sbin/tcpdump/print-ip6.c,v > retrieving revision 1.23 > diff -u -p -r1.23 print-ip6.c > --- print-ip6.c 16 Nov 2015 00:16:39 -0000 1.23 > +++ print-ip6.c 12 Dec 2016 02:48:21 -0000 > @@ -184,6 +184,18 @@ ip6_print(const u_char *bp, u_int length > if (! vflag) > printf(" (encap)"); > goto end; > + > +#ifndef IPPROTO_GRE > +#define IPPROTO_GRE 47 > +#endif > + case IPPROTO_GRE: > + gre_print(cp, len); > + if (! vflag) { > + printf(" (gre encap)"); > + goto out; > + } > + goto end; > + > case IPPROTO_NONE: > (void)printf("no next header"); > goto end; >