]> The Tcpdump Group git mirrors - tcpdump/blobdiff - print-gre.c
Get rid of unneeded includes of <netinet/in_systm.h> and <netinet/ip.h>.
[tcpdump] / print-gre.c
index cf2ba469265932a148842f644770fafa6e1be99a..aa05dc588bf1b3cf65d0657a544f91088279e0f3 100644 (file)
@@ -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 <sys/param.h>
 #include <sys/time.h>
-#include <sys/uio.h>
 #include <sys/socket.h>
 
 #include <netinet/in.h>
@@ -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]);