xref: /minix3/external/bsd/tcpdump/dist/print-dvmrp.c (revision b636d99d91c3d54204248f643c14627405d4afd1)
1*b636d99dSDavid van Moolenbroek /*
2*b636d99dSDavid van Moolenbroek  * Copyright (c) 1995, 1996
3*b636d99dSDavid van Moolenbroek  *	The Regents of the University of California.  All rights reserved.
4*b636d99dSDavid van Moolenbroek  *
5*b636d99dSDavid van Moolenbroek  * Redistribution and use in source and binary forms, with or without
6*b636d99dSDavid van Moolenbroek  * modification, are permitted provided that: (1) source code distributions
7*b636d99dSDavid van Moolenbroek  * retain the above copyright notice and this paragraph in its entirety, (2)
8*b636d99dSDavid van Moolenbroek  * distributions including binary code include the above copyright notice and
9*b636d99dSDavid van Moolenbroek  * this paragraph in its entirety in the documentation or other materials
10*b636d99dSDavid van Moolenbroek  * provided with the distribution, and (3) all advertising materials mentioning
11*b636d99dSDavid van Moolenbroek  * features or use of this software display the following acknowledgement:
12*b636d99dSDavid van Moolenbroek  * ``This product includes software developed by the University of California,
13*b636d99dSDavid van Moolenbroek  * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
14*b636d99dSDavid van Moolenbroek  * the University nor the names of its contributors may be used to endorse
15*b636d99dSDavid van Moolenbroek  * or promote products derived from this software without specific prior
16*b636d99dSDavid van Moolenbroek  * written permission.
17*b636d99dSDavid van Moolenbroek  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
18*b636d99dSDavid van Moolenbroek  * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
19*b636d99dSDavid van Moolenbroek  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
20*b636d99dSDavid van Moolenbroek  */
21*b636d99dSDavid van Moolenbroek 
22*b636d99dSDavid van Moolenbroek #include <sys/cdefs.h>
23*b636d99dSDavid van Moolenbroek #ifndef lint
24*b636d99dSDavid van Moolenbroek __RCSID("$NetBSD: print-dvmrp.c,v 1.4 2014/11/20 03:05:03 christos Exp $");
25*b636d99dSDavid van Moolenbroek #endif
26*b636d99dSDavid van Moolenbroek 
27*b636d99dSDavid van Moolenbroek #define NETDISSECT_REWORKED
28*b636d99dSDavid van Moolenbroek #ifdef HAVE_CONFIG_H
29*b636d99dSDavid van Moolenbroek #include "config.h"
30*b636d99dSDavid van Moolenbroek #endif
31*b636d99dSDavid van Moolenbroek 
32*b636d99dSDavid van Moolenbroek #include <tcpdump-stdinc.h>
33*b636d99dSDavid van Moolenbroek 
34*b636d99dSDavid van Moolenbroek #include "interface.h"
35*b636d99dSDavid van Moolenbroek #include "extract.h"
36*b636d99dSDavid van Moolenbroek #include "addrtoname.h"
37*b636d99dSDavid van Moolenbroek 
38*b636d99dSDavid van Moolenbroek /*
39*b636d99dSDavid van Moolenbroek  * DVMRP message types and flag values shamelessly stolen from
40*b636d99dSDavid van Moolenbroek  * mrouted/dvmrp.h.
41*b636d99dSDavid van Moolenbroek  */
42*b636d99dSDavid van Moolenbroek #define DVMRP_PROBE		1	/* for finding neighbors */
43*b636d99dSDavid van Moolenbroek #define DVMRP_REPORT		2	/* for reporting some or all routes */
44*b636d99dSDavid van Moolenbroek #define DVMRP_ASK_NEIGHBORS	3	/* sent by mapper, asking for a list */
45*b636d99dSDavid van Moolenbroek 					/* of this router's neighbors */
46*b636d99dSDavid van Moolenbroek #define DVMRP_NEIGHBORS		4	/* response to such a request */
47*b636d99dSDavid van Moolenbroek #define DVMRP_ASK_NEIGHBORS2	5	/* as above, want new format reply */
48*b636d99dSDavid van Moolenbroek #define DVMRP_NEIGHBORS2	6
49*b636d99dSDavid van Moolenbroek #define DVMRP_PRUNE		7	/* prune message */
50*b636d99dSDavid van Moolenbroek #define DVMRP_GRAFT		8	/* graft message */
51*b636d99dSDavid van Moolenbroek #define DVMRP_GRAFT_ACK		9	/* graft acknowledgement */
52*b636d99dSDavid van Moolenbroek 
53*b636d99dSDavid van Moolenbroek /*
54*b636d99dSDavid van Moolenbroek  * 'flags' byte values in DVMRP_NEIGHBORS2 reply.
55*b636d99dSDavid van Moolenbroek  */
56*b636d99dSDavid van Moolenbroek #define DVMRP_NF_TUNNEL		0x01	/* neighbors reached via tunnel */
57*b636d99dSDavid van Moolenbroek #define DVMRP_NF_SRCRT		0x02	/* tunnel uses IP source routing */
58*b636d99dSDavid van Moolenbroek #define DVMRP_NF_DOWN		0x10	/* kernel state of interface */
59*b636d99dSDavid van Moolenbroek #define DVMRP_NF_DISABLED	0x20	/* administratively disabled */
60*b636d99dSDavid van Moolenbroek #define DVMRP_NF_QUERIER	0x40	/* I am the subnet's querier */
61*b636d99dSDavid van Moolenbroek 
62*b636d99dSDavid van Moolenbroek static int print_probe(netdissect_options *, const u_char *, const u_char *, u_int);
63*b636d99dSDavid van Moolenbroek static int print_report(netdissect_options *, const u_char *, const u_char *, u_int);
64*b636d99dSDavid van Moolenbroek static int print_neighbors(netdissect_options *, const u_char *, const u_char *, u_int);
65*b636d99dSDavid van Moolenbroek static int print_neighbors2(netdissect_options *, const u_char *, const u_char *, u_int);
66*b636d99dSDavid van Moolenbroek static int print_prune(netdissect_options *, const u_char *);
67*b636d99dSDavid van Moolenbroek static int print_graft(netdissect_options *, const u_char *);
68*b636d99dSDavid van Moolenbroek static int print_graft_ack(netdissect_options *, const u_char *);
69*b636d99dSDavid van Moolenbroek 
70*b636d99dSDavid van Moolenbroek static uint32_t target_level;
71*b636d99dSDavid van Moolenbroek 
72*b636d99dSDavid van Moolenbroek void
dvmrp_print(netdissect_options * ndo,register const u_char * bp,register u_int len)73*b636d99dSDavid van Moolenbroek dvmrp_print(netdissect_options *ndo,
74*b636d99dSDavid van Moolenbroek             register const u_char *bp, register u_int len)
75*b636d99dSDavid van Moolenbroek {
76*b636d99dSDavid van Moolenbroek 	register const u_char *ep;
77*b636d99dSDavid van Moolenbroek 	register u_char type;
78*b636d99dSDavid van Moolenbroek 
79*b636d99dSDavid van Moolenbroek 	ep = (const u_char *)ndo->ndo_snapend;
80*b636d99dSDavid van Moolenbroek 	if (bp >= ep)
81*b636d99dSDavid van Moolenbroek 		return;
82*b636d99dSDavid van Moolenbroek 
83*b636d99dSDavid van Moolenbroek 	ND_TCHECK(bp[1]);
84*b636d99dSDavid van Moolenbroek 	type = bp[1];
85*b636d99dSDavid van Moolenbroek 
86*b636d99dSDavid van Moolenbroek 	/* Skip IGMP header */
87*b636d99dSDavid van Moolenbroek 	bp += 8;
88*b636d99dSDavid van Moolenbroek 	len -= 8;
89*b636d99dSDavid van Moolenbroek 
90*b636d99dSDavid van Moolenbroek 	switch (type) {
91*b636d99dSDavid van Moolenbroek 
92*b636d99dSDavid van Moolenbroek 	case DVMRP_PROBE:
93*b636d99dSDavid van Moolenbroek 		ND_PRINT((ndo, " Probe"));
94*b636d99dSDavid van Moolenbroek 		if (ndo->ndo_vflag) {
95*b636d99dSDavid van Moolenbroek 			if (print_probe(ndo, bp, ep, len) < 0)
96*b636d99dSDavid van Moolenbroek 				goto trunc;
97*b636d99dSDavid van Moolenbroek 		}
98*b636d99dSDavid van Moolenbroek 		break;
99*b636d99dSDavid van Moolenbroek 
100*b636d99dSDavid van Moolenbroek 	case DVMRP_REPORT:
101*b636d99dSDavid van Moolenbroek 		ND_PRINT((ndo, " Report"));
102*b636d99dSDavid van Moolenbroek 		if (ndo->ndo_vflag > 1) {
103*b636d99dSDavid van Moolenbroek 			if (print_report(ndo, bp, ep, len) < 0)
104*b636d99dSDavid van Moolenbroek 				goto trunc;
105*b636d99dSDavid van Moolenbroek 		}
106*b636d99dSDavid van Moolenbroek 		break;
107*b636d99dSDavid van Moolenbroek 
108*b636d99dSDavid van Moolenbroek 	case DVMRP_ASK_NEIGHBORS:
109*b636d99dSDavid van Moolenbroek 		ND_PRINT((ndo, " Ask-neighbors(old)"));
110*b636d99dSDavid van Moolenbroek 		break;
111*b636d99dSDavid van Moolenbroek 
112*b636d99dSDavid van Moolenbroek 	case DVMRP_NEIGHBORS:
113*b636d99dSDavid van Moolenbroek 		ND_PRINT((ndo, " Neighbors(old)"));
114*b636d99dSDavid van Moolenbroek 		if (print_neighbors(ndo, bp, ep, len) < 0)
115*b636d99dSDavid van Moolenbroek 			goto trunc;
116*b636d99dSDavid van Moolenbroek 		break;
117*b636d99dSDavid van Moolenbroek 
118*b636d99dSDavid van Moolenbroek 	case DVMRP_ASK_NEIGHBORS2:
119*b636d99dSDavid van Moolenbroek 		ND_PRINT((ndo, " Ask-neighbors2"));
120*b636d99dSDavid van Moolenbroek 		break;
121*b636d99dSDavid van Moolenbroek 
122*b636d99dSDavid van Moolenbroek 	case DVMRP_NEIGHBORS2:
123*b636d99dSDavid van Moolenbroek 		ND_PRINT((ndo, " Neighbors2"));
124*b636d99dSDavid van Moolenbroek 		/*
125*b636d99dSDavid van Moolenbroek 		 * extract version and capabilities from IGMP group
126*b636d99dSDavid van Moolenbroek 		 * address field
127*b636d99dSDavid van Moolenbroek 		 */
128*b636d99dSDavid van Moolenbroek 		bp -= 4;
129*b636d99dSDavid van Moolenbroek 		ND_TCHECK2(bp[0], 4);
130*b636d99dSDavid van Moolenbroek 		target_level = (bp[0] << 24) | (bp[1] << 16) |
131*b636d99dSDavid van Moolenbroek 		    (bp[2] << 8) | bp[3];
132*b636d99dSDavid van Moolenbroek 		bp += 4;
133*b636d99dSDavid van Moolenbroek 		if (print_neighbors2(ndo, bp, ep, len) < 0)
134*b636d99dSDavid van Moolenbroek 			goto trunc;
135*b636d99dSDavid van Moolenbroek 		break;
136*b636d99dSDavid van Moolenbroek 
137*b636d99dSDavid van Moolenbroek 	case DVMRP_PRUNE:
138*b636d99dSDavid van Moolenbroek 		ND_PRINT((ndo, " Prune"));
139*b636d99dSDavid van Moolenbroek 		if (print_prune(ndo, bp) < 0)
140*b636d99dSDavid van Moolenbroek 			goto trunc;
141*b636d99dSDavid van Moolenbroek 		break;
142*b636d99dSDavid van Moolenbroek 
143*b636d99dSDavid van Moolenbroek 	case DVMRP_GRAFT:
144*b636d99dSDavid van Moolenbroek 		ND_PRINT((ndo, " Graft"));
145*b636d99dSDavid van Moolenbroek 		if (print_graft(ndo, bp) < 0)
146*b636d99dSDavid van Moolenbroek 			goto trunc;
147*b636d99dSDavid van Moolenbroek 		break;
148*b636d99dSDavid van Moolenbroek 
149*b636d99dSDavid van Moolenbroek 	case DVMRP_GRAFT_ACK:
150*b636d99dSDavid van Moolenbroek 		ND_PRINT((ndo, " Graft-ACK"));
151*b636d99dSDavid van Moolenbroek 		if (print_graft_ack(ndo, bp) < 0)
152*b636d99dSDavid van Moolenbroek 			goto trunc;
153*b636d99dSDavid van Moolenbroek 		break;
154*b636d99dSDavid van Moolenbroek 
155*b636d99dSDavid van Moolenbroek 	default:
156*b636d99dSDavid van Moolenbroek 		ND_PRINT((ndo, " [type %d]", type));
157*b636d99dSDavid van Moolenbroek 		break;
158*b636d99dSDavid van Moolenbroek 	}
159*b636d99dSDavid van Moolenbroek 	return;
160*b636d99dSDavid van Moolenbroek 
161*b636d99dSDavid van Moolenbroek trunc:
162*b636d99dSDavid van Moolenbroek 	ND_PRINT((ndo, "[|dvmrp]"));
163*b636d99dSDavid van Moolenbroek 	return;
164*b636d99dSDavid van Moolenbroek }
165*b636d99dSDavid van Moolenbroek 
166*b636d99dSDavid van Moolenbroek static int
print_report(netdissect_options * ndo,register const u_char * bp,register const u_char * ep,register u_int len)167*b636d99dSDavid van Moolenbroek print_report(netdissect_options *ndo,
168*b636d99dSDavid van Moolenbroek              register const u_char *bp, register const u_char *ep,
169*b636d99dSDavid van Moolenbroek              register u_int len)
170*b636d99dSDavid van Moolenbroek {
171*b636d99dSDavid van Moolenbroek 	register uint32_t mask, origin;
172*b636d99dSDavid van Moolenbroek 	register int metric, done;
173*b636d99dSDavid van Moolenbroek 	register u_int i, width;
174*b636d99dSDavid van Moolenbroek 
175*b636d99dSDavid van Moolenbroek 	while (len > 0) {
176*b636d99dSDavid van Moolenbroek 		if (len < 3) {
177*b636d99dSDavid van Moolenbroek 			ND_PRINT((ndo, " [|]"));
178*b636d99dSDavid van Moolenbroek 			return (0);
179*b636d99dSDavid van Moolenbroek 		}
180*b636d99dSDavid van Moolenbroek 		ND_TCHECK2(bp[0], 3);
181*b636d99dSDavid van Moolenbroek 		mask = (uint32_t)0xff << 24 | bp[0] << 16 | bp[1] << 8 | bp[2];
182*b636d99dSDavid van Moolenbroek 		width = 1;
183*b636d99dSDavid van Moolenbroek 		if (bp[0])
184*b636d99dSDavid van Moolenbroek 			width = 2;
185*b636d99dSDavid van Moolenbroek 		if (bp[1])
186*b636d99dSDavid van Moolenbroek 			width = 3;
187*b636d99dSDavid van Moolenbroek 		if (bp[2])
188*b636d99dSDavid van Moolenbroek 			width = 4;
189*b636d99dSDavid van Moolenbroek 
190*b636d99dSDavid van Moolenbroek 		ND_PRINT((ndo, "\n\tMask %s", intoa(htonl(mask))));
191*b636d99dSDavid van Moolenbroek 		bp += 3;
192*b636d99dSDavid van Moolenbroek 		len -= 3;
193*b636d99dSDavid van Moolenbroek 		do {
194*b636d99dSDavid van Moolenbroek 			if (bp + width + 1 > ep) {
195*b636d99dSDavid van Moolenbroek 				ND_PRINT((ndo, " [|]"));
196*b636d99dSDavid van Moolenbroek 				return (0);
197*b636d99dSDavid van Moolenbroek 			}
198*b636d99dSDavid van Moolenbroek 			if (len < width + 1) {
199*b636d99dSDavid van Moolenbroek 				ND_PRINT((ndo, "\n\t  [Truncated Report]"));
200*b636d99dSDavid van Moolenbroek 				return (0);
201*b636d99dSDavid van Moolenbroek 			}
202*b636d99dSDavid van Moolenbroek 			origin = 0;
203*b636d99dSDavid van Moolenbroek 			for (i = 0; i < width; ++i) {
204*b636d99dSDavid van Moolenbroek 				ND_TCHECK(*bp);
205*b636d99dSDavid van Moolenbroek 				origin = origin << 8 | *bp++;
206*b636d99dSDavid van Moolenbroek 			}
207*b636d99dSDavid van Moolenbroek 			for ( ; i < 4; ++i)
208*b636d99dSDavid van Moolenbroek 				origin <<= 8;
209*b636d99dSDavid van Moolenbroek 
210*b636d99dSDavid van Moolenbroek 			ND_TCHECK(*bp);
211*b636d99dSDavid van Moolenbroek 			metric = *bp++;
212*b636d99dSDavid van Moolenbroek 			done = metric & 0x80;
213*b636d99dSDavid van Moolenbroek 			metric &= 0x7f;
214*b636d99dSDavid van Moolenbroek 			ND_PRINT((ndo, "\n\t  %s metric %d", intoa(htonl(origin)),
215*b636d99dSDavid van Moolenbroek 				metric));
216*b636d99dSDavid van Moolenbroek 			len -= width + 1;
217*b636d99dSDavid van Moolenbroek 		} while (!done);
218*b636d99dSDavid van Moolenbroek 	}
219*b636d99dSDavid van Moolenbroek 	return (0);
220*b636d99dSDavid van Moolenbroek trunc:
221*b636d99dSDavid van Moolenbroek 	return (-1);
222*b636d99dSDavid van Moolenbroek }
223*b636d99dSDavid van Moolenbroek 
224*b636d99dSDavid van Moolenbroek static int
print_probe(netdissect_options * ndo,register const u_char * bp,register const u_char * ep,register u_int len)225*b636d99dSDavid van Moolenbroek print_probe(netdissect_options *ndo,
226*b636d99dSDavid van Moolenbroek             register const u_char *bp, register const u_char *ep,
227*b636d99dSDavid van Moolenbroek             register u_int len)
228*b636d99dSDavid van Moolenbroek {
229*b636d99dSDavid van Moolenbroek 	register uint32_t genid;
230*b636d99dSDavid van Moolenbroek 
231*b636d99dSDavid van Moolenbroek 	ND_TCHECK2(bp[0], 4);
232*b636d99dSDavid van Moolenbroek 	if ((len < 4) || ((bp + 4) > ep)) {
233*b636d99dSDavid van Moolenbroek 		/* { (ctags) */
234*b636d99dSDavid van Moolenbroek 		ND_PRINT((ndo, " [|}"));
235*b636d99dSDavid van Moolenbroek 		return (0);
236*b636d99dSDavid van Moolenbroek 	}
237*b636d99dSDavid van Moolenbroek 	genid = (bp[0] << 24) | (bp[1] << 16) | (bp[2] << 8) | bp[3];
238*b636d99dSDavid van Moolenbroek 	bp += 4;
239*b636d99dSDavid van Moolenbroek 	len -= 4;
240*b636d99dSDavid van Moolenbroek 	ND_PRINT((ndo, ndo->ndo_vflag > 1 ? "\n\t" : " "));
241*b636d99dSDavid van Moolenbroek 	ND_PRINT((ndo, "genid %u", genid));
242*b636d99dSDavid van Moolenbroek 	if (ndo->ndo_vflag < 2)
243*b636d99dSDavid van Moolenbroek 		return (0);
244*b636d99dSDavid van Moolenbroek 
245*b636d99dSDavid van Moolenbroek 	while ((len > 0) && (bp < ep)) {
246*b636d99dSDavid van Moolenbroek 		ND_TCHECK2(bp[0], 4);
247*b636d99dSDavid van Moolenbroek 		ND_PRINT((ndo, "\n\tneighbor %s", ipaddr_string(ndo, bp)));
248*b636d99dSDavid van Moolenbroek 		bp += 4; len -= 4;
249*b636d99dSDavid van Moolenbroek 	}
250*b636d99dSDavid van Moolenbroek 	return (0);
251*b636d99dSDavid van Moolenbroek trunc:
252*b636d99dSDavid van Moolenbroek 	return (-1);
253*b636d99dSDavid van Moolenbroek }
254*b636d99dSDavid van Moolenbroek 
255*b636d99dSDavid van Moolenbroek static int
print_neighbors(netdissect_options * ndo,register const u_char * bp,register const u_char * ep,register u_int len)256*b636d99dSDavid van Moolenbroek print_neighbors(netdissect_options *ndo,
257*b636d99dSDavid van Moolenbroek                 register const u_char *bp, register const u_char *ep,
258*b636d99dSDavid van Moolenbroek                 register u_int len)
259*b636d99dSDavid van Moolenbroek {
260*b636d99dSDavid van Moolenbroek 	const u_char *laddr;
261*b636d99dSDavid van Moolenbroek 	register u_char metric;
262*b636d99dSDavid van Moolenbroek 	register u_char thresh;
263*b636d99dSDavid van Moolenbroek 	register int ncount;
264*b636d99dSDavid van Moolenbroek 
265*b636d99dSDavid van Moolenbroek 	while (len > 0 && bp < ep) {
266*b636d99dSDavid van Moolenbroek 		ND_TCHECK2(bp[0], 7);
267*b636d99dSDavid van Moolenbroek 		laddr = bp;
268*b636d99dSDavid van Moolenbroek 		bp += 4;
269*b636d99dSDavid van Moolenbroek 		metric = *bp++;
270*b636d99dSDavid van Moolenbroek 		thresh = *bp++;
271*b636d99dSDavid van Moolenbroek 		ncount = *bp++;
272*b636d99dSDavid van Moolenbroek 		len -= 7;
273*b636d99dSDavid van Moolenbroek 		while (--ncount >= 0) {
274*b636d99dSDavid van Moolenbroek 			ND_TCHECK2(bp[0], 4);
275*b636d99dSDavid van Moolenbroek 			ND_PRINT((ndo, " [%s ->", ipaddr_string(ndo, laddr)));
276*b636d99dSDavid van Moolenbroek 			ND_PRINT((ndo, " %s, (%d/%d)]",
277*b636d99dSDavid van Moolenbroek 				   ipaddr_string(ndo, bp), metric, thresh));
278*b636d99dSDavid van Moolenbroek 			bp += 4;
279*b636d99dSDavid van Moolenbroek 			len -= 4;
280*b636d99dSDavid van Moolenbroek 		}
281*b636d99dSDavid van Moolenbroek 	}
282*b636d99dSDavid van Moolenbroek 	return (0);
283*b636d99dSDavid van Moolenbroek trunc:
284*b636d99dSDavid van Moolenbroek 	return (-1);
285*b636d99dSDavid van Moolenbroek }
286*b636d99dSDavid van Moolenbroek 
287*b636d99dSDavid van Moolenbroek static int
print_neighbors2(netdissect_options * ndo,register const u_char * bp,register const u_char * ep,register u_int len)288*b636d99dSDavid van Moolenbroek print_neighbors2(netdissect_options *ndo,
289*b636d99dSDavid van Moolenbroek                  register const u_char *bp, register const u_char *ep,
290*b636d99dSDavid van Moolenbroek                  register u_int len)
291*b636d99dSDavid van Moolenbroek {
292*b636d99dSDavid van Moolenbroek 	const u_char *laddr;
293*b636d99dSDavid van Moolenbroek 	register u_char metric, thresh, flags;
294*b636d99dSDavid van Moolenbroek 	register int ncount;
295*b636d99dSDavid van Moolenbroek 
296*b636d99dSDavid van Moolenbroek 	ND_PRINT((ndo, " (v %d.%d):",
297*b636d99dSDavid van Moolenbroek 	       (int)target_level & 0xff,
298*b636d99dSDavid van Moolenbroek 	       (int)(target_level >> 8) & 0xff));
299*b636d99dSDavid van Moolenbroek 
300*b636d99dSDavid van Moolenbroek 	while (len > 0 && bp < ep) {
301*b636d99dSDavid van Moolenbroek 		ND_TCHECK2(bp[0], 8);
302*b636d99dSDavid van Moolenbroek 		laddr = bp;
303*b636d99dSDavid van Moolenbroek 		bp += 4;
304*b636d99dSDavid van Moolenbroek 		metric = *bp++;
305*b636d99dSDavid van Moolenbroek 		thresh = *bp++;
306*b636d99dSDavid van Moolenbroek 		flags = *bp++;
307*b636d99dSDavid van Moolenbroek 		ncount = *bp++;
308*b636d99dSDavid van Moolenbroek 		len -= 8;
309*b636d99dSDavid van Moolenbroek 		while (--ncount >= 0 && (len >= 4) && (bp + 4) <= ep) {
310*b636d99dSDavid van Moolenbroek 			ND_PRINT((ndo, " [%s -> ", ipaddr_string(ndo, laddr)));
311*b636d99dSDavid van Moolenbroek 			ND_PRINT((ndo, "%s (%d/%d", ipaddr_string(ndo, bp),
312*b636d99dSDavid van Moolenbroek 				     metric, thresh));
313*b636d99dSDavid van Moolenbroek 			if (flags & DVMRP_NF_TUNNEL)
314*b636d99dSDavid van Moolenbroek 				ND_PRINT((ndo, "/tunnel"));
315*b636d99dSDavid van Moolenbroek 			if (flags & DVMRP_NF_SRCRT)
316*b636d99dSDavid van Moolenbroek 				ND_PRINT((ndo, "/srcrt"));
317*b636d99dSDavid van Moolenbroek 			if (flags & DVMRP_NF_QUERIER)
318*b636d99dSDavid van Moolenbroek 				ND_PRINT((ndo, "/querier"));
319*b636d99dSDavid van Moolenbroek 			if (flags & DVMRP_NF_DISABLED)
320*b636d99dSDavid van Moolenbroek 				ND_PRINT((ndo, "/disabled"));
321*b636d99dSDavid van Moolenbroek 			if (flags & DVMRP_NF_DOWN)
322*b636d99dSDavid van Moolenbroek 				ND_PRINT((ndo, "/down"));
323*b636d99dSDavid van Moolenbroek 			ND_PRINT((ndo, ")]"));
324*b636d99dSDavid van Moolenbroek 			bp += 4;
325*b636d99dSDavid van Moolenbroek 			len -= 4;
326*b636d99dSDavid van Moolenbroek 		}
327*b636d99dSDavid van Moolenbroek 		if (ncount != -1) {
328*b636d99dSDavid van Moolenbroek 			ND_PRINT((ndo, " [|]"));
329*b636d99dSDavid van Moolenbroek 			return (0);
330*b636d99dSDavid van Moolenbroek 		}
331*b636d99dSDavid van Moolenbroek 	}
332*b636d99dSDavid van Moolenbroek 	return (0);
333*b636d99dSDavid van Moolenbroek trunc:
334*b636d99dSDavid van Moolenbroek 	return (-1);
335*b636d99dSDavid van Moolenbroek }
336*b636d99dSDavid van Moolenbroek 
337*b636d99dSDavid van Moolenbroek static int
print_prune(netdissect_options * ndo,register const u_char * bp)338*b636d99dSDavid van Moolenbroek print_prune(netdissect_options *ndo,
339*b636d99dSDavid van Moolenbroek             register const u_char *bp)
340*b636d99dSDavid van Moolenbroek {
341*b636d99dSDavid van Moolenbroek 	ND_TCHECK2(bp[0], 12);
342*b636d99dSDavid van Moolenbroek 	ND_PRINT((ndo, " src %s grp %s", ipaddr_string(ndo, bp), ipaddr_string(ndo, bp + 4)));
343*b636d99dSDavid van Moolenbroek 	bp += 8;
344*b636d99dSDavid van Moolenbroek 	ND_PRINT((ndo, " timer "));
345*b636d99dSDavid van Moolenbroek 	relts_print(ndo, EXTRACT_32BITS(bp));
346*b636d99dSDavid van Moolenbroek 	return (0);
347*b636d99dSDavid van Moolenbroek trunc:
348*b636d99dSDavid van Moolenbroek 	return (-1);
349*b636d99dSDavid van Moolenbroek }
350*b636d99dSDavid van Moolenbroek 
351*b636d99dSDavid van Moolenbroek static int
print_graft(netdissect_options * ndo,register const u_char * bp)352*b636d99dSDavid van Moolenbroek print_graft(netdissect_options *ndo,
353*b636d99dSDavid van Moolenbroek             register const u_char *bp)
354*b636d99dSDavid van Moolenbroek {
355*b636d99dSDavid van Moolenbroek 	ND_TCHECK2(bp[0], 8);
356*b636d99dSDavid van Moolenbroek 	ND_PRINT((ndo, " src %s grp %s", ipaddr_string(ndo, bp), ipaddr_string(ndo, bp + 4)));
357*b636d99dSDavid van Moolenbroek 	return (0);
358*b636d99dSDavid van Moolenbroek trunc:
359*b636d99dSDavid van Moolenbroek 	return (-1);
360*b636d99dSDavid van Moolenbroek }
361*b636d99dSDavid van Moolenbroek 
362*b636d99dSDavid van Moolenbroek static int
print_graft_ack(netdissect_options * ndo,register const u_char * bp)363*b636d99dSDavid van Moolenbroek print_graft_ack(netdissect_options *ndo,
364*b636d99dSDavid van Moolenbroek                 register const u_char *bp)
365*b636d99dSDavid van Moolenbroek {
366*b636d99dSDavid van Moolenbroek 	ND_TCHECK2(bp[0], 8);
367*b636d99dSDavid van Moolenbroek 	ND_PRINT((ndo, " src %s grp %s", ipaddr_string(ndo, bp), ipaddr_string(ndo, bp + 4)));
368*b636d99dSDavid van Moolenbroek 	return (0);
369*b636d99dSDavid van Moolenbroek trunc:
370*b636d99dSDavid van Moolenbroek 	return (-1);
371*b636d99dSDavid van Moolenbroek }
372