xref: /freebsd/contrib/tcpdump/print-802_11.c (revision 0a7e5f1f02aad2ff5fff1c60f44c6975fd07e1d9)
1 /*
2  * Copyright (c) 2001
3  *	Fortress Technologies, Inc.  All rights reserved.
4  *      Charlie Lenahan (clenahan@fortresstech.com)
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that: (1) source code distributions
8  * retain the above copyright notice and this paragraph in its entirety, (2)
9  * distributions including binary code include the above copyright notice and
10  * this paragraph in its entirety in the documentation or other materials
11  * provided with the distribution, and (3) all advertising materials mentioning
12  * features or use of this software display the following acknowledgement:
13  * ``This product includes software developed by the University of California,
14  * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
15  * the University nor the names of its contributors may be used to endorse
16  * or promote products derived from this software without specific prior
17  * written permission.
18  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
19  * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
20  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
21  */
22 
23 /* \summary: IEEE 802.11 printer */
24 
25 #include <config.h>
26 
27 #include "netdissect-stdinc.h"
28 
29 #include <string.h>
30 
31 #include "netdissect.h"
32 #include "addrtoname.h"
33 
34 #include "extract.h"
35 
36 #include "cpack.h"
37 
38 
39 /* Lengths of 802.11 header components. */
40 #define	IEEE802_11_FC_LEN		2
41 #define	IEEE802_11_DUR_LEN		2
42 #define	IEEE802_11_DA_LEN		6
43 #define	IEEE802_11_SA_LEN		6
44 #define	IEEE802_11_BSSID_LEN		6
45 #define	IEEE802_11_RA_LEN		6
46 #define	IEEE802_11_TA_LEN		6
47 #define	IEEE802_11_ADDR1_LEN		6
48 #define	IEEE802_11_SEQ_LEN		2
49 #define	IEEE802_11_CTL_LEN		2
50 #define	IEEE802_11_CARRIED_FC_LEN	2
51 #define	IEEE802_11_HT_CONTROL_LEN	4
52 #define	IEEE802_11_IV_LEN		3
53 #define	IEEE802_11_KID_LEN		1
54 
55 /* Frame check sequence length. */
56 #define	IEEE802_11_FCS_LEN		4
57 
58 /* Lengths of beacon components. */
59 #define	IEEE802_11_TSTAMP_LEN		8
60 #define	IEEE802_11_BCNINT_LEN		2
61 #define	IEEE802_11_CAPINFO_LEN		2
62 #define	IEEE802_11_LISTENINT_LEN	2
63 
64 #define	IEEE802_11_AID_LEN		2
65 #define	IEEE802_11_STATUS_LEN		2
66 #define	IEEE802_11_REASON_LEN		2
67 
68 /* Length of previous AP in reassociation frame */
69 #define	IEEE802_11_AP_LEN		6
70 
71 #define	T_MGMT 0x0  /* management */
72 #define	T_CTRL 0x1  /* control */
73 #define	T_DATA 0x2 /* data */
74 #define	T_RESV 0x3  /* reserved */
75 
76 #define	ST_ASSOC_REQUEST	0x0
77 #define	ST_ASSOC_RESPONSE	0x1
78 #define	ST_REASSOC_REQUEST	0x2
79 #define	ST_REASSOC_RESPONSE	0x3
80 #define	ST_PROBE_REQUEST	0x4
81 #define	ST_PROBE_RESPONSE	0x5
82 /* RESERVED			0x6  */
83 /* RESERVED			0x7  */
84 #define	ST_BEACON		0x8
85 #define	ST_ATIM			0x9
86 #define	ST_DISASSOC		0xA
87 #define	ST_AUTH			0xB
88 #define	ST_DEAUTH		0xC
89 #define	ST_ACTION		0xD
90 /* RESERVED			0xE  */
91 /* RESERVED			0xF  */
92 
93 static const struct tok st_str[] = {
94 	{ ST_ASSOC_REQUEST,    "Assoc Request"    },
95 	{ ST_ASSOC_RESPONSE,   "Assoc Response"   },
96 	{ ST_REASSOC_REQUEST,  "ReAssoc Request"  },
97 	{ ST_REASSOC_RESPONSE, "ReAssoc Response" },
98 	{ ST_PROBE_REQUEST,    "Probe Request"    },
99 	{ ST_PROBE_RESPONSE,   "Probe Response"   },
100 	{ ST_BEACON,           "Beacon"           },
101 	{ ST_ATIM,             "ATIM"             },
102 	{ ST_DISASSOC,         "Disassociation"   },
103 	{ ST_AUTH,             "Authentication"   },
104 	{ ST_DEAUTH,           "DeAuthentication" },
105 	{ ST_ACTION,           "Action"           },
106 	{ 0, NULL }
107 };
108 
109 #define CTRL_CONTROL_WRAPPER	0x7
110 #define	CTRL_BAR	0x8
111 #define	CTRL_BA		0x9
112 #define	CTRL_PS_POLL	0xA
113 #define	CTRL_RTS	0xB
114 #define	CTRL_CTS	0xC
115 #define	CTRL_ACK	0xD
116 #define	CTRL_CF_END	0xE
117 #define	CTRL_END_ACK	0xF
118 
119 static const struct tok ctrl_str[] = {
120 	{ CTRL_CONTROL_WRAPPER, "Control Wrapper" },
121 	{ CTRL_BAR,             "BAR"             },
122 	{ CTRL_BA,              "BA"              },
123 	{ CTRL_PS_POLL,         "Power Save-Poll" },
124 	{ CTRL_RTS,             "Request-To-Send" },
125 	{ CTRL_CTS,             "Clear-To-Send"   },
126 	{ CTRL_ACK,             "Acknowledgment"  },
127 	{ CTRL_CF_END,          "CF-End"          },
128 	{ CTRL_END_ACK,         "CF-End+CF-Ack"   },
129 	{ 0, NULL }
130 };
131 
132 #define	DATA_DATA			0x0
133 #define	DATA_DATA_CF_ACK		0x1
134 #define	DATA_DATA_CF_POLL		0x2
135 #define	DATA_DATA_CF_ACK_POLL		0x3
136 #define	DATA_NODATA			0x4
137 #define	DATA_NODATA_CF_ACK		0x5
138 #define	DATA_NODATA_CF_POLL		0x6
139 #define	DATA_NODATA_CF_ACK_POLL		0x7
140 
141 #define DATA_QOS_DATA			0x8
142 #define DATA_QOS_DATA_CF_ACK		0x9
143 #define DATA_QOS_DATA_CF_POLL		0xA
144 #define DATA_QOS_DATA_CF_ACK_POLL	0xB
145 #define DATA_QOS_NODATA			0xC
146 #define DATA_QOS_CF_POLL_NODATA		0xE
147 #define DATA_QOS_CF_ACK_POLL_NODATA	0xF
148 
149 /*
150  * The subtype field of a data frame is, in effect, composed of 4 flag
151  * bits - CF-Ack, CF-Poll, Null (means the frame doesn't actually have
152  * any data), and QoS.
153  */
154 #define DATA_FRAME_IS_CF_ACK(x)		((x) & 0x01)
155 #define DATA_FRAME_IS_CF_POLL(x)	((x) & 0x02)
156 #define DATA_FRAME_IS_NULL(x)		((x) & 0x04)
157 #define DATA_FRAME_IS_QOS(x)		((x) & 0x08)
158 
159 /*
160  * Bits in the frame control field.
161  */
162 #define	FC_VERSION(fc)		((fc) & 0x3)
163 #define	FC_TYPE(fc)		(((fc) >> 2) & 0x3)
164 #define	FC_SUBTYPE(fc)		(((fc) >> 4) & 0xF)
165 #define	FC_TO_DS(fc)		((fc) & 0x0100)
166 #define	FC_FROM_DS(fc)		((fc) & 0x0200)
167 #define	FC_MORE_FLAG(fc)	((fc) & 0x0400)
168 #define	FC_RETRY(fc)		((fc) & 0x0800)
169 #define	FC_POWER_MGMT(fc)	((fc) & 0x1000)
170 #define	FC_MORE_DATA(fc)	((fc) & 0x2000)
171 #define	FC_PROTECTED(fc)	((fc) & 0x4000)
172 #define	FC_ORDER(fc)		((fc) & 0x8000)
173 
174 struct mgmt_header_t {
175 	nd_uint16_t	fc;
176 	nd_uint16_t	duration;
177 	nd_mac_addr	da;
178 	nd_mac_addr	sa;
179 	nd_mac_addr	bssid;
180 	nd_uint16_t	seq_ctrl;
181 };
182 
183 #define	MGMT_HDRLEN	(IEEE802_11_FC_LEN+IEEE802_11_DUR_LEN+\
184 			 IEEE802_11_DA_LEN+IEEE802_11_SA_LEN+\
185 			 IEEE802_11_BSSID_LEN+IEEE802_11_SEQ_LEN)
186 
187 #define	CAPABILITY_ESS(cap)	((cap) & 0x0001)
188 #define	CAPABILITY_IBSS(cap)	((cap) & 0x0002)
189 #define	CAPABILITY_CFP(cap)	((cap) & 0x0004)
190 #define	CAPABILITY_CFP_REQ(cap)	((cap) & 0x0008)
191 #define	CAPABILITY_PRIVACY(cap)	((cap) & 0x0010)
192 
193 struct ssid_t {
194 	u_int		length;
195 	u_char		ssid[33];  /* 32 + 1 for null */
196 };
197 
198 struct rates_t {
199 	u_int		length;
200 	uint8_t		rate[16];
201 };
202 
203 struct challenge_t {
204 	u_int		length;
205 	uint8_t		text[254]; /* 1-253 + 1 for null */
206 };
207 
208 struct fh_t {
209 	u_int		length;
210 	uint16_t	dwell_time;
211 	uint8_t		hop_set;
212 	uint8_t	hop_pattern;
213 	uint8_t		hop_index;
214 };
215 
216 struct ds_t {
217 	u_int		length;
218 	uint8_t		channel;
219 };
220 
221 struct cf_t {
222 	u_int		length;
223 	uint8_t		count;
224 	uint8_t		period;
225 	uint16_t	max_duration;
226 	uint16_t	dur_remaining;
227 };
228 
229 struct tim_t {
230 	u_int		length;
231 	uint8_t		count;
232 	uint8_t		period;
233 	uint8_t		bitmap_control;
234 	uint8_t		bitmap[251];
235 };
236 
237 #define	E_SSID		0
238 #define	E_RATES	1
239 #define	E_FH		2
240 #define	E_DS		3
241 #define	E_CF		4
242 #define	E_TIM		5
243 #define	E_IBSS		6
244 /* reserved		7 */
245 /* reserved		8 */
246 /* reserved		9 */
247 /* reserved		10 */
248 /* reserved		11 */
249 /* reserved		12 */
250 /* reserved		13 */
251 /* reserved		14 */
252 /* reserved		15 */
253 /* reserved		16 */
254 
255 #define	E_CHALLENGE	16
256 /* reserved		17 */
257 /* reserved		18 */
258 /* reserved		19 */
259 /* reserved		16 */
260 /* reserved		16 */
261 
262 
263 struct mgmt_body_t {
264 	uint8_t		timestamp[IEEE802_11_TSTAMP_LEN];
265 	uint16_t	beacon_interval;
266 	uint16_t	listen_interval;
267 	uint16_t	status_code;
268 	uint16_t	aid;
269 	u_char		ap[IEEE802_11_AP_LEN];
270 	uint16_t	reason_code;
271 	uint16_t	auth_alg;
272 	uint16_t	auth_trans_seq_num;
273 	int		challenge_present;
274 	struct challenge_t  challenge;
275 	uint16_t	capability_info;
276 	int		ssid_present;
277 	struct ssid_t	ssid;
278 	int		rates_present;
279 	struct rates_t	rates;
280 	int		ds_present;
281 	struct ds_t	ds;
282 	int		cf_present;
283 	struct cf_t	cf;
284 	int		fh_present;
285 	struct fh_t	fh;
286 	int		tim_present;
287 	struct tim_t	tim;
288 };
289 
290 struct ctrl_control_wrapper_hdr_t {
291 	nd_uint16_t	fc;
292 	nd_uint16_t	duration;
293 	nd_mac_addr	addr1;
294 	nd_uint16_t	carried_fc[IEEE802_11_CARRIED_FC_LEN];
295 	nd_uint16_t	ht_control[IEEE802_11_HT_CONTROL_LEN];
296 };
297 
298 #define	CTRL_CONTROL_WRAPPER_HDRLEN	(IEEE802_11_FC_LEN+IEEE802_11_DUR_LEN+\
299 					 IEEE802_11_ADDR1_LEN+\
300 					 IEEE802_11_CARRIED_FC_LEN+\
301 					 IEEE802_11_HT_CONTROL_LEN)
302 
303 struct ctrl_rts_hdr_t {
304 	nd_uint16_t	fc;
305 	nd_uint16_t	duration;
306 	nd_mac_addr	ra;
307 	nd_mac_addr	ta;
308 };
309 
310 #define	CTRL_RTS_HDRLEN	(IEEE802_11_FC_LEN+IEEE802_11_DUR_LEN+\
311 			 IEEE802_11_RA_LEN+IEEE802_11_TA_LEN)
312 
313 struct ctrl_cts_hdr_t {
314 	nd_uint16_t	fc;
315 	nd_uint16_t	duration;
316 	nd_mac_addr	ra;
317 };
318 
319 #define	CTRL_CTS_HDRLEN	(IEEE802_11_FC_LEN+IEEE802_11_DUR_LEN+IEEE802_11_RA_LEN)
320 
321 struct ctrl_ack_hdr_t {
322 	nd_uint16_t	fc;
323 	nd_uint16_t	duration;
324 	nd_mac_addr	ra;
325 };
326 
327 #define	CTRL_ACK_HDRLEN	(IEEE802_11_FC_LEN+IEEE802_11_DUR_LEN+IEEE802_11_RA_LEN)
328 
329 struct ctrl_ps_poll_hdr_t {
330 	nd_uint16_t	fc;
331 	nd_uint16_t	aid;
332 	nd_mac_addr	bssid;
333 	nd_mac_addr	ta;
334 };
335 
336 #define	CTRL_PS_POLL_HDRLEN	(IEEE802_11_FC_LEN+IEEE802_11_AID_LEN+\
337 				 IEEE802_11_BSSID_LEN+IEEE802_11_TA_LEN)
338 
339 struct ctrl_end_hdr_t {
340 	nd_uint16_t	fc;
341 	nd_uint16_t	duration;
342 	nd_mac_addr	ra;
343 	nd_mac_addr	bssid;
344 };
345 
346 #define	CTRL_END_HDRLEN	(IEEE802_11_FC_LEN+IEEE802_11_DUR_LEN+\
347 			 IEEE802_11_RA_LEN+IEEE802_11_BSSID_LEN)
348 
349 struct ctrl_end_ack_hdr_t {
350 	nd_uint16_t	fc;
351 	nd_uint16_t	duration;
352 	nd_mac_addr	ra;
353 	nd_mac_addr	bssid;
354 };
355 
356 #define	CTRL_END_ACK_HDRLEN	(IEEE802_11_FC_LEN+IEEE802_11_DUR_LEN+\
357 				 IEEE802_11_RA_LEN+IEEE802_11_BSSID_LEN)
358 
359 struct ctrl_ba_hdr_t {
360 	nd_uint16_t	fc;
361 	nd_uint16_t	duration;
362 	nd_mac_addr	ra;
363 	nd_mac_addr	ta;
364 };
365 
366 #define	CTRL_BA_HDRLEN	(IEEE802_11_FC_LEN+IEEE802_11_DUR_LEN+\
367 			 IEEE802_11_RA_LEN+IEEE802_11_TA_LEN)
368 
369 struct ctrl_bar_hdr_t {
370 	nd_uint16_t	fc;
371 	nd_uint16_t	dur;
372 	nd_mac_addr	ra;
373 	nd_mac_addr	ta;
374 	nd_uint16_t	ctl;
375 	nd_uint16_t	seq;
376 };
377 
378 #define	CTRL_BAR_HDRLEN		(IEEE802_11_FC_LEN+IEEE802_11_DUR_LEN+\
379 				 IEEE802_11_RA_LEN+IEEE802_11_TA_LEN+\
380 				 IEEE802_11_CTL_LEN+IEEE802_11_SEQ_LEN)
381 
382 struct meshcntl_t {
383 	nd_uint8_t	flags;
384 	nd_uint8_t	ttl;
385 	nd_uint32_t	seq;
386 	nd_mac_addr	addr4;
387 	nd_mac_addr	addr5;
388 	nd_mac_addr	addr6;
389 };
390 
391 #define	IV_IV(iv)	((iv) & 0xFFFFFF)
392 #define	IV_PAD(iv)	(((iv) >> 24) & 0x3F)
393 #define	IV_KEYID(iv)	(((iv) >> 30) & 0x03)
394 
395 #define PRINT_SSID(p) \
396 	if (p.ssid_present) { \
397 		ND_PRINT(" ("); \
398 		fn_print_str(ndo, p.ssid.ssid); \
399 		ND_PRINT(")"); \
400 	}
401 
402 #define PRINT_RATE(_sep, _r, _suf) \
403 	ND_PRINT("%s%2.1f%s", _sep, (.5 * ((_r) & 0x7f)), _suf)
404 #define PRINT_RATES(p) \
405 	if (p.rates_present) { \
406 		const char *sep = " ["; \
407 		if (p.rates.length != 0) { \
408 			for (u_int z = 0; z < p.rates.length ; z++) { \
409 				PRINT_RATE(sep, p.rates.rate[z], \
410 					(p.rates.rate[z] & 0x80 ? "*" : "")); \
411 				sep = " "; \
412 			} \
413 			ND_PRINT(" Mbit]"); \
414 		} \
415 	}
416 
417 #define PRINT_DS_CHANNEL(p) \
418 	if (p.ds_present) \
419 		ND_PRINT(" CH: %u", p.ds.channel); \
420 	ND_PRINT("%s", \
421 	    CAPABILITY_PRIVACY(p.capability_info) ? ", PRIVACY" : "");
422 
423 #define MAX_MCS_INDEX	76
424 
425 /*
426  * Indices are:
427  *
428  *	the MCS index (0-76);
429  *
430  *	0 for 20 MHz, 1 for 40 MHz;
431  *
432  *	0 for a long guard interval, 1 for a short guard interval.
433  */
434 static const float ieee80211_float_htrates[MAX_MCS_INDEX+1][2][2] = {
435 	/* MCS  0  */
436 	{	/* 20 Mhz */ {    6.5f,		/* SGI */    7.2f, },
437 		/* 40 Mhz */ {   13.5f,		/* SGI */   15.0f, },
438 	},
439 
440 	/* MCS  1  */
441 	{	/* 20 Mhz */ {   13.0f,		/* SGI */   14.4f, },
442 		/* 40 Mhz */ {   27.0f,		/* SGI */   30.0f, },
443 	},
444 
445 	/* MCS  2  */
446 	{	/* 20 Mhz */ {   19.5f,		/* SGI */   21.7f, },
447 		/* 40 Mhz */ {   40.5f,		/* SGI */   45.0f, },
448 	},
449 
450 	/* MCS  3  */
451 	{	/* 20 Mhz */ {   26.0f,		/* SGI */   28.9f, },
452 		/* 40 Mhz */ {   54.0f,		/* SGI */   60.0f, },
453 	},
454 
455 	/* MCS  4  */
456 	{	/* 20 Mhz */ {   39.0f,		/* SGI */   43.3f, },
457 		/* 40 Mhz */ {   81.0f,		/* SGI */   90.0f, },
458 	},
459 
460 	/* MCS  5  */
461 	{	/* 20 Mhz */ {   52.0f,		/* SGI */   57.8f, },
462 		/* 40 Mhz */ {  108.0f,		/* SGI */  120.0f, },
463 	},
464 
465 	/* MCS  6  */
466 	{	/* 20 Mhz */ {   58.5f,		/* SGI */   65.0f, },
467 		/* 40 Mhz */ {  121.5f,		/* SGI */  135.0f, },
468 	},
469 
470 	/* MCS  7  */
471 	{	/* 20 Mhz */ {   65.0f,		/* SGI */   72.2f, },
472 		/* 40 Mhz */ {   135.0f,	/* SGI */  150.0f, },
473 	},
474 
475 	/* MCS  8  */
476 	{	/* 20 Mhz */ {   13.0f,		/* SGI */   14.4f, },
477 		/* 40 Mhz */ {   27.0f,		/* SGI */   30.0f, },
478 	},
479 
480 	/* MCS  9  */
481 	{	/* 20 Mhz */ {   26.0f,		/* SGI */   28.9f, },
482 		/* 40 Mhz */ {   54.0f,		/* SGI */   60.0f, },
483 	},
484 
485 	/* MCS 10  */
486 	{	/* 20 Mhz */ {   39.0f,		/* SGI */   43.3f, },
487 		/* 40 Mhz */ {   81.0f,		/* SGI */   90.0f, },
488 	},
489 
490 	/* MCS 11  */
491 	{	/* 20 Mhz */ {   52.0f,		/* SGI */   57.8f, },
492 		/* 40 Mhz */ {  108.0f,		/* SGI */  120.0f, },
493 	},
494 
495 	/* MCS 12  */
496 	{	/* 20 Mhz */ {   78.0f,		/* SGI */   86.7f, },
497 		/* 40 Mhz */ {  162.0f,		/* SGI */  180.0f, },
498 	},
499 
500 	/* MCS 13  */
501 	{	/* 20 Mhz */ {  104.0f,		/* SGI */  115.6f, },
502 		/* 40 Mhz */ {  216.0f,		/* SGI */  240.0f, },
503 	},
504 
505 	/* MCS 14  */
506 	{	/* 20 Mhz */ {  117.0f,		/* SGI */  130.0f, },
507 		/* 40 Mhz */ {  243.0f,		/* SGI */  270.0f, },
508 	},
509 
510 	/* MCS 15  */
511 	{	/* 20 Mhz */ {  130.0f,		/* SGI */  144.4f, },
512 		/* 40 Mhz */ {  270.0f,		/* SGI */  300.0f, },
513 	},
514 
515 	/* MCS 16  */
516 	{	/* 20 Mhz */ {   19.5f,		/* SGI */   21.7f, },
517 		/* 40 Mhz */ {   40.5f,		/* SGI */   45.0f, },
518 	},
519 
520 	/* MCS 17  */
521 	{	/* 20 Mhz */ {   39.0f,		/* SGI */   43.3f, },
522 		/* 40 Mhz */ {   81.0f,		/* SGI */   90.0f, },
523 	},
524 
525 	/* MCS 18  */
526 	{	/* 20 Mhz */ {   58.5f,		/* SGI */   65.0f, },
527 		/* 40 Mhz */ {  121.5f,		/* SGI */  135.0f, },
528 	},
529 
530 	/* MCS 19  */
531 	{	/* 20 Mhz */ {   78.0f,		/* SGI */   86.7f, },
532 		/* 40 Mhz */ {  162.0f,		/* SGI */  180.0f, },
533 	},
534 
535 	/* MCS 20  */
536 	{	/* 20 Mhz */ {  117.0f,		/* SGI */  130.0f, },
537 		/* 40 Mhz */ {  243.0f,		/* SGI */  270.0f, },
538 	},
539 
540 	/* MCS 21  */
541 	{	/* 20 Mhz */ {  156.0f,		/* SGI */  173.3f, },
542 		/* 40 Mhz */ {  324.0f,		/* SGI */  360.0f, },
543 	},
544 
545 	/* MCS 22  */
546 	{	/* 20 Mhz */ {  175.5f,		/* SGI */  195.0f, },
547 		/* 40 Mhz */ {  364.5f,		/* SGI */  405.0f, },
548 	},
549 
550 	/* MCS 23  */
551 	{	/* 20 Mhz */ {  195.0f,		/* SGI */  216.7f, },
552 		/* 40 Mhz */ {  405.0f,		/* SGI */  450.0f, },
553 	},
554 
555 	/* MCS 24  */
556 	{	/* 20 Mhz */ {   26.0f,		/* SGI */   28.9f, },
557 		/* 40 Mhz */ {   54.0f,		/* SGI */   60.0f, },
558 	},
559 
560 	/* MCS 25  */
561 	{	/* 20 Mhz */ {   52.0f,		/* SGI */   57.8f, },
562 		/* 40 Mhz */ {  108.0f,		/* SGI */  120.0f, },
563 	},
564 
565 	/* MCS 26  */
566 	{	/* 20 Mhz */ {   78.0f,		/* SGI */   86.7f, },
567 		/* 40 Mhz */ {  162.0f,		/* SGI */  180.0f, },
568 	},
569 
570 	/* MCS 27  */
571 	{	/* 20 Mhz */ {  104.0f,		/* SGI */  115.6f, },
572 		/* 40 Mhz */ {  216.0f,		/* SGI */  240.0f, },
573 	},
574 
575 	/* MCS 28  */
576 	{	/* 20 Mhz */ {  156.0f,		/* SGI */  173.3f, },
577 		/* 40 Mhz */ {  324.0f,		/* SGI */  360.0f, },
578 	},
579 
580 	/* MCS 29  */
581 	{	/* 20 Mhz */ {  208.0f,		/* SGI */  231.1f, },
582 		/* 40 Mhz */ {  432.0f,		/* SGI */  480.0f, },
583 	},
584 
585 	/* MCS 30  */
586 	{	/* 20 Mhz */ {  234.0f,		/* SGI */  260.0f, },
587 		/* 40 Mhz */ {  486.0f,		/* SGI */  540.0f, },
588 	},
589 
590 	/* MCS 31  */
591 	{	/* 20 Mhz */ {  260.0f,		/* SGI */  288.9f, },
592 		/* 40 Mhz */ {  540.0f,		/* SGI */  600.0f, },
593 	},
594 
595 	/* MCS 32  */
596 	{	/* 20 Mhz */ {    0.0f,		/* SGI */    0.0f, }, /* not valid */
597 		/* 40 Mhz */ {    6.0f,		/* SGI */    6.7f, },
598 	},
599 
600 	/* MCS 33  */
601 	{	/* 20 Mhz */ {   39.0f,		/* SGI */   43.3f, },
602 		/* 40 Mhz */ {   81.0f,		/* SGI */   90.0f, },
603 	},
604 
605 	/* MCS 34  */
606 	{	/* 20 Mhz */ {   52.0f,		/* SGI */   57.8f, },
607 		/* 40 Mhz */ {  108.0f,		/* SGI */  120.0f, },
608 	},
609 
610 	/* MCS 35  */
611 	{	/* 20 Mhz */ {   65.0f,		/* SGI */   72.2f, },
612 		/* 40 Mhz */ {  135.0f,		/* SGI */  150.0f, },
613 	},
614 
615 	/* MCS 36  */
616 	{	/* 20 Mhz */ {   58.5f,		/* SGI */   65.0f, },
617 		/* 40 Mhz */ {  121.5f,		/* SGI */  135.0f, },
618 	},
619 
620 	/* MCS 37  */
621 	{	/* 20 Mhz */ {   78.0f,		/* SGI */   86.7f, },
622 		/* 40 Mhz */ {  162.0f,		/* SGI */  180.0f, },
623 	},
624 
625 	/* MCS 38  */
626 	{	/* 20 Mhz */ {   97.5f,		/* SGI */  108.3f, },
627 		/* 40 Mhz */ {  202.5f,		/* SGI */  225.0f, },
628 	},
629 
630 	/* MCS 39  */
631 	{	/* 20 Mhz */ {   52.0f,		/* SGI */   57.8f, },
632 		/* 40 Mhz */ {  108.0f,		/* SGI */  120.0f, },
633 	},
634 
635 	/* MCS 40  */
636 	{	/* 20 Mhz */ {   65.0f,		/* SGI */   72.2f, },
637 		/* 40 Mhz */ {  135.0f,		/* SGI */  150.0f, },
638 	},
639 
640 	/* MCS 41  */
641 	{	/* 20 Mhz */ {   65.0f,		/* SGI */   72.2f, },
642 		/* 40 Mhz */ {  135.0f,		/* SGI */  150.0f, },
643 	},
644 
645 	/* MCS 42  */
646 	{	/* 20 Mhz */ {   78.0f,		/* SGI */   86.7f, },
647 		/* 40 Mhz */ {  162.0f,		/* SGI */  180.0f, },
648 	},
649 
650 	/* MCS 43  */
651 	{	/* 20 Mhz */ {   91.0f,		/* SGI */  101.1f, },
652 		/* 40 Mhz */ {  189.0f,		/* SGI */  210.0f, },
653 	},
654 
655 	/* MCS 44  */
656 	{	/* 20 Mhz */ {   91.0f,		/* SGI */  101.1f, },
657 		/* 40 Mhz */ {  189.0f,		/* SGI */  210.0f, },
658 	},
659 
660 	/* MCS 45  */
661 	{	/* 20 Mhz */ {  104.0f,		/* SGI */  115.6f, },
662 		/* 40 Mhz */ {  216.0f,		/* SGI */  240.0f, },
663 	},
664 
665 	/* MCS 46  */
666 	{	/* 20 Mhz */ {   78.0f,		/* SGI */   86.7f, },
667 		/* 40 Mhz */ {  162.0f,		/* SGI */  180.0f, },
668 	},
669 
670 	/* MCS 47  */
671 	{	/* 20 Mhz */ {   97.5f,		/* SGI */  108.3f, },
672 		/* 40 Mhz */ {  202.5f,		/* SGI */  225.0f, },
673 	},
674 
675 	/* MCS 48  */
676 	{	/* 20 Mhz */ {   97.5f,		/* SGI */  108.3f, },
677 		/* 40 Mhz */ {  202.5f,		/* SGI */  225.0f, },
678 	},
679 
680 	/* MCS 49  */
681 	{	/* 20 Mhz */ {  117.0f,		/* SGI */  130.0f, },
682 		/* 40 Mhz */ {  243.0f,		/* SGI */  270.0f, },
683 	},
684 
685 	/* MCS 50  */
686 	{	/* 20 Mhz */ {  136.5f,		/* SGI */  151.7f, },
687 		/* 40 Mhz */ {  283.5f,		/* SGI */  315.0f, },
688 	},
689 
690 	/* MCS 51  */
691 	{	/* 20 Mhz */ {  136.5f,		/* SGI */  151.7f, },
692 		/* 40 Mhz */ {  283.5f,		/* SGI */  315.0f, },
693 	},
694 
695 	/* MCS 52  */
696 	{	/* 20 Mhz */ {  156.0f,		/* SGI */  173.3f, },
697 		/* 40 Mhz */ {  324.0f,		/* SGI */  360.0f, },
698 	},
699 
700 	/* MCS 53  */
701 	{	/* 20 Mhz */ {   65.0f,		/* SGI */   72.2f, },
702 		/* 40 Mhz */ {  135.0f,		/* SGI */  150.0f, },
703 	},
704 
705 	/* MCS 54  */
706 	{	/* 20 Mhz */ {   78.0f,		/* SGI */   86.7f, },
707 		/* 40 Mhz */ {  162.0f,		/* SGI */  180.0f, },
708 	},
709 
710 	/* MCS 55  */
711 	{	/* 20 Mhz */ {   91.0f,		/* SGI */  101.1f, },
712 		/* 40 Mhz */ {  189.0f,		/* SGI */  210.0f, },
713 	},
714 
715 	/* MCS 56  */
716 	{	/* 20 Mhz */ {   78.0f,		/* SGI */   86.7f, },
717 		/* 40 Mhz */ {  162.0f,		/* SGI */  180.0f, },
718 	},
719 
720 	/* MCS 57  */
721 	{	/* 20 Mhz */ {   91.0f,		/* SGI */  101.1f, },
722 		/* 40 Mhz */ {  189.0f,		/* SGI */  210.0f, },
723 	},
724 
725 	/* MCS 58  */
726 	{	/* 20 Mhz */ {  104.0f,		/* SGI */  115.6f, },
727 		/* 40 Mhz */ {  216.0f,		/* SGI */  240.0f, },
728 	},
729 
730 	/* MCS 59  */
731 	{	/* 20 Mhz */ {  117.0f,		/* SGI */  130.0f, },
732 		/* 40 Mhz */ {  243.0f,		/* SGI */  270.0f, },
733 	},
734 
735 	/* MCS 60  */
736 	{	/* 20 Mhz */ {  104.0f,		/* SGI */  115.6f, },
737 		/* 40 Mhz */ {  216.0f,		/* SGI */  240.0f, },
738 	},
739 
740 	/* MCS 61  */
741 	{	/* 20 Mhz */ {  117.0f,		/* SGI */  130.0f, },
742 		/* 40 Mhz */ {  243.0f,		/* SGI */  270.0f, },
743 	},
744 
745 	/* MCS 62  */
746 	{	/* 20 Mhz */ {  130.0f,		/* SGI */  144.4f, },
747 		/* 40 Mhz */ {  270.0f,		/* SGI */  300.0f, },
748 	},
749 
750 	/* MCS 63  */
751 	{	/* 20 Mhz */ {  130.0f,		/* SGI */  144.4f, },
752 		/* 40 Mhz */ {  270.0f,		/* SGI */  300.0f, },
753 	},
754 
755 	/* MCS 64  */
756 	{	/* 20 Mhz */ {  143.0f,		/* SGI */  158.9f, },
757 		/* 40 Mhz */ {  297.0f,		/* SGI */  330.0f, },
758 	},
759 
760 	/* MCS 65  */
761 	{	/* 20 Mhz */ {   97.5f,		/* SGI */  108.3f, },
762 		/* 40 Mhz */ {  202.5f,		/* SGI */  225.0f, },
763 	},
764 
765 	/* MCS 66  */
766 	{	/* 20 Mhz */ {  117.0f,		/* SGI */  130.0f, },
767 		/* 40 Mhz */ {  243.0f,		/* SGI */  270.0f, },
768 	},
769 
770 	/* MCS 67  */
771 	{	/* 20 Mhz */ {  136.5f,		/* SGI */  151.7f, },
772 		/* 40 Mhz */ {  283.5f,		/* SGI */  315.0f, },
773 	},
774 
775 	/* MCS 68  */
776 	{	/* 20 Mhz */ {  117.0f,		/* SGI */  130.0f, },
777 		/* 40 Mhz */ {  243.0f,		/* SGI */  270.0f, },
778 	},
779 
780 	/* MCS 69  */
781 	{	/* 20 Mhz */ {  136.5f,		/* SGI */  151.7f, },
782 		/* 40 Mhz */ {  283.5f,		/* SGI */  315.0f, },
783 	},
784 
785 	/* MCS 70  */
786 	{	/* 20 Mhz */ {  156.0f,		/* SGI */  173.3f, },
787 		/* 40 Mhz */ {  324.0f,		/* SGI */  360.0f, },
788 	},
789 
790 	/* MCS 71  */
791 	{	/* 20 Mhz */ {  175.5f,		/* SGI */  195.0f, },
792 		/* 40 Mhz */ {  364.5f,		/* SGI */  405.0f, },
793 	},
794 
795 	/* MCS 72  */
796 	{	/* 20 Mhz */ {  156.0f,		/* SGI */  173.3f, },
797 		/* 40 Mhz */ {  324.0f,		/* SGI */  360.0f, },
798 	},
799 
800 	/* MCS 73  */
801 	{	/* 20 Mhz */ {  175.5f,		/* SGI */  195.0f, },
802 		/* 40 Mhz */ {  364.5f,		/* SGI */  405.0f, },
803 	},
804 
805 	/* MCS 74  */
806 	{	/* 20 Mhz */ {  195.0f,		/* SGI */  216.7f, },
807 		/* 40 Mhz */ {  405.0f,		/* SGI */  450.0f, },
808 	},
809 
810 	/* MCS 75  */
811 	{	/* 20 Mhz */ {  195.0f,		/* SGI */  216.7f, },
812 		/* 40 Mhz */ {  405.0f,		/* SGI */  450.0f, },
813 	},
814 
815 	/* MCS 76  */
816 	{	/* 20 Mhz */ {  214.5f,		/* SGI */  238.3f, },
817 		/* 40 Mhz */ {  445.5f,		/* SGI */  495.0f, },
818 	},
819 };
820 
821 static const char *auth_alg_text[]={"Open System","Shared Key","EAP"};
822 #define NUM_AUTH_ALGS	(sizeof(auth_alg_text) / sizeof(auth_alg_text[0]))
823 
824 static const char *status_text[] = {
825 	"Successful",						/*  0 */
826 	"Unspecified failure",					/*  1 */
827 	"TDLS wakeup schedule rejected but alternative schedule "
828 	  "provided",					/*  2 */
829 	"TDLS wakeup schedule rejected",/*  3 */
830 	"Reserved",						/*  4 */
831 	"Security disabled",			/*  5 */
832 	"Unacceptable lifetime",		/*  6 */
833 	"Not in same BSS",				/*  7 */
834 	"Reserved",						/*  8 */
835 	"Reserved",						/*  9 */
836 	"Cannot Support all requested capabilities in the Capability "
837 	  "Information field",					/* 10 */
838 	"Reassociation denied due to inability to confirm that association "
839 	  "exists",						/* 11 */
840 	"Association denied due to reason outside the scope of this "
841 	  "standard",						/* 12 */
842 	"Responding STA does not support the specified authentication "
843 	  "algorithm",						/* 13 */
844 	"Received an Authentication frame with authentication transaction "
845 	  "sequence number out of expected sequence",		/* 14 */
846 	"Authentication rejected because of challenge failure",	/* 15 */
847 	"Authentication rejected due to timeout waiting for next frame in "
848 	  "sequence",						/* 16 */
849 	"Association denied because AP is unable to handle "
850 	  "additional associated STAs",				/* 17 */
851 	"Association denied due to requesting STA not supporting "
852 	  "all of the data rates in the BSSBasicRateSet parameter, "
853 	  "the Basic HT-MCS Set field of the HT Operation "
854 	  "parameter, or the Basic VHT-MCS and NSS Set field in "
855 	  "the VHT Operation parameter",	/* 18 */
856 	"Association denied due to requesting STA not supporting "
857 	  "the short preamble option",				/* 19 */
858 	"Reserved",					/* 20 */
859 	"Reserved",					/* 21 */
860 	"Association request rejected because Spectrum Management "
861 	  "capability is required",				/* 22 */
862 	"Association request rejected because the information in the "
863 	  "Power Capability element is unacceptable",		/* 23 */
864 	"Association request rejected because the information in the "
865 	  "Supported Channels element is unacceptable",		/* 24 */
866 	"Association denied due to requesting STA not supporting "
867 	  "the Short Slot Time option",				/* 25 */
868 	"Reserved",				/* 26 */
869 	"Association denied because the requested STA does not support HT "
870 	  "features",						/* 27 */
871 	"R0KH unreachable",					/* 28 */
872 	"Association denied because the requesting STA does not "
873 	  "support the phased coexistence operation (PCO) "
874 	  "transition time required by the AP",		/* 29 */
875 	"Association request rejected temporarily; try again "
876 	  "later",							/* 30 */
877 	"Robust management frame policy violation",	/* 31 */
878 	"Unspecified, QoS-related failure",			/* 32 */
879 	"Association denied because QoS AP or PCP has "
880 	  "insufficient bandwidth to handle another QoS "
881 	  "STA",									/* 33 */
882 	"Association denied due to excessive frame loss rates and/or "
883 	  "poor conditions on current operating channel",	/* 34 */
884 	"Association (with QoS BSS) denied because the requesting STA "
885 	  "does not support the QoS facility",			/* 35 */
886 	"Reserved",									/* 36 */
887 	"The request has been declined",			/* 37 */
888 	"The request has not been successful as one or more parameters "
889 	  "have invalid values",				/* 38 */
890 	"The allocation or TS has not been created because the request "
891 	  "cannot be honored; however, a suggested TSPEC/DMG TSPEC is "
892 	  "provided so that the initiating STA can attempt to set "
893 	  "another allocation or TS with the suggested changes to the "
894 	  "TSPEC/DMG TSPEC",					/* 39 */
895 	"Invalid element, i.e., an element defined in this standard "
896 	  "for which the content does not meet the specifications in "
897 	  "Clause 9",								/* 40 */
898 	"Invalid group cipher",						/* 41 */
899 	"Invalid pairwise cipher",					/* 42 */
900 	"Invalid AKMP",								/* 43 */
901 	"Unsupported RSNE version",					/* 44 */
902 	"Invalid RSNE capabilities",				/* 45 */
903 	"Cipher suite rejected because of security policy",		/* 46 */
904 	"The TS or allocation has not been created; however, the "
905 	  "HC or PCP might be capable of creating a TS or "
906 	  "allocation, in response to a request, after the time "
907 	  "indicated in the TS Delay element",		/* 47 */
908 	"Direct Link is not allowed in the BSS by policy",	/* 48 */
909 	"The Destination STA is not present within this BSS",	/* 49 */
910 	"The Destination STA is not a QoS STA",		/* 50 */
911 
912 	"Association denied because the listen interval is "
913 	  "too large",								/* 51 */
914 	"Invalid FT Action frame count",			/* 52 */
915 	"Invalid pairwise master key identifier (PMKID)", /* 53 */
916 	"Invalid MDE",								/* 54 */
917 	"Invalid FTE",								/* 55 */
918 	"Requested TCLAS processing is not supported by the AP "
919 	  "or PCP",									/* 56 */
920 	"The AP or PCP has insufficient TCLAS processing "
921 	  "resources to satisfy the request",		/* 57 */
922 	"The TS has not been created because the request "
923 	  "cannot be honored; however, the HC or PCP suggests "
924 	  "that the STA transition to a different BSS to set up "
925 	  "the TS",									/* 58 */
926 	"GAS Advertisement Protocol not supported",	/* 59 */
927 	"No outstanding GAS request",				/* 60 */
928 	"GAS Response not received from the Advertisement "
929 	  "Server",									/* 61 */
930 	"STA timed out waiting for GAS Query Response", /* 62 */
931 	"LARGE GAS Response is larger than query response "
932 	  "length limit",							/* 63 */
933 	"Request refused because home network does not support "
934 	  "request",								/* 64 */
935 	"Advertisement Server in the network is not currently "
936 	  "reachable",								/* 65 */
937 	"Reserved",									/* 66 */
938 	"Request refused due to permissions received via SSPN "
939 	  "interface",								/* 67 */
940 	"Request refused because the AP or PCP does not "
941 	  "support unauthenticated access",			/* 68 */
942 	"Reserved",									/* 69 */
943 	"Reserved",									/* 70 */
944 	"Reserved",									/* 71 */
945 	"Invalid contents of RSNE",				/* 72 */
946 	"U-APSD coexistence is not supported",		/* 73 */
947 	"Requested U-APSD coexistence mode is not supported", /* 74 */
948 	"Requested Interval/Duration value cannot be "
949 	  "supported with U-APSD coexistence",		/* 75 */
950 	"Authentication is rejected because an Anti-Clogging "
951 	  "Token is required",						/* 76 */
952 	"Authentication is rejected because the offered "
953 	  "finite cyclic group is not supported",	/* 77 */
954 	"The TBTT adjustment request has not been successful "
955 	  "because the STA could not find an alternative TBTT", /* 78 */
956 	"Transmission failure",						/* 79 */
957 	"Requested TCLAS Not Supported",			/* 80 */
958 	"TCLAS Resources Exhausted",				/* 81 */
959 	"Rejected with Suggested BSS transition",	/* 82 */
960 	"Reject with recommended schedule",			/* 83 */
961 	"Reject because no wakeup schedule specified", /* 84 */
962 	"Success, the destination STA is in power save mode", /* 85 */
963 	"FST pending, in process of admitting FST session", /* 86 */
964 	"Performing FST now",						/* 87 */
965 	"FST pending, gap(s) in block ack window",	/* 88 */
966 	"Reject because of U-PID setting",			/* 89 */
967 	"Reserved",									/* 90 */
968 	"Reserved",									/* 91 */
969 	"(Re)Association refused for some external reason", /* 92 */
970 	"(Re)Association refused because of memory limits "
971 	  "at the AP",								/* 93 */
972 	"(Re)Association refused because emergency services "
973 	  "are not supported at the AP",			/* 94 */
974 	"GAS query response not yet received",		/* 95 */
975 	"Reject since the request is for transition to a "
976 	  "frequency band subject to DSE procedures and "
977 	  "FST Initiator is a dependent STA",		/* 96 */
978 	"Requested TCLAS processing has been terminated by "
979 	  "the AP",									/* 97 */
980 	"The TS schedule conflicts with an existing "
981 	  "schedule; an alternative schedule is provided", /* 98 */
982 	"The association has been denied; however, one or "
983 	  "more Multi-band elements are included that can "
984 	  "be used by the receiving STA to join the BSS", /* 99 */
985 	"The request failed due to a reservation conflict", /* 100 */
986 	"The request failed due to exceeded MAF limit", /* 101 */
987 	"The request failed due to exceeded MCCA track "
988 	  "limit",									/* 102 */
989 	"Association denied because the information in the"
990 	  "Spectrum Management field is unacceptable", /* 103 */
991 	"Association denied because the requesting STA "
992 	  "does not support VHT features",			/* 104 */
993 	"Enablement denied",						/* 105 */
994 	"Enablement denied due to restriction from an "
995 	  "authorized GDB",							/* 106 */
996 	"Authorization deenabled",					/* 107 */
997 };
998 #define NUM_STATUSES	(sizeof(status_text) / sizeof(status_text[0]))
999 
1000 static const char *reason_text[] = {
1001 	"Reserved",						/* 0 */
1002 	"Unspecified reason",					/* 1 */
1003 	"Previous authentication no longer valid",		/* 2 */
1004 	"Deauthenticated because sending STA is leaving (or has left) "
1005 	  "IBSS or ESS",					/* 3 */
1006 	"Disassociated due to inactivity",			/* 4 */
1007 	"Disassociated because AP is unable to handle all currently "
1008 	  " associated STAs",				/* 5 */
1009 	"Class 2 frame received from nonauthenticated STA", /* 6 */
1010 	"Class 3 frame received from nonassociated STA",	/* 7 */
1011 	"Disassociated because sending STA is leaving "
1012 	  "(or has left) BSS",					/* 8 */
1013 	"STA requesting (re)association is not authenticated with "
1014 	  "responding STA",					/* 9 */
1015 	"Disassociated because the information in the Power Capability "
1016 	  "element is unacceptable",				/* 10 */
1017 	"Disassociated because the information in the Supported Channels "
1018 	  "element is unacceptable",				/* 11 */
1019 	"Disassociated due to BSS transition management",	/* 12 */
1020 	"Invalid element, i.e., an element defined in this standard for "
1021 	  "which the content does not meet the specifications "
1022 	  "in Clause 9",						/* 13 */
1023 	"Message integrity code (MIC) failure",	/* 14 */
1024 	"4-Way Handshake timeout",				/* 15 */
1025 	"Group key handshake timeout",			/* 16 */
1026 	"Information element in 4-Way Handshake different from (Re)Association"
1027 	  "Request/Probe Response/Beacon frame",	/* 17 */
1028 	"Invalid group cipher",					/* 18 */
1029 	"Invalid pairwise cipher",				/* 19 */
1030 	"Invalid AKMP",							/* 20 */
1031 	"Unsupported RSNE version",				/* 21 */
1032 	"Invalid RSNE capabilities",				/* 22 */
1033 	"IEEE 802.1X authentication failed",			/* 23 */
1034 	"Cipher suite rejected because of the security policy",		/* 24 */
1035 	"TDLS direct-link teardown due to TDLS peer STA "
1036 	  "unreachable via the TDLS direct link",				/* 25 */
1037 	"TDLS direct-link teardown for unspecified reason",		/* 26 */
1038 	"Disassociated because session terminated by SSP request",/* 27 */
1039 	"Disassociated because of lack of SSP roaming agreement",/* 28 */
1040 	"Requested service rejected because of SSP cipher suite or "
1041 	  "AKM requirement",						/* 29 */
1042 	"Requested service not authorized in this location",	/* 30 */
1043 	"TS deleted because QoS AP lacks sufficient bandwidth for this "
1044 	  "QoS STA due to a change in BSS service characteristics or "
1045 	  "operational mode (e.g. an HT BSS change from 40 MHz channel "
1046 	  "to 20 MHz channel)",					/* 31 */
1047 	"Disassociated for unspecified, QoS-related reason",	/* 32 */
1048 	"Disassociated because QoS AP lacks sufficient bandwidth for this "
1049 	  "QoS STA",						/* 33 */
1050 	"Disassociated because of excessive number of frames that need to be "
1051 	  "acknowledged, but are not acknowledged due to AP transmissions "
1052 	  "and/or poor channel conditions",			/* 34 */
1053 	"Disassociated because STA is transmitting outside the limits "
1054 	  "of its TXOPs",					/* 35 */
1055 	"Requested from peer STA as the STA is leaving the BSS "
1056 	  "(or resetting)",					/* 36 */
1057 	"Requested from peer STA as it does not want to use the "
1058 	  "mechanism",						/* 37 */
1059 	"Requested from peer STA as the STA received frames using the "
1060 	  "mechanism for which a set up is required",		/* 38 */
1061 	"Requested from peer STA due to time out",		/* 39 */
1062 	"Reserved",						/* 40 */
1063 	"Reserved",						/* 41 */
1064 	"Reserved",						/* 42 */
1065 	"Reserved",						/* 43 */
1066 	"Reserved",						/* 44 */
1067 	"Peer STA does not support the requested cipher suite",	/* 45 */
1068 	"In a DLS Teardown frame: The teardown was initiated by the "
1069 	  "DLS peer. In a Disassociation frame: Disassociated because "
1070 	  "authorized access limit reached",					/* 46 */
1071 	"In a DLS Teardown frame: The teardown was initiated by the "
1072 	  "AP. In a Disassociation frame: Disassociated due to external "
1073 	  "service requirements",								/* 47 */
1074 	"Invalid FT Action frame count",						/* 48 */
1075 	"Invalid pairwise master key identifier (PMKID)",		/* 49 */
1076 	"Invalid MDE",											/* 50 */
1077 	"Invalid FTE",											/* 51 */
1078 	"Mesh peering canceled for unknown reasons",			/* 52 */
1079 	"The mesh STA has reached the supported maximum number of "
1080 	  "peer mesh STAs",										/* 53 */
1081 	"The received information violates the Mesh Configuration "
1082 	  "policy configured in the mesh STA profile",			/* 54 */
1083 	"The mesh STA has received a Mesh Peering Close frame "
1084 	  "requesting to close the mesh peering",				/* 55 */
1085 	"The mesh STA has resent dot11MeshMaxRetries Mesh "
1086 	  "Peering Open frames, without receiving a Mesh Peering "
1087 	  "Confirm frame",										/* 56 */
1088 	"The confirmTimer for the mesh peering instance times out",	/* 57 */
1089 	"The mesh STA fails to unwrap the GTK or the values in the "
1090 	  "wrapped contents do not match",						/* 58 */
1091 	"The mesh STA receives inconsistent information about the "
1092 	  "mesh parameters between mesh peering Management frames",	/* 59 */
1093 	"The mesh STA fails the authenticated mesh peering exchange "
1094 	  "because due to failure in selecting either the pairwise "
1095 	  "ciphersuite or group ciphersuite",					/* 60 */
1096 	"The mesh STA does not have proxy information for this "
1097 	  "external destination",								/* 61 */
1098 	"The mesh STA does not have forwarding information for this "
1099 	  "destination",										/* 62 */
1100 	"The mesh STA determines that the link to the next hop of an "
1101 	  "active path in its forwarding information is no longer "
1102 	  "usable",												/* 63 */
1103 	"The Deauthentication frame was sent because the MAC "
1104 	  "address of the STA already exists in the mesh BSS",	/* 64 */
1105 	"The mesh STA performs channel switch to meet regulatory "
1106 	  "requirements",										/* 65 */
1107 	"The mesh STA performs channel switching with unspecified "
1108 	  "reason",												/* 66 */
1109 };
1110 #define NUM_REASONS	(sizeof(reason_text) / sizeof(reason_text[0]))
1111 
1112 static int
wep_print(netdissect_options * ndo,const u_char * p)1113 wep_print(netdissect_options *ndo,
1114 	  const u_char *p)
1115 {
1116 	uint32_t iv;
1117 
1118 	ND_TCHECK_LEN(p, IEEE802_11_IV_LEN + IEEE802_11_KID_LEN);
1119 	iv = GET_LE_U_4(p);
1120 
1121 	ND_PRINT(" IV:%3x Pad %x KeyID %x", IV_IV(iv), IV_PAD(iv),
1122 	    IV_KEYID(iv));
1123 
1124 	return 1;
1125 trunc:
1126 	return 0;
1127 }
1128 
1129 static int
parse_elements(netdissect_options * ndo,struct mgmt_body_t * pbody,const u_char * p,int offset,u_int length)1130 parse_elements(netdissect_options *ndo,
1131 	       struct mgmt_body_t *pbody, const u_char *p, int offset,
1132 	       u_int length)
1133 {
1134 	u_int elementlen;
1135 	struct ssid_t ssid;
1136 	struct challenge_t challenge;
1137 	struct rates_t rates;
1138 	struct ds_t ds;
1139 	struct cf_t cf;
1140 	struct tim_t tim;
1141 
1142 	/*
1143 	 * We haven't seen any elements yet.
1144 	 */
1145 	pbody->challenge_present = 0;
1146 	pbody->ssid_present = 0;
1147 	pbody->rates_present = 0;
1148 	pbody->ds_present = 0;
1149 	pbody->cf_present = 0;
1150 	pbody->tim_present = 0;
1151 
1152 	while (length != 0) {
1153 		/* Make sure we at least have the element ID and length. */
1154 		ND_TCHECK_2(p + offset);
1155 		if (length < 2)
1156 			goto trunc;
1157 		elementlen = GET_U_1(p + offset + 1);
1158 
1159 		/* Make sure we have the entire element. */
1160 		ND_TCHECK_LEN(p + offset + 2, elementlen);
1161 		if (length < elementlen + 2)
1162 			goto trunc;
1163 
1164 		switch (GET_U_1(p + offset)) {
1165 		case E_SSID:
1166 			ssid.length = elementlen;
1167 			offset += 2;
1168 			length -= 2;
1169 			if (ssid.length != 0) {
1170 				if (ssid.length > sizeof(ssid.ssid) - 1)
1171 					return 0;
1172 				memcpy(&ssid.ssid, p + offset, ssid.length);
1173 				offset += ssid.length;
1174 				length -= ssid.length;
1175 			}
1176 			ssid.ssid[ssid.length] = '\0';
1177 			/*
1178 			 * Present and not truncated.
1179 			 *
1180 			 * If we haven't already seen an SSID IE,
1181 			 * copy this one, otherwise ignore this one,
1182 			 * so we later report the first one we saw.
1183 			 */
1184 			if (!pbody->ssid_present) {
1185 				pbody->ssid = ssid;
1186 				pbody->ssid_present = 1;
1187 			}
1188 			break;
1189 		case E_CHALLENGE:
1190 			challenge.length = elementlen;
1191 			offset += 2;
1192 			length -= 2;
1193 			if (challenge.length != 0) {
1194 				if (challenge.length >
1195 				    sizeof(challenge.text) - 1)
1196 					return 0;
1197 				memcpy(&challenge.text, p + offset,
1198 				    challenge.length);
1199 				offset += challenge.length;
1200 				length -= challenge.length;
1201 			}
1202 			challenge.text[challenge.length] = '\0';
1203 			/*
1204 			 * Present and not truncated.
1205 			 *
1206 			 * If we haven't already seen a challenge IE,
1207 			 * copy this one, otherwise ignore this one,
1208 			 * so we later report the first one we saw.
1209 			 */
1210 			if (!pbody->challenge_present) {
1211 				pbody->challenge = challenge;
1212 				pbody->challenge_present = 1;
1213 			}
1214 			break;
1215 		case E_RATES:
1216 			rates.length = elementlen;
1217 			offset += 2;
1218 			length -= 2;
1219 			if (rates.length != 0) {
1220 				if (rates.length > sizeof(rates.rate))
1221 					return 0;
1222 				memcpy(&rates.rate, p + offset, rates.length);
1223 				offset += rates.length;
1224 				length -= rates.length;
1225 			}
1226 			/*
1227 			 * Present and not truncated.
1228 			 *
1229 			 * If we haven't already seen a rates IE,
1230 			 * copy this one if it's not zero-length,
1231 			 * otherwise ignore this one, so we later
1232 			 * report the first one we saw.
1233 			 *
1234 			 * We ignore zero-length rates IEs as some
1235 			 * devices seem to put a zero-length rates
1236 			 * IE, followed by an SSID IE, followed by
1237 			 * a non-zero-length rates IE into frames,
1238 			 * even though IEEE Std 802.11-2007 doesn't
1239 			 * seem to indicate that a zero-length rates
1240 			 * IE is valid.
1241 			 */
1242 			if (!pbody->rates_present && rates.length != 0) {
1243 				pbody->rates = rates;
1244 				pbody->rates_present = 1;
1245 			}
1246 			break;
1247 		case E_DS:
1248 			ds.length = elementlen;
1249 			offset += 2;
1250 			length -= 2;
1251 			if (ds.length != 1) {
1252 				offset += ds.length;
1253 				length -= ds.length;
1254 				break;
1255 			}
1256 			ds.channel = GET_U_1(p + offset);
1257 			offset += 1;
1258 			length -= 1;
1259 			/*
1260 			 * Present and not truncated.
1261 			 *
1262 			 * If we haven't already seen a DS IE,
1263 			 * copy this one, otherwise ignore this one,
1264 			 * so we later report the first one we saw.
1265 			 */
1266 			if (!pbody->ds_present) {
1267 				pbody->ds = ds;
1268 				pbody->ds_present = 1;
1269 			}
1270 			break;
1271 		case E_CF:
1272 			cf.length = elementlen;
1273 			offset += 2;
1274 			length -= 2;
1275 			if (cf.length != 6) {
1276 				offset += cf.length;
1277 				length -= cf.length;
1278 				break;
1279 			}
1280 			cf.count = GET_U_1(p + offset);
1281 			offset += 1;
1282 			length -= 1;
1283 			cf.period = GET_U_1(p + offset);
1284 			offset += 1;
1285 			length -= 1;
1286 			cf.max_duration = GET_LE_U_2(p + offset);
1287 			offset += 2;
1288 			length -= 2;
1289 			cf.dur_remaining = GET_LE_U_2(p + offset);
1290 			offset += 2;
1291 			length -= 2;
1292 			/*
1293 			 * Present and not truncated.
1294 			 *
1295 			 * If we haven't already seen a CF IE,
1296 			 * copy this one, otherwise ignore this one,
1297 			 * so we later report the first one we saw.
1298 			 */
1299 			if (!pbody->cf_present) {
1300 				pbody->cf = cf;
1301 				pbody->cf_present = 1;
1302 			}
1303 			break;
1304 		case E_TIM:
1305 			tim.length = elementlen;
1306 			offset += 2;
1307 			length -= 2;
1308 			if (tim.length <= 3U) {
1309 				offset += tim.length;
1310 				length -= tim.length;
1311 				break;
1312 			}
1313 			if (tim.length - 3U > sizeof(tim.bitmap))
1314 				return 0;
1315 			tim.count = GET_U_1(p + offset);
1316 			offset += 1;
1317 			length -= 1;
1318 			tim.period = GET_U_1(p + offset);
1319 			offset += 1;
1320 			length -= 1;
1321 			tim.bitmap_control = GET_U_1(p + offset);
1322 			offset += 1;
1323 			length -= 1;
1324 			memcpy(tim.bitmap, p + offset, tim.length - 3);
1325 			offset += tim.length - 3;
1326 			length -= tim.length - 3;
1327 			/*
1328 			 * Present and not truncated.
1329 			 *
1330 			 * If we haven't already seen a TIM IE,
1331 			 * copy this one, otherwise ignore this one,
1332 			 * so we later report the first one we saw.
1333 			 */
1334 			if (!pbody->tim_present) {
1335 				pbody->tim = tim;
1336 				pbody->tim_present = 1;
1337 			}
1338 			break;
1339 		default:
1340 #if 0
1341 			ND_PRINT("(1) unhandled element_id (%u)  ",
1342 			    GET_U_1(p + offset));
1343 #endif
1344 			offset += 2 + elementlen;
1345 			length -= 2 + elementlen;
1346 			break;
1347 		}
1348 	}
1349 
1350 	/* No problems found. */
1351 	return 1;
1352 trunc:
1353 	return 0;
1354 }
1355 
1356 /*********************************************************************************
1357  * Print Handle functions for the management frame types
1358  *********************************************************************************/
1359 
1360 static int
handle_beacon(netdissect_options * ndo,const u_char * p,u_int length)1361 handle_beacon(netdissect_options *ndo,
1362 	      const u_char *p, u_int length)
1363 {
1364 	struct mgmt_body_t pbody;
1365 	int offset = 0;
1366 	int ret;
1367 
1368 	memset(&pbody, 0, sizeof(pbody));
1369 
1370 	ND_TCHECK_LEN(p, IEEE802_11_TSTAMP_LEN + IEEE802_11_BCNINT_LEN +
1371 		      IEEE802_11_CAPINFO_LEN);
1372 	if (length < IEEE802_11_TSTAMP_LEN + IEEE802_11_BCNINT_LEN +
1373 	    IEEE802_11_CAPINFO_LEN)
1374 		goto trunc;
1375 	memcpy(&pbody.timestamp, p, IEEE802_11_TSTAMP_LEN);
1376 	offset += IEEE802_11_TSTAMP_LEN;
1377 	length -= IEEE802_11_TSTAMP_LEN;
1378 	pbody.beacon_interval = GET_LE_U_2(p + offset);
1379 	offset += IEEE802_11_BCNINT_LEN;
1380 	length -= IEEE802_11_BCNINT_LEN;
1381 	pbody.capability_info = GET_LE_U_2(p + offset);
1382 	offset += IEEE802_11_CAPINFO_LEN;
1383 	length -= IEEE802_11_CAPINFO_LEN;
1384 
1385 	ret = parse_elements(ndo, &pbody, p, offset, length);
1386 
1387 	PRINT_SSID(pbody);
1388 	PRINT_RATES(pbody);
1389 	ND_PRINT(" %s",
1390 	    CAPABILITY_ESS(pbody.capability_info) ? "ESS" : "IBSS");
1391 	PRINT_DS_CHANNEL(pbody);
1392 
1393 	return ret;
1394 trunc:
1395 	return 0;
1396 }
1397 
1398 static int
handle_assoc_request(netdissect_options * ndo,const u_char * p,u_int length)1399 handle_assoc_request(netdissect_options *ndo,
1400 		     const u_char *p, u_int length)
1401 {
1402 	struct mgmt_body_t pbody;
1403 	int offset = 0;
1404 	int ret;
1405 
1406 	memset(&pbody, 0, sizeof(pbody));
1407 
1408 	ND_TCHECK_LEN(p, IEEE802_11_CAPINFO_LEN + IEEE802_11_LISTENINT_LEN);
1409 	if (length < IEEE802_11_CAPINFO_LEN + IEEE802_11_LISTENINT_LEN)
1410 		goto trunc;
1411 	pbody.capability_info = GET_LE_U_2(p);
1412 	offset += IEEE802_11_CAPINFO_LEN;
1413 	length -= IEEE802_11_CAPINFO_LEN;
1414 	pbody.listen_interval = GET_LE_U_2(p + offset);
1415 	offset += IEEE802_11_LISTENINT_LEN;
1416 	length -= IEEE802_11_LISTENINT_LEN;
1417 
1418 	ret = parse_elements(ndo, &pbody, p, offset, length);
1419 
1420 	PRINT_SSID(pbody);
1421 	PRINT_RATES(pbody);
1422 	return ret;
1423 trunc:
1424 	return 0;
1425 }
1426 
1427 static int
handle_assoc_response(netdissect_options * ndo,const u_char * p,u_int length)1428 handle_assoc_response(netdissect_options *ndo,
1429 		      const u_char *p, u_int length)
1430 {
1431 	struct mgmt_body_t pbody;
1432 	int offset = 0;
1433 	int ret;
1434 
1435 	memset(&pbody, 0, sizeof(pbody));
1436 
1437 	ND_TCHECK_LEN(p, IEEE802_11_CAPINFO_LEN + IEEE802_11_STATUS_LEN +
1438 		      IEEE802_11_AID_LEN);
1439 	if (length < IEEE802_11_CAPINFO_LEN + IEEE802_11_STATUS_LEN +
1440 	    IEEE802_11_AID_LEN)
1441 		goto trunc;
1442 	pbody.capability_info = GET_LE_U_2(p);
1443 	offset += IEEE802_11_CAPINFO_LEN;
1444 	length -= IEEE802_11_CAPINFO_LEN;
1445 	pbody.status_code = GET_LE_U_2(p + offset);
1446 	offset += IEEE802_11_STATUS_LEN;
1447 	length -= IEEE802_11_STATUS_LEN;
1448 	pbody.aid = GET_LE_U_2(p + offset);
1449 	offset += IEEE802_11_AID_LEN;
1450 	length -= IEEE802_11_AID_LEN;
1451 
1452 	ret = parse_elements(ndo, &pbody, p, offset, length);
1453 
1454 	ND_PRINT(" AID(%x) :%s: %s", ((uint16_t)(pbody.aid << 2 )) >> 2 ,
1455 	    CAPABILITY_PRIVACY(pbody.capability_info) ? " PRIVACY " : "",
1456 	    (pbody.status_code < NUM_STATUSES
1457 		? status_text[pbody.status_code]
1458 		: "n/a"));
1459 
1460 	return ret;
1461 trunc:
1462 	return 0;
1463 }
1464 
1465 static int
handle_reassoc_request(netdissect_options * ndo,const u_char * p,u_int length)1466 handle_reassoc_request(netdissect_options *ndo,
1467 		       const u_char *p, u_int length)
1468 {
1469 	struct mgmt_body_t pbody;
1470 	int offset = 0;
1471 	int ret;
1472 
1473 	memset(&pbody, 0, sizeof(pbody));
1474 
1475 	ND_TCHECK_LEN(p, IEEE802_11_CAPINFO_LEN + IEEE802_11_LISTENINT_LEN +
1476 		      IEEE802_11_AP_LEN);
1477 	if (length < IEEE802_11_CAPINFO_LEN + IEEE802_11_LISTENINT_LEN +
1478 	    IEEE802_11_AP_LEN)
1479 		goto trunc;
1480 	pbody.capability_info = GET_LE_U_2(p);
1481 	offset += IEEE802_11_CAPINFO_LEN;
1482 	length -= IEEE802_11_CAPINFO_LEN;
1483 	pbody.listen_interval = GET_LE_U_2(p + offset);
1484 	offset += IEEE802_11_LISTENINT_LEN;
1485 	length -= IEEE802_11_LISTENINT_LEN;
1486 	memcpy(&pbody.ap, p+offset, IEEE802_11_AP_LEN);
1487 	offset += IEEE802_11_AP_LEN;
1488 	length -= IEEE802_11_AP_LEN;
1489 
1490 	ret = parse_elements(ndo, &pbody, p, offset, length);
1491 
1492 	PRINT_SSID(pbody);
1493 	ND_PRINT(" AP : %s", etheraddr_string(ndo,  pbody.ap ));
1494 
1495 	return ret;
1496 trunc:
1497 	return 0;
1498 }
1499 
1500 static int
handle_reassoc_response(netdissect_options * ndo,const u_char * p,u_int length)1501 handle_reassoc_response(netdissect_options *ndo,
1502 			const u_char *p, u_int length)
1503 {
1504 	/* Same as a Association Response */
1505 	return handle_assoc_response(ndo, p, length);
1506 }
1507 
1508 static int
handle_probe_request(netdissect_options * ndo,const u_char * p,u_int length)1509 handle_probe_request(netdissect_options *ndo,
1510 		     const u_char *p, u_int length)
1511 {
1512 	struct mgmt_body_t  pbody;
1513 	int offset = 0;
1514 	int ret;
1515 
1516 	memset(&pbody, 0, sizeof(pbody));
1517 
1518 	ret = parse_elements(ndo, &pbody, p, offset, length);
1519 
1520 	PRINT_SSID(pbody);
1521 	PRINT_RATES(pbody);
1522 
1523 	return ret;
1524 }
1525 
1526 static int
handle_probe_response(netdissect_options * ndo,const u_char * p,u_int length)1527 handle_probe_response(netdissect_options *ndo,
1528 		      const u_char *p, u_int length)
1529 {
1530 	struct mgmt_body_t  pbody;
1531 	int offset = 0;
1532 	int ret;
1533 
1534 	memset(&pbody, 0, sizeof(pbody));
1535 
1536 	ND_TCHECK_LEN(p, IEEE802_11_TSTAMP_LEN + IEEE802_11_BCNINT_LEN +
1537 		      IEEE802_11_CAPINFO_LEN);
1538 	if (length < IEEE802_11_TSTAMP_LEN + IEEE802_11_BCNINT_LEN +
1539 	    IEEE802_11_CAPINFO_LEN)
1540 		goto trunc;
1541 	memcpy(&pbody.timestamp, p, IEEE802_11_TSTAMP_LEN);
1542 	offset += IEEE802_11_TSTAMP_LEN;
1543 	length -= IEEE802_11_TSTAMP_LEN;
1544 	pbody.beacon_interval = GET_LE_U_2(p + offset);
1545 	offset += IEEE802_11_BCNINT_LEN;
1546 	length -= IEEE802_11_BCNINT_LEN;
1547 	pbody.capability_info = GET_LE_U_2(p + offset);
1548 	offset += IEEE802_11_CAPINFO_LEN;
1549 	length -= IEEE802_11_CAPINFO_LEN;
1550 
1551 	ret = parse_elements(ndo, &pbody, p, offset, length);
1552 
1553 	PRINT_SSID(pbody);
1554 	PRINT_RATES(pbody);
1555 	PRINT_DS_CHANNEL(pbody);
1556 
1557 	return ret;
1558 trunc:
1559 	return 0;
1560 }
1561 
1562 static int
handle_atim(void)1563 handle_atim(void)
1564 {
1565 	/* the frame body for ATIM is null. */
1566 	return 1;
1567 }
1568 
1569 static int
handle_disassoc(netdissect_options * ndo,const u_char * p,u_int length)1570 handle_disassoc(netdissect_options *ndo,
1571 		const u_char *p, u_int length)
1572 {
1573 	struct mgmt_body_t  pbody;
1574 
1575 	memset(&pbody, 0, sizeof(pbody));
1576 
1577 	ND_TCHECK_LEN(p, IEEE802_11_REASON_LEN);
1578 	if (length < IEEE802_11_REASON_LEN)
1579 		goto trunc;
1580 	pbody.reason_code = GET_LE_U_2(p);
1581 
1582 	ND_PRINT(": %s",
1583 	    (pbody.reason_code < NUM_REASONS)
1584 		? reason_text[pbody.reason_code]
1585 		: "Reserved");
1586 
1587 	return 1;
1588 trunc:
1589 	return 0;
1590 }
1591 
1592 static int
handle_auth(netdissect_options * ndo,const u_char * p,u_int length)1593 handle_auth(netdissect_options *ndo,
1594 	    const u_char *p, u_int length)
1595 {
1596 	struct mgmt_body_t  pbody;
1597 	int offset = 0;
1598 	int ret;
1599 
1600 	memset(&pbody, 0, sizeof(pbody));
1601 
1602 	ND_TCHECK_6(p);
1603 	if (length < 6)
1604 		goto trunc;
1605 	pbody.auth_alg = GET_LE_U_2(p);
1606 	offset += 2;
1607 	length -= 2;
1608 	pbody.auth_trans_seq_num = GET_LE_U_2(p + offset);
1609 	offset += 2;
1610 	length -= 2;
1611 	pbody.status_code = GET_LE_U_2(p + offset);
1612 	offset += 2;
1613 	length -= 2;
1614 
1615 	ret = parse_elements(ndo, &pbody, p, offset, length);
1616 
1617 	if ((pbody.auth_alg == 1) &&
1618 	    ((pbody.auth_trans_seq_num == 2) ||
1619 	     (pbody.auth_trans_seq_num == 3))) {
1620 		ND_PRINT(" (%s)-%x [Challenge Text] %s",
1621 		    (pbody.auth_alg < NUM_AUTH_ALGS)
1622 			? auth_alg_text[pbody.auth_alg]
1623 			: "Reserved",
1624 		    pbody.auth_trans_seq_num,
1625 		    ((pbody.auth_trans_seq_num % 2)
1626 			? ((pbody.status_code < NUM_STATUSES)
1627 			       ? status_text[pbody.status_code]
1628 			       : "n/a") : ""));
1629 		return ret;
1630 	}
1631 	ND_PRINT(" (%s)-%x: %s",
1632 	    (pbody.auth_alg < NUM_AUTH_ALGS)
1633 		? auth_alg_text[pbody.auth_alg]
1634 		: "Reserved",
1635 	    pbody.auth_trans_seq_num,
1636 	    (pbody.auth_trans_seq_num % 2)
1637 		? ((pbody.status_code < NUM_STATUSES)
1638 		    ? status_text[pbody.status_code]
1639 		    : "n/a")
1640 		: "");
1641 
1642 	return ret;
1643 trunc:
1644 	return 0;
1645 }
1646 
1647 static int
handle_deauth(netdissect_options * ndo,const uint8_t * src,const u_char * p,u_int length)1648 handle_deauth(netdissect_options *ndo,
1649 	      const uint8_t *src, const u_char *p, u_int length)
1650 {
1651 	struct mgmt_body_t  pbody;
1652 	const char *reason = NULL;
1653 
1654 	memset(&pbody, 0, sizeof(pbody));
1655 
1656 	ND_TCHECK_LEN(p, IEEE802_11_REASON_LEN);
1657 	if (length < IEEE802_11_REASON_LEN)
1658 		goto trunc;
1659 	pbody.reason_code = GET_LE_U_2(p);
1660 
1661 	reason = (pbody.reason_code < NUM_REASONS)
1662 			? reason_text[pbody.reason_code]
1663 			: "Reserved";
1664 
1665 	if (ndo->ndo_eflag) {
1666 		ND_PRINT(": %s", reason);
1667 	} else {
1668 		ND_PRINT(" (%s): %s", GET_ETHERADDR_STRING(src), reason);
1669 	}
1670 	return 1;
1671 trunc:
1672 	return 0;
1673 }
1674 
1675 #define	PRINT_HT_ACTION(v) (\
1676 	(v) == 0 ? ND_PRINT("TxChWidth"): \
1677 	(v) == 1 ? ND_PRINT("MIMOPwrSave"): \
1678 		   ND_PRINT("Act#%u", (v)))
1679 #define	PRINT_BA_ACTION(v) (\
1680 	(v) == 0 ? ND_PRINT("ADDBA Request"): \
1681 	(v) == 1 ? ND_PRINT("ADDBA Response"): \
1682 	(v) == 2 ? ND_PRINT("DELBA"): \
1683 		   ND_PRINT("Act#%u", (v)))
1684 #define	PRINT_MESHLINK_ACTION(v) (\
1685 	(v) == 0 ? ND_PRINT("Request"): \
1686 	(v) == 1 ? ND_PRINT("Report"): \
1687 		   ND_PRINT("Act#%u", (v)))
1688 #define	PRINT_MESHPEERING_ACTION(v) (\
1689 	(v) == 0 ? ND_PRINT("Open"): \
1690 	(v) == 1 ? ND_PRINT("Confirm"): \
1691 	(v) == 2 ? ND_PRINT("Close"): \
1692 		   ND_PRINT("Act#%u", (v)))
1693 #define	PRINT_MESHPATH_ACTION(v) (\
1694 	(v) == 0 ? ND_PRINT("Request"): \
1695 	(v) == 1 ? ND_PRINT("Report"): \
1696 	(v) == 2 ? ND_PRINT("Error"): \
1697 	(v) == 3 ? ND_PRINT("RootAnnouncement"): \
1698 		   ND_PRINT("Act#%u", (v)))
1699 
1700 #define PRINT_MESH_ACTION(v) (\
1701 	(v) == 0 ? ND_PRINT("MeshLink"): \
1702 	(v) == 1 ? ND_PRINT("HWMP"): \
1703 	(v) == 2 ? ND_PRINT("Gate Announcement"): \
1704 	(v) == 3 ? ND_PRINT("Congestion Control"): \
1705 	(v) == 4 ? ND_PRINT("MCCA Setup Request"): \
1706 	(v) == 5 ? ND_PRINT("MCCA Setup Reply"): \
1707 	(v) == 6 ? ND_PRINT("MCCA Advertisement Request"): \
1708 	(v) == 7 ? ND_PRINT("MCCA Advertisement"): \
1709 	(v) == 8 ? ND_PRINT("MCCA Teardown"): \
1710 	(v) == 9 ? ND_PRINT("TBTT Adjustment Request"): \
1711 	(v) == 10 ? ND_PRINT("TBTT Adjustment Response"): \
1712 		   ND_PRINT("Act#%u", (v)))
1713 #define PRINT_MULTIHOP_ACTION(v) (\
1714 	(v) == 0 ? ND_PRINT("Proxy Update"): \
1715 	(v) == 1 ? ND_PRINT("Proxy Update Confirmation"): \
1716 		   ND_PRINT("Act#%u", (v)))
1717 #define PRINT_SELFPROT_ACTION(v) (\
1718 	(v) == 1 ? ND_PRINT("Peering Open"): \
1719 	(v) == 2 ? ND_PRINT("Peering Confirm"): \
1720 	(v) == 3 ? ND_PRINT("Peering Close"): \
1721 	(v) == 4 ? ND_PRINT("Group Key Inform"): \
1722 	(v) == 5 ? ND_PRINT("Group Key Acknowledge"): \
1723 		   ND_PRINT("Act#%u", (v)))
1724 
1725 static int
handle_action(netdissect_options * ndo,const uint8_t * src,const u_char * p,u_int length)1726 handle_action(netdissect_options *ndo,
1727 	      const uint8_t *src, const u_char *p, u_int length)
1728 {
1729 	ND_TCHECK_2(p);
1730 	if (length < 2)
1731 		goto trunc;
1732 	if (ndo->ndo_eflag) {
1733 		ND_PRINT(": ");
1734 	} else {
1735 		ND_PRINT(" (%s): ", GET_ETHERADDR_STRING(src));
1736 	}
1737 	switch (GET_U_1(p)) {
1738 	case 0: ND_PRINT("Spectrum Management Act#%u", GET_U_1(p + 1)); break;
1739 	case 1: ND_PRINT("QoS Act#%u", GET_U_1(p + 1)); break;
1740 	case 2: ND_PRINT("DLS Act#%u", GET_U_1(p + 1)); break;
1741 	case 3: ND_PRINT("BA "); PRINT_BA_ACTION(GET_U_1(p + 1)); break;
1742 	case 7: ND_PRINT("HT "); PRINT_HT_ACTION(GET_U_1(p + 1)); break;
1743 	case 13: ND_PRINT("MeshAction "); PRINT_MESH_ACTION(GET_U_1(p + 1)); break;
1744 	case 14:
1745 		ND_PRINT("MultihopAction");
1746 		PRINT_MULTIHOP_ACTION(GET_U_1(p + 1)); break;
1747 	case 15:
1748 		ND_PRINT("SelfprotectAction ");
1749 		PRINT_SELFPROT_ACTION(GET_U_1(p + 1)); break;
1750 	case 127: ND_PRINT("Vendor Act#%u", GET_U_1(p + 1)); break;
1751 	default:
1752 		ND_PRINT("Reserved(%u) Act#%u", GET_U_1(p), GET_U_1(p + 1));
1753 		break;
1754 	}
1755 	return 1;
1756 trunc:
1757 	return 0;
1758 }
1759 
1760 
1761 /*********************************************************************************
1762  * Print Body funcs
1763  *********************************************************************************/
1764 
1765 
1766 static int
mgmt_body_print(netdissect_options * ndo,uint16_t fc,const uint8_t * src,const u_char * p,u_int length)1767 mgmt_body_print(netdissect_options *ndo,
1768 		uint16_t fc, const uint8_t *src, const u_char *p, u_int length)
1769 {
1770 	ND_PRINT("%s", tok2str(st_str, "Unhandled Management subtype(%x)", FC_SUBTYPE(fc)));
1771 
1772 	/* There may be a problem w/ AP not having this bit set */
1773 	if (FC_PROTECTED(fc))
1774 		return wep_print(ndo, p);
1775 	switch (FC_SUBTYPE(fc)) {
1776 	case ST_ASSOC_REQUEST:
1777 		return handle_assoc_request(ndo, p, length);
1778 	case ST_ASSOC_RESPONSE:
1779 		return handle_assoc_response(ndo, p, length);
1780 	case ST_REASSOC_REQUEST:
1781 		return handle_reassoc_request(ndo, p, length);
1782 	case ST_REASSOC_RESPONSE:
1783 		return handle_reassoc_response(ndo, p, length);
1784 	case ST_PROBE_REQUEST:
1785 		return handle_probe_request(ndo, p, length);
1786 	case ST_PROBE_RESPONSE:
1787 		return handle_probe_response(ndo, p, length);
1788 	case ST_BEACON:
1789 		return handle_beacon(ndo, p, length);
1790 	case ST_ATIM:
1791 		return handle_atim();
1792 	case ST_DISASSOC:
1793 		return handle_disassoc(ndo, p, length);
1794 	case ST_AUTH:
1795 		return handle_auth(ndo, p, length);
1796 	case ST_DEAUTH:
1797 		return handle_deauth(ndo, src, p, length);
1798 	case ST_ACTION:
1799 		return handle_action(ndo, src, p, length);
1800 	default:
1801 		return 1;
1802 	}
1803 }
1804 
1805 
1806 /*********************************************************************************
1807  * Handles printing all the control frame types
1808  *********************************************************************************/
1809 
1810 static int
ctrl_body_print(netdissect_options * ndo,uint16_t fc,const u_char * p)1811 ctrl_body_print(netdissect_options *ndo,
1812 		uint16_t fc, const u_char *p)
1813 {
1814 	ND_PRINT("%s", tok2str(ctrl_str, "Unknown Ctrl Subtype", FC_SUBTYPE(fc)));
1815 	switch (FC_SUBTYPE(fc)) {
1816 	case CTRL_CONTROL_WRAPPER:
1817 		/* XXX - requires special handling */
1818 		break;
1819 	case CTRL_BAR:
1820 		ND_TCHECK_LEN(p, CTRL_BAR_HDRLEN);
1821 		if (!ndo->ndo_eflag)
1822 			ND_PRINT(" RA:%s TA:%s CTL(%x) SEQ(%u) ",
1823 			    GET_ETHERADDR_STRING(((const struct ctrl_bar_hdr_t *)p)->ra),
1824 			    GET_ETHERADDR_STRING(((const struct ctrl_bar_hdr_t *)p)->ta),
1825 			    GET_LE_U_2(((const struct ctrl_bar_hdr_t *)p)->ctl),
1826 			    GET_LE_U_2(((const struct ctrl_bar_hdr_t *)p)->seq));
1827 		break;
1828 	case CTRL_BA:
1829 		ND_TCHECK_LEN(p, CTRL_BA_HDRLEN);
1830 		if (!ndo->ndo_eflag)
1831 			ND_PRINT(" RA:%s ",
1832 			    GET_ETHERADDR_STRING(((const struct ctrl_ba_hdr_t *)p)->ra));
1833 		break;
1834 	case CTRL_PS_POLL:
1835 		ND_TCHECK_LEN(p, CTRL_PS_POLL_HDRLEN);
1836 		ND_PRINT(" AID(%x)",
1837 		    GET_LE_U_2(((const struct ctrl_ps_poll_hdr_t *)p)->aid));
1838 		break;
1839 	case CTRL_RTS:
1840 		ND_TCHECK_LEN(p, CTRL_RTS_HDRLEN);
1841 		if (!ndo->ndo_eflag)
1842 			ND_PRINT(" TA:%s ",
1843 			    GET_ETHERADDR_STRING(((const struct ctrl_rts_hdr_t *)p)->ta));
1844 		break;
1845 	case CTRL_CTS:
1846 		ND_TCHECK_LEN(p, CTRL_CTS_HDRLEN);
1847 		if (!ndo->ndo_eflag)
1848 			ND_PRINT(" RA:%s ",
1849 			    GET_ETHERADDR_STRING(((const struct ctrl_cts_hdr_t *)p)->ra));
1850 		break;
1851 	case CTRL_ACK:
1852 		ND_TCHECK_LEN(p, CTRL_ACK_HDRLEN);
1853 		if (!ndo->ndo_eflag)
1854 			ND_PRINT(" RA:%s ",
1855 			    GET_ETHERADDR_STRING(((const struct ctrl_ack_hdr_t *)p)->ra));
1856 		break;
1857 	case CTRL_CF_END:
1858 		ND_TCHECK_LEN(p, CTRL_END_HDRLEN);
1859 		if (!ndo->ndo_eflag)
1860 			ND_PRINT(" RA:%s ",
1861 			    GET_ETHERADDR_STRING(((const struct ctrl_end_hdr_t *)p)->ra));
1862 		break;
1863 	case CTRL_END_ACK:
1864 		ND_TCHECK_LEN(p, CTRL_END_ACK_HDRLEN);
1865 		if (!ndo->ndo_eflag)
1866 			ND_PRINT(" RA:%s ",
1867 			    GET_ETHERADDR_STRING(((const struct ctrl_end_ack_hdr_t *)p)->ra));
1868 		break;
1869 	}
1870 	return 1;
1871 trunc:
1872 	return 0;
1873 }
1874 
1875 /*
1876  *  Data Frame - Address field contents
1877  *
1878  *  To Ds  | From DS | Addr 1 | Addr 2 | Addr 3 | Addr 4
1879  *    0    |  0      |  DA    | SA     | BSSID  | n/a
1880  *    0    |  1      |  DA    | BSSID  | SA     | n/a
1881  *    1    |  0      |  BSSID | SA     | DA     | n/a
1882  *    1    |  1      |  RA    | TA     | DA     | SA
1883  */
1884 
1885 /*
1886  * Function to get source and destination MAC addresses for a data frame.
1887  */
1888 static void
get_data_src_dst_mac(uint16_t fc,const u_char * p,const uint8_t ** srcp,const uint8_t ** dstp)1889 get_data_src_dst_mac(uint16_t fc, const u_char *p, const uint8_t **srcp,
1890 		     const uint8_t **dstp)
1891 {
1892 #define ADDR1  (p + 4)
1893 #define ADDR2  (p + 10)
1894 #define ADDR3  (p + 16)
1895 #define ADDR4  (p + 24)
1896 
1897 	if (!FC_TO_DS(fc)) {
1898 		if (!FC_FROM_DS(fc)) {
1899 			/* not To DS and not From DS */
1900 			*srcp = ADDR2;
1901 			*dstp = ADDR1;
1902 		} else {
1903 			/* not To DS and From DS */
1904 			*srcp = ADDR3;
1905 			*dstp = ADDR1;
1906 		}
1907 	} else {
1908 		if (!FC_FROM_DS(fc)) {
1909 			/* To DS and not From DS */
1910 			*srcp = ADDR2;
1911 			*dstp = ADDR3;
1912 		} else {
1913 			/* To DS and From DS */
1914 			*srcp = ADDR4;
1915 			*dstp = ADDR3;
1916 		}
1917 	}
1918 
1919 #undef ADDR1
1920 #undef ADDR2
1921 #undef ADDR3
1922 #undef ADDR4
1923 }
1924 
1925 static void
get_mgmt_src_dst_mac(const u_char * p,const uint8_t ** srcp,const uint8_t ** dstp)1926 get_mgmt_src_dst_mac(const u_char *p, const uint8_t **srcp, const uint8_t **dstp)
1927 {
1928 	const struct mgmt_header_t *hp = (const struct mgmt_header_t *) p;
1929 
1930 	if (srcp != NULL)
1931 		*srcp = hp->sa;
1932 	if (dstp != NULL)
1933 		*dstp = hp->da;
1934 }
1935 
1936 /*
1937  * Print Header funcs
1938  */
1939 
1940 static void
data_header_print(netdissect_options * ndo,uint16_t fc,const u_char * p)1941 data_header_print(netdissect_options *ndo, uint16_t fc, const u_char *p)
1942 {
1943 	u_int subtype = FC_SUBTYPE(fc);
1944 
1945 	if (DATA_FRAME_IS_CF_ACK(subtype) || DATA_FRAME_IS_CF_POLL(subtype) ||
1946 	    DATA_FRAME_IS_QOS(subtype)) {
1947 		ND_PRINT("CF ");
1948 		if (DATA_FRAME_IS_CF_ACK(subtype)) {
1949 			if (DATA_FRAME_IS_CF_POLL(subtype))
1950 				ND_PRINT("Ack/Poll");
1951 			else
1952 				ND_PRINT("Ack");
1953 		} else {
1954 			if (DATA_FRAME_IS_CF_POLL(subtype))
1955 				ND_PRINT("Poll");
1956 		}
1957 		if (DATA_FRAME_IS_QOS(subtype))
1958 			ND_PRINT("+QoS");
1959 		ND_PRINT(" ");
1960 	}
1961 
1962 #define ADDR1  (p + 4)
1963 #define ADDR2  (p + 10)
1964 #define ADDR3  (p + 16)
1965 #define ADDR4  (p + 24)
1966 
1967 	if (!FC_TO_DS(fc) && !FC_FROM_DS(fc)) {
1968 		ND_PRINT("DA:%s SA:%s BSSID:%s ",
1969 		    GET_ETHERADDR_STRING(ADDR1), GET_ETHERADDR_STRING(ADDR2),
1970 		    GET_ETHERADDR_STRING(ADDR3));
1971 	} else if (!FC_TO_DS(fc) && FC_FROM_DS(fc)) {
1972 		ND_PRINT("DA:%s BSSID:%s SA:%s ",
1973 		    GET_ETHERADDR_STRING(ADDR1), GET_ETHERADDR_STRING(ADDR2),
1974 		    GET_ETHERADDR_STRING(ADDR3));
1975 	} else if (FC_TO_DS(fc) && !FC_FROM_DS(fc)) {
1976 		ND_PRINT("BSSID:%s SA:%s DA:%s ",
1977 		    GET_ETHERADDR_STRING(ADDR1), GET_ETHERADDR_STRING(ADDR2),
1978 		    GET_ETHERADDR_STRING(ADDR3));
1979 	} else if (FC_TO_DS(fc) && FC_FROM_DS(fc)) {
1980 		ND_PRINT("RA:%s TA:%s DA:%s SA:%s ",
1981 		    GET_ETHERADDR_STRING(ADDR1), GET_ETHERADDR_STRING(ADDR2),
1982 		    GET_ETHERADDR_STRING(ADDR3), GET_ETHERADDR_STRING(ADDR4));
1983 	}
1984 
1985 #undef ADDR1
1986 #undef ADDR2
1987 #undef ADDR3
1988 #undef ADDR4
1989 }
1990 
1991 static void
mgmt_header_print(netdissect_options * ndo,const u_char * p)1992 mgmt_header_print(netdissect_options *ndo, const u_char *p)
1993 {
1994 	const struct mgmt_header_t *hp = (const struct mgmt_header_t *) p;
1995 
1996 	ND_PRINT("BSSID:%s DA:%s SA:%s ",
1997 	    GET_ETHERADDR_STRING((hp)->bssid), GET_ETHERADDR_STRING((hp)->da),
1998 	    GET_ETHERADDR_STRING((hp)->sa));
1999 }
2000 
2001 static void
ctrl_header_print(netdissect_options * ndo,uint16_t fc,const u_char * p)2002 ctrl_header_print(netdissect_options *ndo, uint16_t fc, const u_char *p)
2003 {
2004 	switch (FC_SUBTYPE(fc)) {
2005 	case CTRL_BAR:
2006 		ND_PRINT(" RA:%s TA:%s CTL(%x) SEQ(%u) ",
2007 		    GET_ETHERADDR_STRING(((const struct ctrl_bar_hdr_t *)p)->ra),
2008 		    GET_ETHERADDR_STRING(((const struct ctrl_bar_hdr_t *)p)->ta),
2009 		    GET_LE_U_2(((const struct ctrl_bar_hdr_t *)p)->ctl),
2010 		    GET_LE_U_2(((const struct ctrl_bar_hdr_t *)p)->seq));
2011 		break;
2012 	case CTRL_BA:
2013 		ND_PRINT("RA:%s TA:%s ",
2014 		    GET_ETHERADDR_STRING(((const struct ctrl_ba_hdr_t *)p)->ra),
2015 		    GET_ETHERADDR_STRING(((const struct ctrl_ba_hdr_t *)p)->ta));
2016 		break;
2017 	case CTRL_PS_POLL:
2018 		ND_PRINT("BSSID:%s TA:%s ",
2019 		    GET_ETHERADDR_STRING(((const struct ctrl_ps_poll_hdr_t *)p)->bssid),
2020 		    GET_ETHERADDR_STRING(((const struct ctrl_ps_poll_hdr_t *)p)->ta));
2021 		break;
2022 	case CTRL_RTS:
2023 		ND_PRINT("RA:%s TA:%s ",
2024 		    GET_ETHERADDR_STRING(((const struct ctrl_rts_hdr_t *)p)->ra),
2025 		    GET_ETHERADDR_STRING(((const struct ctrl_rts_hdr_t *)p)->ta));
2026 		break;
2027 	case CTRL_CTS:
2028 		ND_PRINT("RA:%s ",
2029 		    GET_ETHERADDR_STRING(((const struct ctrl_cts_hdr_t *)p)->ra));
2030 		break;
2031 	case CTRL_ACK:
2032 		ND_PRINT("RA:%s ",
2033 		    GET_ETHERADDR_STRING(((const struct ctrl_ack_hdr_t *)p)->ra));
2034 		break;
2035 	case CTRL_CF_END:
2036 		ND_PRINT("RA:%s BSSID:%s ",
2037 		    GET_ETHERADDR_STRING(((const struct ctrl_end_hdr_t *)p)->ra),
2038 		    GET_ETHERADDR_STRING(((const struct ctrl_end_hdr_t *)p)->bssid));
2039 		break;
2040 	case CTRL_END_ACK:
2041 		ND_PRINT("RA:%s BSSID:%s ",
2042 		    GET_ETHERADDR_STRING(((const struct ctrl_end_ack_hdr_t *)p)->ra),
2043 		    GET_ETHERADDR_STRING(((const struct ctrl_end_ack_hdr_t *)p)->bssid));
2044 		break;
2045 	default:
2046 		/* We shouldn't get here - we should already have quit */
2047 		break;
2048 	}
2049 }
2050 
2051 static int
extract_header_length(netdissect_options * ndo,uint16_t fc)2052 extract_header_length(netdissect_options *ndo,
2053 		      uint16_t fc)
2054 {
2055 	int len;
2056 
2057 	switch (FC_TYPE(fc)) {
2058 	case T_MGMT:
2059 		return MGMT_HDRLEN;
2060 	case T_CTRL:
2061 		switch (FC_SUBTYPE(fc)) {
2062 		case CTRL_CONTROL_WRAPPER:
2063 			return CTRL_CONTROL_WRAPPER_HDRLEN;
2064 		case CTRL_BAR:
2065 			return CTRL_BAR_HDRLEN;
2066 		case CTRL_BA:
2067 			return CTRL_BA_HDRLEN;
2068 		case CTRL_PS_POLL:
2069 			return CTRL_PS_POLL_HDRLEN;
2070 		case CTRL_RTS:
2071 			return CTRL_RTS_HDRLEN;
2072 		case CTRL_CTS:
2073 			return CTRL_CTS_HDRLEN;
2074 		case CTRL_ACK:
2075 			return CTRL_ACK_HDRLEN;
2076 		case CTRL_CF_END:
2077 			return CTRL_END_HDRLEN;
2078 		case CTRL_END_ACK:
2079 			return CTRL_END_ACK_HDRLEN;
2080 		default:
2081 			ND_PRINT("unknown 802.11 ctrl frame subtype (%u)", FC_SUBTYPE(fc));
2082 			return 0;
2083 		}
2084 	case T_DATA:
2085 		len = (FC_TO_DS(fc) && FC_FROM_DS(fc)) ? 30 : 24;
2086 		if (DATA_FRAME_IS_QOS(FC_SUBTYPE(fc)))
2087 			len += 2;
2088 		return len;
2089 	default:
2090 		ND_PRINT("unknown 802.11 frame type (%u)", FC_TYPE(fc));
2091 		return 0;
2092 	}
2093 }
2094 
2095 static int
extract_mesh_header_length(netdissect_options * ndo,const u_char * p)2096 extract_mesh_header_length(netdissect_options *ndo, const u_char *p)
2097 {
2098 	return (GET_U_1(p) &~ 3) ? 0 : 6*(1 + (GET_U_1(p) & 3));
2099 }
2100 
2101 /*
2102  * Print the 802.11 MAC header.
2103  */
2104 static void
ieee_802_11_hdr_print(netdissect_options * ndo,uint16_t fc,const u_char * p,u_int hdrlen,u_int meshdrlen)2105 ieee_802_11_hdr_print(netdissect_options *ndo,
2106 		      uint16_t fc, const u_char *p, u_int hdrlen,
2107 		      u_int meshdrlen)
2108 {
2109 	if (ndo->ndo_vflag) {
2110 		if (FC_MORE_DATA(fc))
2111 			ND_PRINT("More Data ");
2112 		if (FC_MORE_FLAG(fc))
2113 			ND_PRINT("More Fragments ");
2114 		if (FC_POWER_MGMT(fc))
2115 			ND_PRINT("Pwr Mgmt ");
2116 		if (FC_RETRY(fc))
2117 			ND_PRINT("Retry ");
2118 		if (FC_ORDER(fc))
2119 			ND_PRINT("Strictly Ordered ");
2120 		if (FC_PROTECTED(fc))
2121 			ND_PRINT("Protected ");
2122 		if (FC_TYPE(fc) != T_CTRL || FC_SUBTYPE(fc) != CTRL_PS_POLL)
2123 			ND_PRINT("%uus ",
2124 			    GET_LE_U_2(((const struct mgmt_header_t *)p)->duration));
2125 	}
2126 	if (meshdrlen != 0) {
2127 		const struct meshcntl_t *mc =
2128 		    (const struct meshcntl_t *)(p + hdrlen - meshdrlen);
2129 		u_int ae = GET_U_1(mc->flags) & 3;
2130 
2131 		ND_PRINT("MeshData (AE %u TTL %u seq %u", ae,
2132 		    GET_U_1(mc->ttl), GET_LE_U_4(mc->seq));
2133 		if (ae > 0)
2134 			ND_PRINT(" A4:%s", GET_ETHERADDR_STRING(mc->addr4));
2135 		if (ae > 1)
2136 			ND_PRINT(" A5:%s", GET_ETHERADDR_STRING(mc->addr5));
2137 		if (ae > 2)
2138 			ND_PRINT(" A6:%s", GET_ETHERADDR_STRING(mc->addr6));
2139 		ND_PRINT(") ");
2140 	}
2141 
2142 	switch (FC_TYPE(fc)) {
2143 	case T_MGMT:
2144 		mgmt_header_print(ndo, p);
2145 		break;
2146 	case T_CTRL:
2147 		ctrl_header_print(ndo, fc, p);
2148 		break;
2149 	case T_DATA:
2150 		data_header_print(ndo, fc, p);
2151 		break;
2152 	default:
2153 		break;
2154 	}
2155 }
2156 
2157 static u_int
ieee802_11_print(netdissect_options * ndo,const u_char * p,u_int length,u_int orig_caplen,int pad,u_int fcslen)2158 ieee802_11_print(netdissect_options *ndo,
2159 		 const u_char *p, u_int length, u_int orig_caplen, int pad,
2160 		 u_int fcslen)
2161 {
2162 	uint16_t fc;
2163 	u_int caplen, hdrlen, meshdrlen;
2164 	struct lladdr_info src, dst;
2165 	int llc_hdrlen;
2166 
2167 	ndo->ndo_protocol = "802.11";
2168 	caplen = orig_caplen;
2169 	/* Remove FCS, if present */
2170 	if (length < fcslen) {
2171 		nd_print_trunc(ndo);
2172 		return caplen;
2173 	}
2174 	length -= fcslen;
2175 	if (caplen > length) {
2176 		/* Amount of FCS in actual packet data, if any */
2177 		fcslen = caplen - length;
2178 		caplen -= fcslen;
2179 		ndo->ndo_snapend -= fcslen;
2180 	}
2181 
2182 	if (caplen < IEEE802_11_FC_LEN) {
2183 		nd_print_trunc(ndo);
2184 		return orig_caplen;
2185 	}
2186 
2187 	fc = GET_LE_U_2(p);
2188 	hdrlen = extract_header_length(ndo, fc);
2189 	if (hdrlen == 0) {
2190 		/* Unknown frame type or control frame subtype; quit. */
2191 		return (0);
2192 	}
2193 	if (pad)
2194 		hdrlen = roundup2(hdrlen, 4);
2195 	if (ndo->ndo_Hflag && FC_TYPE(fc) == T_DATA &&
2196 	    DATA_FRAME_IS_QOS(FC_SUBTYPE(fc))) {
2197 		if(!ND_TTEST_1(p + hdrlen)) {
2198 			nd_print_trunc(ndo);
2199 			return hdrlen;
2200 		}
2201 		meshdrlen = extract_mesh_header_length(ndo, p + hdrlen);
2202 		hdrlen += meshdrlen;
2203 	} else
2204 		meshdrlen = 0;
2205 
2206 	if (caplen < hdrlen) {
2207 		nd_print_trunc(ndo);
2208 		return hdrlen;
2209 	}
2210 
2211 	if (ndo->ndo_eflag)
2212 		ieee_802_11_hdr_print(ndo, fc, p, hdrlen, meshdrlen);
2213 
2214 	/*
2215 	 * Go past the 802.11 header.
2216 	 */
2217 	length -= hdrlen;
2218 	caplen -= hdrlen;
2219 	p += hdrlen;
2220 
2221 	src.addr_string = etheraddr_string;
2222 	dst.addr_string = etheraddr_string;
2223 	switch (FC_TYPE(fc)) {
2224 	case T_MGMT:
2225 		get_mgmt_src_dst_mac(p - hdrlen, &src.addr, &dst.addr);
2226 		if (!mgmt_body_print(ndo, fc, src.addr, p, length)) {
2227 			nd_print_trunc(ndo);
2228 			return hdrlen;
2229 		}
2230 		break;
2231 	case T_CTRL:
2232 		if (!ctrl_body_print(ndo, fc, p - hdrlen)) {
2233 			nd_print_trunc(ndo);
2234 			return hdrlen;
2235 		}
2236 		break;
2237 	case T_DATA:
2238 		if (DATA_FRAME_IS_NULL(FC_SUBTYPE(fc)))
2239 			return hdrlen;	/* no-data frame */
2240 		/* There may be a problem w/ AP not having this bit set */
2241 		if (FC_PROTECTED(fc)) {
2242 			ND_PRINT("Data");
2243 			if (!wep_print(ndo, p)) {
2244 				nd_print_trunc(ndo);
2245 				return hdrlen;
2246 			}
2247 		} else {
2248 			get_data_src_dst_mac(fc, p - hdrlen, &src.addr, &dst.addr);
2249 			llc_hdrlen = llc_print(ndo, p, length, caplen, &src, &dst);
2250 			if (llc_hdrlen < 0) {
2251 				/*
2252 				 * Some kinds of LLC packet we cannot
2253 				 * handle intelligently
2254 				 */
2255 				if (!ndo->ndo_suppress_default_print)
2256 					ND_DEFAULTPRINT(p, caplen);
2257 				llc_hdrlen = -llc_hdrlen;
2258 			}
2259 			hdrlen += llc_hdrlen;
2260 		}
2261 		break;
2262 	default:
2263 		/* We shouldn't get here - we should already have quit */
2264 		break;
2265 	}
2266 
2267 	return hdrlen;
2268 }
2269 
2270 /*
2271  * This is the top level routine of the printer.  'p' points
2272  * to the 802.11 header of the packet, 'h->ts' is the timestamp,
2273  * 'h->len' is the length of the packet off the wire, and 'h->caplen'
2274  * is the number of bytes actually captured.
2275  */
2276 void
ieee802_11_if_print(netdissect_options * ndo,const struct pcap_pkthdr * h,const u_char * p)2277 ieee802_11_if_print(netdissect_options *ndo,
2278 		    const struct pcap_pkthdr *h, const u_char *p)
2279 {
2280 	ndo->ndo_protocol = "802.11";
2281 	ndo->ndo_ll_hdr_len += ieee802_11_print(ndo, p, h->len, h->caplen, 0, 0);
2282 }
2283 
2284 
2285 /* $FreeBSD: projects/clang400-import/contrib/tcpdump/print-802_11.c 276788 2015-01-07 19:55:18Z delphij $ */
2286 /* NetBSD: ieee802_11_radio.h,v 1.2 2006/02/26 03:04:03 dyoung Exp  */
2287 
2288 /*-
2289  * Copyright (c) 2003, 2004 David Young.  All rights reserved.
2290  *
2291  * Redistribution and use in source and binary forms, with or without
2292  * modification, are permitted provided that the following conditions
2293  * are met:
2294  * 1. Redistributions of source code must retain the above copyright
2295  *    notice, this list of conditions and the following disclaimer.
2296  * 2. Redistributions in binary form must reproduce the above copyright
2297  *    notice, this list of conditions and the following disclaimer in the
2298  *    documentation and/or other materials provided with the distribution.
2299  * 3. The name of David Young may not be used to endorse or promote
2300  *    products derived from this software without specific prior
2301  *    written permission.
2302  *
2303  * THIS SOFTWARE IS PROVIDED BY DAVID YOUNG ``AS IS'' AND ANY
2304  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
2305  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
2306  * PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL DAVID
2307  * YOUNG BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
2308  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
2309  * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2310  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
2311  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
2312  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2313  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
2314  * OF SUCH DAMAGE.
2315  */
2316 
2317 /* A generic radio capture format is desirable. It must be
2318  * rigidly defined (e.g., units for fields should be given),
2319  * and easily extensible.
2320  *
2321  * The following is an extensible radio capture format. It is
2322  * based on a bitmap indicating which fields are present.
2323  *
2324  * I am trying to describe precisely what the application programmer
2325  * should expect in the following, and for that reason I tell the
2326  * units and origin of each measurement (where it applies), or else I
2327  * use sufficiently weaselly language ("is a monotonically nondecreasing
2328  * function of...") that I cannot set false expectations for lawyerly
2329  * readers.
2330  */
2331 
2332 /*
2333  * The radio capture header precedes the 802.11 header.
2334  *
2335  * Note well: all radiotap fields are little-endian.
2336  */
2337 struct ieee80211_radiotap_header {
2338 	nd_uint8_t	it_version;	/* Version 0. Only increases
2339 					 * for drastic changes,
2340 					 * introduction of compatible
2341 					 * new fields does not count.
2342 					 */
2343 	nd_uint8_t	it_pad;
2344 	nd_uint16_t	it_len;		/* length of the whole
2345 					 * header in bytes, including
2346 					 * it_version, it_pad,
2347 					 * it_len, and data fields.
2348 					 */
2349 	nd_uint32_t	it_present;	/* A bitmap telling which
2350 					 * fields are present. Set bit 31
2351 					 * (0x80000000) to extend the
2352 					 * bitmap by another 32 bits.
2353 					 * Additional extensions are made
2354 					 * by setting bit 31.
2355 					 */
2356 };
2357 
2358 /* Name                                 Data type       Units
2359  * ----                                 ---------       -----
2360  *
2361  * IEEE80211_RADIOTAP_TSFT              uint64_t       microseconds
2362  *
2363  *      Value in microseconds of the MAC's 64-bit 802.11 Time
2364  *      Synchronization Function timer when the first bit of the
2365  *      MPDU arrived at the MAC. For received frames, only.
2366  *
2367  * IEEE80211_RADIOTAP_CHANNEL           2 x uint16_t   MHz, bitmap
2368  *
2369  *      Tx/Rx frequency in MHz, followed by flags (see below).
2370  *	Note that IEEE80211_RADIOTAP_XCHANNEL must be used to
2371  *	represent an HT channel as there is not enough room in
2372  *	the flags word.
2373  *
2374  * IEEE80211_RADIOTAP_FHSS              uint16_t       see below
2375  *
2376  *      For frequency-hopping radios, the hop set (first byte)
2377  *      and pattern (second byte).
2378  *
2379  * IEEE80211_RADIOTAP_RATE              uint8_t        500kb/s or index
2380  *
2381  *      Tx/Rx data rate.  If bit 0x80 is set then it represents an
2382  *	an MCS index and not an IEEE rate.
2383  *
2384  * IEEE80211_RADIOTAP_DBM_ANTSIGNAL     int8_t         decibels from
2385  *                                                     one milliwatt (dBm)
2386  *
2387  *      RF signal power at the antenna, decibel difference from
2388  *      one milliwatt.
2389  *
2390  * IEEE80211_RADIOTAP_DBM_ANTNOISE      int8_t         decibels from
2391  *                                                     one milliwatt (dBm)
2392  *
2393  *      RF noise power at the antenna, decibel difference from one
2394  *      milliwatt.
2395  *
2396  * IEEE80211_RADIOTAP_DB_ANTSIGNAL      uint8_t        decibel (dB)
2397  *
2398  *      RF signal power at the antenna, decibel difference from an
2399  *      arbitrary, fixed reference.
2400  *
2401  * IEEE80211_RADIOTAP_DB_ANTNOISE       uint8_t        decibel (dB)
2402  *
2403  *      RF noise power at the antenna, decibel difference from an
2404  *      arbitrary, fixed reference point.
2405  *
2406  * IEEE80211_RADIOTAP_LOCK_QUALITY      uint16_t       unitless
2407  *
2408  *      Quality of Barker code lock. Unitless. Monotonically
2409  *      nondecreasing with "better" lock strength. Called "Signal
2410  *      Quality" in datasheets.  (Is there a standard way to measure
2411  *      this?)
2412  *
2413  * IEEE80211_RADIOTAP_TX_ATTENUATION    uint16_t       unitless
2414  *
2415  *      Transmit power expressed as unitless distance from max
2416  *      power set at factory calibration.  0 is max power.
2417  *      Monotonically nondecreasing with lower power levels.
2418  *
2419  * IEEE80211_RADIOTAP_DB_TX_ATTENUATION uint16_t       decibels (dB)
2420  *
2421  *      Transmit power expressed as decibel distance from max power
2422  *      set at factory calibration.  0 is max power.  Monotonically
2423  *      nondecreasing with lower power levels.
2424  *
2425  * IEEE80211_RADIOTAP_DBM_TX_POWER      int8_t         decibels from
2426  *                                                     one milliwatt (dBm)
2427  *
2428  *      Transmit power expressed as dBm (decibels from a 1 milliwatt
2429  *      reference). This is the absolute power level measured at
2430  *      the antenna port.
2431  *
2432  * IEEE80211_RADIOTAP_FLAGS             uint8_t        bitmap
2433  *
2434  *      Properties of transmitted and received frames. See flags
2435  *      defined below.
2436  *
2437  * IEEE80211_RADIOTAP_ANTENNA           uint8_t        antenna index
2438  *
2439  *      Unitless indication of the Rx/Tx antenna for this packet.
2440  *      The first antenna is antenna 0.
2441  *
2442  * IEEE80211_RADIOTAP_RX_FLAGS          uint16_t       bitmap
2443  *
2444  *     Properties of received frames. See flags defined below.
2445  *
2446  * IEEE80211_RADIOTAP_XCHANNEL          uint32_t       bitmap
2447  *					uint16_t       MHz
2448  *					uint8_t        channel number
2449  *					uint8_t        .5 dBm
2450  *
2451  *	Extended channel specification: flags (see below) followed by
2452  *	frequency in MHz, the corresponding IEEE channel number, and
2453  *	finally the maximum regulatory transmit power cap in .5 dBm
2454  *	units.  This property supersedes IEEE80211_RADIOTAP_CHANNEL
2455  *	and only one of the two should be present.
2456  *
2457  * IEEE80211_RADIOTAP_MCS		uint8_t        known
2458  *					uint8_t        flags
2459  *					uint8_t        mcs
2460  *
2461  *	Bitset indicating which fields have known values, followed
2462  *	by bitset of flag values, followed by the MCS rate index as
2463  *	in IEEE 802.11n.
2464  *
2465  *
2466  * IEEE80211_RADIOTAP_AMPDU_STATUS	u32, u16, u8, u8	unitless
2467  *
2468  *	Contains the AMPDU information for the subframe.
2469  *
2470  * IEEE80211_RADIOTAP_VHT	u16, u8, u8, u8[4], u8, u8, u16
2471  *
2472  *	Contains VHT information about this frame.
2473  *
2474  * IEEE80211_RADIOTAP_VENDOR_NAMESPACE
2475  *					uint8_t  OUI[3]
2476  *                                      uint8_t        subspace
2477  *                                      uint16_t       length
2478  *
2479  *     The Vendor Namespace Field contains three sub-fields. The first
2480  *     sub-field is 3 bytes long. It contains the vendor's IEEE 802
2481  *     Organizationally Unique Identifier (OUI). The fourth byte is a
2482  *     vendor-specific "namespace selector."
2483  *
2484  */
2485 enum ieee80211_radiotap_type {
2486 	IEEE80211_RADIOTAP_TSFT = 0,
2487 	IEEE80211_RADIOTAP_FLAGS = 1,
2488 	IEEE80211_RADIOTAP_RATE = 2,
2489 	IEEE80211_RADIOTAP_CHANNEL = 3,
2490 	IEEE80211_RADIOTAP_FHSS = 4,
2491 	IEEE80211_RADIOTAP_DBM_ANTSIGNAL = 5,
2492 	IEEE80211_RADIOTAP_DBM_ANTNOISE = 6,
2493 	IEEE80211_RADIOTAP_LOCK_QUALITY = 7,
2494 	IEEE80211_RADIOTAP_TX_ATTENUATION = 8,
2495 	IEEE80211_RADIOTAP_DB_TX_ATTENUATION = 9,
2496 	IEEE80211_RADIOTAP_DBM_TX_POWER = 10,
2497 	IEEE80211_RADIOTAP_ANTENNA = 11,
2498 	IEEE80211_RADIOTAP_DB_ANTSIGNAL = 12,
2499 	IEEE80211_RADIOTAP_DB_ANTNOISE = 13,
2500 	IEEE80211_RADIOTAP_RX_FLAGS = 14,
2501 	/* NB: gap for netbsd definitions */
2502 	IEEE80211_RADIOTAP_XCHANNEL = 18,
2503 	IEEE80211_RADIOTAP_MCS = 19,
2504 	IEEE80211_RADIOTAP_AMPDU_STATUS = 20,
2505 	IEEE80211_RADIOTAP_VHT = 21,
2506 	IEEE80211_RADIOTAP_NAMESPACE = 29,
2507 	IEEE80211_RADIOTAP_VENDOR_NAMESPACE = 30,
2508 	IEEE80211_RADIOTAP_EXT = 31
2509 };
2510 
2511 /* channel attributes */
2512 #define	IEEE80211_CHAN_TURBO	0x00010	/* Turbo channel */
2513 #define	IEEE80211_CHAN_CCK	0x00020	/* CCK channel */
2514 #define	IEEE80211_CHAN_OFDM	0x00040	/* OFDM channel */
2515 #define	IEEE80211_CHAN_2GHZ	0x00080	/* 2 GHz spectrum channel. */
2516 #define	IEEE80211_CHAN_5GHZ	0x00100	/* 5 GHz spectrum channel */
2517 #define	IEEE80211_CHAN_PASSIVE	0x00200	/* Only passive scan allowed */
2518 #define	IEEE80211_CHAN_DYN	0x00400	/* Dynamic CCK-OFDM channel */
2519 #define	IEEE80211_CHAN_GFSK	0x00800	/* GFSK channel (FHSS PHY) */
2520 #define	IEEE80211_CHAN_GSM	0x01000	/* 900 MHz spectrum channel */
2521 #define	IEEE80211_CHAN_STURBO	0x02000	/* 11a static turbo channel only */
2522 #define	IEEE80211_CHAN_HALF	0x04000	/* Half rate channel */
2523 #define	IEEE80211_CHAN_QUARTER	0x08000	/* Quarter rate channel */
2524 #define	IEEE80211_CHAN_HT20	0x10000	/* HT 20 channel */
2525 #define	IEEE80211_CHAN_HT40U	0x20000	/* HT 40 channel w/ ext above */
2526 #define	IEEE80211_CHAN_HT40D	0x40000	/* HT 40 channel w/ ext below */
2527 
2528 /* Useful combinations of channel characteristics, borrowed from Ethereal */
2529 #define IEEE80211_CHAN_A \
2530 	(IEEE80211_CHAN_5GHZ | IEEE80211_CHAN_OFDM)
2531 #define IEEE80211_CHAN_B \
2532 	(IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_CCK)
2533 #define IEEE80211_CHAN_G \
2534 	(IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_DYN)
2535 #define IEEE80211_CHAN_TA \
2536 	(IEEE80211_CHAN_5GHZ | IEEE80211_CHAN_OFDM | IEEE80211_CHAN_TURBO)
2537 #define IEEE80211_CHAN_TG \
2538 	(IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_DYN  | IEEE80211_CHAN_TURBO)
2539 
2540 
2541 /* For IEEE80211_RADIOTAP_FLAGS */
2542 #define	IEEE80211_RADIOTAP_F_CFP	0x01	/* sent/received
2543 						 * during CFP
2544 						 */
2545 #define	IEEE80211_RADIOTAP_F_SHORTPRE	0x02	/* sent/received
2546 						 * with short
2547 						 * preamble
2548 						 */
2549 #define	IEEE80211_RADIOTAP_F_WEP	0x04	/* sent/received
2550 						 * with WEP encryption
2551 						 */
2552 #define	IEEE80211_RADIOTAP_F_FRAG	0x08	/* sent/received
2553 						 * with fragmentation
2554 						 */
2555 #define	IEEE80211_RADIOTAP_F_FCS	0x10	/* frame includes FCS */
2556 #define	IEEE80211_RADIOTAP_F_DATAPAD	0x20	/* frame has padding between
2557 						 * 802.11 header and payload
2558 						 * (to 32-bit boundary)
2559 						 */
2560 #define	IEEE80211_RADIOTAP_F_BADFCS	0x40	/* does not pass FCS check */
2561 
2562 /* For IEEE80211_RADIOTAP_RX_FLAGS */
2563 #define IEEE80211_RADIOTAP_F_RX_BADFCS	0x0001	/* frame failed crc check */
2564 #define IEEE80211_RADIOTAP_F_RX_PLCP_CRC	0x0002	/* frame failed PLCP CRC check */
2565 
2566 /* For IEEE80211_RADIOTAP_MCS known */
2567 #define IEEE80211_RADIOTAP_MCS_BANDWIDTH_KNOWN		0x01
2568 #define IEEE80211_RADIOTAP_MCS_MCS_INDEX_KNOWN		0x02	/* MCS index field */
2569 #define IEEE80211_RADIOTAP_MCS_GUARD_INTERVAL_KNOWN	0x04
2570 #define IEEE80211_RADIOTAP_MCS_HT_FORMAT_KNOWN		0x08
2571 #define IEEE80211_RADIOTAP_MCS_FEC_TYPE_KNOWN		0x10
2572 #define IEEE80211_RADIOTAP_MCS_STBC_KNOWN		0x20
2573 #define IEEE80211_RADIOTAP_MCS_NESS_KNOWN		0x40
2574 #define IEEE80211_RADIOTAP_MCS_NESS_BIT_1		0x80
2575 
2576 /* For IEEE80211_RADIOTAP_MCS flags */
2577 #define IEEE80211_RADIOTAP_MCS_BANDWIDTH_MASK	0x03
2578 #define IEEE80211_RADIOTAP_MCS_BANDWIDTH_20	0
2579 #define IEEE80211_RADIOTAP_MCS_BANDWIDTH_40	1
2580 #define IEEE80211_RADIOTAP_MCS_BANDWIDTH_20L	2
2581 #define IEEE80211_RADIOTAP_MCS_BANDWIDTH_20U	3
2582 #define IEEE80211_RADIOTAP_MCS_SHORT_GI		0x04 /* short guard interval */
2583 #define IEEE80211_RADIOTAP_MCS_HT_GREENFIELD	0x08
2584 #define IEEE80211_RADIOTAP_MCS_FEC_LDPC		0x10
2585 #define IEEE80211_RADIOTAP_MCS_STBC_MASK	0x60
2586 #define		IEEE80211_RADIOTAP_MCS_STBC_1	1
2587 #define		IEEE80211_RADIOTAP_MCS_STBC_2	2
2588 #define		IEEE80211_RADIOTAP_MCS_STBC_3	3
2589 #define IEEE80211_RADIOTAP_MCS_STBC_SHIFT	5
2590 #define IEEE80211_RADIOTAP_MCS_NESS_BIT_0	0x80
2591 
2592 /* For IEEE80211_RADIOTAP_AMPDU_STATUS */
2593 #define IEEE80211_RADIOTAP_AMPDU_REPORT_ZEROLEN		0x0001
2594 #define IEEE80211_RADIOTAP_AMPDU_IS_ZEROLEN		0x0002
2595 #define IEEE80211_RADIOTAP_AMPDU_LAST_KNOWN		0x0004
2596 #define IEEE80211_RADIOTAP_AMPDU_IS_LAST		0x0008
2597 #define IEEE80211_RADIOTAP_AMPDU_DELIM_CRC_ERR		0x0010
2598 #define IEEE80211_RADIOTAP_AMPDU_DELIM_CRC_KNOWN	0x0020
2599 
2600 /* For IEEE80211_RADIOTAP_VHT known */
2601 #define IEEE80211_RADIOTAP_VHT_STBC_KNOWN			0x0001
2602 #define IEEE80211_RADIOTAP_VHT_TXOP_PS_NA_KNOWN			0x0002
2603 #define IEEE80211_RADIOTAP_VHT_GUARD_INTERVAL_KNOWN		0x0004
2604 #define IEEE80211_RADIOTAP_VHT_SGI_NSYM_DIS_KNOWN		0x0008
2605 #define IEEE80211_RADIOTAP_VHT_LDPC_EXTRA_OFDM_SYM_KNOWN	0x0010
2606 #define IEEE80211_RADIOTAP_VHT_BEAMFORMED_KNOWN			0x0020
2607 #define IEEE80211_RADIOTAP_VHT_BANDWIDTH_KNOWN			0x0040
2608 #define IEEE80211_RADIOTAP_VHT_GROUP_ID_KNOWN			0x0080
2609 #define IEEE80211_RADIOTAP_VHT_PARTIAL_AID_KNOWN		0x0100
2610 
2611 /* For IEEE80211_RADIOTAP_VHT flags */
2612 #define IEEE80211_RADIOTAP_VHT_STBC			0x01
2613 #define IEEE80211_RADIOTAP_VHT_TXOP_PS_NA		0x02
2614 #define IEEE80211_RADIOTAP_VHT_SHORT_GI			0x04
2615 #define IEEE80211_RADIOTAP_VHT_SGI_NSYM_M10_9		0x08
2616 #define IEEE80211_RADIOTAP_VHT_LDPC_EXTRA_OFDM_SYM	0x10
2617 #define IEEE80211_RADIOTAP_VHT_BEAMFORMED		0x20
2618 
2619 #define IEEE80211_RADIOTAP_VHT_BANDWIDTH_MASK	0x1f
2620 
2621 #define IEEE80211_RADIOTAP_VHT_NSS_MASK		0x0f
2622 #define IEEE80211_RADIOTAP_VHT_MCS_MASK		0xf0
2623 #define IEEE80211_RADIOTAP_VHT_MCS_SHIFT	4
2624 
2625 #define IEEE80211_RADIOTAP_CODING_LDPC_USERn			0x01
2626 
2627 #define	IEEE80211_CHAN_FHSS \
2628 	(IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_GFSK)
2629 #define	IEEE80211_CHAN_A \
2630 	(IEEE80211_CHAN_5GHZ | IEEE80211_CHAN_OFDM)
2631 #define	IEEE80211_CHAN_B \
2632 	(IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_CCK)
2633 #define	IEEE80211_CHAN_PUREG \
2634 	(IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_OFDM)
2635 #define	IEEE80211_CHAN_G \
2636 	(IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_DYN)
2637 
2638 #define	IS_CHAN_FHSS(flags) \
2639 	((flags & IEEE80211_CHAN_FHSS) == IEEE80211_CHAN_FHSS)
2640 #define	IS_CHAN_A(flags) \
2641 	((flags & IEEE80211_CHAN_A) == IEEE80211_CHAN_A)
2642 #define	IS_CHAN_B(flags) \
2643 	((flags & IEEE80211_CHAN_B) == IEEE80211_CHAN_B)
2644 #define	IS_CHAN_PUREG(flags) \
2645 	((flags & IEEE80211_CHAN_PUREG) == IEEE80211_CHAN_PUREG)
2646 #define	IS_CHAN_G(flags) \
2647 	((flags & IEEE80211_CHAN_G) == IEEE80211_CHAN_G)
2648 #define	IS_CHAN_ANYG(flags) \
2649 	(IS_CHAN_PUREG(flags) || IS_CHAN_G(flags))
2650 
2651 static void
print_chaninfo(netdissect_options * ndo,uint16_t freq,uint32_t flags,uint32_t presentflags)2652 print_chaninfo(netdissect_options *ndo,
2653 	       uint16_t freq, uint32_t flags, uint32_t presentflags)
2654 {
2655 	ND_PRINT("%u MHz", freq);
2656 	if (presentflags & (1 << IEEE80211_RADIOTAP_MCS)) {
2657 		/*
2658 		 * We have the MCS field, so this is 11n, regardless
2659 		 * of what the channel flags say.
2660 		 */
2661 		ND_PRINT(" 11n");
2662 	} else {
2663 		if (IS_CHAN_FHSS(flags))
2664 			ND_PRINT(" FHSS");
2665 		if (IS_CHAN_A(flags)) {
2666 			if (flags & IEEE80211_CHAN_HALF)
2667 				ND_PRINT(" 11a/10Mhz");
2668 			else if (flags & IEEE80211_CHAN_QUARTER)
2669 				ND_PRINT(" 11a/5Mhz");
2670 			else
2671 				ND_PRINT(" 11a");
2672 		}
2673 		if (IS_CHAN_ANYG(flags)) {
2674 			if (flags & IEEE80211_CHAN_HALF)
2675 				ND_PRINT(" 11g/10Mhz");
2676 			else if (flags & IEEE80211_CHAN_QUARTER)
2677 				ND_PRINT(" 11g/5Mhz");
2678 			else
2679 				ND_PRINT(" 11g");
2680 		} else if (IS_CHAN_B(flags))
2681 			ND_PRINT(" 11b");
2682 		if (flags & IEEE80211_CHAN_TURBO)
2683 			ND_PRINT(" Turbo");
2684 	}
2685 	/*
2686 	 * These apply to 11n.
2687 	 */
2688 	if (flags & IEEE80211_CHAN_HT20)
2689 		ND_PRINT(" ht/20");
2690 	else if (flags & IEEE80211_CHAN_HT40D)
2691 		ND_PRINT(" ht/40-");
2692 	else if (flags & IEEE80211_CHAN_HT40U)
2693 		ND_PRINT(" ht/40+");
2694 	ND_PRINT(" ");
2695 }
2696 
2697 static int
print_radiotap_field(netdissect_options * ndo,struct cpack_state * s,uint32_t bit,uint8_t * flagsp,uint32_t presentflags)2698 print_radiotap_field(netdissect_options *ndo,
2699 		     struct cpack_state *s, uint32_t bit, uint8_t *flagsp,
2700 		     uint32_t presentflags)
2701 {
2702 	u_int i;
2703 	int rc;
2704 
2705 	switch (bit) {
2706 
2707 	case IEEE80211_RADIOTAP_TSFT: {
2708 		uint64_t tsft;
2709 
2710 		rc = nd_cpack_uint64(ndo, s, &tsft);
2711 		if (rc != 0)
2712 			goto trunc;
2713 		ND_PRINT("%" PRIu64 "us tsft ", tsft);
2714 		break;
2715 		}
2716 
2717 	case IEEE80211_RADIOTAP_FLAGS: {
2718 		uint8_t flagsval;
2719 
2720 		rc = nd_cpack_uint8(ndo, s, &flagsval);
2721 		if (rc != 0)
2722 			goto trunc;
2723 		*flagsp = flagsval;
2724 		if (flagsval & IEEE80211_RADIOTAP_F_CFP)
2725 			ND_PRINT("cfp ");
2726 		if (flagsval & IEEE80211_RADIOTAP_F_SHORTPRE)
2727 			ND_PRINT("short preamble ");
2728 		if (flagsval & IEEE80211_RADIOTAP_F_WEP)
2729 			ND_PRINT("wep ");
2730 		if (flagsval & IEEE80211_RADIOTAP_F_FRAG)
2731 			ND_PRINT("fragmented ");
2732 		if (flagsval & IEEE80211_RADIOTAP_F_BADFCS)
2733 			ND_PRINT("bad-fcs ");
2734 		break;
2735 		}
2736 
2737 	case IEEE80211_RADIOTAP_RATE: {
2738 		uint8_t rate;
2739 
2740 		rc = nd_cpack_uint8(ndo, s, &rate);
2741 		if (rc != 0)
2742 			goto trunc;
2743 		/*
2744 		 * XXX On FreeBSD rate & 0x80 means we have an MCS. On
2745 		 * Linux and AirPcap it does not.  (What about
2746 		 * macOS, NetBSD, OpenBSD, and DragonFly BSD?)
2747 		 *
2748 		 * This is an issue either for proprietary extensions
2749 		 * to 11a or 11g, which do exist, or for 11n
2750 		 * implementations that stuff a rate value into
2751 		 * this field, which also appear to exist.
2752 		 *
2753 		 * We currently handle that by assuming that
2754 		 * if the 0x80 bit is set *and* the remaining
2755 		 * bits have a value between 0 and 15 it's
2756 		 * an MCS value, otherwise it's a rate.  If
2757 		 * there are cases where systems that use
2758 		 * "0x80 + MCS index" for MCS indices > 15,
2759 		 * or stuff a rate value here between 64 and
2760 		 * 71.5 Mb/s in here, we'll need a preference
2761 		 * setting.  Such rates do exist, e.g. 11n
2762 		 * MCS 7 at 20 MHz with a long guard interval.
2763 		 */
2764 		if (rate >= 0x80 && rate <= 0x8f) {
2765 			/*
2766 			 * XXX - we don't know the channel width
2767 			 * or guard interval length, so we can't
2768 			 * convert this to a data rate.
2769 			 *
2770 			 * If you want us to show a data rate,
2771 			 * use the MCS field, not the Rate field;
2772 			 * the MCS field includes not only the
2773 			 * MCS index, it also includes bandwidth
2774 			 * and guard interval information.
2775 			 *
2776 			 * XXX - can we get the channel width
2777 			 * from XChannel and the guard interval
2778 			 * information from Flags, at least on
2779 			 * FreeBSD?
2780 			 */
2781 			ND_PRINT("MCS %u ", rate & 0x7f);
2782 		} else
2783 			ND_PRINT("%2.1f Mb/s ", .5 * rate);
2784 		break;
2785 		}
2786 
2787 	case IEEE80211_RADIOTAP_CHANNEL: {
2788 		uint16_t frequency;
2789 		uint16_t flags;
2790 
2791 		rc = nd_cpack_uint16(ndo, s, &frequency);
2792 		if (rc != 0)
2793 			goto trunc;
2794 		rc = nd_cpack_uint16(ndo, s, &flags);
2795 		if (rc != 0)
2796 			goto trunc;
2797 		/*
2798 		 * If CHANNEL and XCHANNEL are both present, skip
2799 		 * CHANNEL.
2800 		 */
2801 		if (presentflags & (1 << IEEE80211_RADIOTAP_XCHANNEL))
2802 			break;
2803 		print_chaninfo(ndo, frequency, flags, presentflags);
2804 		break;
2805 		}
2806 
2807 	case IEEE80211_RADIOTAP_FHSS: {
2808 		uint8_t hopset;
2809 		uint8_t hoppat;
2810 
2811 		rc = nd_cpack_uint8(ndo, s, &hopset);
2812 		if (rc != 0)
2813 			goto trunc;
2814 		rc = nd_cpack_uint8(ndo, s, &hoppat);
2815 		if (rc != 0)
2816 			goto trunc;
2817 		ND_PRINT("fhset %u fhpat %u ", hopset, hoppat);
2818 		break;
2819 		}
2820 
2821 	case IEEE80211_RADIOTAP_DBM_ANTSIGNAL: {
2822 		int8_t dbm_antsignal;
2823 
2824 		rc = nd_cpack_int8(ndo, s, &dbm_antsignal);
2825 		if (rc != 0)
2826 			goto trunc;
2827 		ND_PRINT("%ddBm signal ", dbm_antsignal);
2828 		break;
2829 		}
2830 
2831 	case IEEE80211_RADIOTAP_DBM_ANTNOISE: {
2832 		int8_t dbm_antnoise;
2833 
2834 		rc = nd_cpack_int8(ndo, s, &dbm_antnoise);
2835 		if (rc != 0)
2836 			goto trunc;
2837 		ND_PRINT("%ddBm noise ", dbm_antnoise);
2838 		break;
2839 		}
2840 
2841 	case IEEE80211_RADIOTAP_LOCK_QUALITY: {
2842 		uint16_t lock_quality;
2843 
2844 		rc = nd_cpack_uint16(ndo, s, &lock_quality);
2845 		if (rc != 0)
2846 			goto trunc;
2847 		ND_PRINT("%u sq ", lock_quality);
2848 		break;
2849 		}
2850 
2851 	case IEEE80211_RADIOTAP_TX_ATTENUATION: {
2852 		int16_t tx_attenuation;
2853 
2854 		rc = nd_cpack_int16(ndo, s, &tx_attenuation);
2855 		if (rc != 0)
2856 			goto trunc;
2857 		ND_PRINT("%d tx power ", -tx_attenuation);
2858 		break;
2859 		}
2860 
2861 	case IEEE80211_RADIOTAP_DB_TX_ATTENUATION: {
2862 		int8_t db_tx_attenuation;
2863 
2864 		rc = nd_cpack_int8(ndo, s, &db_tx_attenuation);
2865 		if (rc != 0)
2866 			goto trunc;
2867 		ND_PRINT("%ddB tx attenuation ", -db_tx_attenuation);
2868 		break;
2869 		}
2870 
2871 	case IEEE80211_RADIOTAP_DBM_TX_POWER: {
2872 		int8_t dbm_tx_power;
2873 
2874 		rc = nd_cpack_int8(ndo, s, &dbm_tx_power);
2875 		if (rc != 0)
2876 			goto trunc;
2877 		ND_PRINT("%ddBm tx power ", dbm_tx_power);
2878 		break;
2879 		}
2880 
2881 	case IEEE80211_RADIOTAP_ANTENNA: {
2882 		uint8_t antenna;
2883 
2884 		rc = nd_cpack_uint8(ndo, s, &antenna);
2885 		if (rc != 0)
2886 			goto trunc;
2887 		ND_PRINT("antenna %u ", antenna);
2888 		break;
2889 		}
2890 
2891 	case IEEE80211_RADIOTAP_DB_ANTSIGNAL: {
2892 		uint8_t db_antsignal;
2893 
2894 		rc = nd_cpack_uint8(ndo, s, &db_antsignal);
2895 		if (rc != 0)
2896 			goto trunc;
2897 		ND_PRINT("%udB signal ", db_antsignal);
2898 		break;
2899 		}
2900 
2901 	case IEEE80211_RADIOTAP_DB_ANTNOISE: {
2902 		uint8_t db_antnoise;
2903 
2904 		rc = nd_cpack_uint8(ndo, s, &db_antnoise);
2905 		if (rc != 0)
2906 			goto trunc;
2907 		ND_PRINT("%udB noise ", db_antnoise);
2908 		break;
2909 		}
2910 
2911 	case IEEE80211_RADIOTAP_RX_FLAGS: {
2912 		uint16_t rx_flags;
2913 
2914 		rc = nd_cpack_uint16(ndo, s, &rx_flags);
2915 		if (rc != 0)
2916 			goto trunc;
2917 		/* Do nothing for now */
2918 		break;
2919 		}
2920 
2921 	case IEEE80211_RADIOTAP_XCHANNEL: {
2922 		uint32_t flags;
2923 		uint16_t frequency;
2924 		uint8_t channel;
2925 		uint8_t maxpower;
2926 
2927 		rc = nd_cpack_uint32(ndo, s, &flags);
2928 		if (rc != 0)
2929 			goto trunc;
2930 		rc = nd_cpack_uint16(ndo, s, &frequency);
2931 		if (rc != 0)
2932 			goto trunc;
2933 		rc = nd_cpack_uint8(ndo, s, &channel);
2934 		if (rc != 0)
2935 			goto trunc;
2936 		rc = nd_cpack_uint8(ndo, s, &maxpower);
2937 		if (rc != 0)
2938 			goto trunc;
2939 		print_chaninfo(ndo, frequency, flags, presentflags);
2940 		break;
2941 		}
2942 
2943 	case IEEE80211_RADIOTAP_MCS: {
2944 		uint8_t known;
2945 		uint8_t flags;
2946 		uint8_t mcs_index;
2947 		static const char *ht_bandwidth[4] = {
2948 			"20 MHz",
2949 			"40 MHz",
2950 			"20 MHz (L)",
2951 			"20 MHz (U)"
2952 		};
2953 		float htrate;
2954 
2955 		rc = nd_cpack_uint8(ndo, s, &known);
2956 		if (rc != 0)
2957 			goto trunc;
2958 		rc = nd_cpack_uint8(ndo, s, &flags);
2959 		if (rc != 0)
2960 			goto trunc;
2961 		rc = nd_cpack_uint8(ndo, s, &mcs_index);
2962 		if (rc != 0)
2963 			goto trunc;
2964 		if (known & IEEE80211_RADIOTAP_MCS_MCS_INDEX_KNOWN) {
2965 			/*
2966 			 * We know the MCS index.
2967 			 */
2968 			if (mcs_index <= MAX_MCS_INDEX) {
2969 				/*
2970 				 * And it's in-range.
2971 				 */
2972 				if (known & (IEEE80211_RADIOTAP_MCS_BANDWIDTH_KNOWN|IEEE80211_RADIOTAP_MCS_GUARD_INTERVAL_KNOWN)) {
2973 					/*
2974 					 * And we know both the bandwidth and
2975 					 * the guard interval, so we can look
2976 					 * up the rate.
2977 					 */
2978 					htrate =
2979 						ieee80211_float_htrates
2980 							[mcs_index]
2981 							[((flags & IEEE80211_RADIOTAP_MCS_BANDWIDTH_MASK) == IEEE80211_RADIOTAP_MCS_BANDWIDTH_40 ? 1 : 0)]
2982 							[((flags & IEEE80211_RADIOTAP_MCS_SHORT_GI) ? 1 : 0)];
2983 				} else {
2984 					/*
2985 					 * We don't know both the bandwidth
2986 					 * and the guard interval, so we can
2987 					 * only report the MCS index.
2988 					 */
2989 					htrate = 0.0;
2990 				}
2991 			} else {
2992 				/*
2993 				 * The MCS value is out of range.
2994 				 */
2995 				htrate = 0.0;
2996 			}
2997 			if (htrate != 0.0) {
2998 				/*
2999 				 * We have the rate.
3000 				 * Print it.
3001 				 */
3002 				ND_PRINT("%.1f Mb/s MCS %u ", htrate, mcs_index);
3003 			} else {
3004 				/*
3005 				 * We at least have the MCS index.
3006 				 * Print it.
3007 				 */
3008 				ND_PRINT("MCS %u ", mcs_index);
3009 			}
3010 		}
3011 		if (known & IEEE80211_RADIOTAP_MCS_BANDWIDTH_KNOWN) {
3012 			ND_PRINT("%s ",
3013 				ht_bandwidth[flags & IEEE80211_RADIOTAP_MCS_BANDWIDTH_MASK]);
3014 		}
3015 		if (known & IEEE80211_RADIOTAP_MCS_GUARD_INTERVAL_KNOWN) {
3016 			ND_PRINT("%s GI ",
3017 				(flags & IEEE80211_RADIOTAP_MCS_SHORT_GI) ?
3018 				"short" : "long");
3019 		}
3020 		if (known & IEEE80211_RADIOTAP_MCS_HT_FORMAT_KNOWN) {
3021 			ND_PRINT("%s ",
3022 				(flags & IEEE80211_RADIOTAP_MCS_HT_GREENFIELD) ?
3023 				"greenfield" : "mixed");
3024 		}
3025 		if (known & IEEE80211_RADIOTAP_MCS_FEC_TYPE_KNOWN) {
3026 			ND_PRINT("%s FEC ",
3027 				(flags & IEEE80211_RADIOTAP_MCS_FEC_LDPC) ?
3028 				"LDPC" : "BCC");
3029 		}
3030 		if (known & IEEE80211_RADIOTAP_MCS_STBC_KNOWN) {
3031 			ND_PRINT("RX-STBC%u ",
3032 				(flags & IEEE80211_RADIOTAP_MCS_STBC_MASK) >> IEEE80211_RADIOTAP_MCS_STBC_SHIFT);
3033 		}
3034 		break;
3035 		}
3036 
3037 	case IEEE80211_RADIOTAP_AMPDU_STATUS: {
3038 		uint32_t reference_num;
3039 		uint16_t flags;
3040 		uint8_t delim_crc;
3041 		uint8_t reserved;
3042 
3043 		rc = nd_cpack_uint32(ndo, s, &reference_num);
3044 		if (rc != 0)
3045 			goto trunc;
3046 		rc = nd_cpack_uint16(ndo, s, &flags);
3047 		if (rc != 0)
3048 			goto trunc;
3049 		rc = nd_cpack_uint8(ndo, s, &delim_crc);
3050 		if (rc != 0)
3051 			goto trunc;
3052 		rc = nd_cpack_uint8(ndo, s, &reserved);
3053 		if (rc != 0)
3054 			goto trunc;
3055 		/* Do nothing for now */
3056 		break;
3057 		}
3058 
3059 	case IEEE80211_RADIOTAP_VHT: {
3060 		uint16_t known;
3061 		uint8_t flags;
3062 		uint8_t bandwidth;
3063 		uint8_t mcs_nss[4];
3064 		uint8_t coding;
3065 		uint8_t group_id;
3066 		uint16_t partial_aid;
3067 		static const char *vht_bandwidth[32] = {
3068 			"20 MHz",
3069 			"40 MHz",
3070 			"20 MHz (L)",
3071 			"20 MHz (U)",
3072 			"80 MHz",
3073 			"80 MHz (L)",
3074 			"80 MHz (U)",
3075 			"80 MHz (LL)",
3076 			"80 MHz (LU)",
3077 			"80 MHz (UL)",
3078 			"80 MHz (UU)",
3079 			"160 MHz",
3080 			"160 MHz (L)",
3081 			"160 MHz (U)",
3082 			"160 MHz (LL)",
3083 			"160 MHz (LU)",
3084 			"160 MHz (UL)",
3085 			"160 MHz (UU)",
3086 			"160 MHz (LLL)",
3087 			"160 MHz (LLU)",
3088 			"160 MHz (LUL)",
3089 			"160 MHz (UUU)",
3090 			"160 MHz (ULL)",
3091 			"160 MHz (ULU)",
3092 			"160 MHz (UUL)",
3093 			"160 MHz (UUU)",
3094 			"unknown (26)",
3095 			"unknown (27)",
3096 			"unknown (28)",
3097 			"unknown (29)",
3098 			"unknown (30)",
3099 			"unknown (31)"
3100 		};
3101 
3102 		rc = nd_cpack_uint16(ndo, s, &known);
3103 		if (rc != 0)
3104 			goto trunc;
3105 		rc = nd_cpack_uint8(ndo, s, &flags);
3106 		if (rc != 0)
3107 			goto trunc;
3108 		rc = nd_cpack_uint8(ndo, s, &bandwidth);
3109 		if (rc != 0)
3110 			goto trunc;
3111 		for (i = 0; i < 4; i++) {
3112 			rc = nd_cpack_uint8(ndo, s, &mcs_nss[i]);
3113 			if (rc != 0)
3114 				goto trunc;
3115 		}
3116 		rc = nd_cpack_uint8(ndo, s, &coding);
3117 		if (rc != 0)
3118 			goto trunc;
3119 		rc = nd_cpack_uint8(ndo, s, &group_id);
3120 		if (rc != 0)
3121 			goto trunc;
3122 		rc = nd_cpack_uint16(ndo, s, &partial_aid);
3123 		if (rc != 0)
3124 			goto trunc;
3125 		for (i = 0; i < 4; i++) {
3126 			u_int nss, mcs;
3127 			nss = mcs_nss[i] & IEEE80211_RADIOTAP_VHT_NSS_MASK;
3128 			mcs = (mcs_nss[i] & IEEE80211_RADIOTAP_VHT_MCS_MASK) >> IEEE80211_RADIOTAP_VHT_MCS_SHIFT;
3129 
3130 			if (nss == 0)
3131 				continue;
3132 
3133 			ND_PRINT("User %u MCS %u ", i, mcs);
3134 			ND_PRINT("%s FEC ",
3135 				(coding & (IEEE80211_RADIOTAP_CODING_LDPC_USERn << i)) ?
3136 				"LDPC" : "BCC");
3137 		}
3138 		if (known & IEEE80211_RADIOTAP_VHT_BANDWIDTH_KNOWN) {
3139 			ND_PRINT("%s ",
3140 				vht_bandwidth[bandwidth & IEEE80211_RADIOTAP_VHT_BANDWIDTH_MASK]);
3141 		}
3142 		if (known & IEEE80211_RADIOTAP_VHT_GUARD_INTERVAL_KNOWN) {
3143 			ND_PRINT("%s GI ",
3144 				(flags & IEEE80211_RADIOTAP_VHT_SHORT_GI) ?
3145 				"short" : "long");
3146 		}
3147 		break;
3148 		}
3149 
3150 	default:
3151 		/* this bit indicates a field whose
3152 		 * size we do not know, so we cannot
3153 		 * proceed.  Just print the bit number.
3154 		 */
3155 		ND_PRINT("[bit %u] ", bit);
3156 		return -1;
3157 	}
3158 
3159 	return 0;
3160 
3161 trunc:
3162 	nd_print_trunc(ndo);
3163 	return rc;
3164 }
3165 
3166 
3167 static int
print_in_radiotap_namespace(netdissect_options * ndo,struct cpack_state * s,uint8_t * flags,uint32_t presentflags,int bit0)3168 print_in_radiotap_namespace(netdissect_options *ndo,
3169 			    struct cpack_state *s, uint8_t *flags,
3170 			    uint32_t presentflags, int bit0)
3171 {
3172 #define	BITNO_32(x) (((x) >> 16) ? 16 + BITNO_16((x) >> 16) : BITNO_16((x)))
3173 #define	BITNO_16(x) (((x) >> 8) ? 8 + BITNO_8((x) >> 8) : BITNO_8((x)))
3174 #define	BITNO_8(x) (((x) >> 4) ? 4 + BITNO_4((x) >> 4) : BITNO_4((x)))
3175 #define	BITNO_4(x) (((x) >> 2) ? 2 + BITNO_2((x) >> 2) : BITNO_2((x)))
3176 #define	BITNO_2(x) (((x) & 2) ? 1 : 0)
3177 	uint32_t present, next_present;
3178 	int bitno;
3179 	enum ieee80211_radiotap_type bit;
3180 	int rc;
3181 
3182 	for (present = presentflags; present; present = next_present) {
3183 		/*
3184 		 * Clear the least significant bit that is set.
3185 		 */
3186 		next_present = present & (present - 1);
3187 
3188 		/*
3189 		 * Get the bit number, within this presence word,
3190 		 * of the remaining least significant bit that
3191 		 * is set.
3192 		 */
3193 		bitno = BITNO_32(present ^ next_present);
3194 
3195 		/*
3196 		 * Stop if this is one of the "same meaning
3197 		 * in all presence flags" bits.
3198 		 */
3199 		if (bitno >= IEEE80211_RADIOTAP_NAMESPACE)
3200 			break;
3201 
3202 		/*
3203 		 * Get the radiotap bit number of that bit.
3204 		 */
3205 		bit = (enum ieee80211_radiotap_type)(bit0 + bitno);
3206 
3207 		rc = print_radiotap_field(ndo, s, bit, flags, presentflags);
3208 		if (rc != 0)
3209 			return rc;
3210 	}
3211 
3212 	return 0;
3213 }
3214 
3215 u_int
ieee802_11_radio_print(netdissect_options * ndo,const u_char * p,u_int length,u_int caplen)3216 ieee802_11_radio_print(netdissect_options *ndo,
3217 		       const u_char *p, u_int length, u_int caplen)
3218 {
3219 #define	BIT(n)	(1U << n)
3220 #define	IS_EXTENDED(__p)	\
3221 	    (GET_LE_U_4(__p) & BIT(IEEE80211_RADIOTAP_EXT)) != 0
3222 
3223 	struct cpack_state cpacker;
3224 	const struct ieee80211_radiotap_header *hdr;
3225 	uint32_t presentflags;
3226 	const nd_uint32_t *presentp, *last_presentp;
3227 	int vendor_namespace;
3228 	uint8_t vendor_oui[3];
3229 	uint8_t vendor_subnamespace;
3230 	uint16_t skip_length;
3231 	int bit0;
3232 	u_int len;
3233 	uint8_t flags;
3234 	int pad;
3235 	u_int fcslen;
3236 
3237 	ndo->ndo_protocol = "802.11_radio";
3238 	if (caplen < sizeof(*hdr)) {
3239 		nd_print_trunc(ndo);
3240 		return caplen;
3241 	}
3242 
3243 	hdr = (const struct ieee80211_radiotap_header *)p;
3244 
3245 	len = GET_LE_U_2(hdr->it_len);
3246 	if (len < sizeof(*hdr)) {
3247 		/*
3248 		 * The length is the length of the entire header, so
3249 		 * it must be as large as the fixed-length part of
3250 		 * the header.
3251 		 */
3252 		nd_print_trunc(ndo);
3253 		return caplen;
3254 	}
3255 
3256 	/*
3257 	 * If we don't have the entire radiotap header, just give up.
3258 	 */
3259 	if (caplen < len) {
3260 		nd_print_trunc(ndo);
3261 		return caplen;
3262 	}
3263 	nd_cpack_init(&cpacker, (const uint8_t *)hdr, len); /* align against header start */
3264 	nd_cpack_advance(&cpacker, sizeof(*hdr)); /* includes the 1st bitmap */
3265 	for (last_presentp = &hdr->it_present;
3266 	     (const u_char*)(last_presentp + 1) <= p + len &&
3267 	     IS_EXTENDED(last_presentp);
3268 	     last_presentp++)
3269 	  nd_cpack_advance(&cpacker, sizeof(hdr->it_present)); /* more bitmaps */
3270 
3271 	/* are there more bitmap extensions than bytes in header? */
3272 	if ((const u_char*)(last_presentp + 1) > p + len) {
3273 		nd_print_trunc(ndo);
3274 		return caplen;
3275 	}
3276 
3277 	/*
3278 	 * Start out at the beginning of the default radiotap namespace.
3279 	 */
3280 	bit0 = 0;
3281 	vendor_namespace = 0;
3282 	memset(vendor_oui, 0, 3);
3283 	vendor_subnamespace = 0;
3284 	skip_length = 0;
3285 	/* Assume no flags */
3286 	flags = 0;
3287 	/* Assume no Atheros padding between 802.11 header and body */
3288 	pad = 0;
3289 	/* Assume no FCS at end of frame */
3290 	fcslen = 0;
3291 	for (presentp = &hdr->it_present; presentp <= last_presentp;
3292 	    presentp++) {
3293 		presentflags = GET_LE_U_4(presentp);
3294 
3295 		/*
3296 		 * If this is a vendor namespace, we don't handle it.
3297 		 */
3298 		if (vendor_namespace) {
3299 			/*
3300 			 * Skip past the stuff we don't understand.
3301 			 * If we add support for any vendor namespaces,
3302 			 * it'd be added here; use vendor_oui and
3303 			 * vendor_subnamespace to interpret the fields.
3304 			 */
3305 			if (nd_cpack_advance(&cpacker, skip_length) != 0) {
3306 				/*
3307 				 * Ran out of space in the packet.
3308 				 */
3309 				break;
3310 			}
3311 
3312 			/*
3313 			 * We've skipped it all; nothing more to
3314 			 * skip.
3315 			 */
3316 			skip_length = 0;
3317 		} else {
3318 			if (print_in_radiotap_namespace(ndo, &cpacker,
3319 			    &flags, presentflags, bit0) != 0) {
3320 				/*
3321 				 * Fatal error - can't process anything
3322 				 * more in the radiotap header.
3323 				 */
3324 				break;
3325 			}
3326 		}
3327 
3328 		/*
3329 		 * Handle the namespace switch bits; we've already handled
3330 		 * the extension bit in all but the last word above.
3331 		 */
3332 		switch (presentflags &
3333 		    (BIT(IEEE80211_RADIOTAP_NAMESPACE)|BIT(IEEE80211_RADIOTAP_VENDOR_NAMESPACE))) {
3334 
3335 		case 0:
3336 			/*
3337 			 * We're not changing namespaces.
3338 			 * advance to the next 32 bits in the current
3339 			 * namespace.
3340 			 */
3341 			bit0 += 32;
3342 			break;
3343 
3344 		case BIT(IEEE80211_RADIOTAP_NAMESPACE):
3345 			/*
3346 			 * We're switching to the radiotap namespace.
3347 			 * Reset the presence-bitmap index to 0, and
3348 			 * reset the namespace to the default radiotap
3349 			 * namespace.
3350 			 */
3351 			bit0 = 0;
3352 			vendor_namespace = 0;
3353 			memset(vendor_oui, 0, 3);
3354 			vendor_subnamespace = 0;
3355 			skip_length = 0;
3356 			break;
3357 
3358 		case BIT(IEEE80211_RADIOTAP_VENDOR_NAMESPACE):
3359 			/*
3360 			 * We're switching to a vendor namespace.
3361 			 * Reset the presence-bitmap index to 0,
3362 			 * note that we're in a vendor namespace,
3363 			 * and fetch the fields of the Vendor Namespace
3364 			 * item.
3365 			 */
3366 			bit0 = 0;
3367 			vendor_namespace = 1;
3368 			if ((nd_cpack_align_and_reserve(&cpacker, 2)) == NULL) {
3369 				nd_print_trunc(ndo);
3370 				break;
3371 			}
3372 			if (nd_cpack_uint8(ndo, &cpacker, &vendor_oui[0]) != 0) {
3373 				nd_print_trunc(ndo);
3374 				break;
3375 			}
3376 			if (nd_cpack_uint8(ndo, &cpacker, &vendor_oui[1]) != 0) {
3377 				nd_print_trunc(ndo);
3378 				break;
3379 			}
3380 			if (nd_cpack_uint8(ndo, &cpacker, &vendor_oui[2]) != 0) {
3381 				nd_print_trunc(ndo);
3382 				break;
3383 			}
3384 			if (nd_cpack_uint8(ndo, &cpacker, &vendor_subnamespace) != 0) {
3385 				nd_print_trunc(ndo);
3386 				break;
3387 			}
3388 			if (nd_cpack_uint16(ndo, &cpacker, &skip_length) != 0) {
3389 				nd_print_trunc(ndo);
3390 				break;
3391 			}
3392 			break;
3393 
3394 		default:
3395 			/*
3396 			 * Illegal combination.  The behavior in this
3397 			 * case is undefined by the radiotap spec; we
3398 			 * just ignore both bits.
3399 			 */
3400 			break;
3401 		}
3402 	}
3403 
3404 	if (flags & IEEE80211_RADIOTAP_F_DATAPAD)
3405 		pad = 1;	/* Atheros padding */
3406 	if (flags & IEEE80211_RADIOTAP_F_FCS)
3407 		fcslen = 4;	/* FCS at end of packet */
3408 	return len + ieee802_11_print(ndo, p + len, length - len, caplen - len, pad,
3409 	    fcslen);
3410 #undef BITNO_32
3411 #undef BITNO_16
3412 #undef BITNO_8
3413 #undef BITNO_4
3414 #undef BITNO_2
3415 #undef BIT
3416 }
3417 
3418 static u_int
ieee802_11_radio_avs_print(netdissect_options * ndo,const u_char * p,u_int length,u_int caplen)3419 ieee802_11_radio_avs_print(netdissect_options *ndo,
3420 			   const u_char *p, u_int length, u_int caplen)
3421 {
3422 	uint32_t caphdr_len;
3423 
3424 	ndo->ndo_protocol = "802.11_radio_avs";
3425 	if (caplen < 8) {
3426 		nd_print_trunc(ndo);
3427 		return caplen;
3428 	}
3429 
3430 	caphdr_len = GET_BE_U_4(p + 4);
3431 	if (caphdr_len < 8) {
3432 		/*
3433 		 * Yow!  The capture header length is claimed not
3434 		 * to be large enough to include even the version
3435 		 * cookie or capture header length!
3436 		 */
3437 		nd_print_trunc(ndo);
3438 		return caplen;
3439 	}
3440 
3441 	if (caplen < caphdr_len) {
3442 		nd_print_trunc(ndo);
3443 		return caplen;
3444 	}
3445 
3446 	return caphdr_len + ieee802_11_print(ndo, p + caphdr_len,
3447 	    length - caphdr_len, caplen - caphdr_len, 0, 0);
3448 }
3449 
3450 #define PRISM_HDR_LEN		144
3451 
3452 #define WLANCAP_MAGIC_COOKIE_BASE 0x80211000
3453 #define WLANCAP_MAGIC_COOKIE_V1	0x80211001
3454 #define WLANCAP_MAGIC_COOKIE_V2	0x80211002
3455 
3456 /*
3457  * For DLT_PRISM_HEADER; like DLT_IEEE802_11, but with an extra header,
3458  * containing information such as radio information, which we
3459  * currently ignore.
3460  *
3461  * If, however, the packet begins with WLANCAP_MAGIC_COOKIE_V1 or
3462  * WLANCAP_MAGIC_COOKIE_V2, it's really DLT_IEEE802_11_RADIO_AVS
3463  * (currently, on Linux, there's no ARPHRD_ type for
3464  * DLT_IEEE802_11_RADIO_AVS, as there is a ARPHRD_IEEE80211_PRISM
3465  * for DLT_PRISM_HEADER, so ARPHRD_IEEE80211_PRISM is used for
3466  * the AVS header, and the first 4 bytes of the header are used to
3467  * indicate whether it's a Prism header or an AVS header).
3468  */
3469 void
prism_if_print(netdissect_options * ndo,const struct pcap_pkthdr * h,const u_char * p)3470 prism_if_print(netdissect_options *ndo,
3471 	       const struct pcap_pkthdr *h, const u_char *p)
3472 {
3473 	u_int caplen = h->caplen;
3474 	u_int length = h->len;
3475 	uint32_t msgcode;
3476 
3477 	ndo->ndo_protocol = "prism";
3478 	if (caplen < 4) {
3479 		nd_print_trunc(ndo);
3480 		ndo->ndo_ll_hdr_len += caplen;
3481 		return;
3482 	}
3483 
3484 	msgcode = GET_BE_U_4(p);
3485 	if (msgcode == WLANCAP_MAGIC_COOKIE_V1 ||
3486 	    msgcode == WLANCAP_MAGIC_COOKIE_V2) {
3487 		ndo->ndo_ll_hdr_len += ieee802_11_radio_avs_print(ndo, p, length, caplen);
3488 		return;
3489 	}
3490 
3491 	if (caplen < PRISM_HDR_LEN) {
3492 		nd_print_trunc(ndo);
3493 		ndo->ndo_ll_hdr_len += caplen;
3494 		return;
3495 	}
3496 
3497 	p += PRISM_HDR_LEN;
3498 	length -= PRISM_HDR_LEN;
3499 	caplen -= PRISM_HDR_LEN;
3500 	ndo->ndo_ll_hdr_len += PRISM_HDR_LEN;
3501 	ndo->ndo_ll_hdr_len += ieee802_11_print(ndo, p, length, caplen, 0, 0);
3502 }
3503 
3504 /*
3505  * For DLT_IEEE802_11_RADIO; like DLT_IEEE802_11, but with an extra
3506  * header, containing information such as radio information.
3507  */
3508 void
ieee802_11_radio_if_print(netdissect_options * ndo,const struct pcap_pkthdr * h,const u_char * p)3509 ieee802_11_radio_if_print(netdissect_options *ndo,
3510 			  const struct pcap_pkthdr *h, const u_char *p)
3511 {
3512 	ndo->ndo_protocol = "802.11_radio";
3513 	ndo->ndo_ll_hdr_len += ieee802_11_radio_print(ndo, p, h->len, h->caplen);
3514 }
3515 
3516 /*
3517  * For DLT_IEEE802_11_RADIO_AVS; like DLT_IEEE802_11, but with an
3518  * extra header, containing information such as radio information,
3519  * which we currently ignore.
3520  */
3521 void
ieee802_11_radio_avs_if_print(netdissect_options * ndo,const struct pcap_pkthdr * h,const u_char * p)3522 ieee802_11_radio_avs_if_print(netdissect_options *ndo,
3523 			      const struct pcap_pkthdr *h, const u_char *p)
3524 {
3525 	ndo->ndo_protocol = "802.11_radio_avs";
3526 	ndo->ndo_ll_hdr_len += ieee802_11_radio_avs_print(ndo, p, h->len, h->caplen);
3527 }
3528