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
91static 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
117static 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
172struct 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
191struct ssid_t {
192	uint8_t		element_id;
193	uint8_t		length;
194	u_char		ssid[33];  /* 32 + 1 for null */
195};
196
197struct rates_t {
198	uint8_t		element_id;
199	uint8_t		length;
200	uint8_t		rate[16];
201};
202
203struct challenge_t {
204	uint8_t		element_id;
205	uint8_t		length;
206	uint8_t		text[254]; /* 1-253 + 1 for null */
207};
208
209struct 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
218struct ds_t {
219	uint8_t		element_id;
220	uint8_t		length;
221	uint8_t		channel;
222};
223
224struct 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
233struct 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
268struct 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
295struct 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
306struct 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
315struct 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
324struct 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
335struct 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
346struct 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
357struct 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
366struct 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
380struct 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: src/sys/net80211/ieee80211_radiotap.h,v 1.5 2005/01/22 20:12:05 sam Exp $ */
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 */
445struct 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 */
584enum 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
686static const char tstr[] = "[|802.11]";
687
688/* Radiotap state */
689/*  This is used to save state when parsing/processing parameters */
690struct 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 */
736static 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
1123static 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
1126static 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
1208static 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
1276static int
1277wep_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
1292static int
1293parse_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
1522static int
1523handle_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
1559static int
1560handle_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
1587static int
1588handle_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
1624static int
1625handle_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
1658static int
1659handle_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
1666static int
1667handle_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
1684static int
1685handle_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
1719static int
1720handle_atim(void)
1721{
1722	/* the frame body for ATIM is null. */
1723	return 1;
1724}
1725
1726static int
1727handle_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
1748static int
1749handle_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
1802static int
1803handle_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
1887static int
1888handle_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
1927static int
1928mgmt_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
1974static int
1975ctrl_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
2059static void
2060data_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
2136static void
2137mgmt_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
2154static void
2155ctrl_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
2212static int
2213extract_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
2251static int
2252extract_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 */
2262static void
2263ieee_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
2325static u_int
2326ieee802_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 */
2434u_int
2435ieee802_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
2465static void
2466print_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
2500static int
2501print_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
2818static u_int
2819ieee802_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
2898out:
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
2913static u_int
2914ieee802_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 */
2963u_int
2964prism_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 */
2994u_int
2995ieee802_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 */
3006u_int
3007ieee802_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