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