]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/tcpdump/print-gre.c
This commit was generated by cvs2svn to compensate for changes in r56915,
[FreeBSD/FreeBSD.git] / contrib / 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.6 1999/11/21 09:36:52 fenner Exp $";
28 #endif
29
30 #ifdef HAVE_CONFIG_H
31 #include "config.h"
32 #endif
33
34 #include <sys/param.h>
35 #include <sys/time.h>
36 #include <sys/uio.h>
37 #include <sys/socket.h>
38
39 #include <netinet/in.h>
40 #include <netinet/in_systm.h>
41 #include <netinet/ip.h>
42
43 #include <netdb.h>
44 #include <stdio.h>
45
46 #include "interface.h"
47 #include "addrtoname.h"
48 #include "extract.h"            /* must come after interface.h */
49
50 #define GRE_SIZE (20)
51
52 struct gre {
53         u_short flags;
54         u_short proto;
55         union {
56                 struct gre_ckof {
57                         u_short cksum;
58                         u_short offset;
59                 }        gre_ckof;
60                 u_int32_t key;
61                 u_int32_t seq;
62         }     gre_void1;
63         union {
64                 u_int32_t key;
65                 u_int32_t seq;
66                 u_int32_t routing;
67         }     gre_void2;
68         union {
69                 u_int32_t seq;
70                 u_int32_t routing;
71         }     gre_void3;
72         union {
73                 u_int32_t routing;
74         }     gre_void4;
75 };
76
77 #define GRE_CP          0x8000  /* Checksum Present */
78 #define GRE_RP          0x4000  /* Routing Present */
79 #define GRE_KP          0x2000  /* Key Present */
80 #define GRE_SP          0x1000  /* Sequence Present */
81
82
83 /*
84  * Deencapsulate and print a GRE-tunneled IP datagram
85  */
86 void
87 gre_print(const u_char *bp, u_int length)
88 {
89         const u_char *cp = bp + 4;
90         const struct gre *gre;
91         u_short flags, proto;
92
93         gre = (const struct gre *)bp;
94
95         if (length < GRE_SIZE) {
96                 goto trunc;
97         }
98         flags = EXTRACT_16BITS(&gre->flags);
99         proto = EXTRACT_16BITS(&gre->proto);
100
101         if (vflag) {
102                 /* Decode the flags */
103                 putchar('[');
104                 if (flags & GRE_CP)
105                         putchar('C');
106                 if (flags & GRE_RP)
107                         putchar('R');
108                 if (flags & GRE_KP)
109                         putchar('K');
110                 if (flags & GRE_SP)
111                         putchar('S');
112                 fputs("] ", stdout);
113         }
114         /* Checksum & Offset are present */
115         if ((flags & GRE_CP) | (flags & GRE_RP))
116                 cp += 4;
117
118         /* We don't support routing fields (variable length) now. Punt. */
119         if (flags & GRE_RP)
120                 return;
121
122         if (flags & GRE_KP)
123                 cp += 4;
124         if (flags & GRE_SP)
125                 cp += 4;
126
127         length -= cp - bp;
128         if (ether_encap_print(proto, cp, length, length) == 0)
129                 printf("gre-proto-0x%04X", proto);
130         return;
131
132 trunc:
133         fputs("[|gre]", stdout);
134
135 }