Move 3 ASN1 dissectors to 'clean' group; move 1 PIDL dissector to 'dirty' group.
[metze/wireshark/wip.git] / epan / dissectors / packet-ieee80211-radiotap.c
1 /*
2  *  packet-ieee80211-radiotap.c
3  *      Decode packets with a Radiotap header
4  *
5  * $Id$
6  *
7  * Wireshark - Network traffic analyzer
8  * By Gerald Combs <gerald@wireshark.org>
9  * Copyright 1998 Gerald Combs
10  *
11  * Copied from README.developer
12  *
13  * This program is free software; you can redistribute it and/or
14  * modify it under the terms of the GNU General Public License
15  * as published by the Free Software Foundation; either version 2
16  * of the License, or (at your option) any later version.
17  *
18  * This program is distributed in the hope that it will be useful,
19  * but WITHOUT ANY WARRANTY; without even the implied warranty of
20  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21  * GNU General Public License for more details.
22  *
23  * You should have received a copy of the GNU General Public License
24  * along with this program; if not, write to the Free Software
25  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
26  */
27
28 #include "config.h"
29
30 #include <glib.h>
31 #include <errno.h>
32
33 #include <epan/packet.h>
34 #include <epan/crc32-tvb.h>
35 #include <epan/frequency-utils.h>
36 #include <epan/tap.h>
37 #include <epan/prefs.h>
38 #include <epan/addr_resolv.h>
39 #include <epan/expert.h>
40 #include "packet-ieee80211.h"
41 #include "packet-ieee80211-radiotap.h"
42 #include "packet-ieee80211-radiotap-iter.h"
43 #include "packet-ieee80211-radiotap-defs.h"
44
45
46 /* protocol */
47 static int proto_radiotap = -1;
48
49 static int hf_radiotap_version = -1;
50 static int hf_radiotap_pad = -1;
51 static int hf_radiotap_length = -1;
52 static int hf_radiotap_present = -1;
53 static int hf_radiotap_mactime = -1;
54 static int hf_radiotap_channel = -1;
55 static int hf_radiotap_channel_frequency = -1;
56 static int hf_radiotap_channel_flags = -1;
57 static int hf_radiotap_channel_flags_turbo = -1;
58 static int hf_radiotap_channel_flags_cck = -1;
59 static int hf_radiotap_channel_flags_ofdm = -1;
60 static int hf_radiotap_channel_flags_2ghz = -1;
61 static int hf_radiotap_channel_flags_5ghz = -1;
62 static int hf_radiotap_channel_flags_passive = -1;
63 static int hf_radiotap_channel_flags_dynamic = -1;
64 static int hf_radiotap_channel_flags_gfsk = -1;
65 static int hf_radiotap_channel_flags_gsm = -1;
66 static int hf_radiotap_channel_flags_sturbo = -1;
67 static int hf_radiotap_channel_flags_half = -1;
68 static int hf_radiotap_channel_flags_quarter = -1;
69 static int hf_radiotap_rxflags = -1;
70 static int hf_radiotap_rxflags_badplcp = -1;
71 static int hf_radiotap_xchannel = -1;
72 static int hf_radiotap_xchannel_frequency = -1;
73 static int hf_radiotap_xchannel_flags = -1;
74 static int hf_radiotap_xchannel_flags_turbo = -1;
75 static int hf_radiotap_xchannel_flags_cck = -1;
76 static int hf_radiotap_xchannel_flags_ofdm = -1;
77 static int hf_radiotap_xchannel_flags_2ghz = -1;
78 static int hf_radiotap_xchannel_flags_5ghz = -1;
79 static int hf_radiotap_xchannel_flags_passive = -1;
80 static int hf_radiotap_xchannel_flags_dynamic = -1;
81 static int hf_radiotap_xchannel_flags_gfsk = -1;
82 static int hf_radiotap_xchannel_flags_gsm = -1;
83 static int hf_radiotap_xchannel_flags_sturbo = -1;
84 static int hf_radiotap_xchannel_flags_half = -1;
85 static int hf_radiotap_xchannel_flags_quarter = -1;
86 static int hf_radiotap_xchannel_flags_ht20 = -1;
87 static int hf_radiotap_xchannel_flags_ht40u = -1;
88 static int hf_radiotap_xchannel_flags_ht40d = -1;
89 #if 0
90 static int hf_radiotap_xchannel_maxpower = -1;
91 #endif
92 static int hf_radiotap_fhss_hopset = -1;
93 static int hf_radiotap_fhss_pattern = -1;
94 static int hf_radiotap_datarate = -1;
95 static int hf_radiotap_antenna = -1;
96 static int hf_radiotap_dbm_antsignal = -1;
97 static int hf_radiotap_db_antsignal = -1;
98 static int hf_radiotap_dbm_antnoise = -1;
99 static int hf_radiotap_db_antnoise = -1;
100 static int hf_radiotap_tx_attenuation = -1;
101 static int hf_radiotap_db_tx_attenuation = -1;
102 static int hf_radiotap_txpower = -1;
103 static int hf_radiotap_vendor_ns = -1;
104 static int hf_radiotap_ven_oui = -1;
105 static int hf_radiotap_ven_subns = -1;
106 static int hf_radiotap_ven_skip = -1;
107 static int hf_radiotap_ven_data = -1;
108 static int hf_radiotap_mcs = -1;
109 static int hf_radiotap_mcs_known = -1;
110 static int hf_radiotap_mcs_have_bw = -1;
111 static int hf_radiotap_mcs_have_index = -1;
112 static int hf_radiotap_mcs_have_gi = -1;
113 static int hf_radiotap_mcs_have_format = -1;
114 static int hf_radiotap_mcs_have_fec = -1;
115 static int hf_radiotap_mcs_have_stbc = -1;
116 static int hf_radiotap_mcs_bw = -1;
117 static int hf_radiotap_mcs_index = -1;
118 static int hf_radiotap_mcs_gi = -1;
119 static int hf_radiotap_mcs_format = -1;
120 static int hf_radiotap_mcs_fec = -1;
121 static int hf_radiotap_mcs_stbc = -1;
122 static int hf_radiotap_ampdu = -1;
123 static int hf_radiotap_ampdu_ref = -1;
124 static int hf_radiotap_ampdu_flags = -1;
125 static int hf_radiotap_ampdu_flags_report_zerolen = -1;
126 static int hf_radiotap_ampdu_flags_is_zerolen = -1;
127 static int hf_radiotap_ampdu_flags_last_known = -1;
128 static int hf_radiotap_ampdu_flags_is_last = -1;
129 static int hf_radiotap_ampdu_flags_delim_crc_error = -1;
130 static int hf_radiotap_ampdu_delim_crc = -1;
131 static int hf_radiotap_vht = -1;
132 static int hf_radiotap_vht_known = -1;
133 static int hf_radiotap_vht_have_stbc = -1;
134 static int hf_radiotap_vht_have_txop_ps = -1;
135 static int hf_radiotap_vht_have_gi = -1;
136 static int hf_radiotap_vht_have_sgi_nsym_da = -1;
137 static int hf_radiotap_vht_have_ldpc_extra = -1;
138 static int hf_radiotap_vht_have_bf = -1;
139 static int hf_radiotap_vht_have_bw = -1;
140 static int hf_radiotap_vht_have_gid = -1;
141 static int hf_radiotap_vht_have_p_aid = -1;
142 static int hf_radiotap_vht_stbc = -1;
143 static int hf_radiotap_vht_txop_ps = -1;
144 static int hf_radiotap_vht_gi = -1;
145 static int hf_radiotap_vht_sgi_nsym_da = -1;
146 static int hf_radiotap_vht_ldpc_extra = -1;
147 static int hf_radiotap_vht_bf = -1;
148 static int hf_radiotap_vht_bw = -1;
149 static int hf_radiotap_vht_nsts[4] = { -1, -1, -1, -1 };
150 static int hf_radiotap_vht_mcs[4] = { -1, -1, -1, -1 };
151 static int hf_radiotap_vht_nss[4] = { -1, -1, -1, -1 };
152 static int hf_radiotap_vht_coding[4] = { -1, -1, -1, -1 };
153 static int hf_radiotap_vht_datarate[4] = { -1, -1, -1, -1 };
154 static int hf_radiotap_vht_gid = -1;
155 static int hf_radiotap_vht_p_aid = -1;
156 static int hf_radiotap_vht_user = -1;
157
158 /* "Present" flags */
159 static int hf_radiotap_present_tsft = -1;
160 static int hf_radiotap_present_flags = -1;
161 static int hf_radiotap_present_rate = -1;
162 static int hf_radiotap_present_channel = -1;
163 static int hf_radiotap_present_fhss = -1;
164 static int hf_radiotap_present_dbm_antsignal = -1;
165 static int hf_radiotap_present_dbm_antnoise = -1;
166 static int hf_radiotap_present_lock_quality = -1;
167 static int hf_radiotap_present_tx_attenuation = -1;
168 static int hf_radiotap_present_db_tx_attenuation = -1;
169 static int hf_radiotap_present_dbm_tx_power = -1;
170 static int hf_radiotap_present_antenna = -1;
171 static int hf_radiotap_present_db_antsignal = -1;
172 static int hf_radiotap_present_db_antnoise = -1;
173 static int hf_radiotap_present_hdrfcs = -1;
174 static int hf_radiotap_present_rxflags = -1;
175 static int hf_radiotap_present_xchannel = -1;
176 static int hf_radiotap_present_mcs = -1;
177 static int hf_radiotap_present_ampdu = -1;
178 static int hf_radiotap_present_vht = -1;
179 static int hf_radiotap_present_reserved = -1;
180 static int hf_radiotap_present_rtap_ns = -1;
181 static int hf_radiotap_present_vendor_ns = -1;
182 static int hf_radiotap_present_ext = -1;
183
184 /* "present.flags" flags */
185 static int hf_radiotap_flags = -1;
186 static int hf_radiotap_flags_cfp = -1;
187 static int hf_radiotap_flags_preamble = -1;
188 static int hf_radiotap_flags_wep = -1;
189 static int hf_radiotap_flags_frag = -1;
190 static int hf_radiotap_flags_fcs = -1;
191 static int hf_radiotap_flags_datapad = -1;
192 static int hf_radiotap_flags_badfcs = -1;
193 static int hf_radiotap_flags_shortgi = -1;
194
195 static int hf_radiotap_quality = -1;
196 static int hf_radiotap_fcs = -1;
197 static int hf_radiotap_fcs_bad = -1;
198
199 static gint ett_radiotap = -1;
200 static gint ett_radiotap_present = -1;
201 static gint ett_radiotap_flags = -1;
202 static gint ett_radiotap_rxflags = -1;
203 static gint ett_radiotap_channel_flags = -1;
204 static gint ett_radiotap_xchannel_flags = -1;
205 static gint ett_radiotap_vendor = -1;
206 static gint ett_radiotap_mcs = -1;
207 static gint ett_radiotap_mcs_known = -1;
208 static gint ett_radiotap_ampdu = -1;
209 static gint ett_radiotap_ampdu_flags = -1;
210 static gint ett_radiotap_vht = -1;
211 static gint ett_radiotap_vht_known = -1;
212 static gint ett_radiotap_vht_user = -1;
213
214 static dissector_handle_t ieee80211_handle;
215 static dissector_handle_t ieee80211_datapad_handle;
216
217 static int radiotap_tap = -1;
218
219 /* Settings */
220 static gboolean radiotap_bit14_fcs = FALSE;
221
222 static void
223 dissect_radiotap(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree);
224
225 #define BITNO_32(x) (((x) >> 16) ? 16 + BITNO_16((x) >> 16) : BITNO_16((x)))
226 #define BITNO_16(x) (((x) >> 8) ? 8 + BITNO_8((x) >> 8) : BITNO_8((x)))
227 #define BITNO_8(x)  (((x) >> 4) ? 4 + BITNO_4((x) >> 4) : BITNO_4((x)))
228 #define BITNO_4(x)  (((x) >> 2) ? 2 + BITNO_2((x) >> 2) : BITNO_2((x)))
229 #define BITNO_2(x)  (((x) & 2) ? 1 : 0)
230 #define BIT(n)  (1 << n)
231
232 /* not officially defined (yet) */
233 #define IEEE80211_RADIOTAP_F_SHORTGI    0x80
234 #define IEEE80211_RADIOTAP_XCHANNEL     18
235 #define IEEE80211_CHAN_HT20             0x10000 /* HT 20 channel */
236 #define IEEE80211_CHAN_HT40U            0x20000 /* HT 40 channel w/ ext above */
237 #define IEEE80211_CHAN_HT40D            0x40000 /* HT 40 channel w/ ext below */
238
239 /* Official specifcation:
240  *
241  * http://www.radiotap.org/
242  *
243  * Unofficial and historical specifications:
244  * http://madwifi-project.org/wiki/DevDocs/RadiotapHeader
245  * NetBSD's ieee80211_radiotap.h file
246  */
247
248 /*
249  * Useful combinations of channel characteristics.
250  */
251 #define IEEE80211_CHAN_FHSS \
252         (IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_GFSK)
253 #define IEEE80211_CHAN_A \
254         (IEEE80211_CHAN_5GHZ | IEEE80211_CHAN_OFDM)
255 #define IEEE80211_CHAN_B \
256         (IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_CCK)
257 #define IEEE80211_CHAN_PUREG \
258         (IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_OFDM)
259 #define IEEE80211_CHAN_G \
260         (IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_DYN)
261 #define IEEE80211_CHAN_T \
262         (IEEE80211_CHAN_5GHZ | IEEE80211_CHAN_OFDM | IEEE80211_CHAN_TURBO)
263 #define IEEE80211_CHAN_108G \
264         (IEEE80211_CHAN_G | IEEE80211_CHAN_TURBO)
265 #define IEEE80211_CHAN_108PUREG \
266         (IEEE80211_CHAN_PUREG | IEEE80211_CHAN_TURBO)
267
268 #define MAX_MCS_VHT_INDEX       9
269
270 /*
271  * Maps a VHT bandwidth index to ieee80211_vhtinfo.rates index.
272  */
273 static const int ieee80211_vht_bw2rate_index[] = {
274                 /*  20Mhz total */      0,
275                 /*  40Mhz total */      1, 0, 0,
276                 /*  80Mhz total */      2, 1, 1, 0, 0, 0, 0,
277                 /* 160Mhz total */      3, 2, 2, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0
278 };
279
280 struct mcs_vht_info {
281         const char *modulation;
282         const char *coding_rate;
283         float       rates[4][2];
284 };
285
286 static const struct mcs_vht_info ieee80211_vhtinfo[MAX_MCS_VHT_INDEX+1] = {
287                 /* MCS  0  */
288                 {       "BPSK",         "1/2",
289                                 {               /* 20 Mhz */  {    6.5f,                /* SGI */    7.2f, },
290                                                 /* 40 Mhz */  {   13.5f,                /* SGI */   15.0f, },
291                                                 /* 80 Mhz */  {   29.3f,                /* SGI */   32.5f, },
292                                                 /* 160 Mhz */ {   58.5f,                /* SGI */   65.0f, }
293                                 }
294                 },
295                 /* MCS  1  */
296                 {       "QPSK",         "1/2",
297                                 {               /* 20 Mhz */  {   13.0f,                /* SGI */   14.4f, },
298                                                 /* 40 Mhz */  {   27.0f,                /* SGI */   30.0f, },
299                                                 /* 80 Mhz */  {   58.5f,                /* SGI */   65.0f, },
300                                                 /* 160 Mhz */ {  117.0f,                /* SGI */  130.0f, }
301                                 }
302                 },
303                 /* MCS  2  */
304                 {       "QPSK",         "3/4",
305                                 {               /* 20 Mhz */  {   19.5f,                /* SGI */   21.7f, },
306                                                 /* 40 Mhz */  {   40.5f,                /* SGI */   45.0f, },
307                                                 /* 80 Mhz */  {   87.8f,                /* SGI */   97.5f, },
308                                                 /* 160 Mhz */ {  175.5f,                /* SGI */  195.0f, }
309                                 }
310                 },
311                 /* MCS  3  */
312                 {       "16-QAM",       "1/2",
313                                 {               /* 20 Mhz */  {   26.0f,                /* SGI */   28.9f, },
314                                                 /* 40 Mhz */  {   54.0f,                /* SGI */   60.0f, },
315                                                 /* 80 Mhz */  {  117.0f,                /* SGI */  130.0f, },
316                                                 /* 160 Mhz */ {  234.0f,                /* SGI */  260.0f, }
317                                 }
318                 },
319                 /* MCS  4  */
320                 {       "16-QAM",       "3/4",
321                                 {               /* 20 Mhz */  {   39.0f,                /* SGI */   43.3f, },
322                                                 /* 40 Mhz */  {   81.0f,                /* SGI */   90.0f, },
323                                                 /* 80 Mhz */  {  175.5f,                /* SGI */  195.0f, },
324                                                 /* 160 Mhz */ {  351.0f,                /* SGI */  390.0f, }
325                                 }
326                 },
327                 /* MCS  5  */
328                 {       "64-QAM",       "2/3",
329                                 {               /* 20 Mhz */  {   52.0f,                /* SGI */   57.8f, },
330                                                 /* 40 Mhz */  {  108.0f,                /* SGI */  120.0f, },
331                                                 /* 80 Mhz */  {  234.0f,                /* SGI */  260.0f, },
332                                                 /* 160 Mhz */ {  468.0f,                /* SGI */  520.0f, }
333                                 }
334                 },
335                 /* MCS  6  */
336                 {       "64-QAM",       "3/4",
337                                 {               /* 20 Mhz */  {   58.5f,                /* SGI */   65.0f, },
338                                                 /* 40 Mhz */  {  121.5f,                /* SGI */  135.0f, },
339                                                 /* 80 Mhz */  {  263.3f,                /* SGI */  292.5f, },
340                                                 /* 160 Mhz */ {  526.5f,                /* SGI */  585.0f, }
341                                 }
342                 },
343                 /* MCS  7  */
344                 {       "64-QAM",       "5/6",
345                                 {               /* 20 Mhz */  {   65.0f,                /* SGI */   72.2f, },
346                                                 /* 40 Mhz */  {  135.0f,                /* SGI */  150.0f, },
347                                                 /* 80 Mhz */  {  292.5f,                /* SGI */  325.0f, },
348                                                 /* 160 Mhz */ {  585.0f,                /* SGI */  650.0f, }
349                                 }
350                 },
351                 /* MCS  8  */
352                 {       "256-QAM",      "3/4",
353                                 {               /* 20 Mhz */  {   78.0f,                /* SGI */   86.7f, },
354                                                 /* 40 Mhz */  {  162.0f,                /* SGI */  180.0f, },
355                                                 /* 80 Mhz */  {  351.0f,                /* SGI */  390.0f, },
356                                                 /* 160 Mhz */ {  702.0f,                /* SGI */  780.0f, }
357                                 }
358                 },
359                 /* MCS  9  */
360                 {       "256-QAM",      "5/6",
361                                 {               /* 20 Mhz */  {    0.0f,                /* SGI */    0.0f, },
362                                                 /* 40 Mhz */  {  180.0f,                /* SGI */  200.0f, },
363                                                 /* 80 Mhz */  {  390.0f,                /* SGI */  433.3f, },
364                                                 /* 160 Mhz */ {  780.0f,                /* SGI */  866.7f, }
365                                 }
366                 }
367 };
368
369 /* In order by value */
370 static const value_string vht_bandwidth[] = {
371         { IEEE80211_RADIOTAP_VHT_BW_20,    "20 MHz" },
372         { IEEE80211_RADIOTAP_VHT_BW_40,    "40 MHz" },
373         { IEEE80211_RADIOTAP_VHT_BW_20L,   "20 MHz lower" },
374         { IEEE80211_RADIOTAP_VHT_BW_20U,   "20 MHz upper" },
375         { IEEE80211_RADIOTAP_VHT_BW_80,    "80 MHz" },
376         { IEEE80211_RADIOTAP_VHT_BW_40L,   "40 MHz lower" },
377         { IEEE80211_RADIOTAP_VHT_BW_40U,   "40 MHz upper" },
378         { IEEE80211_RADIOTAP_VHT_BW_20LL,  "20 MHz, channel 1/4" },
379         { IEEE80211_RADIOTAP_VHT_BW_20LU,  "20 MHz, channel 2/4" },
380         { IEEE80211_RADIOTAP_VHT_BW_20UL,  "20 MHz, channel 3/4" },
381         { IEEE80211_RADIOTAP_VHT_BW_20UU,  "20 MHz, channel 4/4" },
382         { IEEE80211_RADIOTAP_VHT_BW_160,   "160 MHz" },
383         { IEEE80211_RADIOTAP_VHT_BW_80L,   "80 MHz lower" },
384         { IEEE80211_RADIOTAP_VHT_BW_80U,   "80 MHz upper" },
385         { IEEE80211_RADIOTAP_VHT_BW_40LL,  "40 MHz, channel 1/4" },
386         { IEEE80211_RADIOTAP_VHT_BW_40LU,  "40 MHz, channel 2/4" },
387         { IEEE80211_RADIOTAP_VHT_BW_40UL,  "40 MHz, channel 3/4" },
388         { IEEE80211_RADIOTAP_VHT_BW_40UU,  "40 MHz, channel 4/4" },
389         { IEEE80211_RADIOTAP_VHT_BW_20LLL, "20 MHz, channel 1/8" },
390         { IEEE80211_RADIOTAP_VHT_BW_20LLU, "20 MHz, channel 2/8" },
391         { IEEE80211_RADIOTAP_VHT_BW_20LUL, "20 MHz, channel 3/8" },
392         { IEEE80211_RADIOTAP_VHT_BW_20LUU, "20 MHz, channel 4/8" },
393         { IEEE80211_RADIOTAP_VHT_BW_20ULL, "20 MHz, channel 5/8" },
394         { IEEE80211_RADIOTAP_VHT_BW_20ULU, "20 MHz, channel 6/8" },
395         { IEEE80211_RADIOTAP_VHT_BW_20UUL, "20 MHz, channel 7/8" },
396         { IEEE80211_RADIOTAP_VHT_BW_20UUU, "20 MHz, channel 8/8" },
397         { 0, NULL }
398 };
399 static value_string_ext vht_bandwidth_ext = VALUE_STRING_EXT_INIT(vht_bandwidth);
400
401 #define MAX_MCS_INDEX   76
402
403 /*
404  * Indices are:
405  *
406  *      the MCS index (0-76);
407  *
408  *      0 for 20 MHz, 1 for 40 MHz;
409  *
410  *      0 for a long guard interval, 1 for a short guard interval.
411  */
412 static const float ieee80211_float_htrates[MAX_MCS_INDEX+1][2][2] = {
413         /* MCS  0  */
414         {       /* 20 Mhz */ {    6.5f,         /* SGI */    7.2f, },
415                 /* 40 Mhz */ {   13.5f,         /* SGI */   15.0f, },
416         },
417
418         /* MCS  1  */
419         {       /* 20 Mhz */ {   13.0f,         /* SGI */   14.4f, },
420                 /* 40 Mhz */ {   27.0f,         /* SGI */   30.0f, },
421         },
422
423         /* MCS  2  */
424         {       /* 20 Mhz */ {   19.5f,         /* SGI */   21.7f, },
425                 /* 40 Mhz */ {   40.5f,         /* SGI */   45.0f, },
426         },
427
428         /* MCS  3  */
429         {       /* 20 Mhz */ {   26.0f,         /* SGI */   28.9f, },
430                 /* 40 Mhz */ {   54.0f,         /* SGI */   60.0f, },
431         },
432
433         /* MCS  4  */
434         {       /* 20 Mhz */ {   39.0f,         /* SGI */   43.3f, },
435                 /* 40 Mhz */ {   81.0f,         /* SGI */   90.0f, },
436         },
437
438         /* MCS  5  */
439         {       /* 20 Mhz */ {   52.0f,         /* SGI */   57.8f, },
440                 /* 40 Mhz */ {  108.0f,         /* SGI */  120.0f, },
441         },
442
443         /* MCS  6  */
444         {       /* 20 Mhz */ {   58.5f,         /* SGI */   65.0f, },
445                 /* 40 Mhz */ {  121.5f,         /* SGI */  135.0f, },
446         },
447
448         /* MCS  7  */
449         {       /* 20 Mhz */ {   65.0f,         /* SGI */   72.2f, },
450                 /* 40 Mhz */ {   135.0f,        /* SGI */  150.0f, },
451         },
452
453         /* MCS  8  */
454         {       /* 20 Mhz */ {   13.0f,         /* SGI */   14.4f, },
455                 /* 40 Mhz */ {   27.0f,         /* SGI */   30.0f, },
456         },
457
458         /* MCS  9  */
459         {       /* 20 Mhz */ {   26.0f,         /* SGI */   28.9f, },
460                 /* 40 Mhz */ {   54.0f,         /* SGI */   60.0f, },
461         },
462
463         /* MCS 10  */
464         {       /* 20 Mhz */ {   39.0f,         /* SGI */   43.3f, },
465                 /* 40 Mhz */ {   81.0f,         /* SGI */   90.0f, },
466         },
467
468         /* MCS 11  */
469         {       /* 20 Mhz */ {   52.0f,         /* SGI */   57.8f, },
470                 /* 40 Mhz */ {  108.0f,         /* SGI */  120.0f, },
471         },
472
473         /* MCS 12  */
474         {       /* 20 Mhz */ {   78.0f,         /* SGI */   86.7f, },
475                 /* 40 Mhz */ {  162.0f,         /* SGI */  180.0f, },
476         },
477
478         /* MCS 13  */
479         {       /* 20 Mhz */ {  104.0f,         /* SGI */  115.6f, },
480                 /* 40 Mhz */ {  216.0f,         /* SGI */  240.0f, },
481         },
482
483         /* MCS 14  */
484         {       /* 20 Mhz */ {  117.0f,         /* SGI */  130.0f, },
485                 /* 40 Mhz */ {  243.0f,         /* SGI */  270.0f, },
486         },
487
488         /* MCS 15  */
489         {       /* 20 Mhz */ {  130.0f,         /* SGI */  144.4f, },
490                 /* 40 Mhz */ {  270.0f,         /* SGI */  300.0f, },
491         },
492
493         /* MCS 16  */
494         {       /* 20 Mhz */ {   19.5f,         /* SGI */   21.7f, },
495                 /* 40 Mhz */ {   40.5f,         /* SGI */   45.0f, },
496         },
497
498         /* MCS 17  */
499         {       /* 20 Mhz */ {   39.0f,         /* SGI */   43.3f, },
500                 /* 40 Mhz */ {   81.0f,         /* SGI */   90.0f, },
501         },
502
503         /* MCS 18  */
504         {       /* 20 Mhz */ {   58.5f,         /* SGI */   65.0f, },
505                 /* 40 Mhz */ {  121.5f,         /* SGI */  135.0f, },
506         },
507
508         /* MCS 19  */
509         {       /* 20 Mhz */ {   78.0f,         /* SGI */   86.7f, },
510                 /* 40 Mhz */ {  162.0f,         /* SGI */  180.0f, },
511         },
512
513         /* MCS 20  */
514         {       /* 20 Mhz */ {  117.0f,         /* SGI */  130.0f, },
515                 /* 40 Mhz */ {  243.0f,         /* SGI */  270.0f, },
516         },
517
518         /* MCS 21  */
519         {       /* 20 Mhz */ {  156.0f,         /* SGI */  173.3f, },
520                 /* 40 Mhz */ {  324.0f,         /* SGI */  360.0f, },
521         },
522
523         /* MCS 22  */
524         {       /* 20 Mhz */ {  175.5f,         /* SGI */  195.0f, },
525                 /* 40 Mhz */ {  364.5f,         /* SGI */  405.0f, },
526         },
527
528         /* MCS 23  */
529         {       /* 20 Mhz */ {  195.0f,         /* SGI */  216.7f, },
530                 /* 40 Mhz */ {  405.0f,         /* SGI */  450.0f, },
531         },
532
533         /* MCS 24  */
534         {       /* 20 Mhz */ {   26.0f,         /* SGI */   28.9f, },
535                 /* 40 Mhz */ {   54.0f,         /* SGI */   60.0f, },
536         },
537
538         /* MCS 25  */
539         {       /* 20 Mhz */ {   52.0f,         /* SGI */   57.8f, },
540                 /* 40 Mhz */ {  108.0f,         /* SGI */  120.0f, },
541         },
542
543         /* MCS 26  */
544         {       /* 20 Mhz */ {   78.0f,         /* SGI */   86.7f, },
545                 /* 40 Mhz */ {  162.0f,         /* SGI */  180.0f, },
546         },
547
548         /* MCS 27  */
549         {       /* 20 Mhz */ {  104.0f,         /* SGI */  115.6f, },
550                 /* 40 Mhz */ {  216.0f,         /* SGI */  240.0f, },
551         },
552
553         /* MCS 28  */
554         {       /* 20 Mhz */ {  156.0f,         /* SGI */  173.3f, },
555                 /* 40 Mhz */ {  324.0f,         /* SGI */  360.0f, },
556         },
557
558         /* MCS 29  */
559         {       /* 20 Mhz */ {  208.0f,         /* SGI */  231.1f, },
560                 /* 40 Mhz */ {  432.0f,         /* SGI */  480.0f, },
561         },
562
563         /* MCS 30  */
564         {       /* 20 Mhz */ {  234.0f,         /* SGI */  260.0f, },
565                 /* 40 Mhz */ {  486.0f,         /* SGI */  540.0f, },
566         },
567
568         /* MCS 31  */
569         {       /* 20 Mhz */ {  260.0f,         /* SGI */  288.9f, },
570                 /* 40 Mhz */ {  540.0f,         /* SGI */  600.0f, },
571         },
572
573         /* MCS 32  */
574         {       /* 20 Mhz */ {    0.0f,         /* SGI */    0.0f, }, /* not valid */
575                 /* 40 Mhz */ {    6.0f,         /* SGI */    6.7f, },
576         },
577
578         /* MCS 33  */
579         {       /* 20 Mhz */ {   39.0f,         /* SGI */   43.3f, },
580                 /* 40 Mhz */ {   81.0f,         /* SGI */   90.0f, },
581         },
582
583         /* MCS 34  */
584         {       /* 20 Mhz */ {   52.0f,         /* SGI */   57.8f, },
585                 /* 40 Mhz */ {  108.0f,         /* SGI */  120.0f, },
586         },
587
588         /* MCS 35  */
589         {       /* 20 Mhz */ {   65.0f,         /* SGI */   72.2f, },
590                 /* 40 Mhz */ {  135.0f,         /* SGI */  150.0f, },
591         },
592
593         /* MCS 36  */
594         {       /* 20 Mhz */ {   58.5f,         /* SGI */   65.0f, },
595                 /* 40 Mhz */ {  121.5f,         /* SGI */  135.0f, },
596         },
597
598         /* MCS 37  */
599         {       /* 20 Mhz */ {   78.0f,         /* SGI */   86.7f, },
600                 /* 40 Mhz */ {  162.0f,         /* SGI */  180.0f, },
601         },
602
603         /* MCS 38  */
604         {       /* 20 Mhz */ {   97.5f,         /* SGI */  108.3f, },
605                 /* 40 Mhz */ {  202.5f,         /* SGI */  225.0f, },
606         },
607
608         /* MCS 39  */
609         {       /* 20 Mhz */ {   52.0f,         /* SGI */   57.8f, },
610                 /* 40 Mhz */ {  108.0f,         /* SGI */  120.0f, },
611         },
612
613         /* MCS 40  */
614         {       /* 20 Mhz */ {   65.0f,         /* SGI */   72.2f, },
615                 /* 40 Mhz */ {  135.0f,         /* SGI */  150.0f, },
616         },
617
618         /* MCS 41  */
619         {       /* 20 Mhz */ {   65.0f,         /* SGI */   72.2f, },
620                 /* 40 Mhz */ {  135.0f,         /* SGI */  150.0f, },
621         },
622
623         /* MCS 42  */
624         {       /* 20 Mhz */ {   78.0f,         /* SGI */   86.7f, },
625                 /* 40 Mhz */ {  162.0f,         /* SGI */  180.0f, },
626         },
627
628         /* MCS 43  */
629         {       /* 20 Mhz */ {   91.0f,         /* SGI */  101.1f, },
630                 /* 40 Mhz */ {  189.0f,         /* SGI */  210.0f, },
631         },
632
633         /* MCS 44  */
634         {       /* 20 Mhz */ {   91.0f,         /* SGI */  101.1f, },
635                 /* 40 Mhz */ {  189.0f,         /* SGI */  210.0f, },
636         },
637
638         /* MCS 45  */
639         {       /* 20 Mhz */ {  104.0f,         /* SGI */  115.6f, },
640                 /* 40 Mhz */ {  216.0f,         /* SGI */  240.0f, },
641         },
642
643         /* MCS 46  */
644         {       /* 20 Mhz */ {   78.0f,         /* SGI */   86.7f, },
645                 /* 40 Mhz */ {  162.0f,         /* SGI */  180.0f, },
646         },
647
648         /* MCS 47  */
649         {       /* 20 Mhz */ {   97.5f,         /* SGI */  108.3f, },
650                 /* 40 Mhz */ {  202.5f,         /* SGI */  225.0f, },
651         },
652
653         /* MCS 48  */
654         {       /* 20 Mhz */ {   97.5f,         /* SGI */  108.3f, },
655                 /* 40 Mhz */ {  202.5f,         /* SGI */  225.0f, },
656         },
657
658         /* MCS 49  */
659         {       /* 20 Mhz */ {  117.0f,         /* SGI */  130.0f, },
660                 /* 40 Mhz */ {  243.0f,         /* SGI */  270.0f, },
661         },
662
663         /* MCS 50  */
664         {       /* 20 Mhz */ {  136.5f,         /* SGI */  151.7f, },
665                 /* 40 Mhz */ {  283.5f,         /* SGI */  315.0f, },
666         },
667
668         /* MCS 51  */
669         {       /* 20 Mhz */ {  136.5f,         /* SGI */  151.7f, },
670                 /* 40 Mhz */ {  283.5f,         /* SGI */  315.0f, },
671         },
672
673         /* MCS 52  */
674         {       /* 20 Mhz */ {  156.0f,         /* SGI */  173.3f, },
675                 /* 40 Mhz */ {  324.0f,         /* SGI */  360.0f, },
676         },
677
678         /* MCS 53  */
679         {       /* 20 Mhz */ {   65.0f,         /* SGI */   72.2f, },
680                 /* 40 Mhz */ {  135.0f,         /* SGI */  150.0f, },
681         },
682
683         /* MCS 54  */
684         {       /* 20 Mhz */ {   78.0f,         /* SGI */   86.7f, },
685                 /* 40 Mhz */ {  162.0f,         /* SGI */  180.0f, },
686         },
687
688         /* MCS 55  */
689         {       /* 20 Mhz */ {   91.0f,         /* SGI */  101.1f, },
690                 /* 40 Mhz */ {  189.0f,         /* SGI */  210.0f, },
691         },
692
693         /* MCS 56  */
694         {       /* 20 Mhz */ {   78.0f,         /* SGI */   86.7f, },
695                 /* 40 Mhz */ {  162.0f,         /* SGI */  180.0f, },
696         },
697
698         /* MCS 57  */
699         {       /* 20 Mhz */ {   91.0f,         /* SGI */  101.1f, },
700                 /* 40 Mhz */ {  189.0f,         /* SGI */  210.0f, },
701         },
702
703         /* MCS 58  */
704         {       /* 20 Mhz */ {  104.0f,         /* SGI */  115.6f, },
705                 /* 40 Mhz */ {  216.0f,         /* SGI */  240.0f, },
706         },
707
708         /* MCS 59  */
709         {       /* 20 Mhz */ {  117.0f,         /* SGI */  130.0f, },
710                 /* 40 Mhz */ {  243.0f,         /* SGI */  270.0f, },
711         },
712
713         /* MCS 60  */
714         {       /* 20 Mhz */ {  104.0f,         /* SGI */  115.6f, },
715                 /* 40 Mhz */ {  216.0f,         /* SGI */  240.0f, },
716         },
717
718         /* MCS 61  */
719         {       /* 20 Mhz */ {  117.0f,         /* SGI */  130.0f, },
720                 /* 40 Mhz */ {  243.0f,         /* SGI */  270.0f, },
721         },
722
723         /* MCS 62  */
724         {       /* 20 Mhz */ {  130.0f,         /* SGI */  144.4f, },
725                 /* 40 Mhz */ {  270.0f,         /* SGI */  300.0f, },
726         },
727
728         /* MCS 63  */
729         {       /* 20 Mhz */ {  130.0f,         /* SGI */  144.4f, },
730                 /* 40 Mhz */ {  270.0f,         /* SGI */  300.0f, },
731         },
732
733         /* MCS 64  */
734         {       /* 20 Mhz */ {  143.0f,         /* SGI */  158.9f, },
735                 /* 40 Mhz */ {  297.0f,         /* SGI */  330.0f, },
736         },
737
738         /* MCS 65  */
739         {       /* 20 Mhz */ {   97.5f,         /* SGI */  108.3f, },
740                 /* 40 Mhz */ {  202.5f,         /* SGI */  225.0f, },
741         },
742
743         /* MCS 66  */
744         {       /* 20 Mhz */ {  117.0f,         /* SGI */  130.0f, },
745                 /* 40 Mhz */ {  243.0f,         /* SGI */  270.0f, },
746         },
747
748         /* MCS 67  */
749         {       /* 20 Mhz */ {  136.5f,         /* SGI */  151.7f, },
750                 /* 40 Mhz */ {  283.5f,         /* SGI */  315.0f, },
751         },
752
753         /* MCS 68  */
754         {       /* 20 Mhz */ {  117.0f,         /* SGI */  130.0f, },
755                 /* 40 Mhz */ {  243.0f,         /* SGI */  270.0f, },
756         },
757
758         /* MCS 69  */
759         {       /* 20 Mhz */ {  136.5f,         /* SGI */  151.7f, },
760                 /* 40 Mhz */ {  283.5f,         /* SGI */  315.0f, },
761         },
762
763         /* MCS 70  */
764         {       /* 20 Mhz */ {  156.0f,         /* SGI */  173.3f, },
765                 /* 40 Mhz */ {  324.0f,         /* SGI */  360.0f, },
766         },
767
768         /* MCS 71  */
769         {       /* 20 Mhz */ {  175.5f,         /* SGI */  195.0f, },
770                 /* 40 Mhz */ {  364.5f,         /* SGI */  405.0f, },
771         },
772
773         /* MCS 72  */
774         {       /* 20 Mhz */ {  156.0f,         /* SGI */  173.3f, },
775                 /* 40 Mhz */ {  324.0f,         /* SGI */  360.0f, },
776         },
777
778         /* MCS 73  */
779         {       /* 20 Mhz */ {  175.5f,         /* SGI */  195.0f, },
780                 /* 40 Mhz */ {  364.5f,         /* SGI */  405.0f, },
781         },
782
783         /* MCS 74  */
784         {       /* 20 Mhz */ {  195.0f,         /* SGI */  216.7f, },
785                 /* 40 Mhz */ {  405.0f,         /* SGI */  450.0f, },
786         },
787
788         /* MCS 75  */
789         {       /* 20 Mhz */ {  195.0f,         /* SGI */  216.7f, },
790                 /* 40 Mhz */ {  405.0f,         /* SGI */  450.0f, },
791         },
792
793         /* MCS 76  */
794         {       /* 20 Mhz */ {  214.5f,         /* SGI */  238.3f, },
795                 /* 40 Mhz */ {  445.5f,         /* SGI */  495.0f, },
796         },
797 };
798
799 /* In order by value */
800 static const value_string phy_type[] = {
801         {0,                                       "Unknown"},                 /* 0x00000 */
802         {IEEE80211_CHAN_B,                        "802.11b"},                 /* 0x000a0 */
803         {IEEE80211_CHAN_PUREG,                    "802.11g (pure-g)"},        /* 0x000c0 */
804         {IEEE80211_CHAN_108PUREG,                 "802.11g (pure-g, turbo)"}, /* 0x000d0 */
805         {IEEE80211_CHAN_A,                        "802.11a"},                 /* 0x00140 */
806         {IEEE80211_CHAN_T,                        "802.11a (turbo)"},         /* 0x00150 */
807         {IEEE80211_CHAN_G,                        "802.11g"},                 /* 0x00480 */
808         {IEEE80211_CHAN_108G,                     "802.11g (turbo)"},         /* 0x00490 */
809         {IEEE80211_CHAN_FHSS,                     "FHSS"},                    /* 0x00880 */
810         {IEEE80211_CHAN_A | IEEE80211_CHAN_HT20,  "802.11a (ht20)"},          /* 0x10140 */
811         {IEEE80211_CHAN_G | IEEE80211_CHAN_HT20,  "802.11g (ht20)"},          /* 0x10480 */
812         {IEEE80211_CHAN_A | IEEE80211_CHAN_HT40U, "802.11a (ht40+)"},         /* 0x20140 */
813         {IEEE80211_CHAN_G | IEEE80211_CHAN_HT40U, "802.11g (ht40+)"},         /* 0x20480 */
814         {IEEE80211_CHAN_A | IEEE80211_CHAN_HT40D, "802.11a (ht40-)"},         /* 0x40140 */
815         {IEEE80211_CHAN_G | IEEE80211_CHAN_HT40D, "802.11g (ht40-)"},         /* 0x40480 */
816         {0, NULL}
817 };
818 static value_string_ext phy_type_ext = VALUE_STRING_EXT_INIT(phy_type);
819
820 static const value_string mcs_bandwidth[] = {
821         { IEEE80211_RADIOTAP_MCS_BW_20,  "20 MHz" },
822         { IEEE80211_RADIOTAP_MCS_BW_40,  "40 MHz" },
823         { IEEE80211_RADIOTAP_MCS_BW_20L, "20 MHz lower" },
824         { IEEE80211_RADIOTAP_MCS_BW_20U, "20 MHz upper" },
825         {0, NULL}
826 };
827
828 static const value_string mcs_format[] = {
829         { 0, "mixed" },
830         { 1, "greenfield" },
831         {0, NULL},
832 };
833
834 static const value_string mcs_fec[] = {
835         { 0, "BCC" },
836         { 1, "LDPC" },
837         {0, NULL}
838 };
839
840 static const value_string mcs_gi[] = {
841         { 0, "long" },
842         { 1, "short" },
843         {0, NULL}
844 };
845
846 static const true_false_string preamble_type = {
847         "Short",
848         "Long",
849 };
850
851 /*
852  * The NetBSD ieee80211_radiotap man page
853  * (http://netbsd.gw.com/cgi-bin/man-cgi?ieee80211_radiotap+9+NetBSD-current)
854  * says:
855  *
856  *    Radiotap capture fields must be naturally aligned.  That is, 16-, 32-,
857  *    and 64-bit fields must begin on 16-, 32-, and 64-bit boundaries, respec-
858  *    tively.  In this way, drivers can avoid unaligned accesses to radiotap
859  *    capture fields.  radiotap-compliant drivers must insert padding before a
860  *    capture field to ensure its natural alignment.  radiotap-compliant packet
861  *    dissectors, such as tcpdump(8), expect the padding.
862  */
863
864 void
865 capture_radiotap(const guchar * pd, int offset, int len, packet_counts * ld)
866 {
867         guint16 it_len;
868         guint32 present, xpresent;
869         guint8  rflags;
870         struct ieee80211_radiotap_header *hdr;
871
872         if (!BYTES_ARE_IN_FRAME(offset, len,
873                                 sizeof(struct ieee80211_radiotap_header))) {
874                 ld->other++;
875                 return;
876         }
877         hdr = (void *)pd;
878         it_len = pletohs(&hdr->it_len);
879         if (!BYTES_ARE_IN_FRAME(offset, len, it_len)) {
880                 ld->other++;
881                 return;
882         }
883
884         if (it_len > len) {
885                 /* Header length is bigger than total packet length */
886                 ld->other++;
887                 return;
888         }
889
890         if (it_len < sizeof(struct ieee80211_radiotap_header)) {
891                 /* Header length is shorter than fixed-length portion of header */
892                 ld->other++;
893                 return;
894         }
895
896         present = pletohl(&hdr->it_present);
897         offset += (int)sizeof(struct ieee80211_radiotap_header);
898         it_len -= (int)sizeof(struct ieee80211_radiotap_header);
899
900         /* skip over other present bitmaps */
901         xpresent = present;
902         while (xpresent & BIT(IEEE80211_RADIOTAP_EXT)) {
903                 if (!BYTES_ARE_IN_FRAME(offset, 4, it_len)) {
904                         ld->other++;
905                         return;
906                 }
907                 xpresent = pletohl(pd + offset);
908                 offset += 4;
909                 it_len -= 4;
910         }
911
912         rflags = 0;
913
914         /*
915          * IEEE80211_RADIOTAP_TSFT is the lowest-order bit,
916          * just skip over it.
917          */
918         if (present & BIT(IEEE80211_RADIOTAP_TSFT)) {
919                 /* align it properly */
920                 if (offset & 7) {
921                         int pad = 8 - (offset & 7);
922                         offset += pad;
923                         it_len -= pad;
924                 }
925
926                 if (it_len < 8) {
927                         /* No room in header for this field. */
928                         ld->other++;
929                         return;
930                 }
931                 /* That field is present, and it's 8 bytes long. */
932                 offset += 8;
933                 it_len -= 8;
934         }
935
936         /*
937          * IEEE80211_RADIOTAP_FLAGS is the next bit.
938          */
939         if (present & BIT(IEEE80211_RADIOTAP_FLAGS)) {
940                 if (it_len < 1) {
941                         /* No room in header for this field. */
942                         ld->other++;
943                         return;
944                 }
945                 /* That field is present; fetch it. */
946                 if (!BYTES_ARE_IN_FRAME(offset, len, 1)) {
947                         ld->other++;
948                         return;
949                 }
950                 rflags = pd[offset];
951         }
952
953         /* 802.11 header follows */
954         if (rflags & IEEE80211_RADIOTAP_F_DATAPAD)
955                 capture_ieee80211_datapad(pd, offset + it_len, len, ld);
956         else
957                 capture_ieee80211(pd, offset + it_len, len, ld);
958 }
959
960 static void
961 dissect_radiotap(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree)
962 {
963         proto_tree *radiotap_tree     = NULL;
964         proto_tree *pt, *present_tree = NULL;
965         proto_tree *ft;
966         proto_item *ti                = NULL;
967         proto_item *hidden_item;
968         int         offset;
969         tvbuff_t   *next_tvb;
970         guint8      version;
971         guint       length;
972         guint32     freq;
973         proto_item *rate_ti;
974         gint8       dbm, db;
975         guint8      rflags            = 0;
976         /* backward compat with bit 14 == fcs in header */
977         proto_item *hdr_fcs_ti        = NULL;
978         int         hdr_fcs_offset    = 0;
979         guint32     sent_fcs          = 0;
980         guint32     calc_fcs;
981         gint        err               = -ENOENT;
982         void       *data;
983         struct _radiotap_info              *radiotap_info;
984         static struct _radiotap_info        rtp_info_arr;
985         struct ieee80211_radiotap_iterator  iter;
986
987         /* our non-standard overrides */
988         static struct radiotap_override overrides[] = {
989                 {IEEE80211_RADIOTAP_XCHANNEL, 4, 8},    /* xchannel */
990
991                 /* keep last */
992                 {14, 4, 4},     /* FCS in header */
993         };
994         guint n_overrides = array_length(overrides);
995
996         if (!radiotap_bit14_fcs)
997                 n_overrides--;
998
999         radiotap_info = &rtp_info_arr;
1000
1001         col_set_str(pinfo->cinfo, COL_PROTOCOL, "WLAN");
1002         col_clear(pinfo->cinfo, COL_INFO);
1003
1004         version = tvb_get_guint8(tvb, 0);
1005         length = tvb_get_letohs(tvb, 2);
1006
1007         radiotap_info->radiotap_length = length;
1008
1009         col_add_fstr(pinfo->cinfo, COL_INFO, "Radiotap Capture v%u, Length %u",
1010                      version, length);
1011
1012         /* Dissect the packet */
1013         if (tree) {
1014                 ti = proto_tree_add_protocol_format(tree, proto_radiotap,
1015                                                     tvb, 0, length,
1016                                                     "Radiotap Header v%u, Length %u",
1017                                                     version, length);
1018                 radiotap_tree = proto_item_add_subtree(ti, ett_radiotap);
1019                 proto_tree_add_uint(radiotap_tree, hf_radiotap_version,
1020                                     tvb, 0, 1, version);
1021                 proto_tree_add_item(radiotap_tree, hf_radiotap_pad,
1022                                     tvb, 1, 1, ENC_BIG_ENDIAN);
1023                 proto_tree_add_uint(radiotap_tree, hf_radiotap_length,
1024                                     tvb, 2, 2, length);
1025         }
1026
1027         data = ep_tvb_memdup(tvb, 0, length);
1028         if (!data)
1029                 return;
1030
1031         if (ieee80211_radiotap_iterator_init(&iter, data, length, NULL)) {
1032                 if (tree)
1033                         proto_item_append_text(ti, " (invalid)");
1034                 /* maybe the length was correct anyway ... */
1035                 goto hand_off_to_80211;
1036         }
1037
1038         iter.overrides = overrides;
1039         iter.n_overrides = n_overrides;
1040
1041         /* Add the "present flags" bitmaps. */
1042         if (tree) {
1043                 guchar   *bmap_start          = (guchar *)data + 4;
1044                 guint     n_bitmaps           = (guint)(iter.this_arg - bmap_start) / 4;
1045                 guint     i;
1046                 gboolean  rtap_ns;
1047                 gboolean  rtap_ns_next        = TRUE;
1048                 guint     rtap_ns_offset;
1049                 guint     rtap_ns_offset_next = 0;
1050
1051                 pt = proto_tree_add_item(radiotap_tree, hf_radiotap_present,
1052                                          tvb, 4, n_bitmaps * 4,
1053                                          ENC_NA);
1054
1055                 for (i = 0; i < n_bitmaps; i++) {
1056                         guint32 bmap = pletohl(bmap_start + 4 * i);
1057
1058                         rtap_ns_offset = rtap_ns_offset_next;
1059                         rtap_ns_offset_next += 32;
1060
1061                         present_tree =
1062                             proto_item_add_subtree(pt, ett_radiotap_present);
1063
1064                         offset = 4 * i;
1065
1066                         rtap_ns = rtap_ns_next;
1067
1068                         /* Evaluate what kind of namespaces will come next */
1069                         if (bmap & BIT(IEEE80211_RADIOTAP_RADIOTAP_NAMESPACE)) {
1070                                 rtap_ns_next = TRUE;
1071                                 rtap_ns_offset_next = 0;
1072                         }
1073                         if (bmap & BIT(IEEE80211_RADIOTAP_VENDOR_NAMESPACE))
1074                                 rtap_ns_next = FALSE;
1075                         if ((bmap & (BIT(IEEE80211_RADIOTAP_RADIOTAP_NAMESPACE) |
1076                                      BIT(IEEE80211_RADIOTAP_VENDOR_NAMESPACE)))
1077                                 == (BIT(IEEE80211_RADIOTAP_RADIOTAP_NAMESPACE) |
1078                                     BIT(IEEE80211_RADIOTAP_VENDOR_NAMESPACE)))
1079                                 goto malformed;
1080
1081                         if (!rtap_ns)
1082                                 goto always_bits;
1083
1084                         /* Currently, we don't know anything about bits >= 32 */
1085                         if (rtap_ns_offset)
1086                                 goto always_bits;
1087
1088                         proto_tree_add_item(present_tree,
1089                                             hf_radiotap_present_tsft, tvb,
1090                                             offset + 4, 4, ENC_LITTLE_ENDIAN);
1091                         proto_tree_add_item(present_tree,
1092                                             hf_radiotap_present_flags, tvb,
1093                                             offset + 4, 4, ENC_LITTLE_ENDIAN);
1094                         proto_tree_add_item(present_tree,
1095                                             hf_radiotap_present_rate, tvb,
1096                                             offset + 4, 4, ENC_LITTLE_ENDIAN);
1097                         proto_tree_add_item(present_tree,
1098                                             hf_radiotap_present_channel, tvb,
1099                                             offset + 4, 4, ENC_LITTLE_ENDIAN);
1100                         proto_tree_add_item(present_tree,
1101                                             hf_radiotap_present_fhss, tvb,
1102                                             offset + 4, 4, ENC_LITTLE_ENDIAN);
1103                         proto_tree_add_item(present_tree,
1104                                             hf_radiotap_present_dbm_antsignal,
1105                                             tvb, offset + 4, 4, ENC_LITTLE_ENDIAN);
1106                         proto_tree_add_item(present_tree,
1107                                             hf_radiotap_present_dbm_antnoise,
1108                                             tvb, offset + 4, 4, ENC_LITTLE_ENDIAN);
1109                         proto_tree_add_item(present_tree,
1110                                             hf_radiotap_present_lock_quality,
1111                                             tvb, offset + 4, 4, ENC_LITTLE_ENDIAN);
1112                         proto_tree_add_item(present_tree,
1113                                             hf_radiotap_present_tx_attenuation,
1114                                             tvb, offset + 4, 4, ENC_LITTLE_ENDIAN);
1115                         proto_tree_add_item(present_tree,
1116                                             hf_radiotap_present_db_tx_attenuation,
1117                                             tvb, offset + 4, 4, ENC_LITTLE_ENDIAN);
1118                         proto_tree_add_item(present_tree,
1119                                             hf_radiotap_present_dbm_tx_power,
1120                                             tvb, offset + 4, 4, ENC_LITTLE_ENDIAN);
1121                         proto_tree_add_item(present_tree,
1122                                             hf_radiotap_present_antenna, tvb,
1123                                             offset + 4, 4, ENC_LITTLE_ENDIAN);
1124                         proto_tree_add_item(present_tree,
1125                                             hf_radiotap_present_db_antsignal,
1126                                             tvb, offset + 4, 4, ENC_LITTLE_ENDIAN);
1127                         proto_tree_add_item(present_tree,
1128                                             hf_radiotap_present_db_antnoise,
1129                                             tvb, offset + 4, 4, ENC_LITTLE_ENDIAN);
1130                         if (radiotap_bit14_fcs) {
1131                                 proto_tree_add_item(present_tree,
1132                                                     hf_radiotap_present_hdrfcs,
1133                                                     tvb, offset + 4, 4, ENC_LITTLE_ENDIAN);
1134                         } else {
1135                                 proto_tree_add_item(present_tree,
1136                                                     hf_radiotap_present_rxflags,
1137                                                     tvb, offset + 4, 4, ENC_LITTLE_ENDIAN);
1138                         }
1139                         proto_tree_add_item(present_tree,
1140                                             hf_radiotap_present_xchannel, tvb,
1141                                             offset + 4, 4, ENC_LITTLE_ENDIAN);
1142
1143                         proto_tree_add_item(present_tree,
1144                                             hf_radiotap_present_mcs, tvb,
1145                                             offset + 4, 4, ENC_LITTLE_ENDIAN);
1146                         proto_tree_add_item(present_tree,
1147                                             hf_radiotap_present_ampdu, tvb,
1148                                             offset + 4, 4, ENC_LITTLE_ENDIAN);
1149                         proto_tree_add_item(present_tree,
1150                                             hf_radiotap_present_vht, tvb,
1151                                             offset + 4, 4, ENC_LITTLE_ENDIAN);
1152                         ti = proto_tree_add_item(present_tree,
1153                                             hf_radiotap_present_reserved, tvb,
1154                                             offset + 4, 4, ENC_LITTLE_ENDIAN);
1155                         /* Check if Reserved/Not Defined is not "zero" */
1156                         if(bmap & IEEE80211_RADIOTAP_NOTDEFINED)
1157                         {
1158                                 expert_add_info_format(pinfo,ti, PI_UNDECODED, PI_NOTE,
1159                                 "Unknown Radiotap fields, code not implemented, "
1160                                 "Please check radiotap documentation, "
1161                                 "Contact Wireshark developers if you want this supported" );
1162                         }
1163  always_bits:
1164                         proto_tree_add_item(present_tree,
1165                                             hf_radiotap_present_rtap_ns, tvb,
1166                                             offset + 4, 4, ENC_LITTLE_ENDIAN);
1167                         proto_tree_add_item(present_tree,
1168                                             hf_radiotap_present_vendor_ns, tvb,
1169                                             offset + 4, 4, ENC_LITTLE_ENDIAN);
1170                         proto_tree_add_item(present_tree,
1171                                             hf_radiotap_present_ext, tvb,
1172                                             offset + 4, 4, ENC_LITTLE_ENDIAN);
1173                 }
1174         }
1175
1176         while (!(err = ieee80211_radiotap_iterator_next(&iter))) {
1177                 offset = (int)((guchar *) iter.this_arg - (guchar *) data);
1178
1179                 if (iter.this_arg_index == IEEE80211_RADIOTAP_VENDOR_NAMESPACE
1180                     && tree) {
1181                         proto_tree *vt, *ven_tree = NULL;
1182                         const gchar *manuf_name;
1183                         guint8 subns;
1184
1185                         manuf_name = tvb_get_manuf_name(tvb, offset);
1186                         subns = tvb_get_guint8(tvb, offset+3);
1187
1188                         vt = proto_tree_add_bytes_format(radiotap_tree,
1189                                                          hf_radiotap_vendor_ns,
1190                                                          tvb, offset,
1191                                                          iter.this_arg_size,
1192                                                          NULL,
1193                                                          "Vendor namespace: %s-%d",
1194                                                          manuf_name, subns);
1195                         ven_tree = proto_item_add_subtree(vt, ett_radiotap_vendor);
1196                         proto_tree_add_bytes_format(ven_tree,
1197                                                     hf_radiotap_ven_oui, tvb,
1198                                                     offset, 3, NULL,
1199                                                     "Vendor: %s", manuf_name);
1200                         proto_tree_add_item(ven_tree, hf_radiotap_ven_subns,
1201                                             tvb, offset + 3, 1, ENC_BIG_ENDIAN);
1202                         proto_tree_add_item(ven_tree, hf_radiotap_ven_skip, tvb,
1203                                             offset + 4, 2, ENC_LITTLE_ENDIAN);
1204                         proto_tree_add_item(ven_tree, hf_radiotap_ven_data, tvb,
1205                                             offset + 6, iter.this_arg_size - 6,
1206                                             ENC_NA);
1207                 }
1208
1209                 if (!iter.is_radiotap_ns)
1210                         continue;
1211
1212                 switch (iter.this_arg_index) {
1213
1214                 case IEEE80211_RADIOTAP_TSFT:
1215                         radiotap_info->tsft = tvb_get_letoh64(tvb, offset);
1216                         if (tree) {
1217                                 proto_tree_add_uint64(radiotap_tree,
1218                                                       hf_radiotap_mactime, tvb,
1219                                                       offset, 8,
1220                                                       radiotap_info->tsft);
1221                         }
1222                         break;
1223
1224                 case IEEE80211_RADIOTAP_FLAGS: {
1225                         rflags = tvb_get_guint8(tvb, offset);
1226                         if (tree) {
1227                                 proto_tree *flags_tree;
1228
1229                                 ft = proto_tree_add_item(radiotap_tree,
1230                                                          hf_radiotap_flags,
1231                                                          tvb, offset, 1, ENC_BIG_ENDIAN);
1232                                 flags_tree =
1233                                     proto_item_add_subtree(ft,
1234                                                            ett_radiotap_flags);
1235
1236                                 proto_tree_add_item(flags_tree,
1237                                                     hf_radiotap_flags_cfp,
1238                                                     tvb, offset, 1, ENC_BIG_ENDIAN);
1239                                 proto_tree_add_item(flags_tree,
1240                                                     hf_radiotap_flags_preamble,
1241                                                     tvb, offset, 1, ENC_BIG_ENDIAN);
1242                                 proto_tree_add_item(flags_tree,
1243                                                     hf_radiotap_flags_wep,
1244                                                     tvb, offset, 1, ENC_BIG_ENDIAN);
1245                                 proto_tree_add_item(flags_tree,
1246                                                     hf_radiotap_flags_frag,
1247                                                     tvb, offset, 1, ENC_BIG_ENDIAN);
1248                                 proto_tree_add_item(flags_tree,
1249                                                     hf_radiotap_flags_fcs,
1250                                                     tvb, offset, 1, ENC_BIG_ENDIAN);
1251                                 proto_tree_add_item(flags_tree,
1252                                                     hf_radiotap_flags_datapad,
1253                                                     tvb, offset, 1, ENC_BIG_ENDIAN);
1254                                 proto_tree_add_item(flags_tree,
1255                                                     hf_radiotap_flags_badfcs,
1256                                                     tvb, offset, 1, ENC_BIG_ENDIAN);
1257                                 proto_tree_add_item(flags_tree,
1258                                                     hf_radiotap_flags_shortgi,
1259                                                     tvb, offset, 1, ENC_BIG_ENDIAN);
1260                         }
1261                         break;
1262                 }
1263
1264                 case IEEE80211_RADIOTAP_RATE: {
1265                         guint32 rate;
1266                         rate = tvb_get_guint8(tvb, offset);
1267                         /*
1268                          * XXX On FreeBSD rate & 0x80 means we have an MCS. On
1269                          * Linux and AirPcap it does not.  (What about
1270                          * Mac OS X, NetBSD, OpenBSD, and DragonFly BSD?)
1271                          *
1272                          * This is an issue either for proprietary extensions
1273                          * to 11a or 11g, which do exist, or for 11n
1274                          * implementations that stuff a rate value into
1275                          * this field, which also appear to exist.
1276                          *
1277                          * We currently handle that by assuming that
1278                          * if the 0x80 bit is set *and* the remaining
1279                          * bits have a value between 0 and 15 it's
1280                          * an MCS value, otherwise it's a rate.  If
1281                          * there are cases where systems that use
1282                          * "0x80 + MCS index" for MCS indices > 15,
1283                          * or stuff a rate value here between 64 and
1284                          * 71.5 Mb/s in here, we'll need a preference
1285                          * setting.  Such rates do exist, e.g. 11n
1286                          * MCS 7 at 20 MHz with a long guard interval.
1287                          */
1288                         if (rate >= 0x80 && rate <= 0x8f) {
1289                                 /*
1290                                  * XXX - we don't know the channel width
1291                                  * or guard interval length, so we can't
1292                                  * convert this to a data rate.
1293                                  *
1294                                  * If you want us to show a data rate,
1295                                  * use the MCS field, not the Rate field;
1296                                  * the MCS field includes not only the
1297                                  * MCS index, it also includes bandwidth
1298                                  * and guard interval information.
1299                                  *
1300                                  * XXX - can we get the channel width
1301                                  * from XChannel and the guard interval
1302                                  * information from Flags, at least on
1303                                  * FreeBSD?
1304                                  */
1305                                 if (tree) {
1306                                         proto_tree_add_uint(radiotap_tree,
1307                                                             hf_radiotap_mcs_index,
1308                                                             tvb, offset, 1,
1309                                                             rate & 0x7f);
1310                                 }
1311                         } else {
1312                                 col_add_fstr(pinfo->cinfo, COL_TX_RATE, "%d.%d",
1313                                              rate / 2, rate & 1 ? 5 : 0);
1314                                 if (tree) {
1315                                         proto_tree_add_float_format(radiotap_tree,
1316                                                                     hf_radiotap_datarate,
1317                                                                     tvb, offset, 1,
1318                                                                     (float)rate / 2,
1319                                                                     "Data Rate: %.1f Mb/s",
1320                                                                     (float)rate / 2);
1321                                 }
1322                                 radiotap_info->rate = rate;
1323                         }
1324                         break;
1325                 }
1326
1327                 case IEEE80211_RADIOTAP_CHANNEL: {
1328                         if (tree) {
1329                                 proto_item *it;
1330                                 proto_tree *flags_tree;
1331                                 guint16     flags;
1332                                 gchar      *chan_str;
1333
1334                                 freq     = tvb_get_letohs(tvb, offset);
1335                                 flags    = tvb_get_letohs(tvb, offset + 2);
1336                                 chan_str = ieee80211_mhz_to_str(freq);
1337                                 col_add_fstr(pinfo->cinfo,
1338                                              COL_FREQ_CHAN, "%s", chan_str);
1339                                 proto_tree_add_uint_format(radiotap_tree,
1340                                                            hf_radiotap_channel_frequency,
1341                                                            tvb, offset, 2, freq,
1342                                                            "Channel frequency: %s",
1343                                                            chan_str);
1344                                 g_free(chan_str);
1345                                 /* We're already 2-byte aligned. */
1346                                 it = proto_tree_add_uint(radiotap_tree,
1347                                                          hf_radiotap_channel_flags,
1348                                                          tvb, offset + 2, 2, flags);
1349                                 flags_tree =
1350                                     proto_item_add_subtree(it,
1351                                                            ett_radiotap_channel_flags);
1352                                 proto_tree_add_boolean(flags_tree,
1353                                                        hf_radiotap_channel_flags_turbo,
1354                                                        tvb, offset + 2, 1, flags);
1355                                 proto_tree_add_boolean(flags_tree,
1356                                                        hf_radiotap_channel_flags_cck,
1357                                                        tvb, offset + 2, 1, flags);
1358                                 proto_tree_add_boolean(flags_tree,
1359                                                        hf_radiotap_channel_flags_ofdm,
1360                                                        tvb, offset + 2, 1, flags);
1361                                 proto_tree_add_boolean(flags_tree,
1362                                                        hf_radiotap_channel_flags_2ghz,
1363                                                        tvb, offset + 2, 1, flags);
1364                                 proto_tree_add_boolean(flags_tree,
1365                                                        hf_radiotap_channel_flags_5ghz,
1366                                                        tvb, offset + 3, 1, flags);
1367                                 proto_tree_add_boolean(flags_tree,
1368                                                        hf_radiotap_channel_flags_passive,
1369                                                        tvb, offset + 3, 1, flags);
1370                                 proto_tree_add_boolean(flags_tree,
1371                                                        hf_radiotap_channel_flags_dynamic,
1372                                                        tvb, offset + 3, 1, flags);
1373                                 proto_tree_add_boolean(flags_tree,
1374                                                        hf_radiotap_channel_flags_gfsk,
1375                                                        tvb, offset + 3, 1, flags);
1376                                 proto_tree_add_boolean(flags_tree,
1377                                                        hf_radiotap_channel_flags_gsm,
1378                                                        tvb, offset + 3, 1, flags);
1379                                 proto_tree_add_boolean(flags_tree,
1380                                                        hf_radiotap_channel_flags_sturbo,
1381                                                        tvb, offset + 3, 1, flags);
1382                                 proto_tree_add_boolean(flags_tree,
1383                                                        hf_radiotap_channel_flags_half,
1384                                                        tvb, offset + 3, 1, flags);
1385                                 proto_tree_add_boolean(flags_tree,
1386                                                        hf_radiotap_channel_flags_quarter,
1387                                                        tvb, offset + 3, 1, flags);
1388                                 radiotap_info->freq = freq;
1389                                 radiotap_info->flags = flags;
1390                         }
1391                         break;
1392                 }
1393
1394                 case IEEE80211_RADIOTAP_FHSS:
1395                         proto_tree_add_item(radiotap_tree,
1396                                             hf_radiotap_fhss_hopset, tvb,
1397                                             offset, 1, ENC_BIG_ENDIAN);
1398                         proto_tree_add_item(radiotap_tree,
1399                                             hf_radiotap_fhss_pattern, tvb,
1400                                             offset, 1, ENC_BIG_ENDIAN);
1401                         break;
1402
1403                 case IEEE80211_RADIOTAP_DBM_ANTSIGNAL:
1404                         dbm = (gint8)tvb_get_guint8(tvb, offset);
1405                         col_add_fstr(pinfo->cinfo, COL_RSSI, "%d dBm", dbm);
1406                         if (tree) {
1407                                 proto_tree_add_int_format(radiotap_tree,
1408                                                           hf_radiotap_dbm_antsignal,
1409                                                           tvb, offset, 1, dbm,
1410                                                           "SSI Signal: %d dBm",
1411                                                           dbm);
1412                         }
1413                         radiotap_info->dbm_antsignal = dbm;
1414                         break;
1415
1416                 case IEEE80211_RADIOTAP_DBM_ANTNOISE:
1417                         dbm = (gint8) tvb_get_guint8(tvb, offset);
1418                         if (tree) {
1419                                 proto_tree_add_int_format(radiotap_tree,
1420                                                           hf_radiotap_dbm_antnoise,
1421                                                           tvb, offset, 1, dbm,
1422                                                           "SSI Noise: %d dBm",
1423                                                           dbm);
1424                         }
1425                         radiotap_info->dbm_antnoise = dbm;
1426                         break;
1427
1428                 case IEEE80211_RADIOTAP_LOCK_QUALITY:
1429                         if (tree) {
1430                                 proto_tree_add_uint(radiotap_tree,
1431                                                     hf_radiotap_quality, tvb,
1432                                                     offset, 2,
1433                                                     tvb_get_letohs(tvb,
1434                                                                    offset));
1435                         }
1436                         break;
1437
1438                 case IEEE80211_RADIOTAP_TX_ATTENUATION:
1439                         proto_tree_add_item(radiotap_tree,
1440                                             hf_radiotap_tx_attenuation, tvb,
1441                                             offset, 2, ENC_BIG_ENDIAN);
1442                         break;
1443
1444                 case IEEE80211_RADIOTAP_DB_TX_ATTENUATION:
1445                         proto_tree_add_item(radiotap_tree,
1446                                             hf_radiotap_db_tx_attenuation, tvb,
1447                                             offset, 2, ENC_BIG_ENDIAN);
1448                         break;
1449
1450                 case IEEE80211_RADIOTAP_DBM_TX_POWER:
1451                         if (tree) {
1452                                 proto_tree_add_int(radiotap_tree,
1453                                                    hf_radiotap_txpower, tvb,
1454                                                    offset, 1,
1455                                                    tvb_get_guint8(tvb, offset));
1456                         }
1457                         break;
1458
1459                 case IEEE80211_RADIOTAP_ANTENNA:
1460                         if (tree) {
1461                                 proto_tree_add_uint(radiotap_tree,
1462                                                     hf_radiotap_antenna, tvb,
1463                                                     offset, 1,
1464                                                     tvb_get_guint8(tvb,
1465                                                                    offset));
1466                         }
1467                         break;
1468
1469                 case IEEE80211_RADIOTAP_DB_ANTSIGNAL:
1470                         db = tvb_get_guint8(tvb, offset);
1471                         col_add_fstr(pinfo->cinfo, COL_RSSI, "%u dB", db);
1472                         if (tree) {
1473                                 proto_tree_add_uint_format(radiotap_tree,
1474                                                            hf_radiotap_db_antsignal,
1475                                                            tvb, offset, 1, db,
1476                                                            "SSI Signal: %u dB",
1477                                                            db);
1478                         }
1479                         break;
1480
1481                 case IEEE80211_RADIOTAP_DB_ANTNOISE:
1482                         db = tvb_get_guint8(tvb, offset);
1483                         if (tree) {
1484                                 proto_tree_add_uint_format(radiotap_tree,
1485                                                            hf_radiotap_db_antnoise,
1486                                                            tvb, offset, 1, db,
1487                                                            "SSI Noise: %u dB",
1488                                                            db);
1489                         }
1490                         break;
1491
1492                 case IEEE80211_RADIOTAP_RX_FLAGS: {
1493                         if (radiotap_bit14_fcs) {
1494                                 if (tree) {
1495                                         sent_fcs   = tvb_get_ntohl(tvb, offset);
1496                                         hdr_fcs_ti = proto_tree_add_uint(radiotap_tree,
1497                                                                          hf_radiotap_fcs, tvb,
1498                                                                          offset, 4, sent_fcs);
1499                                         hdr_fcs_offset = offset;
1500                                 }
1501                         } else {
1502
1503                                 if (tree) {
1504                                         proto_tree *flags_tree;
1505                                         proto_item *it;
1506                                         guint16     flags;
1507                                         flags = tvb_get_letohs(tvb, offset);
1508                                         it = proto_tree_add_uint(radiotap_tree,
1509                                                                  hf_radiotap_rxflags,
1510                                                                  tvb, offset, 2, flags);
1511                                         flags_tree =
1512                                             proto_item_add_subtree(it,
1513                                                                    ett_radiotap_rxflags);
1514                                         proto_tree_add_boolean(flags_tree,
1515                                                                hf_radiotap_rxflags_badplcp,
1516                                                                tvb, offset, 1, flags);
1517                                 }
1518                         }
1519                         break;
1520                 }
1521
1522                 case IEEE80211_RADIOTAP_XCHANNEL: {
1523                         if (tree) {
1524                                 proto_item *it;
1525                                 proto_tree *flags_tree;
1526                                 guint32     flags;
1527                                 int         channel;
1528
1529                                 flags   = tvb_get_letohl(tvb, offset);
1530                                 freq    = tvb_get_letohs(tvb, offset + 4);
1531                                 channel = tvb_get_guint8(tvb, offset + 6);
1532                                 proto_tree_add_uint(radiotap_tree,
1533                                                     hf_radiotap_xchannel,
1534                                                     tvb, offset + 6, 1,
1535                                                     (guint32) channel);
1536                                 proto_tree_add_uint(radiotap_tree,
1537                                                     hf_radiotap_xchannel_frequency,
1538                                                     tvb, offset + 4, 2, freq);
1539                                 it = proto_tree_add_uint(radiotap_tree,
1540                                                          hf_radiotap_xchannel_flags,
1541                                                          tvb, offset + 0, 4, flags);
1542                                 flags_tree =
1543                                     proto_item_add_subtree(it, ett_radiotap_xchannel_flags);
1544                                 proto_tree_add_boolean(flags_tree,
1545                                                        hf_radiotap_xchannel_flags_turbo,
1546                                                        tvb, offset + 0, 1, flags);
1547                                 proto_tree_add_boolean(flags_tree,
1548                                                        hf_radiotap_xchannel_flags_cck,
1549                                                        tvb, offset + 0, 1, flags);
1550                                 proto_tree_add_boolean(flags_tree,
1551                                                        hf_radiotap_xchannel_flags_ofdm,
1552                                                        tvb, offset + 0, 1, flags);
1553                                 proto_tree_add_boolean(flags_tree,
1554                                                        hf_radiotap_xchannel_flags_2ghz,
1555                                                        tvb, offset + 0, 1, flags);
1556                                 proto_tree_add_boolean(flags_tree,
1557                                                        hf_radiotap_xchannel_flags_5ghz,
1558                                                        tvb, offset + 1, 1, flags);
1559                                 proto_tree_add_boolean(flags_tree,
1560                                                        hf_radiotap_xchannel_flags_passive,
1561                                                        tvb, offset + 1, 1, flags);
1562                                 proto_tree_add_boolean(flags_tree,
1563                                                        hf_radiotap_xchannel_flags_dynamic,
1564                                                        tvb, offset + 1, 1, flags);
1565                                 proto_tree_add_boolean(flags_tree,
1566                                                        hf_radiotap_xchannel_flags_gfsk,
1567                                                        tvb, offset + 1, 1, flags);
1568                                 proto_tree_add_boolean(flags_tree,
1569                                                        hf_radiotap_xchannel_flags_gsm,
1570                                                        tvb, offset + 1, 1, flags);
1571                                 proto_tree_add_boolean(flags_tree,
1572                                                        hf_radiotap_xchannel_flags_sturbo,
1573                                                        tvb, offset + 1, 1, flags);
1574                                 proto_tree_add_boolean(flags_tree,
1575                                                        hf_radiotap_xchannel_flags_half,
1576                                                        tvb, offset + 1, 1, flags);
1577                                 proto_tree_add_boolean(flags_tree,
1578                                                        hf_radiotap_xchannel_flags_quarter,
1579                                                        tvb, offset + 1, 1, flags);
1580                                 proto_tree_add_boolean(flags_tree,
1581                                                        hf_radiotap_xchannel_flags_ht20,
1582                                                        tvb, offset + 2, 1, flags);
1583                                 proto_tree_add_boolean(flags_tree,
1584                                                        hf_radiotap_xchannel_flags_ht40u,
1585                                                        tvb, offset + 2, 1, flags);
1586                                 proto_tree_add_boolean(flags_tree,
1587                                                        hf_radiotap_xchannel_flags_ht40d,
1588                                                        tvb, offset + 2, 1, flags);
1589 #if 0
1590                                 proto_tree_add_uint(radiotap_tree,
1591                                                     hf_radiotap_xchannel_maxpower,
1592                                                     tvb, offset + 7, 1, maxpower);
1593 #endif
1594                         }
1595                         break;
1596                 }
1597                 case IEEE80211_RADIOTAP_MCS: {
1598                         proto_tree *mcs_tree = NULL, *mcs_known_tree;
1599                         guint8      mcs_known, mcs_flags;
1600                         guint8      mcs;
1601                         guint       bandwidth;
1602                         guint       gi_length;
1603                         gboolean    can_calculate_rate;
1604
1605                         /*
1606                          * Start out assuming that we can calculate the rate;
1607                          * if we are missing any of the MCS index, channel
1608                          * width, or guard interval length, we can't.
1609                          */
1610                         can_calculate_rate = TRUE;
1611
1612                         mcs_known = tvb_get_guint8(tvb, offset);
1613                         mcs_flags = tvb_get_guint8(tvb, offset + 1);
1614                         mcs = tvb_get_guint8(tvb, offset + 2);
1615
1616                         if (tree) {
1617                                 proto_item *it;
1618
1619                                 it = proto_tree_add_item(radiotap_tree, hf_radiotap_mcs,
1620                                                          tvb, offset, 3, ENC_NA);
1621                                 mcs_tree = proto_item_add_subtree(it, ett_radiotap_mcs);
1622                                 it = proto_tree_add_uint(mcs_tree, hf_radiotap_mcs_known,
1623                                                          tvb, offset, 1, mcs_known);
1624                                 mcs_known_tree = proto_item_add_subtree(it, ett_radiotap_mcs_known);
1625                                 proto_tree_add_item(mcs_known_tree, hf_radiotap_mcs_have_bw,
1626                                             tvb, offset, 1, ENC_LITTLE_ENDIAN);
1627                                 proto_tree_add_item(mcs_known_tree, hf_radiotap_mcs_have_index,
1628                                                     tvb, offset, 1, ENC_LITTLE_ENDIAN);
1629                                 proto_tree_add_item(mcs_known_tree, hf_radiotap_mcs_have_gi,
1630                                                     tvb, offset, 1, ENC_LITTLE_ENDIAN);
1631                                 proto_tree_add_item(mcs_known_tree, hf_radiotap_mcs_have_format,
1632                                                     tvb, offset, 1, ENC_LITTLE_ENDIAN);
1633                                 proto_tree_add_item(mcs_known_tree, hf_radiotap_mcs_have_fec,
1634                                                     tvb, offset, 1, ENC_LITTLE_ENDIAN);
1635                                 proto_tree_add_item(mcs_known_tree, hf_radiotap_mcs_have_stbc,
1636                                                     tvb, offset, 1, ENC_LITTLE_ENDIAN);
1637                         }
1638                         if (mcs_known & IEEE80211_RADIOTAP_MCS_HAVE_BW) {
1639                                 bandwidth = ((mcs_flags & IEEE80211_RADIOTAP_MCS_BW_MASK) == IEEE80211_RADIOTAP_MCS_BW_40) ?
1640                                     1 : 0;
1641                                 if (mcs_tree)
1642                                         proto_tree_add_uint(mcs_tree, hf_radiotap_mcs_bw,
1643                                                             tvb, offset + 1, 1, mcs_flags);
1644                         } else {
1645                                 bandwidth = 0;
1646                                 can_calculate_rate = FALSE;     /* no bandwidth */
1647                         }
1648                         if (mcs_known & IEEE80211_RADIOTAP_MCS_HAVE_GI) {
1649                                 gi_length = (mcs_flags & IEEE80211_RADIOTAP_MCS_SGI) ?
1650                                     1 : 0;
1651                                 if (mcs_tree)
1652                                         proto_tree_add_uint(mcs_tree, hf_radiotap_mcs_gi,
1653                                                             tvb, offset + 1, 1, mcs_flags);
1654                         } else {
1655                                 gi_length = 0;
1656                                 can_calculate_rate = FALSE;     /* no GI width */
1657                         }
1658                         if (mcs_known & IEEE80211_RADIOTAP_MCS_HAVE_FMT) {
1659                                 if (mcs_tree)
1660                                         proto_tree_add_uint(mcs_tree, hf_radiotap_mcs_format,
1661                                                             tvb, offset + 1, 1, mcs_flags);
1662                         }
1663                         if (mcs_known & IEEE80211_RADIOTAP_MCS_HAVE_FEC) {
1664                                 if (mcs_tree)
1665                                         proto_tree_add_uint(mcs_tree, hf_radiotap_mcs_fec,
1666                                                             tvb, offset + 1, 1, mcs_flags);
1667                         }
1668                         if (mcs_known & IEEE80211_RADIOTAP_MCS_HAVE_STBC) {
1669                                 if (mcs_tree)
1670                                         proto_tree_add_boolean(mcs_tree, hf_radiotap_mcs_stbc,
1671                                                             tvb, offset + 1, 1, mcs_flags);
1672                         }
1673                         if (mcs_known & IEEE80211_RADIOTAP_MCS_HAVE_MCS) {
1674                                 if (mcs_tree)
1675                                         proto_tree_add_uint(mcs_tree, hf_radiotap_mcs_index,
1676                                                             tvb, offset + 2, 1, mcs);
1677                         } else
1678                                 can_calculate_rate = FALSE;     /* no MCS index */
1679
1680                         /*
1681                          * If we have the MCS index, channel width, and
1682                          * guard interval length, and the MCS index is
1683                          * valid, we can compute the rate.  If the resulting
1684                          * rate is non-zero, report it.  (If it's zero,
1685                          * it's an MCS/channel width/GI combination that
1686                          * 802.11n doesn't support.)
1687                          */
1688                         if (can_calculate_rate && mcs <= MAX_MCS_INDEX
1689                             && ieee80211_float_htrates[mcs][bandwidth][gi_length] != 0.0) {
1690                                 col_add_fstr(pinfo->cinfo, COL_TX_RATE, "%.1f",
1691                                              ieee80211_float_htrates[mcs][bandwidth][gi_length]);
1692                                 if (tree) {
1693                                         rate_ti = proto_tree_add_float_format(radiotap_tree,
1694                                             hf_radiotap_datarate,
1695                                             tvb, offset, 3,
1696                                             ieee80211_float_htrates[mcs][bandwidth][gi_length],
1697                                             "Data Rate: %.1f Mb/s",
1698                                             ieee80211_float_htrates[mcs][bandwidth][gi_length]);
1699                                         PROTO_ITEM_SET_GENERATED(rate_ti);
1700                                 }
1701                         }
1702                         break;
1703                 }
1704                 case IEEE80211_RADIOTAP_AMPDU_STATUS: {
1705                         proto_item *it;
1706                         proto_tree *ampdu_tree = NULL, *ampdu_flags_tree;
1707                         guint16     flags;
1708
1709                         flags = tvb_get_letohs(tvb, offset + 4);
1710
1711                         if (tree) {
1712                                 it = proto_tree_add_item(radiotap_tree, hf_radiotap_ampdu,
1713                                                          tvb, offset, 8, ENC_NA);
1714                                 ampdu_tree = proto_item_add_subtree(it, ett_radiotap_ampdu);
1715
1716                                 proto_tree_add_item(ampdu_tree, hf_radiotap_ampdu_ref,
1717                                                     tvb, offset, 4, ENC_LITTLE_ENDIAN);
1718
1719                                 it = proto_tree_add_item(ampdu_tree, hf_radiotap_ampdu_flags,
1720                                                          tvb, offset + 4, 2, ENC_LITTLE_ENDIAN);
1721                                 ampdu_flags_tree = proto_item_add_subtree(it, ett_radiotap_ampdu_flags);
1722                                 proto_tree_add_item(ampdu_flags_tree, hf_radiotap_ampdu_flags_report_zerolen,
1723                                                     tvb, offset + 4, 2, ENC_LITTLE_ENDIAN);
1724                                 proto_tree_add_item(ampdu_flags_tree, hf_radiotap_ampdu_flags_is_zerolen,
1725                                                     tvb, offset + 4, 2, ENC_LITTLE_ENDIAN);
1726                                 proto_tree_add_item(ampdu_flags_tree, hf_radiotap_ampdu_flags_last_known,
1727                                                     tvb, offset + 4, 2, ENC_LITTLE_ENDIAN);
1728                                 proto_tree_add_item(ampdu_flags_tree, hf_radiotap_ampdu_flags_is_last,
1729                                                     tvb, offset + 4, 2, ENC_LITTLE_ENDIAN);
1730                                 proto_tree_add_item(ampdu_flags_tree, hf_radiotap_ampdu_flags_delim_crc_error,
1731                                                     tvb, offset + 4, 2, ENC_LITTLE_ENDIAN);
1732                         }
1733                         if (flags & IEEE80211_RADIOTAP_AMPDU_DELIM_CRC_KNOWN) {
1734                                 if (ampdu_tree)
1735                                         proto_tree_add_item(ampdu_tree, hf_radiotap_ampdu_delim_crc,
1736                                                             tvb, offset + 6, 1, ENC_NA);
1737                         }
1738                         break;
1739                 }
1740                 case IEEE80211_RADIOTAP_VHT: {
1741                         proto_item *it, *it_root = NULL;
1742                         proto_tree *vht_tree     = NULL, *vht_known_tree = NULL, *user_tree = NULL;
1743                         guint16     known, nsts;
1744                         guint8      flags, bw, mcs_nss;
1745                         guint       bandwidth    = 0;
1746                         guint       gi_length    = 0;
1747                         guint       nss          = 0;
1748                         guint       mcs          = 0;
1749                         gboolean    can_calculate_rate;
1750                         guint       i;
1751
1752                         /*
1753                          * Start out assuming that we can calculate the rate;
1754                          * if we are missing any of the MCS index, channel
1755                          * width, or guard interval length, we can't.
1756                          */
1757                         can_calculate_rate = TRUE;
1758
1759                         known = tvb_get_letohs(tvb, offset);
1760                         flags = tvb_get_guint8(tvb, offset + 2);
1761                         bw    = tvb_get_guint8(tvb, offset + 3);
1762
1763                         if (tree) {
1764                                 it_root = proto_tree_add_item(radiotap_tree, hf_radiotap_vht,
1765                                                 tvb, offset, 12, ENC_NA);
1766                                 vht_tree = proto_item_add_subtree(it_root, ett_radiotap_vht);
1767                                 it = proto_tree_add_item(vht_tree, hf_radiotap_vht_known,
1768                                                 tvb, offset, 2, known);
1769                                 vht_known_tree = proto_item_add_subtree(it, ett_radiotap_vht_known);
1770
1771                                 proto_tree_add_item(vht_known_tree, hf_radiotap_vht_have_stbc,
1772                                                 tvb, offset, 2, ENC_LITTLE_ENDIAN);
1773                                 proto_tree_add_item(vht_known_tree, hf_radiotap_vht_have_txop_ps,
1774                                                 tvb, offset, 2, ENC_LITTLE_ENDIAN);
1775                                 proto_tree_add_item(vht_known_tree, hf_radiotap_vht_have_gi,
1776                                                 tvb, offset, 2, ENC_LITTLE_ENDIAN);
1777                                 proto_tree_add_item(vht_known_tree, hf_radiotap_vht_have_sgi_nsym_da,
1778                                                 tvb, offset, 2, ENC_LITTLE_ENDIAN);
1779                                 proto_tree_add_item(vht_known_tree, hf_radiotap_vht_have_ldpc_extra,
1780                                                 tvb, offset, 2, ENC_LITTLE_ENDIAN);
1781                                 proto_tree_add_item(vht_known_tree, hf_radiotap_vht_have_bf,
1782                                                 tvb, offset, 2, ENC_LITTLE_ENDIAN);
1783                                 proto_tree_add_item(vht_known_tree, hf_radiotap_vht_have_bw,
1784                                                 tvb, offset, 2, ENC_LITTLE_ENDIAN);
1785                                 proto_tree_add_item(vht_known_tree, hf_radiotap_vht_have_gid,
1786                                                 tvb, offset, 2, ENC_LITTLE_ENDIAN);
1787                                 proto_tree_add_item(vht_known_tree, hf_radiotap_vht_have_p_aid,
1788                                                 tvb, offset, 2, ENC_LITTLE_ENDIAN);
1789                         }
1790
1791                         if (known & IEEE80211_RADIOTAP_VHT_HAVE_STBC) {
1792                                 if (vht_tree)
1793                                         proto_tree_add_item(vht_tree, hf_radiotap_vht_stbc,
1794                                                         tvb, offset + 2, 1, ENC_LITTLE_ENDIAN);
1795                         }
1796
1797                         if (known & IEEE80211_RADIOTAP_VHT_HAVE_TXOP_PS) {
1798                                 if (vht_tree)
1799                                         proto_tree_add_item(vht_tree, hf_radiotap_vht_txop_ps,
1800                                                         tvb, offset + 2, 1, ENC_LITTLE_ENDIAN);
1801                         }
1802
1803                         if (known & IEEE80211_RADIOTAP_VHT_HAVE_GI) {
1804                                 gi_length = (flags & IEEE80211_RADIOTAP_VHT_SGI) ? 1 : 0;
1805                                 if (vht_tree) {
1806                                         proto_tree_add_item(vht_tree, hf_radiotap_vht_gi,
1807                                                         tvb, offset + 2, 1, ENC_LITTLE_ENDIAN);
1808                                         proto_tree_add_item(vht_tree, hf_radiotap_vht_sgi_nsym_da,
1809                                                         tvb, offset + 2, 1, ENC_LITTLE_ENDIAN);
1810                                 }
1811                         } else {
1812                                 can_calculate_rate = FALSE;     /* no GI width */
1813                         }
1814
1815                         if (known & IEEE80211_RADIOTAP_VHT_HAVE_LDPC_EXTRA) {
1816                                 if (vht_tree) {
1817                                         proto_tree_add_item(vht_tree, hf_radiotap_vht_ldpc_extra,
1818                                                         tvb, offset + 2, 1, ENC_LITTLE_ENDIAN);
1819                                 }
1820                         }
1821
1822                         if (known & IEEE80211_RADIOTAP_VHT_HAVE_BF) {
1823                                 if (vht_tree)
1824                                         proto_tree_add_item(vht_tree, hf_radiotap_vht_bf,
1825                                                         tvb, offset + 2, 1, ENC_LITTLE_ENDIAN);
1826                         }
1827
1828                         if (known & IEEE80211_RADIOTAP_VHT_HAVE_BW) {
1829                                 if (bw <= sizeof(ieee80211_vht_bw2rate_index)/sizeof(ieee80211_vht_bw2rate_index[0]))
1830                                         bandwidth = ieee80211_vht_bw2rate_index[bw];
1831                                 else
1832                                         can_calculate_rate = FALSE; /* unknown bandwidth */
1833
1834                                 if (vht_tree)
1835                                         proto_tree_add_item(vht_tree, hf_radiotap_vht_bw,
1836                                                         tvb, offset + 3, 1, ENC_LITTLE_ENDIAN);
1837                         } else {
1838                                 can_calculate_rate = FALSE;     /* no bandwidth */
1839                         }
1840
1841                         for(i=0; i<4; i++) {
1842                                 mcs_nss = tvb_get_guint8(tvb, offset + 4 + i);
1843                                 nss = (mcs_nss & IEEE80211_RADIOTAP_VHT_NSS);
1844                                 mcs = (mcs_nss & IEEE80211_RADIOTAP_VHT_MCS) >> 4;
1845
1846                                 if ((known & IEEE80211_RADIOTAP_VHT_HAVE_STBC) && (flags & IEEE80211_RADIOTAP_VHT_STBC))
1847                                         nsts = 2 * nss;
1848                                 else
1849                                         nsts = nss;
1850
1851                                 if (nss) {
1852                                         if (vht_tree) {
1853                                                 it = proto_tree_add_item(vht_tree, hf_radiotap_vht_user,
1854                                                         tvb, offset + 4, 5, ENC_NA);
1855                                                 proto_item_append_text(it, " %d: MCS %u", i, mcs);
1856                                                 user_tree = proto_item_add_subtree(it, ett_radiotap_vht_user);
1857
1858                                                 it = proto_tree_add_item(user_tree, hf_radiotap_vht_mcs[i],
1859                                                         tvb, offset + 4 + i, 1,
1860                                                         ENC_LITTLE_ENDIAN);
1861                                                 if (mcs > MAX_MCS_VHT_INDEX) {
1862                                                         proto_item_append_text(it, " (invalid)");
1863                                                 } else {
1864                                                         proto_item_append_text(it, " (%s %s)",
1865                                                                 ieee80211_vhtinfo[mcs].modulation,
1866                                                                 ieee80211_vhtinfo[mcs].coding_rate);
1867                                                 }
1868
1869                                                 proto_tree_add_item(user_tree, hf_radiotap_vht_nss[i],
1870                                                         tvb, offset + 4 + i, 1, ENC_LITTLE_ENDIAN);
1871                                                 proto_tree_add_uint(user_tree, hf_radiotap_vht_nsts[i],
1872                                                         tvb, offset + 4 + i, 1, nsts);
1873                                                 proto_tree_add_item(user_tree, hf_radiotap_vht_coding[i],
1874                                                         tvb, offset + 8, 1,ENC_LITTLE_ENDIAN);
1875                                         }
1876
1877                                         if (can_calculate_rate) {
1878                                                 float rate = ieee80211_vhtinfo[mcs].rates[bandwidth][gi_length] * nss;
1879                                                 if (rate != 0.0f && user_tree) {
1880                                                         rate_ti = proto_tree_add_float_format(user_tree,
1881                                                                         hf_radiotap_vht_datarate[i],
1882                                                                         tvb, offset, 12, rate,
1883                                                                         "Data Rate: %.1f Mb/s", rate);
1884                                                         PROTO_ITEM_SET_GENERATED(rate_ti);
1885                                                 }
1886                                         }
1887                                 }
1888                         }
1889
1890                         if (known & IEEE80211_RADIOTAP_VHT_HAVE_GID) {
1891                                 if (vht_tree)
1892                                         proto_tree_add_item(vht_tree, hf_radiotap_vht_gid,
1893                                                         tvb, offset+9, 1, ENC_LITTLE_ENDIAN);
1894                         }
1895
1896                         if (known & IEEE80211_RADIOTAP_VHT_HAVE_PAID) {
1897                                 if (vht_tree) {
1898                                         proto_tree_add_item(vht_tree, hf_radiotap_vht_p_aid,
1899                                                         tvb, offset+10, 2, ENC_LITTLE_ENDIAN);
1900                                 }
1901                         }
1902
1903                         break;
1904                 }
1905                 }
1906         }
1907
1908         if (err != -ENOENT && tree) {
1909  malformed:
1910                 proto_item_append_text(ti, " (malformed)");
1911         }
1912
1913         /* This handles the case of an FCS exiting at the end of the frame. */
1914         if (rflags & IEEE80211_RADIOTAP_F_FCS)
1915                 pinfo->pseudo_header->ieee_802_11.fcs_len = 4;
1916         else
1917                 pinfo->pseudo_header->ieee_802_11.fcs_len = 0;
1918
1919  hand_off_to_80211:
1920         /* Grab the rest of the frame. */
1921         next_tvb = tvb_new_subset_remaining(tvb, length);
1922
1923         /* If we had an in-header FCS, check it.
1924          * This can only happen if the backward-compat configuration option
1925          * is chosen by the user. */
1926         if (hdr_fcs_ti) {
1927                 /* It would be very strange for the header to have an FCS for the
1928                  * frame *and* the frame to have the FCS at the end, but it's possible, so
1929                  * take that into account by using the FCS length recorded in pinfo. */
1930
1931                 /* Watch out for [erroneously] short frames */
1932                 if (tvb_length(next_tvb) >
1933                     (unsigned int)pinfo->pseudo_header->ieee_802_11.fcs_len) {
1934                         calc_fcs =
1935                             crc32_802_tvb(next_tvb,
1936                                 tvb_length(next_tvb) -
1937                                 pinfo->pseudo_header->ieee_802_11.fcs_len);
1938
1939                         /* By virtue of hdr_fcs_ti being set, we know that 'tree' is set,
1940                          * so there's no need to check it here. */
1941                         if (calc_fcs == sent_fcs) {
1942                                 proto_item_append_text(hdr_fcs_ti,
1943                                                        " [correct]");
1944                         } else {
1945                                 proto_item_append_text(hdr_fcs_ti,
1946                                                        " [incorrect, should be 0x%08x]",
1947                                                        calc_fcs);
1948                                 hidden_item =
1949                                     proto_tree_add_boolean(radiotap_tree,
1950                                                            hf_radiotap_fcs_bad,
1951                                                            tvb, hdr_fcs_offset,
1952                                                            4, TRUE);
1953                                 PROTO_ITEM_SET_HIDDEN(hidden_item);
1954                         }
1955                 } else {
1956                         proto_item_append_text(hdr_fcs_ti,
1957                                                " [cannot verify - not enough data]");
1958                 }
1959         }
1960
1961         /* dissect the 802.11 header next */
1962         call_dissector((rflags & IEEE80211_RADIOTAP_F_DATAPAD) ?
1963                        ieee80211_datapad_handle : ieee80211_handle,
1964                        next_tvb, pinfo, tree);
1965
1966         tap_queue_packet(radiotap_tap, pinfo, radiotap_info);
1967 }
1968
1969
1970 void proto_register_radiotap(void)
1971 {
1972
1973         static hf_register_info hf[] = {
1974                 {&hf_radiotap_version,
1975                  {"Header revision", "radiotap.version",
1976                   FT_UINT8, BASE_DEC, NULL, 0x0,
1977                   "Version of radiotap header format", HFILL}},
1978
1979                 {&hf_radiotap_pad,
1980                  {"Header pad", "radiotap.pad",
1981                   FT_UINT8, BASE_DEC, NULL, 0x0,
1982                   "Padding", HFILL}},
1983
1984                 {&hf_radiotap_length,
1985                  {"Header length", "radiotap.length",
1986                   FT_UINT16, BASE_DEC, NULL, 0x0,
1987                   "Length of header including version, pad, length and data fields", HFILL}},
1988
1989                 {&hf_radiotap_present,
1990                  {"Present flags", "radiotap.present",
1991                   FT_NONE, BASE_NONE, NULL, 0x0,
1992                   "Bitmask indicating which fields are present", HFILL}},
1993
1994 #define RADIOTAP_MASK(name)     BIT(IEEE80211_RADIOTAP_ ##name)
1995
1996                 /* Boolean 'present' flags */
1997                 {&hf_radiotap_present_tsft,
1998                  {"TSFT", "radiotap.present.tsft",
1999                   FT_BOOLEAN, 32, NULL, RADIOTAP_MASK(TSFT),
2000                   "Specifies if the Time Synchronization Function Timer field is present", HFILL}},
2001
2002                 {&hf_radiotap_present_flags,
2003                  {"Flags", "radiotap.present.flags",
2004                   FT_BOOLEAN, 32, NULL, RADIOTAP_MASK(FLAGS),
2005                   "Specifies if the channel flags field is present", HFILL}},
2006
2007                 {&hf_radiotap_present_rate,
2008                  {"Rate", "radiotap.present.rate",
2009                   FT_BOOLEAN, 32, NULL, RADIOTAP_MASK(RATE),
2010                   "Specifies if the transmit/receive rate field is present", HFILL}},
2011
2012                 {&hf_radiotap_present_channel,
2013                  {"Channel", "radiotap.present.channel",
2014                   FT_BOOLEAN, 32, NULL, RADIOTAP_MASK(CHANNEL),
2015                   "Specifies if the transmit/receive frequency field is present", HFILL}},
2016
2017                 {&hf_radiotap_present_fhss,
2018                  {"FHSS", "radiotap.present.fhss",
2019                   FT_BOOLEAN, 32, NULL, RADIOTAP_MASK(FHSS),
2020                   "Specifies if the hop set and pattern is present for frequency hopping radios", HFILL}},
2021
2022                 {&hf_radiotap_present_dbm_antsignal,
2023                  {"dBm Antenna Signal", "radiotap.present.dbm_antsignal",
2024                   FT_BOOLEAN, 32, NULL, RADIOTAP_MASK(DBM_ANTSIGNAL),
2025                   "Specifies if the antenna signal strength in dBm is present", HFILL}},
2026
2027                 {&hf_radiotap_present_dbm_antnoise,
2028                  {"dBm Antenna Noise", "radiotap.present.dbm_antnoise",
2029                   FT_BOOLEAN, 32, NULL, RADIOTAP_MASK(DBM_ANTNOISE),
2030                   "Specifies if the RF noise power at antenna field is present", HFILL}},
2031
2032                 {&hf_radiotap_present_lock_quality,
2033                  {"Lock Quality", "radiotap.present.lock_quality",
2034                   FT_BOOLEAN, 32, NULL, RADIOTAP_MASK(LOCK_QUALITY),
2035                   "Specifies if the signal quality field is present", HFILL}},
2036
2037                 {&hf_radiotap_present_tx_attenuation,
2038                  {"TX Attenuation", "radiotap.present.tx_attenuation",
2039                   FT_BOOLEAN, 32, NULL, RADIOTAP_MASK(TX_ATTENUATION),
2040                   "Specifies if the transmit power distance from max power field is present", HFILL}},
2041
2042                 {&hf_radiotap_present_db_tx_attenuation,
2043                  {"dB TX Attenuation", "radiotap.present.db_tx_attenuation",
2044                   FT_BOOLEAN, 32, NULL, RADIOTAP_MASK(DB_TX_ATTENUATION),
2045                   "Specifies if the transmit power distance from max power (in dB) field is present", HFILL}},
2046
2047                 {&hf_radiotap_present_dbm_tx_power,
2048                  {"dBm TX Power", "radiotap.present.dbm_tx_power",
2049                   FT_BOOLEAN, 32, NULL, RADIOTAP_MASK(DBM_TX_POWER),
2050                   "Specifies if the transmit power (in dBm) field is present", HFILL}},
2051
2052                 {&hf_radiotap_present_antenna,
2053                  {"Antenna", "radiotap.present.antenna",
2054                   FT_BOOLEAN, 32, NULL, RADIOTAP_MASK(ANTENNA),
2055                   "Specifies if the antenna number field is present", HFILL}},
2056
2057                 {&hf_radiotap_present_db_antsignal,
2058                  {"dB Antenna Signal", "radiotap.present.db_antsignal",
2059                   FT_BOOLEAN, 32, NULL, RADIOTAP_MASK(DB_ANTSIGNAL),
2060                   "Specifies if the RF signal power at antenna in dB field is present", HFILL}},
2061
2062                 {&hf_radiotap_present_db_antnoise,
2063                  {"dB Antenna Noise", "radiotap.present.db_antnoise",
2064                   FT_BOOLEAN, 32, NULL, RADIOTAP_MASK(DB_ANTNOISE),
2065                   "Specifies if the RF signal power at antenna in dBm field is present", HFILL}},
2066
2067                 {&hf_radiotap_present_rxflags,
2068                  {"RX flags", "radiotap.present.rxflags",
2069                   FT_BOOLEAN, 32, NULL, RADIOTAP_MASK(RX_FLAGS),
2070                   "Specifies if the RX flags field is present", HFILL}},
2071
2072                 {&hf_radiotap_present_hdrfcs,
2073                  {"FCS in header", "radiotap.present.fcs",
2074                   FT_BOOLEAN, 32, NULL, RADIOTAP_MASK(RX_FLAGS),
2075                   "Specifies if the FCS field is present", HFILL}},
2076
2077                 {&hf_radiotap_present_xchannel,
2078                  {"Channel+", "radiotap.present.xchannel",
2079                   FT_BOOLEAN, 32, NULL, RADIOTAP_MASK(XCHANNEL),
2080                   "Specifies if the extended channel info field is present", HFILL}},
2081
2082                 {&hf_radiotap_present_mcs,
2083                  {"HT information", "radiotap.present.mcs",
2084                   FT_BOOLEAN, 32, NULL, RADIOTAP_MASK(MCS),
2085                   "Specifies if the HT field is present", HFILL}},
2086
2087                 {&hf_radiotap_present_ampdu,
2088                  {"A-MPDU Status", "radiotap.present.ampdu",
2089                   FT_BOOLEAN, 32, NULL, RADIOTAP_MASK(AMPDU_STATUS),
2090                   "Specifies if the A-MPDU status field is present", HFILL}},
2091
2092                 {&hf_radiotap_present_vht,
2093                  {"VHT information", "radiotap.present.vht",
2094                   FT_BOOLEAN, 32, NULL, RADIOTAP_MASK(VHT),
2095                   "Specifies if the VHT field is present", HFILL}},
2096
2097                 {&hf_radiotap_present_reserved,
2098                  {"Reserved", "radiotap.present.reserved",
2099                   FT_UINT32, BASE_HEX, NULL, IEEE80211_RADIOTAP_NOTDEFINED,
2100                   "Not (yet) defined present flag (Must be zero)", HFILL}},
2101
2102                 {&hf_radiotap_present_rtap_ns,
2103                  {"Radiotap NS next", "radiotap.present.rtap_ns",
2104                   FT_BOOLEAN, 32, NULL, RADIOTAP_MASK(RADIOTAP_NAMESPACE),
2105                   "Specifies a reset to the radiotap namespace", HFILL}},
2106
2107                 {&hf_radiotap_present_vendor_ns,
2108                  {"Vendor NS next", "radiotap.present.vendor_ns",
2109                   FT_BOOLEAN, 32, NULL, RADIOTAP_MASK(VENDOR_NAMESPACE),
2110                   "Specifies that the next bitmap is in a vendor namespace", HFILL}},
2111
2112                 {&hf_radiotap_present_ext,
2113                  {"Ext", "radiotap.present.ext",
2114                   FT_BOOLEAN, 32, NULL, RADIOTAP_MASK(EXT),
2115                   "Specifies if there are any extensions to the header present", HFILL}},
2116
2117                 /* Boolean 'present.flags' flags */
2118                 {&hf_radiotap_flags,
2119                  {"Flags", "radiotap.flags",
2120                   FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL}},
2121
2122                 {&hf_radiotap_flags_cfp,
2123                  {"CFP", "radiotap.flags.cfp",
2124                   FT_BOOLEAN, 8, NULL, IEEE80211_RADIOTAP_F_CFP,
2125                   "Sent/Received during CFP", HFILL}},
2126
2127                 {&hf_radiotap_flags_preamble,
2128                  {"Preamble", "radiotap.flags.preamble",
2129                   FT_BOOLEAN, 8, TFS(&preamble_type),
2130                   IEEE80211_RADIOTAP_F_SHORTPRE,
2131                   "Sent/Received with short preamble", HFILL}},
2132
2133                 {&hf_radiotap_flags_wep,
2134                  {"WEP", "radiotap.flags.wep",
2135                   FT_BOOLEAN, 8, NULL, IEEE80211_RADIOTAP_F_WEP,
2136                   "Sent/Received with WEP encryption", HFILL}},
2137
2138                 {&hf_radiotap_flags_frag,
2139                  {"Fragmentation", "radiotap.flags.frag",
2140                   FT_BOOLEAN, 8, NULL, IEEE80211_RADIOTAP_F_FRAG,
2141                   "Sent/Received with fragmentation", HFILL}},
2142
2143                 {&hf_radiotap_flags_fcs,
2144                  {"FCS at end", "radiotap.flags.fcs",
2145                   FT_BOOLEAN, 8, NULL, IEEE80211_RADIOTAP_F_FCS,
2146                   "Frame includes FCS at end", HFILL}},
2147
2148                 {&hf_radiotap_flags_datapad,
2149                  {"Data Pad", "radiotap.flags.datapad",
2150                   FT_BOOLEAN, 8, NULL, IEEE80211_RADIOTAP_F_DATAPAD,
2151                   "Frame has padding between 802.11 header and payload", HFILL}},
2152
2153                 {&hf_radiotap_flags_badfcs,
2154                  {"Bad FCS", "radiotap.flags.badfcs",
2155                   FT_BOOLEAN, 8, NULL, IEEE80211_RADIOTAP_F_BADFCS,
2156                   "Frame received with bad FCS", HFILL}},
2157
2158                 {&hf_radiotap_flags_shortgi,
2159                  {"Short GI", "radiotap.flags.shortgi",
2160                   FT_BOOLEAN, 8, NULL, IEEE80211_RADIOTAP_F_SHORTGI,
2161                   "Frame Sent/Received with HT short Guard Interval", HFILL}},
2162
2163                 {&hf_radiotap_mactime,
2164                  {"MAC timestamp", "radiotap.mactime",
2165                   FT_UINT64, BASE_DEC, NULL, 0x0,
2166                   "Value in microseconds of the MAC's Time Synchronization Function timer"
2167                   " when the first bit of the MPDU arrived at the MAC.",
2168                   HFILL}},
2169
2170                 {&hf_radiotap_quality,
2171                  {"Signal Quality", "radiotap.quality",
2172                   FT_UINT16, BASE_DEC, NULL, 0x0,
2173                   "Signal quality (unitless measure)", HFILL}},
2174
2175                 {&hf_radiotap_fcs,
2176                  {"802.11 FCS", "radiotap.fcs",
2177                   FT_UINT32, BASE_HEX, NULL, 0x0,
2178                   "Frame check sequence of this frame", HFILL}},
2179
2180                 {&hf_radiotap_channel,
2181                  {"Channel", "radiotap.channel",
2182                   FT_UINT32, BASE_DEC, NULL, 0x0,
2183                   "802.11 channel number that this frame was sent/received on", HFILL}},
2184
2185                 {&hf_radiotap_channel_frequency,
2186                  {"Channel frequency", "radiotap.channel.freq",
2187                   FT_UINT32, BASE_DEC, NULL, 0x0,
2188                   "Channel frequency in megahertz that this frame was sent/received on", HFILL}},
2189
2190                 {&hf_radiotap_channel_flags,
2191                  {"Channel type", "radiotap.channel.type",
2192                   FT_UINT16, BASE_HEX | BASE_EXT_STRING, &phy_type_ext, 0x0,
2193                   NULL, HFILL}},
2194
2195                 {&hf_radiotap_channel_flags_turbo,
2196                  {"Turbo", "radiotap.channel.type.turbo",
2197                   FT_BOOLEAN, 16, NULL, 0x0010, "Channel Type Turbo", HFILL}},
2198
2199                 {&hf_radiotap_channel_flags_cck,
2200                  {"Complementary Code Keying (CCK)", "radiotap.channel.type.cck",
2201                   FT_BOOLEAN, 16, NULL, 0x0020,
2202                   "Channel Type Complementary Code Keying (CCK) Modulation", HFILL}},
2203
2204                 {&hf_radiotap_channel_flags_ofdm,
2205                  {"Orthogonal Frequency-Division Multiplexing (OFDM)", "radiotap.channel.type.ofdm",
2206                   FT_BOOLEAN, 16, NULL, 0x0040,
2207                   "Channel Type Orthogonal Frequency-Division Multiplexing (OFDM)", HFILL}},
2208
2209                 {&hf_radiotap_channel_flags_2ghz,
2210                  {"2 GHz spectrum", "radiotap.channel.type.2ghz",
2211                   FT_BOOLEAN, 16, NULL, 0x0080, "Channel Type 2 GHz spectrum", HFILL}},
2212
2213                 {&hf_radiotap_channel_flags_5ghz,
2214                  {"5 GHz spectrum", "radiotap.channel.type.5ghz",
2215                   FT_BOOLEAN, 16, NULL, 0x0100, "Channel Type 5 GHz spectrum", HFILL}},
2216
2217                 {&hf_radiotap_channel_flags_passive,
2218                  {"Passive", "radiotap.channel.type.passive",
2219                   FT_BOOLEAN, 16, NULL, 0x0200,
2220                   "Channel Type Passive", HFILL}},
2221
2222                 {&hf_radiotap_channel_flags_dynamic,
2223                  {"Dynamic CCK-OFDM", "radiotap.channel.type.dynamic",
2224                   FT_BOOLEAN, 16, NULL, 0x0400,
2225                   "Channel Type Dynamic CCK-OFDM Channel", HFILL}},
2226
2227                 {&hf_radiotap_channel_flags_gfsk,
2228                  {"Gaussian Frequency Shift Keying (GFSK)", "radiotap.channel.type.gfsk",
2229                   FT_BOOLEAN, 16, NULL, 0x0800,
2230                   "Channel Type Gaussian Frequency Shift Keying (GFSK) Modulation", HFILL}},
2231
2232                 {&hf_radiotap_channel_flags_gsm,
2233                  {"GSM (900MHz)", "radiotap.channel.type.gsm",
2234                   FT_BOOLEAN, 16, NULL, 0x1000,
2235                   "Channel Type GSM", HFILL}},
2236
2237                 {&hf_radiotap_channel_flags_sturbo,
2238                  {"Static Turbo", "radiotap.channel.type.sturbo",
2239                   FT_BOOLEAN, 16, NULL, 0x2000,
2240                   "Channel Type Status Turbo", HFILL}},
2241
2242                 {&hf_radiotap_channel_flags_half,
2243                  {"Half Rate Channel (10MHz Channel Width)", "radiotap.channel.type.half",
2244                   FT_BOOLEAN, 16, NULL, 0x4000,
2245                   "Channel Type Half Rate", HFILL}},
2246
2247                 {&hf_radiotap_channel_flags_quarter,
2248                  {"Quarter Rate Channel (5MHz Channel Width)", "radiotap.channel.type.quarter",
2249                   FT_BOOLEAN, 16, NULL, 0x8000,
2250                   "Channel Type Quarter Rate", HFILL}},
2251
2252                 {&hf_radiotap_rxflags,
2253                  {"RX flags", "radiotap.rxflags",
2254                   FT_UINT16, BASE_HEX, NULL, 0x0,
2255                   NULL, HFILL}},
2256
2257                 {&hf_radiotap_rxflags_badplcp,
2258                  {"Bad PLCP", "radiotap.rxflags.badplcp",
2259                   FT_BOOLEAN, 24, NULL, IEEE80211_RADIOTAP_F_RX_BADPLCP,
2260                   "Frame with bad PLCP", HFILL}},
2261
2262                 {&hf_radiotap_xchannel,
2263                  {"Channel number", "radiotap.xchannel",
2264                   FT_UINT32, BASE_DEC, NULL, 0x0,
2265                   NULL, HFILL}},
2266
2267                 {&hf_radiotap_xchannel_frequency,
2268                  {"Channel frequency", "radiotap.xchannel.freq",
2269                   FT_UINT32, BASE_DEC, NULL, 0x0,
2270                   NULL, HFILL}},
2271
2272                 {&hf_radiotap_xchannel_flags,
2273                  {"Channel type", "radiotap.xchannel.flags",
2274                   FT_UINT32, BASE_HEX | BASE_EXT_STRING, &phy_type_ext, 0x0,
2275                   NULL, HFILL}},
2276
2277                 {&hf_radiotap_xchannel_flags_turbo,
2278                  {"Turbo", "radiotap.xchannel.type.turbo",
2279                   FT_BOOLEAN, 24, NULL, 0x0010,
2280                   "Channel Type Turbo", HFILL}},
2281
2282                 {&hf_radiotap_xchannel_flags_cck,
2283                  {"Complementary Code Keying (CCK)", "radiotap.xchannel.type.cck",
2284                   FT_BOOLEAN, 24, NULL, 0x0020,
2285                   "Channel Type Complementary Code Keying (CCK) Modulation", HFILL}},
2286
2287                 {&hf_radiotap_xchannel_flags_ofdm,
2288                  {"Orthogonal Frequency-Division Multiplexing (OFDM)", "radiotap.xchannel.type.ofdm",
2289                   FT_BOOLEAN, 24, NULL, 0x0040,
2290                   "Channel Type Orthogonal Frequency-Division Multiplexing (OFDM)", HFILL}},
2291
2292                 {&hf_radiotap_xchannel_flags_2ghz,
2293                  {"2 GHz spectrum", "radiotap.xchannel.type.2ghz",
2294                   FT_BOOLEAN, 24, NULL, 0x0080,
2295                   "Channel Type 2 GHz spectrum", HFILL}},
2296
2297                 {&hf_radiotap_xchannel_flags_5ghz,
2298                  {"5 GHz spectrum", "radiotap.xchannel.type.5ghz",
2299                   FT_BOOLEAN, 24, NULL, 0x0100,
2300                   "Channel Type 5 GHz spectrum", HFILL}},
2301
2302                 {&hf_radiotap_xchannel_flags_passive,
2303                  {"Passive", "radiotap.channel.xtype.passive",
2304                   FT_BOOLEAN, 24, NULL, 0x0200,
2305                   "Channel Type Passive", HFILL}},
2306
2307                 {&hf_radiotap_xchannel_flags_dynamic,
2308                  {"Dynamic CCK-OFDM", "radiotap.xchannel.type.dynamic",
2309                   FT_BOOLEAN, 24, NULL, 0x0400,
2310                   "Channel Type Dynamic CCK-OFDM Channel", HFILL}},
2311
2312                 {&hf_radiotap_xchannel_flags_gfsk,
2313                  {"Gaussian Frequency Shift Keying (GFSK)",
2314                   "radiotap.xchannel.type.gfsk",
2315                   FT_BOOLEAN, 24, NULL, 0x0800,
2316                   "Channel Type Gaussian Frequency Shift Keying (GFSK) Modulation",
2317                   HFILL}},
2318
2319                 {&hf_radiotap_xchannel_flags_gsm,
2320                  {"GSM (900MHz)", "radiotap.xchannel.type.gsm",
2321                   FT_BOOLEAN, 24, NULL, 0x1000,
2322                   "Channel Type GSM", HFILL}},
2323
2324                 {&hf_radiotap_xchannel_flags_sturbo,
2325                  {"Static Turbo", "radiotap.xchannel.type.sturbo",
2326                   FT_BOOLEAN, 24, NULL, 0x2000,
2327                   "Channel Type Status Turbo", HFILL}},
2328
2329                 {&hf_radiotap_xchannel_flags_half,
2330                  {"Half Rate Channel (10MHz Channel Width)", "radiotap.xchannel.type.half",
2331                   FT_BOOLEAN, 24, NULL, 0x4000,
2332                   "Channel Type Half Rate", HFILL}},
2333
2334                 {&hf_radiotap_xchannel_flags_quarter,
2335                  {"Quarter Rate Channel (5MHz Channel Width)", "radiotap.xchannel.type.quarter",
2336                   FT_BOOLEAN, 24, NULL, 0x8000,
2337                   "Channel Type Quarter Rate", HFILL}},
2338
2339                 {&hf_radiotap_xchannel_flags_ht20,
2340                  {"HT Channel (20MHz Channel Width)", "radiotap.xchannel.type.ht20",
2341                   FT_BOOLEAN, 24, NULL, 0x10000,
2342                   "Channel Type HT/20", HFILL}},
2343
2344                 {&hf_radiotap_xchannel_flags_ht40u,
2345                  {"HT Channel (40MHz Channel Width with Extension channel above)", "radiotap.xchannel.type.ht40u",
2346                   FT_BOOLEAN, 24, NULL, 0x20000,
2347                   "Channel Type HT/40+", HFILL}},
2348
2349                 {&hf_radiotap_xchannel_flags_ht40d,
2350                  {"HT Channel (40MHz Channel Width with Extension channel below)", "radiotap.xchannel.type.ht40d",
2351                   FT_BOOLEAN, 24, NULL, 0x40000,
2352                   "Channel Type HT/40-", HFILL}},
2353 #if 0
2354                 {&hf_radiotap_xchannel_maxpower,
2355                  {"Max transmit power", "radiotap.xchannel.maxpower",
2356                   FT_UINT32, BASE_DEC, NULL, 0x0,
2357                   NULL, HFILL}},
2358 #endif
2359                 {&hf_radiotap_fhss_hopset,
2360                  {"FHSS Hop Set", "radiotap.fhss.hopset",
2361                   FT_UINT8, BASE_DEC, NULL, 0x0,
2362                   "Frequency Hopping Spread Spectrum hopset", HFILL}},
2363
2364                 {&hf_radiotap_fhss_pattern,
2365                  {"FHSS Pattern", "radiotap.fhss.pattern",
2366                   FT_UINT8, BASE_DEC, NULL, 0x0,
2367                   "Frequency Hopping Spread Spectrum hop pattern", HFILL}},
2368
2369                 {&hf_radiotap_datarate,
2370                  {"Data rate (Mb/s)", "radiotap.datarate",
2371                   FT_FLOAT, BASE_NONE, NULL, 0x0,
2372                   "Speed this frame was sent/received at", HFILL}},
2373
2374                 {&hf_radiotap_antenna,
2375                  {"Antenna", "radiotap.antenna",
2376                   FT_UINT32, BASE_DEC, NULL, 0x0,
2377                   "Antenna number this frame was sent/received over (starting at 0)", HFILL}},
2378
2379                 {&hf_radiotap_dbm_antsignal,
2380                  {"SSI Signal (dBm)", "radiotap.dbm_antsignal",
2381                   FT_INT32, BASE_DEC, NULL, 0x0,
2382                   "RF signal power at the antenna from a fixed,"
2383                   " arbitrary value in decibels from one milliwatt", HFILL}},
2384
2385                 {&hf_radiotap_db_antsignal,
2386                  {"SSI Signal (dB)", "radiotap.db_antsignal",
2387                   FT_UINT32, BASE_DEC, NULL, 0x0,
2388                   "RF signal power at the antenna from a fixed, arbitrary value in decibels", HFILL}},
2389
2390                 {&hf_radiotap_dbm_antnoise,
2391                  {"SSI Noise (dBm)", "radiotap.dbm_antnoise",
2392                   FT_INT32, BASE_DEC, NULL, 0x0,
2393                   "RF noise power at the antenna from a fixed, arbitrary value"
2394                   " in decibels per one milliwatt", HFILL}},
2395
2396                 {&hf_radiotap_db_antnoise,
2397                  {"SSI Noise (dB)", "radiotap.db_antnoise",
2398                   FT_UINT32, BASE_DEC, NULL, 0x0,
2399                   "RF noise power at the antenna from a fixed, arbitrary value"
2400                   " in decibels", HFILL}},
2401
2402                 {&hf_radiotap_tx_attenuation,
2403                  {"Transmit attenuation", "radiotap.txattenuation",
2404                   FT_UINT16, BASE_DEC, NULL, 0x0,
2405                   "Transmit power expressed as unitless distance from max power"
2406                   " set at factory (0 is max power)", HFILL}},
2407
2408                 {&hf_radiotap_db_tx_attenuation,
2409                  {"Transmit attenuation (dB)", "radiotap.db_txattenuation",
2410                   FT_UINT16, BASE_DEC, NULL, 0x0,
2411                   "Transmit power expressed as decibels from max power"
2412                   " set at factory (0 is max power)", HFILL}},
2413
2414                 {&hf_radiotap_txpower,
2415                  {"Transmit power", "radiotap.txpower",
2416                   FT_INT32, BASE_DEC, NULL, 0x0,
2417                   "Transmit power in decibels per one milliwatt (dBm)", HFILL}},
2418
2419                 {&hf_radiotap_mcs,
2420                  {"MCS information", "radiotap.mcs",
2421                   FT_NONE, BASE_NONE, NULL, 0x0,
2422                   NULL, HFILL}},
2423
2424                 {&hf_radiotap_mcs_known,
2425                  {"Known MCS information", "radiotap.mcs.known",
2426                   FT_UINT8, BASE_HEX, NULL, 0x0,
2427                   "Bit mask indicating what MCS information is present", HFILL}},
2428
2429                 {&hf_radiotap_mcs_have_bw,
2430                  {"Bandwidth", "radiotap.mcs.have_bw",
2431                   FT_BOOLEAN, 8, NULL, IEEE80211_RADIOTAP_MCS_HAVE_BW,
2432                   "Bandwidth information present", HFILL}},
2433
2434                 {&hf_radiotap_mcs_have_gi,
2435                  {"Guard interval", "radiotap.mcs.have_gi",
2436                   FT_BOOLEAN, 8, NULL, IEEE80211_RADIOTAP_MCS_HAVE_GI,
2437                   "Sent/Received guard interval information present", HFILL}},
2438
2439                 {&hf_radiotap_mcs_have_format,
2440                  {"Format", "radiotap.mcs.have_format",
2441                   FT_BOOLEAN, 8, NULL, IEEE80211_RADIOTAP_MCS_HAVE_FMT,
2442                   "Format information present", HFILL}},
2443
2444                 {&hf_radiotap_mcs_have_fec,
2445                  {"FEC", "radiotap.mcs.have_fec",
2446                   FT_BOOLEAN, 8, NULL, IEEE80211_RADIOTAP_MCS_HAVE_FEC,
2447                   "Forward error correction information present", HFILL}},
2448
2449                 {&hf_radiotap_mcs_have_stbc,
2450                  {"STBC", "radiotap.mcs.have_stbc",
2451                   FT_BOOLEAN, 8, NULL, IEEE80211_RADIOTAP_MCS_HAVE_STBC,
2452                   "Space Time Block Coding information present", HFILL}},
2453
2454                 {&hf_radiotap_mcs_have_index,
2455                  {"MCS index", "radiotap.mcs.have_index",
2456                   FT_BOOLEAN, 8, NULL, IEEE80211_RADIOTAP_MCS_HAVE_MCS,
2457                   "MCS index information present", HFILL}},
2458
2459                 {&hf_radiotap_mcs_bw,
2460                  {"Bandwidth", "radiotap.mcs.bw",
2461                   FT_UINT8, BASE_DEC, VALS(mcs_bandwidth),
2462                   IEEE80211_RADIOTAP_MCS_BW_MASK, NULL, HFILL}},
2463
2464                 {&hf_radiotap_mcs_gi,
2465                  {"Guard interval", "radiotap.mcs.gi",
2466                   FT_UINT8, BASE_DEC, VALS(mcs_gi), IEEE80211_RADIOTAP_MCS_SGI,
2467                   "Sent/Received guard interval", HFILL}},
2468
2469                 {&hf_radiotap_mcs_format,
2470                  {"Format", "radiotap.mcs.format",
2471                   FT_UINT8, BASE_DEC, VALS(mcs_format), IEEE80211_RADIOTAP_MCS_FMT_GF,
2472                   NULL, HFILL}},
2473
2474                 {&hf_radiotap_mcs_fec,
2475                  {"FEC", "radiotap.mcs.fec",
2476                   FT_UINT8, BASE_DEC, VALS(mcs_fec), IEEE80211_RADIOTAP_MCS_FEC_LDPC,
2477                   "forward error correction", HFILL}},
2478
2479                 {&hf_radiotap_mcs_stbc,
2480                  {"STBC", "radiotap.mcs.stbc",
2481                   FT_BOOLEAN, 8, TFS(&tfs_on_off), IEEE80211_RADIOTAP_MCS_STBC,
2482                   "Space Time Block Code", HFILL}},
2483
2484                 {&hf_radiotap_mcs_index,
2485                  {"MCS index", "radiotap.mcs.index",
2486                   FT_UINT8, BASE_DEC, NULL, 0x0,
2487                   NULL, HFILL}},
2488
2489                 {&hf_radiotap_ampdu,
2490                  {"A-MPDU status", "radiotap.ampdu",
2491                   FT_NONE, BASE_NONE, NULL, 0x0,
2492                   NULL, HFILL}},
2493
2494                 {&hf_radiotap_ampdu_ref,
2495                  {"A-MPDU reference number", "radiotap.ampdu.reference",
2496                   FT_UINT32, BASE_DEC, NULL, 0x0,
2497                   NULL, HFILL}},
2498
2499                 {&hf_radiotap_ampdu_flags,
2500                  {"A-MPDU flags", "radiotap.ampdu.flags",
2501                   FT_UINT16, BASE_HEX, NULL, 0x0,
2502                   "A-MPDU status flags", HFILL}},
2503
2504                 {&hf_radiotap_ampdu_flags_report_zerolen,
2505                  {"Driver reports 0-length subframes in this A-MPDU", "radiotap.ampdu.flags.report_zerolen",
2506                   FT_BOOLEAN, 16, NULL, IEEE80211_RADIOTAP_AMPDU_REPORT_ZEROLEN,
2507                   NULL, HFILL}},
2508
2509                 {&hf_radiotap_ampdu_flags_is_zerolen,
2510                  {"This is a 0-length subframe", "radiotap.ampdu.flags.is_zerolen",
2511                   FT_BOOLEAN, 16, NULL, IEEE80211_RADIOTAP_AMPDU_IS_ZEROLEN,
2512                   NULL, HFILL}},
2513
2514                 {&hf_radiotap_ampdu_flags_last_known,
2515                  {"Last subframe of this A-MPDU is known", "radiotap.ampdu.flags.lastknown",
2516                   FT_BOOLEAN, 16, NULL, IEEE80211_RADIOTAP_AMPDU_LAST_KNOWN,
2517                   NULL, HFILL}},
2518
2519                 {&hf_radiotap_ampdu_flags_is_last,
2520                  {"This is the last subframe of this A-MPDU", "radiotap.ampdu.flags.last",
2521                   FT_BOOLEAN, 16, NULL, IEEE80211_RADIOTAP_AMPDU_IS_LAST,
2522                   NULL, HFILL}},
2523
2524                 {&hf_radiotap_ampdu_flags_delim_crc_error,
2525                  {"Delimiter CRC error on this subframe", "radiotap.ampdu.flags.delim_crc_error",
2526                   FT_BOOLEAN, 16, NULL, IEEE80211_RADIOTAP_AMPDU_DELIM_CRC_ERR,
2527                   NULL, HFILL}},
2528
2529                 {&hf_radiotap_ampdu_delim_crc,
2530                  {"A-MPDU subframe delimiter CRC", "radiotap.ampdu.delim_crc",
2531                   FT_UINT8, BASE_HEX, NULL, 0x0,
2532                   NULL, HFILL}},
2533
2534                 {&hf_radiotap_vht,
2535                  {"VHT information", "radiotap.vht",
2536                   FT_NONE, BASE_NONE, NULL, 0x0,
2537                   NULL, HFILL}},
2538
2539                 {&hf_radiotap_vht_known,
2540                  {"Known VHT information", "radiotap.vht.known",
2541                   FT_UINT8, BASE_HEX, NULL, 0x0,
2542                   "Bit mask indicating what VHT information is present", HFILL}},
2543
2544                 {&hf_radiotap_vht_user,
2545                  {"User", "radiotap.vht.user",
2546                   FT_NONE, BASE_NONE, NULL, 0x0,
2547                   NULL, HFILL}},
2548
2549                 {&hf_radiotap_vht_have_stbc,
2550                  {"STBC", "radiotap.vht.have_stbc",
2551                   FT_BOOLEAN, 16, NULL, IEEE80211_RADIOTAP_VHT_HAVE_STBC,
2552                   "Space Time Block Coding information present", HFILL}},
2553
2554                 {&hf_radiotap_vht_have_txop_ps,
2555                  {"TXOP_PS_NOT_ALLOWED", "radiotap.vht.have_txop_ps",
2556                   FT_BOOLEAN, 16, NULL, IEEE80211_RADIOTAP_VHT_HAVE_TXOP_PS,
2557                   "TXOP_PS_NOT_ALLOWED information present", HFILL}},
2558
2559                 {&hf_radiotap_vht_have_gi,
2560                  {"Guard interval", "radiotap.vht.have_gi",
2561                   FT_BOOLEAN, 16, NULL, IEEE80211_RADIOTAP_VHT_HAVE_GI,
2562                   "Short/Long guard interval information present", HFILL}},
2563
2564                 {&hf_radiotap_vht_have_sgi_nsym_da,
2565                  {"SGI Nsym disambiguation", "radiotap.vht.have_sgi_nsym_da",
2566                   FT_BOOLEAN, 16, NULL, IEEE80211_RADIOTAP_VHT_HAVE_SGI_NSYM_DA,
2567                   "Short guard interval Nsym disambiguation information present", HFILL}},
2568
2569                 {&hf_radiotap_vht_have_ldpc_extra,
2570                  {"LDPC extra OFDM symbol", "radiotap.vht.ldpc_extra",
2571                   FT_BOOLEAN, 16, NULL, IEEE80211_RADIOTAP_VHT_HAVE_LDPC_EXTRA,
2572                   NULL, HFILL}},
2573
2574                 {&hf_radiotap_vht_have_bf,
2575                  {"Beamformed", "radiotap.vht.have_beamformed",
2576                   FT_BOOLEAN, 16, NULL, IEEE80211_RADIOTAP_VHT_HAVE_BF,
2577                   NULL, HFILL}},
2578
2579                 {&hf_radiotap_vht_have_bw,
2580                  {"Bandwidth", "radiotap.mcs.have_bw",
2581                   FT_BOOLEAN, 16, NULL, IEEE80211_RADIOTAP_VHT_HAVE_BW,
2582                   NULL, HFILL}},
2583
2584                 {&hf_radiotap_vht_have_gid,
2585                  {"Group ID", "radiotap.mcs.have_gid",
2586                   FT_BOOLEAN, 16, NULL, IEEE80211_RADIOTAP_VHT_HAVE_GID,
2587                   NULL, HFILL}},
2588
2589                 {&hf_radiotap_vht_have_p_aid,
2590                  {"Partial AID", "radiotap.mcs.have_paid",
2591                   FT_BOOLEAN, 16, NULL, IEEE80211_RADIOTAP_VHT_HAVE_PAID,
2592                   NULL, HFILL}},
2593
2594                 {&hf_radiotap_vht_stbc,
2595                  {"STBC", "radiotap.vht.stbc",
2596                   FT_BOOLEAN, 8, TFS(&tfs_on_off), IEEE80211_RADIOTAP_VHT_STBC,
2597                   "Space Time Block Coding flag", HFILL}},
2598
2599                 {&hf_radiotap_vht_txop_ps,
2600                  {"TXOP_PS_NOT_ALLOWED", "radiotap.vht.txop_ps",
2601                   FT_BOOLEAN, 8, NULL, IEEE80211_RADIOTAP_VHT_TXOP_PS,
2602                   "Flag indicating whether STAs may doze during TXOP", HFILL}},
2603
2604                 {&hf_radiotap_vht_gi,
2605                  {"Guard interval", "radiotap.vht.gi",
2606                   FT_UINT8, BASE_DEC, VALS(mcs_gi), IEEE80211_RADIOTAP_VHT_SGI,
2607                   "Short/Long guard interval", HFILL}},
2608
2609                 {&hf_radiotap_vht_sgi_nsym_da,
2610                  {"SGI Nsym disambiguation", "radiotap.vht.sgi_nsym_da",
2611                   FT_BOOLEAN, 8, NULL, IEEE80211_RADIOTAP_VHT_SGI_NSYM_DA,
2612                   "Short Guard Interval Nsym disambiguation", HFILL}},
2613
2614                 {&hf_radiotap_vht_ldpc_extra,
2615                  {"LDPC extra OFDM symbol", "radiotap.vht.ldpc_extra",
2616                   FT_BOOLEAN, 8, NULL, IEEE80211_RADIOTAP_VHT_LDPC_EXTRA,
2617                   NULL, HFILL}},
2618
2619                 {&hf_radiotap_vht_bf,
2620                  {"Beamformed", "radiotap.vht.beamformed",
2621                   FT_BOOLEAN, 8, NULL, IEEE80211_RADIOTAP_VHT_BF,
2622                   NULL, HFILL}},
2623
2624                 {&hf_radiotap_vht_bw,
2625                  {"Bandwidth", "radiotap.vht.bw",
2626                   FT_UINT8, BASE_DEC | BASE_EXT_STRING, &vht_bandwidth_ext, 0x0,
2627                   NULL, HFILL}},
2628
2629                 {&hf_radiotap_vht_nsts[0],
2630                  {"Space-time streams 0", "radiotap.vht.nsts.0",
2631                   FT_UINT8, BASE_DEC, NULL, 0x0,
2632                   "Number of Space-time streams", HFILL}},
2633
2634                 {&hf_radiotap_vht_nsts[1],
2635                  {"Space-time streams 1", "radiotap.vht.nsts.1",
2636                   FT_UINT8, BASE_DEC, NULL, 0x0,
2637                   "Number of Space-time streams", HFILL}},
2638
2639                 {&hf_radiotap_vht_nsts[2],
2640                  {"Space-time streams 2", "radiotap.vht.nsts.2",
2641                   FT_UINT8, BASE_DEC, NULL, 0x0,
2642                   "Number of Space-time streams", HFILL}},
2643
2644                 {&hf_radiotap_vht_nsts[3],
2645                  {"Space-time streams 3", "radiotap.vht.nsts.3",
2646                   FT_UINT8, BASE_DEC, NULL, 0x0,
2647                   "Number of Space-time streams", HFILL}},
2648
2649                 {&hf_radiotap_vht_mcs[0],
2650                  {"MCS index 0", "radiotap.vht.mcs.0",
2651                   FT_UINT8, BASE_DEC, NULL, IEEE80211_RADIOTAP_VHT_MCS,
2652                   "MCS index", HFILL}},
2653
2654                 {&hf_radiotap_vht_mcs[1],
2655                  {"MCS index 1", "radiotap.vht.mcs.1",
2656                   FT_UINT8, BASE_DEC, NULL, IEEE80211_RADIOTAP_VHT_MCS,
2657                   "MCS index", HFILL}},
2658
2659                 {&hf_radiotap_vht_mcs[2],
2660                  {"MCS index 2", "radiotap.vht.mcs.2",
2661                   FT_UINT8, BASE_DEC, NULL, IEEE80211_RADIOTAP_VHT_MCS,
2662                   "MCS index", HFILL}},
2663
2664                 {&hf_radiotap_vht_mcs[3],
2665                  {"MCS index 3", "radiotap.vht.mcs.3",
2666                   FT_UINT8, BASE_DEC, NULL, IEEE80211_RADIOTAP_VHT_MCS,
2667                   "MCS index", HFILL}},
2668
2669                 {&hf_radiotap_vht_nss[0],
2670                  {"Spatial streams 0", "radiotap.vht.nss.0",
2671                   FT_UINT8, BASE_DEC, NULL, IEEE80211_RADIOTAP_VHT_NSS,
2672                   "Number of spatial streams", HFILL}},
2673
2674                 {&hf_radiotap_vht_nss[1],
2675                  {"Spatial streams 1", "radiotap.vht.nss.1",
2676                   FT_UINT8, BASE_DEC, NULL, IEEE80211_RADIOTAP_VHT_NSS,
2677                   "Number of spatial streams", HFILL}},
2678
2679                 {&hf_radiotap_vht_nss[2],
2680                  {"Spatial streams 2", "radiotap.vht.nss.2",
2681                   FT_UINT8, BASE_DEC, NULL, IEEE80211_RADIOTAP_VHT_NSS,
2682                   "Number of spatial streams", HFILL}},
2683
2684                 {&hf_radiotap_vht_nss[3],
2685                  {"Spatial streams 3", "radiotap.vht.nss.3",
2686                   FT_UINT8, BASE_DEC, NULL, IEEE80211_RADIOTAP_VHT_NSS,
2687                   "Number of spatial streams", HFILL}},
2688
2689                 {&hf_radiotap_vht_coding[0],
2690                  {"Coding 0", "radiotap.vht.coding.0",
2691                   FT_UINT8, BASE_DEC, VALS(mcs_fec), 0x0,
2692                   "Coding", HFILL}},
2693
2694                 {&hf_radiotap_vht_coding[1],
2695                  {"Coding 1", "radiotap.vht.coding.1",
2696                   FT_UINT8, BASE_DEC, VALS(mcs_fec), 0x0,
2697                   "Coding", HFILL}},
2698
2699                 {&hf_radiotap_vht_coding[2],
2700                  {"Coding 2", "radiotap.vht.coding.2",
2701                   FT_UINT8, BASE_DEC, VALS(mcs_fec), 0x0,
2702                   "Coding", HFILL}},
2703
2704                 {&hf_radiotap_vht_coding[3],
2705                  {"Coding 3", "radiotap.vht.coding.3",
2706                   FT_UINT8, BASE_DEC, VALS(mcs_fec), 0x0,
2707                   "Coding", HFILL}},
2708
2709                 {&hf_radiotap_vht_datarate[0],
2710                  {"Data rate (Mb/s) 0", "radiotap.vht.datarate.0",
2711                   FT_FLOAT, BASE_NONE, NULL, 0x0,
2712                   "Speed this frame was sent/received at", HFILL}},
2713
2714                 {&hf_radiotap_vht_datarate[1],
2715                  {"Data rate (Mb/s) 1", "radiotap.vht.datarate.1",
2716                   FT_FLOAT, BASE_NONE, NULL, 0x0,
2717                   "Speed this frame was sent/received at", HFILL}},
2718
2719                 {&hf_radiotap_vht_datarate[2],
2720                  {"Data rate (Mb/s) 2", "radiotap.vht.datarate.2",
2721                   FT_FLOAT, BASE_NONE, NULL, 0x0,
2722                   "Speed this frame was sent/received at", HFILL}},
2723
2724                 {&hf_radiotap_vht_datarate[3],
2725                  {"Data rate (Mb/s) 3", "radiotap.vht.datarate.3",
2726                   FT_FLOAT, BASE_NONE, NULL, 0x0,
2727                   "Speed this frame was sent/received at", HFILL}},
2728
2729                 {&hf_radiotap_vht_gid,
2730                  {"Group Id", "radiotap.vht.gid",
2731                   FT_UINT8, BASE_DEC, NULL, 0x0,
2732                   NULL, HFILL}},
2733
2734                 {&hf_radiotap_vht_p_aid,
2735                  {"Partial AID", "radiotap.vht.paid",
2736                   FT_UINT16, BASE_DEC, NULL, 0x0,
2737                   NULL, HFILL}},
2738
2739                 {&hf_radiotap_vendor_ns,
2740                  {"Vendor namespace", "radiotap.vendor_namespace",
2741                   FT_BYTES, BASE_NONE, NULL, 0x0,
2742                   NULL, HFILL}},
2743
2744                 {&hf_radiotap_ven_oui,
2745                  {"Vendor OUI", "radiotap.vendor_oui",
2746                   FT_BYTES, BASE_NONE, NULL, 0x0,
2747                   NULL, HFILL}},
2748
2749                 {&hf_radiotap_ven_subns,
2750                  {"Vendor sub namespace", "radiotap.vendor_subns",
2751                   FT_UINT8, BASE_DEC, NULL, 0x0,
2752                   "Vendor-specified sub namespace", HFILL}},
2753
2754                 {&hf_radiotap_ven_skip,
2755                  {"Vendor data length", "radiotap.vendor_data_len",
2756                   FT_UINT16, BASE_DEC, NULL, 0x0,
2757                   "Length of vendor-specified data", HFILL}},
2758
2759                 {&hf_radiotap_ven_data,
2760                  {"Vendor data", "radiotap.vendor_data",
2761                   FT_NONE, BASE_NONE, NULL, 0x0,
2762                   "Vendor-specified data", HFILL}},
2763
2764                 /* Special variables */
2765                 {&hf_radiotap_fcs_bad,
2766                  {"Bad FCS", "radiotap.fcs_bad",
2767                   FT_BOOLEAN, BASE_NONE, NULL, 0x0,
2768                   "Specifies if this frame has a bad frame check sequence", HFILL}},
2769
2770         };
2771         static gint *ett[] = {
2772                 &ett_radiotap,
2773                 &ett_radiotap_present,
2774                 &ett_radiotap_flags,
2775                 &ett_radiotap_rxflags,
2776                 &ett_radiotap_channel_flags,
2777                 &ett_radiotap_xchannel_flags,
2778                 &ett_radiotap_vendor,
2779                 &ett_radiotap_mcs,
2780                 &ett_radiotap_mcs_known,
2781                 &ett_radiotap_ampdu,
2782                 &ett_radiotap_ampdu_flags,
2783                 &ett_radiotap_vht,
2784                 &ett_radiotap_vht_known,
2785                 &ett_radiotap_vht_user
2786         };
2787         module_t *radiotap_module;
2788
2789         proto_radiotap =
2790             proto_register_protocol("IEEE 802.11 Radiotap Capture header",
2791                                     "802.11 Radiotap", "radiotap");
2792         proto_register_field_array(proto_radiotap, hf, array_length(hf));
2793         proto_register_subtree_array(ett, array_length(ett));
2794         register_dissector("radiotap", dissect_radiotap, proto_radiotap);
2795
2796         radiotap_tap = register_tap("radiotap");
2797
2798         radiotap_module = prefs_register_protocol(proto_radiotap, NULL);
2799         prefs_register_bool_preference(radiotap_module, "bit14_fcs_in_header",
2800                                        "Assume bit 14 means FCS in header",
2801                                        "Radiotap has a bit to indicate whether the FCS is still on the frame or not. "
2802                                        "Some generators (e.g. AirPcap) use a non-standard radiotap flag 14 to put "
2803                                        "the FCS into the header.",
2804                                        &radiotap_bit14_fcs);
2805 }
2806
2807 void proto_reg_handoff_radiotap(void)
2808 {
2809         dissector_handle_t radiotap_handle;
2810
2811         /* handle for 802.11 dissector */
2812         ieee80211_handle = find_dissector("wlan");
2813         ieee80211_datapad_handle = find_dissector("wlan_datapad");
2814
2815         radiotap_handle = find_dissector("radiotap");
2816
2817         dissector_add_uint("wtap_encap", WTAP_ENCAP_IEEE_802_11_RADIOTAP,
2818                            radiotap_handle);
2819 }
2820
2821 /*
2822  * Editor modelines  -  http://www.wireshark.org/tools/modelines.html
2823  *
2824  * Local variables:
2825  * c-basic-offset: 8
2826  * tab-width: 8
2827  * indent-tabs-mode: t
2828  * End:
2829  *
2830  * vi: set shiftwidth=8 tabstop=8 noexpandtab:
2831  * :indentSize=8:tabSize=8:noTabs=false:
2832  */