xref: /openbsd/usr.sbin/tcpdump/print-802_11.c (revision 9b7c3dbb)
1 /*	$OpenBSD: print-802_11.c,v 1.32 2016/02/21 16:09:47 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 int	 ieee80211_elements(struct ieee80211_frame *, u_int);
105 int	 ieee80211_frame(struct ieee80211_frame *, u_int);
106 int	 ieee80211_print(struct ieee80211_frame *, u_int);
107 u_int	 ieee80211_any2ieee(u_int, u_int);
108 void	 ieee80211_reason(u_int16_t);
109 
110 #define TCARR(a)	TCHECK2(*a, sizeof(a))
111 
112 int ieee80211_encap = 0;
113 
114 int
115 ieee80211_hdr(struct ieee80211_frame *wh)
116 {
117 	struct ieee80211_frame_addr4 *w4;
118 
119 	switch (wh->i_fc[1] & IEEE80211_FC1_DIR_MASK) {
120 	case IEEE80211_FC1_DIR_NODS:
121 		TCARR(wh->i_addr2);
122 		printf("%s", etheraddr_string(wh->i_addr2));
123 		TCARR(wh->i_addr1);
124 		printf(" > %s", etheraddr_string(wh->i_addr1));
125 		TCARR(wh->i_addr3);
126 		printf(", bssid %s", etheraddr_string(wh->i_addr3));
127 		break;
128 	case IEEE80211_FC1_DIR_TODS:
129 		TCARR(wh->i_addr2);
130 		printf("%s", etheraddr_string(wh->i_addr2));
131 		TCARR(wh->i_addr3);
132 		printf(" > %s", etheraddr_string(wh->i_addr3));
133 		TCARR(wh->i_addr1);
134 		printf(", bssid %s, > DS", etheraddr_string(wh->i_addr1));
135 		break;
136 	case IEEE80211_FC1_DIR_FROMDS:
137 		TCARR(wh->i_addr3);
138 		printf("%s", etheraddr_string(wh->i_addr3));
139 		TCARR(wh->i_addr1);
140 		printf(" > %s", etheraddr_string(wh->i_addr1));
141 		TCARR(wh->i_addr2);
142 		printf(", bssid %s, DS >", etheraddr_string(wh->i_addr2));
143 		break;
144 	case IEEE80211_FC1_DIR_DSTODS:
145 		w4 = (struct ieee80211_frame_addr4 *) wh;
146 		TCARR(w4->i_addr4);
147 		printf("%s", etheraddr_string(w4->i_addr4));
148 		TCARR(w4->i_addr3);
149 		printf(" > %s", etheraddr_string(w4->i_addr3));
150 		TCARR(w4->i_addr2);
151 		printf(", bssid %s", etheraddr_string(w4->i_addr2));
152 		TCARR(w4->i_addr1);
153 		printf(" > %s, DS > DS", etheraddr_string(w4->i_addr1));
154 		break;
155 	}
156 	if (vflag) {
157 		u_int16_t seq;
158 		TCARR(wh->i_seq);
159 		bcopy(wh->i_seq, &seq, sizeof(u_int16_t));
160 		printf(" (seq %u): ", letoh16(seq));
161 	} else
162 		printf(": ");
163 
164 	return (0);
165 
166  trunc:
167 	/* Truncated elements in frame */
168 	return (1);
169 }
170 
171 int
172 ieee80211_data(struct ieee80211_frame *wh, u_int len)
173 {
174 	u_int8_t *t = (u_int8_t *)wh;
175 	u_int datalen;
176 	int data = !(wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_NODATA);
177 	int hasqos = ((wh->i_fc[0] &
178 	    (IEEE80211_FC0_TYPE_MASK | IEEE80211_FC0_SUBTYPE_QOS)) ==
179 	    (IEEE80211_FC0_TYPE_DATA | IEEE80211_FC0_SUBTYPE_QOS));
180 	u_char *esrc = NULL, *edst = NULL;
181 
182 	if (hasqos) {
183 		struct ieee80211_qosframe *wq;
184 
185 		wq = (struct ieee80211_qosframe *) wh;
186 		TCHECK(*wq);
187 		t += sizeof(*wq);
188 		datalen = len - sizeof(*wq);
189 	} else {
190 		TCHECK(*wh);
191 		t += sizeof(*wh);
192 		datalen = len - sizeof(*wh);
193 	}
194 
195 	switch (wh->i_fc[1] & IEEE80211_FC1_DIR_MASK) {
196 	case IEEE80211_FC1_DIR_TODS:
197 		esrc = wh->i_addr2;
198 		edst = wh->i_addr3;
199 		break;
200 	case IEEE80211_FC1_DIR_FROMDS:
201 		esrc = wh->i_addr3;
202 		edst = wh->i_addr1;
203 		break;
204 	case IEEE80211_FC1_DIR_NODS:
205 		esrc = wh->i_addr2;
206 		edst = wh->i_addr1;
207 		break;
208 	case IEEE80211_FC1_DIR_DSTODS:
209 		if (hasqos) {
210 			struct ieee80211_qosframe_addr4 *w4;
211 
212 			w4 = (struct ieee80211_qosframe_addr4 *) wh;
213 			TCHECK(*w4);
214 			t = (u_int8_t *) (w4 + 1);
215 			datalen = len - sizeof(*w4);
216 			esrc = w4->i_addr4;
217 			edst = w4->i_addr3;
218 		} else {
219 			struct ieee80211_frame_addr4 *w4;
220 
221 			w4 = (struct ieee80211_frame_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 		}
228 		break;
229 	}
230 
231 	if (data && esrc)
232 		llc_print(t, datalen, datalen, esrc, edst);
233 	else if (eflag && esrc)
234 		printf("%s > %s",
235 		    etheraddr_string(esrc), etheraddr_string(edst));
236 
237 	return (0);
238 
239  trunc:
240 	/* Truncated elements in frame */
241 	return (1);
242 }
243 
244 /* Caller checks len */
245 void
246 ieee80211_print_element(u_int8_t *data, u_int len)
247 {
248 	u_int8_t *p;
249 	int i;
250 
251 	printf(" 0x");
252 	for (i = 0, p = data; i < len; i++, p++)
253 		printf("%02x", *p);
254 }
255 
256 /* Caller checks len */
257 void
258 ieee80211_print_essid(u_int8_t *essid, u_int len)
259 {
260 	u_int8_t *p;
261 	int i;
262 
263 	if (len > IEEE80211_NWID_LEN)
264 		len = IEEE80211_NWID_LEN;
265 
266 	/* determine printable or not */
267 	for (i = 0, p = essid; i < len; i++, p++) {
268 		if (*p < ' ' || *p > 0x7e)
269 			break;
270 	}
271 	if (i == len) {
272 		printf(" (");
273 		for (i = 0, p = essid; i < len; i++, p++)
274 			putchar(*p);
275 		putchar(')');
276 	} else
277 		ieee80211_print_element(essid, len);
278 }
279 
280 /* Caller checks len */
281 void
282 ieee80211_print_country(u_int8_t *data, u_int len)
283 {
284 	u_int8_t first_chan, nchan, maxpower;
285 
286 	if (len < 6)
287 		return;
288 
289 	/* country string */
290 	printf((isprint(data[0]) ? " '%c" : " '\\%03o"), data[0]);
291 	printf((isprint(data[1]) ? "%c" : "\\%03o"), data[1]);
292 	printf((isprint(data[2]) ? "%c'" : "\\%03o'"), data[2]);
293 
294 	len -= 3;
295 	data += 3;
296 
297 	/* channels and corresponding TX power limits */
298 	while (len >= 3) {
299 		/* no pretty-printing for nonsensical zero values,
300 		 * nor for operating extension IDs (values >= 201) */
301 		if (data[0] == 0 || data[1] == 0 ||
302 		    data[0] >= 201 || data[1] >= 201) {
303 			printf(", %d %d %d", data[0], data[1], data[2]);
304 			len -= 3;
305 			data += 3;
306 			continue;
307 		}
308 
309 		first_chan = data[0];
310 		nchan = data[1];
311 		maxpower = data[2];
312 
313 		printf(", channel%s %d", nchan == 1 ? "" : "s", first_chan);
314 		if (nchan > 1)
315 			printf("-%d", first_chan + nchan - 1);
316 		printf(" limit %ddB", maxpower);
317 
318 		len -= 3;
319 		data += 3;
320 	}
321 }
322 
323 /* Caller checks len */
324 void
325 ieee80211_print_htcaps(u_int8_t *data, u_int len)
326 {
327 	uint16_t htcaps, rxrate;
328 	int smps, rxstbc;
329 	uint8_t ampdu, txmcs;
330 	int i;
331 	uint8_t *rxmcs;
332 
333 	if (len < 2) {
334 		ieee80211_print_element(data, len);
335 		return;
336 	}
337 
338 	htcaps = (data[0]) | (data[1] << 8);
339 	printf("=<");
340 
341 	/* channel width */
342 	if (htcaps & IEEE80211_HTCAP_CBW20_40)
343 		printf("20/40MHz");
344 	else
345 		printf("20MHz");
346 
347 	/* LDPC coding */
348 	if (htcaps & IEEE80211_HTCAP_LDPC)
349 		printf(",LDPC");
350 
351 	/* spatial multiplexing power save mode */
352 	smps = (htcaps & IEEE80211_HTCAP_SMPS_MASK)
353 	    >> IEEE80211_HTCAP_SMPS_SHIFT;
354 	if (smps == 0)
355 		printf(",SMPS static");
356 	else if (smps == 1)
357 		printf(",SMPS dynamic");
358 
359 	/* 11n greenfield mode */
360 	if (htcaps & IEEE80211_HTCAP_GF)
361 		printf(",greenfield");
362 
363 	/* short guard interval */
364 	if (htcaps & IEEE80211_HTCAP_SGI20)
365 		printf(",SGI@20MHz");
366 	if (htcaps & IEEE80211_HTCAP_SGI40)
367 		printf(",SGI@40MHz");
368 
369 	/* space-time block coding */
370 	if (htcaps & IEEE80211_HTCAP_TXSTBC)
371 		printf(",TXSTBC");
372 	rxstbc = (htcaps & IEEE80211_HTCAP_RXSTBC_MASK)
373 	    >> IEEE80211_HTCAP_RXSTBC_SHIFT;
374 	if (rxstbc > 0 && rxstbc < 4)
375 		printf(",RXSTBC %d stream", rxstbc);
376 
377 	/* delayed block-ack */
378 	if (htcaps & IEEE80211_HTCAP_DELAYEDBA)
379 		printf(",delayed BA");
380 
381 	/* max A-MSDU length */
382 	if (htcaps & IEEE80211_HTCAP_AMSDU7935)
383 		printf(",A-MSDU 7935");
384 	else
385 		printf(",A-MSDU 3839");
386 
387 	/* DSSS/CCK in 40MHz mode */
388 	if (htcaps & IEEE80211_HTCAP_DSSSCCK40)
389 		printf(",DSSS/CCK@40MHz");
390 
391 	/* 40MHz intolerant */
392 	if (htcaps & IEEE80211_HTCAP_40INTOLERANT)
393 		printf(",40MHz intolerant");
394 
395 	/* L-SIG TXOP protection */
396 	if (htcaps & IEEE80211_HTCAP_LSIGTXOPPROT)
397 		printf(",L-SIG TXOP prot");
398 
399 	if (len < 3) {
400 		printf(">");
401 		return;
402 	}
403 
404 	/* A-MPDU parameters. */
405 	ampdu = data[2];
406 
407 	/* A-MPDU length exponent */
408 	if ((ampdu & IEEE80211_AMPDU_PARAM_LE) >= 0 &&
409 	    (ampdu & IEEE80211_AMPDU_PARAM_LE) <= 3)
410 		printf(",A-MPDU max %d",
411 		    (1 << (13 + (ampdu & IEEE80211_AMPDU_PARAM_LE))) - 1);
412 
413 	/* A-MPDU start spacing */
414 	if (ampdu & IEEE80211_AMPDU_PARAM_SS) {
415 		float ss;
416 
417 		switch ((ampdu & IEEE80211_AMPDU_PARAM_SS) >> 2) {
418 		case 1:
419 			ss = 0.25;
420 			break;
421 		case 2:
422 			ss = 0.5;
423 			break;
424 		case 3:
425 			ss = 1;
426 			break;
427 		case 4:
428 			ss = 2;
429 			break;
430 		case 5:
431 			ss = 4;
432 			break;
433 		case 6:
434 			ss = 8;
435 			break;
436 		case 7:
437 			ss = 16;
438 			break;
439 		default:
440 			ss = 0;
441 			break;
442 		}
443 		if (ss != 0)
444 			printf(",A-MPDU spacing %.2fus", ss);
445 	}
446 
447 	if (len < 21) {
448 		printf(">");
449 		return;
450 	}
451 
452 	/* Supported MCS set. */
453 	printf(",RxMCS 0x");
454 	rxmcs = &data[3];
455 	for (i = 0; i < 10; i++)
456 		printf("%02x", rxmcs[i]);
457 
458 	/* Max MCS Rx rate (a value of 0 means "not specified"). */
459 	rxrate = ((data[13] | (data[14]) << 8) & IEEE80211_MCS_RX_RATE_HIGH);
460 	if (rxrate)
461 		printf(",RxMaxrate %huMb/s", rxrate);
462 
463 	/* Tx MCS Set */
464 	txmcs = data[15];
465 	if (txmcs & IEEE80211_TX_MCS_SET_DEFINED) {
466 		if (txmcs & IEEE80211_TX_RX_MCS_NOT_EQUAL) {
467 			/* Number of spatial Tx streams. */
468 			printf(",%d Tx streams",
469 			     1 + ((txmcs & IEEE80211_TX_SPATIAL_STREAMS) >> 2));
470 			/* Transmit unequal modulation supported. */
471 			if (txmcs & IEEE80211_TX_UNEQUAL_MODULATION)
472 				printf(",UEQM");
473 		}
474 	}
475 
476 	printf(">");
477 }
478 
479 /* Caller checks len */
480 void
481 ieee80211_print_htop(u_int8_t *data, u_int len)
482 {
483 	u_int8_t primary_chan;
484 	u_int8_t htopinfo[5];
485 	u_int8_t basic_mcs[16];
486 	int sco, prot, i;
487 
488 	if (len < sizeof(primary_chan) + sizeof(htopinfo) + sizeof(basic_mcs)) {
489 		ieee80211_print_element(data, len);
490 		return;
491 	}
492 
493 	htopinfo[0] = data[1];
494 
495 	printf("=<");
496 
497 	/* primary channel and secondary channel offset */
498 	primary_chan = data[0];
499 	sco = ((htopinfo[0] & IEEE80211_HTOP0_SCO_MASK)
500 	    >> IEEE80211_HTOP0_SCO_SHIFT);
501 	if (sco == 0) /* no secondary channel */
502 		printf("20MHz chan %d", primary_chan);
503 	else if (sco == 1) { /* secondary channel above */
504 		if (primary_chan >= 1 && primary_chan <= 13) /* 2GHz */
505 			printf("40MHz chan %d:%d", primary_chan,
506 			    primary_chan + 1);
507 		else if (primary_chan >= 34) /* 5GHz */
508 			printf("40MHz chan %d:%d", primary_chan,
509 			    primary_chan + 4);
510 		else
511 			printf("[invalid 40MHz chan %d+]", primary_chan);
512 	} else if (sco == 3) { /* secondary channel below */
513 		if (primary_chan >= 2 && primary_chan <= 14) /* 2GHz */
514 			printf("40MHz chan %d:%d", primary_chan,
515 			    primary_chan - 1);
516 		else if (primary_chan >= 40) /* 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
522 		printf("chan %d [invalid secondary channel offset %d]",
523 		    primary_chan, sco);
524 
525 	/* STA channel width */
526 	if ((htopinfo[0] & IEEE80211_HTOP0_CHW) == 0)
527 		printf(",STA chanw 20MHz");
528 
529 	/* reduced interframe space (RIFS) permitted */
530 	if (htopinfo[0] & IEEE80211_HTOP0_RIFS)
531 		printf(",RIFS");
532 
533 	htopinfo[1] = data[2];
534 
535 	/* protection requirements for HT transmissions */
536 	prot = ((htopinfo[1] & IEEE80211_HTOP1_PROT_MASK)
537 	    >> IEEE80211_HTOP1_PROT_SHIFT);
538 	if (prot == 1)
539 		printf(",protect non-member");
540 	else if (prot == 2)
541 		printf(",protect 20MHz");
542 	else if (prot == 3)
543 		printf(",protect non-HT");
544 
545 	/* non-greenfield STA present */
546 	if (htopinfo[1] & IEEE80211_HTOP1_NONGF_STA)
547 		printf(",non-greenfield STA");
548 
549 	/* non-HT STA present */
550 	if (htopinfo[1] & IEEE80211_HTOP1_OBSS_NONHT_STA)
551 		printf(",non-HT STA");
552 
553 	htopinfo[3] = data[4];
554 
555 	/* dual-beacon */
556 	if (htopinfo[3] & IEEE80211_HTOP2_DUALBEACON)
557 		printf(",dualbeacon");
558 
559 	/* dual CTS protection */
560 	if (htopinfo[3] & IEEE80211_HTOP2_DUALCTSPROT)
561 		printf(",dualctsprot");
562 
563 	htopinfo[4] = data[5];
564 
565 	/* space-time block coding (STBC) beacon */
566 	if ((htopinfo[4] << 8) & IEEE80211_HTOP2_STBCBEACON)
567 		printf(",STBC beacon");
568 
569 	/* L-SIG (non-HT signal field) TX opportunity (TXOP) protection */
570 	if ((htopinfo[4] << 8) & IEEE80211_HTOP2_LSIGTXOP)
571 		printf(",lsigtxprot");
572 
573 	/* phased-coexistence operation (PCO) active */
574 	if ((htopinfo[4] << 8) & IEEE80211_HTOP2_PCOACTIVE) {
575 		/* PCO phase */
576 		if ((htopinfo[4] << 8) & IEEE80211_HTOP2_PCOPHASE40)
577 			printf(",pco40MHz");
578 		else
579 			printf(",pco20MHz");
580 	}
581 
582 	/* basic MCS set */
583 	memcpy(basic_mcs, &data[6], sizeof(basic_mcs));
584 	printf(",basic MCS set 0x");
585 	for (i = 0; i < sizeof(basic_mcs) / sizeof(basic_mcs[0]); i++)
586 			printf("%x", basic_mcs[i]);
587 
588 	printf(">");
589 }
590 
591 int
592 ieee80211_elements(struct ieee80211_frame *wh, u_int flen)
593 {
594 	u_int8_t *buf, *frm;
595 	u_int64_t tstamp;
596 	u_int16_t bintval, capinfo;
597 	int i;
598 
599 	buf = (u_int8_t *)wh;
600 	frm = (u_int8_t *)&wh[1];
601 
602 	TCHECK2(*frm, 8);
603 	bcopy(frm, &tstamp, sizeof(u_int64_t));
604 	frm += 8;
605 
606 	if (vflag > 1)
607 		printf(", timestamp %llu", letoh64(tstamp));
608 
609 	TCHECK2(*frm, 2);
610 	bcopy(frm, &bintval, sizeof(u_int16_t));
611 	frm += 2;
612 
613 	if (vflag > 1)
614 		printf(", interval %u", letoh16(bintval));
615 
616 	TCHECK2(*frm, 2);
617 	bcopy(frm, &capinfo, sizeof(u_int16_t));
618 	frm += 2;
619 
620 	if (vflag)
621 		printb(", caps", letoh16(capinfo),
622 		    IEEE80211_CAPINFO_BITS);
623 
624 	while (TTEST2(*frm, 2)) {
625 		u_int len = frm[1];
626 		u_int8_t *data = frm + 2;
627 
628 		if (!TTEST2(*data, len))
629 			break;
630 
631 #define ELEM_CHECK(l)	if (len != l) break
632 
633 		switch (*frm) {
634 		case IEEE80211_ELEMID_SSID:
635 			printf(", ssid");
636 			ieee80211_print_essid(data, len);
637 			break;
638 		case IEEE80211_ELEMID_RATES:
639 			printf(", rates");
640 			if (!vflag)
641 				break;
642 			for (i = len; i > 0; i--, data++)
643 				printf(" %uM",
644 				    (data[0] & IEEE80211_RATE_VAL) / 2);
645 			break;
646 		case IEEE80211_ELEMID_FHPARMS:
647 			ELEM_CHECK(5);
648 			printf(", fh (dwell %u, chan %u, index %u)",
649 			    (data[1] << 8) | data[0],
650 			    (data[2] - 1) * 80 + data[3],	/* FH_CHAN */
651 			    data[4]);
652 			break;
653 		case IEEE80211_ELEMID_DSPARMS:
654 			ELEM_CHECK(1);
655 			printf(", ds");
656 			if (vflag)
657 				printf(" (chan %u)", data[0]);
658 			break;
659 		case IEEE80211_ELEMID_CFPARMS:
660 			printf(", cf");
661 			if (vflag)
662 				ieee80211_print_element(data, len);
663 			break;
664 		case IEEE80211_ELEMID_TIM:
665 			printf(", tim");
666 			if (vflag)
667 				ieee80211_print_element(data, len);
668 			break;
669 		case IEEE80211_ELEMID_IBSSPARMS:
670 			printf(", ibss");
671 			if (vflag)
672 				ieee80211_print_element(data, len);
673 			break;
674 		case IEEE80211_ELEMID_COUNTRY:
675 			printf(", country");
676 			if (vflag)
677 				ieee80211_print_country(data, len);
678 			break;
679 		case IEEE80211_ELEMID_CHALLENGE:
680 			printf(", challenge");
681 			if (vflag)
682 				ieee80211_print_element(data, len);
683 			break;
684 		case IEEE80211_ELEMID_CSA:
685 			ELEM_CHECK(3);
686 			printf(", csa (chan %u count %u%s)", data[1], data[2],
687 			    (data[0] == 1) ? " noTX" : "");
688 			break;
689 		case IEEE80211_ELEMID_ERP:
690 			printf(", erp");
691 			if (vflag)
692 				ieee80211_print_element(data, len);
693 			break;
694 		case IEEE80211_ELEMID_RSN:
695 			printf(", rsn");
696 			if (vflag)
697 				ieee80211_print_element(data, len);
698 			break;
699 		case IEEE80211_ELEMID_XRATES:
700 			printf(", xrates");
701 			if (!vflag)
702 				break;
703 			for (i = len; i > 0; i--, data++)
704 				printf(" %uM",
705 				    (data[0] & IEEE80211_RATE_VAL) / 2);
706 			break;
707 		case IEEE80211_ELEMID_TPC_REPORT:
708 			printf(", tpcreport");
709 			if (vflag)
710 				ieee80211_print_element(data, len);
711 			break;
712 		case IEEE80211_ELEMID_TPC_REQUEST:
713 			printf(", tpcrequest");
714 			if (vflag)
715 				ieee80211_print_element(data, len);
716 			break;
717 		case IEEE80211_ELEMID_HTCAPS:
718 			printf(", htcaps");
719 			if (vflag)
720 				ieee80211_print_htcaps(data, len);
721 			break;
722 		case IEEE80211_ELEMID_HTOP:
723 			printf(", htop");
724 			if (vflag)
725 				ieee80211_print_htop(data, len);
726 			break;
727 		case IEEE80211_ELEMID_POWER_CONSTRAINT:
728 			ELEM_CHECK(1);
729 			printf(", power constraint %udB", data[0]);
730 			break;
731 		case IEEE80211_ELEMID_QBSS_LOAD:
732 			ELEM_CHECK(5);
733 			printf(", %u stations, %d%% utilization, "
734 			    "admission capacity %uus/s",
735 			    (data[0] | data[1] << 8),
736 			    (data[2] * 100) / 255,
737 			    (data[3] | data[4] << 8) / 32);
738 			break;
739 		case IEEE80211_ELEMID_VENDOR:
740 			printf(", vendor");
741 			if (vflag)
742 				ieee80211_print_element(data, len);
743 			break;
744 		default:
745 			printf(", %u:%u", (u_int) *frm, len);
746 			if (vflag)
747 				ieee80211_print_element(data, len);
748 			break;
749 		}
750 		frm += len + 2;
751 
752 		if (frm >= snapend)
753 			break;
754 	}
755 
756 #undef ELEM_CHECK
757 
758 	return (0);
759 
760  trunc:
761 	/* Truncated elements in frame */
762 	return (1);
763 }
764 
765 int
766 ieee80211_frame(struct ieee80211_frame *wh, u_int len)
767 {
768 	u_int8_t subtype, type, *frm;
769 
770 	TCARR(wh->i_fc);
771 
772 	type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK;
773 	subtype = wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK;
774 
775 	frm = (u_int8_t *)&wh[1];
776 
777 	if (vflag)
778 		printb(" flags", wh->i_fc[1], IEEE80211_FC1_BITS);
779 
780 	switch (type) {
781 	case IEEE80211_FC0_TYPE_DATA:
782 		printf(": %s: ", ieee80211_data_subtype_name[
783 		    subtype >> IEEE80211_FC0_SUBTYPE_SHIFT]);
784 		ieee80211_data(wh, len);
785 		break;
786 	case IEEE80211_FC0_TYPE_MGT:
787 		printf(": %s", ieee80211_mgt_subtype_name[
788 		    subtype >> IEEE80211_FC0_SUBTYPE_SHIFT]);
789 		switch (subtype) {
790 		case IEEE80211_FC0_SUBTYPE_BEACON:
791 		case IEEE80211_FC0_SUBTYPE_PROBE_RESP:
792 			if (ieee80211_elements(wh, len) != 0)
793 				goto trunc;
794 			break;
795 		case IEEE80211_FC0_SUBTYPE_AUTH:
796 			TCHECK2(*frm, 2);		/* Auth Algorithm */
797 			switch (IEEE80211_AUTH_ALGORITHM(frm)) {
798 			case IEEE80211_AUTH_ALG_OPEN:
799 				TCHECK2(*frm, 4);	/* Auth Transaction */
800 				switch (IEEE80211_AUTH_TRANSACTION(frm)) {
801 				case IEEE80211_AUTH_OPEN_REQUEST:
802 					printf(" request");
803 					break;
804 				case IEEE80211_AUTH_OPEN_RESPONSE:
805 					printf(" response");
806 					break;
807 				}
808 				break;
809 			case IEEE80211_AUTH_ALG_SHARED:
810 				TCHECK2(*frm, 4);	/* Auth Transaction */
811 				switch (IEEE80211_AUTH_TRANSACTION(frm)) {
812 				case IEEE80211_AUTH_SHARED_REQUEST:
813 					printf(" request");
814 					break;
815 				case IEEE80211_AUTH_SHARED_CHALLENGE:
816 					printf(" challenge");
817 					break;
818 				case IEEE80211_AUTH_SHARED_RESPONSE:
819 					printf(" response");
820 					break;
821 				case IEEE80211_AUTH_SHARED_PASS:
822 					printf(" pass");
823 					break;
824 				}
825 				break;
826 			case IEEE80211_AUTH_ALG_LEAP:
827 				printf(" (leap)");
828 				break;
829 			}
830 			break;
831 		case IEEE80211_FC0_SUBTYPE_DEAUTH:
832 		case IEEE80211_FC0_SUBTYPE_DISASSOC:
833 			TCHECK2(*frm, 2);		/* Reason Code */
834 			ieee80211_reason(frm[0] | (frm[1] << 8));
835 			break;
836 		}
837 		break;
838 	case IEEE80211_FC0_TYPE_CTL: {
839 		u_int8_t *t = (u_int8_t *) wh;
840 
841 		printf(": %s", ieee80211_ctl_subtype_name[
842 		    subtype >> IEEE80211_FC0_SUBTYPE_SHIFT]);
843 		if (!vflag)
844 			break;
845 
846 		/* See 802.11 2012 "8.3.1 Control frames". */
847 		t += 2; /* skip Frame Control */
848 		switch (subtype) {
849 		case IEEE80211_FC0_SUBTYPE_RTS:
850 		case IEEE80211_FC0_SUBTYPE_BAR:
851 		case IEEE80211_FC0_SUBTYPE_BA:
852 			TCHECK2(*t, 2); /* Duration */
853 			printf(", duration %dms", (t[0] | t[1] << 8));
854 			t += 2;
855 			TCHECK2(*t, 6); /* RA */
856 			printf(", ra %s", etheraddr_string(t));
857 			t += 6;
858 			TCHECK2(*t, 6); /* TA */
859 			printf(", ta %s", etheraddr_string(t));
860 			if (subtype == IEEE80211_FC0_SUBTYPE_BAR ||
861 			    subtype == IEEE80211_FC0_SUBTYPE_BA) {
862 				u_int16_t ctrl;
863 
864 				t += 6;
865 				TCHECK2(*t, 2); /* BAR/BA control */
866 				ctrl = t[0] | (t[1] << 8);
867 				if (ctrl & IEEE80211_BA_ACK_POLICY)
868 					printf(", no ack");
869 				else
870 					printf(", normal ack");
871 				if ((ctrl & IEEE80211_BA_MULTI_TID) == 0 &&
872 				    (ctrl & IEEE80211_BA_COMPRESSED) == 0)
873 					printf(", basic variant");
874 				else if ((ctrl & IEEE80211_BA_MULTI_TID) &&
875 				    (ctrl & IEEE80211_BA_COMPRESSED))
876 					printf(", multi-tid variant");
877 				else if (ctrl & IEEE80211_BA_COMPRESSED)
878 					printf(", compressed variant");
879 			}
880 			break;
881 		case IEEE80211_FC0_SUBTYPE_CTS:
882 		case IEEE80211_FC0_SUBTYPE_ACK:
883 			TCHECK2(*t, 2); /* Duration */
884 			printf(", duration %dms", (t[0] | t[1] << 8));
885 			t += 2;
886 			TCHECK2(*t, 6); /* RA */
887 			printf(", ra %s", etheraddr_string(t));
888 			break;
889 		case IEEE80211_FC0_SUBTYPE_PS_POLL:
890 			TCHECK2(*t, 2); /* AID */
891 			printf(", aid 0x%x", (t[0] | t[1] << 8));
892 			t += 2;
893 			TCHECK2(*t, 6); /* BSSID(RA) */
894 			printf(", ra %s", etheraddr_string(t));
895 			t += 6;
896 			TCHECK2(*t, 6); /* TA */
897 			printf(", ta %s", etheraddr_string(t));
898 			break;
899 		}
900 		break;
901 	}
902 	default:
903 		printf(": type#%d", type);
904 		break;
905 	}
906 
907 	return (0);
908 
909  trunc:
910 	/* Truncated 802.11 frame */
911 	return (1);
912 }
913 
914 u_int
915 ieee80211_any2ieee(u_int freq, u_int flags)
916 {
917 	if (flags & IEEE80211_CHAN_2GHZ) {
918 		if (freq == 2484)
919 			return 14;
920 		if (freq < 2484)
921 			return (freq - 2407) / 5;
922 		else
923 			return 15 + ((freq - 2512) / 20);
924 	} else if (flags & IEEE80211_CHAN_5GHZ) {
925 		return (freq - 5000) / 5;
926 	} else {
927 		/* Assume channel is already an IEEE number */
928 		return (freq);
929 	}
930 }
931 
932 int
933 ieee80211_print(struct ieee80211_frame *wh, u_int len)
934 {
935 	if (eflag)
936 		if (ieee80211_hdr(wh))
937 			return (1);
938 
939 	printf("802.11");
940 
941 	return (ieee80211_frame(wh, len));
942 }
943 
944 void
945 ieee802_11_if_print(u_char *user, const struct pcap_pkthdr *h,
946     const u_char *p)
947 {
948 	struct ieee80211_frame *wh = (struct ieee80211_frame*)p;
949 
950 	if (!ieee80211_encap)
951 		ts_print(&h->ts);
952 
953 	packetp = p;
954 	snapend = p + h->caplen;
955 
956 	if (ieee80211_print(wh, (u_int)h->len) != 0)
957 		printf("[|802.11]");
958 
959 	if (!ieee80211_encap) {
960 		if (xflag)
961 			default_print(p, (u_int)h->len);
962 		putchar('\n');
963 	}
964 }
965 
966 void
967 ieee802_11_radio_if_print(u_char *user, const struct pcap_pkthdr *h,
968     const u_char *p)
969 {
970 	struct ieee80211_radiotap_header *rh =
971 	    (struct ieee80211_radiotap_header*)p;
972 	struct ieee80211_frame *wh;
973 	u_int8_t *t;
974 	u_int32_t present;
975 	u_int len, rh_len;
976 	u_int16_t tmp;
977 
978 	if (!ieee80211_encap)
979 		ts_print(&h->ts);
980 
981 	packetp = p;
982 	snapend = p + h->caplen;
983 
984 	TCHECK(*rh);
985 
986 	len = h->len;
987 	rh_len = letoh16(rh->it_len);
988 	if (rh->it_version != 0) {
989 		printf("[?radiotap + 802.11 v:%u]", rh->it_version);
990 		goto out;
991 	}
992 
993 	wh = (struct ieee80211_frame *)(p + rh_len);
994 	if (len <= rh_len || ieee80211_print(wh, len - rh_len))
995 		printf("[|802.11]");
996 
997 	t = (u_int8_t*)p + sizeof(struct ieee80211_radiotap_header);
998 
999 	if ((present = letoh32(rh->it_present)) == 0)
1000 		goto out;
1001 
1002 	printf(", <radiotap v%u", rh->it_version);
1003 
1004 #define RADIOTAP(_x)	\
1005 	(present & (1 << IEEE80211_RADIOTAP_##_x))
1006 
1007 	if (RADIOTAP(TSFT)) {
1008 		u_int64_t tsf;
1009 
1010 		TCHECK2(*t, 8);
1011 		bcopy(t, &tsf, sizeof(u_int64_t));
1012 		if (vflag > 1)
1013 			printf(", tsf %llu", letoh64(tsf));
1014 		t += 8;
1015 	}
1016 
1017 	if (RADIOTAP(FLAGS)) {
1018 		u_int8_t flags = *(u_int8_t*)t;
1019 		TCHECK2(*t, 1);
1020 
1021 		if (flags & IEEE80211_RADIOTAP_F_CFP)
1022 			printf(", CFP");
1023 		if (flags & IEEE80211_RADIOTAP_F_SHORTPRE)
1024 			printf(", SHORTPRE");
1025 		if (flags & IEEE80211_RADIOTAP_F_WEP)
1026 			printf(", WEP");
1027 		if (flags & IEEE80211_RADIOTAP_F_FRAG)
1028 			printf(", FRAG");
1029 		t += 1;
1030 	}
1031 
1032 	if (RADIOTAP(RATE)) {
1033 		TCHECK2(*t, 1);
1034 		if (vflag)
1035 			printf(", %uMbit/s", (*(u_int8_t*)t) / 2);
1036 		t += 1;
1037 	}
1038 
1039 	if (RADIOTAP(CHANNEL)) {
1040 		u_int16_t freq, flags;
1041 		TCHECK2(*t, 2);
1042 
1043 		bcopy(t, &freq, sizeof(u_int16_t));
1044 		freq = letoh16(freq);
1045 		t += 2;
1046 		TCHECK2(*t, 2);
1047 		bcopy(t, &flags, sizeof(u_int16_t));
1048 		flags = letoh16(flags);
1049 		t += 2;
1050 
1051 		printf(", chan %u", ieee80211_any2ieee(freq, flags));
1052 
1053 		if (flags & IEEE80211_CHAN_DYN &&
1054 		    flags & IEEE80211_CHAN_2GHZ)
1055 			printf(", 11g");
1056 		else if (flags & IEEE80211_CHAN_CCK &&
1057 		    flags & IEEE80211_CHAN_2GHZ)
1058 			printf(", 11b");
1059 		else if (flags & IEEE80211_CHAN_OFDM &&
1060 		    flags & IEEE80211_CHAN_2GHZ)
1061 			printf(", 11G");
1062 		else if (flags & IEEE80211_CHAN_OFDM &&
1063 		    flags & IEEE80211_CHAN_5GHZ)
1064 			printf(", 11a");
1065 
1066 		if (flags & IEEE80211_CHAN_XR)
1067 			printf(", XR");
1068 	}
1069 
1070 	if (RADIOTAP(FHSS)) {
1071 		TCHECK2(*t, 2);
1072 		printf(", fhss %u/%u", *(u_int8_t*)t, *(u_int8_t*)t + 1);
1073 		t += 2;
1074 	}
1075 
1076 	if (RADIOTAP(DBM_ANTSIGNAL)) {
1077 		TCHECK(*t);
1078 		printf(", sig %ddBm", *(int8_t*)t);
1079 		t += 1;
1080 	}
1081 
1082 	if (RADIOTAP(DBM_ANTNOISE)) {
1083 		TCHECK(*t);
1084 		printf(", noise %ddBm", *(int8_t*)t);
1085 		t += 1;
1086 	}
1087 
1088 	if (RADIOTAP(LOCK_QUALITY)) {
1089 		TCHECK2(*t, 2);
1090 		if (vflag) {
1091 			bcopy(t, &tmp, sizeof(u_int16_t));
1092 			printf(", quality %u", letoh16(tmp));
1093 		}
1094 		t += 2;
1095 	}
1096 
1097 	if (RADIOTAP(TX_ATTENUATION)) {
1098 		TCHECK2(*t, 2);
1099 		if (vflag) {
1100 			bcopy(t, &tmp, sizeof(u_int16_t));
1101 			printf(", txatt %u", letoh16(tmp));
1102 		}
1103 		t += 2;
1104 	}
1105 
1106 	if (RADIOTAP(DB_TX_ATTENUATION)) {
1107 		TCHECK2(*t, 2);
1108 		if (vflag) {
1109 			bcopy(t, &tmp, sizeof(u_int16_t));
1110 			printf(", txatt %udB", letoh16(tmp));
1111 		}
1112 		t += 2;
1113 	}
1114 
1115 	if (RADIOTAP(DBM_TX_POWER)) {
1116 		TCHECK(*t);
1117 		printf(", txpower %ddBm", *(int8_t*)t);
1118 		t += 1;
1119 	}
1120 
1121 	if (RADIOTAP(ANTENNA)) {
1122 		TCHECK(*t);
1123 		if (vflag)
1124 			printf(", antenna %u", *(u_int8_t*)t);
1125 		t += 1;
1126 	}
1127 
1128 	if (RADIOTAP(DB_ANTSIGNAL)) {
1129 		TCHECK(*t);
1130 		printf(", signal %udB", *(u_int8_t*)t);
1131 		t += 1;
1132 	}
1133 
1134 	if (RADIOTAP(DB_ANTNOISE)) {
1135 		TCHECK(*t);
1136 		printf(", noise %udB", *(u_int8_t*)t);
1137 		t += 1;
1138 	}
1139 
1140 	if (RADIOTAP(FCS)) {
1141 		TCHECK2(*t, 4);
1142 		if (vflag) {
1143 			u_int32_t fcs;
1144 			bcopy(t, &fcs, sizeof(u_int32_t));
1145 			printf(", fcs %08x", letoh32(fcs));
1146 		}
1147 		t += 4;
1148 	}
1149 
1150 	if (RADIOTAP(RSSI)) {
1151 		u_int8_t rssi, max_rssi;
1152 		TCHECK(*t);
1153 		rssi = *(u_int8_t*)t;
1154 		t += 1;
1155 		TCHECK(*t);
1156 		max_rssi = *(u_int8_t*)t;
1157 		t += 1;
1158 
1159 		printf(", rssi %u/%u", rssi, max_rssi);
1160 	}
1161 
1162 #undef RADIOTAP
1163 
1164 	putchar('>');
1165 	goto out;
1166 
1167  trunc:
1168 	/* Truncated frame */
1169 	printf("[|radiotap + 802.11]");
1170 
1171  out:
1172 	if (!ieee80211_encap) {
1173 		if (xflag)
1174 			default_print(p, h->len);
1175 		putchar('\n');
1176 	}
1177 }
1178 
1179 void
1180 ieee80211_reason(u_int16_t reason)
1181 {
1182 	if (!vflag)
1183 		return;
1184 
1185 	switch (reason) {
1186 	case IEEE80211_REASON_UNSPECIFIED:
1187 		printf(", unspecified failure");
1188 		break;
1189 	case IEEE80211_REASON_AUTH_EXPIRE:
1190 		printf(", authentication expired");
1191 		break;
1192 	case IEEE80211_REASON_AUTH_LEAVE:
1193 		printf(", deauth - station left");
1194 		break;
1195 	case IEEE80211_REASON_ASSOC_EXPIRE:
1196 		printf(", association expired");
1197 		break;
1198 	case IEEE80211_REASON_ASSOC_TOOMANY:
1199 		printf(", too many associated stations");
1200 		break;
1201 	case IEEE80211_REASON_NOT_AUTHED:
1202 		printf(", not authenticated");
1203 		break;
1204 	case IEEE80211_REASON_NOT_ASSOCED:
1205 		printf(", not associated");
1206 		break;
1207 	case IEEE80211_REASON_ASSOC_LEAVE:
1208 		printf(", disassociated - station left");
1209 		break;
1210 	case IEEE80211_REASON_ASSOC_NOT_AUTHED:
1211 		printf(", association but not authenticated");
1212 		break;
1213 	case IEEE80211_REASON_RSN_REQUIRED:
1214 		printf(", rsn required");
1215 		break;
1216 	case IEEE80211_REASON_RSN_INCONSISTENT:
1217 		printf(", rsn inconsistent");
1218 		break;
1219 	case IEEE80211_REASON_IE_INVALID:
1220 		printf(", ie invalid");
1221 		break;
1222 	case IEEE80211_REASON_MIC_FAILURE:
1223 		printf(", mic failure");
1224 		break;
1225 	default:
1226 		printf(", unknown reason %u", reason);
1227 	}
1228 }
1229