xref: /openbsd-src/usr.sbin/tcpdump/print-802_11.c (revision c1a45aed656e7d5627c30c92421893a76f370ccb)
1 /*	$OpenBSD: print-802_11.c,v 1.42 2022/03/17 14:00:53 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)	TCHECK2(*a, sizeof(a))
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_MASK) {
127 	case IEEE80211_FC1_DIR_NODS:
128 		TCARR(wh->i_addr2);
129 		printf("%s", etheraddr_string(wh->i_addr2));
130 		TCARR(wh->i_addr1);
131 		printf(" > %s", etheraddr_string(wh->i_addr1));
132 		TCARR(wh->i_addr3);
133 		printf(", bssid %s", etheraddr_string(wh->i_addr3));
134 		break;
135 	case IEEE80211_FC1_DIR_TODS:
136 		TCARR(wh->i_addr2);
137 		printf("%s", etheraddr_string(wh->i_addr2));
138 		TCARR(wh->i_addr3);
139 		printf(" > %s", etheraddr_string(wh->i_addr3));
140 		TCARR(wh->i_addr1);
141 		printf(", bssid %s, > DS", etheraddr_string(wh->i_addr1));
142 		break;
143 	case IEEE80211_FC1_DIR_FROMDS:
144 		TCARR(wh->i_addr3);
145 		printf("%s", etheraddr_string(wh->i_addr3));
146 		TCARR(wh->i_addr1);
147 		printf(" > %s", etheraddr_string(wh->i_addr1));
148 		TCARR(wh->i_addr2);
149 		printf(", bssid %s, DS >", etheraddr_string(wh->i_addr2));
150 		break;
151 	case IEEE80211_FC1_DIR_DSTODS:
152 		w4 = (struct ieee80211_frame_addr4 *) wh;
153 		TCARR(w4->i_addr4);
154 		printf("%s", etheraddr_string(w4->i_addr4));
155 		TCARR(w4->i_addr3);
156 		printf(" > %s", etheraddr_string(w4->i_addr3));
157 		TCARR(w4->i_addr2);
158 		printf(", bssid %s", etheraddr_string(w4->i_addr2));
159 		TCARR(w4->i_addr1);
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);
166 		bcopy(wh->i_seq, &seq, sizeof(u_int16_t));
167 		printf(" (seq %u frag %u): ",
168 		    letoh16(seq) >> IEEE80211_SEQ_SEQ_SHIFT,
169 		    letoh16(seq) & IEEE80211_SEQ_FRAG_MASK);
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_NODATA);
186 	int hasqos = ((wh->i_fc[0] &
187 	    (IEEE80211_FC0_TYPE_MASK | IEEE80211_FC0_SUBTYPE_QOS)) ==
188 	    (IEEE80211_FC0_TYPE_DATA | IEEE80211_FC0_SUBTYPE_QOS));
189 	u_char *esrc = NULL, *edst = NULL;
190 
191 	if (hasqos) {
192 		struct ieee80211_qosframe *wq;
193 
194 		wq = (struct ieee80211_qosframe *) wh;
195 		TCHECK(*wq);
196 		t += sizeof(*wq);
197 		datalen = len - sizeof(*wq);
198 	} else {
199 		TCHECK(*wh);
200 		t += sizeof(*wh);
201 		datalen = len - sizeof(*wh);
202 	}
203 
204 	switch (wh->i_fc[1] & IEEE80211_FC1_DIR_MASK) {
205 	case IEEE80211_FC1_DIR_TODS:
206 		esrc = wh->i_addr2;
207 		edst = wh->i_addr3;
208 		break;
209 	case IEEE80211_FC1_DIR_FROMDS:
210 		esrc = wh->i_addr3;
211 		edst = wh->i_addr1;
212 		break;
213 	case IEEE80211_FC1_DIR_NODS:
214 		esrc = wh->i_addr2;
215 		edst = wh->i_addr1;
216 		break;
217 	case IEEE80211_FC1_DIR_DSTODS:
218 		if (hasqos) {
219 			struct ieee80211_qosframe_addr4 *w4;
220 
221 			w4 = (struct ieee80211_qosframe_addr4 *) wh;
222 			TCHECK(*w4);
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);
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_LEN)
273 		len = IEEE80211_NWID_LEN;
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);
284 		putchar(')');
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_40)
352 		printf("20/40MHz");
353 	else
354 		printf("20MHz");
355 
356 	/* LDPC coding */
357 	if (htcaps & IEEE80211_HTCAP_LDPC)
358 		printf(",LDPC");
359 
360 	/* spatial multiplexing power save mode */
361 	smps = (htcaps & IEEE80211_HTCAP_SMPS_MASK)
362 	    >> IEEE80211_HTCAP_SMPS_SHIFT;
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_GF)
370 		printf(",greenfield");
371 
372 	/* short guard interval */
373 	if (htcaps & IEEE80211_HTCAP_SGI20)
374 		printf(",SGI@20MHz");
375 	if (htcaps & IEEE80211_HTCAP_SGI40)
376 		printf(",SGI@40MHz");
377 
378 	/* space-time block coding */
379 	if (htcaps & IEEE80211_HTCAP_TXSTBC)
380 		printf(",TXSTBC");
381 	rxstbc = (htcaps & IEEE80211_HTCAP_RXSTBC_MASK)
382 	    >> IEEE80211_HTCAP_RXSTBC_SHIFT;
383 	if (rxstbc > 0 && rxstbc < 4)
384 		printf(",RXSTBC %d stream", rxstbc);
385 
386 	/* delayed block-ack */
387 	if (htcaps & IEEE80211_HTCAP_DELAYEDBA)
388 		printf(",delayed BA");
389 
390 	/* max A-MSDU length */
391 	if (htcaps & IEEE80211_HTCAP_AMSDU7935)
392 		printf(",A-MSDU 7935");
393 	else
394 		printf(",A-MSDU 3839");
395 
396 	/* DSSS/CCK in 40MHz mode */
397 	if (htcaps & IEEE80211_HTCAP_DSSSCCK40)
398 		printf(",DSSS/CCK@40MHz");
399 
400 	/* 40MHz intolerant */
401 	if (htcaps & IEEE80211_HTCAP_40INTOLERANT)
402 		printf(",40MHz intolerant");
403 
404 	/* L-SIG TXOP protection */
405 	if (htcaps & IEEE80211_HTCAP_LSIGTXOPPROT)
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_LE) >= 0 &&
418 	    (ampdu & IEEE80211_AMPDU_PARAM_LE) <= 3)
419 		printf(",A-MPDU max %d",
420 		    (1 << (13 + (ampdu & IEEE80211_AMPDU_PARAM_LE))) - 1);
421 
422 	/* A-MPDU start spacing */
423 	if (ampdu & IEEE80211_AMPDU_PARAM_SS) {
424 		float ss;
425 
426 		switch ((ampdu & IEEE80211_AMPDU_PARAM_SS) >> 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_HIGH);
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_DEFINED) {
475 		if (txmcs & IEEE80211_TX_RX_MCS_NOT_EQUAL) {
476 			/* Number of spatial Tx streams. */
477 			printf(",%d Tx streams",
478 			     1 + ((txmcs & IEEE80211_TX_SPATIAL_STREAMS) >> 2));
479 			/* Transmit unequal modulation supported. */
480 			if (txmcs & IEEE80211_TX_UNEQUAL_MODULATION)
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_MASK)
509 	    >> IEEE80211_HTOP0_SCO_SHIFT);
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_CHW) == 0)
536 		printf(",STA chanw 20MHz");
537 
538 	/* reduced interframe space (RIFS) permitted */
539 	if (htopinfo[0] & IEEE80211_HTOP0_RIFS)
540 		printf(",RIFS");
541 
542 	htopinfo[1] = data[2];
543 
544 	/* protection requirements for HT transmissions */
545 	htprot = ((htopinfo[1] & IEEE80211_HTOP1_PROT_MASK)
546 	    >> IEEE80211_HTOP1_PROT_SHIFT);
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_STA)
567 		printf(",non-greenfield STA");
568 
569 	/* non-HT STA present */
570 	if (htopinfo[1] & IEEE80211_HTOP1_OBSS_NONHT_STA)
571 		printf(",non-HT STA");
572 
573 	htopinfo[3] = data[4];
574 
575 	/* dual-beacon */
576 	if (htopinfo[3] & IEEE80211_HTOP2_DUALBEACON)
577 		printf(",dualbeacon");
578 
579 	/* dual CTS protection */
580 	if (htopinfo[3] & IEEE80211_HTOP2_DUALCTSPROT)
581 		printf(",dualctsprot");
582 
583 	htopinfo[4] = data[5];
584 
585 	/* space-time block coding (STBC) beacon */
586 	if ((htopinfo[4] << 8) & IEEE80211_HTOP2_STBCBEACON)
587 		printf(",STBC beacon");
588 
589 	/* L-SIG (non-HT signal field) TX opportunity (TXOP) protection */
590 	if ((htopinfo[4] << 8) & IEEE80211_HTOP2_LSIGTXOP)
591 		printf(",lsigtxprot");
592 
593 	/* phased-coexistence operation (PCO) active */
594 	if ((htopinfo[4] << 8) & IEEE80211_HTOP2_PCOACTIVE) {
595 		/* PCO phase */
596 		if ((htopinfo[4] << 8) & IEEE80211_HTOP2_PCOPHASE40)
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_SS; nss++) {
617 		mcs = (mcsmap & IEEE80211_VHT_MCS_FOR_SS_MASK(nss)) >>
618 		    IEEE80211_VHT_MCS_FOR_SS_SHIFT(nss);
619 		switch (mcs) {
620 		case IEEE80211_VHT_MCS_0_9:
621 			printf(" 0-9@%uSS", nss);
622 			break;
623 		case IEEE80211_VHT_MCS_0_8:
624 			printf(" 0-8@%uSS", nss);
625 			break;
626 		case IEEE80211_VHT_MCS_0_7:
627 			printf(" 0-7@%uSS", nss);
628 			break;
629 		case IEEE80211_VHT_MCS_SS_NOT_SUPP:
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_MASK) {
655 	case IEEE80211_VHTCAP_MAX_MPDU_LENGTH_11454:
656 		printf("max MPDU 11454");
657 		break;
658 	case IEEE80211_VHTCAP_MAX_MPDU_LENGTH_7991:
659 		printf("max MPDU 7991");
660 		break;
661 	case IEEE80211_VHTCAP_MAX_MPDU_LENGTH_3895:
662 	default:
663 		printf("max MPDU 3895");
664 		break;
665 	}
666 
667 	/* supported channel widths */
668 	switch ((vhtcaps & IEEE80211_VHTCAP_CHAN_WIDTH_MASK) <<
669 	    IEEE80211_VHTCAP_CHAN_WIDTH_SHIFT) {
670 	case IEEE80211_VHTCAP_CHAN_WIDTH_160_8080:
671 		printf(",80+80MHz");
672 		/* fallthrough */
673 	case IEEE80211_VHTCAP_CHAN_WIDTH_160:
674 		printf(",160MHz");
675 		/* fallthrough */
676 	case IEEE80211_VHTCAP_CHAN_WIDTH_80:
677 	default:
678 		printf(",80MHz");
679 		break;
680 	}
681 
682 	/* LDPC coding */
683 	if (vhtcaps & IEEE80211_VHTCAP_RX_LDPC)
684 		printf(",LDPC");
685 
686 	/* short guard interval */
687 	if (vhtcaps & IEEE80211_VHTCAP_SGI80)
688 		printf(",SGI@80MHz");
689 	if (vhtcaps & IEEE80211_VHTCAP_SGI160)
690 		printf(",SGI@160MHz");
691 
692 	/* space-time block coding */
693 	if (vhtcaps & IEEE80211_VHTCAP_TX_STBC)
694 		printf(",TxSTBC");
695 	rxstbc = (vhtcaps & IEEE80211_VHTCAP_RX_STBC_SS_MASK)
696 	    >> IEEE80211_VHTCAP_RX_STBC_SS_SHIFT;
697 	if (rxstbc > 0 && rxstbc <= 7)
698 		printf(",RxSTBC %d stream", rxstbc);
699 
700 	/* beamforming */
701 	if (vhtcaps & IEEE80211_VHTCAP_SU_BEAMFORMER) {
702 		printf(",beamformer");
703 		num_sts = ((vhtcaps & IEEE80211_VHTCAP_NUM_STS_MASK) >>
704 		    IEEE80211_VHTCAP_NUM_STS_SHIFT);
705 		if (num_sts)
706 			printf(" STS %u", num_sts);
707 	}
708 	if (vhtcaps & IEEE80211_VHTCAP_SU_BEAMFORMEE) {
709 		printf(",beamformee");
710 		num_sts = ((vhtcaps & IEEE80211_VHTCAP_BEAMFORMEE_STS_MASK) >>
711 		    IEEE80211_VHTCAP_BEAMFORMEE_STS_SHIFT);
712 		if (num_sts)
713 			printf(" STS %u", num_sts);
714 	}
715 
716 	if (vhtcaps & IEEE80211_VHTCAP_TXOP_PS)
717 		printf(",TXOP PS");
718 	if (vhtcaps & IEEE80211_VHTCAP_HTC_VHT)
719 		printf(",+HTC VHT");
720 
721 	/* max A-MPDU length */
722 	max_ampdu = ((vhtcaps & IEEE80211_VHTCAP_MAX_AMPDU_LEN_MASK) >>
723 	    IEEE80211_VHTCAP_MAX_AMPDU_LEN_SHIFT);
724 	if (max_ampdu >= IEEE80211_VHTCAP_MAX_AMPDU_LEN_8K &&
725 	    max_ampdu <= IEEE80211_VHTCAP_MAX_AMPDU_LEN_1024K)
726 		printf(",max A-MPDU %uK", (1 << (max_ampdu + 3)));
727 
728 	link_adapt = ((vhtcaps & IEEE80211_VHTCAP_LINK_ADAPT_MASK) >>
729 	    IEEE80211_VHTCAP_LINK_ADAPT_SHIFT);
730 	if (link_adapt == IEEE80211_VHTCAP_LINK_ADAPT_UNSOL_MFB)
731 		printf(",linkadapt unsolicited MFB");
732 	else if (link_adapt == IEEE80211_VHTCAP_LINK_ADAPT_MRQ_MFB)
733 		printf(",linkadapt MRQ MFB");
734 
735 	if (vhtcaps & IEEE80211_VHTCAP_RX_ANT_PATTERN)
736 		printf(",Rx ant pattern consistent");
737 	if (vhtcaps & IEEE80211_VHTCAP_TX_ANT_PATTERN)
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_MASK);
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_MASK);
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_8080:
776 		printf("80+80MHz chan");
777 		break;
778 	case IEEE80211_VHTOP0_CHAN_WIDTH_160:
779 		printf("160MHz chan");
780 		break;
781 	case IEEE80211_VHTOP0_CHAN_WIDTH_80:
782 		printf("80MHz chan");
783 		break;
784 	case IEEE80211_VHTOP0_CHAN_WIDTH_HT:
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, 3) != 0 &&
808 	    memcmp(selector, IEEE80211_OUI, 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, 3) != 0 &&
844 	    memcmp(selector, IEEE80211_OUI, 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 	default:
864 		printf("%d", selector[3]);
865 		break;
866 	}
867 }
868 
869 /* Caller checks len */
870 void
871 ieee80211_print_rsn(u_int8_t *data, u_int len)
872 {
873 	uint16_t version, nciphers, nakms, rsncap, npmk;
874 	int i, j;
875 	uint8_t selector[4];
876 
877 	if (len < 2) {
878 		ieee80211_print_element(data, len);
879 		return;
880 	}
881 
882 	version = (data[0]) | (data[1] << 8);
883 	printf("=<version %d", version);
884 
885 	if (len < 6) {
886 		printf(">");
887 		return;
888 	}
889 
890 	data += 2;
891 	printf(",groupcipher ");
892 	for (i = 0; i < 4; i++)
893 		selector[i] = data[i];
894 	ieee80211_print_rsncipher(selector);
895 
896 	if (len < 8) {
897 		printf(">");
898 		return;
899 	}
900 
901 	data += 4;
902 	nciphers = (data[0]) | ((data[1]) << 8);
903 	data += 2;
904 
905 	if (len < 8 + (nciphers * 4)) {
906 		printf(">");
907 		return;
908 	}
909 
910 	printf(",cipher%s ", nciphers > 1 ? "s" : "");
911 	for (i = 0; i < nciphers; i++) {
912 		for (j = 0; j < 4; j++)
913 			selector[j] = data[i + j];
914 		ieee80211_print_rsncipher(selector);
915 		if (i < nciphers - 1)
916 			printf(" ");
917 		data += 4;
918 	}
919 
920 	if (len < 8 + (nciphers * 4) + 2) {
921 		printf(">");
922 		return;
923 	}
924 
925 	nakms = (data[0]) | ((data[1]) << 8);
926 	data += 2;
927 
928 	if (len < 8 + (nciphers * 4) + 2 + (nakms * 4)) {
929 		printf(">");
930 		return;
931 	}
932 
933 	printf(",akm%s ", nakms > 1 ? "s" : "");
934 	for (i = 0; i < nciphers; i++) {
935 		for (j = 0; j < 4; j++)
936 			selector[j] = data[i + j];
937 		ieee80211_print_akm(selector);
938 		if (i < nciphers - 1)
939 			printf(" ");
940 		data += 4;
941 	}
942 
943 	if (len < 8 + (nciphers * 4) + 2 + (nakms * 4) + 2) {
944 		printf(">");
945 		return;
946 	}
947 
948 	rsncap = (data[0]) | ((data[1]) << 8);
949 	printf(",rsncap 0x%x", rsncap);
950 	data += 2;
951 
952 	if (len < 8 + (nciphers * 4) + 2 + (nakms * 4) + 2 + 2) {
953 		printf(">");
954 		return;
955 	}
956 
957 	npmk = (data[0]) | ((data[1]) << 8);
958 	data += 2;
959 
960 	if (len < 8 + (nciphers * 4) + 2 + (nakms * 4) + 2 + 2 +
961 	    (npmk * IEEE80211_PMKID_LEN)) {
962 		printf(">");
963 		return;
964 	}
965 
966 	if (npmk >= 1)
967 		printf(",pmkid%s ", npmk > 1 ? "s" : "");
968 	for (i = 0; i < npmk; i++) {
969 		printf("0x");
970 		for (j = 0; j < IEEE80211_PMKID_LEN; j++)
971 			printf("%x", data[i + j]);
972 		if (i < npmk - 1)
973 			printf(" ");
974 		data += IEEE80211_PMKID_LEN;
975 	}
976 
977 	if (len < 8 + (nciphers * 4) + 2 + (nakms * 4) + 2 + 2 +
978 	    (npmk * IEEE80211_PMKID_LEN) + 4) {
979 		printf(">");
980 		return;
981 	}
982 
983 	printf(",integrity-groupcipher ");
984 	for (i = 0; i < 4; i++)
985 		selector[i] = data[i];
986 	ieee80211_print_rsncipher(selector);
987 
988 	printf(">");
989 }
990 
991 int
992 ieee80211_print_beacon(struct ieee80211_frame *wh, u_int len)
993 {
994 	uint64_t tstamp;
995 	uint16_t bintval, capinfo;
996 	uint8_t *frm;
997 
998 	if (len < sizeof(tstamp) + sizeof(bintval) + sizeof(capinfo))
999 		return 1; /* truncated */
1000 
1001 	frm = (u_int8_t *)&wh[1];
1002 
1003 	bcopy(frm, &tstamp, sizeof(u_int64_t));
1004 	frm += 8;
1005 	if (vflag > 1)
1006 		printf(", timestamp %llu", letoh64(tstamp));
1007 
1008 	bcopy(frm, &bintval, sizeof(u_int16_t));
1009 	frm += 2;
1010 	if (vflag > 1)
1011 		printf(", interval %u", letoh16(bintval));
1012 
1013 	bcopy(frm, &capinfo, sizeof(u_int16_t));
1014 	frm += 2;
1015 	if (vflag)
1016 		printb(", caps", letoh16(capinfo), IEEE80211_CAPINFO_BITS);
1017 
1018 	return ieee80211_print_elements(frm);
1019 }
1020 
1021 int
1022 ieee80211_print_assocreq(struct ieee80211_frame *wh, u_int len)
1023 {
1024 	uint8_t subtype;
1025 	uint16_t capinfo, lintval;
1026 	uint8_t *frm;
1027 
1028 	subtype = wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK;
1029 
1030 	if (len < sizeof(capinfo) + sizeof(lintval) +
1031 	    (subtype == IEEE80211_FC0_SUBTYPE_REASSOC_REQ ?
1032 	    IEEE80211_ADDR_LEN : 0))
1033 		return 1; /* truncated */
1034 
1035 	frm = (u_int8_t *)&wh[1];
1036 
1037 	bcopy(frm, &capinfo, sizeof(u_int16_t));
1038 	frm += 2;
1039 	if (vflag)
1040 		printb(", caps", letoh16(capinfo), IEEE80211_CAPINFO_BITS);
1041 
1042 	bcopy(frm, &lintval, sizeof(u_int16_t));
1043 	frm += 2;
1044 	if (vflag > 1)
1045 		printf(", listen interval %u", letoh16(lintval));
1046 
1047 	if (subtype == IEEE80211_FC0_SUBTYPE_REASSOC_REQ) {
1048 		if (vflag)
1049 			printf(", AP %s", etheraddr_string(frm));
1050 		frm += IEEE80211_ADDR_LEN;
1051 	}
1052 
1053 	return ieee80211_print_elements(frm);
1054 }
1055 
1056 int
1057 ieee80211_print_elements(uint8_t *frm)
1058 {
1059 	int i;
1060 
1061 	while (TTEST2(*frm, 2)) {
1062 		u_int len = frm[1];
1063 		u_int8_t *data = frm + 2;
1064 
1065 		if (!TTEST2(*data, len))
1066 			break;
1067 
1068 #define ELEM_CHECK(l)	if (len != l) goto trunc
1069 
1070 		switch (*frm) {
1071 		case IEEE80211_ELEMID_SSID:
1072 			printf(", ssid");
1073 			ieee80211_print_essid(data, len);
1074 			break;
1075 		case IEEE80211_ELEMID_RATES:
1076 			printf(", rates");
1077 			if (!vflag)
1078 				break;
1079 			for (i = len; i > 0; i--, data++)
1080 				printf(" %uM%s",
1081 				    (data[0] & IEEE80211_RATE_VAL) / 2,
1082 				    (data[0] & IEEE80211_RATE_BASIC
1083 				    ? "*" : ""));
1084 			break;
1085 		case IEEE80211_ELEMID_FHPARMS:
1086 			ELEM_CHECK(5);
1087 			printf(", fh (dwell %u, chan %u, index %u)",
1088 			    (data[1] << 8) | data[0],
1089 			    (data[2] - 1) * 80 + data[3],	/* FH_CHAN */
1090 			    data[4]);
1091 			break;
1092 		case IEEE80211_ELEMID_DSPARMS:
1093 			ELEM_CHECK(1);
1094 			printf(", ds");
1095 			if (vflag)
1096 				printf(" (chan %u)", data[0]);
1097 			break;
1098 		case IEEE80211_ELEMID_CFPARMS:
1099 			printf(", cf");
1100 			if (vflag)
1101 				ieee80211_print_element(data, len);
1102 			break;
1103 		case IEEE80211_ELEMID_TIM:
1104 			printf(", tim");
1105 			if (vflag)
1106 				ieee80211_print_element(data, len);
1107 			break;
1108 		case IEEE80211_ELEMID_IBSSPARMS:
1109 			printf(", ibss");
1110 			if (vflag)
1111 				ieee80211_print_element(data, len);
1112 			break;
1113 		case IEEE80211_ELEMID_COUNTRY:
1114 			printf(", country");
1115 			if (vflag)
1116 				ieee80211_print_country(data, len);
1117 			break;
1118 		case IEEE80211_ELEMID_CHALLENGE:
1119 			printf(", challenge");
1120 			if (vflag)
1121 				ieee80211_print_element(data, len);
1122 			break;
1123 		case IEEE80211_ELEMID_CSA:
1124 			ELEM_CHECK(3);
1125 			printf(", csa (chan %u count %u%s)", data[1], data[2],
1126 			    (data[0] == 1) ? " noTX" : "");
1127 			break;
1128 		case IEEE80211_ELEMID_ERP:
1129 			printf(", erp");
1130 			if (vflag)
1131 				ieee80211_print_element(data, len);
1132 			break;
1133 		case IEEE80211_ELEMID_RSN:
1134 			printf(", rsn");
1135 			if (vflag)
1136 				ieee80211_print_rsn(data, len);
1137 			break;
1138 		case IEEE80211_ELEMID_XRATES:
1139 			printf(", xrates");
1140 			if (!vflag)
1141 				break;
1142 			for (i = len; i > 0; i--, data++)
1143 				printf(" %uM",
1144 				    (data[0] & IEEE80211_RATE_VAL) / 2);
1145 			break;
1146 		case IEEE80211_ELEMID_TPC_REPORT:
1147 			printf(", tpcreport");
1148 			if (vflag)
1149 				ieee80211_print_element(data, len);
1150 			break;
1151 		case IEEE80211_ELEMID_TPC_REQUEST:
1152 			printf(", tpcrequest");
1153 			if (vflag)
1154 				ieee80211_print_element(data, len);
1155 			break;
1156 		case IEEE80211_ELEMID_HTCAPS:
1157 			printf(", htcaps");
1158 			if (vflag)
1159 				ieee80211_print_htcaps(data, len);
1160 			break;
1161 		case IEEE80211_ELEMID_HTOP:
1162 			printf(", htop");
1163 			if (vflag)
1164 				ieee80211_print_htop(data, len);
1165 			break;
1166 		case IEEE80211_ELEMID_VHTCAPS:
1167 			printf(", vhtcaps");
1168 			if (vflag)
1169 				ieee80211_print_vhtcaps(data, len);
1170 			break;
1171 		case IEEE80211_ELEMID_VHTOP:
1172 			printf(", vhtop");
1173 			if (vflag)
1174 				ieee80211_print_vhtop(data, len);
1175 			break;
1176 		case IEEE80211_ELEMID_POWER_CONSTRAINT:
1177 			ELEM_CHECK(1);
1178 			printf(", power constraint %udB", data[0]);
1179 			break;
1180 		case IEEE80211_ELEMID_QBSS_LOAD:
1181 			ELEM_CHECK(5);
1182 			printf(", %u stations, %d%% utilization, "
1183 			    "admission capacity %uus/s",
1184 			    (data[0] | data[1] << 8),
1185 			    (data[2] * 100) / 255,
1186 			    (data[3] | data[4] << 8) / 32);
1187 			break;
1188 		case IEEE80211_ELEMID_VENDOR:
1189 			printf(", vendor");
1190 			if (vflag)
1191 				ieee80211_print_element(data, len);
1192 			break;
1193 		default:
1194 			printf(", %u:%u", (u_int) *frm, len);
1195 			if (vflag)
1196 				ieee80211_print_element(data, len);
1197 			break;
1198 		}
1199 		frm += len + 2;
1200 
1201 		if (frm >= snapend)
1202 			break;
1203 	}
1204 
1205 #undef ELEM_CHECK
1206 
1207 	return (0);
1208 
1209  trunc:
1210 	/* Truncated elements in frame */
1211 	return (1);
1212 }
1213 
1214 int
1215 ieee80211_frame(struct ieee80211_frame *wh, u_int len)
1216 {
1217 	u_int8_t subtype, type, *frm;
1218 
1219 	TCARR(wh->i_fc);
1220 
1221 	type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK;
1222 	subtype = wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK;
1223 
1224 	frm = (u_int8_t *)&wh[1];
1225 
1226 	if (vflag)
1227 		printb(" flags", wh->i_fc[1], IEEE80211_FC1_BITS);
1228 
1229 	switch (type) {
1230 	case IEEE80211_FC0_TYPE_DATA:
1231 		printf(": %s: ", ieee80211_data_subtype_name[
1232 		    subtype >> IEEE80211_FC0_SUBTYPE_SHIFT]);
1233 		ieee80211_data(wh, len);
1234 		break;
1235 	case IEEE80211_FC0_TYPE_MGT:
1236 		printf(": %s", ieee80211_mgt_subtype_name[
1237 		    subtype >> IEEE80211_FC0_SUBTYPE_SHIFT]);
1238 		switch (subtype) {
1239 		case IEEE80211_FC0_SUBTYPE_BEACON:
1240 		case IEEE80211_FC0_SUBTYPE_PROBE_RESP:
1241 			if (ieee80211_print_beacon(wh, len) != 0)
1242 				goto trunc;
1243 			break;
1244 		case IEEE80211_FC0_SUBTYPE_ASSOC_REQ:
1245 		case IEEE80211_FC0_SUBTYPE_REASSOC_REQ:
1246 			if (ieee80211_print_assocreq(wh, len) != 0)
1247 				goto trunc;
1248 			break;
1249 		case IEEE80211_FC0_SUBTYPE_AUTH:
1250 			TCHECK2(*frm, 2);		/* Auth Algorithm */
1251 			switch (IEEE80211_AUTH_ALGORITHM(frm)) {
1252 			case IEEE80211_AUTH_ALG_OPEN:
1253 				TCHECK2(*frm, 4);	/* Auth Transaction */
1254 				switch (IEEE80211_AUTH_TRANSACTION(frm)) {
1255 				case IEEE80211_AUTH_OPEN_REQUEST:
1256 					printf(" request");
1257 					break;
1258 				case IEEE80211_AUTH_OPEN_RESPONSE:
1259 					printf(" response");
1260 					break;
1261 				}
1262 				break;
1263 			case IEEE80211_AUTH_ALG_SHARED:
1264 				TCHECK2(*frm, 4);	/* Auth Transaction */
1265 				switch (IEEE80211_AUTH_TRANSACTION(frm)) {
1266 				case IEEE80211_AUTH_SHARED_REQUEST:
1267 					printf(" request");
1268 					break;
1269 				case IEEE80211_AUTH_SHARED_CHALLENGE:
1270 					printf(" challenge");
1271 					break;
1272 				case IEEE80211_AUTH_SHARED_RESPONSE:
1273 					printf(" response");
1274 					break;
1275 				case IEEE80211_AUTH_SHARED_PASS:
1276 					printf(" pass");
1277 					break;
1278 				}
1279 				break;
1280 			case IEEE80211_AUTH_ALG_LEAP:
1281 				printf(" (leap)");
1282 				break;
1283 			}
1284 			break;
1285 		case IEEE80211_FC0_SUBTYPE_DEAUTH:
1286 		case IEEE80211_FC0_SUBTYPE_DISASSOC:
1287 			TCHECK2(*frm, 2);		/* Reason Code */
1288 			ieee80211_reason(frm[0] | (frm[1] << 8));
1289 			break;
1290 		}
1291 		break;
1292 	case IEEE80211_FC0_TYPE_CTL: {
1293 		u_int8_t *t = (u_int8_t *) wh;
1294 
1295 		printf(": %s", ieee80211_ctl_subtype_name[
1296 		    subtype >> IEEE80211_FC0_SUBTYPE_SHIFT]);
1297 		if (!vflag)
1298 			break;
1299 
1300 		/* See 802.11 2012 "8.3.1 Control frames". */
1301 		t += 2; /* skip Frame Control */
1302 		switch (subtype) {
1303 		case IEEE80211_FC0_SUBTYPE_RTS:
1304 		case IEEE80211_FC0_SUBTYPE_BAR:
1305 		case IEEE80211_FC0_SUBTYPE_BA:
1306 			TCHECK2(*t, 2); /* Duration */
1307 			printf(", duration %dus", (t[0] | t[1] << 8));
1308 			t += 2;
1309 			TCHECK2(*t, 6); /* RA */
1310 			printf(", ra %s", etheraddr_string(t));
1311 			t += 6;
1312 			TCHECK2(*t, 6); /* TA */
1313 			printf(", ta %s", etheraddr_string(t));
1314 			if (subtype == IEEE80211_FC0_SUBTYPE_BAR ||
1315 			    subtype == IEEE80211_FC0_SUBTYPE_BA) {
1316 				u_int16_t ctrl;
1317 
1318 				t += 6;
1319 				TCHECK2(*t, 2); /* BAR/BA control */
1320 				ctrl = t[0] | (t[1] << 8);
1321 				if (ctrl & IEEE80211_BA_ACK_POLICY)
1322 					printf(", no ack");
1323 				else
1324 					printf(", normal ack");
1325 				if ((ctrl & IEEE80211_BA_MULTI_TID) == 0 &&
1326 				    (ctrl & IEEE80211_BA_COMPRESSED) == 0)
1327 					printf(", basic variant");
1328 				else if ((ctrl & IEEE80211_BA_MULTI_TID) &&
1329 				    (ctrl & IEEE80211_BA_COMPRESSED))
1330 					printf(", multi-tid variant");
1331 				else if (ctrl & IEEE80211_BA_COMPRESSED)
1332 					printf(", compressed variant");
1333 			}
1334 			break;
1335 		case IEEE80211_FC0_SUBTYPE_CTS:
1336 		case IEEE80211_FC0_SUBTYPE_ACK:
1337 			TCHECK2(*t, 2); /* Duration */
1338 			printf(", duration %dus", (t[0] | t[1] << 8));
1339 			t += 2;
1340 			TCHECK2(*t, 6); /* RA */
1341 			printf(", ra %s", etheraddr_string(t));
1342 			break;
1343 		case IEEE80211_FC0_SUBTYPE_PS_POLL:
1344 			TCHECK2(*t, 2); /* AID */
1345 			printf(", aid 0x%x", (t[0] | t[1] << 8));
1346 			t += 2;
1347 			TCHECK2(*t, 6); /* BSSID(RA) */
1348 			printf(", ra %s", etheraddr_string(t));
1349 			t += 6;
1350 			TCHECK2(*t, 6); /* TA */
1351 			printf(", ta %s", etheraddr_string(t));
1352 			break;
1353 		}
1354 		break;
1355 	}
1356 	default:
1357 		printf(": type#%d", type);
1358 		break;
1359 	}
1360 
1361 	return (0);
1362 
1363  trunc:
1364 	/* Truncated 802.11 frame */
1365 	return (1);
1366 }
1367 
1368 u_int
1369 ieee80211_any2ieee(u_int freq, u_int flags)
1370 {
1371 	if (flags & IEEE80211_CHAN_2GHZ) {
1372 		if (freq == 2484)
1373 			return 14;
1374 		if (freq < 2484)
1375 			return (freq - 2407) / 5;
1376 		else
1377 			return 15 + ((freq - 2512) / 20);
1378 	} else if (flags & IEEE80211_CHAN_5GHZ) {
1379 		return (freq - 5000) / 5;
1380 	} else {
1381 		/* Assume channel is already an IEEE number */
1382 		return (freq);
1383 	}
1384 }
1385 
1386 int
1387 ieee80211_print(struct ieee80211_frame *wh, u_int len)
1388 {
1389 	if (eflag)
1390 		if (ieee80211_hdr(wh))
1391 			return (1);
1392 
1393 	printf("802.11");
1394 
1395 	return (ieee80211_frame(wh, len));
1396 }
1397 
1398 void
1399 ieee802_11_if_print(u_char *user, const struct pcap_pkthdr *h,
1400     const u_char *p)
1401 {
1402 	struct ieee80211_frame *wh = (struct ieee80211_frame*)p;
1403 
1404 	if (!ieee80211_encap)
1405 		ts_print(&h->ts);
1406 
1407 	packetp = p;
1408 	snapend = p + h->caplen;
1409 
1410 	if (ieee80211_print(wh, (u_int)h->len) != 0)
1411 		printf("[|802.11]");
1412 
1413 	if (!ieee80211_encap) {
1414 		if (xflag)
1415 			default_print(p, (u_int)h->len);
1416 		putchar('\n');
1417 	}
1418 }
1419 
1420 void
1421 ieee802_11_radio_if_print(u_char *user, const struct pcap_pkthdr *h,
1422     const u_char *p)
1423 {
1424 	struct ieee80211_radiotap_header *rh =
1425 	    (struct ieee80211_radiotap_header*)p;
1426 	struct ieee80211_frame *wh;
1427 	u_int8_t *t;
1428 	u_int32_t present;
1429 	u_int len, rh_len;
1430 	u_int16_t tmp;
1431 
1432 	if (!ieee80211_encap)
1433 		ts_print(&h->ts);
1434 
1435 	packetp = p;
1436 	snapend = p + h->caplen;
1437 
1438 	TCHECK(*rh);
1439 
1440 	len = h->len;
1441 	rh_len = letoh16(rh->it_len);
1442 	if (rh->it_version != 0) {
1443 		printf("[?radiotap + 802.11 v:%u]", rh->it_version);
1444 		goto out;
1445 	}
1446 
1447 	wh = (struct ieee80211_frame *)(p + rh_len);
1448 	if (len <= rh_len || ieee80211_print(wh, len - rh_len))
1449 		printf("[|802.11]");
1450 
1451 	t = (u_int8_t*)p + sizeof(struct ieee80211_radiotap_header);
1452 
1453 	if ((present = letoh32(rh->it_present)) == 0)
1454 		goto out;
1455 
1456 	printf(", <radiotap v%u", rh->it_version);
1457 
1458 #define RADIOTAP(_x)	\
1459 	(present & (1 << IEEE80211_RADIOTAP_##_x))
1460 
1461 	if (RADIOTAP(TSFT)) {
1462 		u_int64_t tsf;
1463 
1464 		TCHECK2(*t, 8);
1465 		bcopy(t, &tsf, sizeof(u_int64_t));
1466 		if (vflag > 1)
1467 			printf(", tsf %llu", letoh64(tsf));
1468 		t += 8;
1469 	}
1470 
1471 	if (RADIOTAP(FLAGS)) {
1472 		u_int8_t flags = *(u_int8_t*)t;
1473 		TCHECK2(*t, 1);
1474 
1475 		if (flags & IEEE80211_RADIOTAP_F_CFP)
1476 			printf(", CFP");
1477 		if (flags & IEEE80211_RADIOTAP_F_SHORTPRE)
1478 			printf(", SHORTPRE");
1479 		if (flags & IEEE80211_RADIOTAP_F_WEP)
1480 			printf(", WEP");
1481 		if (flags & IEEE80211_RADIOTAP_F_FRAG)
1482 			printf(", FRAG");
1483 		t += 1;
1484 	}
1485 
1486 	if (RADIOTAP(RATE)) {
1487 		TCHECK2(*t, 1);
1488 		if (vflag) {
1489 			uint8_t rate = *(u_int8_t*)t;
1490 			if (rate & 0x80)
1491 				printf(", MCS %u", rate & 0x7f);
1492 			else
1493 				printf(", %uMbit/s", rate / 2);
1494 		}
1495 		t += 1;
1496 	}
1497 
1498 	if (RADIOTAP(CHANNEL)) {
1499 		u_int16_t freq, flags;
1500 		TCHECK2(*t, 2);
1501 
1502 		bcopy(t, &freq, sizeof(u_int16_t));
1503 		freq = letoh16(freq);
1504 		t += 2;
1505 		TCHECK2(*t, 2);
1506 		bcopy(t, &flags, sizeof(u_int16_t));
1507 		flags = letoh16(flags);
1508 		t += 2;
1509 
1510 		printf(", chan %u", ieee80211_any2ieee(freq, flags));
1511 
1512 		if (flags & IEEE80211_CHAN_HT)
1513 			printf(", 11n");
1514 		else if (flags & IEEE80211_CHAN_DYN &&
1515 		    flags & IEEE80211_CHAN_2GHZ)
1516 			printf(", 11g");
1517 		else if (flags & IEEE80211_CHAN_CCK &&
1518 		    flags & IEEE80211_CHAN_2GHZ)
1519 			printf(", 11b");
1520 		else if (flags & IEEE80211_CHAN_OFDM &&
1521 		    flags & IEEE80211_CHAN_2GHZ)
1522 			printf(", 11G");
1523 		else if (flags & IEEE80211_CHAN_OFDM &&
1524 		    flags & IEEE80211_CHAN_5GHZ)
1525 			printf(", 11a");
1526 
1527 		if (flags & IEEE80211_CHAN_XR)
1528 			printf(", XR");
1529 	}
1530 
1531 	if (RADIOTAP(FHSS)) {
1532 		TCHECK2(*t, 2);
1533 		printf(", fhss %u/%u", *(u_int8_t*)t, *(u_int8_t*)t + 1);
1534 		t += 2;
1535 	}
1536 
1537 	if (RADIOTAP(DBM_ANTSIGNAL)) {
1538 		TCHECK(*t);
1539 		printf(", sig %ddBm", *(int8_t*)t);
1540 		t += 1;
1541 	}
1542 
1543 	if (RADIOTAP(DBM_ANTNOISE)) {
1544 		TCHECK(*t);
1545 		printf(", noise %ddBm", *(int8_t*)t);
1546 		t += 1;
1547 	}
1548 
1549 	if (RADIOTAP(LOCK_QUALITY)) {
1550 		TCHECK2(*t, 2);
1551 		if (vflag) {
1552 			bcopy(t, &tmp, sizeof(u_int16_t));
1553 			printf(", quality %u", letoh16(tmp));
1554 		}
1555 		t += 2;
1556 	}
1557 
1558 	if (RADIOTAP(TX_ATTENUATION)) {
1559 		TCHECK2(*t, 2);
1560 		if (vflag) {
1561 			bcopy(t, &tmp, sizeof(u_int16_t));
1562 			printf(", txatt %u", letoh16(tmp));
1563 		}
1564 		t += 2;
1565 	}
1566 
1567 	if (RADIOTAP(DB_TX_ATTENUATION)) {
1568 		TCHECK2(*t, 2);
1569 		if (vflag) {
1570 			bcopy(t, &tmp, sizeof(u_int16_t));
1571 			printf(", txatt %udB", letoh16(tmp));
1572 		}
1573 		t += 2;
1574 	}
1575 
1576 	if (RADIOTAP(DBM_TX_POWER)) {
1577 		TCHECK(*t);
1578 		printf(", txpower %ddBm", *(int8_t*)t);
1579 		t += 1;
1580 	}
1581 
1582 	if (RADIOTAP(ANTENNA)) {
1583 		TCHECK(*t);
1584 		if (vflag)
1585 			printf(", antenna %u", *(u_int8_t*)t);
1586 		t += 1;
1587 	}
1588 
1589 	if (RADIOTAP(DB_ANTSIGNAL)) {
1590 		TCHECK(*t);
1591 		printf(", signal %udB", *(u_int8_t*)t);
1592 		t += 1;
1593 	}
1594 
1595 	if (RADIOTAP(DB_ANTNOISE)) {
1596 		TCHECK(*t);
1597 		printf(", noise %udB", *(u_int8_t*)t);
1598 		t += 1;
1599 	}
1600 
1601 	if (RADIOTAP(FCS)) {
1602 		TCHECK2(*t, 4);
1603 		if (vflag) {
1604 			u_int32_t fcs;
1605 			bcopy(t, &fcs, sizeof(u_int32_t));
1606 			printf(", fcs %08x", letoh32(fcs));
1607 		}
1608 		t += 4;
1609 	}
1610 
1611 	if (RADIOTAP(RSSI)) {
1612 		u_int8_t rssi, max_rssi;
1613 		TCHECK(*t);
1614 		rssi = *(u_int8_t*)t;
1615 		t += 1;
1616 		TCHECK(*t);
1617 		max_rssi = *(u_int8_t*)t;
1618 		t += 1;
1619 
1620 		printf(", rssi %u/%u", rssi, max_rssi);
1621 	}
1622 
1623 #undef RADIOTAP
1624 
1625 	putchar('>');
1626 	goto out;
1627 
1628  trunc:
1629 	/* Truncated frame */
1630 	printf("[|radiotap + 802.11]");
1631 
1632  out:
1633 	if (!ieee80211_encap) {
1634 		if (xflag)
1635 			default_print(p, h->len);
1636 		putchar('\n');
1637 	}
1638 }
1639 
1640 void
1641 ieee80211_reason(u_int16_t reason)
1642 {
1643 	if (!vflag)
1644 		return;
1645 
1646 	switch (reason) {
1647 	case IEEE80211_REASON_UNSPECIFIED:
1648 		printf(", unspecified failure");
1649 		break;
1650 	case IEEE80211_REASON_AUTH_EXPIRE:
1651 		printf(", authentication expired");
1652 		break;
1653 	case IEEE80211_REASON_AUTH_LEAVE:
1654 		printf(", deauth - station left");
1655 		break;
1656 	case IEEE80211_REASON_ASSOC_EXPIRE:
1657 		printf(", association expired");
1658 		break;
1659 	case IEEE80211_REASON_ASSOC_TOOMANY:
1660 		printf(", too many associated stations");
1661 		break;
1662 	case IEEE80211_REASON_NOT_AUTHED:
1663 		printf(", not authenticated");
1664 		break;
1665 	case IEEE80211_REASON_NOT_ASSOCED:
1666 		printf(", not associated");
1667 		break;
1668 	case IEEE80211_REASON_ASSOC_LEAVE:
1669 		printf(", disassociated - station left");
1670 		break;
1671 	case IEEE80211_REASON_ASSOC_NOT_AUTHED:
1672 		printf(", association but not authenticated");
1673 		break;
1674 	case IEEE80211_REASON_RSN_REQUIRED:
1675 		printf(", rsn required");
1676 		break;
1677 	case IEEE80211_REASON_RSN_INCONSISTENT:
1678 		printf(", rsn inconsistent");
1679 		break;
1680 	case IEEE80211_REASON_IE_INVALID:
1681 		printf(", ie invalid");
1682 		break;
1683 	case IEEE80211_REASON_MIC_FAILURE:
1684 		printf(", mic failure");
1685 		break;
1686 	default:
1687 		printf(", unknown reason %u", reason);
1688 	}
1689 }
1690