]> The Tcpdump Group git mirrors - tcpdump/blob - print-gre.c
Initial revision
[tcpdump] / print-gre.c
1 /*
2 * Copyright (c) 1996
3 * The Regents of the University of California. All rights reserved.
4 *
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.
17 *
18 * Initial contribution from John Hawkinson <jhawk@bbnplanet.com>
19 *
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.
23 */
24
25 #ifndef lint
26 static const char rcsid[] =
27 "@(#) $Header: /tcpdump/master/tcpdump/print-gre.c,v 1.4 1999-10-07 23:47:11 mcr Exp $";
28 #endif
29
30 #include <sys/param.h>
31 #include <sys/time.h>
32 #include <sys/uio.h>
33 #include <sys/socket.h>
34
35 #include <netinet/in.h>
36 #include <netinet/in_systm.h>
37 #include <netinet/ip.h>
38
39 #include <netdb.h>
40 #include <stdio.h>
41
42 #include "interface.h"
43 #include "addrtoname.h"
44 #include "extract.h" /* must come after interface.h */
45
46 #define GRE_SIZE (20)
47
48 struct gre {
49 u_short flags;
50 u_short proto;
51 union {
52 struct gre_ckof {
53 u_short cksum;
54 u_short offset;
55 } gre_ckof;
56 u_int32_t key;
57 u_int32_t seq;
58 } gre_void1;
59 union {
60 u_int32_t key;
61 u_int32_t seq;
62 u_int32_t routing;
63 } gre_void2;
64 union {
65 u_int32_t seq;
66 u_int32_t routing;
67 } gre_void3;
68 union {
69 u_int32_t routing;
70 } gre_void4;
71 };
72
73 #define GRE_CP 0x8000 /* Checksum Present */
74 #define GRE_RP 0x4000 /* Routing Present */
75 #define GRE_KP 0x2000 /* Key Present */
76 #define GRE_SP 0x1000 /* Sequence Present */
77
78
79 #define GREPROTO_IP 0x0800
80
81
82 /*
83 * Deencapsulate and print a GRE-tunneled IP datagram
84 */
85 void
86 gre_print(const u_char *bp, u_int length)
87 {
88 const u_char *cp = bp + 4;
89 const struct gre *gre;
90 u_short flags, proto;
91
92 gre = (const struct gre *)bp;
93
94 if (length < GRE_SIZE) {
95 goto trunc;
96 }
97 flags = EXTRACT_16BITS(&gre->flags);
98 proto = EXTRACT_16BITS(&gre->proto);
99
100 if (vflag) {
101 /* Decode the flags */
102 putchar('[');
103 if (flags & GRE_CP)
104 putchar('C');
105 if (flags & GRE_RP)
106 putchar('R');
107 if (flags & GRE_KP)
108 putchar('K');
109 if (flags & GRE_SP)
110 putchar('S');
111 fputs("] ", stdout);
112 }
113 /* Checksum & Offset are present */
114 if ((flags & GRE_CP) | (flags & GRE_RP))
115 cp += 4;
116
117 /* We don't support routing fields (variable length) now. Punt. */
118 if (flags & GRE_RP)
119 return;
120
121 if (flags & GRE_KP)
122 cp += 4;
123 if (flags & GRE_SP)
124 cp += 4;
125
126 switch (proto) {
127
128 case GREPROTO_IP:
129 ip_print(cp, length - ((cp - bp) / sizeof(u_char)));
130 break;
131
132 default:
133 printf("gre-proto-0x%04X", proto);
134 break;
135 }
136 return;
137
138 trunc:
139 fputs("[|gre]", stdout);
140
141 }