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