Bug Summary

File:src/usr.sbin/tcpdump/print-802_11.c
Warning:line 1413, column 3
Value stored to 't' is never read

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple amd64-unknown-openbsd7.0 -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name print-802_11.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 1 -pic-is-pie -mframe-pointer=all -relaxed-aliasing -fno-rounding-math -mconstructor-aliases -munwind-tables -target-cpu x86-64 -target-feature +retpoline-indirect-calls -target-feature +retpoline-indirect-branches -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/usr/src/usr.sbin/tcpdump/obj -resource-dir /usr/local/lib/clang/13.0.0 -I /usr/src/usr.sbin/tcpdump/../../sbin/pfctl -I /usr/src/usr.sbin/tcpdump/../hostapd -I /usr/src/usr.sbin/tcpdump/../../lib/libpcap -D CSLIP -D PPP -D HAVE_FDDI -D ETHER_SERVICE -D HAVE_ETHER_NTOHOST -D INET6 -I /usr/src/usr.sbin/tcpdump/../../sbin/pfctl -D FAKE_PF_KERNEL -internal-isystem /usr/local/lib/clang/13.0.0/include -internal-externc-isystem /usr/include -O2 -fdebug-compilation-dir=/usr/src/usr.sbin/tcpdump/obj -ferror-limit 19 -fwrapv -D_RET_PROTECTOR -ret-protector -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -fno-builtin-malloc -fno-builtin-calloc -fno-builtin-realloc -fno-builtin-valloc -fno-builtin-free -fno-builtin-strdup -fno-builtin-strndup -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /home/ben/Projects/vmm/scan-build/2022-01-12-194120-40624-1 -x c /usr/src/usr.sbin/tcpdump/print-802_11.c
1/* $OpenBSD: print-802_11.c,v 1.41 2021/06/28 14:35:42 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
40const 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
59const 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
78const 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
97int ieee80211_hdr(struct ieee80211_frame *);
98int ieee80211_data(struct ieee80211_frame *, u_int);
99void ieee80211_print_element(u_int8_t *, u_int);
100void ieee80211_print_essid(u_int8_t *, u_int);
101void ieee80211_print_country(u_int8_t *, u_int);
102void ieee80211_print_htcaps(u_int8_t *, u_int);
103void ieee80211_print_htop(u_int8_t *, u_int);
104void ieee80211_print_rsncipher(u_int8_t []);
105void ieee80211_print_akm(u_int8_t []);
106void ieee80211_print_rsn(u_int8_t *, u_int);
107int ieee80211_print_beacon(struct ieee80211_frame *, u_int);
108int ieee80211_print_assocreq(struct ieee80211_frame *, u_int);
109int ieee80211_print_elements(uint8_t *);
110int ieee80211_frame(struct ieee80211_frame *, u_int);
111int ieee80211_print(struct ieee80211_frame *, u_int);
112u_int ieee80211_any2ieee(u_int, u_int);
113void ieee80211_reason(u_int16_t);
114
115#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
116
117int ieee80211_encap = 0;
118
119int
120ieee80211_hdr(struct ieee80211_frame *wh)
121{
122 struct ieee80211_frame_addr4 *w4;
123
124 switch (wh->i_fc[1] & IEEE80211_FC1_DIR_MASK0x03) {
125 case IEEE80211_FC1_DIR_NODS0x00:
126 TCARR(wh->i_addr2)if (!(snapend - (sizeof(wh->i_addr2)) <= snapend &&
(const u_char *)&(*wh->i_addr2) <= snapend - (sizeof
(wh->i_addr2)))) goto trunc
;
127 printf("%s", etheraddr_string(wh->i_addr2));
128 TCARR(wh->i_addr1)if (!(snapend - (sizeof(wh->i_addr1)) <= snapend &&
(const u_char *)&(*wh->i_addr1) <= snapend - (sizeof
(wh->i_addr1)))) goto trunc
;
129 printf(" > %s", etheraddr_string(wh->i_addr1));
130 TCARR(wh->i_addr3)if (!(snapend - (sizeof(wh->i_addr3)) <= snapend &&
(const u_char *)&(*wh->i_addr3) <= snapend - (sizeof
(wh->i_addr3)))) goto trunc
;
131 printf(", bssid %s", etheraddr_string(wh->i_addr3));
132 break;
133 case IEEE80211_FC1_DIR_TODS0x01:
134 TCARR(wh->i_addr2)if (!(snapend - (sizeof(wh->i_addr2)) <= snapend &&
(const u_char *)&(*wh->i_addr2) <= snapend - (sizeof
(wh->i_addr2)))) goto trunc
;
135 printf("%s", etheraddr_string(wh->i_addr2));
136 TCARR(wh->i_addr3)if (!(snapend - (sizeof(wh->i_addr3)) <= snapend &&
(const u_char *)&(*wh->i_addr3) <= snapend - (sizeof
(wh->i_addr3)))) goto trunc
;
137 printf(" > %s", etheraddr_string(wh->i_addr3));
138 TCARR(wh->i_addr1)if (!(snapend - (sizeof(wh->i_addr1)) <= snapend &&
(const u_char *)&(*wh->i_addr1) <= snapend - (sizeof
(wh->i_addr1)))) goto trunc
;
139 printf(", bssid %s, > DS", etheraddr_string(wh->i_addr1));
140 break;
141 case IEEE80211_FC1_DIR_FROMDS0x02:
142 TCARR(wh->i_addr3)if (!(snapend - (sizeof(wh->i_addr3)) <= snapend &&
(const u_char *)&(*wh->i_addr3) <= snapend - (sizeof
(wh->i_addr3)))) goto trunc
;
143 printf("%s", etheraddr_string(wh->i_addr3));
144 TCARR(wh->i_addr1)if (!(snapend - (sizeof(wh->i_addr1)) <= snapend &&
(const u_char *)&(*wh->i_addr1) <= snapend - (sizeof
(wh->i_addr1)))) goto trunc
;
145 printf(" > %s", etheraddr_string(wh->i_addr1));
146 TCARR(wh->i_addr2)if (!(snapend - (sizeof(wh->i_addr2)) <= snapend &&
(const u_char *)&(*wh->i_addr2) <= snapend - (sizeof
(wh->i_addr2)))) goto trunc
;
147 printf(", bssid %s, DS >", etheraddr_string(wh->i_addr2));
148 break;
149 case IEEE80211_FC1_DIR_DSTODS0x03:
150 w4 = (struct ieee80211_frame_addr4 *) wh;
151 TCARR(w4->i_addr4)if (!(snapend - (sizeof(w4->i_addr4)) <= snapend &&
(const u_char *)&(*w4->i_addr4) <= snapend - (sizeof
(w4->i_addr4)))) goto trunc
;
152 printf("%s", etheraddr_string(w4->i_addr4));
153 TCARR(w4->i_addr3)if (!(snapend - (sizeof(w4->i_addr3)) <= snapend &&
(const u_char *)&(*w4->i_addr3) <= snapend - (sizeof
(w4->i_addr3)))) goto trunc
;
154 printf(" > %s", etheraddr_string(w4->i_addr3));
155 TCARR(w4->i_addr2)if (!(snapend - (sizeof(w4->i_addr2)) <= snapend &&
(const u_char *)&(*w4->i_addr2) <= snapend - (sizeof
(w4->i_addr2)))) goto trunc
;
156 printf(", bssid %s", etheraddr_string(w4->i_addr2));
157 TCARR(w4->i_addr1)if (!(snapend - (sizeof(w4->i_addr1)) <= snapend &&
(const u_char *)&(*w4->i_addr1) <= snapend - (sizeof
(w4->i_addr1)))) goto trunc
;
158 printf(" > %s, DS > DS", etheraddr_string(w4->i_addr1));
159 break;
160 }
161 if (vflag) {
162 u_int16_t seq;
163 TCARR(wh->i_seq)if (!(snapend - (sizeof(wh->i_seq)) <= snapend &&
(const u_char *)&(*wh->i_seq) <= snapend - (sizeof
(wh->i_seq)))) goto trunc
;
164 bcopy(wh->i_seq, &seq, sizeof(u_int16_t));
165 printf(" (seq %u frag %u): ",
166 letoh16(seq)((__uint16_t)(seq)) >> IEEE80211_SEQ_SEQ_SHIFT4,
167 letoh16(seq)((__uint16_t)(seq)) & IEEE80211_SEQ_FRAG_MASK0x000f);
168 } else
169 printf(": ");
170
171 return (0);
172
173 trunc:
174 /* Truncated elements in frame */
175 return (1);
176}
177
178int
179ieee80211_data(struct ieee80211_frame *wh, u_int len)
180{
181 u_int8_t *t = (u_int8_t *)wh;
182 u_int datalen;
183 int data = !(wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_NODATA0x40);
184 int hasqos = ((wh->i_fc[0] &
185 (IEEE80211_FC0_TYPE_MASK0x0c | IEEE80211_FC0_SUBTYPE_QOS0x80)) ==
186 (IEEE80211_FC0_TYPE_DATA0x08 | IEEE80211_FC0_SUBTYPE_QOS0x80));
187 u_char *esrc = NULL((void *)0), *edst = NULL((void *)0);
188
189 if (hasqos) {
190 struct ieee80211_qosframe *wq;
191
192 wq = (struct ieee80211_qosframe *) wh;
193 TCHECK(*wq)if (!(snapend - (sizeof(*wq)) <= snapend && (const
u_char *)&(*wq) <= snapend - (sizeof(*wq)))) goto trunc
;
194 t += sizeof(*wq);
195 datalen = len - sizeof(*wq);
196 } else {
197 TCHECK(*wh)if (!(snapend - (sizeof(*wh)) <= snapend && (const
u_char *)&(*wh) <= snapend - (sizeof(*wh)))) goto trunc
;
198 t += sizeof(*wh);
199 datalen = len - sizeof(*wh);
200 }
201
202 switch (wh->i_fc[1] & IEEE80211_FC1_DIR_MASK0x03) {
203 case IEEE80211_FC1_DIR_TODS0x01:
204 esrc = wh->i_addr2;
205 edst = wh->i_addr3;
206 break;
207 case IEEE80211_FC1_DIR_FROMDS0x02:
208 esrc = wh->i_addr3;
209 edst = wh->i_addr1;
210 break;
211 case IEEE80211_FC1_DIR_NODS0x00:
212 esrc = wh->i_addr2;
213 edst = wh->i_addr1;
214 break;
215 case IEEE80211_FC1_DIR_DSTODS0x03:
216 if (hasqos) {
217 struct ieee80211_qosframe_addr4 *w4;
218
219 w4 = (struct ieee80211_qosframe_addr4 *) wh;
220 TCHECK(*w4)if (!(snapend - (sizeof(*w4)) <= snapend && (const
u_char *)&(*w4) <= snapend - (sizeof(*w4)))) goto trunc
;
221 t = (u_int8_t *) (w4 + 1);
222 datalen = len - sizeof(*w4);
223 esrc = w4->i_addr4;
224 edst = w4->i_addr3;
225 } else {
226 struct ieee80211_frame_addr4 *w4;
227
228 w4 = (struct ieee80211_frame_addr4 *) wh;
229 TCHECK(*w4)if (!(snapend - (sizeof(*w4)) <= snapend && (const
u_char *)&(*w4) <= snapend - (sizeof(*w4)))) goto trunc
;
230 t = (u_int8_t *) (w4 + 1);
231 datalen = len - sizeof(*w4);
232 esrc = w4->i_addr4;
233 edst = w4->i_addr3;
234 }
235 break;
236 }
237
238 if (data && esrc)
239 llc_print(t, datalen, datalen, esrc, edst);
240 else if (eflag && esrc)
241 printf("%s > %s",
242 etheraddr_string(esrc), etheraddr_string(edst));
243
244 return (0);
245
246 trunc:
247 /* Truncated elements in frame */
248 return (1);
249}
250
251/* Caller checks len */
252void
253ieee80211_print_element(u_int8_t *data, u_int len)
254{
255 u_int8_t *p;
256 int i;
257
258 printf(" 0x");
259 for (i = 0, p = data; i < len; i++, p++)
260 printf("%02x", *p);
261}
262
263/* Caller checks len */
264void
265ieee80211_print_essid(u_int8_t *essid, u_int len)
266{
267 u_int8_t *p;
268 int i;
269
270 if (len > IEEE80211_NWID_LEN32)
271 len = IEEE80211_NWID_LEN32;
272
273 /* determine printable or not */
274 for (i = 0, p = essid; i < len; i++, p++) {
275 if (*p < ' ' || *p > 0x7e)
276 break;
277 }
278 if (i == len) {
279 printf(" (");
280 for (i = 0, p = essid; i < len; i++, p++)
281 putchar(*p)(!__isthreaded ? __sputc(*p, (&__sF[1])) : (putc)(*p, (&
__sF[1])))
;
282 putchar(')')(!__isthreaded ? __sputc(')', (&__sF[1])) : (putc)(')', (
&__sF[1])))
;
283 } else
284 ieee80211_print_element(essid, len);
285}
286
287/* Caller checks len */
288void
289ieee80211_print_country(u_int8_t *data, u_int len)
290{
291 u_int8_t first_chan, nchan, maxpower;
292
293 if (len < 6)
294 return;
295
296 /* country string */
297 printf((isprint(data[0]) ? " '%c" : " '\\%03o"), data[0]);
298 printf((isprint(data[1]) ? "%c" : "\\%03o"), data[1]);
299 printf((isprint(data[2]) ? "%c'" : "\\%03o'"), data[2]);
300
301 len -= 3;
302 data += 3;
303
304 /* channels and corresponding TX power limits */
305 while (len >= 3) {
306 /* no pretty-printing for nonsensical zero values,
307 * nor for operating extension IDs (values >= 201) */
308 if (data[0] == 0 || data[1] == 0 ||
309 data[0] >= 201 || data[1] >= 201) {
310 printf(", %d %d %d", data[0], data[1], data[2]);
311 len -= 3;
312 data += 3;
313 continue;
314 }
315
316 first_chan = data[0];
317 nchan = data[1];
318 maxpower = data[2];
319
320 printf(", channel%s %d", nchan == 1 ? "" : "s", first_chan);
321 if (nchan > 1)
322 printf("-%d", first_chan + nchan - 1);
323 printf(" limit %ddB", maxpower);
324
325 len -= 3;
326 data += 3;
327 }
328}
329
330/* Caller checks len */
331void
332ieee80211_print_htcaps(u_int8_t *data, u_int len)
333{
334 uint16_t htcaps, rxrate;
335 int smps, rxstbc;
336 uint8_t ampdu, txmcs;
337 int i;
338 uint8_t *rxmcs;
339
340 if (len < 2) {
341 ieee80211_print_element(data, len);
342 return;
343 }
344
345 htcaps = (data[0]) | (data[1] << 8);
346 printf("=<");
347
348 /* channel width */
349 if (htcaps & IEEE80211_HTCAP_CBW20_400x00000002)
350 printf("20/40MHz");
351 else
352 printf("20MHz");
353
354 /* LDPC coding */
355 if (htcaps & IEEE80211_HTCAP_LDPC0x00000001)
356 printf(",LDPC");
357
358 /* spatial multiplexing power save mode */
359 smps = (htcaps & IEEE80211_HTCAP_SMPS_MASK0x0000000c)
360 >> IEEE80211_HTCAP_SMPS_SHIFT2;
361 if (smps == 0)
362 printf(",SMPS static");
363 else if (smps == 1)
364 printf(",SMPS dynamic");
365
366 /* 11n greenfield mode */
367 if (htcaps & IEEE80211_HTCAP_GF0x00000010)
368 printf(",greenfield");
369
370 /* short guard interval */
371 if (htcaps & IEEE80211_HTCAP_SGI200x00000020)
372 printf(",SGI@20MHz");
373 if (htcaps & IEEE80211_HTCAP_SGI400x00000040)
374 printf(",SGI@40MHz");
375
376 /* space-time block coding */
377 if (htcaps & IEEE80211_HTCAP_TXSTBC0x00000080)
378 printf(",TXSTBC");
379 rxstbc = (htcaps & IEEE80211_HTCAP_RXSTBC_MASK0x00000300)
380 >> IEEE80211_HTCAP_RXSTBC_SHIFT8;
381 if (rxstbc > 0 && rxstbc < 4)
382 printf(",RXSTBC %d stream", rxstbc);
383
384 /* delayed block-ack */
385 if (htcaps & IEEE80211_HTCAP_DELAYEDBA0x00000400)
386 printf(",delayed BA");
387
388 /* max A-MSDU length */
389 if (htcaps & IEEE80211_HTCAP_AMSDU79350x00000800)
390 printf(",A-MSDU 7935");
391 else
392 printf(",A-MSDU 3839");
393
394 /* DSSS/CCK in 40MHz mode */
395 if (htcaps & IEEE80211_HTCAP_DSSSCCK400x00001000)
396 printf(",DSSS/CCK@40MHz");
397
398 /* 40MHz intolerant */
399 if (htcaps & IEEE80211_HTCAP_40INTOLERANT0x00004000)
400 printf(",40MHz intolerant");
401
402 /* L-SIG TXOP protection */
403 if (htcaps & IEEE80211_HTCAP_LSIGTXOPPROT0x00008000)
404 printf(",L-SIG TXOP prot");
405
406 if (len < 3) {
407 printf(">");
408 return;
409 }
410
411 /* A-MPDU parameters. */
412 ampdu = data[2];
413
414 /* A-MPDU length exponent */
415 if ((ampdu & IEEE80211_AMPDU_PARAM_LE0x03) >= 0 &&
416 (ampdu & IEEE80211_AMPDU_PARAM_LE0x03) <= 3)
417 printf(",A-MPDU max %d",
418 (1 << (13 + (ampdu & IEEE80211_AMPDU_PARAM_LE0x03))) - 1);
419
420 /* A-MPDU start spacing */
421 if (ampdu & IEEE80211_AMPDU_PARAM_SS0x1c) {
422 float ss;
423
424 switch ((ampdu & IEEE80211_AMPDU_PARAM_SS0x1c) >> 2) {
425 case 1:
426 ss = 0.25;
427 break;
428 case 2:
429 ss = 0.5;
430 break;
431 case 3:
432 ss = 1;
433 break;
434 case 4:
435 ss = 2;
436 break;
437 case 5:
438 ss = 4;
439 break;
440 case 6:
441 ss = 8;
442 break;
443 case 7:
444 ss = 16;
445 break;
446 default:
447 ss = 0;
448 break;
449 }
450 if (ss != 0)
451 printf(",A-MPDU spacing %.2fus", ss);
452 }
453
454 if (len < 21) {
455 printf(">");
456 return;
457 }
458
459 /* Supported MCS set. */
460 printf(",RxMCS 0x");
461 rxmcs = &data[3];
462 for (i = 0; i < 10; i++)
463 printf("%02x", rxmcs[i]);
464
465 /* Max MCS Rx rate (a value of 0 means "not specified"). */
466 rxrate = ((data[13] | (data[14]) << 8) & IEEE80211_MCS_RX_RATE_HIGH0x03ff);
467 if (rxrate)
468 printf(",RxMaxrate %huMb/s", rxrate);
469
470 /* Tx MCS Set */
471 txmcs = data[15];
472 if (txmcs & IEEE80211_TX_MCS_SET_DEFINED0x01) {
473 if (txmcs & IEEE80211_TX_RX_MCS_NOT_EQUAL0x02) {
474 /* Number of spatial Tx streams. */
475 printf(",%d Tx streams",
476 1 + ((txmcs & IEEE80211_TX_SPATIAL_STREAMS0x0c) >> 2));
477 /* Transmit unequal modulation supported. */
478 if (txmcs & IEEE80211_TX_UNEQUAL_MODULATION0x10)
479 printf(",UEQM");
480 }
481 }
482
483 printf(">");
484}
485
486/* Caller checks len */
487void
488ieee80211_print_htop(u_int8_t *data, u_int len)
489{
490 u_int8_t primary_chan;
491 u_int8_t htopinfo[5];
492 u_int8_t basic_mcs[16];
493 int sco, htprot, i;
494
495 if (len < sizeof(primary_chan) + sizeof(htopinfo) + sizeof(basic_mcs)) {
496 ieee80211_print_element(data, len);
497 return;
498 }
499
500 htopinfo[0] = data[1];
501
502 printf("=<");
503
504 /* primary channel and secondary channel offset */
505 primary_chan = data[0];
506 sco = ((htopinfo[0] & IEEE80211_HTOP0_SCO_MASK0x03)
507 >> IEEE80211_HTOP0_SCO_SHIFT0);
508 if (sco == 0) /* no secondary channel */
509 printf("20MHz chan %d", primary_chan);
510 else if (sco == 1) { /* secondary channel above */
511 if (primary_chan >= 1 && primary_chan <= 13) /* 2GHz */
512 printf("40MHz chan %d:%d", primary_chan,
513 primary_chan + 1);
514 else if (primary_chan >= 34) /* 5GHz */
515 printf("40MHz chan %d:%d", primary_chan,
516 primary_chan + 4);
517 else
518 printf("[invalid 40MHz chan %d+]", primary_chan);
519 } else if (sco == 3) { /* secondary channel below */
520 if (primary_chan >= 2 && primary_chan <= 14) /* 2GHz */
521 printf("40MHz chan %d:%d", primary_chan,
522 primary_chan - 1);
523 else if (primary_chan >= 40) /* 5GHz */
524 printf("40MHz chan %d:%d", primary_chan,
525 primary_chan - 4);
526 else
527 printf("[invalid 40MHz chan %d-]", primary_chan);
528 } else
529 printf("chan %d [invalid secondary channel offset %d]",
530 primary_chan, sco);
531
532 /* STA channel width */
533 if ((htopinfo[0] & IEEE80211_HTOP0_CHW0x04) == 0)
534 printf(",STA chanw 20MHz");
535
536 /* reduced interframe space (RIFS) permitted */
537 if (htopinfo[0] & IEEE80211_HTOP0_RIFS0x08)
538 printf(",RIFS");
539
540 htopinfo[1] = data[2];
541
542 /* protection requirements for HT transmissions */
543 htprot = ((htopinfo[1] & IEEE80211_HTOP1_PROT_MASK0x0003)
544 >> IEEE80211_HTOP1_PROT_SHIFT0);
545 switch (htprot) {
546 case IEEE80211_HTPROT_NONE:
547 printf(",htprot none");
548 break;
549 case IEEE80211_HTPROT_NONMEMBER:
550 printf(",htprot non-member");
551 break;
552 case IEEE80211_HTPROT_20MHZ:
553 printf(",htprot 20MHz");
554 break;
555 case IEEE80211_HTPROT_NONHT_MIXED:
556 printf(",htprot non-HT-mixed");
557 break;
558 default:
559 printf(",htprot %d", htprot);
560 break;
561 }
562
563 /* non-greenfield STA present */
564 if (htopinfo[1] & IEEE80211_HTOP1_NONGF_STA0x0004)
565 printf(",non-greenfield STA");
566
567 /* non-HT STA present */
568 if (htopinfo[1] & IEEE80211_HTOP1_OBSS_NONHT_STA0x0010)
569 printf(",non-HT STA");
570
571 htopinfo[3] = data[4];
572
573 /* dual-beacon */
574 if (htopinfo[3] & IEEE80211_HTOP2_DUALBEACON0x0040)
575 printf(",dualbeacon");
576
577 /* dual CTS protection */
578 if (htopinfo[3] & IEEE80211_HTOP2_DUALCTSPROT0x0080)
579 printf(",dualctsprot");
580
581 htopinfo[4] = data[5];
582
583 /* space-time block coding (STBC) beacon */
584 if ((htopinfo[4] << 8) & IEEE80211_HTOP2_STBCBEACON0x0100)
585 printf(",STBC beacon");
586
587 /* L-SIG (non-HT signal field) TX opportunity (TXOP) protection */
588 if ((htopinfo[4] << 8) & IEEE80211_HTOP2_LSIGTXOP0x0200)
589 printf(",lsigtxprot");
590
591 /* phased-coexistence operation (PCO) active */
592 if ((htopinfo[4] << 8) & IEEE80211_HTOP2_PCOACTIVE0x0400) {
593 /* PCO phase */
594 if ((htopinfo[4] << 8) & IEEE80211_HTOP2_PCOPHASE400x0800)
595 printf(",pco40MHz");
596 else
597 printf(",pco20MHz");
598 }
599
600 /* basic MCS set */
601 memcpy(basic_mcs, &data[6], sizeof(basic_mcs));
602 printf(",basic MCS set 0x");
603 for (i = 0; i < sizeof(basic_mcs) / sizeof(basic_mcs[0]); i++)
604 printf("%x", basic_mcs[i]);
605
606 printf(">");
607}
608
609void
610ieee80211_print_rsncipher(uint8_t selector[4])
611{
612 if (memcmp(selector, MICROSOFT_OUI((const u_int8_t[]){ 0x00, 0x50, 0xf2 }), 3) != 0 &&
613 memcmp(selector, IEEE80211_OUI((const u_int8_t[]){ 0x00, 0x0f, 0xac }), 3) != 0) {
614 printf("0x%x%x%x%x", selector[0], selector[1], selector[2],
615 selector[3]);
616 return;
617 }
618
619 /* See 802.11-2012 Table 8-99 */
620 switch (selector[3]) {
621 case 0: /* use group data cipher suite */
622 printf("usegroup");
623 break;
624 case 1: /* WEP-40 */
625 printf("wep40");
626 break;
627 case 2: /* TKIP */
628 printf("tkip");
629 break;
630 case 4: /* CCMP (RSNA default) */
631 printf("ccmp");
632 break;
633 case 5: /* WEP-104 */
634 printf("wep104");
635 break;
636 case 6: /* BIP */
637 printf("bip");
638 break;
639 default:
640 printf("%d", selector[3]);
641 break;
642 }
643}
644
645void
646ieee80211_print_akm(uint8_t selector[4])
647{
648 if (memcmp(selector, MICROSOFT_OUI((const u_int8_t[]){ 0x00, 0x50, 0xf2 }), 3) != 0 &&
649 memcmp(selector, IEEE80211_OUI((const u_int8_t[]){ 0x00, 0x0f, 0xac }), 3) != 0) {
650 printf("0x%x%x%x%x", selector[0], selector[1], selector[2],
651 selector[3]);
652 return;
653 }
654
655 switch (selector[3]) {
656 case 1:
657 printf("802.1x");
658 break;
659 case 2:
660 printf("PSK");
661 break;
662 case 5:
663 printf("SHA256-802.1x");
664 break;
665 case 6:
666 printf("SHA256-PSK");
667 break;
668 default:
669 printf("%d", selector[3]);
670 break;
671 }
672}
673
674/* Caller checks len */
675void
676ieee80211_print_rsn(u_int8_t *data, u_int len)
677{
678 uint16_t version, nciphers, nakms, rsncap, npmk;
679 int i, j;
680 uint8_t selector[4];
681
682 if (len < 2) {
683 ieee80211_print_element(data, len);
684 return;
685 }
686
687 version = (data[0]) | (data[1] << 8);
688 printf("=<version %d", version);
689
690 if (len < 6) {
691 printf(">");
692 return;
693 }
694
695 data += 2;
696 printf(",groupcipher ");
697 for (i = 0; i < 4; i++)
698 selector[i] = data[i];
699 ieee80211_print_rsncipher(selector);
700
701 if (len < 8) {
702 printf(">");
703 return;
704 }
705
706 data += 4;
707 nciphers = (data[0]) | ((data[1]) << 8);
708 data += 2;
709
710 if (len < 8 + (nciphers * 4)) {
711 printf(">");
712 return;
713 }
714
715 printf(",cipher%s ", nciphers > 1 ? "s" : "");
716 for (i = 0; i < nciphers; i++) {
717 for (j = 0; j < 4; j++)
718 selector[j] = data[i + j];
719 ieee80211_print_rsncipher(selector);
720 if (i < nciphers - 1)
721 printf(" ");
722 data += 4;
723 }
724
725 if (len < 8 + (nciphers * 4) + 2) {
726 printf(">");
727 return;
728 }
729
730 nakms = (data[0]) | ((data[1]) << 8);
731 data += 2;
732
733 if (len < 8 + (nciphers * 4) + 2 + (nakms * 4)) {
734 printf(">");
735 return;
736 }
737
738 printf(",akm%s ", nakms > 1 ? "s" : "");
739 for (i = 0; i < nciphers; i++) {
740 for (j = 0; j < 4; j++)
741 selector[j] = data[i + j];
742 ieee80211_print_akm(selector);
743 if (i < nciphers - 1)
744 printf(" ");
745 data += 4;
746 }
747
748 if (len < 8 + (nciphers * 4) + 2 + (nakms * 4) + 2) {
749 printf(">");
750 return;
751 }
752
753 rsncap = (data[0]) | ((data[1]) << 8);
754 printf(",rsncap 0x%x", rsncap);
755 data += 2;
756
757 if (len < 8 + (nciphers * 4) + 2 + (nakms * 4) + 2 + 2) {
758 printf(">");
759 return;
760 }
761
762 npmk = (data[0]) | ((data[1]) << 8);
763 data += 2;
764
765 if (len < 8 + (nciphers * 4) + 2 + (nakms * 4) + 2 + 2 +
766 (npmk * IEEE80211_PMKID_LEN16)) {
767 printf(">");
768 return;
769 }
770
771 if (npmk >= 1)
772 printf(",pmkid%s ", npmk > 1 ? "s" : "");
773 for (i = 0; i < npmk; i++) {
774 printf("0x");
775 for (j = 0; j < IEEE80211_PMKID_LEN16; j++)
776 printf("%x", data[i + j]);
777 if (i < npmk - 1)
778 printf(" ");
779 data += IEEE80211_PMKID_LEN16;
780 }
781
782 if (len < 8 + (nciphers * 4) + 2 + (nakms * 4) + 2 + 2 +
783 (npmk * IEEE80211_PMKID_LEN16) + 4) {
784 printf(">");
785 return;
786 }
787
788 printf(",integrity-groupcipher ");
789 for (i = 0; i < 4; i++)
790 selector[i] = data[i];
791 ieee80211_print_rsncipher(selector);
792
793 printf(">");
794}
795
796int
797ieee80211_print_beacon(struct ieee80211_frame *wh, u_int len)
798{
799 uint64_t tstamp;
800 uint16_t bintval, capinfo;
801 uint8_t *frm;
802
803 if (len < sizeof(tstamp) + sizeof(bintval) + sizeof(capinfo))
804 return 1; /* truncated */
805
806 frm = (u_int8_t *)&wh[1];
807
808 bcopy(frm, &tstamp, sizeof(u_int64_t));
809 frm += 8;
810 if (vflag > 1)
811 printf(", timestamp %llu", letoh64(tstamp)((__uint64_t)(tstamp)));
812
813 bcopy(frm, &bintval, sizeof(u_int16_t));
814 frm += 2;
815 if (vflag > 1)
816 printf(", interval %u", letoh16(bintval)((__uint16_t)(bintval)));
817
818 bcopy(frm, &capinfo, sizeof(u_int16_t));
819 frm += 2;
820 if (vflag)
821 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"
);
822
823 return ieee80211_print_elements(frm);
824}
825
826int
827ieee80211_print_assocreq(struct ieee80211_frame *wh, u_int len)
828{
829 uint8_t subtype;
830 uint16_t capinfo, lintval;
831 uint8_t *frm;
832
833 subtype = wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK0xf0;
834
835 if (len < sizeof(capinfo) + sizeof(lintval) +
836 (subtype == IEEE80211_FC0_SUBTYPE_REASSOC_REQ0x20 ?
837 IEEE80211_ADDR_LEN6 : 0))
838 return 1; /* truncated */
839
840 frm = (u_int8_t *)&wh[1];
841
842 bcopy(frm, &capinfo, sizeof(u_int16_t));
843 frm += 2;
844 if (vflag)
845 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"
);
846
847 bcopy(frm, &lintval, sizeof(u_int16_t));
848 frm += 2;
849 if (vflag > 1)
850 printf(", listen interval %u", letoh16(lintval)((__uint16_t)(lintval)));
851
852 if (subtype == IEEE80211_FC0_SUBTYPE_REASSOC_REQ0x20) {
853 if (vflag)
854 printf(", AP %s", etheraddr_string(frm));
855 frm += IEEE80211_ADDR_LEN6;
856 }
857
858 return ieee80211_print_elements(frm);
859}
860
861int
862ieee80211_print_elements(uint8_t *frm)
863{
864 int i;
865
866 while (TTEST2(*frm, 2)(snapend - (2) <= snapend && (const u_char *)&
(*frm) <= snapend - (2))
) {
867 u_int len = frm[1];
868 u_int8_t *data = frm + 2;
869
870 if (!TTEST2(*data, len)(snapend - (len) <= snapend && (const u_char *)&
(*data) <= snapend - (len))
)
871 break;
872
873#define ELEM_CHECK(l) if (len != l) goto trunc
874
875 switch (*frm) {
876 case IEEE80211_ELEMID_SSID:
877 printf(", ssid");
878 ieee80211_print_essid(data, len);
879 break;
880 case IEEE80211_ELEMID_RATES:
881 printf(", rates");
882 if (!vflag)
883 break;
884 for (i = len; i > 0; i--, data++)
885 printf(" %uM%s",
886 (data[0] & IEEE80211_RATE_VAL0x7f) / 2,
887 (data[0] & IEEE80211_RATE_BASIC0x80
888 ? "*" : ""));
889 break;
890 case IEEE80211_ELEMID_FHPARMS:
891 ELEM_CHECK(5);
892 printf(", fh (dwell %u, chan %u, index %u)",
893 (data[1] << 8) | data[0],
894 (data[2] - 1) * 80 + data[3], /* FH_CHAN */
895 data[4]);
896 break;
897 case IEEE80211_ELEMID_DSPARMS:
898 ELEM_CHECK(1);
899 printf(", ds");
900 if (vflag)
901 printf(" (chan %u)", data[0]);
902 break;
903 case IEEE80211_ELEMID_CFPARMS:
904 printf(", cf");
905 if (vflag)
906 ieee80211_print_element(data, len);
907 break;
908 case IEEE80211_ELEMID_TIM:
909 printf(", tim");
910 if (vflag)
911 ieee80211_print_element(data, len);
912 break;
913 case IEEE80211_ELEMID_IBSSPARMS:
914 printf(", ibss");
915 if (vflag)
916 ieee80211_print_element(data, len);
917 break;
918 case IEEE80211_ELEMID_COUNTRY:
919 printf(", country");
920 if (vflag)
921 ieee80211_print_country(data, len);
922 break;
923 case IEEE80211_ELEMID_CHALLENGE:
924 printf(", challenge");
925 if (vflag)
926 ieee80211_print_element(data, len);
927 break;
928 case IEEE80211_ELEMID_CSA:
929 ELEM_CHECK(3);
930 printf(", csa (chan %u count %u%s)", data[1], data[2],
931 (data[0] == 1) ? " noTX" : "");
932 break;
933 case IEEE80211_ELEMID_ERP:
934 printf(", erp");
935 if (vflag)
936 ieee80211_print_element(data, len);
937 break;
938 case IEEE80211_ELEMID_RSN:
939 printf(", rsn");
940 if (vflag)
941 ieee80211_print_rsn(data, len);
942 break;
943 case IEEE80211_ELEMID_XRATES:
944 printf(", xrates");
945 if (!vflag)
946 break;
947 for (i = len; i > 0; i--, data++)
948 printf(" %uM",
949 (data[0] & IEEE80211_RATE_VAL0x7f) / 2);
950 break;
951 case IEEE80211_ELEMID_TPC_REPORT:
952 printf(", tpcreport");
953 if (vflag)
954 ieee80211_print_element(data, len);
955 break;
956 case IEEE80211_ELEMID_TPC_REQUEST:
957 printf(", tpcrequest");
958 if (vflag)
959 ieee80211_print_element(data, len);
960 break;
961 case IEEE80211_ELEMID_HTCAPS:
962 printf(", htcaps");
963 if (vflag)
964 ieee80211_print_htcaps(data, len);
965 break;
966 case IEEE80211_ELEMID_HTOP:
967 printf(", htop");
968 if (vflag)
969 ieee80211_print_htop(data, len);
970 break;
971 case IEEE80211_ELEMID_POWER_CONSTRAINT:
972 ELEM_CHECK(1);
973 printf(", power constraint %udB", data[0]);
974 break;
975 case IEEE80211_ELEMID_QBSS_LOAD:
976 ELEM_CHECK(5);
977 printf(", %u stations, %d%% utilization, "
978 "admission capacity %uus/s",
979 (data[0] | data[1] << 8),
980 (data[2] * 100) / 255,
981 (data[3] | data[4] << 8) / 32);
982 break;
983 case IEEE80211_ELEMID_VENDOR:
984 printf(", vendor");
985 if (vflag)
986 ieee80211_print_element(data, len);
987 break;
988 default:
989 printf(", %u:%u", (u_int) *frm, len);
990 if (vflag)
991 ieee80211_print_element(data, len);
992 break;
993 }
994 frm += len + 2;
995
996 if (frm >= snapend)
997 break;
998 }
999
1000#undef ELEM_CHECK
1001
1002 return (0);
1003
1004 trunc:
1005 /* Truncated elements in frame */
1006 return (1);
1007}
1008
1009int
1010ieee80211_frame(struct ieee80211_frame *wh, u_int len)
1011{
1012 u_int8_t subtype, type, *frm;
1013
1014 TCARR(wh->i_fc)if (!(snapend - (sizeof(wh->i_fc)) <= snapend &&
(const u_char *)&(*wh->i_fc) <= snapend - (sizeof(
wh->i_fc)))) goto trunc
;
1015
1016 type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK0x0c;
1017 subtype = wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK0xf0;
1018
1019 frm = (u_int8_t *)&wh[1];
1020
1021 if (vflag)
1022 printb(" flags", wh->i_fc[1], IEEE80211_FC1_BITS"\20\03MORE_FRAG\04RETRY\05PWR_MGT\06MORE_DATA" "\07PROTECTED\08ORDER");
1023
1024 switch (type) {
1025 case IEEE80211_FC0_TYPE_DATA0x08:
1026 printf(": %s: ", ieee80211_data_subtype_name[
1027 subtype >> IEEE80211_FC0_SUBTYPE_SHIFT4]);
1028 ieee80211_data(wh, len);
1029 break;
1030 case IEEE80211_FC0_TYPE_MGT0x00:
1031 printf(": %s", ieee80211_mgt_subtype_name[
1032 subtype >> IEEE80211_FC0_SUBTYPE_SHIFT4]);
1033 switch (subtype) {
1034 case IEEE80211_FC0_SUBTYPE_BEACON0x80:
1035 case IEEE80211_FC0_SUBTYPE_PROBE_RESP0x50:
1036 if (ieee80211_print_beacon(wh, len) != 0)
1037 goto trunc;
1038 break;
1039 case IEEE80211_FC0_SUBTYPE_ASSOC_REQ0x00:
1040 case IEEE80211_FC0_SUBTYPE_REASSOC_REQ0x20:
1041 if (ieee80211_print_assocreq(wh, len) != 0)
1042 goto trunc;
1043 break;
1044 case IEEE80211_FC0_SUBTYPE_AUTH0xb0:
1045 TCHECK2(*frm, 2)if (!(snapend - (2) <= snapend && (const u_char *)
&(*frm) <= snapend - (2))) goto trunc
; /* Auth Algorithm */
1046 switch (IEEE80211_AUTH_ALGORITHM(frm)((frm)[0] | ((frm)[1] << 8))) {
1047 case IEEE80211_AUTH_ALG_OPEN0x0000:
1048 TCHECK2(*frm, 4)if (!(snapend - (4) <= snapend && (const u_char *)
&(*frm) <= snapend - (4))) goto trunc
; /* Auth Transaction */
1049 switch (IEEE80211_AUTH_TRANSACTION(frm)((frm)[2] | ((frm)[3] << 8))) {
1050 case IEEE80211_AUTH_OPEN_REQUEST:
1051 printf(" request");
1052 break;
1053 case IEEE80211_AUTH_OPEN_RESPONSE:
1054 printf(" response");
1055 break;
1056 }
1057 break;
1058 case IEEE80211_AUTH_ALG_SHARED0x0001:
1059 TCHECK2(*frm, 4)if (!(snapend - (4) <= snapend && (const u_char *)
&(*frm) <= snapend - (4))) goto trunc
; /* Auth Transaction */
1060 switch (IEEE80211_AUTH_TRANSACTION(frm)((frm)[2] | ((frm)[3] << 8))) {
1061 case IEEE80211_AUTH_SHARED_REQUEST:
1062 printf(" request");
1063 break;
1064 case IEEE80211_AUTH_SHARED_CHALLENGE:
1065 printf(" challenge");
1066 break;
1067 case IEEE80211_AUTH_SHARED_RESPONSE:
1068 printf(" response");
1069 break;
1070 case IEEE80211_AUTH_SHARED_PASS:
1071 printf(" pass");
1072 break;
1073 }
1074 break;
1075 case IEEE80211_AUTH_ALG_LEAP0x0080:
1076 printf(" (leap)");
1077 break;
1078 }
1079 break;
1080 case IEEE80211_FC0_SUBTYPE_DEAUTH0xc0:
1081 case IEEE80211_FC0_SUBTYPE_DISASSOC0xa0:
1082 TCHECK2(*frm, 2)if (!(snapend - (2) <= snapend && (const u_char *)
&(*frm) <= snapend - (2))) goto trunc
; /* Reason Code */
1083 ieee80211_reason(frm[0] | (frm[1] << 8));
1084 break;
1085 }
1086 break;
1087 case IEEE80211_FC0_TYPE_CTL0x04: {
1088 u_int8_t *t = (u_int8_t *) wh;
1089
1090 printf(": %s", ieee80211_ctl_subtype_name[
1091 subtype >> IEEE80211_FC0_SUBTYPE_SHIFT4]);
1092 if (!vflag)
1093 break;
1094
1095 /* See 802.11 2012 "8.3.1 Control frames". */
1096 t += 2; /* skip Frame Control */
1097 switch (subtype) {
1098 case IEEE80211_FC0_SUBTYPE_RTS0xb0:
1099 case IEEE80211_FC0_SUBTYPE_BAR0x80:
1100 case IEEE80211_FC0_SUBTYPE_BA0x90:
1101 TCHECK2(*t, 2)if (!(snapend - (2) <= snapend && (const u_char *)
&(*t) <= snapend - (2))) goto trunc
; /* Duration */
1102 printf(", duration %dus", (t[0] | t[1] << 8));
1103 t += 2;
1104 TCHECK2(*t, 6)if (!(snapend - (6) <= snapend && (const u_char *)
&(*t) <= snapend - (6))) goto trunc
; /* RA */
1105 printf(", ra %s", etheraddr_string(t));
1106 t += 6;
1107 TCHECK2(*t, 6)if (!(snapend - (6) <= snapend && (const u_char *)
&(*t) <= snapend - (6))) goto trunc
; /* TA */
1108 printf(", ta %s", etheraddr_string(t));
1109 if (subtype == IEEE80211_FC0_SUBTYPE_BAR0x80 ||
1110 subtype == IEEE80211_FC0_SUBTYPE_BA0x90) {
1111 u_int16_t ctrl;
1112
1113 t += 6;
1114 TCHECK2(*t, 2)if (!(snapend - (2) <= snapend && (const u_char *)
&(*t) <= snapend - (2))) goto trunc
; /* BAR/BA control */
1115 ctrl = t[0] | (t[1] << 8);
1116 if (ctrl & IEEE80211_BA_ACK_POLICY0x0001)
1117 printf(", no ack");
1118 else
1119 printf(", normal ack");
1120 if ((ctrl & IEEE80211_BA_MULTI_TID0x0002) == 0 &&
1121 (ctrl & IEEE80211_BA_COMPRESSED0x0004) == 0)
1122 printf(", basic variant");
1123 else if ((ctrl & IEEE80211_BA_MULTI_TID0x0002) &&
1124 (ctrl & IEEE80211_BA_COMPRESSED0x0004))
1125 printf(", multi-tid variant");
1126 else if (ctrl & IEEE80211_BA_COMPRESSED0x0004)
1127 printf(", compressed variant");
1128 }
1129 break;
1130 case IEEE80211_FC0_SUBTYPE_CTS0xc0:
1131 case IEEE80211_FC0_SUBTYPE_ACK0xd0:
1132 TCHECK2(*t, 2)if (!(snapend - (2) <= snapend && (const u_char *)
&(*t) <= snapend - (2))) goto trunc
; /* Duration */
1133 printf(", duration %dus", (t[0] | t[1] << 8));
1134 t += 2;
1135 TCHECK2(*t, 6)if (!(snapend - (6) <= snapend && (const u_char *)
&(*t) <= snapend - (6))) goto trunc
; /* RA */
1136 printf(", ra %s", etheraddr_string(t));
1137 break;
1138 case IEEE80211_FC0_SUBTYPE_PS_POLL0xa0:
1139 TCHECK2(*t, 2)if (!(snapend - (2) <= snapend && (const u_char *)
&(*t) <= snapend - (2))) goto trunc
; /* AID */
1140 printf(", aid 0x%x", (t[0] | t[1] << 8));
1141 t += 2;
1142 TCHECK2(*t, 6)if (!(snapend - (6) <= snapend && (const u_char *)
&(*t) <= snapend - (6))) goto trunc
; /* BSSID(RA) */
1143 printf(", ra %s", etheraddr_string(t));
1144 t += 6;
1145 TCHECK2(*t, 6)if (!(snapend - (6) <= snapend && (const u_char *)
&(*t) <= snapend - (6))) goto trunc
; /* TA */
1146 printf(", ta %s", etheraddr_string(t));
1147 break;
1148 }
1149 break;
1150 }
1151 default:
1152 printf(": type#%d", type);
1153 break;
1154 }
1155
1156 return (0);
1157
1158 trunc:
1159 /* Truncated 802.11 frame */
1160 return (1);
1161}
1162
1163u_int
1164ieee80211_any2ieee(u_int freq, u_int flags)
1165{
1166 if (flags & IEEE80211_CHAN_2GHZ0x0080) {
1167 if (freq == 2484)
1168 return 14;
1169 if (freq < 2484)
1170 return (freq - 2407) / 5;
1171 else
1172 return 15 + ((freq - 2512) / 20);
1173 } else if (flags & IEEE80211_CHAN_5GHZ0x0100) {
1174 return (freq - 5000) / 5;
1175 } else {
1176 /* Assume channel is already an IEEE number */
1177 return (freq);
1178 }
1179}
1180
1181int
1182ieee80211_print(struct ieee80211_frame *wh, u_int len)
1183{
1184 if (eflag)
1185 if (ieee80211_hdr(wh))
1186 return (1);
1187
1188 printf("802.11");
1189
1190 return (ieee80211_frame(wh, len));
1191}
1192
1193void
1194ieee802_11_if_print(u_char *user, const struct pcap_pkthdr *h,
1195 const u_char *p)
1196{
1197 struct ieee80211_frame *wh = (struct ieee80211_frame*)p;
1198
1199 if (!ieee80211_encap)
1200 ts_print(&h->ts);
1201
1202 packetp = p;
1203 snapend = p + h->caplen;
1204
1205 if (ieee80211_print(wh, (u_int)h->len) != 0)
1206 printf("[|802.11]");
1207
1208 if (!ieee80211_encap) {
1209 if (xflag)
1210 default_print(p, (u_int)h->len);
1211 putchar('\n')(!__isthreaded ? __sputc('\n', (&__sF[1])) : (putc)('\n',
(&__sF[1])))
;
1212 }
1213}
1214
1215void
1216ieee802_11_radio_if_print(u_char *user, const struct pcap_pkthdr *h,
1217 const u_char *p)
1218{
1219 struct ieee80211_radiotap_header *rh =
1220 (struct ieee80211_radiotap_header*)p;
1221 struct ieee80211_frame *wh;
1222 u_int8_t *t;
1223 u_int32_t present;
1224 u_int len, rh_len;
1225 u_int16_t tmp;
1226
1227 if (!ieee80211_encap)
1228 ts_print(&h->ts);
1229
1230 packetp = p;
1231 snapend = p + h->caplen;
1232
1233 TCHECK(*rh)if (!(snapend - (sizeof(*rh)) <= snapend && (const
u_char *)&(*rh) <= snapend - (sizeof(*rh)))) goto trunc
;
1234
1235 len = h->len;
1236 rh_len = letoh16(rh->it_len)((__uint16_t)(rh->it_len));
1237 if (rh->it_version != 0) {
1238 printf("[?radiotap + 802.11 v:%u]", rh->it_version);
1239 goto out;
1240 }
1241
1242 wh = (struct ieee80211_frame *)(p + rh_len);
1243 if (len <= rh_len || ieee80211_print(wh, len - rh_len))
1244 printf("[|802.11]");
1245
1246 t = (u_int8_t*)p + sizeof(struct ieee80211_radiotap_header);
1247
1248 if ((present = letoh32(rh->it_present)((__uint32_t)(rh->it_present))) == 0)
1249 goto out;
1250
1251 printf(", <radiotap v%u", rh->it_version);
1252
1253#define RADIOTAP(_x) \
1254 (present & (1 << IEEE80211_RADIOTAP_##_x))
1255
1256 if (RADIOTAP(TSFT)) {
1257 u_int64_t tsf;
1258
1259 TCHECK2(*t, 8)if (!(snapend - (8) <= snapend && (const u_char *)
&(*t) <= snapend - (8))) goto trunc
;
1260 bcopy(t, &tsf, sizeof(u_int64_t));
1261 if (vflag > 1)
1262 printf(", tsf %llu", letoh64(tsf)((__uint64_t)(tsf)));
1263 t += 8;
1264 }
1265
1266 if (RADIOTAP(FLAGS)) {
1267 u_int8_t flags = *(u_int8_t*)t;
1268 TCHECK2(*t, 1)if (!(snapend - (1) <= snapend && (const u_char *)
&(*t) <= snapend - (1))) goto trunc
;
1269
1270 if (flags & IEEE80211_RADIOTAP_F_CFP0x01)
1271 printf(", CFP");
1272 if (flags & IEEE80211_RADIOTAP_F_SHORTPRE0x02)
1273 printf(", SHORTPRE");
1274 if (flags & IEEE80211_RADIOTAP_F_WEP0x04)
1275 printf(", WEP");
1276 if (flags & IEEE80211_RADIOTAP_F_FRAG0x08)
1277 printf(", FRAG");
1278 t += 1;
1279 }
1280
1281 if (RADIOTAP(RATE)) {
1282 TCHECK2(*t, 1)if (!(snapend - (1) <= snapend && (const u_char *)
&(*t) <= snapend - (1))) goto trunc
;
1283 if (vflag) {
1284 uint8_t rate = *(u_int8_t*)t;
1285 if (rate & 0x80)
1286 printf(", MCS %u", rate & 0x7f);
1287 else
1288 printf(", %uMbit/s", rate / 2);
1289 }
1290 t += 1;
1291 }
1292
1293 if (RADIOTAP(CHANNEL)) {
1294 u_int16_t freq, flags;
1295 TCHECK2(*t, 2)if (!(snapend - (2) <= snapend && (const u_char *)
&(*t) <= snapend - (2))) goto trunc
;
1296
1297 bcopy(t, &freq, sizeof(u_int16_t));
1298 freq = letoh16(freq)((__uint16_t)(freq));
1299 t += 2;
1300 TCHECK2(*t, 2)if (!(snapend - (2) <= snapend && (const u_char *)
&(*t) <= snapend - (2))) goto trunc
;
1301 bcopy(t, &flags, sizeof(u_int16_t));
1302 flags = letoh16(flags)((__uint16_t)(flags));
1303 t += 2;
1304
1305 printf(", chan %u", ieee80211_any2ieee(freq, flags));
1306
1307 if (flags & IEEE80211_CHAN_HT0x2000)
1308 printf(", 11n");
1309 else if (flags & IEEE80211_CHAN_DYN0x0400 &&
1310 flags & IEEE80211_CHAN_2GHZ0x0080)
1311 printf(", 11g");
1312 else if (flags & IEEE80211_CHAN_CCK0x0020 &&
1313 flags & IEEE80211_CHAN_2GHZ0x0080)
1314 printf(", 11b");
1315 else if (flags & IEEE80211_CHAN_OFDM0x0040 &&
1316 flags & IEEE80211_CHAN_2GHZ0x0080)
1317 printf(", 11G");
1318 else if (flags & IEEE80211_CHAN_OFDM0x0040 &&
1319 flags & IEEE80211_CHAN_5GHZ0x0100)
1320 printf(", 11a");
1321
1322 if (flags & IEEE80211_CHAN_XR0x1000)
1323 printf(", XR");
1324 }
1325
1326 if (RADIOTAP(FHSS)) {
1327 TCHECK2(*t, 2)if (!(snapend - (2) <= snapend && (const u_char *)
&(*t) <= snapend - (2))) goto trunc
;
1328 printf(", fhss %u/%u", *(u_int8_t*)t, *(u_int8_t*)t + 1);
1329 t += 2;
1330 }
1331
1332 if (RADIOTAP(DBM_ANTSIGNAL)) {
1333 TCHECK(*t)if (!(snapend - (sizeof(*t)) <= snapend && (const u_char
*)&(*t) <= snapend - (sizeof(*t)))) goto trunc
;
1334 printf(", sig %ddBm", *(int8_t*)t);
1335 t += 1;
1336 }
1337
1338 if (RADIOTAP(DBM_ANTNOISE)) {
1339 TCHECK(*t)if (!(snapend - (sizeof(*t)) <= snapend && (const u_char
*)&(*t) <= snapend - (sizeof(*t)))) goto trunc
;
1340 printf(", noise %ddBm", *(int8_t*)t);
1341 t += 1;
1342 }
1343
1344 if (RADIOTAP(LOCK_QUALITY)) {
1345 TCHECK2(*t, 2)if (!(snapend - (2) <= snapend && (const u_char *)
&(*t) <= snapend - (2))) goto trunc
;
1346 if (vflag) {
1347 bcopy(t, &tmp, sizeof(u_int16_t));
1348 printf(", quality %u", letoh16(tmp)((__uint16_t)(tmp)));
1349 }
1350 t += 2;
1351 }
1352
1353 if (RADIOTAP(TX_ATTENUATION)) {
1354 TCHECK2(*t, 2)if (!(snapend - (2) <= snapend && (const u_char *)
&(*t) <= snapend - (2))) goto trunc
;
1355 if (vflag) {
1356 bcopy(t, &tmp, sizeof(u_int16_t));
1357 printf(", txatt %u", letoh16(tmp)((__uint16_t)(tmp)));
1358 }
1359 t += 2;
1360 }
1361
1362 if (RADIOTAP(DB_TX_ATTENUATION)) {
1363 TCHECK2(*t, 2)if (!(snapend - (2) <= snapend && (const u_char *)
&(*t) <= snapend - (2))) goto trunc
;
1364 if (vflag) {
1365 bcopy(t, &tmp, sizeof(u_int16_t));
1366 printf(", txatt %udB", letoh16(tmp)((__uint16_t)(tmp)));
1367 }
1368 t += 2;
1369 }
1370
1371 if (RADIOTAP(DBM_TX_POWER)) {
1372 TCHECK(*t)if (!(snapend - (sizeof(*t)) <= snapend && (const u_char
*)&(*t) <= snapend - (sizeof(*t)))) goto trunc
;
1373 printf(", txpower %ddBm", *(int8_t*)t);
1374 t += 1;
1375 }
1376
1377 if (RADIOTAP(ANTENNA)) {
1378 TCHECK(*t)if (!(snapend - (sizeof(*t)) <= snapend && (const u_char
*)&(*t) <= snapend - (sizeof(*t)))) goto trunc
;
1379 if (vflag)
1380 printf(", antenna %u", *(u_int8_t*)t);
1381 t += 1;
1382 }
1383
1384 if (RADIOTAP(DB_ANTSIGNAL)) {
1385 TCHECK(*t)if (!(snapend - (sizeof(*t)) <= snapend && (const u_char
*)&(*t) <= snapend - (sizeof(*t)))) goto trunc
;
1386 printf(", signal %udB", *(u_int8_t*)t);
1387 t += 1;
1388 }
1389
1390 if (RADIOTAP(DB_ANTNOISE)) {
1391 TCHECK(*t)if (!(snapend - (sizeof(*t)) <= snapend && (const u_char
*)&(*t) <= snapend - (sizeof(*t)))) goto trunc
;
1392 printf(", noise %udB", *(u_int8_t*)t);
1393 t += 1;
1394 }
1395
1396 if (RADIOTAP(FCS)) {
1397 TCHECK2(*t, 4)if (!(snapend - (4) <= snapend && (const u_char *)
&(*t) <= snapend - (4))) goto trunc
;
1398 if (vflag) {
1399 u_int32_t fcs;
1400 bcopy(t, &fcs, sizeof(u_int32_t));
1401 printf(", fcs %08x", letoh32(fcs)((__uint32_t)(fcs)));
1402 }
1403 t += 4;
1404 }
1405
1406 if (RADIOTAP(RSSI)) {
1407 u_int8_t rssi, max_rssi;
1408 TCHECK(*t)if (!(snapend - (sizeof(*t)) <= snapend && (const u_char
*)&(*t) <= snapend - (sizeof(*t)))) goto trunc
;
1409 rssi = *(u_int8_t*)t;
1410 t += 1;
1411 TCHECK(*t)if (!(snapend - (sizeof(*t)) <= snapend && (const u_char
*)&(*t) <= snapend - (sizeof(*t)))) goto trunc
;
1412 max_rssi = *(u_int8_t*)t;
1413 t += 1;
Value stored to 't' is never read
1414
1415 printf(", rssi %u/%u", rssi, max_rssi);
1416 }
1417
1418#undef RADIOTAP
1419
1420 putchar('>')(!__isthreaded ? __sputc('>', (&__sF[1])) : (putc)('>'
, (&__sF[1])))
;
1421 goto out;
1422
1423 trunc:
1424 /* Truncated frame */
1425 printf("[|radiotap + 802.11]");
1426
1427 out:
1428 if (!ieee80211_encap) {
1429 if (xflag)
1430 default_print(p, h->len);
1431 putchar('\n')(!__isthreaded ? __sputc('\n', (&__sF[1])) : (putc)('\n',
(&__sF[1])))
;
1432 }
1433}
1434
1435void
1436ieee80211_reason(u_int16_t reason)
1437{
1438 if (!vflag)
1439 return;
1440
1441 switch (reason) {
1442 case IEEE80211_REASON_UNSPECIFIED:
1443 printf(", unspecified failure");
1444 break;
1445 case IEEE80211_REASON_AUTH_EXPIRE:
1446 printf(", authentication expired");
1447 break;
1448 case IEEE80211_REASON_AUTH_LEAVE:
1449 printf(", deauth - station left");
1450 break;
1451 case IEEE80211_REASON_ASSOC_EXPIRE:
1452 printf(", association expired");
1453 break;
1454 case IEEE80211_REASON_ASSOC_TOOMANY:
1455 printf(", too many associated stations");
1456 break;
1457 case IEEE80211_REASON_NOT_AUTHED:
1458 printf(", not authenticated");
1459 break;
1460 case IEEE80211_REASON_NOT_ASSOCED:
1461 printf(", not associated");
1462 break;
1463 case IEEE80211_REASON_ASSOC_LEAVE:
1464 printf(", disassociated - station left");
1465 break;
1466 case IEEE80211_REASON_ASSOC_NOT_AUTHED:
1467 printf(", association but not authenticated");
1468 break;
1469 case IEEE80211_REASON_RSN_REQUIRED:
1470 printf(", rsn required");
1471 break;
1472 case IEEE80211_REASON_RSN_INCONSISTENT:
1473 printf(", rsn inconsistent");
1474 break;
1475 case IEEE80211_REASON_IE_INVALID:
1476 printf(", ie invalid");
1477 break;
1478 case IEEE80211_REASON_MIC_FAILURE:
1479 printf(", mic failure");
1480 break;
1481 default:
1482 printf(", unknown reason %u", reason);
1483 }
1484}