GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: usr.sbin/tcpdump/print-stp.c Lines: 0 117 0.0 %
Date: 2017-11-13 Branches: 0 69 0.0 %

Line Branch Exec Source
1
/*	$OpenBSD: print-stp.c,v 1.9 2015/01/16 06:40:21 deraadt Exp $	*/
2
3
/*
4
 * Copyright (c) 2000 Jason L. Wright (jason@thought.net)
5
 * All rights reserved.
6
 *
7
 * Redistribution and use in source and binary forms, with or without
8
 * modification, are permitted provided that the following conditions
9
 * are met:
10
 * 1. Redistributions of source code must retain the above copyright
11
 *    notice, this list of conditions and the following disclaimer.
12
 * 2. Redistributions in binary form must reproduce the above copyright
13
 *    notice, this list of conditions and the following disclaimer in the
14
 *    documentation and/or other materials provided with the distribution.
15
 *
16
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19
 * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
20
 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
22
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
24
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
25
 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26
 * POSSIBILITY OF SUCH DAMAGE.
27
 */
28
29
/*
30
 * Pretty print 802.1D Bridge Protocol Data Units
31
 */
32
33
#include <sys/time.h>
34
#include <sys/socket.h>
35
#include <sys/file.h>
36
#include <sys/ioctl.h>
37
38
struct mbuf;
39
struct rtentry;
40
#include <net/if.h>
41
42
#include <netinet/in.h>
43
#include <netinet/ip.h>
44
45
#include <ctype.h>
46
#include <netdb.h>
47
#include <pcap.h>
48
#include <signal.h>
49
#include <stdio.h>
50
51
#include <netinet/if_ether.h>
52
#include "ethertype.h"
53
54
#include <net/ppp_defs.h>
55
#include "interface.h"
56
#include "addrtoname.h"
57
#include "extract.h"
58
#include "llc.h"
59
60
#define	STP_MSGTYPE_CBPDU	0x00
61
#define	STP_MSGTYPE_RSTP	0x02
62
#define	STP_MSGTYPE_TBPDU	0x80
63
64
#define	STP_FLAGS_STPMASK	0x81		/* strip unused STP flags */
65
#define	STP_FLAGS_RSTPMASK	0x7f		/* strip unused RSTP flags */
66
#define	STP_FLAGS_TC		0x01		/* Topology change */
67
#define	STP_FLAGS_P		0x02		/* Proposal flag */
68
#define	STP_FLAGS_ROLE		0x0c		/* Port Role */
69
#define	STP_FLAGS_ROLE_S	2		/* Port Role offset */
70
#define	STP_FLAGS_ROLE_ALT	1		/* Alt/Backup port */
71
#define	STP_FLAGS_ROLE_ROOT	2		/* Root port */
72
#define	STP_FLAGS_ROLE_DESG	3		/* Designated port */
73
#define	STP_FLAGS_L		0x10		/* Learning flag */
74
#define	STP_FLAGS_F		0x20		/* Forwarding flag */
75
#define	STP_FLAGS_A		0x40		/* Agreement flag */
76
#define	STP_FLAGS_TCA		0x80		/* Topology change ack */
77
#define STP_FLAGS_BITS								\
78
	"\20\1TC\2PROPOSAL\5LEARNING\6FORWARDING\7AGREED\10TCACK"
79
80
enum {
81
	STP_PROTO_STP	= 0x00,
82
	STP_PROTO_RSTP	= 0x02,
83
	STP_PROTO_SSTP	= 0x10	/* Cizzco-Eeeh */
84
};
85
86
static void stp_print_cbpdu(const u_char *, u_int, int);
87
static void stp_print_tbpdu(const u_char *, u_int);
88
89
void
90
stp_print(p, len)
91
	const u_char *p;
92
	u_int len;
93
{
94
	u_int16_t id;
95
	int proto = STP_PROTO_STP;
96
97
	if (len < 3)
98
		goto truncated;
99
	if (p[0] == LLCSAP_8021D && p[1] == LLCSAP_8021D && p[2] == LLC_UI)
100
		printf("802.1d");
101
	else if (p[0] == LLCSAP_SNAP && p[1] == LLCSAP_SNAP && p[2] == LLC_UI) {
102
		proto = STP_PROTO_SSTP;
103
		printf("SSTP");
104
		p += 5;
105
		len -= 5;
106
	} else {
107
		printf("invalid protocol");
108
		return;
109
	}
110
	p += 3;
111
	len -= 3;
112
113
	if (len < 3)
114
		goto truncated;
115
	id = EXTRACT_16BITS(p);
116
	if (id != 0) {
117
		printf(" unknown protocol id(0x%x)", id);
118
		return;
119
	}
120
	switch (p[2]) {
121
	case STP_PROTO_STP:
122
		printf(" STP");
123
		break;
124
	case STP_PROTO_RSTP:
125
		printf(" RSTP");
126
		break;
127
	default:
128
		printf(" unknown protocol ver(0x%x)", p[2]);
129
		return;
130
	}
131
	p += 3;
132
	len -= 3;
133
134
	if (len < 1)
135
		goto truncated;
136
	switch (*p) {
137
	case STP_MSGTYPE_CBPDU:
138
		stp_print_cbpdu(p, len, proto);
139
		break;
140
	case STP_MSGTYPE_RSTP:
141
		stp_print_cbpdu(p, len, STP_PROTO_RSTP);
142
		break;
143
	case STP_MSGTYPE_TBPDU:
144
		stp_print_tbpdu(p, len);
145
		break;
146
	default:
147
		printf(" unknown message (0x%02x)", *p);
148
		break;
149
	}
150
151
	return;
152
153
truncated:
154
	printf("[|802.1d]");
155
}
156
157
static void
158
stp_print_cbpdu(p, len, proto)
159
	const u_char *p;
