File: | src/usr.sbin/tcpdump/print-802_11.c |
Warning: | line 1621, column 3 Value stored to 't' is never read |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
1 | /* $OpenBSD: print-802_11.c,v 1.44 2022/07/22 20:37:56 stsp Exp $ */ |
2 | |
3 | /* |
4 | * Copyright (c) 2005 Reyk Floeter <reyk@openbsd.org> |
5 | * |
6 | * Permission to use, copy, modify, and distribute this software for any |
7 | * purpose with or without fee is hereby granted, provided that the above |
8 | * copyright notice and this permission notice appear in all copies. |
9 | * |
10 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES |
11 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF |
12 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR |
13 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES |
14 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN |
15 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF |
16 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |
17 | */ |
18 | |
19 | #include <sys/time.h> |
20 | #include <sys/socket.h> |
21 | #include <sys/file.h> |
22 | #include <sys/ioctl.h> |
23 | |
24 | #include <net/if.h> |
25 | |
26 | #include <netinet/in.h> |
27 | #include <netinet/if_ether.h> |
28 | |
29 | #include <net80211/ieee80211.h> |
30 | #include <net80211/ieee80211_radiotap.h> |
31 | |
32 | #include <ctype.h> |
33 | #include <pcap.h> |
34 | #include <stdio.h> |
35 | #include <string.h> |
36 | |
37 | #include "addrtoname.h" |
38 | #include "interface.h" |
39 | |
40 | const char *ieee80211_ctl_subtype_name[] = { |
41 | "reserved#0", |
42 | "reserved#1", |
43 | "reserved#2", |
44 | "reserved#3", |
45 | "reserved#4", |
46 | "reserved#5", |
47 | "reserved#6", |
48 | "wrapper", |
49 | "block ack request", |
50 | "block ack", |
51 | "ps poll", |
52 | "rts", |
53 | "cts", |
54 | "ack", |
55 | "cf-end", |
56 | "cf-end-ack", |
57 | }; |
58 | |
59 | const char *ieee80211_mgt_subtype_name[] = { |
60 | "association request", |
61 | "association response", |
62 | "reassociation request", |
63 | "reassociation response", |
64 | "probe request", |
65 | "probe response", |
66 | "reserved#6", |
67 | "reserved#7", |
68 | "beacon", |
69 | "atim", |
70 | "disassociation", |
71 | "authentication", |
72 | "deauthentication", |
73 | "action", |
74 | "action noack", |
75 | "reserved#15" |
76 | }; |
77 | |
78 | const char *ieee80211_data_subtype_name[] = { |
79 | "data", |
80 | "data cf ack", |
81 | "data cf poll", |
82 | "data cf poll ack", |
83 | "no-data", |
84 | "no-data cf poll", |
85 | "no-data cf ack", |
86 | "no-data cf poll ack", |
87 | "QoS data", |
88 | "QoS data cf ack", |
89 | "QoS data cf poll", |
90 | "QoS data cf poll ack", |
91 | "QoS no-data", |
92 | "QoS no-data cf poll", |
93 | "QoS no-data cf ack", |
94 | "QoS no-data cf poll ack" |
95 | }; |
96 | |
97 | int ieee80211_hdr(struct ieee80211_frame *); |
98 | int ieee80211_data(struct ieee80211_frame *, u_int); |
99 | void ieee80211_print_element(u_int8_t *, u_int); |
100 | void ieee80211_print_essid(u_int8_t *, u_int); |
101 | void ieee80211_print_country(u_int8_t *, u_int); |
102 | void ieee80211_print_htcaps(u_int8_t *, u_int); |
103 | void ieee80211_print_htop(u_int8_t *, u_int); |
104 | void ieee80211_print_vhtcaps(u_int8_t *, u_int); |
105 | void ieee80211_print_vhtop(u_int8_t *, u_int); |
106 | void ieee80211_print_rsncipher(u_int8_t []); |
107 | void ieee80211_print_akm(u_int8_t []); |
108 | void ieee80211_print_rsn(u_int8_t *, u_int); |
109 | int ieee80211_print_beacon(struct ieee80211_frame *, u_int); |
110 | int ieee80211_print_assocreq(struct ieee80211_frame *, u_int); |
111 | int ieee80211_print_elements(uint8_t *); |
112 | int ieee80211_frame(struct ieee80211_frame *, u_int); |
113 | int ieee80211_print(struct ieee80211_frame *, u_int); |
114 | u_int ieee80211_any2ieee(u_int, u_int); |
115 | void ieee80211_reason(u_int16_t); |
116 | |
117 | #define TCARR(a)if (!(snapend - (sizeof(a)) <= snapend && (const u_char *)&(*a) <= snapend - (sizeof(a)))) goto trunc TCHECK2(*a, sizeof(a))if (!(snapend - (sizeof(a)) <= snapend && (const u_char *)&(*a) <= snapend - (sizeof(a)))) goto trunc |
118 | |
119 | int ieee80211_encap = 0; |
120 | |
121 | int |
122 | ieee80211_hdr(struct ieee80211_frame *wh) |
123 | { |
124 | struct ieee80211_frame_addr4 *w4; |
125 | |
126 | switch (wh->i_fc[1] & IEEE80211_FC1_DIR_MASK0x03) { |
127 | case IEEE80211_FC1_DIR_NODS0x00: |
128 | TCARR(wh->i_addr2)if (!(snapend - (sizeof(wh->i_addr2)) <= snapend && (const u_char *)&(*wh->i_addr2) <= snapend - (sizeof (wh->i_addr2)))) goto trunc; |
129 | printf("%s", etheraddr_string(wh->i_addr2)); |
130 | TCARR(wh->i_addr1)if (!(snapend - (sizeof(wh->i_addr1)) <= snapend && (const u_char *)&(*wh->i_addr1) <= snapend - (sizeof (wh->i_addr1)))) goto trunc; |
131 | printf(" > %s", etheraddr_string(wh->i_addr1)); |
132 | TCARR(wh->i_addr3)if (!(snapend - (sizeof(wh->i_addr3)) <= snapend && (const u_char *)&(*wh->i_addr3) <= snapend - (sizeof (wh->i_addr3)))) goto trunc; |
133 | printf(", bssid %s", etheraddr_string(wh->i_addr3)); |
134 | break; |
135 | case IEEE80211_FC1_DIR_TODS0x01: |
136 | TCARR(wh->i_addr2)if (!(snapend - (sizeof(wh->i_addr2)) <= snapend && (const u_char *)&(*wh->i_addr2) <= snapend - (sizeof (wh->i_addr2)))) goto trunc; |
137 | printf("%s", etheraddr_string(wh->i_addr2)); |
138 | TCARR(wh->i_addr3)if (!(snapend - (sizeof(wh->i_addr3)) <= snapend && (const u_char *)&(*wh->i_addr3) <= snapend - (sizeof (wh->i_addr3)))) goto trunc; |
139 | printf(" > %s", etheraddr_string(wh->i_addr3)); |
140 | TCARR(wh->i_addr1)if (!(snapend - (sizeof(wh->i_addr1)) <= snapend && (const u_char *)&(*wh->i_addr1) <= snapend - (sizeof (wh->i_addr1)))) goto trunc; |
141 | printf(", bssid %s, > DS", etheraddr_string(wh->i_addr1)); |
142 | break; |
143 | case IEEE80211_FC1_DIR_FROMDS0x02: |
144 | TCARR(wh->i_addr3)if (!(snapend - (sizeof(wh->i_addr3)) <= snapend && (const u_char *)&(*wh->i_addr3) <= snapend - (sizeof (wh->i_addr3)))) goto trunc; |
145 | printf("%s", etheraddr_string(wh->i_addr3)); |
146 | TCARR(wh->i_addr1)if (!(snapend - (sizeof(wh->i_addr1)) <= snapend && (const u_char *)&(*wh->i_addr1) <= snapend - (sizeof (wh->i_addr1)))) goto trunc; |
147 | printf(" > %s", etheraddr_string(wh->i_addr1)); |
148 | TCARR(wh->i_addr2)if (!(snapend - (sizeof(wh->i_addr2)) <= snapend && (const u_char *)&(*wh->i_addr2) <= snapend - (sizeof (wh->i_addr2)))) goto trunc; |
149 | printf(", bssid %s, DS >", etheraddr_string(wh->i_addr2)); |
150 | break; |
151 | case IEEE80211_FC1_DIR_DSTODS0x03: |
152 | w4 = (struct ieee80211_frame_addr4 *) wh; |
153 | TCARR(w4->i_addr4)if (!(snapend - (sizeof(w4->i_addr4)) <= snapend && (const u_char *)&(*w4->i_addr4) <= snapend - (sizeof (w4->i_addr4)))) goto trunc; |
154 | printf("%s", etheraddr_string(w4->i_addr4)); |
155 | TCARR(w4->i_addr3)if (!(snapend - (sizeof(w4->i_addr3)) <= snapend && (const u_char *)&(*w4->i_addr3) <= snapend - (sizeof (w4->i_addr3)))) goto trunc; |
156 | printf(" > %s", etheraddr_string(w4->i_addr3)); |
157 | TCARR(w4->i_addr2)if (!(snapend - (sizeof(w4->i_addr2)) <= snapend && (const u_char *)&(*w4->i_addr2) <= snapend - (sizeof (w4->i_addr2)))) goto trunc; |
158 | printf(", bssid %s", etheraddr_string(w4->i_addr2)); |
159 | TCARR(w4->i_addr1)if (!(snapend - (sizeof(w4->i_addr1)) <= snapend && (const u_char *)&(*w4->i_addr1) <= snapend - (sizeof (w4->i_addr1)))) goto trunc; |
160 | printf(" > %s, DS > DS", etheraddr_string(w4->i_addr1)); |
161 | break; |
162 | } |
163 | if (vflag) { |
164 | u_int16_t seq; |
165 | TCARR(wh->i_seq)if (!(snapend - (sizeof(wh->i_seq)) <= snapend && (const u_char *)&(*wh->i_seq) <= snapend - (sizeof (wh->i_seq)))) goto trunc; |
166 | bcopy(wh->i_seq, &seq, sizeof(u_int16_t)); |
167 | printf(" (seq %u frag %u): ", |
168 | letoh16(seq)((__uint16_t)(seq)) >> IEEE80211_SEQ_SEQ_SHIFT4, |
169 | letoh16(seq)((__uint16_t)(seq)) & IEEE80211_SEQ_FRAG_MASK0x000f); |
170 | } else |
171 | printf(": "); |
172 | |
173 | return (0); |
174 | |
175 | trunc: |
176 | /* Truncated elements in frame */ |
177 | return (1); |
178 | } |
179 | |
180 | int |
181 | ieee80211_data(struct ieee80211_frame *wh, u_int len) |
182 | { |
183 | u_int8_t *t = (u_int8_t *)wh; |
184 | u_int datalen; |
185 | int data = !(wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_NODATA0x40); |
186 | int hasqos = ((wh->i_fc[0] & |
187 | (IEEE80211_FC0_TYPE_MASK0x0c | IEEE80211_FC0_SUBTYPE_QOS0x80)) == |
188 | (IEEE80211_FC0_TYPE_DATA0x08 | IEEE80211_FC0_SUBTYPE_QOS0x80)); |
189 | u_char *esrc = NULL((void *)0), *edst = NULL((void *)0); |
190 | |
191 | if (hasqos) { |
192 | struct ieee80211_qosframe *wq; |
193 | |
194 | wq = (struct ieee80211_qosframe *) wh; |
195 | TCHECK(*wq)if (!(snapend - (sizeof(*wq)) <= snapend && (const u_char *)&(*wq) <= snapend - (sizeof(*wq)))) goto trunc; |
196 | t += sizeof(*wq); |
197 | datalen = len - sizeof(*wq); |
198 | } else { |
199 | TCHECK(*wh)if (!(snapend - (sizeof(*wh)) <= snapend && (const u_char *)&(*wh) <= snapend - (sizeof(*wh)))) goto trunc; |
200 | t += sizeof(*wh); |
201 | datalen = len - sizeof(*wh); |
202 | } |
203 | |
204 | switch (wh->i_fc[1] & IEEE80211_FC1_DIR_MASK0x03) { |
205 | case IEEE80211_FC1_DIR_TODS0x01: |
206 | esrc = wh->i_addr2; |
207 | edst = wh->i_addr3; |
208 | break; |
209 | case IEEE80211_FC1_DIR_FROMDS0x02: |
210 | esrc = wh->i_addr3; |
211 | edst = wh->i_addr1; |
212 | break; |
213 | case IEEE80211_FC1_DIR_NODS0x00: |
214 | esrc = wh->i_addr2; |
215 | edst = wh->i_addr1; |
216 | break; |
217 | case IEEE80211_FC1_DIR_DSTODS0x03: |
218 | if (hasqos) { |
219 | struct ieee80211_qosframe_addr4 *w4; |
220 | |
221 | w4 = (struct ieee80211_qosframe_addr4 *) wh; |
222 | TCHECK(*w4)if (!(snapend - (sizeof(*w4)) <= snapend && (const u_char *)&(*w4) <= snapend - (sizeof(*w4)))) goto trunc; |
223 | t = (u_int8_t *) (w4 + 1); |
224 | datalen = len - sizeof(*w4); |
225 | esrc = w4->i_addr4; |
226 | edst = w4->i_addr3; |
227 | } else { |
228 | struct ieee80211_frame_addr4 *w4; |
229 | |
230 | w4 = (struct ieee80211_frame_addr4 *) wh; |
231 | TCHECK(*w4)if (!(snapend - (sizeof(*w4)) <= snapend && (const u_char *)&(*w4) <= snapend - (sizeof(*w4)))) goto trunc; |
232 | t = (u_int8_t *) (w4 + 1); |
233 | datalen = len - sizeof(*w4); |
234 | esrc = w4->i_addr4; |
235 | edst = w4->i_addr3; |
236 | } |
237 | break; |
238 | } |
239 | |
240 | if (data && esrc) |
241 | llc_print(t, datalen, datalen, esrc, edst); |
242 | else if (eflag && esrc) |
243 | printf("%s > %s", |
244 | etheraddr_string(esrc), etheraddr_string(edst)); |
245 | |
246 | return (0); |
247 | |
248 | trunc: |
249 | /* Truncated elements in frame */ |
250 | return (1); |
251 | } |
252 | |
253 | /* Caller checks len */ |
254 | void |
255 | ieee80211_print_element(u_int8_t *data, u_int len) |
256 | { |
257 | u_int8_t *p; |
258 | int i; |
259 | |
260 | printf(" 0x"); |
261 | for (i = 0, p = data; i < len; i++, p++) |
262 | printf("%02x", *p); |
263 | } |
264 | |
265 | /* Caller checks len */ |
266 | void |
267 | ieee80211_print_essid(u_int8_t *essid, u_int len) |
268 | { |
269 | u_int8_t *p; |
270 | int i; |
271 | |
272 | if (len > IEEE80211_NWID_LEN32) |
273 | len = IEEE80211_NWID_LEN32; |
274 | |
275 | /* determine printable or not */ |
276 | for (i = 0, p = essid; i < len; i++, p++) { |
277 | if (*p < ' ' || *p > 0x7e) |
278 | break; |
279 | } |
280 | if (i == len) { |
281 | printf(" ("); |
282 | for (i = 0, p = essid; i < len; i++, p++) |
283 | putchar(*p)(!__isthreaded ? __sputc(*p, (&__sF[1])) : (putc)(*p, (& __sF[1]))); |
284 | putchar(')')(!__isthreaded ? __sputc(')', (&__sF[1])) : (putc)(')', ( &__sF[1]))); |
285 | } else |
286 | ieee80211_print_element(essid, len); |
287 | } |
288 | |
289 | /* Caller checks len */ |
290 | void |
291 | ieee80211_print_country(u_int8_t *data, u_int len) |
292 | { |
293 | u_int8_t first_chan, nchan, maxpower; |
294 | |
295 | if (len < 6) |
296 | return; |
297 | |
298 | /* country string */ |
299 | printf((isprint(data[0]) ? " '%c" : " '\\%03o"), data[0]); |
300 | printf((isprint(data[1]) ? "%c" : "\\%03o"), data[1]); |
301 | printf((isprint(data[2]) ? "%c'" : "\\%03o'"), data[2]); |
302 | |
303 | len -= 3; |
304 | data += 3; |
305 | |
306 | /* channels and corresponding TX power limits */ |
307 | while (len >= 3) { |
308 | /* no pretty-printing for nonsensical zero values, |
309 | * nor for operating extension IDs (values >= 201) */ |
310 | if (data[0] == 0 || data[1] == 0 || |
311 | data[0] >= 201 || data[1] >= 201) { |
312 | printf(", %d %d %d", data[0], data[1], data[2]); |
313 | len -= 3; |
314 | data += 3; |
315 | continue; |
316 | } |
317 | |
318 | first_chan = data[0]; |
319 | nchan = data[1]; |
320 | maxpower = data[2]; |
321 | |
322 | printf(", channel%s %d", nchan == 1 ? "" : "s", first_chan); |
323 | if (nchan > 1) |
324 | printf("-%d", first_chan + nchan - 1); |
325 | printf(" limit %ddB", maxpower); |
326 | |
327 | len -= 3; |
328 | data += 3; |
329 | } |
330 | } |
331 | |
332 | /* Caller checks len */ |
333 | void |
334 | ieee80211_print_htcaps(u_int8_t *data, u_int len) |
335 | { |
336 | uint16_t htcaps, rxrate; |
337 | int smps, rxstbc; |
338 | uint8_t ampdu, txmcs; |
339 | int i; |
340 | uint8_t *rxmcs; |
341 | |
342 | if (len < 2) { |
343 | ieee80211_print_element(data, len); |
344 | return; |
345 | } |
346 | |
347 | htcaps = (data[0]) | (data[1] << 8); |
348 | printf("=<"); |
349 | |
350 | /* channel width */ |
351 | if (htcaps & IEEE80211_HTCAP_CBW20_400x00000002) |
352 | printf("20/40MHz"); |
353 | else |
354 | printf("20MHz"); |
355 | |
356 | /* LDPC coding */ |
357 | if (htcaps & IEEE80211_HTCAP_LDPC0x00000001) |
358 | printf(",LDPC"); |
359 | |
360 | /* spatial multiplexing power save mode */ |
361 | smps = (htcaps & IEEE80211_HTCAP_SMPS_MASK0x0000000c) |
362 | >> IEEE80211_HTCAP_SMPS_SHIFT2; |
363 | if (smps == 0) |
364 | printf(",SMPS static"); |
365 | else if (smps == 1) |
366 | printf(",SMPS dynamic"); |
367 | |
368 | /* 11n greenfield mode */ |
369 | if (htcaps & IEEE80211_HTCAP_GF0x00000010) |
370 | printf(",greenfield"); |
371 | |
372 | /* short guard interval */ |
373 | if (htcaps & IEEE80211_HTCAP_SGI200x00000020) |
374 | printf(",SGI@20MHz"); |
375 | if (htcaps & IEEE80211_HTCAP_SGI400x00000040) |
376 | printf(",SGI@40MHz"); |
377 | |
378 | /* space-time block coding */ |
379 | if (htcaps & IEEE80211_HTCAP_TXSTBC0x00000080) |
380 | printf(",TXSTBC"); |
381 | rxstbc = (htcaps & IEEE80211_HTCAP_RXSTBC_MASK0x00000300) |
382 | >> IEEE80211_HTCAP_RXSTBC_SHIFT8; |
383 | if (rxstbc > 0 && rxstbc < 4) |
384 | printf(",RXSTBC %d stream", rxstbc); |
385 | |
386 | /* delayed block-ack */ |
387 | if (htcaps & IEEE80211_HTCAP_DELAYEDBA0x00000400) |
388 | printf(",delayed BA"); |
389 | |
390 | /* max A-MSDU length */ |
391 | if (htcaps & IEEE80211_HTCAP_AMSDU79350x00000800) |
392 | printf(",A-MSDU 7935"); |
393 | else |
394 | printf(",A-MSDU 3839"); |
395 | |
396 | /* DSSS/CCK in 40MHz mode */ |
397 | if (htcaps & IEEE80211_HTCAP_DSSSCCK400x00001000) |
398 | printf(",DSSS/CCK@40MHz"); |
399 | |
400 | /* 40MHz intolerant */ |
401 | if (htcaps & IEEE80211_HTCAP_40INTOLERANT0x00004000) |
402 | printf(",40MHz intolerant"); |
403 | |
404 | /* L-SIG TXOP protection */ |
405 | if (htcaps & IEEE80211_HTCAP_LSIGTXOPPROT0x00008000) |
406 | printf(",L-SIG TXOP prot"); |
407 | |
408 | if (len < 3) { |
409 | printf(">"); |
410 | return; |
411 | } |
412 | |
413 | /* A-MPDU parameters. */ |
414 | ampdu = data[2]; |
415 | |
416 | /* A-MPDU length exponent */ |
417 | if ((ampdu & IEEE80211_AMPDU_PARAM_LE0x03) >= 0 && |
418 | (ampdu & IEEE80211_AMPDU_PARAM_LE0x03) <= 3) |
419 | printf(",A-MPDU max %d", |
420 | (1 << (13 + (ampdu & IEEE80211_AMPDU_PARAM_LE0x03))) - 1); |
421 | |
422 | /* A-MPDU start spacing */ |
423 | if (ampdu & IEEE80211_AMPDU_PARAM_SS0x1c) { |
424 | float ss; |
425 | |
426 | switch ((ampdu & IEEE80211_AMPDU_PARAM_SS0x1c) >> 2) { |
427 | case 1: |
428 | ss = 0.25; |
429 | break; |
430 | case 2: |
431 | ss = 0.5; |
432 | break; |
433 | case 3: |
434 | ss = 1; |
435 | break; |
436 | case 4: |
437 | ss = 2; |
438 | break; |
439 | case 5: |
440 | ss = 4; |
441 | break; |
442 | case 6: |
443 | ss = 8; |
444 | break; |
445 | case 7: |
446 | ss = 16; |
447 | break; |
448 | default: |
449 | ss = 0; |
450 | break; |
451 | } |
452 | if (ss != 0) |
453 | printf(",A-MPDU spacing %.2fus", ss); |
454 | } |
455 | |
456 | if (len < 21) { |
457 | printf(">"); |
458 | return; |
459 | } |
460 | |
461 | /* Supported MCS set. */ |
462 | printf(",RxMCS 0x"); |
463 | rxmcs = &data[3]; |
464 | for (i = 0; i < 10; i++) |
465 | printf("%02x", rxmcs[i]); |
466 | |
467 | /* Max MCS Rx rate (a value of 0 means "not specified"). */ |
468 | rxrate = ((data[13] | (data[14]) << 8) & IEEE80211_MCS_RX_RATE_HIGH0x03ff); |
469 | if (rxrate) |
470 | printf(",RxMaxrate %huMb/s", rxrate); |
471 | |
472 | /* Tx MCS Set */ |
473 | txmcs = data[15]; |
474 | if (txmcs & IEEE80211_TX_MCS_SET_DEFINED0x01) { |
475 | if (txmcs & IEEE80211_TX_RX_MCS_NOT_EQUAL0x02) { |
476 | /* Number of spatial Tx streams. */ |
477 | printf(",%d Tx streams", |
478 | 1 + ((txmcs & IEEE80211_TX_SPATIAL_STREAMS0x0c) >> 2)); |
479 | /* Transmit unequal modulation supported. */ |
480 | if (txmcs & IEEE80211_TX_UNEQUAL_MODULATION0x10) |
481 | printf(",UEQM"); |
482 | } |
483 | } |
484 | |
485 | printf(">"); |
486 | } |
487 | |
488 | /* Caller checks len */ |
489 | void |
490 | ieee80211_print_htop(u_int8_t *data, u_int len) |
491 | { |
492 | u_int8_t primary_chan; |
493 | u_int8_t htopinfo[5]; |
494 | u_int8_t basic_mcs[16]; |
495 | int sco, htprot, i; |
496 | |
497 | if (len < sizeof(primary_chan) + sizeof(htopinfo) + sizeof(basic_mcs)) { |
498 | ieee80211_print_element(data, len); |
499 | return; |
500 | } |
501 | |
502 | htopinfo[0] = data[1]; |
503 | |
504 | printf("=<"); |
505 | |
506 | /* primary channel and secondary channel offset */ |
507 | primary_chan = data[0]; |
508 | sco = ((htopinfo[0] & IEEE80211_HTOP0_SCO_MASK0x03) |
509 | >> IEEE80211_HTOP0_SCO_SHIFT0); |
510 | if (sco == 0) /* no secondary channel */ |
511 | printf("20MHz chan %d", primary_chan); |
512 | else if (sco == 1) { /* secondary channel above */ |
513 | if (primary_chan >= 1 && primary_chan <= 13) /* 2GHz */ |
514 | printf("40MHz chan %d:%d", primary_chan, |
515 | primary_chan + 1); |
516 | else if (primary_chan >= 34) /* 5GHz */ |
517 | printf("40MHz chan %d:%d", primary_chan, |
518 | primary_chan + 4); |
519 | else |
520 | printf("[invalid 40MHz chan %d+]", primary_chan); |
521 | } else if (sco == 3) { /* secondary channel below */ |
522 | if (primary_chan >= 2 && primary_chan <= 14) /* 2GHz */ |
523 | printf("40MHz chan %d:%d", primary_chan, |
524 | primary_chan - 1); |
525 | else if (primary_chan >= 40) /* 5GHz */ |
526 | printf("40MHz chan %d:%d", primary_chan, |
527 | primary_chan - 4); |
528 | else |
529 | printf("[invalid 40MHz chan %d-]", primary_chan); |
530 | } else |
531 | printf("chan %d [invalid secondary channel offset %d]", |
532 | primary_chan, sco); |
533 | |
534 | /* STA channel width */ |
535 | if ((htopinfo[0] & IEEE80211_HTOP0_CHW0x04) == 0) |
536 | printf(",STA chanw 20MHz"); |
537 | |
538 | /* reduced interframe space (RIFS) permitted */ |
539 | if (htopinfo[0] & IEEE80211_HTOP0_RIFS0x08) |
540 | printf(",RIFS"); |
541 | |
542 | htopinfo[1] = data[2]; |
543 | |
544 | /* protection requirements for HT transmissions */ |
545 | htprot = ((htopinfo[1] & IEEE80211_HTOP1_PROT_MASK0x0003) |
546 | >> IEEE80211_HTOP1_PROT_SHIFT0); |
547 | switch (htprot) { |
548 | case IEEE80211_HTPROT_NONE: |
549 | printf(",htprot none"); |
550 | break; |
551 | case IEEE80211_HTPROT_NONMEMBER: |
552 | printf(",htprot non-member"); |
553 | break; |
554 | case IEEE80211_HTPROT_20MHZ: |
555 | printf(",htprot 20MHz"); |
556 | break; |
557 | case IEEE80211_HTPROT_NONHT_MIXED: |
558 | printf(",htprot non-HT-mixed"); |
559 | break; |
560 | default: |
561 | printf(",htprot %d", htprot); |
562 | break; |
563 | } |
564 | |
565 | /* non-greenfield STA present */ |
566 | if (htopinfo[1] & IEEE80211_HTOP1_NONGF_STA0x0004) |
567 | printf(",non-greenfield STA"); |
568 | |
569 | /* non-HT STA present */ |
570 | if (htopinfo[1] & IEEE80211_HTOP1_OBSS_NONHT_STA0x0010) |
571 | printf(",non-HT STA"); |
572 | |
573 | htopinfo[3] = data[4]; |
574 | |
575 | /* dual-beacon */ |
576 | if (htopinfo[3] & IEEE80211_HTOP2_DUALBEACON0x0040) |
577 | printf(",dualbeacon"); |
578 | |
579 | /* dual CTS protection */ |
580 | if (htopinfo[3] & IEEE80211_HTOP2_DUALCTSPROT0x0080) |
581 | printf(",dualctsprot"); |
582 | |
583 | htopinfo[4] = data[5]; |
584 | |
585 | /* space-time block coding (STBC) beacon */ |
586 | if ((htopinfo[4] << 8) & IEEE80211_HTOP2_STBCBEACON0x0100) |
587 | printf(",STBC beacon"); |
588 | |
589 | /* L-SIG (non-HT signal field) TX opportunity (TXOP) protection */ |
590 | if ((htopinfo[4] << 8) & IEEE80211_HTOP2_LSIGTXOP0x0200) |
591 | printf(",lsigtxprot"); |
592 | |
593 | /* phased-coexistence operation (PCO) active */ |
594 | if ((htopinfo[4] << 8) & IEEE80211_HTOP2_PCOACTIVE0x0400) { |
595 | /* PCO phase */ |
596 | if ((htopinfo[4] << 8) & IEEE80211_HTOP2_PCOPHASE400x0800) |
597 | printf(",pco40MHz"); |
598 | else |
599 | printf(",pco20MHz"); |
600 | } |
601 | |
602 | /* basic MCS set */ |
603 | memcpy(basic_mcs, &data[6], sizeof(basic_mcs)); |
604 | printf(",basic MCS set 0x"); |
605 | for (i = 0; i < sizeof(basic_mcs) / sizeof(basic_mcs[0]); i++) |
606 | printf("%x", basic_mcs[i]); |
607 | |
608 | printf(">"); |
609 | } |
610 | |
611 | void |
612 | print_vht_mcsmap(uint16_t mcsmap) |
613 | { |
614 | int nss, mcs; |
615 | |
616 | for (nss = 1; nss < IEEE80211_VHT_NUM_SS8; nss++) { |
617 | mcs = (mcsmap & IEEE80211_VHT_MCS_FOR_SS_MASK(nss)(0x3 << (2*((nss)-1)))) >> |
618 | IEEE80211_VHT_MCS_FOR_SS_SHIFT(nss)(2*((nss)-1)); |
619 | switch (mcs) { |
620 | case IEEE80211_VHT_MCS_0_92: |
621 | printf(" 0-9@%uSS", nss); |
622 | break; |
623 | case IEEE80211_VHT_MCS_0_81: |
624 | printf(" 0-8@%uSS", nss); |
625 | break; |
626 | case IEEE80211_VHT_MCS_0_70: |
627 | printf(" 0-7@%uSS", nss); |
628 | break; |
629 | case IEEE80211_VHT_MCS_SS_NOT_SUPP3: |
630 | default: |
631 | break; |
632 | } |
633 | } |
634 | } |
635 | |
636 | /* Caller checks len */ |
637 | void |
638 | ieee80211_print_vhtcaps(u_int8_t *data, u_int len) |
639 | { |
640 | uint32_t vhtcaps; |
641 | uint16_t rxmcs, txmcs, max_lgi; |
642 | uint32_t rxstbc, num_sts, max_ampdu, link_adapt; |
643 | |
644 | if (len < 12) { |
645 | ieee80211_print_element(data, len); |
646 | return; |
647 | } |
648 | |
649 | vhtcaps = (data[0] | (data[1] << 8) | data[2] << 16 | |
650 | data[3] << 24); |
651 | printf("=<"); |
652 | |
653 | /* max MPDU length */ |
654 | switch (vhtcaps & IEEE80211_VHTCAP_MAX_MPDU_LENGTH_MASK0x00000003) { |
655 | case IEEE80211_VHTCAP_MAX_MPDU_LENGTH_114542: |
656 | printf("max MPDU 11454"); |
657 | break; |
658 | case IEEE80211_VHTCAP_MAX_MPDU_LENGTH_79911: |
659 | printf("max MPDU 7991"); |
660 | break; |
661 | case IEEE80211_VHTCAP_MAX_MPDU_LENGTH_38950: |
662 | default: |
663 | printf("max MPDU 3895"); |
664 | break; |
665 | } |
666 | |
667 | /* supported channel widths */ |
668 | switch ((vhtcaps & IEEE80211_VHTCAP_CHAN_WIDTH_MASK0x0c) << |
669 | IEEE80211_VHTCAP_CHAN_WIDTH_SHIFT2) { |
670 | case IEEE80211_VHTCAP_CHAN_WIDTH_160_80802: |
671 | printf(",80+80MHz"); |
672 | /* fallthrough */ |
673 | case IEEE80211_VHTCAP_CHAN_WIDTH_1601: |
674 | printf(",160MHz"); |
675 | /* fallthrough */ |
676 | case IEEE80211_VHTCAP_CHAN_WIDTH_800: |
677 | default: |
678 | printf(",80MHz"); |
679 | break; |
680 | } |
681 | |
682 | /* LDPC coding */ |
683 | if (vhtcaps & IEEE80211_VHTCAP_RX_LDPC0x00000010) |
684 | printf(",LDPC"); |
685 | |
686 | /* short guard interval */ |
687 | if (vhtcaps & IEEE80211_VHTCAP_SGI800x00000020) |
688 | printf(",SGI@80MHz"); |
689 | if (vhtcaps & IEEE80211_VHTCAP_SGI1600x00000040) |
690 | printf(",SGI@160MHz"); |
691 | |
692 | /* space-time block coding */ |
693 | if (vhtcaps & IEEE80211_VHTCAP_TX_STBC0x00000080) |
694 | printf(",TxSTBC"); |
695 | rxstbc = (vhtcaps & IEEE80211_VHTCAP_RX_STBC_SS_MASK0x00000700) |
696 | >> IEEE80211_VHTCAP_RX_STBC_SS_SHIFT8; |
697 | if (rxstbc > 0 && rxstbc <= 7) |
698 | printf(",RxSTBC %d stream", rxstbc); |
699 | |
700 | /* beamforming */ |
701 | if (vhtcaps & IEEE80211_VHTCAP_SU_BEAMFORMER0x00000800) { |
702 | printf(",beamformer"); |
703 | num_sts = ((vhtcaps & IEEE80211_VHTCAP_NUM_STS_MASK0x00070000) >> |
704 | IEEE80211_VHTCAP_NUM_STS_SHIFT16); |
705 | if (num_sts) |
706 | printf(" STS %u", num_sts); |
707 | } |
708 | if (vhtcaps & IEEE80211_VHTCAP_SU_BEAMFORMEE0x00001000) { |
709 | printf(",beamformee"); |
710 | num_sts = ((vhtcaps & IEEE80211_VHTCAP_BEAMFORMEE_STS_MASK0x0000e000) >> |
711 | IEEE80211_VHTCAP_BEAMFORMEE_STS_SHIFT13); |
712 | if (num_sts) |
713 | printf(" STS %u", num_sts); |
714 | } |
715 | |
716 | if (vhtcaps & IEEE80211_VHTCAP_TXOP_PS0x00200000) |
717 | printf(",TXOP PS"); |
718 | if (vhtcaps & IEEE80211_VHTCAP_HTC_VHT0x00400000) |
719 | printf(",+HTC VHT"); |
720 | |
721 | /* max A-MPDU length */ |
722 | max_ampdu = ((vhtcaps & IEEE80211_VHTCAP_MAX_AMPDU_LEN_MASK0x03800000) >> |
723 | IEEE80211_VHTCAP_MAX_AMPDU_LEN_SHIFT23); |
724 | if (max_ampdu >= IEEE80211_VHTCAP_MAX_AMPDU_LEN_8K0 && |
725 | max_ampdu <= IEEE80211_VHTCAP_MAX_AMPDU_LEN_1024K7) |
726 | printf(",max A-MPDU %uK", (1 << (max_ampdu + 3))); |
727 | |
728 | link_adapt = ((vhtcaps & IEEE80211_VHTCAP_LINK_ADAPT_MASK0x0c000000) >> |
729 | IEEE80211_VHTCAP_LINK_ADAPT_SHIFT26); |
730 | if (link_adapt == IEEE80211_VHTCAP_LINK_ADAPT_UNSOL_MFB2) |
731 | printf(",linkadapt unsolicited MFB"); |
732 | else if (link_adapt == IEEE80211_VHTCAP_LINK_ADAPT_MRQ_MFB3) |
733 | printf(",linkadapt MRQ MFB"); |
734 | |
735 | if (vhtcaps & IEEE80211_VHTCAP_RX_ANT_PATTERN0x10000000) |
736 | printf(",Rx ant pattern consistent"); |
737 | if (vhtcaps & IEEE80211_VHTCAP_TX_ANT_PATTERN0x20000000) |
738 | printf(",Tx ant pattern consistent"); |
739 | |
740 | /* Supported MCS set. */ |
741 | rxmcs = (data[4] | (data[5] << 8)); |
742 | printf(",RxMCS"); |
743 | print_vht_mcsmap(rxmcs); |
744 | max_lgi = ((data[6] | (data[7] << 8)) & |
745 | IEEE80211_VHT_MAX_LGI_MBIT_S_MASK0x1fff); |
746 | if (max_lgi) |
747 | printf(",Rx max LGI rate %uMbit/s", max_lgi); |
748 | txmcs = (data[8] | (data[9] << 8)); |
749 | printf(",TxMCS"); |
750 | print_vht_mcsmap(txmcs); |
751 | max_lgi = ((data[6] | (data[7] << 8)) & |
752 | IEEE80211_VHT_MAX_LGI_MBIT_S_MASK0x1fff); |
753 | if (max_lgi) |
754 | printf(",Tx max LGI rate %uMbit/s", max_lgi); |
755 | |
756 | printf(">"); |
757 | } |
758 | |
759 | /* Caller checks len */ |
760 | void |
761 | ieee80211_print_vhtop(u_int8_t *data, u_int len) |
762 | { |
763 | u_int8_t chan_width, freq_idx0, freq_idx1; |
764 | uint16_t basic_mcs; |
765 | |
766 | if (len < 5) { |
767 | ieee80211_print_element(data, len); |
768 | return; |
769 | } |
770 | |
771 | chan_width = data[0]; |
772 | printf("=<"); |
773 | |
774 | switch (chan_width) { |
775 | case IEEE80211_VHTOP0_CHAN_WIDTH_80803: |
776 | printf("80+80MHz chan"); |
777 | break; |
778 | case IEEE80211_VHTOP0_CHAN_WIDTH_1602: |
779 | printf("160MHz chan"); |
780 | break; |
781 | case IEEE80211_VHTOP0_CHAN_WIDTH_801: |
782 | printf("80MHz chan"); |
783 | break; |
784 | case IEEE80211_VHTOP0_CHAN_WIDTH_HT0: |
785 | default: |
786 | printf("using HT chan width"); |
787 | break; |
788 | } |
789 | |
790 | freq_idx0 = data[1]; |
791 | if (freq_idx0) |
792 | printf(",center chan %u", freq_idx0); |
793 | freq_idx1 = data[2]; |
794 | if (freq_idx1) |
795 | printf(",second center chan %u", freq_idx1); |
796 | |
797 | basic_mcs = (data[3] | data[4] << 8); |
798 | printf(",basic MCS set"); |
799 | print_vht_mcsmap(basic_mcs); |
800 | |
801 | printf(">"); |
802 | } |
803 | |
804 | void |
805 | ieee80211_print_rsncipher(uint8_t selector[4]) |
806 | { |
807 | if (memcmp(selector, MICROSOFT_OUI((const u_int8_t[]){ 0x00, 0x50, 0xf2 }), 3) != 0 && |
808 | memcmp(selector, IEEE80211_OUI((const u_int8_t[]){ 0x00, 0x0f, 0xac }), 3) != 0) { |
809 | printf("0x%x%x%x%x", selector[0], selector[1], selector[2], |
810 | selector[3]); |
811 | return; |
812 | } |
813 | |
814 | /* See 802.11-2012 Table 8-99 */ |
815 | switch (selector[3]) { |
816 | case 0: /* use group data cipher suite */ |
817 | printf("usegroup"); |
818 | break; |
819 | case 1: /* WEP-40 */ |
820 | printf("wep40"); |
821 | break; |
822 | case 2: /* TKIP */ |
823 | printf("tkip"); |
824 | break; |
825 | case 4: /* CCMP (RSNA default) */ |
826 | printf("ccmp"); |
827 | break; |
828 | case 5: /* WEP-104 */ |
829 | printf("wep104"); |
830 | break; |
831 | case 6: /* BIP */ |
832 | printf("bip"); |
833 | break; |
834 | default: |
835 | printf("%d", selector[3]); |
836 | break; |
837 | } |
838 | } |
839 | |
840 | void |
841 | ieee80211_print_akm(uint8_t selector[4]) |
842 | { |
843 | if (memcmp(selector, MICROSOFT_OUI((const u_int8_t[]){ 0x00, 0x50, 0xf2 }), 3) != 0 && |
844 | memcmp(selector, IEEE80211_OUI((const u_int8_t[]){ 0x00, 0x0f, 0xac }), 3) != 0) { |
845 | printf("0x%x%x%x%x", selector[0], selector[1], selector[2], |
846 | selector[3]); |
847 | return; |
848 | } |
849 | |
850 | switch (selector[3]) { |
851 | case 1: |
852 | printf("802.1x"); |
853 | break; |
854 | case 2: |
855 | printf("PSK"); |
856 | break; |
857 | case 5: |
858 | printf("SHA256-802.1x"); |
859 | break; |
860 | case 6: |
861 | printf("SHA256-PSK"); |
862 | break; |
863 | case 8: |
864 | printf("SAE"); |
865 | break; |
866 | default: |
867 | printf("%d", selector[3]); |
868 | break; |
869 | } |
870 | } |
871 | |
872 | /* Caller checks len */ |
873 | void |
874 | ieee80211_print_rsn(u_int8_t *data, u_int len) |
875 | { |
876 | uint16_t version, nciphers, nakms, rsncap, npmk; |
877 | int i, j; |
878 | uint8_t selector[4]; |
879 | |
880 | if (len < 2) { |
881 | ieee80211_print_element(data, len); |
882 | return; |
883 | } |
884 | |
885 | version = (data[0]) | (data[1] << 8); |
886 | printf("=<version %d", version); |
887 | |
888 | if (len < 6) { |
889 | printf(">"); |
890 | return; |
891 | } |
892 | |
893 | data += 2; |
894 | printf(",groupcipher "); |
895 | for (i = 0; i < 4; i++) |
896 | selector[i] = data[i]; |
897 | ieee80211_print_rsncipher(selector); |
898 | |
899 | if (len < 8) { |
900 | printf(">"); |
901 | return; |
902 | } |
903 | |
904 | data += 4; |
905 | nciphers = (data[0]) | ((data[1]) << 8); |
906 | data += 2; |
907 | |
908 | if (len < 8 + (nciphers * 4)) { |
909 | printf(">"); |
910 | return; |
911 | } |
912 | |
913 | printf(",cipher%s ", nciphers > 1 ? "s" : ""); |
914 | for (i = 0; i < nciphers; i++) { |
915 | for (j = 0; j < 4; j++) |
916 | selector[j] = data[j]; |
917 | ieee80211_print_rsncipher(selector); |
918 | if (i < nciphers - 1) |
919 | printf(" "); |
920 | data += 4; |
921 | } |
922 | |
923 | if (len < 8 + (nciphers * 4) + 2) { |
924 | printf(">"); |
925 | return; |
926 | } |
927 | |
928 | nakms = (data[0]) | ((data[1]) << 8); |
929 | data += 2; |
930 | |
931 | if (len < 8 + (nciphers * 4) + 2 + (nakms * 4)) { |
932 | printf(">"); |
933 | return; |
934 | } |
935 | |
936 | printf(",akm%s ", nakms > 1 ? "s" : ""); |
937 | for (i = 0; i < nakms; i++) { |
938 | for (j = 0; j < 4; j++) |
939 | selector[j] = data[j]; |
940 | ieee80211_print_akm(selector); |
941 | if (i < nakms - 1) |
942 | printf(" "); |
943 | data += 4; |
944 | } |
945 | |
946 | if (len < 8 + (nciphers * 4) + 2 + (nakms * 4) + 2) { |
947 | printf(">"); |
948 | return; |
949 | } |
950 | |
951 | rsncap = (data[0]) | ((data[1]) << 8); |
952 | printf(",rsncap 0x%x", rsncap); |
953 | data += 2; |
954 | |
955 | if (len < 8 + (nciphers * 4) + 2 + (nakms * 4) + 2 + 2) { |
956 | printf(">"); |
957 | return; |
958 | } |
959 | |
960 | npmk = (data[0]) | ((data[1]) << 8); |
961 | data += 2; |
962 | |
963 | if (len < 8 + (nciphers * 4) + 2 + (nakms * 4) + 2 + 2 + |
964 | (npmk * IEEE80211_PMKID_LEN16)) { |
965 | printf(">"); |
966 | return; |
967 | } |
968 | |
969 | if (npmk >= 1) |
970 | printf(",pmkid%s ", npmk > 1 ? "s" : ""); |
971 | for (i = 0; i < npmk; i++) { |
972 | printf("0x"); |
973 | for (j = 0; j < IEEE80211_PMKID_LEN16; j++) |
974 | printf("%x", data[j]); |
975 | if (i < npmk - 1) |
976 | printf(" "); |
977 | data += IEEE80211_PMKID_LEN16; |
978 | } |
979 | |
980 | if (len < 8 + (nciphers * 4) + 2 + (nakms * 4) + 2 + 2 + |
981 | (npmk * IEEE80211_PMKID_LEN16) + 4) { |
982 | printf(">"); |
983 | return; |
984 | } |
985 | |
986 | printf(",integrity-groupcipher "); |
987 | for (i = 0; i < 4; i++) |
988 | selector[i] = data[i]; |
989 | ieee80211_print_rsncipher(selector); |
990 | |
991 | printf(">"); |
992 | } |
993 | |
994 | int |
995 | ieee80211_print_beacon(struct ieee80211_frame *wh, u_int len) |
996 | { |
997 | uint64_t tstamp; |
998 | uint16_t bintval, capinfo; |
999 | uint8_t *frm; |
1000 | |
1001 | if (len < sizeof(tstamp) + sizeof(bintval) + sizeof(capinfo)) |
1002 | return 1; /* truncated */ |
1003 | |
1004 | frm = (u_int8_t *)&wh[1]; |
1005 | |
1006 | bcopy(frm, &tstamp, sizeof(u_int64_t)); |
1007 | frm += 8; |
1008 | if (vflag > 1) |
1009 | printf(", timestamp %llu", letoh64(tstamp)((__uint64_t)(tstamp))); |
1010 | |
1011 | bcopy(frm, &bintval, sizeof(u_int16_t)); |
1012 | frm += 2; |
1013 | if (vflag > 1) |
1014 | printf(", interval %u", letoh16(bintval)((__uint16_t)(bintval))); |
1015 | |
1016 | bcopy(frm, &capinfo, sizeof(u_int16_t)); |
1017 | frm += 2; |
1018 | if (vflag) |
1019 | printb(", caps", letoh16(capinfo)((__uint16_t)(capinfo)), IEEE80211_CAPINFO_BITS"\10\01ESS\02IBSS\03CF_POLLABLE\04CF_POLLREQ" "\05PRIVACY\06SHORT_PREAMBLE\07PBCC\10CHNL_AGILITY" "\11SPECTRUM_MGMT\12QOS\13SHORT_SLOTTIME\14APSD" "\15RADIO_MEASUREMENT\16DSSSOFDM\17DELAYED_B_ACK\20IMMEDIATE_B_ACK"); |
1020 | |
1021 | return ieee80211_print_elements(frm); |
1022 | } |
1023 | |
1024 | int |
1025 | ieee80211_print_assocreq(struct ieee80211_frame *wh, u_int len) |
1026 | { |
1027 | uint8_t subtype; |
1028 | uint16_t capinfo, lintval; |
1029 | uint8_t *frm; |
1030 | |
1031 | subtype = wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK0xf0; |
1032 | |
1033 | if (len < sizeof(capinfo) + sizeof(lintval) + |
1034 | (subtype == IEEE80211_FC0_SUBTYPE_REASSOC_REQ0x20 ? |
1035 | IEEE80211_ADDR_LEN6 : 0)) |
1036 | return 1; /* truncated */ |
1037 | |
1038 | frm = (u_int8_t *)&wh[1]; |
1039 | |
1040 | bcopy(frm, &capinfo, sizeof(u_int16_t)); |
1041 | frm += 2; |
1042 | if (vflag) |
1043 | printb(", caps", letoh16(capinfo)((__uint16_t)(capinfo)), IEEE80211_CAPINFO_BITS"\10\01ESS\02IBSS\03CF_POLLABLE\04CF_POLLREQ" "\05PRIVACY\06SHORT_PREAMBLE\07PBCC\10CHNL_AGILITY" "\11SPECTRUM_MGMT\12QOS\13SHORT_SLOTTIME\14APSD" "\15RADIO_MEASUREMENT\16DSSSOFDM\17DELAYED_B_ACK\20IMMEDIATE_B_ACK"); |
1044 | |
1045 | bcopy(frm, &lintval, sizeof(u_int16_t)); |
1046 | frm += 2; |
1047 | if (vflag > 1) |
1048 | printf(", listen interval %u", letoh16(lintval)((__uint16_t)(lintval))); |
1049 | |
1050 | if (subtype == IEEE80211_FC0_SUBTYPE_REASSOC_REQ0x20) { |
1051 | if (vflag) |
1052 | printf(", AP %s", etheraddr_string(frm)); |
1053 | frm += IEEE80211_ADDR_LEN6; |
1054 | } |
1055 | |
1056 | return ieee80211_print_elements(frm); |
1057 | } |
1058 | |
1059 | int |
1060 | ieee80211_print_elements(uint8_t *frm) |
1061 | { |
1062 | int i; |
1063 | |
1064 | while (TTEST2(*frm, 2)(snapend - (2) <= snapend && (const u_char *)& (*frm) <= snapend - (2))) { |
1065 | u_int len = frm[1]; |
1066 | u_int8_t *data = frm + 2; |
1067 | |
1068 | if (!TTEST2(*data, len)(snapend - (len) <= snapend && (const u_char *)& (*data) <= snapend - (len))) |
1069 | break; |
1070 | |
1071 | #define ELEM_CHECK(l) if (len != l) goto trunc |
1072 | |
1073 | switch (*frm) { |
1074 | case IEEE80211_ELEMID_SSID: |
1075 | printf(", ssid"); |
1076 | ieee80211_print_essid(data, len); |
1077 | break; |
1078 | case IEEE80211_ELEMID_RATES: |
1079 | printf(", rates"); |
1080 | if (!vflag) |
1081 | break; |
1082 | for (i = len; i > 0; i--, data++) |
1083 | printf(" %uM%s", |
1084 | (data[0] & IEEE80211_RATE_VAL0x7f) / 2, |
1085 | (data[0] & IEEE80211_RATE_BASIC0x80 |
1086 | ? "*" : "")); |
1087 | break; |
1088 | case IEEE80211_ELEMID_FHPARMS: |
1089 | ELEM_CHECK(5); |
1090 | printf(", fh (dwell %u, chan %u, index %u)", |
1091 | (data[1] << 8) | data[0], |
1092 | (data[2] - 1) * 80 + data[3], /* FH_CHAN */ |
1093 | data[4]); |
1094 | break; |
1095 | case IEEE80211_ELEMID_DSPARMS: |
1096 | ELEM_CHECK(1); |
1097 | printf(", ds"); |
1098 | if (vflag) |
1099 | printf(" (chan %u)", data[0]); |
1100 | break; |
1101 | case IEEE80211_ELEMID_CFPARMS: |
1102 | printf(", cf"); |
1103 | if (vflag) |
1104 | ieee80211_print_element(data, len); |
1105 | break; |
1106 | case IEEE80211_ELEMID_TIM: |
1107 | printf(", tim"); |
1108 | if (vflag) |
1109 | ieee80211_print_element(data, len); |
1110 | break; |
1111 | case IEEE80211_ELEMID_IBSSPARMS: |
1112 | printf(", ibss"); |
1113 | if (vflag) |
1114 | ieee80211_print_element(data, len); |
1115 | break; |
1116 | case IEEE80211_ELEMID_COUNTRY: |
1117 | printf(", country"); |
1118 | if (vflag) |
1119 | ieee80211_print_country(data, len); |
1120 | break; |
1121 | case IEEE80211_ELEMID_CHALLENGE: |
1122 | printf(", challenge"); |
1123 | if (vflag) |
1124 | ieee80211_print_element(data, len); |
1125 | break; |
1126 | case IEEE80211_ELEMID_CSA: |
1127 | ELEM_CHECK(3); |
1128 | printf(", csa (chan %u count %u%s)", data[1], data[2], |
1129 | (data[0] == 1) ? " noTX" : ""); |
1130 | break; |
1131 | case IEEE80211_ELEMID_ERP: |
1132 | printf(", erp"); |
1133 | if (vflag) |
1134 | ieee80211_print_element(data, len); |
1135 | break; |
1136 | case IEEE80211_ELEMID_RSN: |
1137 | printf(", rsn"); |
1138 | if (vflag) |
1139 | ieee80211_print_rsn(data, len); |
1140 | break; |
1141 | case IEEE80211_ELEMID_XRATES: |
1142 | printf(", xrates"); |
1143 | if (!vflag) |
1144 | break; |
1145 | for (i = len; i > 0; i--, data++) |
1146 | printf(" %uM", |
1147 | (data[0] & IEEE80211_RATE_VAL0x7f) / 2); |
1148 | break; |
1149 | case IEEE80211_ELEMID_TPC_REPORT: |
1150 | printf(", tpcreport"); |
1151 | if (vflag) |
1152 | ieee80211_print_element(data, len); |
1153 | break; |
1154 | case IEEE80211_ELEMID_TPC_REQUEST: |
1155 | printf(", tpcrequest"); |
1156 | if (vflag) |
1157 | ieee80211_print_element(data, len); |
1158 | break; |
1159 | case IEEE80211_ELEMID_HTCAPS: |
1160 | printf(", htcaps"); |
1161 | if (vflag) |
1162 | ieee80211_print_htcaps(data, len); |
1163 | break; |
1164 | case IEEE80211_ELEMID_HTOP: |
1165 | printf(", htop"); |
1166 | if (vflag) |
1167 | ieee80211_print_htop(data, len); |
1168 | break; |
1169 | case IEEE80211_ELEMID_VHTCAPS: |
1170 | printf(", vhtcaps"); |
1171 | if (vflag) |
1172 | ieee80211_print_vhtcaps(data, len); |
1173 | break; |
1174 | case IEEE80211_ELEMID_VHTOP: |
1175 | printf(", vhtop"); |
1176 | if (vflag) |
1177 | ieee80211_print_vhtop(data, len); |
1178 | break; |
1179 | case IEEE80211_ELEMID_POWER_CONSTRAINT: |
1180 | ELEM_CHECK(1); |
1181 | printf(", power constraint %udB", data[0]); |
1182 | break; |
1183 | case IEEE80211_ELEMID_QBSS_LOAD: |
1184 | ELEM_CHECK(5); |
1185 | printf(", %u stations, %d%% utilization, " |
1186 | "admission capacity %uus/s", |
1187 | (data[0] | data[1] << 8), |
1188 | (data[2] * 100) / 255, |
1189 | (data[3] | data[4] << 8) / 32); |
1190 | break; |
1191 | case IEEE80211_ELEMID_VENDOR: |
1192 | printf(", vendor"); |
1193 | if (vflag) |
1194 | ieee80211_print_element(data, len); |
1195 | break; |
1196 | default: |
1197 | printf(", %u:%u", (u_int) *frm, len); |
1198 | if (vflag) |
1199 | ieee80211_print_element(data, len); |
1200 | break; |
1201 | } |
1202 | frm += len + 2; |
1203 | |
1204 | if (frm >= snapend) |
1205 | break; |
1206 | } |
1207 | |
1208 | #undef ELEM_CHECK |
1209 | |
1210 | return (0); |
1211 | |
1212 | trunc: |
1213 | /* Truncated elements in frame */ |
1214 | return (1); |
1215 | } |
1216 | |
1217 | int |
1218 | ieee80211_frame(struct ieee80211_frame *wh, u_int len) |
1219 | { |
1220 | u_int8_t subtype, type, *frm; |
1221 | |
1222 | TCARR(wh->i_fc)if (!(snapend - (sizeof(wh->i_fc)) <= snapend && (const u_char *)&(*wh->i_fc) <= snapend - (sizeof( wh->i_fc)))) goto trunc; |
1223 | |
1224 | type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK0x0c; |
1225 | subtype = wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK0xf0; |
1226 | |
1227 | frm = (u_int8_t *)&wh[1]; |
1228 | |
1229 | if (vflag) |
1230 | printb(" flags", wh->i_fc[1], IEEE80211_FC1_BITS"\20\03MORE_FRAG\04RETRY\05PWR_MGT\06MORE_DATA" "\07PROTECTED\08ORDER"); |
1231 | |
1232 | switch (type) { |
1233 | case IEEE80211_FC0_TYPE_DATA0x08: |
1234 | printf(": %s: ", ieee80211_data_subtype_name[ |
1235 | subtype >> IEEE80211_FC0_SUBTYPE_SHIFT4]); |
1236 | ieee80211_data(wh, len); |
1237 | break; |
1238 | case IEEE80211_FC0_TYPE_MGT0x00: |
1239 | printf(": %s", ieee80211_mgt_subtype_name[ |
1240 | subtype >> IEEE80211_FC0_SUBTYPE_SHIFT4]); |
1241 | switch (subtype) { |
1242 | case IEEE80211_FC0_SUBTYPE_BEACON0x80: |
1243 | case IEEE80211_FC0_SUBTYPE_PROBE_RESP0x50: |
1244 | if (ieee80211_print_beacon(wh, len) != 0) |
1245 | goto trunc; |
1246 | break; |
1247 | case IEEE80211_FC0_SUBTYPE_ASSOC_REQ0x00: |
1248 | case IEEE80211_FC0_SUBTYPE_REASSOC_REQ0x20: |
1249 | if (ieee80211_print_assocreq(wh, len) != 0) |
1250 | goto trunc; |
1251 | break; |
1252 | case IEEE80211_FC0_SUBTYPE_AUTH0xb0: |
1253 | TCHECK2(*frm, 2)if (!(snapend - (2) <= snapend && (const u_char *) &(*frm) <= snapend - (2))) goto trunc; /* Auth Algorithm */ |
1254 | switch (IEEE80211_AUTH_ALGORITHM(frm)((frm)[0] | ((frm)[1] << 8))) { |
1255 | case IEEE80211_AUTH_ALG_OPEN0x0000: |
1256 | TCHECK2(*frm, 4)if (!(snapend - (4) <= snapend && (const u_char *) &(*frm) <= snapend - (4))) goto trunc; /* Auth Transaction */ |
1257 | switch (IEEE80211_AUTH_TRANSACTION(frm)((frm)[2] | ((frm)[3] << 8))) { |
1258 | case IEEE80211_AUTH_OPEN_REQUEST: |
1259 | printf(" request"); |
1260 | break; |
1261 | case IEEE80211_AUTH_OPEN_RESPONSE: |
1262 | printf(" response"); |
1263 | break; |
1264 | } |
1265 | break; |
1266 | case IEEE80211_AUTH_ALG_SHARED0x0001: |
1267 | TCHECK2(*frm, 4)if (!(snapend - (4) <= snapend && (const u_char *) &(*frm) <= snapend - (4))) goto trunc; /* Auth Transaction */ |
1268 | switch (IEEE80211_AUTH_TRANSACTION(frm)((frm)[2] | ((frm)[3] << 8))) { |
1269 | case IEEE80211_AUTH_SHARED_REQUEST: |
1270 | printf(" request"); |
1271 | break; |
1272 | case IEEE80211_AUTH_SHARED_CHALLENGE: |
1273 | printf(" challenge"); |
1274 | break; |
1275 | case IEEE80211_AUTH_SHARED_RESPONSE: |
1276 | printf(" response"); |
1277 | break; |
1278 | case IEEE80211_AUTH_SHARED_PASS: |
1279 | printf(" pass"); |
1280 | break; |
1281 | } |
1282 | break; |
1283 | case IEEE80211_AUTH_ALG_LEAP0x0080: |
1284 | printf(" (leap)"); |
1285 | break; |
1286 | } |
1287 | break; |
1288 | case IEEE80211_FC0_SUBTYPE_DEAUTH0xc0: |
1289 | case IEEE80211_FC0_SUBTYPE_DISASSOC0xa0: |
1290 | TCHECK2(*frm, 2)if (!(snapend - (2) <= snapend && (const u_char *) &(*frm) <= snapend - (2))) goto trunc; /* Reason Code */ |
1291 | ieee80211_reason(frm[0] | (frm[1] << 8)); |
1292 | break; |
1293 | } |
1294 | break; |
1295 | case IEEE80211_FC0_TYPE_CTL0x04: { |
1296 | u_int8_t *t = (u_int8_t *) wh; |
1297 | |
1298 | printf(": %s", ieee80211_ctl_subtype_name[ |
1299 | subtype >> IEEE80211_FC0_SUBTYPE_SHIFT4]); |
1300 | if (!vflag) |
1301 | break; |
1302 | |
1303 | /* See 802.11 2012 "8.3.1 Control frames". */ |
1304 | t += 2; /* skip Frame Control */ |
1305 | switch (subtype) { |
1306 | case IEEE80211_FC0_SUBTYPE_RTS0xb0: |
1307 | case IEEE80211_FC0_SUBTYPE_BAR0x80: |
1308 | case IEEE80211_FC0_SUBTYPE_BA0x90: |
1309 | TCHECK2(*t, 2)if (!(snapend - (2) <= snapend && (const u_char *) &(*t) <= snapend - (2))) goto trunc; /* Duration */ |
1310 | printf(", duration %dus", (t[0] | t[1] << 8)); |
1311 | t += 2; |
1312 | TCHECK2(*t, 6)if (!(snapend - (6) <= snapend && (const u_char *) &(*t) <= snapend - (6))) goto trunc; /* RA */ |
1313 | printf(", ra %s", etheraddr_string(t)); |
1314 | t += 6; |
1315 | TCHECK2(*t, 6)if (!(snapend - (6) <= snapend && (const u_char *) &(*t) <= snapend - (6))) goto trunc; /* TA */ |
1316 | printf(", ta %s", etheraddr_string(t)); |
1317 | if (subtype == IEEE80211_FC0_SUBTYPE_BAR0x80 || |
1318 | subtype == IEEE80211_FC0_SUBTYPE_BA0x90) { |
1319 | u_int16_t ctrl; |
1320 | |
1321 | t += 6; |
1322 | TCHECK2(*t, 2)if (!(snapend - (2) <= snapend && (const u_char *) &(*t) <= snapend - (2))) goto trunc; /* BAR/BA control */ |
1323 | ctrl = t[0] | (t[1] << 8); |
1324 | if (ctrl & IEEE80211_BA_ACK_POLICY0x0001) |
1325 | printf(", no ack"); |
1326 | else |
1327 | printf(", normal ack"); |
1328 | if ((ctrl & IEEE80211_BA_MULTI_TID0x0002) == 0 && |
1329 | (ctrl & IEEE80211_BA_COMPRESSED0x0004) == 0) |
1330 | printf(", basic variant"); |
1331 | else if ((ctrl & IEEE80211_BA_MULTI_TID0x0002) && |
1332 | (ctrl & IEEE80211_BA_COMPRESSED0x0004)) |
1333 | printf(", multi-tid variant"); |
1334 | else if (ctrl & IEEE80211_BA_COMPRESSED0x0004) |
1335 | printf(", compressed variant"); |
1336 | } |
1337 | break; |
1338 | case IEEE80211_FC0_SUBTYPE_CTS0xc0: |
1339 | case IEEE80211_FC0_SUBTYPE_ACK0xd0: |
1340 | TCHECK2(*t, 2)if (!(snapend - (2) <= snapend && (const u_char *) &(*t) <= snapend - (2))) goto trunc; /* Duration */ |
1341 | printf(", duration %dus", (t[0] | t[1] << 8)); |
1342 | t += 2; |
1343 | TCHECK2(*t, 6)if (!(snapend - (6) <= snapend && (const u_char *) &(*t) <= snapend - (6))) goto trunc; /* RA */ |
1344 | printf(", ra %s", etheraddr_string(t)); |
1345 | break; |
1346 | case IEEE80211_FC0_SUBTYPE_PS_POLL0xa0: |
1347 | TCHECK2(*t, 2)if (!(snapend - (2) <= snapend && (const u_char *) &(*t) <= snapend - (2))) goto trunc; /* AID */ |
1348 | printf(", aid 0x%x", (t[0] | t[1] << 8)); |
1349 | t += 2; |
1350 | TCHECK2(*t, 6)if (!(snapend - (6) <= snapend && (const u_char *) &(*t) <= snapend - (6))) goto trunc; /* BSSID(RA) */ |
1351 | printf(", ra %s", etheraddr_string(t)); |
1352 | t += 6; |
1353 | TCHECK2(*t, 6)if (!(snapend - (6) <= snapend && (const u_char *) &(*t) <= snapend - (6))) goto trunc; /* TA */ |
1354 | printf(", ta %s", etheraddr_string(t)); |
1355 | break; |
1356 | } |
1357 | break; |
1358 | } |
1359 | default: |
1360 | printf(": type#%d", type); |
1361 | break; |
1362 | } |
1363 | |
1364 | return (0); |
1365 | |
1366 | trunc: |
1367 | /* Truncated 802.11 frame */ |
1368 | return (1); |
1369 | } |
1370 | |
1371 | u_int |
1372 | ieee80211_any2ieee(u_int freq, u_int flags) |
1373 | { |
1374 | if (flags & IEEE80211_CHAN_2GHZ0x0080) { |
1375 | if (freq == 2484) |
1376 | return 14; |
1377 | if (freq < 2484) |
1378 | return (freq - 2407) / 5; |
1379 | else |
1380 | return 15 + ((freq - 2512) / 20); |
1381 | } else if (flags & IEEE80211_CHAN_5GHZ0x0100) { |
1382 | return (freq - 5000) / 5; |
1383 | } else { |
1384 | /* Assume channel is already an IEEE number */ |
1385 | return (freq); |
1386 | } |
1387 | } |
1388 | |
1389 | int |
1390 | ieee80211_print(struct ieee80211_frame *wh, u_int len) |
1391 | { |
1392 | if (eflag) |
1393 | if (ieee80211_hdr(wh)) |
1394 | return (1); |
1395 | |
1396 | printf("802.11"); |
1397 | |
1398 | return (ieee80211_frame(wh, len)); |
1399 | } |
1400 | |
1401 | void |
1402 | ieee802_11_if_print(u_char *user, const struct pcap_pkthdr *h, |
1403 | const u_char *p) |
1404 | { |
1405 | struct ieee80211_frame *wh = (struct ieee80211_frame*)p; |
1406 | |
1407 | if (!ieee80211_encap) |
1408 | ts_print(&h->ts); |
1409 | |
1410 | packetp = p; |
1411 | snapend = p + h->caplen; |
1412 | |
1413 | if (ieee80211_print(wh, (u_int)h->len) != 0) |
1414 | printf("[|802.11]"); |
1415 | |
1416 | if (!ieee80211_encap) { |
1417 | if (xflag) |
1418 | default_print(p, (u_int)h->len); |
1419 | putchar('\n')(!__isthreaded ? __sputc('\n', (&__sF[1])) : (putc)('\n', (&__sF[1]))); |
1420 | } |
1421 | } |
1422 | |
1423 | void |
1424 | ieee802_11_radio_if_print(u_char *user, const struct pcap_pkthdr *h, |
1425 | const u_char *p) |
1426 | { |
1427 | struct ieee80211_radiotap_header *rh = |
1428 | (struct ieee80211_radiotap_header*)p; |
1429 | struct ieee80211_frame *wh; |
1430 | u_int8_t *t; |
1431 | u_int32_t present; |
1432 | u_int len, rh_len; |
1433 | u_int16_t tmp; |
1434 | |
1435 | if (!ieee80211_encap) |
1436 | ts_print(&h->ts); |
1437 | |
1438 | packetp = p; |
1439 | snapend = p + h->caplen; |
1440 | |
1441 | TCHECK(*rh)if (!(snapend - (sizeof(*rh)) <= snapend && (const u_char *)&(*rh) <= snapend - (sizeof(*rh)))) goto trunc; |
1442 | |
1443 | len = h->len; |
1444 | rh_len = letoh16(rh->it_len)((__uint16_t)(rh->it_len)); |
1445 | if (rh->it_version != 0) { |
1446 | printf("[?radiotap + 802.11 v:%u]", rh->it_version); |
1447 | goto out; |
1448 | } |
1449 | |
1450 | wh = (struct ieee80211_frame *)(p + rh_len); |
1451 | if (len <= rh_len || ieee80211_print(wh, len - rh_len)) |
1452 | printf("[|802.11]"); |
1453 | |
1454 | t = (u_int8_t*)p + sizeof(struct ieee80211_radiotap_header); |
1455 | |
1456 | if ((present = letoh32(rh->it_present)((__uint32_t)(rh->it_present))) == 0) |
1457 | goto out; |
1458 | |
1459 | printf(", <radiotap v%u", rh->it_version); |
1460 | |
1461 | #define RADIOTAP(_x) \ |
1462 | (present & (1 << IEEE80211_RADIOTAP_##_x)) |
1463 | |
1464 | if (RADIOTAP(TSFT)) { |
1465 | u_int64_t tsf; |
1466 | |
1467 | TCHECK2(*t, 8)if (!(snapend - (8) <= snapend && (const u_char *) &(*t) <= snapend - (8))) goto trunc; |
1468 | bcopy(t, &tsf, sizeof(u_int64_t)); |
1469 | if (vflag > 1) |
1470 | printf(", tsf %llu", letoh64(tsf)((__uint64_t)(tsf))); |
1471 | t += 8; |
1472 | } |
1473 | |
1474 | if (RADIOTAP(FLAGS)) { |
1475 | u_int8_t flags = *(u_int8_t*)t; |
1476 | TCHECK2(*t, 1)if (!(snapend - (1) <= snapend && (const u_char *) &(*t) <= snapend - (1))) goto trunc; |
1477 | |
1478 | if (flags & IEEE80211_RADIOTAP_F_CFP0x01) |
1479 | printf(", CFP"); |
1480 | if (flags & IEEE80211_RADIOTAP_F_SHORTPRE0x02) |
1481 | printf(", SHORTPRE"); |
1482 | if (flags & IEEE80211_RADIOTAP_F_WEP0x04) |
1483 | printf(", WEP"); |
1484 | if (flags & IEEE80211_RADIOTAP_F_FRAG0x08) |
1485 | printf(", FRAG"); |
1486 | t += 1; |
1487 | } |
1488 | |
1489 | if (RADIOTAP(RATE)) { |
1490 | TCHECK2(*t, 1)if (!(snapend - (1) <= snapend && (const u_char *) &(*t) <= snapend - (1))) goto trunc; |
1491 | if (vflag) { |
1492 | uint8_t rate = *(u_int8_t*)t; |
1493 | if (rate & 0x80) |
1494 | printf(", MCS %u", rate & 0x7f); |
1495 | else |
1496 | printf(", %uMbit/s", rate / 2); |
1497 | } |
1498 | t += 1; |
1499 | } |
1500 | |
1501 | if (RADIOTAP(CHANNEL)) { |
1502 | u_int16_t freq, flags; |
1503 | TCHECK2(*t, 2)if (!(snapend - (2) <= snapend && (const u_char *) &(*t) <= snapend - (2))) goto trunc; |
1504 | |
1505 | bcopy(t, &freq, sizeof(u_int16_t)); |
1506 | freq = letoh16(freq)((__uint16_t)(freq)); |
1507 | t += 2; |
1508 | TCHECK2(*t, 2)if (!(snapend - (2) <= snapend && (const u_char *) &(*t) <= snapend - (2))) goto trunc; |
1509 | bcopy(t, &flags, sizeof(u_int16_t)); |
1510 | flags = letoh16(flags)((__uint16_t)(flags)); |
1511 | t += 2; |
1512 | |
1513 | printf(", chan %u", ieee80211_any2ieee(freq, flags)); |
1514 | |
1515 | if (flags & IEEE80211_CHAN_HT0x2000) |
1516 | printf(", 11n"); |
1517 | else if (flags & IEEE80211_CHAN_DYN0x0400 && |
1518 | flags & IEEE80211_CHAN_2GHZ0x0080) |
1519 | printf(", 11g"); |
1520 | else if (flags & IEEE80211_CHAN_CCK0x0020 && |
1521 | flags & IEEE80211_CHAN_2GHZ0x0080) |
1522 | printf(", 11b"); |
1523 | else if (flags & IEEE80211_CHAN_OFDM0x0040 && |
1524 | flags & IEEE80211_CHAN_2GHZ0x0080) |
1525 | printf(", 11G"); |
1526 | else if (flags & IEEE80211_CHAN_OFDM0x0040 && |
1527 | flags & IEEE80211_CHAN_5GHZ0x0100) |
1528 | printf(", 11a"); |
1529 | |
1530 | if (flags & IEEE80211_CHAN_XR0x1000) |
1531 | printf(", XR"); |
1532 | } |
1533 | |
1534 | if (RADIOTAP(FHSS)) { |
1535 | TCHECK2(*t, 2)if (!(snapend - (2) <= snapend && (const u_char *) &(*t) <= snapend - (2))) goto trunc; |
1536 | printf(", fhss %u/%u", *(u_int8_t*)t, *(u_int8_t*)t + 1); |
1537 | t += 2; |
1538 | } |
1539 | |
1540 | if (RADIOTAP(DBM_ANTSIGNAL)) { |
1541 | TCHECK(*t)if (!(snapend - (sizeof(*t)) <= snapend && (const u_char *)&(*t) <= snapend - (sizeof(*t)))) goto trunc; |
1542 | printf(", sig %ddBm", *(int8_t*)t); |
1543 | t += 1; |
1544 | } |
1545 | |
1546 | if (RADIOTAP(DBM_ANTNOISE)) { |
1547 | TCHECK(*t)if (!(snapend - (sizeof(*t)) <= snapend && (const u_char *)&(*t) <= snapend - (sizeof(*t)))) goto trunc; |
1548 | printf(", noise %ddBm", *(int8_t*)t); |
1549 | t += 1; |
1550 | } |
1551 | |
1552 | if (RADIOTAP(LOCK_QUALITY)) { |
1553 | TCHECK2(*t, 2)if (!(snapend - (2) <= snapend && (const u_char *) &(*t) <= snapend - (2))) goto trunc; |
1554 | if (vflag) { |
1555 | bcopy(t, &tmp, sizeof(u_int16_t)); |
1556 | printf(", quality %u", letoh16(tmp)((__uint16_t)(tmp))); |
1557 | } |
1558 | t += 2; |
1559 | } |
1560 | |
1561 | if (RADIOTAP(TX_ATTENUATION)) { |
1562 | TCHECK2(*t, 2)if (!(snapend - (2) <= snapend && (const u_char *) &(*t) <= snapend - (2))) goto trunc; |
1563 | if (vflag) { |
1564 | bcopy(t, &tmp, sizeof(u_int16_t)); |
1565 | printf(", txatt %u", letoh16(tmp)((__uint16_t)(tmp))); |
1566 | } |
1567 | t += 2; |
1568 | } |
1569 | |
1570 | if (RADIOTAP(DB_TX_ATTENUATION)) { |
1571 | TCHECK2(*t, 2)if (!(snapend - (2) <= snapend && (const u_char *) &(*t) <= snapend - (2))) goto trunc; |
1572 | if (vflag) { |
1573 | bcopy(t, &tmp, sizeof(u_int16_t)); |
1574 | printf(", txatt %udB", letoh16(tmp)((__uint16_t)(tmp))); |
1575 | } |
1576 | t += 2; |
1577 | } |
1578 | |
1579 | if (RADIOTAP(DBM_TX_POWER)) { |
1580 | TCHECK(*t)if (!(snapend - (sizeof(*t)) <= snapend && (const u_char *)&(*t) <= snapend - (sizeof(*t)))) goto trunc; |
1581 | printf(", txpower %ddBm", *(int8_t*)t); |
1582 | t += 1; |
1583 | } |
1584 | |
1585 | if (RADIOTAP(ANTENNA)) { |
1586 | TCHECK(*t)if (!(snapend - (sizeof(*t)) <= snapend && (const u_char *)&(*t) <= snapend - (sizeof(*t)))) goto trunc; |
1587 | if (vflag) |
1588 | printf(", antenna %u", *(u_int8_t*)t); |
1589 | t += 1; |
1590 | } |
1591 | |
1592 | if (RADIOTAP(DB_ANTSIGNAL)) { |
1593 | TCHECK(*t)if (!(snapend - (sizeof(*t)) <= snapend && (const u_char *)&(*t) <= snapend - (sizeof(*t)))) goto trunc; |
1594 | printf(", signal %udB", *(u_int8_t*)t); |
1595 | t += 1; |
1596 | } |
1597 | |
1598 | if (RADIOTAP(DB_ANTNOISE)) { |
1599 | TCHECK(*t)if (!(snapend - (sizeof(*t)) <= snapend && (const u_char *)&(*t) <= snapend - (sizeof(*t)))) goto trunc; |
1600 | printf(", noise %udB", *(u_int8_t*)t); |
1601 | t += 1; |
1602 | } |
1603 | |
1604 | if (RADIOTAP(FCS)) { |
1605 | TCHECK2(*t, 4)if (!(snapend - (4) <= snapend && (const u_char *) &(*t) <= snapend - (4))) goto trunc; |
1606 | if (vflag) { |
1607 | u_int32_t fcs; |
1608 | bcopy(t, &fcs, sizeof(u_int32_t)); |
1609 | printf(", fcs %08x", letoh32(fcs)((__uint32_t)(fcs))); |
1610 | } |
1611 | t += 4; |
1612 | } |
1613 | |
1614 | if (RADIOTAP(RSSI)) { |
1615 | u_int8_t rssi, max_rssi; |
1616 | TCHECK(*t)if (!(snapend - (sizeof(*t)) <= snapend && (const u_char *)&(*t) <= snapend - (sizeof(*t)))) goto trunc; |
1617 | rssi = *(u_int8_t*)t; |
1618 | t += 1; |
1619 | TCHECK(*t)if (!(snapend - (sizeof(*t)) <= snapend && (const u_char *)&(*t) <= snapend - (sizeof(*t)))) goto trunc; |
1620 | max_rssi = *(u_int8_t*)t; |
1621 | t += 1; |
Value stored to 't' is never read | |
1622 | |
1623 | printf(", rssi %u/%u", rssi, max_rssi); |
1624 | } |
1625 | |
1626 | #undef RADIOTAP |
1627 | |
1628 | putchar('>')(!__isthreaded ? __sputc('>', (&__sF[1])) : (putc)('>' , (&__sF[1]))); |
1629 | goto out; |
1630 | |
1631 | trunc: |
1632 | /* Truncated frame */ |
1633 | printf("[|radiotap + 802.11]"); |
1634 | |
1635 | out: |
1636 | if (!ieee80211_encap) { |
1637 | if (xflag) |
1638 | default_print(p, h->len); |
1639 | putchar('\n')(!__isthreaded ? __sputc('\n', (&__sF[1])) : (putc)('\n', (&__sF[1]))); |
1640 | } |
1641 | } |
1642 | |
1643 | void |
1644 | ieee80211_reason(u_int16_t reason) |
1645 | { |
1646 | if (!vflag) |
1647 | return; |
1648 | |
1649 | switch (reason) { |
1650 | case IEEE80211_REASON_UNSPECIFIED: |
1651 | printf(", unspecified failure"); |
1652 | break; |
1653 | case IEEE80211_REASON_AUTH_EXPIRE: |
1654 | printf(", authentication expired"); |
1655 | break; |
1656 | case IEEE80211_REASON_AUTH_LEAVE: |
1657 | printf(", deauth - station left"); |
1658 | break; |
1659 | case IEEE80211_REASON_ASSOC_EXPIRE: |
1660 | printf(", association expired"); |
1661 | break; |
1662 | case IEEE80211_REASON_ASSOC_TOOMANY: |
1663 | printf(", too many associated stations"); |
1664 | break; |
1665 | case IEEE80211_REASON_NOT_AUTHED: |
1666 | printf(", not authenticated"); |
1667 | break; |
1668 | case IEEE80211_REASON_NOT_ASSOCED: |
1669 | printf(", not associated"); |
1670 | break; |
1671 | case IEEE80211_REASON_ASSOC_LEAVE: |
1672 | printf(", disassociated - station left"); |
1673 | break; |
1674 | case IEEE80211_REASON_ASSOC_NOT_AUTHED: |
1675 | printf(", association but not authenticated"); |
1676 | break; |
1677 | case IEEE80211_REASON_RSN_REQUIRED: |
1678 | printf(", rsn required"); |
1679 | break; |
1680 | case IEEE80211_REASON_RSN_INCONSISTENT: |
1681 | printf(", rsn inconsistent"); |
1682 | break; |
1683 | case IEEE80211_REASON_IE_INVALID: |
1684 | printf(", ie invalid"); |
1685 | break; |
1686 | case IEEE80211_REASON_MIC_FAILURE: |
1687 | printf(", mic failure"); |
1688 | break; |
1689 | default: |
1690 | printf(", unknown reason %u", reason); |
1691 | } |
1692 | } |