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