3 * The Regents of the University of California. All rights reserved.
5 * Redistribution and use in source and binary forms are permitted
6 * provided that the above copyright notice and this paragraph are
7 * duplicated in all such forms and that any documentation,
8 * advertising materials, and other materials related to such
9 * distribution and use acknowledge that the software was developed
10 * by the University of California, Lawrence Berkeley Laboratory,
11 * Berkeley, CA. The name of the University may not be used to
12 * endorse or promote products derived from this software without
13 * specific prior written permission.
14 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
15 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
16 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
18 * Initial contribution from John Hawkinson <jhawk@bbnplanet.com>
20 * This module implements support for decoding GRE (Generic Routing
21 * Encapsulation) tunnels; they're documented in RFC1701 and RFC1702.
22 * This code only supports the IP encapsulation thereof.
26 static const char rcsid
[] =
27 "@(#) $Header: /tcpdump/master/tcpdump/print-gre.c,v 1.14 2002-06-01 23:50:31 guy Exp $";
34 #include <sys/param.h>
36 #include <sys/socket.h>
38 #include <netinet/in.h>
43 #include "interface.h"
44 #include "addrtoname.h"
45 #include "extract.h" /* must come after interface.h */
53 #define GRE_CP 0x8000 /* Checksum Present */
54 #define GRE_VER_MASK 0x0007 /* Version */
56 /* RFC 2890 - Key and Sequence extensions to GRE */
57 #define GRE_KP 0x2000 /* Key Present */
58 #define GRE_SP 0x1000 /* Sequence Present */
60 /* Legacy from RFC 1700 */
61 #define GRE_RP 0x4000 /* Routing Present */
62 #define GRE_sP 0x0800 /* strict source route present */
63 #define GRE_RECUR_MASK 0x0700 /* Recursion Control */
64 #define GRE_RECUR_SHIFT 8
66 #define GRE_COP (GRE_RP|GRE_CP) /* Checksum & Offset Present */
68 /* "Enhanced GRE" from RFC2637 - PPTP */
69 #define GRE_AP 0x0080 /* Ack present */
71 #define GRE_MBZ_MASK 0x0078 /* not defined */
74 * Deencapsulate and print a GRE-tunneled IP datagram
77 gre_print(const u_char
*bp
, u_int length
)
79 const u_char
*cp
= bp
+ 4;
80 const struct gre
*gre
;
81 u_int16_t flags
, proto
;
83 u_short extracted_ethertype
;
85 gre
= (const struct gre
*)bp
;
88 flags
= EXTRACT_16BITS(&gre
->flags
);
89 proto
= EXTRACT_16BITS(&gre
->proto
);
93 /* Decode the flags */
107 if (flags
& GRE_RECUR_MASK
)
108 printf("R%x", (flags
& GRE_RECUR_MASK
) >> GRE_RECUR_SHIFT
);
109 ver
= flags
& GRE_VER_MASK
;
112 if (flags
& GRE_MBZ_MASK
)
113 printf("!%x", flags
& GRE_MBZ_MASK
);
117 if (flags
& GRE_COP
) {
118 int checksum
, offset
;
121 checksum
= EXTRACT_16BITS(cp
);
122 offset
= EXTRACT_16BITS(cp
+ 2);
124 if (flags
& GRE_CP
) {
125 /* Checksum present */
127 /* todo: check checksum */
129 printf("C:%04x ", checksum
);
131 if (flags
& GRE_RP
) {
135 printf("O:%04x ", offset
);
137 cp
+= 4; /* skip checksum and offset */
139 if (flags
& GRE_KP
) {
141 if (ver
== 1) { /* PPTP */
143 printf("PL:%u ", EXTRACT_16BITS(cp
));
144 printf("ID:%04x ", EXTRACT_16BITS(cp
+2));
147 printf("K:%08x ", EXTRACT_32BITS(cp
));
148 cp
+= 4; /* skip key */
150 if (flags
& GRE_SP
) {
152 printf("S:%u ", EXTRACT_32BITS(cp
));
153 cp
+= 4; /* skip seq */
155 if (flags
& GRE_AP
&& ver
>= 1) {
157 printf("A:%u ", EXTRACT_32BITS(cp
));
158 cp
+= 4; /* skip ack */
160 /* We don't support routing fields (variable length) now. Punt. */
167 if (ether_encap_print(proto
, cp
, length
, length
,
168 &extracted_ethertype
) == 0)
169 printf("gre-proto-0x%04X", proto
);
173 fputs("[|gre]", stdout
);