3 * Decode packets with a Radiotap header
7 * Wireshark - Network traffic analyzer
8 * By Gerald Combs <gerald@wireshark.org>
9 * Copyright 1998 Gerald Combs
11 * Copied from README.developer
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.
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.
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.
35 #include <epan/packet.h>
36 #include <epan/crc32.h>
37 #include <epan/frequency-utils.h>
39 #include <epan/prefs.h>
40 #include "packet-ieee80211.h"
41 #include "packet-radiotap.h"
43 /* Official specifcation:
45 * http://www.radiotap.org/
47 * Unofficial and historical specifications:
48 * http://madwifi.org/wiki/DevDocs/RadiotapHeader
49 * NetBSD's ieee80211_radiotap.h file
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.
59 guint16 it_len; /* length of the whole
60 * header in bytes, including
62 * it_len, and data fields.
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
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 */
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
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 */
117 * Useful combinations of channel characteristics.
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)
136 /* For IEEE80211_RADIOTAP_FLAGS */
137 #define IEEE80211_RADIOTAP_F_CFP 0x01 /* sent/received
140 #define IEEE80211_RADIOTAP_F_SHORTPRE 0x02 /* sent/received
144 #define IEEE80211_RADIOTAP_F_WEP 0x04 /* sent/received
145 * with WEP encryption
147 #define IEEE80211_RADIOTAP_F_FRAG 0x08 /* sent/received
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)
155 #define IEEE80211_RADIOTAP_F_BADFCS 0x40 /* does not pass FCS check */
156 #define IEEE80211_RADIOTAP_F_SHORTGI 0x80 /* HT short GI */
158 /* For IEEE80211_RADIOTAP_RX_FLAGS */
159 #define IEEE80211_RADIOTAP_F_RX_BADPLCP 0x0002 /* bad PLCP */
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 */
182 static int proto_radiotap = -1;
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;
225 static int hf_radiotap_xchannel_maxpower = -1;
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;
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;
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;
270 static int hf_radiotap_quality = -1;
271 static int hf_radiotap_fcs = -1;
272 static int hf_radiotap_fcs_bad = -1;
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;
281 static dissector_handle_t ieee80211_handle;
282 static dissector_handle_t ieee80211_datapad_handle;
284 static int radiotap_tap = -1;
287 static gboolean radiotap_bit14_fcs = FALSE;
290 dissect_radiotap(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
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)
300 * The NetBSD ieee80211_radiotap man page
301 * (http://netbsd.gw.com/cgi-bin/man-cgi?ieee80211_radiotap+9+NetBSD-current)
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.
313 * Returns the amount required to align "offset" with "width"
315 #define ALIGN_OFFSET(offset, width) \
316 ( (((offset) + ((width) - 1)) & (~((width) - 1))) - offset )
320 capture_radiotap(const guchar *pd, int offset, int len, packet_counts *ld)
326 if(!BYTES_ARE_IN_FRAME(offset, len, RADIOTAP_MIN_HEADER_LEN)) {
330 it_len = pletohs(&pd[RADIOTAP_LENGTH_OFFSET]);
331 if(!BYTES_ARE_IN_FRAME(offset, len, it_len)) {
337 /* Header length is bigger than total packet length */
342 if(it_len < RADIOTAP_MIN_HEADER_LEN) {
343 /* Header length is shorter than fixed-length portion of header */
348 present = pletohl(&pd[RADIOTAP_PRESENT_OFFSET]);
349 offset += RADIOTAP_MIN_HEADER_LEN;
350 it_len -= RADIOTAP_MIN_HEADER_LEN;
355 * IEEE80211_RADIOTAP_TSFT is the lowest-order bit.
357 if (present & BIT(IEEE80211_RADIOTAP_TSFT)) {
359 /* No room in header for this field. */
363 /* That field is present, and it's 8 bits long. */
369 * IEEE80211_RADIOTAP_FLAGS is the next bit.
371 if (present & BIT(IEEE80211_RADIOTAP_FLAGS)) {
373 /* No room in header for this field. */
377 /* That field is present; fetch it. */
378 if(!BYTES_ARE_IN_FRAME(offset, len, 1)) {
385 /* 802.11 header follows */
386 if (rflags & IEEE80211_RADIOTAP_F_DATAPAD)
387 capture_ieee80211_datapad(pd, offset + it_len, len, ld);
389 capture_ieee80211(pd, offset + it_len, len, ld);
393 proto_register_radiotap(void)
395 static const value_string phy_type[] = {
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" },
414 static const true_false_string preamble_type = {
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 } },
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 } },
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
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 } },
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 } },
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 } },
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 } },
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 } },
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 } },
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 } },
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 } },
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 } },
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 } },
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 } },
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 } },
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 } },
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 } },
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 } },
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 } },
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 } },
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 } },
545 /* Boolean 'present.flags' flags */
546 { &hf_radiotap_flags,
547 { "Flags", "radiotap.flags",
548 FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL } },
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 } },
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 } },
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 } },
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 } },
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 } },
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 } },
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 } },
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 } },
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 } },
596 { &hf_radiotap_quality,
597 { "Signal Quality", "radiotap.quality",
598 FT_UINT16, BASE_DEC, NULL, 0x0,
599 "Signal quality (unitless measure)", HFILL } },
602 { "802.11 FCS", "radiotap.fcs",
603 FT_UINT32, BASE_HEX, NULL, 0x0,
604 "Frame check sequence of this frame", HFILL } },
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 } },
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 } },
616 { &hf_radiotap_channel_flags,
617 { "Channel type", "radiotap.channel.type",
618 FT_UINT16, BASE_HEX, VALS(phy_type), 0x0,
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 } },
658 { &hf_radiotap_rxflags,
659 { "RX flags", "radiotap.rxflags",
660 FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL } },
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 } },
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 } },
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 } },
723 { &hf_radiotap_xchannel_maxpower,
724 { "Max transmit power", "radiotap.xchannel.maxpower",
725 FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL } },
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 } },
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 } },
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 } },
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 } },
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 } },
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 } },
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 } },
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 } },
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 } },
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 } },
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 } },
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 } },
789 static gint *ett[] = {
791 &ett_radiotap_present,
793 &ett_radiotap_rxflags,
794 &ett_radiotap_channel_flags,
795 &ett_radiotap_xchannel_flags
797 module_t *radiotap_module;
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);
804 radiotap_tap = register_tap("radiotap");
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);
816 dissect_radiotap(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
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;
825 guint length, length_remaining;
826 guint32 rate, freq, flags;
829 guint32 present, next_present;
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;
837 struct _radiotap_info *radiotap_info;
838 static struct _radiotap_info rtp_info_arr[1];
840 radiotap_info = &rtp_info_arr[0];
842 col_set_str(pinfo->cinfo, COL_PROTOCOL, "WLAN");
843 col_clear(pinfo->cinfo, COL_INFO);
846 version = tvb_get_guint8(tvb, offset);
847 length = tvb_get_letohs(tvb, offset+2);
848 present = tvb_get_letohl(tvb, offset+4);
850 radiotap_info->radiotap_length = length;
852 col_add_fstr(pinfo->cinfo, COL_INFO, "Radiotap Capture v%u, Length %u",
855 /* Dissect the packet */
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);
867 length_remaining = length;
870 * FIXME: This only works if there is exactly 1 it_present
871 * field in the header
873 if (length_remaining < RADIOTAP_MIN_HEADER_LEN) {
875 * Radiotap header is shorter than the fixed-length portion
876 * plus one "present" bitset.
879 proto_item_append_text(ti, " (bogus - minimum length is 8)");
882 /* Subtree for the "present flags" bitfield. */
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);
888 proto_tree_add_item(present_tree, hf_radiotap_present_tsft,
890 proto_tree_add_item(present_tree, hf_radiotap_present_flags,
892 proto_tree_add_item(present_tree, hf_radiotap_present_rate,
894 proto_tree_add_item(present_tree, hf_radiotap_present_channel,
896 proto_tree_add_item(present_tree, hf_radiotap_present_fhss,
898 proto_tree_add_item(present_tree, hf_radiotap_present_dbm_antsignal,
900 proto_tree_add_item(present_tree, hf_radiotap_present_dbm_antnoise,
902 proto_tree_add_item(present_tree, hf_radiotap_present_lock_quality,
904 proto_tree_add_item(present_tree, hf_radiotap_present_tx_attenuation,
906 proto_tree_add_item(present_tree, hf_radiotap_present_db_tx_attenuation,
908 proto_tree_add_item(present_tree, hf_radiotap_present_dbm_tx_attenuation,
910 proto_tree_add_item(present_tree, hf_radiotap_present_antenna,
912 proto_tree_add_item(present_tree, hf_radiotap_present_db_antsignal,
914 proto_tree_add_item(present_tree, hf_radiotap_present_db_antnoise,
916 if (radiotap_bit14_fcs) {
917 proto_tree_add_item(present_tree, hf_radiotap_present_hdrfcs,
920 proto_tree_add_item(present_tree, hf_radiotap_present_rxflags,
923 proto_tree_add_item(present_tree, hf_radiotap_present_xchannel,
925 proto_tree_add_item(present_tree, hf_radiotap_present_ext,
928 offset += RADIOTAP_MIN_HEADER_LEN;
929 length_remaining -= RADIOTAP_MIN_HEADER_LEN;
932 for (; present; present = next_present) {
933 /* clear the least significant bit that is set */
934 next_present = present & (present - 1);
936 /* extract the least significant bit that is set */
937 bit = BITNO_32(present ^ next_present);
940 case IEEE80211_RADIOTAP_FLAGS:
941 if (length_remaining < 1)
943 rflags = tvb_get_guint8(tvb, offset);
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);
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);
970 case IEEE80211_RADIOTAP_RATE:
971 if (length_remaining < 1)
973 rate = tvb_get_guint8(tvb, offset);
975 /* XXX adjust by CW and short GI like other sniffers? */
976 rate = ieee80211_htrates[rate & 0xf];
978 col_add_fstr(pinfo->cinfo, COL_TX_RATE, "%d.%d",
979 rate / 2, rate & 1 ? 5 : 0);
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);
987 radiotap_info->rate = rate;
989 case IEEE80211_RADIOTAP_DBM_ANTSIGNAL:
990 if (length_remaining < 1)
992 dbm = (gint8) tvb_get_guint8(tvb, offset);
993 col_add_fstr(pinfo->cinfo, COL_RSSI, "%d dBm", dbm);
995 proto_tree_add_int_format(radiotap_tree,
996 hf_radiotap_dbm_antsignal,
998 "SSI Signal: %d dBm", dbm);
1002 radiotap_info->dbm_antsignal=dbm;
1004 case IEEE80211_RADIOTAP_DB_ANTSIGNAL:
1005 if (length_remaining < 1)
1007 db = tvb_get_guint8(tvb, offset);
1008 col_add_fstr(pinfo->cinfo, COL_RSSI, "%u dB", db);
1010 proto_tree_add_uint_format(radiotap_tree,
1011 hf_radiotap_db_antsignal,
1013 "SSI Signal: %u dB", db);
1018 case IEEE80211_RADIOTAP_DBM_ANTNOISE:
1019 if (length_remaining < 1)
1021 dbm = (gint8) tvb_get_guint8(tvb, offset);
1023 proto_tree_add_int_format(radiotap_tree,
1024 hf_radiotap_dbm_antnoise,
1025 tvb, offset, 1, dbm,
1026 "SSI Noise: %d dBm", dbm);
1030 radiotap_info->dbm_antnoise=dbm;
1032 case IEEE80211_RADIOTAP_DB_ANTNOISE:
1033 if (length_remaining < 1)
1035 db = tvb_get_guint8(tvb, offset);
1037 proto_tree_add_uint_format(radiotap_tree,
1038 hf_radiotap_db_antnoise,
1040 "SSI Noise: %u dB", db);
1045 case IEEE80211_RADIOTAP_ANTENNA:
1046 if (length_remaining < 1)
1049 proto_tree_add_uint(radiotap_tree, hf_radiotap_antenna,
1050 tvb, offset, 1, tvb_get_guint8(tvb, offset));
1055 case IEEE80211_RADIOTAP_DBM_TX_POWER:
1056 if (length_remaining < 1)
1059 proto_tree_add_int(radiotap_tree, hf_radiotap_txpower,
1060 tvb, offset, 1, tvb_get_guint8(tvb, offset));
1065 case IEEE80211_RADIOTAP_CHANNEL:
1068 proto_tree *flags_tree;
1071 align_offset = ALIGN_OFFSET(offset, 2);
1072 offset += align_offset;
1073 length_remaining -= align_offset;
1074 if (length_remaining < 2)
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);
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;
1116 offset+=4 /* Channel + flags */;
1117 length_remaining-=4;
1120 case IEEE80211_RADIOTAP_XCHANNEL: {
1122 proto_tree *flags_tree;
1124 align_offset = ALIGN_OFFSET(offset, 4);
1125 offset += align_offset;
1126 length_remaining -= align_offset;
1127 if (length_remaining < 8)
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);
1175 proto_tree_add_uint(radiotap_tree, hf_radiotap_xchannel_maxpower,
1176 tvb, offset+7, 1, maxpower);
1179 offset+=8 /* flags + freq + ieee + maxregpower */;
1180 length_remaining-=8;
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)
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);
1194 length_remaining-=2;
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)
1202 proto_tree_add_item(radiotap_tree, hf_radiotap_tx_attenuation,
1203 tvb, offset, 2, FALSE);
1205 length_remaining-=2;
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)
1213 proto_tree_add_item(radiotap_tree, hf_radiotap_db_tx_attenuation,
1214 tvb, offset, 2, FALSE);
1216 length_remaining-=2;
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)
1224 radiotap_info->tsft=tvb_get_letoh64(tvb, offset);
1226 proto_tree_add_uint64(radiotap_tree, hf_radiotap_mactime,
1227 tvb, offset, 8,radiotap_info->tsft );
1230 length_remaining-=8;
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)
1239 proto_tree_add_uint(radiotap_tree, hf_radiotap_quality,
1240 tvb, offset, 2, tvb_get_letohs(tvb, offset));
1243 length_remaining-=2;
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)
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;
1259 length_remaining-=4;
1263 align_offset = ALIGN_OFFSET(offset, 2);
1264 offset += align_offset;
1265 length_remaining -= align_offset;
1266 if (length_remaining < 2)
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);
1277 length_remaining-=2;
1282 * This indicates a field whose size we do not
1283 * know, so we cannot proceed.
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;
1294 pinfo->pseudo_header->ieee_802_11.fcs_len = 0;
1296 /* Grab the rest of the frame. */
1297 next_tvb = tvb_new_subset(tvb, length, -1, -1);
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. */
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. */
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);
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]");
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);
1326 proto_item_append_text(hdr_fcs_ti,
1327 " [cannot verify - not enough data]");
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);
1336 tap_queue_packet(radiotap_tap, pinfo, radiotap_info);
1340 proto_reg_handoff_radiotap(void)
1342 dissector_handle_t radiotap_handle;
1344 /* handle for 802.11 dissector */
1345 ieee80211_handle = find_dissector("wlan");
1346 ieee80211_datapad_handle = find_dissector("wlan_datapad");
1348 radiotap_handle = find_dissector("radiotap");
1350 dissector_add("wtap_encap", WTAP_ENCAP_IEEE_802_11_WLAN_RADIOTAP, radiotap_handle);
1359 * indent-tabs-mode: t
1362 * ex: set shiftwidth=4 tabstop=8 noexpandtab
1363 * :indentSize=4:tabSize=8:noTabs=false: