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