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