1 /* packet-ieee80211-wlancap.c
2 * Routines for AVS linux-wlan monitoring mode header dissection
6 * Wireshark - Network traffic analyzer
7 * By Gerald Combs <gerald@wireshark.org>
8 * Copyright 1998 Gerald Combs
10 * Copied from README.developer
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
31 #include <epan/packet.h>
32 #include "packet-ieee80211.h"
34 static dissector_handle_t ieee80211_handle;
36 static int proto_wlancap = -1;
38 /* AVS WLANCAP radio header */
39 static int hf_wlan_magic = -1;
40 static int hf_wlan_version = -1;
41 static int hf_wlan_length = -1;
42 static int hf_wlan_phytype = -1;
43 static int hf_wlan_antenna = -1;
44 static int hf_wlan_priority = -1;
45 static int hf_wlan_ssi_type = -1;
46 static int hf_wlan_preamble = -1;
47 static int hf_wlan_encoding = -1;
48 static int hf_wlan_sequence = -1;
49 static int hf_wlan_drops = -1;
50 static int hf_wlan_receiver_addr = -1;
51 static int hf_wlan_padding = -1;
53 static int hf_mactime = -1;
54 static int hf_hosttime = -1;
55 static int hf_channel_frequency = -1;
56 static int hf_data_rate = -1;
57 static int hf_channel = -1;
58 static int hf_dbm_antnoise = -1;
59 static int hf_rawrssi_antnoise = -1;
60 static int hf_normrssi_antnoise = -1;
61 static int hf_rawrssi_antsignal = -1;
62 static int hf_dbm_antsignal = -1;
63 static int hf_normrssi_antsignal = -1;
65 static gint ett_radio = -1;
67 static dissector_handle_t wlancap_handle;
70 capture_wlancap(const guchar *pd, int offset, int len, packet_counts *ld)
74 if (!BYTES_ARE_IN_FRAME(offset, len, sizeof(guint32)*2)) {
79 length = pntohl(pd+sizeof(guint32));
81 if (!BYTES_ARE_IN_FRAME(offset, len, length)) {
88 /* 802.11 header follows */
89 capture_ieee80211(pd, offset, len, ld);
93 * AVS linux-wlan-based products use a new sniff header to replace the
94 * old Prism header. This one has additional fields, is designed to be
95 * non-hardware-specific, and more importantly, version and length fields
96 * so it can be extended later without breaking anything.
98 * Support by Solomon Peachy
100 * Description, from the capturefrm.txt file in the linux-wlan-ng 0.2.9
101 * release (linux-wlan-ng-0.2.9/doc/capturefrm.txt):
103 AVS Capture Frame Format
107 The original header format for "monitor mode" or capturing frames was
108 a considerable hack. The document covers a redesign of that format.
110 Any questions, corrections, or proposed changes go to info@linux-wlan.com
113 All sniff frames follow the same format:
115 Offset Name Size Description
116 --------------------------------------------------------------------
117 0 CaptureHeader AVS capture metadata header
118 64 802.11Header [10-30] 802.11 frame header
119 ?? 802.11Payload [0-2312] 802.11 frame payload
120 ?? 802.11FCS 4 802.11 frame check sequence
122 Note that the header and payload are variable length and the payload
125 If the hardware does not supply the FCS to the driver, then the frame shall
126 have a FCS of 0xFFFFFFFF.
129 All multibyte fields of the capture header are in "network" byte
130 order. The "host to network" and "network to host" functions should
131 work just fine. All the remaining multibyte fields are ordered
132 according to their respective standards.
134 4. Capture Header Format
135 The following fields make up the AVS capture header:
138 ------------------------------
155 72 receiver_addr uint8[6]
157 ------------------------------
160 The following subsections detail the fields of the capture header.
163 The version field identifies this type of frame as a subtype of
164 ETH_P_802111_CAPTURE as received by an ARPHRD_IEEE80211_PRISM or
165 an ARPHRD_IEEE80211_CAPTURE device. The value of this field shall be
166 0x80211002. As new revisions of this header are necessary, we can
167 increment the version appropriately.
170 The length field contains the length of the entire AVS capture header,
174 Many WLAN devices supply a relatively high resolution frame reception
175 time value. This field contains the value supplied by the device. If
176 the device does not supply a receive time value, this field shall be
177 set to zero. The units for this field are microseconds.
179 If possible, this time value should be absolute, representing the number
180 of microseconds elapsed since the UNIX epoch.
183 The hosttime field is set to the current value of the host maintained
184 clock variable when the frame is received by the host.
186 If possible, this time value should be absolute, representing the number
187 of microseconds elapsed since the UNIX epoch.
190 The phytype field identifies what type of PHY is employed by the WLAN
191 device used to capture this frame. The valid values are:
194 -------------------------------------
195 phytype_fhss_dot11_97 1
196 phytype_dsss_dot11_97 2
198 phytype_dsss_dot11_b 4
199 phytype_pbcc_dot11_b 5
200 phytype_ofdm_dot11_g 6
201 phytype_pbcc_dot11_g 7
202 phytype_ofdm_dot11_a 8
203 phytype_dss_ofdm_dot11_g 9
207 This represents the frequency or channel number of the receiver at the
208 time the frame was received. It is interpreted as follows:
210 For frequency hopping radios, this field is broken in to the
214 ------------------------
220 For non-hopping radios, the frequency is interpreted as follows:
223 -----------------------------------------
224 < 256 Channel number (using externally-defined
226 < 10000 Center frequency, in MHz
227 >= 10000 Center frequency, in KHz
230 The data rate field contains the rate at which the frame was received
234 For WLAN devices that indicate the receive antenna for each frame, the
235 antenna field shall contain an index value into the dot11AntennaList.
236 If the device does not indicate a receive antenna value, this field
237 shall be set to zero.
240 The priority field indicates the receive priority of the frame. The
241 value is in the range [0-15] with the value 0 reserved to indicate
242 contention period and the value 6 reserved to indicate contention free
246 The ssi_type field is used to indicate what type of signal strength
247 information is present: "None", "Normalized RSSI" or "dBm". "None"
248 indicates that the underlying WLAN device does not supply any signal
249 strength at all and the ssi_* values are unset. "Normalized RSSI"
250 values are integers in the range [0-1000] where higher numbers
251 indicate stronger signal. "dBm" values indicate an actual signal
252 strength measurement quantity and are usually in the range [-108 - 10].
253 The following values indicate the three types:
256 ---------------------------------------------
263 The ssi_signal field contains the signal strength value reported by
264 the WLAN device for this frame. Note that this is a signed quantity
265 and if the ssi_type value is "dBm" that the value may be negative.
268 The ssi_noise field contains the noise or "silence" value reported by
269 the WLAN device. This value is commonly defined to be the "signal
270 strength reported immediately prior to the baseband processor lock on
271 the frame preamble". If the hardware does not provide noise data, this
272 shall equal 0xffffffff.
275 For PHYs that support variable preamble lengths, the preamble field
276 indicates the preamble type used for this frame. The values are:
279 ---------------------------------------------
285 This specifies the encoding of the received packet. For PHYs that support
286 multiple encoding types, this will tell us which one was used.
289 ---------------------------------------------
301 This is a receive frame sequence counter. The sniff host shall
302 increment this by one for every valid frame received off the medium.
303 By watching for gaps in the sequence numbers we can determine when
304 packets are lost due to unreliable transport, rather than a frame never
305 being received to begin with.
308 This is a counter of the number of known frame drops that occured. This
309 is particularly useful when the system or hardware cannot keep up with
313 This specifies the MAC address of the receiver of this frame.
314 It is six octets in length. This field is followed by two octets of
315 padding to keep the structure 32-bit word aligned.
317 ================================
321 * Added contact e-mail address to introduction
322 * Added sniffer_addr, drop count, and sequence fields, bringing total
324 * Bumped version to 0x80211002
325 * Mactime is specified in microseconds, not nanoseconds
326 * Added 64QAM, 16QAM, BPSK, QPSK encodings
328 ================================
330 Changes: v2.1->v2.1.1
332 * Renamed 'channel' to 'frequency'
333 * Clarified the interpretation of the frequency/channel field.
334 * Renamed 'sniffer address' to 'receiver address'
335 * Clarified timestamp fields.
339 * Signal/noise strength type values.
341 #define SSI_NONE 0 /* no SSI information */
342 #define SSI_NORM_RSSI 1 /* normalized RSSI - 0-1000 */
343 #define SSI_DBM 2 /* dBm */
344 #define SSI_RAW_RSSI 3 /* raw RSSI from the hardware */
347 dissect_wlancap(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
349 proto_tree *wlan_tree = NULL;
360 col_set_str(pinfo->cinfo, COL_PROTOCOL, "WLAN");
361 col_clear(pinfo->cinfo, COL_INFO);
364 version = tvb_get_ntohl(tvb, offset) - WLANCAP_MAGIC_COOKIE_BASE;
366 length = tvb_get_ntohl(tvb, offset+4);
368 col_add_fstr(pinfo->cinfo, COL_INFO, "AVS WLAN Capture v%x, Length %d",version, length);
374 /* Dissect the AVS header */
376 ti = proto_tree_add_item(tree, proto_wlancap, tvb, 0, length, ENC_NA);
377 wlan_tree = proto_item_add_subtree(ti, ett_radio);
378 proto_tree_add_item(wlan_tree, hf_wlan_magic, tvb, offset, 4, ENC_BIG_ENDIAN);
379 proto_tree_add_item(wlan_tree, hf_wlan_version, tvb, offset, 4, ENC_BIG_ENDIAN);
383 proto_tree_add_item(wlan_tree, hf_wlan_length, tvb, offset, 4, ENC_BIG_ENDIAN);
386 proto_tree_add_item(wlan_tree, hf_mactime, tvb, offset, 8, ENC_BIG_ENDIAN);
389 proto_tree_add_item(wlan_tree, hf_hosttime, tvb, offset, 8, ENC_BIG_ENDIAN);
392 proto_tree_add_item(wlan_tree, hf_wlan_phytype, tvb, offset, 4, ENC_BIG_ENDIAN);
395 /* XXX cook channel (fh uses different numbers) */
396 channel = tvb_get_ntohl(tvb, offset);
398 col_add_fstr(pinfo->cinfo, COL_FREQ_CHAN, "%u", channel);
400 proto_tree_add_uint(wlan_tree, hf_channel, tvb, offset, 4, channel);
401 } else if (channel < 10000) {
402 col_add_fstr(pinfo->cinfo, COL_FREQ_CHAN, "%u MHz", channel);
404 proto_tree_add_uint_format(wlan_tree, hf_channel_frequency, tvb, offset,
405 4, channel, "Frequency: %u MHz", channel);
407 col_add_fstr(pinfo->cinfo, COL_FREQ_CHAN, "%u KHz", channel);
409 proto_tree_add_uint_format(wlan_tree, hf_channel_frequency, tvb, offset,
410 4, channel, "Frequency: %u KHz", channel);
413 datarate = tvb_get_ntohl(tvb, offset);
414 if (datarate < 100000) {
415 /* In units of 100 Kb/s; convert to b/s */
419 col_add_fstr(pinfo->cinfo, COL_TX_RATE, "%u.%u",
421 ((datarate % 1000000) > 500000) ? 5 : 0);
423 proto_tree_add_uint64_format(wlan_tree, hf_data_rate, tvb, offset, 4,
425 "Data Rate: %u.%u Mb/s",
427 ((datarate % 1000000) > 500000) ? 5 : 0);
431 proto_tree_add_item(wlan_tree, hf_wlan_antenna, tvb, offset, 4, ENC_BIG_ENDIAN);
434 proto_tree_add_item(wlan_tree, hf_wlan_priority, tvb, offset, 4, ENC_BIG_ENDIAN);
436 ssi_type = tvb_get_ntohl(tvb, offset);
438 proto_tree_add_uint(wlan_tree, hf_wlan_ssi_type, tvb, offset, 4, ssi_type);
444 /* either there is no SSI information, or we don't know what type it is */
448 /* Normalized RSSI */
449 col_add_fstr(pinfo->cinfo, COL_RSSI, "%u (norm)", tvb_get_ntohl(tvb, offset));
451 proto_tree_add_item(wlan_tree, hf_normrssi_antsignal, tvb, offset, 4, ENC_BIG_ENDIAN);
456 col_add_fstr(pinfo->cinfo, COL_RSSI, "%d dBm", tvb_get_ntohl(tvb, offset));
458 proto_tree_add_item(wlan_tree, hf_dbm_antsignal, tvb, offset, 4, ENC_BIG_ENDIAN);
463 col_add_fstr(pinfo->cinfo, COL_RSSI, "%u (raw)", tvb_get_ntohl(tvb, offset));
465 proto_tree_add_item(wlan_tree, hf_rawrssi_antsignal, tvb, offset, 4, ENC_BIG_ENDIAN);
469 antnoise = tvb_get_ntohl(tvb, offset);
470 /* 0xffffffff means "hardware does not provide noise data" */
471 if (antnoise != 0xffffffff) {
476 /* either there is no SSI information, or we don't know what type it is */
480 /* Normalized RSSI */
482 proto_tree_add_uint(wlan_tree, hf_normrssi_antnoise, tvb, offset, 4, antnoise);
488 proto_tree_add_int(wlan_tree, hf_dbm_antnoise, tvb, offset, 4, antnoise);
494 proto_tree_add_uint(wlan_tree, hf_rawrssi_antnoise, tvb, offset, 4, antnoise);
500 proto_tree_add_item(wlan_tree, hf_wlan_preamble, tvb, offset, 4, ENC_BIG_ENDIAN);
503 proto_tree_add_item(wlan_tree, hf_wlan_encoding, tvb, offset, 4, ENC_BIG_ENDIAN);
507 proto_tree_add_item(wlan_tree, hf_wlan_sequence, tvb, offset, 4, ENC_BIG_ENDIAN);
510 proto_tree_add_item(wlan_tree, hf_wlan_drops, tvb, offset, 4, ENC_BIG_ENDIAN);
513 proto_tree_add_item(wlan_tree, hf_wlan_receiver_addr, tvb, offset, 6, ENC_NA);
516 proto_tree_add_item(wlan_tree, hf_wlan_padding, tvb, offset, 2, ENC_NA);
524 /* dissect the 802.11 header next */
525 next_tvb = tvb_new_subset_remaining(tvb, offset);
526 call_dissector(ieee80211_handle, next_tvb, pinfo, tree);
529 static const value_string phy_type[] = {
531 { 1, "FHSS 802.11 '97" },
532 { 2, "DSSS 802.11 '97" },
533 { 3, "IR Baseband" },
534 { 4, "DSSS 802.11b" },
535 { 5, "PBCC 802.11b" },
536 { 6, "OFDM 802.11g" },
537 { 7, "PBCC 802.11g" },
538 { 8, "OFDM 802.11a" },
542 static const value_string encoding_type[] = {
555 static const value_string ssi_type[] = {
556 { SSI_NONE, "None" },
557 { SSI_NORM_RSSI, "Normalized RSSI" },
559 { SSI_RAW_RSSI, "Raw RSSI" },
563 static const value_string preamble_type[] = {
570 static hf_register_info hf_wlancap[] = {
572 {"MAC timestamp", "wlan.mactime", FT_UINT64, BASE_DEC, NULL, 0x0,
573 "Value in microseconds of the MAC's Time Synchronization Function timer when the first bit of the MPDU arrived at the MAC", HFILL }},
576 {"Host timestamp", "wlan.hosttime", FT_UINT64, BASE_DEC, NULL, 0x0,
579 {&hf_channel_frequency,
580 {"Channel frequency", "wlan.channel_frequency", FT_UINT32, BASE_DEC, NULL, 0x0,
581 "Channel frequency in megahertz that this frame was sent/received on", HFILL }},
584 {"Data Rate", "wlan.data_rate", FT_UINT64, BASE_DEC, NULL, 0,
585 "Data rate (b/s)", HFILL }},
587 {"Channel", "wlan.channel", FT_UINT8, BASE_DEC, NULL, 0,
588 "802.11 channel number that this frame was sent/received on", HFILL }},
591 {"Antenna", "wlan.antenna", FT_UINT32, BASE_DEC, NULL, 0x0,
592 "Antenna number this frame was sent/received over (starting at 0)", HFILL } },
593 {&hf_rawrssi_antnoise,
594 {"Raw RSSI Noise", "wlan.rawrssi_antnoise", FT_UINT32, BASE_DEC, NULL, 0x0,
595 "RF noise power at the antenna, reported as RSSI by the adapter", HFILL }},
597 {"SSI Noise (dBm)", "wlan.dbm_antnoise", FT_INT32, BASE_DEC, NULL, 0x0,
598 "RF noise power at the antenna from a fixed, arbitrary value in decibels per one milliwatt", HFILL }},
600 {&hf_normrssi_antnoise,
601 {"Normalized RSSI Noise", "wlan.normrssi_antnoise", FT_UINT32, BASE_DEC, NULL, 0x0,
602 "RF noise power at the antenna, normalized to the range 0-1000", HFILL }},
603 {&hf_rawrssi_antsignal,
604 {"Raw RSSI Signal", "wlan.rawrssi_antsignal", FT_UINT32, BASE_DEC, NULL, 0x0,
605 "RF signal power at the antenna, reported as RSSI by the adapter", HFILL }},
607 {"SSI Signal (dBm)", "wlan.dbm_antsignal", FT_INT32, BASE_DEC, NULL, 0x0,
608 "RF signal power at the antenna from a fixed, arbitrary value in decibels from one milliwatt", HFILL }},
610 {&hf_normrssi_antsignal,
611 {"Normalized RSSI Signal", "wlan.normrssi_antsignal", FT_UINT32, BASE_DEC, NULL, 0x0,
612 "RF signal power at the antenna, normalized to the range 0-1000", HFILL }},
614 /* AVS-specific header fields.
615 XXX - make as many of these generic as possible. */
617 {"Header magic", "wlancap.magic", FT_UINT32, BASE_HEX, NULL, 0xFFFFFFF0, NULL, HFILL } },
618 { &hf_wlan_version, { "Header revision", "wlancap.version", FT_UINT32,
619 BASE_DEC, NULL, 0xF, NULL, HFILL } },
620 { &hf_wlan_length, { "Header length", "wlancap.length", FT_UINT32,
621 BASE_DEC, NULL, 0x0, NULL, HFILL } },
623 {"PHY type", "wlan.phytype", FT_UINT32, BASE_DEC, VALS(phy_type), 0x0,
626 { &hf_wlan_priority, { "Priority", "wlancap.priority", FT_UINT32, BASE_DEC,
627 NULL, 0x0, NULL, HFILL } },
628 { &hf_wlan_ssi_type, { "SSI Type", "wlancap.ssi_type", FT_UINT32, BASE_DEC,
629 VALS(ssi_type), 0x0, NULL, HFILL } },
630 { &hf_wlan_preamble, { "Preamble", "wlancap.preamble", FT_UINT32,
631 BASE_DEC, VALS(preamble_type), 0x0, NULL, HFILL } },
632 { &hf_wlan_encoding, { "Encoding Type", "wlancap.encoding", FT_UINT32,
633 BASE_DEC, VALS(encoding_type), 0x0, NULL, HFILL } },
634 { &hf_wlan_sequence, { "Receive sequence", "wlancap.sequence", FT_UINT32,
635 BASE_DEC, NULL, 0x0, NULL, HFILL } },
636 { &hf_wlan_drops, { "Known Dropped Frames", "wlancap.drops", FT_UINT32,
637 BASE_DEC, NULL, 0x0, NULL, HFILL } },
638 { &hf_wlan_receiver_addr, { "Receiver Address", "wlancap.receiver_addr", FT_ETHER,
639 BASE_NONE, NULL, 0x0, "Receiver Hardware Address", HFILL } },
640 { &hf_wlan_padding, { "Padding", "wlancap.padding", FT_BYTES,
641 BASE_NONE, NULL, 0x0, NULL, HFILL } }
644 static gint *tree_array[] = {
648 void proto_register_ieee80211_wlancap(void)
650 proto_wlancap = proto_register_protocol("AVS WLAN Capture header",
651 "AVS WLANCAP", "wlancap");
652 proto_register_field_array(proto_wlancap, hf_wlancap,
653 array_length(hf_wlancap));
654 register_dissector("wlancap", dissect_wlancap, proto_wlancap);
656 wlancap_handle = create_dissector_handle(dissect_wlancap, proto_wlancap);
657 dissector_add_uint("wtap_encap", WTAP_ENCAP_IEEE_802_11_WLAN_AVS,
659 proto_register_subtree_array(tree_array, array_length(tree_array));
662 void proto_reg_handoff_ieee80211_wlancap(void)
664 ieee80211_handle = find_dissector("wlan");
673 * indent-tabs-mode: nil
676 * ex: set shiftwidth=2 tabstop=8 expandtab:
677 * :indentSize=2:tabSize=8:noTabs=true: