xref: /openbsd/usr.sbin/tcpdump/print-802_11.c (revision 46e5e1a2)
1 /*	$OpenBSD: print-802_11.c,v 1.44 2022/07/22 20:37:56 stsp Exp $	*/
2 
3 /*
4  * Copyright (c) 2005 Reyk Floeter <reyk@openbsd.org>
5  *
6  * Permission to use, copy, modify, and distribute this software for any
7  * purpose with or without fee is hereby granted, provided that the above
8  * copyright notice and this permission notice appear in all copies.
9  *
10  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17  */
18 
19 #include <sys/time.h>
20 #include <sys/socket.h>
21 #include <sys/file.h>
22 #include <sys/ioctl.h>
23 
24 #include <net/if.h>
25 
26 #include <netinet/in.h>
27 #include <netinet/if_ether.h>
28 
29 #include <net80211/ieee80211.h>
30 #include <net80211/ieee80211_radiotap.h>
31 
32 #include <ctype.h>
33 #include <pcap.h>
34 #include <stdio.h>
35 #include <string.h>
36 
37 #include "addrtoname.h"
38 #include "interface.h"
39 
40 const char *ieee80211_ctl_subtype_name[] = {
41 	"reserved#0",
42 	"reserved#1",
43 	"reserved#2",
44 	"reserved#3",
45 	"reserved#4",
46 	"reserved#5",
47 	"reserved#6",
48 	"wrapper",
49 	"block ack request",
50 	"block ack",
51 	"ps poll",
52 	"rts",
53 	"cts",
54 	"ack",
55 	"cf-end",
56 	"cf-end-ack",
57 };
58 
59 const char *ieee80211_mgt_subtype_name[] = {
60 	"association request",
61 	"association response",
62 	"reassociation request",
63 	"reassociation response",
64 	"probe request",
65 	"probe response",
66 	"reserved#6",
67 	"reserved#7",
68 	"beacon",
69 	"atim",
70 	"disassociation",
71 	"authentication",
72 	"deauthentication",
73 	"action",
74 	"action noack",
75 	"reserved#15"
76 };
77 
78 const char *ieee80211_data_subtype_name[] = {
79 	"data",
80 	"data cf ack",
81 	"data cf poll",
82 	"data cf poll ack",
83 	"no-data",
84 	"no-data cf poll",
85 	"no-data cf ack",
86 	"no-data cf poll ack",
87 	"QoS data",
88 	"QoS data cf ack",
89 	"QoS data cf poll",
90 	"QoS data cf poll ack",
91 	"QoS no-data",
92 	"QoS no-data cf poll",
93 	"QoS no-data cf ack",
94 	"QoS no-data cf poll ack"
95 };
96 
97 int	 ieee80211_hdr(struct ieee80211_frame *);
98 int	 ieee80211_data(struct ieee80211_frame *, u_int);
99 void	 ieee80211_print_element(u_int8_t *, u_int);
100 void	 ieee80211_print_essid(u_int8_t *, u_int);
101 void	 ieee80211_print_country(u_int8_t *, u_int);
102 void	 ieee80211_print_htcaps(u_int8_t *, u_int);
103 void	 ieee80211_print_htop(u_int8_t *, u_int);
104 void	 ieee80211_print_vhtcaps(u_int8_t *, u_int);
105 void	 ieee80211_print_vhtop(u_int8_t *, u_int);
106 void	 ieee80211_print_rsncipher(u_int8_t []);
107 void	 ieee80211_print_akm(u_int8_t []);
108 void	 ieee80211_print_rsn(u_int8_t *, u_int);
109 int	 ieee80211_print_beacon(struct ieee80211_frame *, u_int);
110 int	 ieee80211_print_assocreq(struct ieee80211_frame *, u_int);
111 int	 ieee80211_print_elements(uint8_t *);
112 int	 ieee80211_frame(struct ieee80211_frame *, u_int);
113 int	 ieee80211_print(struct ieee80211_frame *, u_int);
114 u_int	 ieee80211_any2ieee(u_int, u_int);
115 void	 ieee80211_reason(u_int16_t);
116 
117 #define TCARR(a)	TCHECK2(*a, sizeof(a))
118 
119 int ieee80211_encap = 0;
120 
121 int
ieee80211_hdr(struct ieee80211_frame * wh)122 ieee80211_hdr(struct ieee80211_frame *wh)
123 {
124 	struct ieee80211_frame_addr4 *w4;
125 
126 	switch (wh->i_fc[1] & IEEE80211_FC1_DIR_MASK) {
127 	case IEEE80211_FC1_DIR_NODS:
128 		TCARR(wh->i_addr2);
129 		printf("%s", etheraddr_string(wh->i_addr2));
130 		TCARR(wh->i_addr1);
131 		printf(" > %s", etheraddr_string(wh->i_addr1));
132 		TCARR(wh->i_addr3);
133 		printf(", bssid %s", etheraddr_string(wh->i_addr3));
134 		break;
135 	case IEEE80211_FC1_DIR_TODS:
136 		TCARR(wh->i_addr2);
137 		printf("%s", etheraddr_string(wh->i_addr2));
138 		TCARR(wh->i_addr3);
139 		printf(" > %s", etheraddr_string(wh->i_addr3));
140 		TCARR(wh->i_addr1);
141 		printf(", bssid %s, > DS", etheraddr_string(wh->i_addr1));
142 		break;
143 	case IEEE80211_FC1_DIR_FROMDS:
144 		TCARR(wh->i_addr3);
145 		printf("%s", etheraddr_string(wh->i_addr3));
146 		TCARR(wh->i_addr1);
147 		printf(" > %s", etheraddr_string(wh->i_addr1));
148 		TCARR(wh->i_addr2);
149 		printf(", bssid %s, DS >", etheraddr_string(wh->i_addr2));
150 		break;
151 	case IEEE80211_FC1_DIR_DSTODS:
152 		w4 = (struct ieee80211_frame_addr4 *) wh;
153 		TCARR(w4->i_addr4);
154 		printf("%s", etheraddr_string(w4->i_addr4));
155 		TCARR(w4->i_addr3);
156 		printf(" > %s", etheraddr_string(w4->i_addr3));
157 		TCARR(w4->i_addr2);
158 		printf(", bssid %s", etheraddr_string(w4->i_addr2));
159 		TCARR(w4->i_addr1);
160 		printf(" > %s, DS > DS", etheraddr_string(w4->i_addr1));
161 		break;
162 	}
163 	if (vflag) {
164 		u_int16_t seq;
165 		TCARR(wh->i_seq);
166 		bcopy(wh->i_seq, &seq, sizeof(u_int16_t));
167 		printf(" (seq %u frag %u): ",
168 		    letoh16(seq) >> IEEE80211_SEQ_SEQ_SHIFT,
169 		    letoh16(seq) & IEEE80211_SEQ_FRAG_MASK);
170 	} else
171 		printf(": ");
172 
173 	return (0);
174 
175  trunc:
176 	/* Truncated elements in frame */
177 	return (1);
178 }
179 
180 int
ieee80211_data(struct ieee80211_frame * wh,u_int len)181 ieee80211_data(struct ieee80211_frame *wh, u_int len)
182 {
183 	u_int8_t *t = (u_int8_t *)wh;
184 	u_int datalen;
185 	int data = !(wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_NODATA);
186 	int hasqos = ((wh->i_fc[0] &
187 	    (IEEE80211_FC0_TYPE_MASK | IEEE80211_FC0_SUBTYPE_QOS)) ==
188 	    (IEEE80211_FC0_TYPE_DATA | IEEE80211_FC0_SUBTYPE_QOS));
189 	u_char *esrc = NULL, *edst = NULL;
190 
191 	if (hasqos) {
192 		struct ieee80211_qosframe *wq;
193 
194 		wq = (struct ieee80211_qosframe *) wh;
195 		TCHECK(*wq);
196 		t += sizeof(*wq);
197 		datalen = len - sizeof(*wq);
198 	} else {
199 		TCHECK(*wh);
200 		t += sizeof(*wh);
201 		datalen = len - sizeof(*wh);
202 	}
203 
204 	switch (wh->i_fc[1] & IEEE80211_FC1_DIR_MASK) {
205 	case IEEE80211_FC1_DIR_TODS:
206 		esrc = wh->i_addr2;
207 		edst = wh->i_addr3;
208 		break;
209 	case IEEE80211_FC1_DIR_FROMDS:
210 		esrc = wh->i_addr3;
211 		edst = wh->i_addr1;
212 		break;
213 	case IEEE80211_FC1_DIR_NODS:
214 		esrc = wh->i_addr2;
215 		edst = wh->i_addr1;
216 		break;
217 	case IEEE80211_FC1_DIR_DSTODS:
218 		if (hasqos) {
219 			struct ieee80211_qosframe_addr4 *w4;
220 
221 			w4 = (struct ieee80211_qosframe_addr4 *) wh;
222 			TCHECK(*w4);
223 			t = (u_int8_t *) (w4 + 1);
224 			datalen = len - sizeof(*w4);
225 			esrc = w4->i_addr4;
226 			edst = w4->i_addr3;
227 		} else {
228 			struct ieee80211_frame_addr4 *w4;
229 
230 			w4 = (struct ieee80211_frame_addr4 *) wh;
231 			TCHECK(*w4);
232 			t = (u_int8_t *) (w4 + 1);
233 			datalen = len - sizeof(*w4);
234 			esrc = w4->i_addr4;
235 			edst = w4->i_addr3;
236 		}
237 		break;
238 	}
239 
240 	if (data && esrc)
241 		llc_print(t, datalen, datalen, esrc, edst);
242 	else if (eflag && esrc)
243 		printf("%s > %s",
244 		    etheraddr_string(esrc), etheraddr_string(edst));
245 
246 	return (0);
247 
248  trunc:
249 	/* Truncated elements in frame */
250 	return (1);
251 }
252 
253 /* Caller checks len */
254 void
ieee80211_print_element(u_int8_t * data,u_int len)255 ieee80211_print_element(u_int8_t *data, u_int len)
256 {
257 	u_int8_t *p;
258 	int i;
259 
260 	printf(" 0x");
261 	for (i = 0, p = data; i < len; i++, p++)
262 		printf("%02x", *p);
263 }
264 
265 /* Caller checks len */
266 void
ieee80211_print_essid(u_int8_t * essid,u_int len)267 ieee80211_print_essid(u_int8_t *essid, u_int len)
268 {
269 	u_int8_t *p;
270 	int i;
271 
272 	if (len > IEEE80211_NWID_LEN)
273 		len = IEEE80211_NWID_LEN;
274 
275 	/* determine printable or not */
276 	for (i = 0, p = essid; i < len; i++, p++) {
277 		if (*p < ' ' || *p > 0x7e)
278 			break;
279 	}
280 	if (i == len) {
281 		printf(" (");
282 		for (i = 0, p = essid; i < len; i++, p++)
283 			putchar(*p);
284 		putchar(')');
285 	} else
286 		ieee80211_print_element(essid, len);
287 }
288 
289 /* Caller checks len */
290 void
ieee80211_print_country(u_int8_t * data,u_int len)291 ieee80211_print_country(u_int8_t *data, u_int len)
292 {
293 	u_int8_t first_chan, nchan, maxpower;
294 
295 	if (len < 6)
296 		return;
297 
298 	/* country string */
299 	printf((isprint(data[0]) ? " '%c" : " '\\%03o"), data[0]);
300 	printf((isprint(data[1]) ? "%c" : "\\%03o"), data[1]);
301 	printf((isprint(data[2]) ? "%c'" : "\\%03o'"), data[2]);
302 
303 	len -= 3;
304 	data += 3;
305 
306 	/* channels and corresponding TX power limits */
307 	while (len >= 3) {
308 		/* no pretty-printing for nonsensical zero values,
309 		 * nor for operating extension IDs (values >= 201) */
310 		if (data[0] == 0 || data[1] == 0 ||
311 		    data[0] >= 201 || data[1] >= 201) {
312 			printf(", %d %d %d", data[0], data[1], data[2]);
313 			len -= 3;
314 			data += 3;
315 			continue;
316 		}
317 
318 		first_chan = data[0];
319 		nchan = data[1];
320 		maxpower = data[2];
321 
322 		printf(", channel%s %d", nchan == 1 ? "" : "s", first_chan);
323 		if (nchan > 1)
324 			printf("-%d", first_chan + nchan - 1);
325 		printf(" limit %ddB", maxpower);
326 
327 		len -= 3;
328 		data += 3;
329 	}
330 }
331 
332 /* Caller checks len */
333 void
ieee80211_print_htcaps(u_int8_t * data,u_int len)334 ieee80211_print_htcaps(u_int8_t *data, u_int len)
335 {
336 	uint16_t htcaps, rxrate;
337 	int smps, rxstbc;
338 	uint8_t ampdu, txmcs;
339 	int i;
340 	uint8_t *rxmcs;
341 
342 	if (len < 2) {
343 		ieee80211_print_element(data, len);
344 		return;
345 	}
346 
347 	htcaps = (data[0]) | (data[1] << 8);
348 	printf("=<");
349 
350 	/* channel width */
351 	if (htcaps & IEEE80211_HTCAP_CBW20_40)
352 		printf("20/40MHz");
353 	else
354 		printf("20MHz");
355 
356 	/* LDPC coding */
357 	if (htcaps & IEEE80211_HTCAP_LDPC)
358 		printf(",LDPC");
359 
360 	/* spatial multiplexing power save mode */
361 	smps = (htcaps & IEEE80211_HTCAP_SMPS_MASK)
362 	    >> IEEE80211_HTCAP_SMPS_SHIFT;
363 	if (smps == 0)
364 		printf(",SMPS static");
365 	else if (smps == 1)
366 		printf(",SMPS dynamic");
367 
368 	/* 11n greenfield mode */
369 	if (htcaps & IEEE80211_HTCAP_GF)
370 		printf(",greenfield");
371 
372 	/* short guard interval */
373 	if (htcaps & IEEE80211_HTCAP_SGI20)
374 		printf(",SGI@20MHz");
375 	if (htcaps & IEEE80211_HTCAP_SGI40)
376 		printf(",SGI@40MHz");
377 
378 	/* space-time block coding */
379 	if (htcaps & IEEE80211_HTCAP_TXSTBC)
380 		printf(",TXSTBC");
381 	rxstbc = (htcaps & IEEE80211_HTCAP_RXSTBC_MASK)
382 	    >> IEEE80211_HTCAP_RXSTBC_SHIFT;
383 	if (rxstbc > 0 && rxstbc < 4)
384 		printf(",RXSTBC %d stream", rxstbc);
385 
386 	/* delayed block-ack */
387 	if (htcaps & IEEE80211_HTCAP_DELAYEDBA)
388 		printf(",delayed BA");
389 
390 	/* max A-MSDU length */
391 	if (htcaps & IEEE80211_HTCAP_AMSDU7935)
392 		printf(",A-MSDU 7935");
393 	else
394 		printf(",A-MSDU 3839");
395 
396 	/* DSSS/CCK in 40MHz mode */
397 	if (htcaps & IEEE80211_HTCAP_DSSSCCK40)
398 		printf(",DSSS/CCK@40MHz");
399 
400 	/* 40MHz intolerant */
401 	if (htcaps & IEEE80211_HTCAP_40INTOLERANT)
402 		printf(",40MHz intolerant");
403 
404 	/* L-SIG TXOP protection */
405 	if (htcaps & IEEE80211_HTCAP_LSIGTXOPPROT)
406 		printf(",L-SIG TXOP prot");
407 
408 	if (len < 3) {
409 		printf(">");
410 		return;
411 	}
412 
413 	/* A-MPDU parameters. */
414 	ampdu = data[2];
415 
416 	/* A-MPDU length exponent */
417 	if ((ampdu & IEEE80211_AMPDU_PARAM_LE) >= 0 &&
418 	    (ampdu & IEEE80211_AMPDU_PARAM_LE) <= 3)
419 		printf(",A-MPDU max %d",
420 		    (1 << (13 + (ampdu & IEEE80211_AMPDU_PARAM_LE))) - 1);
421 
422 	/* A-MPDU start spacing */
423 	if (ampdu & IEEE80211_AMPDU_PARAM_SS) {
424 		float ss;
425 
426 		switch ((ampdu & IEEE80211_AMPDU_PARAM_SS) >> 2) {
427 		case 1:
428 			ss = 0.25;
429 			break;
430 		case 2:
431 			ss = 0.5;
432 			break;
433 		case 3:
434 			ss = 1;
435 			break;
436 		case 4:
437 			ss = 2;
438 			break;
439 		case 5:
440 			ss = 4;
441 			break;
442 		case 6:
443 			ss = 8;
444 			break;
445 		case 7:
446 			ss = 16;
447 			break;
448 		default:
449 			ss = 0;
450 			break;
451 		}
452 		if (ss != 0)
453 			printf(",A-MPDU spacing %.2fus", ss);
454 	}
455 
456 	if (len < 21) {
457 		printf(">");
458 		return;
459 	}
460 
461 	/* Supported MCS set. */
462 	printf(",RxMCS 0x");
463 	rxmcs = &data[3];
464 	for (i = 0; i < 10; i++)
465 		printf("%02x", rxmcs[i]);
466 
467 	/* Max MCS Rx rate (a value of 0 means "not specified"). */
468 	rxrate = ((data[13] | (data[14]) << 8) & IEEE80211_MCS_RX_RATE_HIGH);
469 	if (rxrate)
470 		printf(",RxMaxrate %huMb/s", rxrate);
471 
472 	/* Tx MCS Set */
473 	txmcs = data[15];
474 	if (txmcs & IEEE80211_TX_MCS_SET_DEFINED) {
475 		if (txmcs & IEEE80211_TX_RX_MCS_NOT_EQUAL) {
476 			/* Number of spatial Tx streams. */
477 			printf(",%d Tx streams",
478 			     1 + ((txmcs & IEEE80211_TX_SPATIAL_STREAMS) >> 2));
479 			/* Transmit unequal modulation supported. */
480 			if (txmcs & IEEE80211_TX_UNEQUAL_MODULATION)
481 				printf(",UEQM");
482 		}
483 	}
484 
485 	printf(">");
486 }
487 
488 /* Caller checks len */
489 void
ieee80211_print_htop(u_int8_t * data,u_int len)490 ieee80211_print_htop(u_int8_t *data, u_int len)
491 {
492 	u_int8_t primary_chan;
493 	u_int8_t htopinfo[5];
494 	u_int8_t basic_mcs[16];
495 	int sco, htprot, i;
496 
497 	if (len < sizeof(primary_chan) + sizeof(htopinfo) + sizeof(basic_mcs)) {
498 		ieee80211_print_element(data, len);
499 		return;
500 	}
501 
502 	htopinfo[0] = data[1];
503 
504 	printf("=<");
505 
506 	/* primary channel and secondary channel offset */
507 	primary_chan = data[0];
508 	sco = ((htopinfo[0] & IEEE80211_HTOP0_SCO_MASK)
509 	    >> IEEE80211_HTOP0_SCO_SHIFT);
510 	if (sco == 0) /* no secondary channel */
511 		printf("20MHz chan %d", primary_chan);
512 	else if (sco == 1) { /* secondary channel above */
513 		if (primary_chan >= 1 && primary_chan <= 13) /* 2GHz */
514 			printf("40MHz chan %d:%d", primary_chan,
515 			    primary_chan + 1);
516 		else if (primary_chan >= 34) /* 5GHz */
517 			printf("40MHz chan %d:%d", primary_chan,
518 			    primary_chan + 4);
519 		else
520 			printf("[invalid 40MHz chan %d+]", primary_chan);
521 	} else if (sco == 3) { /* secondary channel below */
522 		if (primary_chan >= 2 && primary_chan <= 14) /* 2GHz */
523 			printf("40MHz chan %d:%d", primary_chan,
524 			    primary_chan - 1);
525 		else if (primary_chan >= 40) /* 5GHz */
526 			printf("40MHz chan %d:%d", primary_chan,
527 			    primary_chan - 4);
528 		else
529 			printf("[invalid 40MHz chan %d-]", primary_chan);
530 	} else
531 		printf("chan %d [invalid secondary channel offset %d]",
532 		    primary_chan, sco);
533 
534 	/* STA channel width */
535 	if ((htopinfo[0] & IEEE80211_HTOP0_CHW) == 0)
536 		printf(",STA chanw 20MHz");
537 
538 	/* reduced interframe space (RIFS) permitted */
539 	if (htopinfo[0] & IEEE80211_HTOP0_RIFS)
540 		printf(",RIFS");
541 
542 	htopinfo[1] = data[2];
543 
544 	/* protection requirements for HT transmissions */
545 	htprot = ((htopinfo[1] & IEEE80211_HTOP1_PROT_MASK)
546 	    >> IEEE80211_HTOP1_PROT_SHIFT);
547 	switch (htprot) {
548 	case IEEE80211_HTPROT_NONE:
549 		printf(",htprot none");
550 		break;
551 	case IEEE80211_HTPROT_NONMEMBER:
552 		printf(",htprot non-member");
553 		break;
554 	case IEEE80211_HTPROT_20MHZ:
555 		printf(",htprot 20MHz");
556 		break;
557 	case IEEE80211_HTPROT_NONHT_MIXED:
558 		printf(",htprot non-HT-mixed");
559 		break;
560 	default:
561 		printf(",htprot %d", htprot);
562 		break;
563 	}
564 
565 	/* non-greenfield STA present */
566 	if (htopinfo[1] & IEEE80211_HTOP1_NONGF_STA)
567 		printf(",non-greenfield STA");
568 
569 	/* non-HT STA present */
570 	if (htopinfo[1] & IEEE80211_HTOP1_OBSS_NONHT_STA)
571 		printf(",non-HT STA");
572 
573 	htopinfo[3] = data[4];
574 
575 	/* dual-beacon */
576 	if (htopinfo[3] & IEEE80211_HTOP2_DUALBEACON)
577 		printf(",dualbeacon");
578 
579 	/* dual CTS protection */
580 	if (htopinfo[3] & IEEE80211_HTOP2_DUALCTSPROT)
581 		printf(",dualctsprot");
582 
583 	htopinfo[4] = data[5];
584 
585 	/* space-time block coding (STBC) beacon */
586 	if ((htopinfo[4] << 8) & IEEE80211_HTOP2_STBCBEACON)
587 		printf(",STBC beacon");
588 
589 	/* L-SIG (non-HT signal field) TX opportunity (TXOP) protection */
590 	if ((htopinfo[4] << 8) & IEEE80211_HTOP2_LSIGTXOP)
591 		printf(",lsigtxprot");
592 
593 	/* phased-coexistence operation (PCO) active */
594 	if ((htopinfo[4] << 8) & IEEE80211_HTOP2_PCOACTIVE) {
595 		/* PCO phase */
596 		if ((htopinfo[4] << 8) & IEEE80211_HTOP2_PCOPHASE40)
597 			printf(",pco40MHz");
598 		else
599 			printf(",pco20MHz");
600 	}
601 
602 	/* basic MCS set */
603 	memcpy(basic_mcs, &data[6], sizeof(basic_mcs));
604 	printf(",basic MCS set 0x");
605 	for (i = 0; i < sizeof(basic_mcs) / sizeof(basic_mcs[0]); i++)
606 			printf("%x", basic_mcs[i]);
607 
608 	printf(">");
609 }
610 
611 void
print_vht_mcsmap(uint16_t mcsmap)612 print_vht_mcsmap(uint16_t mcsmap)
613 {
614 	int nss, mcs;
615 
616 	for (nss = 1; nss < IEEE80211_VHT_NUM_SS; nss++) {
617 		mcs = (mcsmap & IEEE80211_VHT_MCS_FOR_SS_MASK(nss)) >>
618 		    IEEE80211_VHT_MCS_FOR_SS_SHIFT(nss);
619 		switch (mcs) {
620 		case IEEE80211_VHT_MCS_0_9:
621 			printf(" 0-9@%uSS", nss);
622 			break;
623 		case IEEE80211_VHT_MCS_0_8:
624 			printf(" 0-8@%uSS", nss);
625 			break;
626 		case IEEE80211_VHT_MCS_0_7:
627 			printf(" 0-7@%uSS", nss);
628 			break;
629 		case IEEE80211_VHT_MCS_SS_NOT_SUPP:
630 		default:
631 			break;
632 		}
633 	}
634 }
635 
636 /* Caller checks len */
637 void
ieee80211_print_vhtcaps(u_int8_t * data,u_int len)638 ieee80211_print_vhtcaps(u_int8_t *data, u_int len)
639 {
640 	uint32_t vhtcaps;
641 	uint16_t rxmcs, txmcs, max_lgi;
642 	uint32_t rxstbc, num_sts, max_ampdu, link_adapt;
643 
644 	if (len < 12) {
645 		ieee80211_print_element(data, len);
646 		return;
647 	}
648 
649 	vhtcaps = (data[0] | (data[1] << 8) | data[2] << 16 |
650 	    data[3] << 24);
651 	printf("=<");
652 
653 	/* max MPDU length */
654 	switch (vhtcaps & IEEE80211_VHTCAP_MAX_MPDU_LENGTH_MASK) {
655 	case IEEE80211_VHTCAP_MAX_MPDU_LENGTH_11454:
656 		printf("max MPDU 11454");
657 		break;
658 	case IEEE80211_VHTCAP_MAX_MPDU_LENGTH_7991:
659 		printf("max MPDU 7991");
660 		break;
661 	case IEEE80211_VHTCAP_MAX_MPDU_LENGTH_3895:
662 	default:
663 		printf("max MPDU 3895");
664 		break;
665 	}
666 
667 	/* supported channel widths */
668 	switch ((vhtcaps & IEEE80211_VHTCAP_CHAN_WIDTH_MASK) <<
669 	    IEEE80211_VHTCAP_CHAN_WIDTH_SHIFT) {
670 	case IEEE80211_VHTCAP_CHAN_WIDTH_160_8080:
671 		printf(",80+80MHz");
672 		/* fallthrough */
673 	case IEEE80211_VHTCAP_CHAN_WIDTH_160:
674 		printf(",160MHz");
675 		/* fallthrough */
676 	case IEEE80211_VHTCAP_CHAN_WIDTH_80:
677 	default:
678 		printf(",80MHz");
679 		break;
680 	}
681 
682 	/* LDPC coding */
683 	if (vhtcaps & IEEE80211_VHTCAP_RX_LDPC)
684 		printf(",LDPC");
685 
686 	/* short guard interval */
687 	if (vhtcaps & IEEE80211_VHTCAP_SGI80)
688 		printf(",SGI@80MHz");
689 	if (vhtcaps & IEEE80211_VHTCAP_SGI160)
690 		printf(",SGI@160MHz");
691 
692 	/* space-time block coding */
693 	if (vhtcaps & IEEE80211_VHTCAP_TX_STBC)
694 		printf(",TxSTBC");
695 	rxstbc = (vhtcaps & IEEE80211_VHTCAP_RX_STBC_SS_MASK)
696 	    >> IEEE80211_VHTCAP_RX_STBC_SS_SHIFT;
697 	if (rxstbc > 0 && rxstbc <= 7)
698 		printf(",RxSTBC %d stream", rxstbc);
699 
700 	/* beamforming */
701 	if (vhtcaps & IEEE80211_VHTCAP_SU_BEAMFORMER) {
702 		printf(",beamformer");
703 		num_sts = ((vhtcaps & IEEE80211_VHTCAP_NUM_STS_MASK) >>
704 		    IEEE80211_VHTCAP_NUM_STS_SHIFT);
705 		if (num_sts)
706 			printf(" STS %u", num_sts);
707 	}
708 	if (vhtcaps & IEEE80211_VHTCAP_SU_BEAMFORMEE) {
709 		printf(",beamformee");
710 		num_sts = ((vhtcaps & IEEE80211_VHTCAP_BEAMFORMEE_STS_MASK) >>
711 		    IEEE80211_VHTCAP_BEAMFORMEE_STS_SHIFT);
712 		if (num_sts)
713 			printf(" STS %u", num_sts);
714 	}
715 
716 	if (vhtcaps & IEEE80211_VHTCAP_TXOP_PS)
717 		printf(",TXOP PS");
718 	if (vhtcaps & IEEE80211_VHTCAP_HTC_VHT)
719 		printf(",+HTC VHT");
720 
721 	/* max A-MPDU length */
722 	max_ampdu = ((vhtcaps & IEEE80211_VHTCAP_MAX_AMPDU_LEN_MASK) >>
723 	    IEEE80211_VHTCAP_MAX_AMPDU_LEN_SHIFT);
724 	if (max_ampdu >= IEEE80211_VHTCAP_MAX_AMPDU_LEN_8K &&
725 	    max_ampdu <= IEEE80211_VHTCAP_MAX_AMPDU_LEN_1024K)
726 		printf(",max A-MPDU %uK", (1 << (max_ampdu + 3)));
727 
728 	link_adapt = ((vhtcaps & IEEE80211_VHTCAP_LINK_ADAPT_MASK) >>
729 	    IEEE80211_VHTCAP_LINK_ADAPT_SHIFT);
730 	if (link_adapt == IEEE80211_VHTCAP_LINK_ADAPT_UNSOL_MFB)
731 		printf(",linkadapt unsolicited MFB");
732 	else if (link_adapt == IEEE80211_VHTCAP_LINK_ADAPT_MRQ_MFB)
733 		printf(",linkadapt MRQ MFB");
734 
735 	if (vhtcaps & IEEE80211_VHTCAP_RX_ANT_PATTERN)
736 		printf(",Rx ant pattern consistent");
737 	if (vhtcaps & IEEE80211_VHTCAP_TX_ANT_PATTERN)
738 		printf(",Tx ant pattern consistent");
739 
740 	/* Supported MCS set. */
741 	rxmcs = (data[4] | (data[5] << 8));
742 	printf(",RxMCS");
743 	print_vht_mcsmap(rxmcs);
744 	max_lgi = ((data[6] | (data[7] << 8)) &
745 	    IEEE80211_VHT_MAX_LGI_MBIT_S_MASK);
746 	if (max_lgi)
747 		printf(",Rx max LGI rate %uMbit/s", max_lgi);
748 	txmcs = (data[8] | (data[9] << 8));
749 	printf(",TxMCS");
750 	print_vht_mcsmap(txmcs);
751 	max_lgi = ((data[6] | (data[7] << 8)) &
752 	    IEEE80211_VHT_MAX_LGI_MBIT_S_MASK);
753 	if (max_lgi)
754 		printf(",Tx max LGI rate %uMbit/s", max_lgi);
755 
756 	printf(">");
757 }
758 
759 /* Caller checks len */
760 void
ieee80211_print_vhtop(u_int8_t * data,u_int len)761 ieee80211_print_vhtop(u_int8_t *data, u_int len)
762 {
763 	u_int8_t chan_width, freq_idx0, freq_idx1;
764 	uint16_t basic_mcs;
765 
766 	if (len < 5) {
767 		ieee80211_print_element(data, len);
768 		return;
769 	}
770 
771 	chan_width = data[0];
772 	printf("=<");
773 
774 	switch (chan_width) {
775 	case IEEE80211_VHTOP0_CHAN_WIDTH_8080:
776 		printf("80+80MHz chan");
777 		break;
778 	case IEEE80211_VHTOP0_CHAN_WIDTH_160:
779 		printf("160MHz chan");
780 		break;
781 	case IEEE80211_VHTOP0_CHAN_WIDTH_80:
782 		printf("80MHz chan");
783 		break;
784 	case IEEE80211_VHTOP0_CHAN_WIDTH_HT:
785 	default:
786 		printf("using HT chan width");
787 		break;
788 	}
789 
790 	freq_idx0 = data[1];
791 	if (freq_idx0)
792 		printf(",center chan %u", freq_idx0);
793 	freq_idx1 = data[2];
794 	if (freq_idx1)
795 		printf(",second center chan %u", freq_idx1);
796 
797 	basic_mcs = (data[3] | data[4] << 8);
798 	printf(",basic MCS set");
799 	print_vht_mcsmap(basic_mcs);
800 
801 	printf(">");
802 }
803 
804 void
ieee80211_print_rsncipher(uint8_t selector[4])805 ieee80211_print_rsncipher(uint8_t selector[4])
806 {
807 	if (memcmp(selector, MICROSOFT_OUI, 3) != 0 &&
808 	    memcmp(selector, IEEE80211_OUI, 3) != 0) {
809 		printf("0x%x%x%x%x", selector[0], selector[1], selector[2],
810 		     selector[3]);
811 	    	return;
812 	}
813 
814 	/* See 802.11-2012 Table 8-99 */
815 	switch (selector[3]) {
816 	case 0:	/* use group data cipher suite */
817 		printf("usegroup");
818 		break;
819 	case 1:	/* WEP-40 */
820 		printf("wep40");
821 		break;
822 	case 2:	/* TKIP */
823 		printf("tkip");
824 		break;
825 	case 4:	/* CCMP (RSNA default) */
826 		printf("ccmp");
827 		break;
828 	case 5:	/* WEP-104 */
829 		printf("wep104");
830 		break;
831 	case 6:	/* BIP */
832 		printf("bip");
833 		break;
834 	default:
835 		printf("%d", selector[3]);
836 		break;
837 	}
838 }
839 
840 void
ieee80211_print_akm(uint8_t selector[4])841 ieee80211_print_akm(uint8_t selector[4])
842 {
843 	if (memcmp(selector, MICROSOFT_OUI, 3) != 0 &&
844 	    memcmp(selector, IEEE80211_OUI, 3) != 0) {
845 		printf("0x%x%x%x%x", selector[0], selector[1], selector[2],
846 		     selector[3]);
847 	    	return;
848 	}
849 
850 	switch (selector[3]) {
851 	case 1:
852 		printf("802.1x");
853 		break;
854 	case 2:
855 		printf("PSK");
856 		break;
857 	case 5:
858 		printf("SHA256-802.1x");
859 		break;
860 	case 6:
861 		printf("SHA256-PSK");
862 		break;
863 	case 8:
864 		printf("SAE");
865 		break;
866 	default:
867 		printf("%d", selector[3]);
868 		break;
869 	}
870 }
871 
872 /* Caller checks len */
873 void
ieee80211_print_rsn(u_int8_t * data,u_int len)874 ieee80211_print_rsn(u_int8_t *data, u_int len)
875 {
876 	uint16_t version, nciphers, nakms, rsncap, npmk;
877 	int i, j;
878 	uint8_t selector[4];
879 
880 	if (len < 2) {
881 		ieee80211_print_element(data, len);
882 		return;
883 	}
884 
885 	version = (data[0]) | (data[1] << 8);
886 	printf("=<version %d", version);
887 
888 	if (len < 6) {
889 		printf(">");
890 		return;
891 	}
892 
893 	data += 2;
894 	printf(",groupcipher ");
895 	for (i = 0; i < 4; i++)
896 		selector[i] = data[i];
897 	ieee80211_print_rsncipher(selector);
898 
899 	if (len < 8) {
900 		printf(">");
901 		return;
902 	}
903 
904 	data += 4;
905 	nciphers = (data[0]) | ((data[1]) << 8);
906 	data += 2;
907 
908 	if (len < 8 + (nciphers * 4)) {
909 		printf(">");
910 		return;
911 	}
912 
913 	printf(",cipher%s ", nciphers > 1 ? "s" : "");
914 	for (i = 0; i < nciphers; i++) {
915 		for (j = 0; j < 4; j++)
916 			selector[j] = data[j];
917 		ieee80211_print_rsncipher(selector);
918 		if (i < nciphers - 1)
919 			printf(" ");
920 		data += 4;
921 	}
922 
923 	if (len < 8 + (nciphers * 4) + 2) {
924 		printf(">");
925 		return;
926 	}
927 
928 	nakms = (data[0]) | ((data[1]) << 8);
929 	data += 2;
930 
931 	if (len < 8 + (nciphers * 4) + 2 + (nakms * 4)) {
932 		printf(">");
933 		return;
934 	}
935 
936 	printf(",akm%s ", nakms > 1 ? "s" : "");
937 	for (i = 0; i < nakms; i++) {
938 		for (j = 0; j < 4; j++)
939 			selector[j] = data[j];
940 		ieee80211_print_akm(selector);
941 		if (i < nakms - 1)
942 			printf(" ");
943 		data += 4;
944 	}
945 
946 	if (len < 8 + (nciphers * 4) + 2 + (nakms * 4) + 2) {
947 		printf(">");
948 		return;
949 	}
950 
951 	rsncap = (data[0]) | ((data[1]) << 8);
952 	printf(",rsncap 0x%x", rsncap);
953 	data += 2;
954 
955 	if (len < 8 + (nciphers * 4) + 2 + (nakms * 4) + 2 + 2) {
956 		printf(">");
957 		return;
958 	}
959 
960 	npmk = (data[0]) | ((data[1]) << 8);
961 	data += 2;
962 
963 	if (len < 8 + (nciphers * 4) + 2 + (nakms * 4) + 2 + 2 +
964 	    (npmk * IEEE80211_PMKID_LEN)) {
965 		printf(">");
966 		return;
967 	}
968 
969 	if (npmk >= 1)
970 		printf(",pmkid%s ", npmk > 1 ? "s" : "");
971 	for (i = 0; i < npmk; i++) {
972 		printf("0x");
973 		for (j = 0; j < IEEE80211_PMKID_LEN; j++)
974 			printf("%x", data[j]);
975 		if (i < npmk - 1)
976 			printf(" ");
977 		data += IEEE80211_PMKID_LEN;
978 	}
979 
980 	if (len < 8 + (nciphers * 4) + 2 + (nakms * 4) + 2 + 2 +
981 	    (npmk * IEEE80211_PMKID_LEN) + 4) {
982 		printf(">");
983 		return;
984 	}
985 
986 	printf(",integrity-groupcipher ");
987 	for (i = 0; i < 4; i++)
988 		selector[i] = data[i];
989 	ieee80211_print_rsncipher(selector);
990 
991 	printf(">");
992 }
993 
994 int
ieee80211_print_beacon(struct ieee80211_frame * wh,u_int len)995 ieee80211_print_beacon(struct ieee80211_frame *wh, u_int len)
996 {
997 	uint64_t tstamp;
998 	uint16_t bintval, capinfo;
999 	uint8_t *frm;
1000 
1001 	if (len < sizeof(tstamp) + sizeof(bintval) + sizeof(capinfo))
1002 		return 1; /* truncated */
1003 
1004 	frm = (u_int8_t *)&wh[1];
1005 
1006 	bcopy(frm, &tstamp, sizeof(u_int64_t));
1007 	frm += 8;
1008 	if (vflag > 1)
1009 		printf(", timestamp %llu", letoh64(tstamp));
1010 
1011 	bcopy(frm, &bintval, sizeof(u_int16_t));
1012 	frm += 2;
1013 	if (vflag > 1)
1014 		printf(", interval %u", letoh16(bintval));
1015 
1016 	bcopy(frm, &capinfo, sizeof(u_int16_t));
1017 	frm += 2;
1018 	if (vflag)
1019 		printb(", caps", letoh16(capinfo), IEEE80211_CAPINFO_BITS);
1020 
1021 	return ieee80211_print_elements(frm);
1022 }
1023 
1024 int
ieee80211_print_assocreq(struct ieee80211_frame * wh,u_int len)1025 ieee80211_print_assocreq(struct ieee80211_frame *wh, u_int len)
1026 {
1027 	uint8_t subtype;
1028 	uint16_t capinfo, lintval;
1029 	uint8_t *frm;
1030 
1031 	subtype = wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK;
1032 
1033 	if (len < sizeof(capinfo) + sizeof(lintval) +
1034 	    (subtype == IEEE80211_FC0_SUBTYPE_REASSOC_REQ ?
1035 	    IEEE80211_ADDR_LEN : 0))
1036 		return 1; /* truncated */
1037 
1038 	frm = (u_int8_t *)&wh[1];
1039 
1040 	bcopy(frm, &capinfo, sizeof(u_int16_t));
1041 	frm += 2;
1042 	if (vflag)
1043 		printb(", caps", letoh16(capinfo), IEEE80211_CAPINFO_BITS);
1044 
1045 	bcopy(frm, &lintval, sizeof(u_int16_t));
1046 	frm += 2;
1047 	if (vflag > 1)
1048 		printf(", listen interval %u", letoh16(lintval));
1049 
1050 	if (subtype == IEEE80211_FC0_SUBTYPE_REASSOC_REQ) {
1051 		if (vflag)
1052 			printf(", AP %s", etheraddr_string(frm));
1053 		frm += IEEE80211_ADDR_LEN;
1054 	}
1055 
1056 	return ieee80211_print_elements(frm);
1057 }
1058 
1059 int
ieee80211_print_elements(uint8_t * frm)1060 ieee80211_print_elements(uint8_t *frm)
1061 {
1062 	int i;
1063 
1064 	while (TTEST2(*frm, 2)) {
1065 		u_int len = frm[1];
1066 		u_int8_t *data = frm + 2;
1067 
1068 		if (!TTEST2(*data, len))
1069 			break;
1070 
1071 #define ELEM_CHECK(l)	if (len != l) goto trunc
1072 
1073 		switch (*frm) {
1074 		case IEEE80211_ELEMID_SSID:
1075 			printf(", ssid");
1076 			ieee80211_print_essid(data, len);
1077 			break;
1078 		case IEEE80211_ELEMID_RATES:
1079 			printf(", rates");
1080 			if (!vflag)
1081 				break;
1082 			for (i = len; i > 0; i--, data++)
1083 				printf(" %uM%s",
1084 				    (data[0] & IEEE80211_RATE_VAL) / 2,
1085 				    (data[0] & IEEE80211_RATE_BASIC
1086 				    ? "*" : ""));
1087 			break;
1088 		case IEEE80211_ELEMID_FHPARMS:
1089 			ELEM_CHECK(5);
1090 			printf(", fh (dwell %u, chan %u, index %u)",
1091 			    (data[1] << 8) | data[0],
1092 			    (data[2] - 1) * 80 + data[3],	/* FH_CHAN */
1093 			    data[4]);
1094 			break;
1095 		case IEEE80211_ELEMID_DSPARMS:
1096 			ELEM_CHECK(1);
1097 			printf(", ds");
1098 			if (vflag)
1099 				printf(" (chan %u)", data[0]);
1100 			break;
1101 		case IEEE80211_ELEMID_CFPARMS:
1102 			printf(", cf");
1103 			if (vflag)
1104 				ieee80211_print_element(data, len);
1105 			break;
1106 		case IEEE80211_ELEMID_TIM:
1107 			printf(", tim");
1108 			if (vflag)
1109 				ieee80211_print_element(data, len);
1110 			break;
1111 		case IEEE80211_ELEMID_IBSSPARMS:
1112 			printf(", ibss");
1113 			if (vflag)
1114 				ieee80211_print_element(data, len);
1115 			break;
1116 		case IEEE80211_ELEMID_COUNTRY:
1117 			printf(", country");
1118 			if (vflag)
1119 				ieee80211_print_country(data, len);
1120 			break;
1121 		case IEEE80211_ELEMID_CHALLENGE:
1122 			printf(", challenge");
1123 			if (vflag)
1124 				ieee80211_print_element(data, len);
1125 			break;
1126 		case IEEE80211_ELEMID_CSA:
1127 			ELEM_CHECK(3);
1128 			printf(", csa (chan %u count %u%s)", data[1], data[2],
1129 			    (data[0] == 1) ? " noTX" : "");
1130 			break;
1131 		case IEEE80211_ELEMID_ERP:
1132 			printf(", erp");
1133 			if (vflag)
1134 				ieee80211_print_element(data, len);
1135 			break;
1136 		case IEEE80211_ELEMID_RSN:
1137 			printf(", rsn");
1138 			if (vflag)
1139 				ieee80211_print_rsn(data, len);
1140 			break;
1141 		case IEEE80211_ELEMID_XRATES:
1142 			printf(", xrates");
1143 			if (!vflag)
1144 				break;
1145 			for (i = len; i > 0; i--, data++)
1146 				printf(" %uM",
1147 				    (data[0] & IEEE80211_RATE_VAL) / 2);
1148 			break;
1149 		case IEEE80211_ELEMID_TPC_REPORT:
1150 			printf(", tpcreport");
1151 			if (vflag)
1152 				ieee80211_print_element(data, len);
1153 			break;
1154 		case IEEE80211_ELEMID_TPC_REQUEST:
1155 			printf(", tpcrequest");
1156 			if (vflag)
1157 				ieee80211_print_element(data, len);
1158 			break;
1159 		case IEEE80211_ELEMID_HTCAPS:
1160 			printf(", htcaps");
1161 			if (vflag)
1162 				ieee80211_print_htcaps(data, len);
1163 			break;
1164 		case IEEE80211_ELEMID_HTOP:
1165 			printf(", htop");
1166 			if (vflag)
1167 				ieee80211_print_htop(data, len);
1168 			break;
1169 		case IEEE80211_ELEMID_VHTCAPS:
1170 			printf(", vhtcaps");
1171 			if (vflag)
1172 				ieee80211_print_vhtcaps(data, len);
1173 			break;
1174 		case IEEE80211_ELEMID_VHTOP:
1175 			printf(", vhtop");
1176 			if (vflag)
1177 				ieee80211_print_vhtop(data, len);
1178 			break;
1179 		case IEEE80211_ELEMID_POWER_CONSTRAINT:
1180 			ELEM_CHECK(1);
1181 			printf(", power constraint %udB", data[0]);
1182 			break;
1183 		case IEEE80211_ELEMID_QBSS_LOAD:
1184 			ELEM_CHECK(5);
1185 			printf(", %u stations, %d%% utilization, "
1186 			    "admission capacity %uus/s",
1187 			    (data[0] | data[1] << 8),
1188 			    (data[2] * 100) / 255,
1189 			    (data[3] | data[4] << 8) / 32);
1190 			break;
1191 		case IEEE80211_ELEMID_VENDOR:
1192 			printf(", vendor");
1193 			if (vflag)
1194 				ieee80211_print_element(data, len);
1195 			break;
1196 		default:
1197 			printf(", %u:%u", (u_int) *frm, len);
1198 			if (vflag)
1199 				ieee80211_print_element(data, len);
1200 			break;
1201 		}
1202 		frm += len + 2;
1203 
1204 		if (frm >= snapend)
1205 			break;
1206 	}
1207 
1208 #undef ELEM_CHECK
1209 
1210 	return (0);
1211 
1212  trunc:
1213 	/* Truncated elements in frame */
1214 	return (1);
1215 }
1216 
1217 int
ieee80211_frame(struct ieee80211_frame * wh,u_int len)1218 ieee80211_frame(struct ieee80211_frame *wh, u_int len)
1219 {
1220 	u_int8_t subtype, type, *frm;
1221 
1222 	TCARR(wh->i_fc);
1223 
1224 	type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK;
1225 	subtype = wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK;
1226 
1227 	frm = (u_int8_t *)&wh[1];
1228 
1229 	if (vflag)
1230 		printb(" flags", wh->i_fc[1], IEEE80211_FC1_BITS);
1231 
1232 	switch (type) {
1233 	case IEEE80211_FC0_TYPE_DATA:
1234 		printf(": %s: ", ieee80211_data_subtype_name[
1235 		    subtype >> IEEE80211_FC0_SUBTYPE_SHIFT]);
1236 		ieee80211_data(wh, len);
1237 		break;
1238 	case IEEE80211_FC0_TYPE_MGT:
1239 		printf(": %s", ieee80211_mgt_subtype_name[
1240 		    subtype >> IEEE80211_FC0_SUBTYPE_SHIFT]);
1241 		switch (subtype) {
1242 		case IEEE80211_FC0_SUBTYPE_BEACON:
1243 		case IEEE80211_FC0_SUBTYPE_PROBE_RESP:
1244 			if (ieee80211_print_beacon(wh, len) != 0)
1245 				goto trunc;
1246 			break;
1247 		case IEEE80211_FC0_SUBTYPE_ASSOC_REQ:
1248 		case IEEE80211_FC0_SUBTYPE_REASSOC_REQ:
1249 			if (ieee80211_print_assocreq(wh, len) != 0)
1250 				goto trunc;
1251 			break;
1252 		case IEEE80211_FC0_SUBTYPE_AUTH:
1253 			TCHECK2(*frm, 2);		/* Auth Algorithm */
1254 			switch (IEEE80211_AUTH_ALGORITHM(frm)) {
1255 			case IEEE80211_AUTH_ALG_OPEN:
1256 				TCHECK2(*frm, 4);	/* Auth Transaction */
1257 				switch (IEEE80211_AUTH_TRANSACTION(frm)) {
1258 				case IEEE80211_AUTH_OPEN_REQUEST:
1259 					printf(" request");
1260 					break;
1261 				case IEEE80211_AUTH_OPEN_RESPONSE:
1262 					printf(" response");
1263 					break;
1264 				}
1265 				break;
1266 			case IEEE80211_AUTH_ALG_SHARED:
1267 				TCHECK2(*frm, 4);	/* Auth Transaction */
1268 				switch (IEEE80211_AUTH_TRANSACTION(frm)) {
1269 				case IEEE80211_AUTH_SHARED_REQUEST:
1270 					printf(" request");
1271 					break;
1272 				case IEEE80211_AUTH_SHARED_CHALLENGE:
1273 					printf(" challenge");
1274 					break;
1275 				case IEEE80211_AUTH_SHARED_RESPONSE:
1276 					printf(" response");
1277 					break;
1278 				case IEEE80211_AUTH_SHARED_PASS:
1279 					printf(" pass");
1280 					break;
1281 				}
1282 				break;
1283 			case IEEE80211_AUTH_ALG_LEAP:
1284 				printf(" (leap)");
1285 				break;
1286 			}
1287 			break;
1288 		case IEEE80211_FC0_SUBTYPE_DEAUTH:
1289 		case IEEE80211_FC0_SUBTYPE_DISASSOC:
1290 			TCHECK2(*frm, 2);		/* Reason Code */
1291 			ieee80211_reason(frm[0] | (frm[1] << 8));
1292 			break;
1293 		}
1294 		break;
1295 	case IEEE80211_FC0_TYPE_CTL: {
1296 		u_int8_t *t = (u_int8_t *) wh;
1297 
1298 		printf(": %s", ieee80211_ctl_subtype_name[
1299 		    subtype >> IEEE80211_FC0_SUBTYPE_SHIFT]);
1300 		if (!vflag)
1301 			break;
1302 
1303 		/* See 802.11 2012 "8.3.1 Control frames". */
1304 		t += 2; /* skip Frame Control */
1305 		switch (subtype) {
1306 		case IEEE80211_FC0_SUBTYPE_RTS:
1307 		case IEEE80211_FC0_SUBTYPE_BAR:
1308 		case IEEE80211_FC0_SUBTYPE_BA:
1309 			TCHECK2(*t, 2); /* Duration */
1310 			printf(", duration %dus", (t[0] | t[1] << 8));
1311 			t += 2;
1312 			TCHECK2(*t, 6); /* RA */
1313 			printf(", ra %s", etheraddr_string(t));
1314 			t += 6;
1315 			TCHECK2(*t, 6); /* TA */
1316 			printf(", ta %s", etheraddr_string(t));
1317 			if (subtype == IEEE80211_FC0_SUBTYPE_BAR ||
1318 			    subtype == IEEE80211_FC0_SUBTYPE_BA) {
1319 				u_int16_t ctrl;
1320 
1321 				t += 6;
1322 				TCHECK2(*t, 2); /* BAR/BA control */
1323 				ctrl = t[0] | (t[1] << 8);
1324 				if (ctrl & IEEE80211_BA_ACK_POLICY)
1325 					printf(", no ack");
1326 				else
1327 					printf(", normal ack");
1328 				if ((ctrl & IEEE80211_BA_MULTI_TID) == 0 &&
1329 				    (ctrl & IEEE80211_BA_COMPRESSED) == 0)
1330 					printf(", basic variant");
1331 				else if ((ctrl & IEEE80211_BA_MULTI_TID) &&
1332 				    (ctrl & IEEE80211_BA_COMPRESSED))
1333 					printf(", multi-tid variant");
1334 				else if (ctrl & IEEE80211_BA_COMPRESSED)
1335 					printf(", compressed variant");
1336 			}
1337 			break;
1338 		case IEEE80211_FC0_SUBTYPE_CTS:
1339 		case IEEE80211_FC0_SUBTYPE_ACK:
1340 			TCHECK2(*t, 2); /* Duration */
1341 			printf(", duration %dus", (t[0] | t[1] << 8));
1342 			t += 2;
1343 			TCHECK2(*t, 6); /* RA */
1344 			printf(", ra %s", etheraddr_string(t));
1345 			break;
1346 		case IEEE80211_FC0_SUBTYPE_PS_POLL:
1347 			TCHECK2(*t, 2); /* AID */
1348 			printf(", aid 0x%x", (t[0] | t[1] << 8));
1349 			t += 2;
1350 			TCHECK2(*t, 6); /* BSSID(RA) */
1351 			printf(", ra %s", etheraddr_string(t));
1352 			t += 6;
1353 			TCHECK2(*t, 6); /* TA */
1354 			printf(", ta %s", etheraddr_string(t));
1355 			break;
1356 		}
1357 		break;
1358 	}
1359 	default:
1360 		printf(": type#%d", type);
1361 		break;
1362 	}
1363 
1364 	return (0);
1365 
1366  trunc:
1367 	/* Truncated 802.11 frame */
1368 	return (1);
1369 }
1370 
1371 u_int
ieee80211_any2ieee(u_int freq,u_int flags)1372 ieee80211_any2ieee(u_int freq, u_int flags)
1373 {
1374 	if (flags & IEEE80211_CHAN_2GHZ) {
1375 		if (freq == 2484)
1376 			return 14;
1377 		if (freq < 2484)
1378 			return (freq - 2407) / 5;
1379 		else
1380 			return 15 + ((freq - 2512) / 20);
1381 	} else if (flags & IEEE80211_CHAN_5GHZ) {
1382 		return (freq - 5000) / 5;
1383 	} else {
1384 		/* Assume channel is already an IEEE number */
1385 		return (freq);
1386 	}
1387 }
1388 
1389 int
ieee80211_print(struct ieee80211_frame * wh,u_int len)1390 ieee80211_print(struct ieee80211_frame *wh, u_int len)
1391 {
1392 	if (eflag)
1393 		if (ieee80211_hdr(wh))
1394 			return (1);
1395 
1396 	printf("802.11");
1397 
1398 	return (ieee80211_frame(wh, len));
1399 }
1400 
1401 void
ieee802_11_if_print(u_char * user,const struct pcap_pkthdr * h,const u_char * p)1402 ieee802_11_if_print(u_char *user, const struct pcap_pkthdr *h,
1403     const u_char *p)
1404 {
1405 	struct ieee80211_frame *wh = (struct ieee80211_frame*)p;
1406 
1407 	if (!ieee80211_encap)
1408 		ts_print(&h->ts);
1409 
1410 	packetp = p;
1411 	snapend = p + h->caplen;
1412 
1413 	if (ieee80211_print(wh, (u_int)h->len) != 0)
1414 		printf("[|802.11]");
1415 
1416 	if (!ieee80211_encap) {
1417 		if (xflag)
1418 			default_print(p, (u_int)h->len);
1419 		putchar('\n');
1420 	}
1421 }
1422 
1423 void
ieee802_11_radio_if_print(u_char * user,const struct pcap_pkthdr * h,const u_char * p)1424 ieee802_11_radio_if_print(u_char *user, const struct pcap_pkthdr *h,
1425     const u_char *p)
1426 {
1427 	struct ieee80211_radiotap_header *rh =
1428 	    (struct ieee80211_radiotap_header*)p;
1429 	struct ieee80211_frame *wh;
1430 	u_int8_t *t;
1431 	u_int32_t present;
1432 	u_int len, rh_len;
1433 	u_int16_t tmp;
1434 
1435 	if (!ieee80211_encap)
1436 		ts_print(&h->ts);
1437 
1438 	packetp = p;
1439 	snapend = p + h->caplen;
1440 
1441 	TCHECK(*rh);
1442 
1443 	len = h->len;
1444 	rh_len = letoh16(rh->it_len);
1445 	if (rh->it_version != 0) {
1446 		printf("[?radiotap + 802.11 v:%u]", rh->it_version);
1447 		goto out;
1448 	}
1449 
1450 	wh = (struct ieee80211_frame *)(p + rh_len);
1451 	if (len <= rh_len || ieee80211_print(wh, len - rh_len))
1452 		printf("[|802.11]");
1453 
1454 	t = (u_int8_t*)p + sizeof(struct ieee80211_radiotap_header);
1455 
1456 	if ((present = letoh32(rh->it_present)) == 0)
1457 		goto out;
1458 
1459 	printf(", <radiotap v%u", rh->it_version);
1460 
1461 #define RADIOTAP(_x)	\
1462 	(present & (1 << IEEE80211_RADIOTAP_##_x))
1463 
1464 	if (RADIOTAP(TSFT)) {
1465 		u_int64_t tsf;
1466 
1467 		TCHECK2(*t, 8);
1468 		bcopy(t, &tsf, sizeof(u_int64_t));
1469 		if (vflag > 1)
1470 			printf(", tsf %llu", letoh64(tsf));
1471 		t += 8;
1472 	}
1473 
1474 	if (RADIOTAP(FLAGS)) {
1475 		u_int8_t flags = *(u_int8_t*)t;
1476 		TCHECK2(*t, 1);
1477 
1478 		if (flags & IEEE80211_RADIOTAP_F_CFP)
1479 			printf(", CFP");
1480 		if (flags & IEEE80211_RADIOTAP_F_SHORTPRE)
1481 			printf(", SHORTPRE");
1482 		if (flags & IEEE80211_RADIOTAP_F_WEP)
1483 			printf(", WEP");
1484 		if (flags & IEEE80211_RADIOTAP_F_FRAG)
1485 			printf(", FRAG");
1486 		t += 1;
1487 	}
1488 
1489 	if (RADIOTAP(RATE)) {
1490 		TCHECK2(*t, 1);
1491 		if (vflag) {
1492 			uint8_t rate = *(u_int8_t*)t;
1493 			if (rate & 0x80)
1494 				printf(", MCS %u", rate & 0x7f);
1495 			else
1496 				printf(", %uMbit/s", rate / 2);
1497 		}
1498 		t += 1;
1499 	}
1500 
1501 	if (RADIOTAP(CHANNEL)) {
1502 		u_int16_t freq, flags;
1503 		TCHECK2(*t, 2);
1504 
1505 		bcopy(t, &freq, sizeof(u_int16_t));
1506 		freq = letoh16(freq);
1507 		t += 2;
1508 		TCHECK2(*t, 2);
1509 		bcopy(t, &flags, sizeof(u_int16_t));
1510 		flags = letoh16(flags);
1511 		t += 2;
1512 
1513 		printf(", chan %u", ieee80211_any2ieee(freq, flags));
1514 
1515 		if (flags & IEEE80211_CHAN_HT)
1516 			printf(", 11n");
1517 		else if (flags & IEEE80211_CHAN_DYN &&
1518 		    flags & IEEE80211_CHAN_2GHZ)
1519 			printf(", 11g");
1520 		else if (flags & IEEE80211_CHAN_CCK &&
1521 		    flags & IEEE80211_CHAN_2GHZ)
1522 			printf(", 11b");
1523 		else if (flags & IEEE80211_CHAN_OFDM &&
1524 		    flags & IEEE80211_CHAN_2GHZ)
1525 			printf(", 11G");
1526 		else if (flags & IEEE80211_CHAN_OFDM &&
1527 		    flags & IEEE80211_CHAN_5GHZ)
1528 			printf(", 11a");
1529 
1530 		if (flags & IEEE80211_CHAN_XR)
1531 			printf(", XR");
1532 	}
1533 
1534 	if (RADIOTAP(FHSS)) {
1535 		TCHECK2(*t, 2);
1536 		printf(", fhss %u/%u", *(u_int8_t*)t, *(u_int8_t*)t + 1);
1537 		t += 2;
1538 	}
1539 
1540 	if (RADIOTAP(DBM_ANTSIGNAL)) {
1541 		TCHECK(*t);
1542 		printf(", sig %ddBm", *(int8_t*)t);
1543 		t += 1;
1544 	}
1545 
1546 	if (RADIOTAP(DBM_ANTNOISE)) {
1547 		TCHECK(*t);
1548 		printf(", noise %ddBm", *(int8_t*)t);
1549 		t += 1;
1550 	}
1551 
1552 	if (RADIOTAP(LOCK_QUALITY)) {
1553 		TCHECK2(*t, 2);
1554 		if (vflag) {
1555 			bcopy(t, &tmp, sizeof(u_int16_t));
1556 			printf(", quality %u", letoh16(tmp));
1557 		}
1558 		t += 2;
1559 	}
1560 
1561 	if (RADIOTAP(TX_ATTENUATION)) {
1562 		TCHECK2(*t, 2);
1563 		if (vflag) {
1564 			bcopy(t, &tmp, sizeof(u_int16_t));
1565 			printf(", txatt %u", letoh16(tmp));
1566 		}
1567 		t += 2;
1568 	}
1569 
1570 	if (RADIOTAP(DB_TX_ATTENUATION)) {
1571 		TCHECK2(*t, 2);
1572 		if (vflag) {
1573 			bcopy(t, &tmp, sizeof(u_int16_t));
1574 			printf(", txatt %udB", letoh16(tmp));
1575 		}
1576 		t += 2;
1577 	}
1578 
1579 	if (RADIOTAP(DBM_TX_POWER)) {
1580 		TCHECK(*t);
1581 		printf(", txpower %ddBm", *(int8_t*)t);
1582 		t += 1;
1583 	}
1584 
1585 	if (RADIOTAP(ANTENNA)) {
1586 		TCHECK(*t);
1587 		if (vflag)
1588 			printf(", antenna %u", *(u_int8_t*)t);
1589 		t += 1;
1590 	}
1591 
1592 	if (RADIOTAP(DB_ANTSIGNAL)) {
1593 		TCHECK(*t);
1594 		printf(", signal %udB", *(u_int8_t*)t);
1595 		t += 1;
1596 	}
1597 
1598 	if (RADIOTAP(DB_ANTNOISE)) {
1599 		TCHECK(*t);
1600 		printf(", noise %udB", *(u_int8_t*)t);
1601 		t += 1;
1602 	}
1603 
1604 	if (RADIOTAP(FCS)) {
1605 		TCHECK2(*t, 4);
1606 		if (vflag) {
1607 			u_int32_t fcs;
1608 			bcopy(t, &fcs, sizeof(u_int32_t));
1609 			printf(", fcs %08x", letoh32(fcs));
1610 		}
1611 		t += 4;
1612 	}
1613 
1614 	if (RADIOTAP(RSSI)) {
1615 		u_int8_t rssi, max_rssi;
1616 		TCHECK(*t);
1617 		rssi = *(u_int8_t*)t;
1618 		t += 1;
1619 		TCHECK(*t);
1620 		max_rssi = *(u_int8_t*)t;
1621 		t += 1;
1622 
1623 		printf(", rssi %u/%u", rssi, max_rssi);
1624 	}
1625 
1626 #undef RADIOTAP
1627 
1628 	putchar('>');
1629 	goto out;
1630 
1631  trunc:
1632 	/* Truncated frame */
1633 	printf("[|radiotap + 802.11]");
1634 
1635  out:
1636 	if (!ieee80211_encap) {
1637 		if (xflag)
1638 			default_print(p, h->len);
1639 		putchar('\n');
1640 	}
1641 }
1642 
1643 void
ieee80211_reason(u_int16_t reason)1644 ieee80211_reason(u_int16_t reason)
1645 {
1646 	if (!vflag)
1647 		return;
1648 
1649 	switch (reason) {
1650 	case IEEE80211_REASON_UNSPECIFIED:
1651 		printf(", unspecified failure");
1652 		break;
1653 	case IEEE80211_REASON_AUTH_EXPIRE:
1654 		printf(", authentication expired");
1655 		break;
1656 	case IEEE80211_REASON_AUTH_LEAVE:
1657 		printf(", deauth - station left");
1658 		break;
1659 	case IEEE80211_REASON_ASSOC_EXPIRE:
1660 		printf(", association expired");
1661 		break;
1662 	case IEEE80211_REASON_ASSOC_TOOMANY:
1663 		printf(", too many associated stations");
1664 		break;
1665 	case IEEE80211_REASON_NOT_AUTHED:
1666 		printf(", not authenticated");
1667 		break;
1668 	case IEEE80211_REASON_NOT_ASSOCED:
1669 		printf(", not associated");
1670 		break;
1671 	case IEEE80211_REASON_ASSOC_LEAVE:
1672 		printf(", disassociated - station left");
1673 		break;
1674 	case IEEE80211_REASON_ASSOC_NOT_AUTHED:
1675 		printf(", association but not authenticated");
1676 		break;
1677 	case IEEE80211_REASON_RSN_REQUIRED:
1678 		printf(", rsn required");
1679 		break;
1680 	case IEEE80211_REASON_RSN_INCONSISTENT:
1681 		printf(", rsn inconsistent");
1682 		break;
1683 	case IEEE80211_REASON_IE_INVALID:
1684 		printf(", ie invalid");
1685 		break;
1686 	case IEEE80211_REASON_MIC_FAILURE:
1687 		printf(", mic failure");
1688 		break;
1689 	default:
1690 		printf(", unknown reason %u", reason);
1691 	}
1692 }
1693