xref: /openbsd-src/usr.sbin/tcpdump/print-stp.c (revision b2ea75c1b17e1a9a339660e7ed45cd24946b230e)
1 /*	$OpenBSD: print-stp.c,v 1.1 2000/10/19 16:31:42 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  * 3. All advertising materials mentioning features or use of this software
16  *    must display the following acknowledgement:
17  *	This product includes software developed by Jason L. Wright
18  * 4. The name of the author may not be used to endorse or promote products
19  *    derived from this software without specific prior written permission.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
22  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
23  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
24  * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
25  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
26  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
27  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
29  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
30  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31  * POSSIBILITY OF SUCH DAMAGE.
32  */
33 
34 /*
35  * Pretty print 802.1D Bridge Protocol Data Units
36  */
37 
38 #include <sys/param.h>
39 #include <sys/time.h>
40 #include <sys/socket.h>
41 #include <sys/file.h>
42 #include <sys/ioctl.h>
43 
44 #ifdef __STDC__
45 struct mbuf;
46 struct rtentry;
47 #endif
48 #include <net/if.h>
49 
50 #include <netinet/in.h>
51 #include <netinet/in_systm.h>
52 #include <netinet/ip.h>
53 
54 #include <netipx/ipx.h>
55 #include <netipx/ipx_if.h>
56 
57 #include <ctype.h>
58 #include <netdb.h>
59 #include <pcap.h>
60 #include <signal.h>
61 #include <stdio.h>
62 
63 #include <netinet/if_ether.h>
64 #include "ethertype.h"
65 
66 #include <net/ppp_defs.h>
67 #include "interface.h"
68 #include "addrtoname.h"
69 #include "extract.h"
70 #include "llc.h"
71 
72 #define	STP_MSGTYPE_CBPDU	0x00
73 #define	STP_MSGTYPE_TBPDU	0x80
74 
75 #define	STP_FLAGS_TC		0x01            /* Topology change */
76 #define	STP_FLAGS_TCA		0x80            /* Topology change ack */
77 
78 static void stp_print_cbpdu(const u_char *, u_int);
79 static void stp_print_tbpdu(const u_char *, u_int);
80 
81 void
82 stp_print(p, len)
83 	const u_char *p;
84 	u_int len;
85 {
86 	u_int16_t id;
87 
88 	if (len < 3)
89 		goto truncated;
90 	if (p[0] != LLCSAP_8021D || p[1] != LLCSAP_8021D || p[2] != LLC_UI) {
91 		printf("invalid protocol");
92 		return;
93 	}
94 	printf("802.1d");
95 	p += 3;
96 	len -= 3;
97 
98 	if (len < 3)
99 		goto truncated;
100 	id = EXTRACT_16BITS(p);
101 	if (id != 0) {
102 		printf(" unknown protocol id(0x%x)", id);
103 		return;
104 	}
105 	if (p[2] != 0) {
106 		printf(" unknown protocol ver(0x%x)", p[2]);
107 		return;
108 	}
109 	p += 3;
110 	len -= 3;
111 
112 	if (len < 1)
113 		goto truncated;
114 	switch (*p) {
115 	case STP_MSGTYPE_CBPDU:
116 		stp_print_cbpdu(p, len);
117 		break;
118 	case STP_MSGTYPE_TBPDU:
119 		stp_print_tbpdu(p, len);
120 		break;
121 	default:
122 		printf(" unknown message (0x%02x)", *p);
123 		break;
124 	}
125 
126 	return;
127 
128 truncated:
129 	printf("[|802.1d]");
130 }
131 
132 static void
133 stp_print_cbpdu(p, len)
134 	const u_char *p;
135 	u_int len;
136 {
137 	u_int32_t cost;
138 	u_int16_t t;
139 	int x;
140 
141 	p += 1;
142 	len -= 1;
143 
144 	printf(" config");
145 
146 	if (len < 1)
147 		goto truncated;
148 	if (*p) {
149 		x = 0;
150 
151 		printf(" flags=0x%x<", *p);
152 		if ((*p) & STP_FLAGS_TC)
153 			printf("%stc", (x++ != 0) ? "," : "");
154 		if ((*p) & STP_FLAGS_TCA)
155 			printf("%stcack", (x++ != 0) ? "," : "");
156 		putchar('>');
157 	}
158 	p += 1;
159 	len -= 1;
160 
161 	if (len < 8)
162 		goto truncated;
163 	printf(" root=");
164 	printf("%x.", EXTRACT_16BITS(p));
165 	p += 2;
166 	len -= 2;
167 	for (x = 0; x < 6; x++) {
168 		printf("%s%x", (x != 0) ? ":" : "", *p);
169 		p++;
170 		len--;
171 	}
172 
173 	if (len < 4)
174 		goto truncated;
175 	cost = EXTRACT_32BITS(p);
176 	printf(" rootcost=0x%x", cost);
177 	p += 4;
178 	len -= 4;
179 
180 	if (len < 8)
181 		goto truncated;
182 	printf(" bridge=");
183 	printf("%x.", EXTRACT_16BITS(p));
184 	p += 2;
185 	len -= 2;
186 	for (x = 0; x < 6; x++) {
187 		printf("%s%x", (x != 0) ? ":" : "", *p);
188 		p++;
189 		len--;
190 	}
191 
192 	if (len < 2)
193 		goto truncated;
194 	t = EXTRACT_16BITS(p);
195 	printf(" port=0x%x", t);
196 	p += 2;
197 	len -= 2;
198 
199 	if (len < 2)
200 		goto truncated;
201 	printf(" age=%u/%u", p[0], p[1]);
202 	p += 2;
203 	len -= 2;
204 
205 	if (len < 2)
206 		goto truncated;
207 	printf(" max=%u/%u", p[0], p[1]);
208 	p += 2;
209 	len -= 2;
210 
211 	if (len < 2)
212 		goto truncated;
213 	printf(" hello=%u/%u", p[0], p[1]);
214 	p += 2;
215 	len -= 2;
216 
217 	if (len < 2)
218 		goto truncated;
219 	printf(" fwdelay=%u/%u", p[0], p[1]);
220 	p += 2;
221 	len -= 2;
222 
223 	return;
224 
225 truncated:
226 	printf("[|802.1d]");
227 }
228 
229 static void
230 stp_print_tbpdu(p, len)
231 	const u_char *p;
232 	u_int len;
233 {
234 	printf(" tcn");
235 }
236