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