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