xref: /minix3/external/bsd/tcpdump/dist/print-gre.c (revision b636d99d91c3d54204248f643c14627405d4afd1)
1*b636d99dSDavid van Moolenbroek /*	$OpenBSD: print-gre.c,v 1.6 2002/10/30 03:04:04 fgsch Exp $	*/
2*b636d99dSDavid van Moolenbroek 
3*b636d99dSDavid van Moolenbroek /*
4*b636d99dSDavid van Moolenbroek  * Copyright (c) 2002 Jason L. Wright (jason@thought.net)
5*b636d99dSDavid van Moolenbroek  * All rights reserved.
6*b636d99dSDavid van Moolenbroek  *
7*b636d99dSDavid van Moolenbroek  * Redistribution and use in source and binary forms, with or without
8*b636d99dSDavid van Moolenbroek  * modification, are permitted provided that the following conditions
9*b636d99dSDavid van Moolenbroek  * are met:
10*b636d99dSDavid van Moolenbroek  * 1. Redistributions of source code must retain the above copyright
11*b636d99dSDavid van Moolenbroek  *    notice, this list of conditions and the following disclaimer.
12*b636d99dSDavid van Moolenbroek  * 2. Redistributions in binary form must reproduce the above copyright
13*b636d99dSDavid van Moolenbroek  *    notice, this list of conditions and the following disclaimer in the
14*b636d99dSDavid van Moolenbroek  *    documentation and/or other materials provided with the distribution.
15*b636d99dSDavid van Moolenbroek  * 3. All advertising materials mentioning features or use of this software
16*b636d99dSDavid van Moolenbroek  *    must display the following acknowledgement:
17*b636d99dSDavid van Moolenbroek  *	This product includes software developed by Jason L. Wright
18*b636d99dSDavid van Moolenbroek  * 4. The name of the author may not be used to endorse or promote products
19*b636d99dSDavid van Moolenbroek  *    derived from this software without specific prior written permission.
20*b636d99dSDavid van Moolenbroek  *
21*b636d99dSDavid van Moolenbroek  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
22*b636d99dSDavid van Moolenbroek  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
23*b636d99dSDavid van Moolenbroek  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
24*b636d99dSDavid van Moolenbroek  * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
25*b636d99dSDavid van Moolenbroek  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
26*b636d99dSDavid van Moolenbroek  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
27*b636d99dSDavid van Moolenbroek  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28*b636d99dSDavid van Moolenbroek  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
29*b636d99dSDavid van Moolenbroek  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
30*b636d99dSDavid van Moolenbroek  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31*b636d99dSDavid van Moolenbroek  * POSSIBILITY OF SUCH DAMAGE.
32*b636d99dSDavid van Moolenbroek  */
33*b636d99dSDavid van Moolenbroek 
34*b636d99dSDavid van Moolenbroek /*
35*b636d99dSDavid van Moolenbroek  * tcpdump filter for GRE - Generic Routing Encapsulation
36*b636d99dSDavid van Moolenbroek  * RFC1701 (GRE), RFC1702 (GRE IPv4), and RFC2637 (Enhanced GRE)
37*b636d99dSDavid van Moolenbroek  */
38*b636d99dSDavid van Moolenbroek 
39*b636d99dSDavid van Moolenbroek #include <sys/cdefs.h>
40*b636d99dSDavid van Moolenbroek #ifndef lint
41*b636d99dSDavid van Moolenbroek __RCSID("$NetBSD: print-gre.c,v 1.6 2015/03/31 21:59:35 christos Exp $");
42*b636d99dSDavid van Moolenbroek #endif
43*b636d99dSDavid van Moolenbroek 
44*b636d99dSDavid van Moolenbroek #define NETDISSECT_REWORKED
45*b636d99dSDavid van Moolenbroek #ifdef HAVE_CONFIG_H
46*b636d99dSDavid van Moolenbroek #include "config.h"
47*b636d99dSDavid van Moolenbroek #endif
48*b636d99dSDavid van Moolenbroek 
49*b636d99dSDavid van Moolenbroek #include <tcpdump-stdinc.h>
50*b636d99dSDavid van Moolenbroek 
51*b636d99dSDavid van Moolenbroek #include <string.h>
52*b636d99dSDavid van Moolenbroek 
53*b636d99dSDavid van Moolenbroek #include "interface.h"
54*b636d99dSDavid van Moolenbroek #include "extract.h"
55*b636d99dSDavid van Moolenbroek #include "ethertype.h"
56*b636d99dSDavid van Moolenbroek 
57*b636d99dSDavid van Moolenbroek static const char tstr[] = "[|gre]";
58*b636d99dSDavid van Moolenbroek 
59*b636d99dSDavid van Moolenbroek #define	GRE_CP		0x8000		/* checksum present */
60*b636d99dSDavid van Moolenbroek #define	GRE_RP		0x4000		/* routing present */
61*b636d99dSDavid van Moolenbroek #define	GRE_KP		0x2000		/* key present */
62*b636d99dSDavid van Moolenbroek #define	GRE_SP		0x1000		/* sequence# present */
63*b636d99dSDavid van Moolenbroek #define	GRE_sP		0x0800		/* source routing */
64*b636d99dSDavid van Moolenbroek #define	GRE_RECRS	0x0700		/* recursion count */
65*b636d99dSDavid van Moolenbroek #define	GRE_AP		0x0080		/* acknowledgment# present */
66*b636d99dSDavid van Moolenbroek 
67*b636d99dSDavid van Moolenbroek static const struct tok gre_flag_values[] = {
68*b636d99dSDavid van Moolenbroek     { GRE_CP, "checksum present"},
69*b636d99dSDavid van Moolenbroek     { GRE_RP, "routing present"},
70*b636d99dSDavid van Moolenbroek     { GRE_KP, "key present"},
71*b636d99dSDavid van Moolenbroek     { GRE_SP, "sequence# present"},
72*b636d99dSDavid van Moolenbroek     { GRE_sP, "source routing present"},
73*b636d99dSDavid van Moolenbroek     { GRE_RECRS, "recursion count"},
74*b636d99dSDavid van Moolenbroek     { GRE_AP, "ack present"},
75*b636d99dSDavid van Moolenbroek     { 0, NULL }
76*b636d99dSDavid van Moolenbroek };
77*b636d99dSDavid van Moolenbroek 
78*b636d99dSDavid van Moolenbroek #define	GRE_VERS_MASK	0x0007		/* protocol version */
79*b636d99dSDavid van Moolenbroek 
80*b636d99dSDavid van Moolenbroek /* source route entry types */
81*b636d99dSDavid van Moolenbroek #define	GRESRE_IP	0x0800		/* IP */
82*b636d99dSDavid van Moolenbroek #define	GRESRE_ASN	0xfffe		/* ASN */
83*b636d99dSDavid van Moolenbroek 
84*b636d99dSDavid van Moolenbroek static void gre_print_0(netdissect_options *, const u_char *, u_int);
85*b636d99dSDavid van Moolenbroek static void gre_print_1(netdissect_options *, const u_char *, u_int);
86*b636d99dSDavid van Moolenbroek static void gre_sre_print(netdissect_options *, uint16_t, uint8_t, uint8_t, const u_char *, u_int);
87*b636d99dSDavid van Moolenbroek static void gre_sre_ip_print(netdissect_options *, uint8_t, uint8_t, const u_char *, u_int);
88*b636d99dSDavid van Moolenbroek static void gre_sre_asn_print(netdissect_options *, uint8_t, uint8_t, const u_char *, u_int);
89*b636d99dSDavid van Moolenbroek 
90*b636d99dSDavid van Moolenbroek void
gre_print(netdissect_options * ndo,const u_char * bp,u_int length)91*b636d99dSDavid van Moolenbroek gre_print(netdissect_options *ndo, const u_char *bp, u_int length)
92*b636d99dSDavid van Moolenbroek {
93*b636d99dSDavid van Moolenbroek 	u_int len = length, vers;
94*b636d99dSDavid van Moolenbroek 
95*b636d99dSDavid van Moolenbroek 	if (len < 2) {
96*b636d99dSDavid van Moolenbroek 		ND_PRINT((ndo, "%s", tstr));
97*b636d99dSDavid van Moolenbroek 		return;
98*b636d99dSDavid van Moolenbroek 	}
99*b636d99dSDavid van Moolenbroek 	vers = EXTRACT_16BITS(bp) & GRE_VERS_MASK;
100*b636d99dSDavid van Moolenbroek         ND_PRINT((ndo, "GREv%u",vers));
101*b636d99dSDavid van Moolenbroek 
102*b636d99dSDavid van Moolenbroek         switch(vers) {
103*b636d99dSDavid van Moolenbroek         case 0:
104*b636d99dSDavid van Moolenbroek             gre_print_0(ndo, bp, len);
105*b636d99dSDavid van Moolenbroek             break;
106*b636d99dSDavid van Moolenbroek         case 1:
107*b636d99dSDavid van Moolenbroek             gre_print_1(ndo, bp, len);
108*b636d99dSDavid van Moolenbroek             break;
109*b636d99dSDavid van Moolenbroek 	default:
110*b636d99dSDavid van Moolenbroek             ND_PRINT((ndo, " ERROR: unknown-version"));
111*b636d99dSDavid van Moolenbroek             break;
112*b636d99dSDavid van Moolenbroek         }
113*b636d99dSDavid van Moolenbroek }
114*b636d99dSDavid van Moolenbroek 
115*b636d99dSDavid van Moolenbroek static void
gre_print_0(netdissect_options * ndo,const u_char * bp,u_int length)116*b636d99dSDavid van Moolenbroek gre_print_0(netdissect_options *ndo, const u_char *bp, u_int length)
117*b636d99dSDavid van Moolenbroek {
118*b636d99dSDavid van Moolenbroek 	u_int len = length;
119*b636d99dSDavid van Moolenbroek 	uint16_t flags, prot;
120*b636d99dSDavid van Moolenbroek 
121*b636d99dSDavid van Moolenbroek 	flags = EXTRACT_16BITS(bp);
122*b636d99dSDavid van Moolenbroek         if (ndo->ndo_vflag)
123*b636d99dSDavid van Moolenbroek             ND_PRINT((ndo, ", Flags [%s]",
124*b636d99dSDavid van Moolenbroek                    bittok2str(gre_flag_values,"none",flags)));
125*b636d99dSDavid van Moolenbroek 
126*b636d99dSDavid van Moolenbroek 	len -= 2;
127*b636d99dSDavid van Moolenbroek 	bp += 2;
128*b636d99dSDavid van Moolenbroek 
129*b636d99dSDavid van Moolenbroek 	if (len < 2)
130*b636d99dSDavid van Moolenbroek 		goto trunc;
131*b636d99dSDavid van Moolenbroek 	prot = EXTRACT_16BITS(bp);
132*b636d99dSDavid van Moolenbroek 	len -= 2;
133*b636d99dSDavid van Moolenbroek 	bp += 2;
134*b636d99dSDavid van Moolenbroek 
135*b636d99dSDavid van Moolenbroek 	if ((flags & GRE_CP) | (flags & GRE_RP)) {
136*b636d99dSDavid van Moolenbroek 		if (len < 2)
137*b636d99dSDavid van Moolenbroek 			goto trunc;
138*b636d99dSDavid van Moolenbroek 		if (ndo->ndo_vflag)
139*b636d99dSDavid van Moolenbroek 			ND_PRINT((ndo, ", sum 0x%x", EXTRACT_16BITS(bp)));
140*b636d99dSDavid van Moolenbroek 		bp += 2;
141*b636d99dSDavid van Moolenbroek 		len -= 2;
142*b636d99dSDavid van Moolenbroek 
143*b636d99dSDavid van Moolenbroek 		if (len < 2)
144*b636d99dSDavid van Moolenbroek 			goto trunc;
145*b636d99dSDavid van Moolenbroek 		ND_PRINT((ndo, ", off 0x%x", EXTRACT_16BITS(bp)));
146*b636d99dSDavid van Moolenbroek 		bp += 2;
147*b636d99dSDavid van Moolenbroek 		len -= 2;
148*b636d99dSDavid van Moolenbroek 	}
149*b636d99dSDavid van Moolenbroek 
150*b636d99dSDavid van Moolenbroek 	if (flags & GRE_KP) {
151*b636d99dSDavid van Moolenbroek 		if (len < 4)
152*b636d99dSDavid van Moolenbroek 			goto trunc;
153*b636d99dSDavid van Moolenbroek 		ND_PRINT((ndo, ", key=0x%x", EXTRACT_32BITS(bp)));
154*b636d99dSDavid van Moolenbroek 		bp += 4;
155*b636d99dSDavid van Moolenbroek 		len -= 4;
156*b636d99dSDavid van Moolenbroek 	}
157*b636d99dSDavid van Moolenbroek 
158*b636d99dSDavid van Moolenbroek 	if (flags & GRE_SP) {
159*b636d99dSDavid van Moolenbroek 		if (len < 4)
160*b636d99dSDavid van Moolenbroek 			goto trunc;
161*b636d99dSDavid van Moolenbroek 		ND_PRINT((ndo, ", seq %u", EXTRACT_32BITS(bp)));
162*b636d99dSDavid van Moolenbroek 		bp += 4;
163*b636d99dSDavid van Moolenbroek 		len -= 4;
164*b636d99dSDavid van Moolenbroek 	}
165*b636d99dSDavid van Moolenbroek 
166*b636d99dSDavid van Moolenbroek 	if (flags & GRE_RP) {
167*b636d99dSDavid van Moolenbroek 		for (;;) {
168*b636d99dSDavid van Moolenbroek 			uint16_t af;
169*b636d99dSDavid van Moolenbroek 			uint8_t sreoff;
170*b636d99dSDavid van Moolenbroek 			uint8_t srelen;
171*b636d99dSDavid van Moolenbroek 
172*b636d99dSDavid van Moolenbroek 			if (len < 4)
173*b636d99dSDavid van Moolenbroek 				goto trunc;
174*b636d99dSDavid van Moolenbroek 			af = EXTRACT_16BITS(bp);
175*b636d99dSDavid van Moolenbroek 			sreoff = *(bp + 2);
176*b636d99dSDavid van Moolenbroek 			srelen = *(bp + 3);
177*b636d99dSDavid van Moolenbroek 			bp += 4;
178*b636d99dSDavid van Moolenbroek 			len -= 4;
179*b636d99dSDavid van Moolenbroek 
180*b636d99dSDavid van Moolenbroek 			if (af == 0 && srelen == 0)
181*b636d99dSDavid van Moolenbroek 				break;
182*b636d99dSDavid van Moolenbroek 
183*b636d99dSDavid van Moolenbroek 			gre_sre_print(ndo, af, sreoff, srelen, bp, len);
184*b636d99dSDavid van Moolenbroek 
185*b636d99dSDavid van Moolenbroek 			if (len < srelen)
186*b636d99dSDavid van Moolenbroek 				goto trunc;
187*b636d99dSDavid van Moolenbroek 			bp += srelen;
188*b636d99dSDavid van Moolenbroek 			len -= srelen;
189*b636d99dSDavid van Moolenbroek 		}
190*b636d99dSDavid van Moolenbroek 	}
191*b636d99dSDavid van Moolenbroek 
192*b636d99dSDavid van Moolenbroek         if (ndo->ndo_eflag)
193*b636d99dSDavid van Moolenbroek             ND_PRINT((ndo, ", proto %s (0x%04x)",
194*b636d99dSDavid van Moolenbroek                    tok2str(ethertype_values,"unknown",prot),
195*b636d99dSDavid van Moolenbroek                    prot));
196*b636d99dSDavid van Moolenbroek 
197*b636d99dSDavid van Moolenbroek         ND_PRINT((ndo, ", length %u",length));
198*b636d99dSDavid van Moolenbroek 
199*b636d99dSDavid van Moolenbroek         if (ndo->ndo_vflag < 1)
200*b636d99dSDavid van Moolenbroek             ND_PRINT((ndo, ": ")); /* put in a colon as protocol demarc */
201*b636d99dSDavid van Moolenbroek         else
202*b636d99dSDavid van Moolenbroek             ND_PRINT((ndo, "\n\t")); /* if verbose go multiline */
203*b636d99dSDavid van Moolenbroek 
204*b636d99dSDavid van Moolenbroek 	switch (prot) {
205*b636d99dSDavid van Moolenbroek 	case ETHERTYPE_IP:
206*b636d99dSDavid van Moolenbroek 	        ip_print(ndo, bp, len);
207*b636d99dSDavid van Moolenbroek 		break;
208*b636d99dSDavid van Moolenbroek 	case ETHERTYPE_IPV6:
209*b636d99dSDavid van Moolenbroek 		ip6_print(ndo, bp, len);
210*b636d99dSDavid van Moolenbroek 		break;
211*b636d99dSDavid van Moolenbroek 	case ETHERTYPE_MPLS:
212*b636d99dSDavid van Moolenbroek 		mpls_print(ndo, bp, len);
213*b636d99dSDavid van Moolenbroek 		break;
214*b636d99dSDavid van Moolenbroek 	case ETHERTYPE_IPX:
215*b636d99dSDavid van Moolenbroek 		ipx_print(ndo, bp, len);
216*b636d99dSDavid van Moolenbroek 		break;
217*b636d99dSDavid van Moolenbroek 	case ETHERTYPE_ATALK:
218*b636d99dSDavid van Moolenbroek 		atalk_print(ndo, bp, len);
219*b636d99dSDavid van Moolenbroek 		break;
220*b636d99dSDavid van Moolenbroek 	case ETHERTYPE_GRE_ISO:
221*b636d99dSDavid van Moolenbroek 		isoclns_print(ndo, bp, len, len);
222*b636d99dSDavid van Moolenbroek 		break;
223*b636d99dSDavid van Moolenbroek 	case ETHERTYPE_TEB:
224*b636d99dSDavid van Moolenbroek 		ether_print(ndo, bp, len, len, NULL, NULL);
225*b636d99dSDavid van Moolenbroek 		break;
226*b636d99dSDavid van Moolenbroek 	default:
227*b636d99dSDavid van Moolenbroek 		ND_PRINT((ndo, "gre-proto-0x%x", prot));
228*b636d99dSDavid van Moolenbroek 	}
229*b636d99dSDavid van Moolenbroek 	return;
230*b636d99dSDavid van Moolenbroek 
231*b636d99dSDavid van Moolenbroek trunc:
232*b636d99dSDavid van Moolenbroek 	ND_PRINT((ndo, "%s", tstr));
233*b636d99dSDavid van Moolenbroek }
234*b636d99dSDavid van Moolenbroek 
235*b636d99dSDavid van Moolenbroek static void
gre_print_1(netdissect_options * ndo,const u_char * bp,u_int length)236*b636d99dSDavid van Moolenbroek gre_print_1(netdissect_options *ndo, const u_char *bp, u_int length)
237*b636d99dSDavid van Moolenbroek {
238*b636d99dSDavid van Moolenbroek 	u_int len = length;
239*b636d99dSDavid van Moolenbroek 	uint16_t flags, prot;
240*b636d99dSDavid van Moolenbroek 
241*b636d99dSDavid van Moolenbroek 	flags = EXTRACT_16BITS(bp);
242*b636d99dSDavid van Moolenbroek 	len -= 2;
243*b636d99dSDavid van Moolenbroek 	bp += 2;
244*b636d99dSDavid van Moolenbroek 
245*b636d99dSDavid van Moolenbroek 	if (ndo->ndo_vflag)
246*b636d99dSDavid van Moolenbroek             ND_PRINT((ndo, ", Flags [%s]",
247*b636d99dSDavid van Moolenbroek                    bittok2str(gre_flag_values,"none",flags)));
248*b636d99dSDavid van Moolenbroek 
249*b636d99dSDavid van Moolenbroek 	if (len < 2)
250*b636d99dSDavid van Moolenbroek 		goto trunc;
251*b636d99dSDavid van Moolenbroek 	prot = EXTRACT_16BITS(bp);
252*b636d99dSDavid van Moolenbroek 	len -= 2;
253*b636d99dSDavid van Moolenbroek 	bp += 2;
254*b636d99dSDavid van Moolenbroek 
255*b636d99dSDavid van Moolenbroek 
256*b636d99dSDavid van Moolenbroek 	if (flags & GRE_KP) {
257*b636d99dSDavid van Moolenbroek 		uint32_t k;
258*b636d99dSDavid van Moolenbroek 
259*b636d99dSDavid van Moolenbroek 		if (len < 4)
260*b636d99dSDavid van Moolenbroek 			goto trunc;
261*b636d99dSDavid van Moolenbroek 		k = EXTRACT_32BITS(bp);
262*b636d99dSDavid van Moolenbroek 		ND_PRINT((ndo, ", call %d", k & 0xffff));
263*b636d99dSDavid van Moolenbroek 		len -= 4;
264*b636d99dSDavid van Moolenbroek 		bp += 4;
265*b636d99dSDavid van Moolenbroek 	}
266*b636d99dSDavid van Moolenbroek 
267*b636d99dSDavid van Moolenbroek 	if (flags & GRE_SP) {
268*b636d99dSDavid van Moolenbroek 		if (len < 4)
269*b636d99dSDavid van Moolenbroek 			goto trunc;
270*b636d99dSDavid van Moolenbroek 		ND_PRINT((ndo, ", seq %u", EXTRACT_32BITS(bp)));
271*b636d99dSDavid van Moolenbroek 		bp += 4;
272*b636d99dSDavid van Moolenbroek 		len -= 4;
273*b636d99dSDavid van Moolenbroek 	}
274*b636d99dSDavid van Moolenbroek 
275*b636d99dSDavid van Moolenbroek 	if (flags & GRE_AP) {
276*b636d99dSDavid van Moolenbroek 		if (len < 4)
277*b636d99dSDavid van Moolenbroek 			goto trunc;
278*b636d99dSDavid van Moolenbroek 		ND_PRINT((ndo, ", ack %u", EXTRACT_32BITS(bp)));
279*b636d99dSDavid van Moolenbroek 		bp += 4;
280*b636d99dSDavid van Moolenbroek 		len -= 4;
281*b636d99dSDavid van Moolenbroek 	}
282*b636d99dSDavid van Moolenbroek 
283*b636d99dSDavid van Moolenbroek 	if ((flags & GRE_SP) == 0)
284*b636d99dSDavid van Moolenbroek 		ND_PRINT((ndo, ", no-payload"));
285*b636d99dSDavid van Moolenbroek 
286*b636d99dSDavid van Moolenbroek         if (ndo->ndo_eflag)
287*b636d99dSDavid van Moolenbroek             ND_PRINT((ndo, ", proto %s (0x%04x)",
288*b636d99dSDavid van Moolenbroek                    tok2str(ethertype_values,"unknown",prot),
289*b636d99dSDavid van Moolenbroek                    prot));
290*b636d99dSDavid van Moolenbroek 
291*b636d99dSDavid van Moolenbroek         ND_PRINT((ndo, ", length %u",length));
292*b636d99dSDavid van Moolenbroek 
293*b636d99dSDavid van Moolenbroek         if ((flags & GRE_SP) == 0)
294*b636d99dSDavid van Moolenbroek             return;
295*b636d99dSDavid van Moolenbroek 
296*b636d99dSDavid van Moolenbroek         if (ndo->ndo_vflag < 1)
297*b636d99dSDavid van Moolenbroek             ND_PRINT((ndo, ": ")); /* put in a colon as protocol demarc */
298*b636d99dSDavid van Moolenbroek         else
299*b636d99dSDavid van Moolenbroek             ND_PRINT((ndo, "\n\t")); /* if verbose go multiline */
300*b636d99dSDavid van Moolenbroek 
301*b636d99dSDavid van Moolenbroek 	switch (prot) {
302*b636d99dSDavid van Moolenbroek 	case ETHERTYPE_PPP:
303*b636d99dSDavid van Moolenbroek 		ppp_print(ndo, bp, len);
304*b636d99dSDavid van Moolenbroek 		break;
305*b636d99dSDavid van Moolenbroek 	default:
306*b636d99dSDavid van Moolenbroek 		ND_PRINT((ndo, "gre-proto-0x%x", prot));
307*b636d99dSDavid van Moolenbroek 		break;
308*b636d99dSDavid van Moolenbroek 	}
309*b636d99dSDavid van Moolenbroek 	return;
310*b636d99dSDavid van Moolenbroek 
311*b636d99dSDavid van Moolenbroek trunc:
312*b636d99dSDavid van Moolenbroek 	ND_PRINT((ndo, "%s", tstr));
313*b636d99dSDavid van Moolenbroek }
314*b636d99dSDavid van Moolenbroek 
315*b636d99dSDavid van Moolenbroek static void
gre_sre_print(netdissect_options * ndo,uint16_t af,uint8_t sreoff,uint8_t srelen,const u_char * bp,u_int len)316*b636d99dSDavid van Moolenbroek gre_sre_print(netdissect_options *ndo, uint16_t af, uint8_t sreoff,
317*b636d99dSDavid van Moolenbroek     uint8_t srelen, const u_char *bp, u_int len)
318*b636d99dSDavid van Moolenbroek {
319*b636d99dSDavid van Moolenbroek 	switch (af) {
320*b636d99dSDavid van Moolenbroek 	case GRESRE_IP:
321*b636d99dSDavid van Moolenbroek 		ND_PRINT((ndo, ", (rtaf=ip"));
322*b636d99dSDavid van Moolenbroek 		gre_sre_ip_print(ndo, sreoff, srelen, bp, len);
323*b636d99dSDavid van Moolenbroek 		ND_PRINT((ndo, ") "));
324*b636d99dSDavid van Moolenbroek 		break;
325*b636d99dSDavid van Moolenbroek 	case GRESRE_ASN:
326*b636d99dSDavid van Moolenbroek 		ND_PRINT((ndo, ", (rtaf=asn"));
327*b636d99dSDavid van Moolenbroek 		gre_sre_asn_print(ndo, sreoff, srelen, bp, len);
328*b636d99dSDavid van Moolenbroek 		ND_PRINT((ndo, ") "));
329*b636d99dSDavid van Moolenbroek 		break;
330*b636d99dSDavid van Moolenbroek 	default:
331*b636d99dSDavid van Moolenbroek 		ND_PRINT((ndo, ", (rtaf=0x%x) ", af));
332*b636d99dSDavid van Moolenbroek 	}
333*b636d99dSDavid van Moolenbroek }
334*b636d99dSDavid van Moolenbroek 
335*b636d99dSDavid van Moolenbroek static void
gre_sre_ip_print(netdissect_options * ndo,uint8_t sreoff,uint8_t srelen,const u_char * bp,u_int len)336*b636d99dSDavid van Moolenbroek gre_sre_ip_print(netdissect_options *ndo, uint8_t sreoff, uint8_t srelen,
337*b636d99dSDavid van Moolenbroek                  const u_char *bp, u_int len)
338*b636d99dSDavid van Moolenbroek {
339*b636d99dSDavid van Moolenbroek 	struct in_addr a;
340*b636d99dSDavid van Moolenbroek 	const u_char *up = bp;
341*b636d99dSDavid van Moolenbroek 
342*b636d99dSDavid van Moolenbroek 	if (sreoff & 3) {
343*b636d99dSDavid van Moolenbroek 		ND_PRINT((ndo, ", badoffset=%u", sreoff));
344*b636d99dSDavid van Moolenbroek 		return;
345*b636d99dSDavid van Moolenbroek 	}
346*b636d99dSDavid van Moolenbroek 	if (srelen & 3) {
347*b636d99dSDavid van Moolenbroek 		ND_PRINT((ndo, ", badlength=%u", srelen));
348*b636d99dSDavid van Moolenbroek 		return;
349*b636d99dSDavid van Moolenbroek 	}
350*b636d99dSDavid van Moolenbroek 	if (sreoff >= srelen) {
351*b636d99dSDavid van Moolenbroek 		ND_PRINT((ndo, ", badoff/len=%u/%u", sreoff, srelen));
352*b636d99dSDavid van Moolenbroek 		return;
353*b636d99dSDavid van Moolenbroek 	}
354*b636d99dSDavid van Moolenbroek 
355*b636d99dSDavid van Moolenbroek 	for (;;) {
356*b636d99dSDavid van Moolenbroek 		if (len < 4 || srelen == 0)
357*b636d99dSDavid van Moolenbroek 			return;
358*b636d99dSDavid van Moolenbroek 
359*b636d99dSDavid van Moolenbroek 		memcpy(&a, bp, sizeof(a));
360*b636d99dSDavid van Moolenbroek 		ND_PRINT((ndo, " %s%s",
361*b636d99dSDavid van Moolenbroek 		    ((bp - up) == sreoff) ? "*" : "",
362*b636d99dSDavid van Moolenbroek 		    inet_ntoa(a)));
363*b636d99dSDavid van Moolenbroek 
364*b636d99dSDavid van Moolenbroek 		bp += 4;
365*b636d99dSDavid van Moolenbroek 		len -= 4;
366*b636d99dSDavid van Moolenbroek 		srelen -= 4;
367*b636d99dSDavid van Moolenbroek 	}
368*b636d99dSDavid van Moolenbroek }
369*b636d99dSDavid van Moolenbroek 
370*b636d99dSDavid van Moolenbroek static void
gre_sre_asn_print(netdissect_options * ndo,uint8_t sreoff,uint8_t srelen,const u_char * bp,u_int len)371*b636d99dSDavid van Moolenbroek gre_sre_asn_print(netdissect_options *ndo, uint8_t sreoff, uint8_t srelen,
372*b636d99dSDavid van Moolenbroek                   const u_char *bp, u_int len)
373*b636d99dSDavid van Moolenbroek {
374*b636d99dSDavid van Moolenbroek 	const u_char *up = bp;
375*b636d99dSDavid van Moolenbroek 
376*b636d99dSDavid van Moolenbroek 	if (sreoff & 1) {
377*b636d99dSDavid van Moolenbroek 		ND_PRINT((ndo, ", badoffset=%u", sreoff));
378*b636d99dSDavid van Moolenbroek 		return;
379*b636d99dSDavid van Moolenbroek 	}
380*b636d99dSDavid van Moolenbroek 	if (srelen & 1) {
381*b636d99dSDavid van Moolenbroek 		ND_PRINT((ndo, ", badlength=%u", srelen));
382*b636d99dSDavid van Moolenbroek 		return;
383*b636d99dSDavid van Moolenbroek 	}
384*b636d99dSDavid van Moolenbroek 	if (sreoff >= srelen) {
385*b636d99dSDavid van Moolenbroek 		ND_PRINT((ndo, ", badoff/len=%u/%u", sreoff, srelen));
386*b636d99dSDavid van Moolenbroek 		return;
387*b636d99dSDavid van Moolenbroek 	}
388*b636d99dSDavid van Moolenbroek 
389*b636d99dSDavid van Moolenbroek 	for (;;) {
390*b636d99dSDavid van Moolenbroek 		if (len < 2 || srelen == 0)
391*b636d99dSDavid van Moolenbroek 			return;
392*b636d99dSDavid van Moolenbroek 
393*b636d99dSDavid van Moolenbroek 		ND_PRINT((ndo, " %s%x",
394*b636d99dSDavid van Moolenbroek 		    ((bp - up) == sreoff) ? "*" : "",
395*b636d99dSDavid van Moolenbroek 		    EXTRACT_16BITS(bp)));
396*b636d99dSDavid van Moolenbroek 
397*b636d99dSDavid van Moolenbroek 		bp += 2;
398*b636d99dSDavid van Moolenbroek 		len -= 2;
399*b636d99dSDavid van Moolenbroek 		srelen -= 2;
400*b636d99dSDavid van Moolenbroek 	}
401*b636d99dSDavid van Moolenbroek }
402