xref: /openbsd-src/usr.sbin/tcpdump/print-802_11.c (revision 4e1ee0786f11cc571bd0be17d38e46f635c719fc)
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 
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_rsncipher(u_int8_t []);
105 void	 ieee80211_print_akm(u_int8_t []);
106 void	 ieee80211_print_rsn(u_int8_t *, u_int);
107 int	 ieee80211_print_beacon(struct ieee80211_frame *, u_int);
108 int	 ieee80211_print_assocreq(struct ieee80211_frame *, u_int);
109 int	 ieee80211_print_elements(uint8_t *);
110 int	 ieee80211_frame(struct ieee80211_frame *, u_int);
111 int	 ieee80211_print(struct ieee80211_frame *, u_int);
112 u_int	 ieee80211_any2ieee(u_int, u_int);
113 void	 ieee80211_reason(u_int16_t);
114 
115 #define TCARR(a)	TCHECK2(*a, sizeof(a))
116 
117 int ieee80211_encap = 0;
118 
119 int
120 ieee80211_hdr(struct ieee80211_frame *wh)
121 {
122 	struct ieee80211_frame_addr4 *w4;
123 
124 	switch (wh->i_fc[1] & IEEE80211_FC1_DIR_MASK) {
125 	case IEEE80211_FC1_DIR_NODS:
126 		TCARR(wh->i_addr2);
127 		printf("%s", etheraddr_string(wh->i_addr2));
128 		TCARR(wh->i_addr1);
129 		printf(" > %s", etheraddr_string(wh->i_addr1));
130 		TCARR(wh->i_addr3);
131 		printf(", bssid %s", etheraddr_string(wh->i_addr3));
132 		break;
133 	case IEEE80211_FC1_DIR_TODS:
134 		TCARR(wh->i_addr2);
135 		printf("%s", etheraddr_string(wh->i_addr2));
136 		TCARR(wh->i_addr3);
137 		printf(" > %s", etheraddr_string(wh->i_addr3));
138 		TCARR(wh->i_addr1);
139 		printf(", bssid %s, > DS", etheraddr_string(wh->i_addr1));
140 		break;
141 	case IEEE80211_FC1_DIR_FROMDS:
142 		TCARR(wh->i_addr3);
143 		printf("%s", etheraddr_string(wh->i_addr3));
144 		TCARR(wh->i_addr1);
145 		printf(" > %s", etheraddr_string(wh->i_addr1));
146 		TCARR(wh->i_addr2);
147 		printf(", bssid %s, DS >", etheraddr_string(wh->i_addr2));
148 		break;
149 	case IEEE80211_FC1_DIR_DSTODS:
150 		w4 = (struct ieee80211_frame_addr4 *) wh;
151 		TCARR(w4->i_addr4);
152 		printf("%s", etheraddr_string(w4->i_addr4));
153 		TCARR(w4->i_addr3);
154 		printf(" > %s", etheraddr_string(w4->i_addr3));
155 		TCARR(w4->i_addr2);
156 		printf(", bssid %s", etheraddr_string(w4->i_addr2));
157 		TCARR(w4->i_addr1);
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);
164 		bcopy(wh->i_seq, &seq, sizeof(u_int16_t));
165 		printf(" (seq %u frag %u): ",
166 		    letoh16(seq) >> IEEE80211_SEQ_SEQ_SHIFT,
167 		    letoh16(seq) & IEEE80211_SEQ_FRAG_MASK);
168 	} else
169 		printf(": ");
170 
171 	return (0);
172 
173  trunc:
174 	/* Truncated elements in frame */
175 	return (1);
176 }
177 
178 int
179 ieee80211_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_NODATA);
184 	int hasqos = ((wh->i_fc[0] &
185 	    (IEEE80211_FC0_TYPE_MASK | IEEE80211_FC0_SUBTYPE_QOS)) ==
186 	    (IEEE80211_FC0_TYPE_DATA | IEEE80211_FC0_SUBTYPE_QOS));
187 	u_char *esrc = NULL, *edst = NULL;
188 
189 	if (hasqos) {
190 		struct ieee80211_qosframe *wq;
191 
192 		wq = (struct ieee80211_qosframe *) wh;
193 		TCHECK(*wq);
194 		t += sizeof(*wq);
195 		datalen = len - sizeof(*wq);
196 	} else {
197 		TCHECK(*wh);
198 		t += sizeof(*wh);
199 		datalen = len - sizeof(*wh);
200 	}
201 
202 	switch (wh->i_fc[1] & IEEE80211_FC1_DIR_MASK) {
203 	case IEEE80211_FC1_DIR_TODS:
204 		esrc = wh->i_addr2;
205 		edst = wh->i_addr3;
206 		break;
207 	case IEEE80211_FC1_DIR_FROMDS:
208 		esrc = wh->i_addr3;
209 		edst = wh->i_addr1;
210 		break;
211 	case IEEE80211_FC1_DIR_NODS:
212 		esrc = wh->i_addr2;
213 		edst = wh->i_addr1;
214 		break;
215 	case IEEE80211_FC1_DIR_DSTODS:
216 		if (hasqos) {
217 			struct ieee80211_qosframe_addr4 *w4;
218 
219 			w4 = (struct ieee80211_qosframe_addr4 *) wh;
220 			TCHECK(*w4);
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);
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 */
252 void
253 ieee80211_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 */
264 void
265 ieee80211_print_essid(u_int8_t *essid, u_int len)
266 {
267 	u_int8_t *p;
268 	int i;
269 
270 	if (len > IEEE80211_NWID_LEN)
271 		len = IEEE80211_NWID_LEN;
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);
282 		putchar(')');
283 	} else
284 		ieee80211_print_element(essid, len);
285 }
286 
287 /* Caller checks len */
288 void
289 ieee80211_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 */
331 void
332 ieee80211_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_40)
350 		printf("20/40MHz");
351 	else
352 		printf("20MHz");
353 
354 	/* LDPC coding */
355 	if (htcaps & IEEE80211_HTCAP_LDPC)
356 		printf(",LDPC");
357 
358 	/* spatial multiplexing power save mode */
359 	smps = (htcaps & IEEE80211_HTCAP_SMPS_MASK)
360 	    >> IEEE80211_HTCAP_SMPS_SHIFT;
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_GF)
368 		printf(",greenfield");
369 
370 	/* short guard interval */
371 	if (htcaps & IEEE80211_HTCAP_SGI20)
372 		printf(",SGI@20MHz");
373 	if (htcaps & IEEE80211_HTCAP_SGI40)
374 		printf(",SGI@40MHz");
375 
376 	/* space-time block coding */
377 	if (htcaps & IEEE80211_HTCAP_TXSTBC)
378 		printf(",TXSTBC");
379 	rxstbc = (htcaps & IEEE80211_HTCAP_RXSTBC_MASK)
380 	    >> IEEE80211_HTCAP_RXSTBC_SHIFT;
381 	if (rxstbc > 0 && rxstbc < 4)
382 		printf(",RXSTBC %d stream", rxstbc);
383 
384 	/* delayed block-ack */
385 	if (htcaps & IEEE80211_HTCAP_DELAYEDBA)
386 		printf(",delayed BA");
387 
388 	/* max A-MSDU length */
389 	if (htcaps & IEEE80211_HTCAP_AMSDU7935)
390 		printf(",A-MSDU 7935");
391 	else
392 		printf(",A-MSDU 3839");
393 
394 	/* DSSS/CCK in 40MHz mode */
395 	if (htcaps & IEEE80211_HTCAP_DSSSCCK40)
396 		printf(",DSSS/CCK@40MHz");
397 
398 	/* 40MHz intolerant */
399 	if (htcaps & IEEE80211_HTCAP_40INTOLERANT)
400 		printf(",40MHz intolerant");
401 
402 	/* L-SIG TXOP protection */
403 	if (htcaps & IEEE80211_HTCAP_LSIGTXOPPROT)
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_LE) >= 0 &&
416 	    (ampdu & IEEE80211_AMPDU_PARAM_LE) <= 3)
417 		printf(",A-MPDU max %d",
418 		    (1 << (13 + (ampdu & IEEE80211_AMPDU_PARAM_LE))) - 1);
419 
420 	/* A-MPDU start spacing */
421 	if (ampdu & IEEE80211_AMPDU_PARAM_SS) {
422 		float ss;
423 
424 		switch ((ampdu & IEEE80211_AMPDU_PARAM_SS) >> 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_HIGH);
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_DEFINED) {
473 		if (txmcs & IEEE80211_TX_RX_MCS_NOT_EQUAL) {
474 			/* Number of spatial Tx streams. */
475 			printf(",%d Tx streams",
476 			     1 + ((txmcs & IEEE80211_TX_SPATIAL_STREAMS) >> 2));
477 			/* Transmit unequal modulation supported. */
478 			if (txmcs & IEEE80211_TX_UNEQUAL_MODULATION)
479 				printf(",UEQM");
480 		}
481 	}
482 
483 	printf(">");
484 }
485 
486 /* Caller checks len */
487 void
488 ieee80211_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_MASK)
507 	    >> IEEE80211_HTOP0_SCO_SHIFT);
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_CHW) == 0)
534 		printf(",STA chanw 20MHz");
535 
536 	/* reduced interframe space (RIFS) permitted */
537 	if (htopinfo[0] & IEEE80211_HTOP0_RIFS)
538 		printf(",RIFS");
539 
540 	htopinfo[1] = data[2];
541 
542 	/* protection requirements for HT transmissions */
543 	htprot = ((htopinfo[1] & IEEE80211_HTOP1_PROT_MASK)
544 	    >> IEEE80211_HTOP1_PROT_SHIFT);
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_STA)
565 		printf(",non-greenfield STA");
566 
567 	/* non-HT STA present */
568 	if (htopinfo[1] & IEEE80211_HTOP1_OBSS_NONHT_STA)
569 		printf(",non-HT STA");
570 
571 	htopinfo[3] = data[4];
572 
573 	/* dual-beacon */
574 	if (htopinfo[3] & IEEE80211_HTOP2_DUALBEACON)
575 		printf(",dualbeacon");
576 
577 	/* dual CTS protection */
578 	if (htopinfo[3] & IEEE80211_HTOP2_DUALCTSPROT)
579 		printf(",dualctsprot");
580 
581 	htopinfo[4] = data[5];
582 
583 	/* space-time block coding (STBC) beacon */
584 	if ((htopinfo[4] << 8) & IEEE80211_HTOP2_STBCBEACON)
585 		printf(",STBC beacon");
586 
587 	/* L-SIG (non-HT signal field) TX opportunity (TXOP) protection */
588 	if ((htopinfo[4] << 8) & IEEE80211_HTOP2_LSIGTXOP)
589 		printf(",lsigtxprot");
590 
591 	/* phased-coexistence operation (PCO) active */
592 	if ((htopinfo[4] << 8) & IEEE80211_HTOP2_PCOACTIVE) {
593 		/* PCO phase */
594 		if ((htopinfo[4] << 8) & IEEE80211_HTOP2_PCOPHASE40)
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 
609 void
610 ieee80211_print_rsncipher(uint8_t selector[4])
611 {
612 	if (memcmp(selector, MICROSOFT_OUI, 3) != 0 &&
613 	    memcmp(selector, IEEE80211_OUI, 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 
645 void
646 ieee80211_print_akm(uint8_t selector[4])
647 {
648 	if (memcmp(selector, MICROSOFT_OUI, 3) != 0 &&
649 	    memcmp(selector, IEEE80211_OUI, 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 */
675 void
676 ieee80211_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_LEN)) {
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_LEN; j++)
776 			printf("%x", data[i + j]);
777 		if (i < npmk - 1)
778 			printf(" ");
779 		data += IEEE80211_PMKID_LEN;
780 	}
781 
782 	if (len < 8 + (nciphers * 4) + 2 + (nakms * 4) + 2 + 2 +
783 	    (npmk * IEEE80211_PMKID_LEN) + 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 
796 int
797 ieee80211_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));
812 
813 	bcopy(frm, &bintval, sizeof(u_int16_t));
814 	frm += 2;
815 	if (vflag > 1)
816 		printf(", interval %u", letoh16(bintval));
817 
818 	bcopy(frm, &capinfo, sizeof(u_int16_t));
819 	frm += 2;
820 	if (vflag)
821 		printb(", caps", letoh16(capinfo), IEEE80211_CAPINFO_BITS);
822 
823 	return ieee80211_print_elements(frm);
824 }
825 
826 int
827 ieee80211_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_MASK;
834 
835 	if (len < sizeof(capinfo) + sizeof(lintval) +
836 	    (subtype == IEEE80211_FC0_SUBTYPE_REASSOC_REQ ?
837 	    IEEE80211_ADDR_LEN : 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), IEEE80211_CAPINFO_BITS);
846 
847 	bcopy(frm, &lintval, sizeof(u_int16_t));
848 	frm += 2;
849 	if (vflag > 1)
850 		printf(", listen interval %u", letoh16(lintval));
851 
852 	if (subtype == IEEE80211_FC0_SUBTYPE_REASSOC_REQ) {
853 		if (vflag)
854 			printf(", AP %s", etheraddr_string(frm));
855 		frm += IEEE80211_ADDR_LEN;
856 	}
857 
858 	return ieee80211_print_elements(frm);
859 }
860 
861 int
862 ieee80211_print_elements(uint8_t *frm)
863 {
864 	int i;
865 
866 	while (TTEST2(*frm, 2)) {
867 		u_int len = frm[1];
868 		u_int8_t *data = frm + 2;
869 
870 		if (!TTEST2(*data, 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_VAL) / 2,
887 				    (data[0] & IEEE80211_RATE_BASIC
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_VAL) / 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 
1009 int
1010 ieee80211_frame(struct ieee80211_frame *wh, u_int len)
1011 {
1012 	u_int8_t subtype, type, *frm;
1013 
1014 	TCARR(wh->i_fc);
1015 
1016 	type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK;
1017 	subtype = wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK;
1018 
1019 	frm = (u_int8_t *)&wh[1];
1020 
1021 	if (vflag)
1022 		printb(" flags", wh->i_fc[1], IEEE80211_FC1_BITS);
1023 
1024 	switch (type) {
1025 	case IEEE80211_FC0_TYPE_DATA:
1026 		printf(": %s: ", ieee80211_data_subtype_name[
1027 		    subtype >> IEEE80211_FC0_SUBTYPE_SHIFT]);
1028 		ieee80211_data(wh, len);
1029 		break;
1030 	case IEEE80211_FC0_TYPE_MGT:
1031 		printf(": %s", ieee80211_mgt_subtype_name[
1032 		    subtype >> IEEE80211_FC0_SUBTYPE_SHIFT]);
1033 		switch (subtype) {
1034 		case IEEE80211_FC0_SUBTYPE_BEACON:
1035 		case IEEE80211_FC0_SUBTYPE_PROBE_RESP:
1036 			if (ieee80211_print_beacon(wh, len) != 0)
1037 				goto trunc;
1038 			break;
1039 		case IEEE80211_FC0_SUBTYPE_ASSOC_REQ:
1040 		case IEEE80211_FC0_SUBTYPE_REASSOC_REQ:
1041 			if (ieee80211_print_assocreq(wh, len) != 0)
1042 				goto trunc;
1043 			break;
1044 		case IEEE80211_FC0_SUBTYPE_AUTH:
1045 			TCHECK2(*frm, 2);		/* Auth Algorithm */
1046 			switch (IEEE80211_AUTH_ALGORITHM(frm)) {
1047 			case IEEE80211_AUTH_ALG_OPEN:
1048 				TCHECK2(*frm, 4);	/* Auth Transaction */
1049 				switch (IEEE80211_AUTH_TRANSACTION(frm)) {
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_SHARED:
1059 				TCHECK2(*frm, 4);	/* Auth Transaction */
1060 				switch (IEEE80211_AUTH_TRANSACTION(frm)) {
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_LEAP:
1076 				printf(" (leap)");
1077 				break;
1078 			}
1079 			break;
1080 		case IEEE80211_FC0_SUBTYPE_DEAUTH:
1081 		case IEEE80211_FC0_SUBTYPE_DISASSOC:
1082 			TCHECK2(*frm, 2);		/* Reason Code */
1083 			ieee80211_reason(frm[0] | (frm[1] << 8));
1084 			break;
1085 		}
1086 		break;
1087 	case IEEE80211_FC0_TYPE_CTL: {
1088 		u_int8_t *t = (u_int8_t *) wh;
1089 
1090 		printf(": %s", ieee80211_ctl_subtype_name[
1091 		    subtype >> IEEE80211_FC0_SUBTYPE_SHIFT]);
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_RTS:
1099 		case IEEE80211_FC0_SUBTYPE_BAR:
1100 		case IEEE80211_FC0_SUBTYPE_BA:
1101 			TCHECK2(*t, 2); /* Duration */
1102 			printf(", duration %dus", (t[0] | t[1] << 8));
1103 			t += 2;
1104 			TCHECK2(*t, 6); /* RA */
1105 			printf(", ra %s", etheraddr_string(t));
1106 			t += 6;
1107 			TCHECK2(*t, 6); /* TA */
1108 			printf(", ta %s", etheraddr_string(t));
1109 			if (subtype == IEEE80211_FC0_SUBTYPE_BAR ||
1110 			    subtype == IEEE80211_FC0_SUBTYPE_BA) {
1111 				u_int16_t ctrl;
1112 
1113 				t += 6;
1114 				TCHECK2(*t, 2); /* BAR/BA control */
1115 				ctrl = t[0] | (t[1] << 8);
1116 				if (ctrl & IEEE80211_BA_ACK_POLICY)
1117 					printf(", no ack");
1118 				else
1119 					printf(", normal ack");
1120 				if ((ctrl & IEEE80211_BA_MULTI_TID) == 0 &&
1121 				    (ctrl & IEEE80211_BA_COMPRESSED) == 0)
1122 					printf(", basic variant");
1123 				else if ((ctrl & IEEE80211_BA_MULTI_TID) &&
1124 				    (ctrl & IEEE80211_BA_COMPRESSED))
1125 					printf(", multi-tid variant");
1126 				else if (ctrl & IEEE80211_BA_COMPRESSED)
1127 					printf(", compressed variant");
1128 			}
1129 			break;
1130 		case IEEE80211_FC0_SUBTYPE_CTS:
1131 		case IEEE80211_FC0_SUBTYPE_ACK:
1132 			TCHECK2(*t, 2); /* Duration */
1133 			printf(", duration %dus", (t[0] | t[1] << 8));
1134 			t += 2;
1135 			TCHECK2(*t, 6); /* RA */
1136 			printf(", ra %s", etheraddr_string(t));
1137 			break;
1138 		case IEEE80211_FC0_SUBTYPE_PS_POLL:
1139 			TCHECK2(*t, 2); /* AID */
1140 			printf(", aid 0x%x", (t[0] | t[1] << 8));
1141 			t += 2;
1142 			TCHECK2(*t, 6); /* BSSID(RA) */
1143 			printf(", ra %s", etheraddr_string(t));
1144 			t += 6;
1145 			TCHECK2(*t, 6); /* 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 
1163 u_int
1164 ieee80211_any2ieee(u_int freq, u_int flags)
1165 {
1166 	if (flags & IEEE80211_CHAN_2GHZ) {
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_5GHZ) {
1174 		return (freq - 5000) / 5;
1175 	} else {
1176 		/* Assume channel is already an IEEE number */
1177 		return (freq);
1178 	}
1179 }
1180 
1181 int
1182 ieee80211_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 
1193 void
1194 ieee802_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');
1212 	}
1213 }
1214 
1215 void
1216 ieee802_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);
1234 
1235 	len = h->len;
1236 	rh_len = letoh16(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)) == 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);
1260 		bcopy(t, &tsf, sizeof(u_int64_t));
1261 		if (vflag > 1)
1262 			printf(", tsf %llu", letoh64(tsf));
1263 		t += 8;
1264 	}
1265 
1266 	if (RADIOTAP(FLAGS)) {
1267 		u_int8_t flags = *(u_int8_t*)t;
1268 		TCHECK2(*t, 1);
1269 
1270 		if (flags & IEEE80211_RADIOTAP_F_CFP)
1271 			printf(", CFP");
1272 		if (flags & IEEE80211_RADIOTAP_F_SHORTPRE)
1273 			printf(", SHORTPRE");
1274 		if (flags & IEEE80211_RADIOTAP_F_WEP)
1275 			printf(", WEP");
1276 		if (flags & IEEE80211_RADIOTAP_F_FRAG)
1277 			printf(", FRAG");
1278 		t += 1;
1279 	}
1280 
1281 	if (RADIOTAP(RATE)) {
1282 		TCHECK2(*t, 1);
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);
1296 
1297 		bcopy(t, &freq, sizeof(u_int16_t));
1298 		freq = letoh16(freq);
1299 		t += 2;
1300 		TCHECK2(*t, 2);
1301 		bcopy(t, &flags, sizeof(u_int16_t));
1302 		flags = letoh16(flags);
1303 		t += 2;
1304 
1305 		printf(", chan %u", ieee80211_any2ieee(freq, flags));
1306 
1307 		if (flags & IEEE80211_CHAN_HT)
1308 			printf(", 11n");
1309 		else if (flags & IEEE80211_CHAN_DYN &&
1310 		    flags & IEEE80211_CHAN_2GHZ)
1311 			printf(", 11g");
1312 		else if (flags & IEEE80211_CHAN_CCK &&
1313 		    flags & IEEE80211_CHAN_2GHZ)
1314 			printf(", 11b");
1315 		else if (flags & IEEE80211_CHAN_OFDM &&
1316 		    flags & IEEE80211_CHAN_2GHZ)
1317 			printf(", 11G");
1318 		else if (flags & IEEE80211_CHAN_OFDM &&
1319 		    flags & IEEE80211_CHAN_5GHZ)
1320 			printf(", 11a");
1321 
1322 		if (flags & IEEE80211_CHAN_XR)
1323 			printf(", XR");
1324 	}
1325 
1326 	if (RADIOTAP(FHSS)) {
1327 		TCHECK2(*t, 2);
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);
1334 		printf(", sig %ddBm", *(int8_t*)t);
1335 		t += 1;
1336 	}
1337 
1338 	if (RADIOTAP(DBM_ANTNOISE)) {
1339 		TCHECK(*t);
1340 		printf(", noise %ddBm", *(int8_t*)t);
1341 		t += 1;
1342 	}
1343 
1344 	if (RADIOTAP(LOCK_QUALITY)) {
1345 		TCHECK2(*t, 2);
1346 		if (vflag) {
1347 			bcopy(t, &tmp, sizeof(u_int16_t));
1348 			printf(", quality %u", letoh16(tmp));
1349 		}
1350 		t += 2;
1351 	}
1352 
1353 	if (RADIOTAP(TX_ATTENUATION)) {
1354 		TCHECK2(*t, 2);
1355 		if (vflag) {
1356 			bcopy(t, &tmp, sizeof(u_int16_t));
1357 			printf(", txatt %u", letoh16(tmp));
1358 		}
1359 		t += 2;
1360 	}
1361 
1362 	if (RADIOTAP(DB_TX_ATTENUATION)) {
1363 		TCHECK2(*t, 2);
1364 		if (vflag) {
1365 			bcopy(t, &tmp, sizeof(u_int16_t));
1366 			printf(", txatt %udB", letoh16(tmp));
1367 		}
1368 		t += 2;
1369 	}
1370 
1371 	if (RADIOTAP(DBM_TX_POWER)) {
1372 		TCHECK(*t);
1373 		printf(", txpower %ddBm", *(int8_t*)t);
1374 		t += 1;
1375 	}
1376 
1377 	if (RADIOTAP(ANTENNA)) {
1378 		TCHECK(*t);
1379 		if (vflag)
1380 			printf(", antenna %u", *(u_int8_t*)t);
1381 		t += 1;
1382 	}
1383 
1384 	if (RADIOTAP(DB_ANTSIGNAL)) {
1385 		TCHECK(*t);
1386 		printf(", signal %udB", *(u_int8_t*)t);
1387 		t += 1;
1388 	}
1389 
1390 	if (RADIOTAP(DB_ANTNOISE)) {
1391 		TCHECK(*t);
1392 		printf(", noise %udB", *(u_int8_t*)t);
1393 		t += 1;
1394 	}
1395 
1396 	if (RADIOTAP(FCS)) {
1397 		TCHECK2(*t, 4);
1398 		if (vflag) {
1399 			u_int32_t fcs;
1400 			bcopy(t, &fcs, sizeof(u_int32_t));
1401 			printf(", fcs %08x", letoh32(fcs));
1402 		}
1403 		t += 4;
1404 	}
1405 
1406 	if (RADIOTAP(RSSI)) {
1407 		u_int8_t rssi, max_rssi;
1408 		TCHECK(*t);
1409 		rssi = *(u_int8_t*)t;
1410 		t += 1;
1411 		TCHECK(*t);
1412 		max_rssi = *(u_int8_t*)t;
1413 		t += 1;
1414 
1415 		printf(", rssi %u/%u", rssi, max_rssi);
1416 	}
1417 
1418 #undef RADIOTAP
1419 
1420 	putchar('>');
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');
1432 	}
1433 }
1434 
1435 void
1436 ieee80211_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 }
1485