GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: usr.sbin/tcpdump/print-dvmrp.c Lines: 0 145 0.0 %
Date: 2017-11-07 Branches: 0 90 0.0 %

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