Don't divide the data rate by 2 - that loses information (yes, I have a
[metze/wireshark/wip.git] / epan / dissectors / packet-radiotap.c
1 /*
2  *  packet-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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
26  */
27
28 #ifdef HAVE_CONFIG_H
29 # include "config.h"
30 #endif
31
32 #include <glib.h>
33 #include <string.h>
34
35 #include <epan/packet.h>
36 #include <epan/crc32.h>
37 #include <epan/frequency-utils.h>
38 #include <epan/tap.h>
39 #include <epan/prefs.h>
40 #include "packet-ieee80211.h"
41 #include "packet-radiotap.h"
42
43 /* Official specifcation:
44  *
45  * http://www.radiotap.org/
46  *
47  * Unofficial and historical specifications:
48  * http://madwifi.org/wiki/DevDocs/RadiotapHeader
49  * NetBSD's ieee80211_radiotap.h file
50  */
51
52 struct ieee80211_radiotap_header {
53     guint8      it_version;     /* Version 0. Only increases
54                                  * for drastic changes,
55                                  * introduction of compatible
56                                  * new fields does not count.
57                                  */
58     guint8      it_pad;
59     guint16     it_len;         /* length of the whole
60                                  * header in bytes, including
61                                  * it_version, it_pad,
62                                  * it_len, and data fields.
63                                  */
64 #define MAX_PRESENT 1
65     guint32   it_present[MAX_PRESENT];  /* A bitmap telling which
66                                          * fields are present. Set bit 31
67                                          * (0x80000000) to extend the
68                                          * bitmap by another 32 bits.
69                                          * Additional extensions are made
70                                          * by setting bit 31.
71                                          */
72 };
73
74 #define RADIOTAP_MIN_HEADER_LEN 8       /* minimum header length */
75 #define RADIOTAP_VERSION_OFFSET 0       /* offset of version field */
76 #define RADIOTAP_LENGTH_OFFSET  2       /* offset of length field */
77 #define RADIOTAP_PRESENT_OFFSET 4       /* offset of "present" field */
78
79 enum ieee80211_radiotap_type {
80     IEEE80211_RADIOTAP_TSFT = 0,
81     IEEE80211_RADIOTAP_FLAGS = 1,
82     IEEE80211_RADIOTAP_RATE = 2,
83     IEEE80211_RADIOTAP_CHANNEL = 3,
84     IEEE80211_RADIOTAP_FHSS = 4,
85     IEEE80211_RADIOTAP_DBM_ANTSIGNAL = 5,
86     IEEE80211_RADIOTAP_DBM_ANTNOISE = 6,
87     IEEE80211_RADIOTAP_LOCK_QUALITY = 7,
88     IEEE80211_RADIOTAP_TX_ATTENUATION = 8,
89     IEEE80211_RADIOTAP_DB_TX_ATTENUATION = 9,
90     IEEE80211_RADIOTAP_DBM_TX_POWER = 10,
91     IEEE80211_RADIOTAP_ANTENNA = 11,
92     IEEE80211_RADIOTAP_DB_ANTSIGNAL = 12,
93     IEEE80211_RADIOTAP_DB_ANTNOISE = 13,
94     IEEE80211_RADIOTAP_RX_FLAGS = 14,
95     IEEE80211_RADIOTAP_XCHANNEL = 18,
96     IEEE80211_RADIOTAP_EXT = 31
97 };
98
99 /* Channel flags. */
100 #define IEEE80211_CHAN_TURBO    0x00010 /* Turbo channel */
101 #define IEEE80211_CHAN_CCK      0x00020 /* CCK channel */
102 #define IEEE80211_CHAN_OFDM     0x00040 /* OFDM channel */
103 #define IEEE80211_CHAN_2GHZ     0x00080 /* 2 GHz spectrum channel. */
104 #define IEEE80211_CHAN_5GHZ     0x00100 /* 5 GHz spectrum channel */
105 #define IEEE80211_CHAN_PASSIVE  0x00200 /* Only passive scan allowed */
106 #define IEEE80211_CHAN_DYN      0x00400 /* Dynamic CCK-OFDM channel */
107 #define IEEE80211_CHAN_GFSK     0x00800 /* GFSK channel (FHSS PHY) */
108 #define IEEE80211_CHAN_GSM      0x01000 /* 900 MHz spectrum channel */
109 #define IEEE80211_CHAN_STURBO   0x02000 /* 11a static turbo channel only */
110 #define IEEE80211_CHAN_HALF     0x04000 /* Half rate channel */
111 #define IEEE80211_CHAN_QUARTER  0x08000 /* Quarter rate channel */
112 #define IEEE80211_CHAN_HT20     0x10000 /* HT 20 channel */
113 #define IEEE80211_CHAN_HT40U    0x20000 /* HT 40 channel w/ ext above */
114 #define IEEE80211_CHAN_HT40D    0x40000 /* HT 40 channel w/ ext below */
115
116 /*
117  * Useful combinations of channel characteristics.
118  */
119 #define IEEE80211_CHAN_FHSS \
120         (IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_GFSK)
121 #define IEEE80211_CHAN_A \
122         (IEEE80211_CHAN_5GHZ | IEEE80211_CHAN_OFDM)
123 #define IEEE80211_CHAN_B \
124         (IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_CCK)
125 #define IEEE80211_CHAN_PUREG \
126         (IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_OFDM)
127 #define IEEE80211_CHAN_G \
128         (IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_DYN)
129 #define IEEE80211_CHAN_T \
130         (IEEE80211_CHAN_5GHZ | IEEE80211_CHAN_OFDM | IEEE80211_CHAN_TURBO)
131 #define IEEE80211_CHAN_108G \
132         (IEEE80211_CHAN_G | IEEE80211_CHAN_TURBO)
133 #define IEEE80211_CHAN_108PUREG \
134         (IEEE80211_CHAN_PUREG | IEEE80211_CHAN_TURBO)
135
136 /* For IEEE80211_RADIOTAP_FLAGS */
137 #define IEEE80211_RADIOTAP_F_CFP        0x01    /* sent/received
138                                                  * during CFP
139                                                  */
140 #define IEEE80211_RADIOTAP_F_SHORTPRE   0x02    /* sent/received
141                                                  * with short
142                                                  * preamble
143                                                  */
144 #define IEEE80211_RADIOTAP_F_WEP        0x04    /* sent/received
145                                                  * with WEP encryption
146                                                  */
147 #define IEEE80211_RADIOTAP_F_FRAG       0x08    /* sent/received
148                                                  * with fragmentation
149                                                  */
150 #define IEEE80211_RADIOTAP_F_FCS        0x10    /* frame includes FCS */
151 #define IEEE80211_RADIOTAP_F_DATAPAD    0x20    /* frame has padding between
152                                                  * 802.11 header and payload
153                                                  * (to 32-bit boundary)
154                                                  */
155 #define IEEE80211_RADIOTAP_F_BADFCS     0x40    /* does not pass FCS check */
156 #define IEEE80211_RADIOTAP_F_SHORTGI    0x80    /* HT short GI */
157
158 /* For IEEE80211_RADIOTAP_RX_FLAGS */
159 #define IEEE80211_RADIOTAP_F_RX_BADPLCP         0x0002 /* bad PLCP */
160
161 /* XXX need max array size */
162 static const int ieee80211_htrates[16] = {
163         13,             /* IFM_IEEE80211_MCS0 */
164         26,             /* IFM_IEEE80211_MCS1 */
165         39,             /* IFM_IEEE80211_MCS2 */
166         52,             /* IFM_IEEE80211_MCS3 */
167         78,             /* IFM_IEEE80211_MCS4 */
168         104,            /* IFM_IEEE80211_MCS5 */
169         117,            /* IFM_IEEE80211_MCS6 */
170         130,            /* IFM_IEEE80211_MCS7 */
171         26,             /* IFM_IEEE80211_MCS8 */
172         52,             /* IFM_IEEE80211_MCS9 */
173         78,             /* IFM_IEEE80211_MCS10 */
174         104,            /* IFM_IEEE80211_MCS11 */
175         156,            /* IFM_IEEE80211_MCS12 */
176         208,            /* IFM_IEEE80211_MCS13 */
177         234,            /* IFM_IEEE80211_MCS14 */
178         260,            /* IFM_IEEE80211_MCS15 */
179 };
180
181 /* protocol */
182 static int proto_radiotap = -1;
183
184 static int hf_radiotap_version = -1;
185 static int hf_radiotap_pad = -1;
186 static int hf_radiotap_length = -1;
187 static int hf_radiotap_present = -1;
188 static int hf_radiotap_mactime = -1;
189 static int hf_radiotap_channel = -1;
190 static int hf_radiotap_channel_frequency = -1;
191 static int hf_radiotap_channel_flags = -1;
192 static int hf_radiotap_channel_flags_turbo = -1;
193 static int hf_radiotap_channel_flags_cck = -1;
194 static int hf_radiotap_channel_flags_ofdm = -1;
195 static int hf_radiotap_channel_flags_2ghz = -1;
196 static int hf_radiotap_channel_flags_5ghz = -1;
197 static int hf_radiotap_channel_flags_passive = -1;
198 static int hf_radiotap_channel_flags_dynamic = -1;
199 static int hf_radiotap_channel_flags_gfsk = -1;
200 static int hf_radiotap_channel_flags_gsm = -1;
201 static int hf_radiotap_channel_flags_sturbo = -1;
202 static int hf_radiotap_channel_flags_half = -1;
203 static int hf_radiotap_channel_flags_quarter = -1;
204 static int hf_radiotap_rxflags = -1;
205 static int hf_radiotap_rxflags_badplcp = -1;
206 static int hf_radiotap_xchannel = -1;
207 static int hf_radiotap_xchannel_frequency = -1;
208 static int hf_radiotap_xchannel_flags = -1;
209 static int hf_radiotap_xchannel_flags_turbo = -1;
210 static int hf_radiotap_xchannel_flags_cck = -1;
211 static int hf_radiotap_xchannel_flags_ofdm = -1;
212 static int hf_radiotap_xchannel_flags_2ghz = -1;
213 static int hf_radiotap_xchannel_flags_5ghz = -1;
214 static int hf_radiotap_xchannel_flags_passive = -1;
215 static int hf_radiotap_xchannel_flags_dynamic = -1;
216 static int hf_radiotap_xchannel_flags_gfsk = -1;
217 static int hf_radiotap_xchannel_flags_gsm = -1;
218 static int hf_radiotap_xchannel_flags_sturbo = -1;
219 static int hf_radiotap_xchannel_flags_half = -1;
220 static int hf_radiotap_xchannel_flags_quarter = -1;
221 static int hf_radiotap_xchannel_flags_ht20 = -1;
222 static int hf_radiotap_xchannel_flags_ht40u = -1;
223 static int hf_radiotap_xchannel_flags_ht40d = -1;
224 #if 0
225 static int hf_radiotap_xchannel_maxpower = -1;
226 #endif
227 static int hf_radiotap_fhss_hopset = -1;
228 static int hf_radiotap_fhss_pattern = -1;
229 static int hf_radiotap_datarate = -1;
230 static int hf_radiotap_antenna = -1;
231 static int hf_radiotap_dbm_antsignal = -1;
232 static int hf_radiotap_db_antsignal = -1;
233 static int hf_radiotap_dbm_antnoise = -1;
234 static int hf_radiotap_db_antnoise = -1;
235 static int hf_radiotap_tx_attenuation = -1;
236 static int hf_radiotap_db_tx_attenuation = -1;
237 static int hf_radiotap_txpower = -1;
238
239 /* "Present" flags */
240 static int hf_radiotap_present_tsft = -1;
241 static int hf_radiotap_present_flags = -1;
242 static int hf_radiotap_present_rate = -1;
243 static int hf_radiotap_present_channel = -1;
244 static int hf_radiotap_present_fhss = -1;
245 static int hf_radiotap_present_dbm_antsignal = -1;
246 static int hf_radiotap_present_dbm_antnoise = -1;
247 static int hf_radiotap_present_lock_quality = -1;
248 static int hf_radiotap_present_tx_attenuation = -1;
249 static int hf_radiotap_present_db_tx_attenuation = -1;
250 static int hf_radiotap_present_dbm_tx_attenuation = -1;
251 static int hf_radiotap_present_antenna = -1;
252 static int hf_radiotap_present_db_antsignal = -1;
253 static int hf_radiotap_present_db_antnoise = -1;
254 static int hf_radiotap_present_hdrfcs = -1;
255 static int hf_radiotap_present_rxflags = -1;
256 static int hf_radiotap_present_xchannel = -1;
257 static int hf_radiotap_present_ext = -1;
258
259 /* "present.flags" flags */
260 static int hf_radiotap_flags = -1;
261 static int hf_radiotap_flags_cfp = -1;
262 static int hf_radiotap_flags_preamble = -1;
263 static int hf_radiotap_flags_wep = -1;
264 static int hf_radiotap_flags_frag = -1;
265 static int hf_radiotap_flags_fcs = -1;
266 static int hf_radiotap_flags_datapad = -1;
267 static int hf_radiotap_flags_badfcs = -1;
268 static int hf_radiotap_flags_shortgi = -1;
269
270 static int hf_radiotap_quality = -1;
271 static int hf_radiotap_fcs = -1;
272 static int hf_radiotap_fcs_bad = -1;
273
274 static gint ett_radiotap = -1;
275 static gint ett_radiotap_present = -1;
276 static gint ett_radiotap_flags = -1;
277 static gint ett_radiotap_rxflags = -1;
278 static gint ett_radiotap_channel_flags = -1;
279 static gint ett_radiotap_xchannel_flags = -1;
280
281 static dissector_handle_t ieee80211_handle;
282 static dissector_handle_t ieee80211_datapad_handle;
283
284 static int radiotap_tap = -1;
285
286 /* Settings */
287 static gboolean radiotap_bit14_fcs = FALSE;
288
289 static void
290 dissect_radiotap(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
291
292 #define BITNO_32(x) (((x) >> 16) ? 16 + BITNO_16((x) >> 16) : BITNO_16((x)))
293 #define BITNO_16(x) (((x) >> 8) ? 8 + BITNO_8((x) >> 8) : BITNO_8((x)))
294 #define BITNO_8(x) (((x) >> 4) ? 4 + BITNO_4((x) >> 4) : BITNO_4((x)))
295 #define BITNO_4(x) (((x) >> 2) ? 2 + BITNO_2((x) >> 2) : BITNO_2((x)))
296 #define BITNO_2(x) (((x) & 2) ? 1 : 0)
297 #define BIT(n)  (1 << n)
298
299 /*
300  * The NetBSD ieee80211_radiotap man page
301  * (http://netbsd.gw.com/cgi-bin/man-cgi?ieee80211_radiotap+9+NetBSD-current)
302  * says:
303  *
304  *    Radiotap capture fields must be naturally aligned.  That is, 16-, 32-,
305  *    and 64-bit fields must begin on 16-, 32-, and 64-bit boundaries, respec-
306  *    tively.  In this way, drivers can avoid unaligned accesses to radiotap
307  *    capture fields.  radiotap-compliant drivers must insert padding before a
308  *    capture field to ensure its natural alignment.  radiotap-compliant packet
309  *    dissectors, such as tcpdump(8), expect the padding.
310  */
311
312 /*
313  * Returns the amount required to align "offset" with "width"
314  */
315 #define ALIGN_OFFSET(offset, width) \
316     ( (((offset) + ((width) - 1)) & (~((width) - 1))) - offset )
317
318
319 void
320 capture_radiotap(const guchar *pd, int offset, int len, packet_counts *ld)
321 {
322     guint16 it_len;
323     guint32 present;
324     guint8 rflags;
325
326     if(!BYTES_ARE_IN_FRAME(offset, len, RADIOTAP_MIN_HEADER_LEN)) {
327         ld->other ++;
328         return;
329     }
330     it_len = pletohs(&pd[RADIOTAP_LENGTH_OFFSET]);
331     if(!BYTES_ARE_IN_FRAME(offset, len, it_len)) {
332         ld->other ++;
333         return;
334     }
335
336     if(it_len > len) {
337         /* Header length is bigger than total packet length */
338         ld->other ++;
339         return;
340     }
341
342     if(it_len < RADIOTAP_MIN_HEADER_LEN) {
343         /* Header length is shorter than fixed-length portion of header */
344         ld->other ++;
345         return;
346     }
347
348     present = pletohl(&pd[RADIOTAP_PRESENT_OFFSET]);
349     offset += RADIOTAP_MIN_HEADER_LEN;
350     it_len -= RADIOTAP_MIN_HEADER_LEN;
351
352     rflags = 0;
353
354     /*
355      * IEEE80211_RADIOTAP_TSFT is the lowest-order bit.
356      */
357     if (present & BIT(IEEE80211_RADIOTAP_TSFT)) {
358         if (it_len < 8) {
359             /* No room in header for this field. */
360             ld->other ++;
361             return;
362         }
363         /* That field is present, and it's 8 bits long. */
364         offset += 8;
365         it_len -= 8;
366     }
367
368     /*
369      * IEEE80211_RADIOTAP_FLAGS is the next bit.
370      */
371     if (present & BIT(IEEE80211_RADIOTAP_FLAGS)) {
372         if (it_len < 1) {
373             /* No room in header for this field. */
374             ld->other ++;
375             return;
376         }
377         /* That field is present; fetch it. */
378         if(!BYTES_ARE_IN_FRAME(offset, len, 1)) {
379             ld->other ++;
380             return;
381         }
382         rflags = pd[offset];
383     }
384
385     /* 802.11 header follows */
386     if (rflags & IEEE80211_RADIOTAP_F_DATAPAD)
387         capture_ieee80211_datapad(pd, offset + it_len, len, ld);
388     else
389         capture_ieee80211(pd, offset + it_len, len, ld);
390 }
391
392 void
393 proto_register_radiotap(void)
394 {
395   static const value_string phy_type[] = {
396     { 0, "Unknown" },
397     { IEEE80211_CHAN_A,         "802.11a" },
398     { IEEE80211_CHAN_A | IEEE80211_CHAN_HT20,           "802.11a (ht20)" },
399     { IEEE80211_CHAN_A | IEEE80211_CHAN_HT40U,          "802.11a (ht40+)" },
400     { IEEE80211_CHAN_A | IEEE80211_CHAN_HT40D,          "802.11a (ht40-)" },
401     { IEEE80211_CHAN_B,         "802.11b" },
402     { IEEE80211_CHAN_PUREG,     "802.11g (pure-g)" },
403     { IEEE80211_CHAN_G,         "802.11g" },
404     { IEEE80211_CHAN_G | IEEE80211_CHAN_HT20,           "802.11g (ht20)" },
405     { IEEE80211_CHAN_G | IEEE80211_CHAN_HT40U,          "802.11g (ht40+)" },
406     { IEEE80211_CHAN_G | IEEE80211_CHAN_HT40D,          "802.11g (ht40-)" },
407     { IEEE80211_CHAN_T,         "802.11a (turbo)" },
408     { IEEE80211_CHAN_108PUREG,  "802.11g (pure-g, turbo)" },
409     { IEEE80211_CHAN_108G,      "802.11g (turbo)" },
410     { IEEE80211_CHAN_FHSS,      "FHSS" },
411     { 0, NULL },
412   };
413
414   static const true_false_string preamble_type = {
415       "Short",
416       "Long",
417   };
418
419   static hf_register_info hf[] = {
420     { &hf_radiotap_version,
421       { "Header revision", "radiotap.version",
422         FT_UINT8, BASE_DEC, NULL, 0x0,
423         "Version of radiotap header format", HFILL } },
424     { &hf_radiotap_pad,
425       { "Header pad", "radiotap.pad",
426         FT_UINT8, BASE_DEC, NULL, 0x0,
427         "Padding", HFILL } },
428     { &hf_radiotap_length,
429        { "Header length", "radiotap.length",
430          FT_UINT16, BASE_DEC, NULL, 0x0,
431          "Length of header including version, pad, length and data fields", HFILL } },
432     { &hf_radiotap_present,
433        { "Present flags", "radiotap.present",
434          FT_UINT32, BASE_HEX, NULL, 0x0, "Bitmask indicating which fields are present", HFILL } },
435
436 #define RADIOTAP_MASK_TSFT                  0x00000001
437 #define RADIOTAP_MASK_FLAGS                 0x00000002
438 #define RADIOTAP_MASK_RATE                  0x00000004
439 #define RADIOTAP_MASK_CHANNEL               0x00000008
440 #define RADIOTAP_MASK_FHSS                  0x00000010
441 #define RADIOTAP_MASK_DBM_ANTSIGNAL         0x00000020
442 #define RADIOTAP_MASK_DBM_ANTNOISE          0x00000040
443 #define RADIOTAP_MASK_LOCK_QUALITY          0x00000080
444 #define RADIOTAP_MASK_TX_ATTENUATION        0x00000100
445 #define RADIOTAP_MASK_DB_TX_ATTENUATION     0x00000200
446 #define RADIOTAP_MASK_DBM_TX_ATTENUATION    0x00000400
447 #define RADIOTAP_MASK_ANTENNA               0x00000800
448 #define RADIOTAP_MASK_DB_ANTSIGNAL          0x00001000
449 #define RADIOTAP_MASK_DB_ANTNOISE           0x00002000
450 #define RADIOTAP_MASK_RX_FLAGS              0x00004000
451 #define RADIOTAP_MASK_XCHANNEL              0x00040000
452 #define RADIOTAP_MASK_EXT                   0x80000000
453
454     /* Boolean 'present' flags */
455     { &hf_radiotap_present_tsft,
456       { "TSFT", "radiotap.present.tsft",
457         FT_BOOLEAN, 32, NULL, RADIOTAP_MASK_TSFT,
458         "Specifies if the Time Synchronization Function Timer field is present", HFILL } },
459
460     { &hf_radiotap_present_flags,
461       { "Flags", "radiotap.present.flags",
462         FT_BOOLEAN, 32, NULL, RADIOTAP_MASK_FLAGS,
463         "Specifies if the channel flags field is present", HFILL } },
464
465     { &hf_radiotap_present_rate,
466       { "Rate", "radiotap.present.rate",
467         FT_BOOLEAN, 32, NULL, RADIOTAP_MASK_RATE,
468         "Specifies if the transmit/receive rate field is present", HFILL } },
469
470     { &hf_radiotap_present_channel,
471       { "Channel", "radiotap.present.channel",
472         FT_BOOLEAN, 32, NULL, RADIOTAP_MASK_CHANNEL,
473         "Specifies if the transmit/receive frequency field is present", HFILL } },
474
475     { &hf_radiotap_present_fhss,
476       { "FHSS", "radiotap.present.fhss",
477         FT_BOOLEAN, 32, NULL, RADIOTAP_MASK_FHSS,
478         "Specifies if the hop set and pattern is present for frequency hopping radios", HFILL } },
479
480     { &hf_radiotap_present_dbm_antsignal,
481       { "DBM Antenna Signal", "radiotap.present.dbm_antsignal",
482         FT_BOOLEAN, 32, NULL, RADIOTAP_MASK_DBM_ANTSIGNAL,
483         "Specifies if the antenna signal strength in dBm is present", HFILL } },
484
485     { &hf_radiotap_present_dbm_antnoise,
486       { "DBM Antenna Noise", "radiotap.present.dbm_antnoise",
487         FT_BOOLEAN, 32, NULL, RADIOTAP_MASK_DBM_ANTNOISE,
488         "Specifies if the RF noise power at antenna field is present", HFILL } },
489
490     { &hf_radiotap_present_lock_quality,
491       { "Lock Quality", "radiotap.present.lock_quality",
492         FT_BOOLEAN, 32, NULL, RADIOTAP_MASK_LOCK_QUALITY,
493         "Specifies if the signal quality field is present", HFILL } },
494
495     { &hf_radiotap_present_tx_attenuation,
496       { "TX Attenuation", "radiotap.present.tx_attenuation",
497         FT_BOOLEAN, 32, NULL, RADIOTAP_MASK_TX_ATTENUATION,
498         "Specifies if the transmit power from max power field is present", HFILL } },
499
500     { &hf_radiotap_present_db_tx_attenuation,
501       { "DB TX Attenuation", "radiotap.present.db_tx_attenuation",
502         FT_BOOLEAN, 32, NULL, RADIOTAP_MASK_DB_TX_ATTENUATION,
503         "Specifies if the transmit power from max power (in dB) field is present", HFILL } },
504
505     { &hf_radiotap_present_dbm_tx_attenuation,
506       { "DBM TX Attenuation", "radiotap.present.dbm_tx_attenuation",
507         FT_BOOLEAN, 32, NULL, RADIOTAP_MASK_DBM_TX_ATTENUATION,
508         "Specifies if the transmit power from max power (in dBm) field is present", HFILL } },
509
510     { &hf_radiotap_present_antenna,
511       { "Antenna", "radiotap.present.antenna",
512         FT_BOOLEAN, 32, NULL, RADIOTAP_MASK_ANTENNA,
513         "Specifies if the antenna number field is present", HFILL } },
514
515     { &hf_radiotap_present_db_antsignal,
516       { "DB Antenna Signal", "radiotap.present.db_antsignal",
517         FT_BOOLEAN, 32, NULL, RADIOTAP_MASK_DB_ANTSIGNAL,
518         "Specifies if the RF signal power at antenna in dB field is present", HFILL } },
519
520     { &hf_radiotap_present_db_antnoise,
521       { "DB Antenna Noise", "radiotap.present.db_antnoise",
522         FT_BOOLEAN, 32, NULL, RADIOTAP_MASK_DB_ANTNOISE,
523         "Specifies if the RF signal power at antenna in dBm field is present", HFILL } },
524
525     { &hf_radiotap_present_rxflags,
526       { "RX flags", "radiotap.present.rxflags",
527         FT_BOOLEAN, 32, NULL, RADIOTAP_MASK_RX_FLAGS,
528         "Specifies if the RX flags field is present", HFILL } },
529
530     { &hf_radiotap_present_hdrfcs,
531       { "FCS in header", "radiotap.present.fcs",
532         FT_BOOLEAN, 32, NULL, RADIOTAP_MASK_RX_FLAGS,
533         "Specifies if the FCS field is present", HFILL } },
534
535     { &hf_radiotap_present_xchannel,
536       { "Channel+", "radiotap.present.xchannel",
537         FT_BOOLEAN, 32, NULL, RADIOTAP_MASK_XCHANNEL,
538         "Specifies if the extended channel info field is present", HFILL } },
539
540     { &hf_radiotap_present_ext,
541       { "Ext", "radiotap.present.ext",
542         FT_BOOLEAN, 32, NULL, RADIOTAP_MASK_EXT,
543         "Specifies if there are any extensions to the header present", HFILL } },
544
545     /* Boolean 'present.flags' flags */
546     { &hf_radiotap_flags,
547       { "Flags", "radiotap.flags",
548         FT_UINT8, BASE_HEX, NULL,  0x0, NULL, HFILL } },
549
550     { &hf_radiotap_flags_cfp,
551       { "CFP", "radiotap.flags.cfp",
552         FT_BOOLEAN, 8, NULL,  IEEE80211_RADIOTAP_F_CFP,
553         "Sent/Received during CFP", HFILL } },
554
555     { &hf_radiotap_flags_preamble,
556       { "Preamble", "radiotap.flags.preamble",
557         FT_BOOLEAN, 8, TFS(&preamble_type),  IEEE80211_RADIOTAP_F_SHORTPRE,
558         "Sent/Received with short preamble", HFILL } },
559
560     { &hf_radiotap_flags_wep,
561       { "WEP", "radiotap.flags.wep",
562         FT_BOOLEAN, 8, NULL, IEEE80211_RADIOTAP_F_WEP,
563         "Sent/Received with WEP encryption", HFILL } },
564
565     { &hf_radiotap_flags_frag,
566       { "Fragmentation", "radiotap.flags.frag",
567         FT_BOOLEAN, 8, NULL, IEEE80211_RADIOTAP_F_FRAG,
568         "Sent/Received with fragmentation", HFILL } },
569
570     { &hf_radiotap_flags_fcs,
571       { "FCS at end", "radiotap.flags.fcs",
572         FT_BOOLEAN, 8, NULL, IEEE80211_RADIOTAP_F_FCS,
573     "Frame includes FCS at end", HFILL } },
574
575     { &hf_radiotap_flags_datapad,
576       { "Data Pad", "radiotap.flags.datapad",
577         FT_BOOLEAN, 8, NULL, IEEE80211_RADIOTAP_F_DATAPAD,
578     "Frame has padding between 802.11 header and payload", HFILL } },
579
580     { &hf_radiotap_flags_badfcs,
581       { "Bad FCS", "radiotap.flags.badfcs",
582         FT_BOOLEAN, 8, NULL, IEEE80211_RADIOTAP_F_BADFCS,
583         "Frame received with bad FCS", HFILL } },
584
585     { &hf_radiotap_flags_shortgi,
586       { "Short GI", "radiotap.flags.shortgi",
587         FT_BOOLEAN, 8, NULL, IEEE80211_RADIOTAP_F_SHORTGI,
588     "Frame Sent/Received with HT short Guard Interval", HFILL } },
589
590
591     { &hf_radiotap_mactime,
592        { "MAC timestamp", "radiotap.mactime",
593          FT_UINT64, BASE_DEC, NULL, 0x0,
594          "Value in microseconds of the MAC's Time Synchronization Function timer when the first bit of the MPDU arrived at the MAC.", HFILL } },
595
596     { &hf_radiotap_quality,
597        { "Signal Quality", "radiotap.quality",
598          FT_UINT16, BASE_DEC, NULL, 0x0,
599          "Signal quality (unitless measure)", HFILL } },
600
601     { &hf_radiotap_fcs,
602        { "802.11 FCS", "radiotap.fcs",
603          FT_UINT32, BASE_HEX, NULL, 0x0,
604          "Frame check sequence of this frame", HFILL } },
605
606     { &hf_radiotap_channel,
607       { "Channel", "radiotap.channel",
608         FT_UINT32, BASE_DEC, NULL, 0x0,
609         "802.11 channel number that this frame was sent/received on", HFILL } },
610
611     { &hf_radiotap_channel_frequency,
612       { "Channel frequency", "radiotap.channel.freq",
613         FT_UINT32, BASE_DEC, NULL, 0x0,
614         "Channel frequency in megahertz that this frame was sent/received on", HFILL } },
615
616     { &hf_radiotap_channel_flags,
617       { "Channel type", "radiotap.channel.type",
618         FT_UINT16, BASE_HEX, VALS(phy_type), 0x0,
619         NULL, HFILL } },
620
621     { &hf_radiotap_channel_flags_turbo,
622        { "Turbo", "radiotap.channel.type.turbo",
623          FT_BOOLEAN, 16, NULL, 0x0010, "Channel Type Turbo", HFILL } },
624     { &hf_radiotap_channel_flags_cck,
625        { "Complementary Code Keying (CCK)", "radiotap.channel.type.cck",
626          FT_BOOLEAN, 16, NULL, 0x0020, "Channel Type Complementary Code Keying (CCK) Modulation", HFILL } },
627     { &hf_radiotap_channel_flags_ofdm,
628        { "Orthogonal Frequency-Division Multiplexing (OFDM)", "radiotap.channel.type.ofdm",
629          FT_BOOLEAN, 16, NULL, 0x0040, "Channel Type Orthogonal Frequency-Division Multiplexing (OFDM)", HFILL } },
630     { &hf_radiotap_channel_flags_2ghz,
631        { "2 GHz spectrum", "radiotap.channel.type.2ghz",
632          FT_BOOLEAN, 16, NULL, 0x0080, "Channel Type 2 GHz spectrum", HFILL } },
633     { &hf_radiotap_channel_flags_5ghz,
634        { "5 GHz spectrum", "radiotap.channel.type.5ghz",
635          FT_BOOLEAN, 16, NULL, 0x0100, "Channel Type 5 GHz spectrum", HFILL } },
636     { &hf_radiotap_channel_flags_passive,
637        { "Passive", "radiotap.channel.type.passive",
638          FT_BOOLEAN, 16, NULL, 0x0200, "Channel Type Passive", HFILL } },
639     { &hf_radiotap_channel_flags_dynamic,
640        { "Dynamic CCK-OFDM", "radiotap.channel.type.dynamic",
641          FT_BOOLEAN, 16, NULL, 0x0400, "Channel Type Dynamic CCK-OFDM Channel", HFILL } },
642     { &hf_radiotap_channel_flags_gfsk,
643        { "Gaussian Frequency Shift Keying (GFSK)", "radiotap.channel.type.gfsk",
644          FT_BOOLEAN, 16, NULL, 0x0800, "Channel Type Gaussian Frequency Shift Keying (GFSK) Modulation", HFILL } },
645     { &hf_radiotap_channel_flags_gsm,
646        { "GSM (900MHz)", "radiotap.channel.type.gsm",
647          FT_BOOLEAN, 16, NULL, 0x1000, "Channel Type GSM", HFILL } },
648     { &hf_radiotap_channel_flags_sturbo,
649        { "Static Turbo", "radiotap.channel.type.sturbo",
650          FT_BOOLEAN, 16, NULL, 0x2000, "Channel Type Status Turbo", HFILL } },
651     { &hf_radiotap_channel_flags_half,
652        { "Half Rate Channel (10MHz Channel Width)", "radiotap.channel.type.half",
653          FT_BOOLEAN, 16, NULL, 0x4000, "Channel Type Half Rate", HFILL } },
654     { &hf_radiotap_channel_flags_quarter,
655        { "Quarter Rate Channel (5MHz Channel Width)", "radiotap.channel.type.quarter",
656          FT_BOOLEAN, 16, NULL, 0x8000, "Channel Type Quarter Rate", HFILL } },
657
658     { &hf_radiotap_rxflags,
659       { "RX flags", "radiotap.rxflags",
660         FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL } },
661
662     { &hf_radiotap_rxflags_badplcp,
663        { "Bad PLCP", "radiotap.rxflags.badplcp",
664          FT_BOOLEAN, 24, NULL, IEEE80211_RADIOTAP_F_RX_BADPLCP,
665          "Frame with bad PLCP", HFILL } },
666
667     { &hf_radiotap_xchannel,
668       { "Channel number", "radiotap.xchannel",
669         FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } },
670     { &hf_radiotap_xchannel_frequency,
671       { "Channel frequency", "radiotap.xchannel.freq",
672         FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } },
673     { &hf_radiotap_xchannel_flags,
674       { "Channel type", "radiotap.xchannel.flags",
675         FT_UINT32, BASE_HEX, VALS(phy_type), 0x0, NULL, HFILL } },
676
677     { &hf_radiotap_xchannel_flags_turbo,
678        { "Turbo", "radiotap.xchannel.type.turbo",
679          FT_BOOLEAN, 24, NULL, 0x0010, "Channel Type Turbo", HFILL } },
680     { &hf_radiotap_xchannel_flags_cck,
681        { "Complementary Code Keying (CCK)", "radiotap.xchannel.type.cck",
682          FT_BOOLEAN, 24, NULL, 0x0020, "Channel Type Complementary Code Keying (CCK) Modulation", HFILL } },
683     { &hf_radiotap_xchannel_flags_ofdm,
684        { "Orthogonal Frequency-Division Multiplexing (OFDM)", "radiotap.xchannel.type.ofdm",
685          FT_BOOLEAN, 24, NULL, 0x0040, "Channel Type Orthogonal Frequency-Division Multiplexing (OFDM)", HFILL } },
686     { &hf_radiotap_xchannel_flags_2ghz,
687        { "2 GHz spectrum", "radiotap.xchannel.type.2ghz",
688          FT_BOOLEAN, 24, NULL, 0x0080, "Channel Type 2 GHz spectrum", HFILL } },
689     { &hf_radiotap_xchannel_flags_5ghz,
690        { "5 GHz spectrum", "radiotap.xchannel.type.5ghz",
691          FT_BOOLEAN, 24, NULL, 0x0100, "Channel Type 5 GHz spectrum", HFILL } },
692     { &hf_radiotap_xchannel_flags_passive,
693        { "Passive", "radiotap.channel.xtype.passive",
694          FT_BOOLEAN, 24, NULL, 0x0200, "Channel Type Passive", HFILL } },
695     { &hf_radiotap_xchannel_flags_dynamic,
696        { "Dynamic CCK-OFDM", "radiotap.xchannel.type.dynamic",
697          FT_BOOLEAN, 24, NULL, 0x0400, "Channel Type Dynamic CCK-OFDM Channel", HFILL } },
698     { &hf_radiotap_xchannel_flags_gfsk,
699        { "Gaussian Frequency Shift Keying (GFSK)", "radiotap.xchannel.type.gfsk",
700          FT_BOOLEAN, 24, NULL, 0x0800, "Channel Type Gaussian Frequency Shift Keying (GFSK) Modulation", HFILL } },
701     { &hf_radiotap_xchannel_flags_gsm,
702        { "GSM (900MHz)", "radiotap.xchannel.type.gsm",
703          FT_BOOLEAN, 24, NULL, 0x1000, "Channel Type GSM", HFILL } },
704     { &hf_radiotap_xchannel_flags_sturbo,
705        { "Static Turbo", "radiotap.xchannel.type.sturbo",
706          FT_BOOLEAN, 24, NULL, 0x2000, "Channel Type Status Turbo", HFILL } },
707     { &hf_radiotap_xchannel_flags_half,
708        { "Half Rate Channel (10MHz Channel Width)", "radiotap.xchannel.type.half",
709          FT_BOOLEAN, 24, NULL, 0x4000, "Channel Type Half Rate", HFILL } },
710     { &hf_radiotap_xchannel_flags_quarter,
711        { "Quarter Rate Channel (5MHz Channel Width)", "radiotap.xchannel.type.quarter",
712          FT_BOOLEAN, 24, NULL, 0x8000, "Channel Type Quarter Rate", HFILL } },
713     { &hf_radiotap_xchannel_flags_ht20,
714        { "HT Channel (20MHz Channel Width)", "radiotap.xchannel.type.ht20",
715          FT_BOOLEAN, 24, NULL, 0x10000, "Channel Type HT/20", HFILL } },
716     { &hf_radiotap_xchannel_flags_ht40u,
717        { "HT Channel (40MHz Channel Width with Extension channel above)", "radiotap.xchannel.type.ht40u",
718          FT_BOOLEAN, 24, NULL, 0x20000, "Channel Type HT/40+", HFILL } },
719     { &hf_radiotap_xchannel_flags_ht40d,
720        { "HT Channel (40MHz Channel Width with Extension channel below)", "radiotap.xchannel.type.ht40d",
721          FT_BOOLEAN, 24, NULL, 0x40000, "Channel Type HT/40-", HFILL } },
722 #if 0
723     { &hf_radiotap_xchannel_maxpower,
724       { "Max transmit power", "radiotap.xchannel.maxpower",
725         FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL } },
726 #endif
727     { &hf_radiotap_fhss_hopset,
728       { "FHSS Hop Set", "radiotap.fhss.hopset",
729         FT_UINT8, BASE_DEC, NULL,  0x0,
730         "Frequency Hopping Spread Spectrum hopset", HFILL } },
731
732     { &hf_radiotap_fhss_pattern,
733       { "FHSS Pattern", "radiotap.fhss.pattern",
734         FT_UINT8, BASE_DEC, NULL,  0x0,
735         "Frequency Hopping Spread Spectrum hop pattern", HFILL } },
736
737     { &hf_radiotap_datarate,
738       { "Data rate", "radiotap.datarate",
739         FT_UINT32, BASE_DEC, NULL, 0x0,
740         "Speed this frame was sent/received at", HFILL } },
741
742     { &hf_radiotap_antenna,
743       { "Antenna", "radiotap.antenna",
744         FT_UINT32, BASE_DEC, NULL, 0x0,
745         "Antenna number this frame was sent/received over (starting at 0)", HFILL } },
746
747     { &hf_radiotap_dbm_antsignal,
748       { "SSI Signal (dBm)", "radiotap.dbm_antsignal",
749         FT_INT32, BASE_DEC, NULL, 0x0,
750         "RF signal power at the antenna from a fixed, arbitrary value in decibels from one milliwatt", HFILL } },
751
752     { &hf_radiotap_db_antsignal,
753       { "SSI Signal (dB)", "radiotap.db_antsignal",
754         FT_UINT32, BASE_DEC, NULL, 0x0,
755         "RF signal power at the antenna from a fixed, arbitrary value in decibels", HFILL } },
756
757     { &hf_radiotap_dbm_antnoise,
758       { "SSI Noise (dBm)", "radiotap.dbm_antnoise",
759         FT_INT32, BASE_DEC, NULL, 0x0,
760         "RF noise power at the antenna from a fixed, arbitrary value in decibels per one milliwatt", HFILL } },
761
762     { &hf_radiotap_db_antnoise,
763       { "SSI Noise (dB)", "radiotap.db_antnoise",
764         FT_UINT32, BASE_DEC, NULL, 0x0,
765         "RF noise power at the antenna from a fixed, arbitrary value in decibels", HFILL } },
766
767     { &hf_radiotap_tx_attenuation,
768       { "Transmit attenuation", "radiotap.txattenuation",
769         FT_UINT16, BASE_DEC, NULL, 0x0,
770         "Transmit power expressed as unitless distance from max power set at factory (0 is max power)", HFILL } },
771
772     { &hf_radiotap_db_tx_attenuation,
773       { "Transmit attenuation (dB)", "radiotap.db_txattenuation",
774         FT_UINT16, BASE_DEC, NULL, 0x0,
775         "Transmit power expressed as decibels from max power set at factory (0 is max power)", HFILL } },
776
777     { &hf_radiotap_txpower,
778       { "Transmit power", "radiotap.txpower",
779         FT_INT32, BASE_DEC, NULL, 0x0,
780         "Transmit power in decibels per one milliwatt (dBm)", HFILL } },
781
782     /* Special variables */
783     { &hf_radiotap_fcs_bad,
784       { "Bad FCS", "radiotap.fcs_bad",
785         FT_BOOLEAN, BASE_NONE, NULL, 0x0,
786         "Specifies if this frame has a bad frame check sequence", HFILL } },
787
788   };
789   static gint *ett[] = {
790     &ett_radiotap,
791     &ett_radiotap_present,
792     &ett_radiotap_flags,
793     &ett_radiotap_rxflags,
794     &ett_radiotap_channel_flags,
795     &ett_radiotap_xchannel_flags
796   };
797   module_t *radiotap_module;
798
799   proto_radiotap = proto_register_protocol("IEEE 802.11 Radiotap Capture header", "802.11 Radiotap", "radiotap");
800   proto_register_field_array(proto_radiotap, hf, array_length(hf));
801   proto_register_subtree_array(ett, array_length(ett));
802   register_dissector("radiotap", dissect_radiotap, proto_radiotap);
803
804   radiotap_tap = register_tap("radiotap");
805
806   radiotap_module = prefs_register_protocol(proto_radiotap, NULL);
807   prefs_register_bool_preference(radiotap_module, "bit14_fcs_in_header",
808       "Assume bit 14 means FCS in header",
809       "Radiotap has a bit to indicate whether the FCS is still on the frame or not. "
810       "Some generators (e.g. AirPcap) use a non-standard radiotap flag 14 to put "
811       "the FCS into the header.",
812       &radiotap_bit14_fcs);
813 }
814
815 static void
816 dissect_radiotap(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
817 {
818     proto_tree *radiotap_tree = NULL;
819     proto_tree *pt, *present_tree = NULL;
820     proto_tree *ft, *flags_tree = NULL;
821     proto_item *ti = NULL, *hidden_item;
822     int align_offset, offset;
823     tvbuff_t *next_tvb;
824     guint32 version;
825     guint length, length_remaining;
826     guint32 rate, freq, flags;
827     gint8 dbm;
828     guint8 db, rflags;
829     guint32 present, next_present;
830     int bit;
831     /* backward compat with bit 14 == fcs in header */
832     proto_item *hdr_fcs_ti = NULL;
833     int hdr_fcs_offset = 0;
834     guint32 sent_fcs = 0;
835     guint32 calc_fcs;
836
837     struct _radiotap_info *radiotap_info;
838     static struct _radiotap_info rtp_info_arr[1];
839     
840     radiotap_info = &rtp_info_arr[0];
841
842     col_set_str(pinfo->cinfo, COL_PROTOCOL, "WLAN");
843     col_clear(pinfo->cinfo, COL_INFO);
844     offset = 0;
845
846     version = tvb_get_guint8(tvb, offset);
847     length = tvb_get_letohs(tvb, offset+2);
848     present = tvb_get_letohl(tvb, offset+4);
849     
850     radiotap_info->radiotap_length = length;
851
852     col_add_fstr(pinfo->cinfo, COL_INFO, "Radiotap Capture v%u, Length %u",
853                 version, length);
854
855     /* Dissect the packet */
856     if (tree) {
857         ti = proto_tree_add_protocol_format(tree, proto_radiotap,
858                 tvb, 0, length, "Radiotap Header v%u, Length %u", version, length);
859         radiotap_tree = proto_item_add_subtree(ti, ett_radiotap);
860         proto_tree_add_uint(radiotap_tree, hf_radiotap_version,
861                 tvb, offset, 1, version);
862         proto_tree_add_item(radiotap_tree, hf_radiotap_pad,
863                 tvb, offset + 1, 1, FALSE);
864         ti = proto_tree_add_uint(radiotap_tree, hf_radiotap_length,
865                 tvb, offset + 2, 2, length);
866     }
867     length_remaining = length;
868
869     /*
870      * FIXME: This only works if there is exactly 1 it_present
871      *        field in the header
872      */
873     if (length_remaining < RADIOTAP_MIN_HEADER_LEN) {
874         /*
875          * Radiotap header is shorter than the fixed-length portion
876          * plus one "present" bitset.
877          */
878         if (tree)
879             proto_item_append_text(ti, " (bogus - minimum length is 8)");
880         return;
881     }
882     /* Subtree for the "present flags" bitfield. */
883     if (tree) {
884         pt = proto_tree_add_uint(radiotap_tree, hf_radiotap_present,
885             tvb, offset + 4, 4, present);
886         present_tree = proto_item_add_subtree(pt, ett_radiotap_present);
887
888         proto_tree_add_item(present_tree, hf_radiotap_present_tsft,
889             tvb, 4, 4, TRUE);
890         proto_tree_add_item(present_tree, hf_radiotap_present_flags,
891             tvb, 4, 4, TRUE);
892         proto_tree_add_item(present_tree, hf_radiotap_present_rate,
893             tvb, 4, 4, TRUE);
894         proto_tree_add_item(present_tree, hf_radiotap_present_channel,
895             tvb, 4, 4, TRUE);
896         proto_tree_add_item(present_tree, hf_radiotap_present_fhss,
897             tvb, 4, 4, TRUE);
898         proto_tree_add_item(present_tree, hf_radiotap_present_dbm_antsignal,
899             tvb, 4, 4, TRUE);
900         proto_tree_add_item(present_tree, hf_radiotap_present_dbm_antnoise,
901             tvb, 4, 4, TRUE);
902         proto_tree_add_item(present_tree, hf_radiotap_present_lock_quality,
903             tvb, 4, 4, TRUE);
904         proto_tree_add_item(present_tree, hf_radiotap_present_tx_attenuation,
905             tvb, 4, 4, TRUE);
906         proto_tree_add_item(present_tree, hf_radiotap_present_db_tx_attenuation,
907             tvb, 4, 4, TRUE);
908         proto_tree_add_item(present_tree, hf_radiotap_present_dbm_tx_attenuation,
909             tvb, 4, 4, TRUE);
910         proto_tree_add_item(present_tree, hf_radiotap_present_antenna,
911             tvb, 4, 4, TRUE);
912         proto_tree_add_item(present_tree, hf_radiotap_present_db_antsignal,
913             tvb, 4, 4, TRUE);
914         proto_tree_add_item(present_tree, hf_radiotap_present_db_antnoise,
915             tvb, 4, 4, TRUE);
916         if (radiotap_bit14_fcs) {
917                 proto_tree_add_item(present_tree, hf_radiotap_present_hdrfcs,
918                         tvb, 4, 4, TRUE);
919         } else {
920                 proto_tree_add_item(present_tree, hf_radiotap_present_rxflags,
921                         tvb, 4, 4, TRUE);
922         }
923         proto_tree_add_item(present_tree, hf_radiotap_present_xchannel,
924             tvb, 4, 4, TRUE);
925         proto_tree_add_item(present_tree, hf_radiotap_present_ext,
926             tvb, 4, 4, TRUE);
927     }
928     offset += RADIOTAP_MIN_HEADER_LEN;
929     length_remaining -= RADIOTAP_MIN_HEADER_LEN;
930
931     rflags = 0;
932     for (; present; present = next_present) {
933         /* clear the least significant bit that is set */
934         next_present = present & (present - 1);
935
936         /* extract the least significant bit that is set */
937         bit = BITNO_32(present ^ next_present);
938
939         switch (bit) {
940         case IEEE80211_RADIOTAP_FLAGS:
941             if (length_remaining < 1)
942                 break;
943             rflags = tvb_get_guint8(tvb, offset);
944             if (tree) {
945         ft = proto_tree_add_item(radiotap_tree, hf_radiotap_flags,
946             tvb, offset, 1, FALSE);
947         flags_tree = proto_item_add_subtree(ft, ett_radiotap_flags);
948
949                 proto_tree_add_item(flags_tree, hf_radiotap_flags_cfp,
950                         tvb, offset, 1, FALSE);
951                 proto_tree_add_item(flags_tree, hf_radiotap_flags_preamble,
952                         tvb, offset, 1, FALSE);
953                 proto_tree_add_item(flags_tree, hf_radiotap_flags_wep,
954                         tvb, offset, 1, FALSE);
955                 proto_tree_add_item(flags_tree, hf_radiotap_flags_frag,
956                         tvb, offset, 1, FALSE);
957                 proto_tree_add_item(flags_tree, hf_radiotap_flags_fcs,
958                         tvb, offset, 1, FALSE);
959                 proto_tree_add_item(flags_tree, hf_radiotap_flags_datapad,
960                         tvb, offset, 1, FALSE);
961                 proto_tree_add_item(flags_tree, hf_radiotap_flags_badfcs,
962                         tvb, offset, 1, FALSE);
963                 proto_tree_add_item(flags_tree, hf_radiotap_flags_shortgi,
964                         tvb, offset, 1, FALSE);
965             }
966             offset++;
967             length_remaining--;
968             break;
969
970         case IEEE80211_RADIOTAP_RATE:
971             if (length_remaining < 1)
972                 break;
973             rate = tvb_get_guint8(tvb, offset);
974             if (rate & 0x80) {
975                 /* XXX adjust by CW and short GI like other sniffers? */
976                 rate = ieee80211_htrates[rate & 0xf];
977             }
978             col_add_fstr(pinfo->cinfo, COL_TX_RATE, "%d.%d",
979                 rate / 2, rate & 1 ? 5 : 0);
980             if (tree) {
981                 proto_tree_add_uint_format(radiotap_tree, hf_radiotap_datarate,
982                         tvb, offset, 1, rate,
983                         "Data Rate: %d.%d Mb/s", rate / 2, rate & 1 ? 5 : 0);
984             }
985             offset++;
986             length_remaining--;
987             radiotap_info->rate = rate;
988             break;
989         case IEEE80211_RADIOTAP_DBM_ANTSIGNAL:
990             if (length_remaining < 1)
991                 break;
992             dbm = (gint8) tvb_get_guint8(tvb, offset);
993             col_add_fstr(pinfo->cinfo, COL_RSSI, "%d dBm", dbm);
994             if (tree) {
995                 proto_tree_add_int_format(radiotap_tree,
996                                           hf_radiotap_dbm_antsignal,
997                                           tvb, offset, 1, dbm,
998                                           "SSI Signal: %d dBm", dbm);
999             }
1000             offset++;
1001             length_remaining--;
1002             radiotap_info->dbm_antsignal=dbm;
1003             break;
1004         case IEEE80211_RADIOTAP_DB_ANTSIGNAL:
1005             if (length_remaining < 1)
1006                 break;
1007             db = tvb_get_guint8(tvb, offset);
1008             col_add_fstr(pinfo->cinfo, COL_RSSI, "%u dB", db);
1009             if (tree) {
1010                 proto_tree_add_uint_format(radiotap_tree,
1011                                            hf_radiotap_db_antsignal,
1012                                            tvb, offset, 1, db,
1013                                            "SSI Signal: %u dB", db);
1014             }
1015             offset++;
1016             length_remaining--;
1017             break;
1018         case IEEE80211_RADIOTAP_DBM_ANTNOISE:
1019             if (length_remaining < 1)
1020                 break;
1021             dbm = (gint8) tvb_get_guint8(tvb, offset);
1022             if (tree) {
1023                 proto_tree_add_int_format(radiotap_tree,
1024                                           hf_radiotap_dbm_antnoise,
1025                                           tvb, offset, 1, dbm,
1026                                           "SSI Noise: %d dBm", dbm);
1027             }
1028             offset++;
1029             length_remaining--;
1030             radiotap_info->dbm_antnoise=dbm;
1031             break;
1032         case IEEE80211_RADIOTAP_DB_ANTNOISE:
1033             if (length_remaining < 1)
1034                 break;
1035             db = tvb_get_guint8(tvb, offset);
1036             if (tree) {
1037                 proto_tree_add_uint_format(radiotap_tree,
1038                                            hf_radiotap_db_antnoise,
1039                                            tvb, offset, 1, db,
1040                                            "SSI Noise: %u dB", db);
1041             }
1042             offset++;
1043             length_remaining--;
1044             break;
1045         case IEEE80211_RADIOTAP_ANTENNA:
1046             if (length_remaining < 1)
1047                 break;
1048             if (tree) {
1049                 proto_tree_add_uint(radiotap_tree, hf_radiotap_antenna,
1050                                    tvb, offset, 1, tvb_get_guint8(tvb, offset));
1051             }
1052             offset++;
1053             length_remaining--;
1054             break;
1055         case IEEE80211_RADIOTAP_DBM_TX_POWER:
1056             if (length_remaining < 1)
1057                 break;
1058             if (tree) {
1059                 proto_tree_add_int(radiotap_tree, hf_radiotap_txpower,
1060                                    tvb, offset, 1, tvb_get_guint8(tvb, offset));
1061             }
1062             offset++;
1063             length_remaining--;
1064             break;
1065         case IEEE80211_RADIOTAP_CHANNEL:
1066         {
1067             proto_item *it;
1068             proto_tree *flags_tree;
1069             gchar *chan_str;
1070
1071             align_offset = ALIGN_OFFSET(offset, 2);
1072             offset += align_offset;
1073             length_remaining -= align_offset;
1074             if (length_remaining < 2)
1075                 break;
1076             if (tree) {
1077                 freq = tvb_get_letohs(tvb, offset);
1078                 flags = tvb_get_letohs(tvb, offset+2);
1079                 chan_str = ieee80211_mhz_to_str(freq);
1080                 col_add_fstr(pinfo->cinfo, COL_FREQ_CHAN, "%s", chan_str);
1081                 proto_tree_add_uint_format(radiotap_tree, hf_radiotap_channel_frequency,
1082                                 tvb, offset, 2, freq,
1083                                 "Channel frequency: %s", chan_str);
1084                 g_free(chan_str);
1085                 /* We're already 2-byte aligned. */
1086                 it = proto_tree_add_uint(radiotap_tree, hf_radiotap_channel_flags,
1087                         tvb, offset+2, 2, flags);
1088                 flags_tree = proto_item_add_subtree(it, ett_radiotap_channel_flags);
1089                 proto_tree_add_boolean(flags_tree, hf_radiotap_channel_flags_turbo,
1090                         tvb, offset+2, 1, flags);
1091                 proto_tree_add_boolean(flags_tree, hf_radiotap_channel_flags_cck,
1092                         tvb, offset+2, 1, flags);
1093                 proto_tree_add_boolean(flags_tree, hf_radiotap_channel_flags_ofdm,
1094                         tvb, offset+2, 1, flags);
1095                 proto_tree_add_boolean(flags_tree, hf_radiotap_channel_flags_2ghz,
1096                         tvb, offset+2, 1, flags);
1097                 proto_tree_add_boolean(flags_tree, hf_radiotap_channel_flags_5ghz,
1098                         tvb, offset+3, 1, flags);
1099                 proto_tree_add_boolean(flags_tree, hf_radiotap_channel_flags_passive,
1100                         tvb, offset+3, 1, flags);
1101                 proto_tree_add_boolean(flags_tree, hf_radiotap_channel_flags_dynamic,
1102                         tvb, offset+3, 1, flags);
1103                 proto_tree_add_boolean(flags_tree, hf_radiotap_channel_flags_gfsk,
1104                         tvb, offset+3, 1, flags);
1105                 proto_tree_add_boolean(flags_tree, hf_radiotap_channel_flags_gsm,
1106                         tvb, offset+3, 1, flags);
1107                 proto_tree_add_boolean(flags_tree, hf_radiotap_channel_flags_sturbo,
1108                         tvb, offset+3, 1, flags);
1109                 proto_tree_add_boolean(flags_tree, hf_radiotap_channel_flags_half,
1110                         tvb, offset+3, 1, flags);
1111                 proto_tree_add_boolean(flags_tree, hf_radiotap_channel_flags_quarter,
1112                         tvb, offset+3, 1, flags);
1113                 radiotap_info->freq=freq;
1114                 radiotap_info->flags=flags;
1115             }
1116             offset+=4 /* Channel + flags */;
1117             length_remaining-=4;
1118             break;
1119         }
1120         case IEEE80211_RADIOTAP_XCHANNEL: {
1121             proto_item *it;
1122             proto_tree *flags_tree;
1123
1124             align_offset = ALIGN_OFFSET(offset, 4);
1125             offset += align_offset;
1126             length_remaining -= align_offset;
1127             if (length_remaining < 8)
1128                 break;
1129             if (tree) {
1130                 int channel;
1131                 guint8 maxpower;
1132
1133                 flags = tvb_get_letohl(tvb, offset);
1134                 freq = tvb_get_letohs(tvb, offset+4);
1135                 channel = tvb_get_guint8(tvb, offset+6);
1136                 maxpower = tvb_get_guint8(tvb, offset+7);
1137                 proto_tree_add_uint(radiotap_tree, hf_radiotap_xchannel,
1138                         tvb, offset+6, 1, (guint32) channel);
1139                 proto_tree_add_uint(radiotap_tree, hf_radiotap_xchannel_frequency,
1140                         tvb, offset+4, 2, freq);
1141                 it = proto_tree_add_uint(radiotap_tree, hf_radiotap_xchannel_flags,
1142                         tvb, offset+0, 4, flags);
1143                 flags_tree = proto_item_add_subtree(it, ett_radiotap_xchannel_flags);
1144                 proto_tree_add_boolean(flags_tree, hf_radiotap_xchannel_flags_turbo,
1145                         tvb, offset+0, 1, flags);
1146                 proto_tree_add_boolean(flags_tree, hf_radiotap_xchannel_flags_cck,
1147                         tvb, offset+0, 1, flags);
1148                 proto_tree_add_boolean(flags_tree, hf_radiotap_xchannel_flags_ofdm,
1149                         tvb, offset+0, 1, flags);
1150                 proto_tree_add_boolean(flags_tree, hf_radiotap_xchannel_flags_2ghz,
1151                         tvb, offset+0, 1, flags);
1152                 proto_tree_add_boolean(flags_tree, hf_radiotap_xchannel_flags_5ghz,
1153                         tvb, offset+1, 1, flags);
1154                 proto_tree_add_boolean(flags_tree, hf_radiotap_xchannel_flags_passive,
1155                         tvb, offset+1, 1, flags);
1156                 proto_tree_add_boolean(flags_tree, hf_radiotap_xchannel_flags_dynamic,
1157                         tvb, offset+1, 1, flags);
1158                 proto_tree_add_boolean(flags_tree, hf_radiotap_xchannel_flags_gfsk,
1159                         tvb, offset+1, 1, flags);
1160                 proto_tree_add_boolean(flags_tree, hf_radiotap_xchannel_flags_gsm,
1161                         tvb, offset+1, 1, flags);
1162                 proto_tree_add_boolean(flags_tree, hf_radiotap_xchannel_flags_sturbo,
1163                         tvb, offset+1, 1, flags);
1164                 proto_tree_add_boolean(flags_tree, hf_radiotap_xchannel_flags_half,
1165                         tvb, offset+1, 1, flags);
1166                 proto_tree_add_boolean(flags_tree, hf_radiotap_xchannel_flags_quarter,
1167                         tvb, offset+1, 1, flags);
1168                 proto_tree_add_boolean(flags_tree, hf_radiotap_xchannel_flags_ht20,
1169                         tvb, offset+2, 1, flags);
1170                 proto_tree_add_boolean(flags_tree, hf_radiotap_xchannel_flags_ht40u,
1171                         tvb, offset+2, 1, flags);
1172                 proto_tree_add_boolean(flags_tree, hf_radiotap_xchannel_flags_ht40d,
1173                         tvb, offset+2, 1, flags);
1174 #if 0
1175                 proto_tree_add_uint(radiotap_tree, hf_radiotap_xchannel_maxpower,
1176                         tvb, offset+7, 1, maxpower);
1177 #endif
1178             }
1179             offset+=8 /* flags + freq + ieee + maxregpower */;
1180             length_remaining-=8;
1181             break;
1182         }
1183         case IEEE80211_RADIOTAP_FHSS:
1184             align_offset = ALIGN_OFFSET(offset, 2);
1185             offset += align_offset;
1186             length_remaining -= align_offset;
1187             if (length_remaining < 2)
1188                 break;
1189             proto_tree_add_item(radiotap_tree, hf_radiotap_fhss_hopset,
1190                 tvb, offset, 1, FALSE);
1191             proto_tree_add_item(radiotap_tree, hf_radiotap_fhss_pattern,
1192                 tvb, offset, 1, FALSE);
1193             offset+=2;
1194             length_remaining-=2;
1195             break;
1196         case IEEE80211_RADIOTAP_TX_ATTENUATION:
1197             align_offset = ALIGN_OFFSET(offset, 2);
1198             offset += align_offset;
1199             length_remaining -= align_offset;
1200             if (length_remaining < 2)
1201                 break;
1202             proto_tree_add_item(radiotap_tree, hf_radiotap_tx_attenuation,
1203                 tvb, offset, 2, FALSE);
1204             offset+=2;
1205             length_remaining-=2;
1206             break;
1207         case IEEE80211_RADIOTAP_DB_TX_ATTENUATION:
1208             align_offset = ALIGN_OFFSET(offset, 2);
1209             offset += align_offset;
1210             length_remaining -= align_offset;
1211             if (length_remaining < 2)
1212                 break;
1213             proto_tree_add_item(radiotap_tree, hf_radiotap_db_tx_attenuation,
1214                 tvb, offset, 2, FALSE);
1215             offset+=2;
1216             length_remaining-=2;
1217             break;
1218         case IEEE80211_RADIOTAP_TSFT:
1219             align_offset = ALIGN_OFFSET(offset, 8);
1220             offset += align_offset;
1221             length_remaining -= align_offset;
1222             if (length_remaining < 8)
1223                 break;
1224             radiotap_info->tsft=tvb_get_letoh64(tvb, offset);
1225             if (tree) {
1226                 proto_tree_add_uint64(radiotap_tree, hf_radiotap_mactime,
1227                                 tvb, offset, 8,radiotap_info->tsft );
1228             }
1229             offset+=8;
1230             length_remaining-=8;
1231             break;
1232         case IEEE80211_RADIOTAP_LOCK_QUALITY:
1233             align_offset = ALIGN_OFFSET(offset, 2);
1234             offset += align_offset;
1235             length_remaining -= align_offset;
1236             if (length_remaining < 2)
1237                 break;
1238             if (tree) {
1239                 proto_tree_add_uint(radiotap_tree, hf_radiotap_quality,
1240                                 tvb, offset, 2, tvb_get_letohs(tvb, offset));
1241             }
1242             offset+=2;
1243             length_remaining-=2;
1244             break;
1245         case IEEE80211_RADIOTAP_RX_FLAGS:
1246             if (radiotap_bit14_fcs) {
1247                 align_offset = ALIGN_OFFSET(offset, 4);
1248                 offset += align_offset;
1249                 length_remaining -= align_offset;
1250                 if (length_remaining < 4)
1251                     break;
1252                 if (tree) {
1253                     sent_fcs = tvb_get_ntohl(tvb, offset);
1254                     hdr_fcs_ti = proto_tree_add_uint(radiotap_tree, hf_radiotap_fcs,
1255                                                      tvb, offset, 4, sent_fcs);
1256                     hdr_fcs_offset = offset;
1257                 }
1258                 offset+=4;
1259                 length_remaining-=4;
1260             } else {
1261                 proto_item *it;
1262
1263                 align_offset = ALIGN_OFFSET(offset, 2);
1264                 offset += align_offset;
1265                 length_remaining -= align_offset;
1266                 if (length_remaining < 2)
1267                     break;
1268                 if (tree) {
1269                     flags = tvb_get_letohs(tvb, offset);
1270                     it = proto_tree_add_uint(radiotap_tree, hf_radiotap_rxflags,
1271                             tvb, offset, 2, flags);
1272                     flags_tree = proto_item_add_subtree(it, ett_radiotap_rxflags);
1273                     proto_tree_add_boolean(flags_tree, hf_radiotap_rxflags_badplcp,
1274                             tvb, offset, 1, flags);
1275                 }
1276                 offset+=2;
1277                 length_remaining-=2;
1278             }
1279             break;
1280         default:
1281             /*
1282              * This indicates a field whose size we do not
1283              * know, so we cannot proceed.
1284              */
1285             next_present = 0;
1286             continue;
1287         }
1288     }
1289
1290     /* This handles the case of an FCS exiting at the end of the frame. */
1291     if (rflags & IEEE80211_RADIOTAP_F_FCS)
1292         pinfo->pseudo_header->ieee_802_11.fcs_len = 4;
1293     else
1294         pinfo->pseudo_header->ieee_802_11.fcs_len = 0;
1295
1296     /* Grab the rest of the frame. */
1297     next_tvb = tvb_new_subset(tvb, length, -1, -1);
1298
1299     /* If we had an in-header FCS, check it.
1300      * This can only happen if the backward-compat configuration option
1301      * is chosen by the user. */
1302     if (hdr_fcs_ti) {
1303         /* It would be very strange for the header to have an FCS for the
1304          * frame *and* the frame to have the FCS at the end, but it's possible, so
1305          * take that into account by using the FCS length recorded in pinfo. */
1306
1307         /* Watch out for [erroneously] short frames */
1308         if (tvb_length(next_tvb) > (unsigned int) pinfo->pseudo_header->ieee_802_11.fcs_len) {
1309             calc_fcs = crc32_802_tvb(next_tvb,
1310                     tvb_length(next_tvb) - pinfo->pseudo_header->ieee_802_11.fcs_len);
1311
1312             /* By virtue of hdr_fcs_ti being set, we know that 'tree' is set,
1313              * so there's no need to check it here. */
1314             if (calc_fcs == sent_fcs) {
1315                 proto_item_append_text(hdr_fcs_ti, " [correct]");
1316             }
1317             else {
1318                 proto_item_append_text(hdr_fcs_ti,
1319                         " [incorrect, should be 0x%08x]", calc_fcs);
1320                 hidden_item = proto_tree_add_boolean(radiotap_tree, hf_radiotap_fcs_bad,
1321                         tvb, hdr_fcs_offset, 4, TRUE);
1322                 PROTO_ITEM_SET_HIDDEN(hidden_item);
1323             }
1324         }
1325         else {
1326                 proto_item_append_text(hdr_fcs_ti,
1327                         " [cannot verify - not enough data]");
1328         }
1329     }
1330
1331     /* dissect the 802.11 header next */
1332     call_dissector((rflags & IEEE80211_RADIOTAP_F_DATAPAD) ?
1333         ieee80211_datapad_handle : ieee80211_handle,
1334         next_tvb, pinfo, tree);
1335     
1336     tap_queue_packet(radiotap_tap, pinfo, radiotap_info);
1337 }
1338
1339 void
1340 proto_reg_handoff_radiotap(void)
1341 {
1342     dissector_handle_t radiotap_handle;
1343
1344     /* handle for 802.11 dissector */
1345     ieee80211_handle = find_dissector("wlan");
1346     ieee80211_datapad_handle = find_dissector("wlan_datapad");
1347
1348     radiotap_handle = find_dissector("radiotap");
1349
1350     dissector_add("wtap_encap", WTAP_ENCAP_IEEE_802_11_WLAN_RADIOTAP, radiotap_handle);
1351 }
1352
1353 /*
1354  * Editor modelines
1355  *
1356  * Local Variables:
1357  * c-basic-offset: 4
1358  * tab-width: 8
1359  * indent-tabs-mode: t
1360  * End:
1361  *
1362  * ex: set shiftwidth=4 tabstop=8 noexpandtab
1363  * :indentSize=4:tabSize=8:noTabs=false:
1364  */
1365