xref: /openbsd-src/usr.sbin/tcpdump/print-stp.c (revision db3296cf5c1dd9058ceecc3a29fe4aaa0bd26000)
1 /*	$OpenBSD: print-stp.c,v 1.3 2003/06/03 00:21:04 jason 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/param.h>
34 #include <sys/time.h>
35 #include <sys/socket.h>
36 #include <sys/file.h>
37 #include <sys/ioctl.h>
38 
39 struct mbuf;
40 struct rtentry;
41 #include <net/if.h>
42 
43 #include <netinet/in.h>
44 #include <netinet/in_systm.h>
45 #include <netinet/ip.h>
46 
47 #include <netipx/ipx.h>
48 #include <netipx/ipx_if.h>
49 
50 #include <ctype.h>
51 #include <netdb.h>
52 #include <pcap.h>
53 #include <signal.h>
54 #include <stdio.h>
55 
56 #include <netinet/if_ether.h>
57 #include "ethertype.h"
58 
59 #include <net/ppp_defs.h>
60 #include "interface.h"
61 #include "addrtoname.h"
62 #include "extract.h"
63 #include "llc.h"
64 
65 #define	STP_MSGTYPE_CBPDU	0x00
66 #define	STP_MSGTYPE_TBPDU	0x80
67 
68 #define	STP_FLAGS_TC		0x01            /* Topology change */
69 #define	STP_FLAGS_TCA		0x80            /* Topology change ack */
70 
71 static void stp_print_cbpdu(const u_char *, u_int);
72 static void stp_print_tbpdu(const u_char *, u_int);
73 
74 void
75 stp_print(p, len)
76 	const u_char *p;
77 	u_int len;
78 {
79 	u_int16_t id;
80 
81 	if (len < 3)
82 		goto truncated;
83 	if (p[0] != LLCSAP_8021D || p[1] != LLCSAP_8021D || p[2] != LLC_UI) {
84 		printf("invalid protocol");
85 		return;
86 	}
87 	printf("802.1d");
88 	p += 3;
89 	len -= 3;
90 
91 	if (len < 3)
92 		goto truncated;
93 	id = EXTRACT_16BITS(p);
94 	if (id != 0) {
95 		printf(" unknown protocol id(0x%x)", id);
96 		return;
97 	}
98 	if (p[2] != 0) {
99 		printf(" unknown protocol ver(0x%x)", p[2]);
100 		return;
101 	}
102 	p += 3;
103 	len -= 3;
104 
105 	if (len < 1)
106 		goto truncated;
107 	switch (*p) {
108 	case STP_MSGTYPE_CBPDU:
109 		stp_print_cbpdu(p, len);
110 		break;
111 	case STP_MSGTYPE_TBPDU:
112 		stp_print_tbpdu(p, len);
113 		break;
114 	default:
115 		printf(" unknown message (0x%02x)", *p);
116 		break;
117 	}
118 
119 	return;
120 
121 truncated:
122 	printf("[|802.1d]");
123 }
124 
125 static void
126 stp_print_cbpdu(p, len)
127 	const u_char *p;
128 	u_int len;
129 {
130 	u_int32_t cost;
131 	u_int16_t t;
132 	int x;
133 
134 	p += 1;
135 	len -= 1;
136 
137 	printf(" config");
138 
139 	if (len < 1)
140 		goto truncated;
141 	if (*p) {
142 		x = 0;
143 
144 		printf(" flags=0x%x<", *p);
145 		if ((*p) & STP_FLAGS_TC)
146 			printf("%stc", (x++ != 0) ? "," : "");
147 		if ((*p) & STP_FLAGS_TCA)
148 			printf("%stcack", (x++ != 0) ? "," : "");
149 		putchar('>');
150 	}
151 	p += 1;
152 	len -= 1;
153 
154 	if (len < 8)
155 		goto truncated;
156 	printf(" root=");
157 	printf("%x.", EXTRACT_16BITS(p));
158 	p += 2;
159 	len -= 2;
160 	for (x = 0; x < 6; x++) {
161 		printf("%s%x", (x != 0) ? ":" : "", *p);
162 		p++;
163 		len--;
164 	}
165 
166 	if (len < 4)
167 		goto truncated;
168 	cost = EXTRACT_32BITS(p);
169 	printf(" rootcost=0x%x", cost);
170 	p += 4;
171 	len -= 4;
172 
173 	if (len < 8)
174 		goto truncated;
175 	printf(" bridge=");
176 	printf("%x.", EXTRACT_16BITS(p));
177 	p += 2;
178 	len -= 2;
179 	for (x = 0; x < 6; x++) {
180 		printf("%s%x", (x != 0) ? ":" : "", *p);
181 		p++;
182 		len--;
183 	}
184 
185 	if (len < 2)
186 		goto truncated;
187 	t = EXTRACT_16BITS(p);
188 	printf(" port=0x%x", t);
189 	p += 2;
190 	len -= 2;
191 
192 	if (len < 2)
193 		goto truncated;
194 	printf(" age=%u/%u", p[0], p[1]);
195 	p += 2;
196 	len -= 2;
197 
198 	if (len < 2)
199 		goto truncated;
200 	printf(" max=%u/%u", p[0], p[1]);
201 	p += 2;
202 	len -= 2;
203 
204 	if (len < 2)
205 		goto truncated;
206 	printf(" hello=%u/%u", p[0], p[1]);
207 	p += 2;
208 	len -= 2;
209 
210 	if (len < 2)
211 		goto truncated;
212 	printf(" fwdelay=%u/%u", p[0], p[1]);
213 	p += 2;
214 	len -= 2;
215 
216 	return;
217 
218 truncated:
219 	printf("[|802.1d]");
220 }
221 
222 static void
223 stp_print_tbpdu(p, len)
224 	const u_char *p;
225 	u_int len;
226 {
227 	printf(" tcn");
228 }
229