X-Git-Url: https://git.tcpdump.org/tcpdump/blobdiff_plain/28468a4a829bf63e1b8ec78368ac4f578f853462..ad6df73f5a6c46a409c7629f5588b1b81dff6357:/print-gre.c diff --git a/print-gre.c b/print-gre.c index cf2ba469..aa05dc58 100644 --- a/print-gre.c +++ b/print-gre.c @@ -24,7 +24,7 @@ #ifndef lint static const char rcsid[] = - "@(#) $Header: /tcpdump/master/tcpdump/print-gre.c,v 1.10 2001-02-03 20:21:28 fenner Exp $"; + "@(#) $Header: /tcpdump/master/tcpdump/print-gre.c,v 1.14 2002-06-01 23:50:31 guy Exp $"; #endif #ifdef HAVE_CONFIG_H @@ -33,7 +33,6 @@ static const char rcsid[] = #include #include -#include #include #include @@ -45,31 +44,9 @@ static const char rcsid[] = #include "addrtoname.h" #include "extract.h" /* must come after interface.h */ -#define GRE_SIZE (20) - struct gre { - u_short flags; - u_short proto; - union { - struct gre_ckof { - u_short cksum; - u_short offset; - } gre_ckof; - u_int32_t key; - u_int32_t seq; - } gre_void1; - union { - u_int32_t key; - u_int32_t seq; - u_int32_t routing; - } gre_void2; - union { - u_int32_t seq; - u_int32_t routing; - } gre_void3; - union { - u_int32_t routing; - } gre_void4; + u_int16_t flags; + u_int16_t proto; }; /* RFC 2784 - GRE */ @@ -86,6 +63,8 @@ struct gre { #define GRE_RECUR_MASK 0x0700 /* Recursion Control */ #define GRE_RECUR_SHIFT 8 +#define GRE_COP (GRE_RP|GRE_CP) /* Checksum & Offset Present */ + /* "Enhanced GRE" from RFC2637 - PPTP */ #define GRE_AP 0x0080 /* Ack present */ @@ -93,21 +72,22 @@ struct gre { /* * Deencapsulate and print a GRE-tunneled IP datagram - * - * XXX PPTP needs to interpret the "key" field... */ void gre_print(const u_char *bp, u_int length) { const u_char *cp = bp + 4; const struct gre *gre; - u_short flags, proto, extracted_ethertype; + u_int16_t flags, proto; + u_short ver=0; + u_short extracted_ethertype; gre = (const struct gre *)bp; TCHECK(gre->proto); flags = EXTRACT_16BITS(&gre->flags); proto = EXTRACT_16BITS(&gre->proto); + (void)printf("gre "); if (flags) { /* Decode the flags */ @@ -126,38 +106,60 @@ gre_print(const u_char *bp, u_int length) putchar('A'); if (flags & GRE_RECUR_MASK) printf("R%x", (flags & GRE_RECUR_MASK) >> GRE_RECUR_SHIFT); - if (flags & GRE_VER_MASK) - printf("v%x", flags & GRE_VER_MASK); + ver = flags & GRE_VER_MASK; + printf("v%u", ver); + if (flags & GRE_MBZ_MASK) printf("!%x", flags & GRE_MBZ_MASK); fputs("] ", stdout); } - /* Checksum & Offset are present */ - if ((flags & GRE_CP) | (flags & GRE_RP)) - cp += 4; - /* We don't support routing fields (variable length) now. Punt. */ - if (flags & GRE_RP) - return; + if (flags & GRE_COP) { + int checksum, offset; + TCHECK2(*cp, 4); + checksum = EXTRACT_16BITS(cp); + offset = EXTRACT_16BITS(cp + 2); + + if (flags & GRE_CP) { + /* Checksum present */ + + /* todo: check checksum */ + if (vflag > 1) + printf("C:%04x ", checksum); + } + if (flags & GRE_RP) { + /* Offset present */ + + if (vflag > 1) + printf("O:%04x ", offset); + } + cp += 4; /* skip checksum and offset */ + } if (flags & GRE_KP) { TCHECK2(*cp, 4); - if (vflag > 1) + if (ver == 1) { /* PPTP */ + if (vflag > 1) + printf("PL:%u ", EXTRACT_16BITS(cp)); + printf("ID:%04x ", EXTRACT_16BITS(cp+2)); + } + else printf("K:%08x ", EXTRACT_32BITS(cp)); cp += 4; /* skip key */ } if (flags & GRE_SP) { TCHECK2(*cp, 4); - if (vflag > 1) - printf("S:%08x ", EXTRACT_32BITS(cp)); + printf("S:%u ", EXTRACT_32BITS(cp)); cp += 4; /* skip seq */ } - if (flags & GRE_AP && (flags & GRE_VER_MASK) >= 1) { + if (flags & GRE_AP && ver >= 1) { TCHECK2(*cp, 4); - if (vflag > 1) - printf("A:%08x ", EXTRACT_32BITS(cp)); + printf("A:%u ", EXTRACT_32BITS(cp)); cp += 4; /* skip ack */ } + /* We don't support routing fields (variable length) now. Punt. */ + if (flags & GRE_RP) + return; TCHECK(cp[0]);