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