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