3 /* $OpenBSD: print-gre.c,v 1.6 2002/10/30 03:04:04 fgsch Exp $ */
6 * Copyright (c) 2002 Jason L. Wright (jason@thought.net)
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
17 * 3. All advertising materials mentioning features or use of this software
18 * must display the following acknowledgement:
19 * This product includes software developed by Jason L. Wright
20 * 4. The name of the author may not be used to endorse or promote products
21 * derived from this software without specific prior written permission.
23 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
24 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
25 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
26 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
27 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
28 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
29 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
31 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
32 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
33 * POSSIBILITY OF SUCH DAMAGE.
37 * tcpdump filter for GRE - Generic Routing Encapsulation
38 * RFC1701 (GRE), RFC1702 (GRE IPv4), and RFC2637 (Enhanced GRE)
41 #include <sys/cdefs.h>
44 static const char rcsid
[] _U_
=
45 "@(#) Header: /tcpdump/master/tcpdump/print-gre.c,v 1.28 2005/04/06 21:32:39 mcr Exp (LBL)";
47 __RCSID("$NetBSD: tcpdump2rcsid.ex,v 1.1 2001/06/25 20:09:58 itojun Exp $");
55 #include <tcpdump-stdinc.h>
60 #include "interface.h"
61 #include "addrtoname.h"
65 #include "ethertype.h"
67 #define GRE_CP 0x8000 /* checksum present */
68 #define GRE_RP 0x4000 /* routing present */
69 #define GRE_KP 0x2000 /* key present */
70 #define GRE_SP 0x1000 /* sequence# present */
71 #define GRE_sP 0x0800 /* source routing */
72 #define GRE_RECRS 0x0700 /* recursion count */
73 #define GRE_AP 0x0080 /* acknowledgment# present */
75 struct tok gre_flag_values
[] = {
76 { GRE_CP
, "checksum present"},
77 { GRE_RP
, "routing present"},
78 { GRE_KP
, "key present"},
79 { GRE_SP
, "sequence# present"},
80 { GRE_sP
, "source routing present"},
81 { GRE_RECRS
, "recursion count"},
82 { GRE_AP
, "ack present"},
86 #define GRE_VERS_MASK 0x0007 /* protocol version */
88 /* source route entry types */
89 #define GRESRE_IP 0x0800 /* IP */
90 #define GRESRE_ASN 0xfffe /* ASN */
92 void gre_print_0(const u_char
*, u_int
);
93 void gre_print_1(const u_char
*, u_int
);
94 void gre_sre_print(u_int16_t
, u_int8_t
, u_int8_t
, const u_char
*, u_int
);
95 void gre_sre_ip_print(u_int8_t
, u_int8_t
, const u_char
*, u_int
);
96 void gre_sre_asn_print(u_int8_t
, u_int8_t
, const u_char
*, u_int
);
99 gre_print(const u_char
*bp
, u_int length
)
101 u_int len
= length
, vers
;
107 vers
= EXTRACT_16BITS(bp
) & GRE_VERS_MASK
;
108 printf("GREv%u",vers
);
112 gre_print_0(bp
, len
);
115 gre_print_1(bp
, len
);
118 printf(" ERROR: unknown-version");
126 gre_print_0(const u_char
*bp
, u_int length
)
129 u_int16_t flags
, prot
;
131 flags
= EXTRACT_16BITS(bp
);
133 printf(", Flags [%s]",
134 bittok2str(gre_flag_values
,"none",flags
));
141 prot
= EXTRACT_16BITS(bp
);
145 if ((flags
& GRE_CP
) | (flags
& GRE_RP
)) {
149 printf(", sum 0x%x", EXTRACT_16BITS(bp
));
155 printf(", off 0x%x", EXTRACT_16BITS(bp
));
160 if (flags
& GRE_KP
) {
163 printf(", key=0x%x", EXTRACT_32BITS(bp
));
168 if (flags
& GRE_SP
) {
171 printf(", seq %u", EXTRACT_32BITS(bp
));
176 if (flags
& GRE_RP
) {
184 af
= EXTRACT_16BITS(bp
);
190 if (af
== 0 && srelen
== 0)
193 gre_sre_print(af
, sreoff
, srelen
, bp
, len
);
203 printf(", proto %s (0x%04x)",
204 tok2str(ethertype_values
,"unknown",prot
),
207 printf(", length %u",length
);
210 printf(": "); /* put in a colon as protocol demarc */
212 printf("\n\t"); /* if verbose go multiline */
216 ip_print(gndo
, bp
, len
);
229 case ETHERTYPE_ATALK
:
230 atalk_print(bp
, len
);
232 case ETHERTYPE_GRE_ISO
:
233 isoclns_print(bp
, len
, len
);
236 printf("gre-proto-0x%x", prot
);
245 gre_print_1(const u_char
*bp
, u_int length
)
248 u_int16_t flags
, prot
;
250 flags
= EXTRACT_16BITS(bp
);
255 printf(", Flags [%s]",
256 bittok2str(gre_flag_values
,"none",flags
));
260 prot
= EXTRACT_16BITS(bp
);
265 if (flags
& GRE_KP
) {
270 k
= EXTRACT_32BITS(bp
);
271 printf(", call %d", k
& 0xffff);
276 if (flags
& GRE_SP
) {
279 printf(", seq %u", EXTRACT_32BITS(bp
));
284 if (flags
& GRE_AP
) {
287 printf(", ack %u", EXTRACT_32BITS(bp
));
292 if ((flags
& GRE_SP
) == 0)
293 printf(", no-payload");
296 printf(", proto %s (0x%04x)",
297 tok2str(ethertype_values
,"unknown",prot
),
300 printf(", length %u",length
);
302 if ((flags
& GRE_SP
) == 0)
306 printf(": "); /* put in a colon as protocol demarc */
308 printf("\n\t"); /* if verbose go multiline */
315 printf("gre-proto-0x%x", prot
);
325 gre_sre_print(u_int16_t af
, u_int8_t sreoff
, u_int8_t srelen
,
326 const u_char
*bp
, u_int len
)
330 printf(", (rtaf=ip");
331 gre_sre_ip_print(sreoff
, srelen
, bp
, len
);
335 printf(", (rtaf=asn");
336 gre_sre_asn_print(sreoff
, srelen
, bp
, len
);
340 printf(", (rtaf=0x%x) ", af
);
344 gre_sre_ip_print(u_int8_t sreoff
, u_int8_t srelen
, const u_char
*bp
, u_int len
)
347 const u_char
*up
= bp
;
350 printf(", badoffset=%u", sreoff
);
354 printf(", badlength=%u", srelen
);
357 if (sreoff
>= srelen
) {
358 printf(", badoff/len=%u/%u", sreoff
, srelen
);
363 if (len
< 4 || srelen
== 0)
366 memcpy(&a
, bp
, sizeof(a
));
368 ((bp
- up
) == sreoff
) ? "*" : "",
378 gre_sre_asn_print(u_int8_t sreoff
, u_int8_t srelen
, const u_char
*bp
, u_int len
)
380 const u_char
*up
= bp
;
383 printf(", badoffset=%u", sreoff
);
387 printf(", badlength=%u", srelen
);
390 if (sreoff
>= srelen
) {
391 printf(", badoff/len=%u/%u", sreoff
, srelen
);
396 if (len
< 2 || srelen
== 0)
400 ((bp
- up
) == sreoff
) ? "*" : "",