160
	u_int len;
161
	int proto;
162
{
163
	u_int32_t cost;
164
	u_int16_t t;
165
	u_int8_t flags, role;
166
	int x;
167
168
	p += 1;
169
	len -= 1;
170
171
	printf(" config");
172
173
	if (len < 1)
174
		goto truncated;
175
	if (*p) {
176
		switch (proto) {
177
		case STP_PROTO_STP:
178
		case STP_PROTO_SSTP:
179
			flags = *p & STP_FLAGS_STPMASK;
180
			role = STP_FLAGS_ROLE_DESG;
181
			break;
182
		case STP_PROTO_RSTP:
183
		default:
184
			flags = *p & STP_FLAGS_RSTPMASK;
185
			role = (flags & STP_FLAGS_ROLE) >> STP_FLAGS_ROLE_S;
186
			break;
187
		}
188
189
		printb(" flags", flags, STP_FLAGS_BITS);
190
		switch (role) {
191
		case STP_FLAGS_ROLE_ALT:
192
			printf(" role=ALT/BACKUP");
193
			break;
194
		case STP_FLAGS_ROLE_ROOT:
195
			printf(" role=ROOT");
196
			break;
197
		case STP_FLAGS_ROLE_DESG:
198
			printf(" role=DESIGNATED");
199
			break;
200
		}
201
	}
202
	p += 1;
203
	len -= 1;
204
205
	if (len < 8)
206
		goto truncated;
207
	printf(" root=");
208
	printf("%x.", EXTRACT_16BITS(p));
209
	p += 2;
210
	len -= 2;
211
	for (x = 0; x < 6; x++) {
212
		printf("%s%x", (x != 0) ? ":" : "", *p);
213
		p++;
214
		len--;
215
	}
216
217
	if (len < 4)
218
		goto truncated;
219
	cost = EXTRACT_32BITS(p);
220
	printf(" rootcost=%u", cost);
221
	p += 4;
222
	len -= 4;
223
224
	if (len < 8)
225
		goto truncated;
226
	printf(" bridge=");
227
	printf("%x.", EXTRACT_16BITS(p));
228
	p += 2;
229
	len -= 2;
230
	for (x = 0; x < 6; x++) {
231
		printf("%s%x", (x != 0) ? ":" : "", *p);
232
		p++;
233
		len--;
234
	}
235
236
	if (len < 2)
237
		goto truncated;
238
	t = EXTRACT_16BITS(p);
239
	switch (proto) {
240
	case STP_PROTO_STP:
241
	case STP_PROTO_SSTP:
242
		printf(" port=%u", t & 0xff);
243
		printf(" ifcost=%u", t >> 8);
244
		break;
245
	case STP_PROTO_RSTP:
246
	default:
247
		printf(" port=%u", t & 0xfff);
248
		printf(" ifcost=%u", t >> 8);
249
		break;
250
	}
251
	p += 2;
252
	len -= 2;
253
254
	if (len < 2)
255
		goto truncated;
256
	printf(" age=%u/%u", p[0], p[1]);
257
	p += 2;
258
	len -= 2;
259
260
	if (len < 2)
261
		goto truncated;
262
	printf(" max=%u/%u", p[0], p[1]);
263
	p += 2;
264
	len -= 2;
265
266
	if (len < 2)
267
		goto truncated;
268
	printf(" hello=%u/%u", p[0], p[1]);
269
	p += 2;
270
	len -= 2;
271
272
	if (len < 2)
273
		goto truncated;
274
	printf(" fwdelay=%u/%u", p[0], p[1]);
275
	p += 2;
276
	len -= 2;
277
278
	if (proto == STP_PROTO_SSTP) {
279
		if (len < 7)
280
			goto truncated;
281
		p += 1;
282
		len -= 1;
283
		if (EXTRACT_16BITS(p) == 0 && EXTRACT_16BITS(p + 2) == 0x02) {
284
			printf(" pvid=%u", EXTRACT_16BITS(p + 4));
285
			p += 6;
286
			len -= 6;
287
		}
288
	}
289
290
	return;
291
292
truncated:
293
	printf("[|802.1d]");
294
}
295
296
static void
297
stp_print_tbpdu(p, len)
298
	const u_char *p;
299
	u_int len;
300
{
301
	printf(" tcn");
302
}