File: | src/usr.sbin/tcpdump/print-stp.c |
Warning: | line 284, column 4 Value stored to 'len' is never read |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
1 | /* $OpenBSD: print-stp.c,v 1.10 2021/12/01 18:28:46 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 | #include <net/if.h> |
39 | |
40 | #include <netinet/in.h> |
41 | #include <netinet/ip.h> |
42 | |
43 | #include <ctype.h> |
44 | #include <netdb.h> |
45 | #include <pcap.h> |
46 | #include <signal.h> |
47 | #include <stdio.h> |
48 | |
49 | #include <netinet/if_ether.h> |
50 | #include "ethertype.h" |
51 | |
52 | #include <net/ppp_defs.h> |
53 | #include "interface.h" |
54 | #include "addrtoname.h" |
55 | #include "extract.h" |
56 | #include "llc.h" |
57 | |
58 | #define STP_MSGTYPE_CBPDU0x00 0x00 |
59 | #define STP_MSGTYPE_RSTP0x02 0x02 |
60 | #define STP_MSGTYPE_TBPDU0x80 0x80 |
61 | |
62 | #define STP_FLAGS_STPMASK0x81 0x81 /* strip unused STP flags */ |
63 | #define STP_FLAGS_RSTPMASK0x7f 0x7f /* strip unused RSTP flags */ |
64 | #define STP_FLAGS_TC0x01 0x01 /* Topology change */ |
65 | #define STP_FLAGS_P0x02 0x02 /* Proposal flag */ |
66 | #define STP_FLAGS_ROLE0x0c 0x0c /* Port Role */ |
67 | #define STP_FLAGS_ROLE_S2 2 /* Port Role offset */ |
68 | #define STP_FLAGS_ROLE_ALT1 1 /* Alt/Backup port */ |
69 | #define STP_FLAGS_ROLE_ROOT2 2 /* Root port */ |
70 | #define STP_FLAGS_ROLE_DESG3 3 /* Designated port */ |
71 | #define STP_FLAGS_L0x10 0x10 /* Learning flag */ |
72 | #define STP_FLAGS_F0x20 0x20 /* Forwarding flag */ |
73 | #define STP_FLAGS_A0x40 0x40 /* Agreement flag */ |
74 | #define STP_FLAGS_TCA0x80 0x80 /* Topology change ack */ |
75 | #define STP_FLAGS_BITS"\20\1TC\2PROPOSAL\5LEARNING\6FORWARDING\7AGREED\10TCACK" \ |
76 | "\20\1TC\2PROPOSAL\5LEARNING\6FORWARDING\7AGREED\10TCACK" |
77 | |
78 | enum { |
79 | STP_PROTO_STP = 0x00, |
80 | STP_PROTO_RSTP = 0x02, |
81 | STP_PROTO_SSTP = 0x10 /* Cizzco-Eeeh */ |
82 | }; |
83 | |
84 | static void stp_print_cbpdu(const u_char *, u_int, int); |
85 | static void stp_print_tbpdu(const u_char *, u_int); |
86 | |
87 | void |
88 | stp_print(p, len) |
89 | const u_char *p; |
90 | u_int len; |
91 | { |
92 | u_int16_t id; |
93 | int proto = STP_PROTO_STP; |
94 | |
95 | if (len < 3) |
96 | goto truncated; |
97 | if (p[0] == LLCSAP_8021D0x42 && p[1] == LLCSAP_8021D0x42 && p[2] == LLC_UI0x03) |
98 | printf("802.1d"); |
99 | else if (p[0] == LLCSAP_SNAP0xaa && p[1] == LLCSAP_SNAP0xaa && p[2] == LLC_UI0x03) { |
100 | proto = STP_PROTO_SSTP; |
101 | printf("SSTP"); |
102 | p += 5; |
103 | len -= 5; |
104 | } else { |
105 | printf("invalid protocol"); |
106 | return; |
107 | } |
108 | p += 3; |
109 | len -= 3; |
110 | |
111 | if (len < 3) |
112 | goto truncated; |
113 | id = EXTRACT_16BITS(p)((u_int16_t)*((const u_int8_t *)(p) + 0) << 8 | (u_int16_t )*((const u_int8_t *)(p) + 1)); |
114 | if (id != 0) { |
115 | printf(" unknown protocol id(0x%x)", id); |
116 | return; |
117 | } |
118 | switch (p[2]) { |
119 | case STP_PROTO_STP: |
120 | printf(" STP"); |
121 | break; |
122 | case STP_PROTO_RSTP: |
123 | printf(" RSTP"); |
124 | break; |
125 | default: |
126 | printf(" unknown protocol ver(0x%x)", p[2]); |
127 | return; |
128 | } |
129 | p += 3; |
130 | len -= 3; |
131 | |
132 | if (len < 1) |
133 | goto truncated; |
134 | switch (*p) { |
135 | case STP_MSGTYPE_CBPDU0x00: |
136 | stp_print_cbpdu(p, len, proto); |
137 | break; |
138 | case STP_MSGTYPE_RSTP0x02: |
139 | stp_print_cbpdu(p, len, STP_PROTO_RSTP); |
140 | break; |
141 | case STP_MSGTYPE_TBPDU0x80: |
142 | stp_print_tbpdu(p, len); |
143 | break; |
144 | default: |
145 | printf(" unknown message (0x%02x)", *p); |
146 | break; |
147 | } |
148 | |
149 | return; |
150 | |
151 | truncated: |
152 | printf("[|802.1d]"); |
153 | } |
154 | |
155 | static void |
156 | stp_print_cbpdu(p, len, proto) |
157 | const u_char *p; |
158 | u_int len; |
159 | int proto; |
160 | { |
161 | u_int32_t cost; |
162 | u_int16_t t; |
163 | u_int8_t flags, role; |
164 | int x; |
165 | |
166 | p += 1; |
167 | len -= 1; |
168 | |
169 | printf(" config"); |
170 | |
171 | if (len < 1) |
172 | goto truncated; |
173 | if (*p) { |
174 | switch (proto) { |
175 | case STP_PROTO_STP: |
176 | case STP_PROTO_SSTP: |
177 | flags = *p & STP_FLAGS_STPMASK0x81; |
178 | role = STP_FLAGS_ROLE_DESG3; |
179 | break; |
180 | case STP_PROTO_RSTP: |
181 | default: |
182 | flags = *p & STP_FLAGS_RSTPMASK0x7f; |
183 | role = (flags & STP_FLAGS_ROLE0x0c) >> STP_FLAGS_ROLE_S2; |
184 | break; |
185 | } |
186 | |
187 | printb(" flags", flags, STP_FLAGS_BITS"\20\1TC\2PROPOSAL\5LEARNING\6FORWARDING\7AGREED\10TCACK"); |
188 | switch (role) { |
189 | case STP_FLAGS_ROLE_ALT1: |
190 | printf(" role=ALT/BACKUP"); |
191 | break; |
192 | case STP_FLAGS_ROLE_ROOT2: |
193 | printf(" role=ROOT"); |
194 | break; |
195 | case STP_FLAGS_ROLE_DESG3: |
196 | printf(" role=DESIGNATED"); |
197 | break; |
198 | } |
199 | } |
200 | p += 1; |
201 | len -= 1; |
202 | |
203 | if (len < 8) |
204 | goto truncated; |
205 | printf(" root="); |
206 | printf("%x.", EXTRACT_16BITS(p)((u_int16_t)*((const u_int8_t *)(p) + 0) << 8 | (u_int16_t )*((const u_int8_t *)(p) + 1))); |
207 | p += 2; |
208 | len -= 2; |
209 | for (x = 0; x < 6; x++) { |
210 | printf("%s%x", (x != 0) ? ":" : "", *p); |
211 | p++; |
212 | len--; |
213 | } |
214 | |
215 | if (len < 4) |
216 | goto truncated; |
217 | cost = EXTRACT_32BITS(p)((u_int32_t)*((const u_int8_t *)(p) + 0) << 24 | (u_int32_t )*((const u_int8_t *)(p) + 1) << 16 | (u_int32_t)*((const u_int8_t *)(p) + 2) << 8 | (u_int32_t)*((const u_int8_t *)(p) + 3)); |
218 | printf(" rootcost=%u", cost); |
219 | p += 4; |
220 | len -= 4; |
221 | |
222 | if (len < 8) |
223 | goto truncated; |
224 | printf(" bridge="); |
225 | printf("%x.", EXTRACT_16BITS(p)((u_int16_t)*((const u_int8_t *)(p) + 0) << 8 | (u_int16_t )*((const u_int8_t *)(p) + 1))); |
226 | p += 2; |
227 | len -= 2; |
228 | for (x = 0; x < 6; x++) { |
229 | printf("%s%x", (x != 0) ? ":" : "", *p); |
230 | p++; |
231 | len--; |
232 | } |
233 | |
234 | if (len < 2) |
235 | goto truncated; |
236 | t = EXTRACT_16BITS(p)((u_int16_t)*((const u_int8_t *)(p) + 0) << 8 | (u_int16_t )*((const u_int8_t *)(p) + 1)); |
237 | switch (proto) { |
238 | case STP_PROTO_STP: |
239 | case STP_PROTO_SSTP: |
240 | printf(" port=%u", t & 0xff); |
241 | printf(" ifcost=%u", t >> 8); |
242 | break; |
243 | case STP_PROTO_RSTP: |
244 | default: |
245 | printf(" port=%u", t & 0xfff); |
246 | printf(" ifcost=%u", t >> 8); |
247 | break; |
248 | } |
249 | p += 2; |
250 | len -= 2; |
251 | |
252 | if (len < 2) |
253 | goto truncated; |
254 | printf(" age=%u/%u", p[0], p[1]); |
255 | p += 2; |
256 | len -= 2; |
257 | |
258 | if (len < 2) |
259 | goto truncated; |
260 | printf(" max=%u/%u", p[0], p[1]); |
261 | p += 2; |
262 | len -= 2; |
263 | |
264 | if (len < 2) |
265 | goto truncated; |
266 | printf(" hello=%u/%u", p[0], p[1]); |
267 | p += 2; |
268 | len -= 2; |
269 | |
270 | if (len < 2) |
271 | goto truncated; |
272 | printf(" fwdelay=%u/%u", p[0], p[1]); |
273 | p += 2; |
274 | len -= 2; |
275 | |
276 | if (proto == STP_PROTO_SSTP) { |
277 | if (len < 7) |
278 | goto truncated; |
279 | p += 1; |
280 | len -= 1; |
281 | if (EXTRACT_16BITS(p)((u_int16_t)*((const u_int8_t *)(p) + 0) << 8 | (u_int16_t )*((const u_int8_t *)(p) + 1)) == 0 && EXTRACT_16BITS(p + 2)((u_int16_t)*((const u_int8_t *)(p + 2) + 0) << 8 | (u_int16_t )*((const u_int8_t *)(p + 2) + 1)) == 0x02) { |
282 | printf(" pvid=%u", EXTRACT_16BITS(p + 4)((u_int16_t)*((const u_int8_t *)(p + 4) + 0) << 8 | (u_int16_t )*((const u_int8_t *)(p + 4) + 1))); |
283 | p += 6; |
284 | len -= 6; |
Value stored to 'len' is never read | |
285 | } |
286 | } |
287 | |
288 | return; |
289 | |
290 | truncated: |
291 | printf("[|802.1d]"); |
292 | } |
293 | |
294 | static void |
295 | stp_print_tbpdu(p, len) |
296 | const u_char *p; |
297 | u_int len; |
298 | { |
299 | printf(" tcn"); |
300 | } |