1 /* packet-ieee80211-wlancap.c
2  * Routines for AVS linux-wlan monitoring mode header dissection
3  *
4  * Wireshark - Network traffic analyzer
5  * By Gerald Combs <gerald@wireshark.org>
6  * Copyright 1998 Gerald Combs
7  *
8  * Copied from README.developer
9  *
10  * SPDX-License-Identifier: GPL-2.0-or-later
11  */
12 
13 #include "config.h"
14 
15 #include <epan/packet.h>
16 #include <epan/capture_dissectors.h>
17 #include <wiretap/wtap.h>
18 #include <wsutil/pint.h>
19 #include <wsutil/802_11-utils.h>
20 
21 #include "packet-ieee80211.h"
22 
23 /*
24  * See
25  *
26  *    https://web.archive.org/web/20040803232023/http://www.shaftnet.org/~pizza/software/capturefrm.txt
27  *
28  * for the format of the header.
29  */
30 void proto_register_ieee80211_wlancap(void);
31 void proto_reg_handoff_ieee80211_wlancap(void);
32 
33 static dissector_handle_t ieee80211_radio_handle;
34 
35 static int proto_wlancap = -1;
36 
37 /* AVS WLANCAP radio header */
38 static int hf_wlancap_magic = -1;
39 static int hf_wlancap_version = -1;
40 static int hf_wlancap_length = -1;
41 static int hf_wlancap_mactime = -1;
42 static int hf_wlancap_hosttime = -1;
43 static int hf_wlancap_phytype = -1;
44 static int hf_wlancap_hop_set = -1;
45 static int hf_wlancap_hop_pattern = -1;
46 static int hf_wlancap_hop_index = -1;
47 static int hf_wlancap_channel = -1;
48 static int hf_wlancap_channel_frequency = -1;
49 static int hf_wlancap_data_rate = -1;
50 static int hf_wlancap_antenna = -1;
51 static int hf_wlancap_priority = -1;
52 static int hf_wlancap_ssi_type = -1;
53 static int hf_wlancap_normrssi_antsignal = -1;
54 static int hf_wlancap_dbm_antsignal = -1;
55 static int hf_wlancap_rawrssi_antsignal = -1;
56 static int hf_wlancap_normrssi_antnoise = -1;
57 static int hf_wlancap_dbm_antnoise = -1;
58 static int hf_wlancap_rawrssi_antnoise = -1;
59 static int hf_wlancap_preamble = -1;
60 static int hf_wlancap_encoding = -1;
61 static int hf_wlancap_sequence = -1;
62 static int hf_wlancap_drops = -1;
63 static int hf_wlancap_receiver_addr = -1;
64 static int hf_wlancap_padding = -1;
65 
66 static gint ett_wlancap = -1;
67 
68 static dissector_handle_t wlancap_handle;
69 static capture_dissector_handle_t wlancap_cap_handle;
70 static capture_dissector_handle_t ieee80211_cap_handle;
71 
72 static gboolean
73 capture_wlancap(const guchar *pd, int offset, int len, capture_packet_info_t *cpinfo, const union wtap_pseudo_header *pseudo_header _U_)
74 {
75   guint32 length;
76 
77   if (!BYTES_ARE_IN_FRAME(offset, len, sizeof(guint32)*2))
78     return FALSE;
79 
80   length = pntoh32(pd+sizeof(guint32));
81 
82   if (!BYTES_ARE_IN_FRAME(offset, len, length))
83     return FALSE;
84 
85   offset += length;
86 
87   /* 802.11 header follows */
88   return call_capture_dissector(ieee80211_cap_handle, pd, offset, len, cpinfo, pseudo_header);
89 }
90 
91 /*
92  * AVS linux-wlan-based products use a new sniff header to replace the
93  * old Prism header.  This one has additional fields, is designed to be
94  * non-hardware-specific, and more importantly, version and length fields
95  * so it can be extended later without breaking anything.
96  *
97  * Support by Solomon Peachy
98  *
99  * Description, from the capturefrm.txt file in the linux-wlan-ng 0.2.9
100  * release (linux-wlan-ng-0.2.9/doc/capturefrm.txt):
101  *
102 AVS Capture Frame Format
103 Version 2.1.1
104 
105 1. Introduction
106 The original header format for "monitor mode" or capturing frames was
107 a considerable hack.  The document covers a redesign of that format.
108 
109   Any questions, corrections, or proposed changes go to info@linux-wlan.com
110 
111 2. Frame Format
112 All sniff frames follow the same format:
113 
114         Offset  Name            Size            Description
115         --------------------------------------------------------------------
116         0       CaptureHeader                   AVS capture metadata header
117         64      802.11Header    [10-30]         802.11 frame header
118         ??      802.11Payload   [0-2312]        802.11 frame payload
119         ??      802.11FCS       4               802.11 frame check sequence
120 
121 Note that the header and payload are variable length and the payload
122 may be empty.
123 
124 If the hardware does not supply the FCS to the driver, then the frame shall
125 have a FCS of 0xFFFFFFFF.
126 
127 3. Byte Order
128 All multibyte fields of the capture header are in "network" byte
129 order.  The "host to network" and "network to host" functions should
130 work just fine.  All the remaining multibyte fields are ordered
131 according to their respective standards.
132 
133 4. Capture Header Format
134 The following fields make up the AVS capture header:
135 
136         Offset  Name            Type
137         ------------------------------
138         0       version         uint32
139         4       length          uint32
140         8       mactime         uint64
141         16      hosttime        uint64
142         24      phytype         uint32
143         28      frequency       uint32
144         32      datarate        uint32
145         36      antenna         uint32
146         40      priority        uint32
147         44      ssi_type        uint32
148         48      ssi_signal      int32
149         52      ssi_noise       int32
150         56      preamble        uint32
151         60      encoding        uint32
152         64      sequence        uint32
153         68      drops           uint32
154         72      receiver_addr   uint8[6]
155         78      padding         uint8[2]
156         ------------------------------
157         80
158 
159 The following subsections detail the fields of the capture header.
160 
161 4.1 version
162 The version field identifies this type of frame as a subtype of
163 ETH_P_802111_CAPTURE as received by an ARPHRD_IEEE80211_PRISM or
164 an ARPHRD_IEEE80211_CAPTURE device.  The value of this field shall be
165 0x80211002.  As new revisions of this header are necessary, we can
166 increment the version appropriately.
167 
168 4.2 length
169 The length field contains the length of the entire AVS capture header,
170 in bytes.
171 
172 4.3 mactime
173 Many WLAN devices supply a relatively high resolution frame reception
174 time value.  This field contains the value supplied by the device.  If
175 the device does not supply a receive time value, this field shall be
176 set to zero.  The units for this field are microseconds.
177 
178 If possible, this time value should be absolute, representing the number
179 of microseconds elapsed since the UNIX epoch.
180 
181 4.4 hosttime
182 The hosttime field is set to the current value of the host maintained
183 clock variable when the frame is received by the host.
184 
185 If possible, this time value should be absolute, representing the number
186 of microseconds elapsed since the UNIX epoch.
187 
188 4.5 phytype
189 The phytype field identifies what type of PHY is employed by the WLAN
190 device used to capture this frame.  The valid values are:
191 
192         PhyType                         Value
193         -------------------------------------
194         phytype_fhss_dot11_97            1
195         phytype_dsss_dot11_97            2
196         phytype_irbaseband               3
197         phytype_dsss_dot11_b             4
198         phytype_pbcc_dot11_b             5
199         phytype_ofdm_dot11_g             6
200         phytype_pbcc_dot11_g             7
201         phytype_ofdm_dot11_a             8
202         phytype_dss_ofdm_dot11_g         9
203 
204 4.6 frequency
205 
206 This represents the frequency or channel number of the receiver at the
207 time the frame was received.  It is interpreted as follows:
208 
209 For frequency hopping radios, this field is broken in to the
210 following subfields:
211 
212         Byte    Subfield
213         ------------------------
214         Byte0   Hop Set
215         Byte1   Hop Pattern
216         Byte2   Hop Index
217         Byte3   reserved
218 
219 For non-hopping radios, the frequency is interpreted as follows:
220 
221        Value                Meaning
222     -----------------------------------------
223        < 256           Channel number (using externally-defined
224                          channelization)
225        < 10000         Center frequency, in MHz
226       >= 10000         Center frequency, in KHz
227 
228 4.7 datarate
229 The data rate field contains the rate at which the frame was received
230 in units of 100kbps.
231 
232 4.8 antenna
233 For WLAN devices that indicate the receive antenna for each frame, the
234 antenna field shall contain an index value into the dot11AntennaList.
235 If the device does not indicate a receive antenna value, this field
236 shall be set to zero.
237 
238 4.9 priority
239 The priority field indicates the receive priority of the frame.  The
240 value is in the range [0-15] with the value 0 reserved to indicate
241 contention period and the value 6 reserved to indicate contention free
242 period.
243 
244 4.10 ssi_type
245 The ssi_type field is used to indicate what type of signal strength
246 information is present: "None", "Normalized RSSI" or "dBm".  "None"
247 indicates that the underlying WLAN device does not supply any signal
248 strength at all and the ssi_* values are unset.  "Normalized RSSI"
249 values are integers in the range [0-1000] where higher numbers
250 indicate stronger signal.  "dBm" values indicate an actual signal
251 strength measurement quantity and are usually in the range [-108 - 10].
252 The following values indicate the three types:
253 
254         Value   Description
255         ---------------------------------------------
256         0       None
257         1       Normalized RSSI
258         2       dBm
259         3       Raw RSSI
260 
261 4.11 ssi_signal
262 The ssi_signal field contains the signal strength value reported by
263 the WLAN device for this frame.  Note that this is a signed quantity
264 and if the ssi_type value is "dBm" that the value may be negative.
265 
266 4.12 ssi_noise
267 The ssi_noise field contains the noise or "silence" value reported by
268 the WLAN device.  This value is commonly defined to be the "signal
269 strength reported immediately prior to the baseband processor lock on
270 the frame preamble".  If the hardware does not provide noise data, this
271 shall equal 0xffffffff.
272 
273 4.12 preamble
274 For PHYs that support variable preamble lengths, the preamble field
275 indicates the preamble type used for this frame.  The values are:
276 
277         Value   Description
278         ---------------------------------------------
279         0       Undefined
280         1       Short Preamble
281         2       Long Preamble
282 
283 4.13 encoding
284 This specifies the encoding of the received packet.  For PHYs that support
285 multiple encoding types, this will tell us which one was used.
286 
287         Value   Description
288         ---------------------------------------------
289         0       Unknown
290         1       CCK
291         2       PBCC
292         3       OFDM
293         4       DSSS-OFDM
294         5       BPSK
295         6       QPSK
296         7       16QAM
297         8       64QAM
298 
299 4.14 sequence
300 This is a receive frame sequence counter.  The sniff host shall
301 increment this by one for every valid frame received off the medium.
302 By watching for gaps in the sequence numbers we can determine when
303 packets are lost due to unreliable transport, rather than a frame never
304 being received to begin with.
305 
306 4.15 drops
307 This is a counter of the number of known frame drops that occurred.  This
308 is particularly useful when the system or hardware cannot keep up with
309 the sniffer load.
310 
311 4.16 receiver_addr
312 This specifies the MAC address of the receiver of this frame.
313 It is six octets in length.  This field is followed by two octets of
314 padding to keep the structure 32-bit word aligned.
315 
316 ================================
317 
318 Changes: v2->v2.1
319 
320  * Added contact e-mail address to introduction
321  * Added sniffer_addr, drop count, and sequence fields, bringing total
322    length to 80 bytes
323  * Bumped version to 0x80211002
324  * Mactime is specified in microseconds, not nanoseconds
325  * Added 64QAM, 16QAM, BPSK, QPSK encodings
326 
327 ================================
328 
329 Changes: v2.1->v2.1.1
330 
331  * Renamed 'channel' to 'frequency'
332  * Clarified the interpretation of the frequency/channel field.
333  * Renamed 'sniffer address' to 'receiver address'
334  * Clarified timestamp fields.
335  */
336 
337 /*
338  * Signal/noise strength type values.
339  */
340 #define SSI_NONE        0       /* no SSI information */
341 #define SSI_NORM_RSSI   1       /* normalized RSSI - 0-1000 */
342 #define SSI_DBM         2       /* dBm */
343 #define SSI_RAW_RSSI    3       /* raw RSSI from the hardware */
344 
345 static int
346 dissect_wlancap(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
347 {
348     proto_tree *wlan_tree = NULL;
349     proto_item *ti;
350     tvbuff_t *next_tvb;
351     int offset;
352     guint32 version;
353     guint32 length;
354     guint32 channel;
355     guint   frequency;
356     gint    calc_channel;
357     guint32 datarate;
358     guint32 ssi_type;
359     gint32  dbm;
360     guint32 antnoise;
361     struct ieee_802_11_phdr phdr;
362 
363     /* We don't have any 802.11 metadata yet. */
364     memset(&phdr, 0, sizeof(phdr));
365     phdr.fcs_len = -1;
366     phdr.decrypted = FALSE;
367     phdr.datapad = FALSE;
368     phdr.phy = PHDR_802_11_PHY_UNKNOWN;
369 
370     col_set_str(pinfo->cinfo, COL_PROTOCOL, "WLAN");
371     col_clear(pinfo->cinfo, COL_INFO);
372     offset = 0;
373 
374     version = tvb_get_ntohl(tvb, offset) - WLANCAP_MAGIC_COOKIE_BASE;
375 
376     length = tvb_get_ntohl(tvb, offset+4);
377 
378     col_add_fstr(pinfo->cinfo, COL_INFO, "AVS WLAN Capture v%x, Length %d",version, length);
379 
380     if (version > 2) {
381       goto skip;
382     }
383 
384     /* Dissect the AVS header */
385     if (tree) {
386       ti = proto_tree_add_item(tree, proto_wlancap, tvb, 0, length, ENC_NA);
387       wlan_tree = proto_item_add_subtree(ti, ett_wlancap);
388       proto_tree_add_item(wlan_tree, hf_wlancap_magic, tvb, offset, 4, ENC_BIG_ENDIAN);
389       proto_tree_add_item(wlan_tree, hf_wlancap_version, tvb, offset, 4, ENC_BIG_ENDIAN);
390     }
391     offset+=4;
392     if (tree)
393       proto_tree_add_item(wlan_tree, hf_wlancap_length, tvb, offset, 4, ENC_BIG_ENDIAN);
394     offset+=4;
395     phdr.has_tsf_timestamp = TRUE;
396     phdr.tsf_timestamp = tvb_get_ntoh64(tvb, offset);
397     if (tree)
398       proto_tree_add_item(wlan_tree, hf_wlancap_mactime, tvb, offset, 8, ENC_BIG_ENDIAN);
399     offset+=8;
400     if (tree)
401       proto_tree_add_item(wlan_tree, hf_wlancap_hosttime, tvb, offset, 8, ENC_BIG_ENDIAN);
402     offset+=8;
403     switch (tvb_get_ntohl(tvb, offset)) {
404 
405     case 1:
406         phdr.phy = PHDR_802_11_PHY_11_FHSS;
407         break;
408 
409     case 2:
410         phdr.phy = PHDR_802_11_PHY_11_DSSS;
411         break;
412 
413     case 3:
414         phdr.phy = PHDR_802_11_PHY_11_IR;
415         break;
416 
417     case 4:
418         phdr.phy = PHDR_802_11_PHY_11B;
419         break;
420 
421     case 5:
422         /* 11b PBCC? */
423         phdr.phy = PHDR_802_11_PHY_11B;
424         break;
425 
426     case 6:
427         phdr.phy = PHDR_802_11_PHY_11G; /* pure? */
428         break;
429 
430     case 7:
431         /* 11a PBCC? */
432         phdr.phy = PHDR_802_11_PHY_11A;
433         break;
434 
435     case 8:
436         phdr.phy = PHDR_802_11_PHY_11A;
437         break;
438 
439     case 9:
440         phdr.phy = PHDR_802_11_PHY_11G; /* mixed? */
441         break;
442     }
443     if (tree)
444       proto_tree_add_item(wlan_tree, hf_wlancap_phytype, tvb, offset, 4, ENC_BIG_ENDIAN);
445     offset+=4;
446 
447     if (phdr.phy == PHDR_802_11_PHY_11_FHSS) {
448       phdr.phy_info.info_11_fhss.has_hop_set = TRUE;
449       phdr.phy_info.info_11_fhss.hop_set = tvb_get_guint8(tvb, offset);
450       if (tree)
451         proto_tree_add_item(wlan_tree, hf_wlancap_hop_set, tvb, offset, 1, ENC_NA);
452       phdr.phy_info.info_11_fhss.has_hop_pattern = TRUE;
453       phdr.phy_info.info_11_fhss.hop_pattern = tvb_get_guint8(tvb, offset + 1);
454       if (tree)
455         proto_tree_add_item(wlan_tree, hf_wlancap_hop_pattern, tvb, offset + 1, 1, ENC_NA);
456       phdr.phy_info.info_11_fhss.has_hop_index = TRUE;
457       phdr.phy_info.info_11_fhss.hop_index = tvb_get_guint8(tvb, offset + 2);
458       if (tree)
459         proto_tree_add_item(wlan_tree, hf_wlancap_hop_index, tvb, offset + 2, 1, ENC_NA);
460     } else {
461       channel = tvb_get_ntohl(tvb, offset);
462       if (channel < 256) {
463         col_add_fstr(pinfo->cinfo, COL_FREQ_CHAN, "%u", channel);
464         phdr.has_channel = TRUE;
465         phdr.channel = channel;
466         if (tree)
467           proto_tree_add_uint(wlan_tree, hf_wlancap_channel, tvb, offset, 4, channel);
468         frequency = ieee80211_chan_to_mhz(channel, (phdr.phy != PHDR_802_11_PHY_11A));
469         if (frequency != 0) {
470           phdr.has_frequency = TRUE;
471           phdr.frequency = frequency;
472         }
473       } else if (channel < 10000) {
474         col_add_fstr(pinfo->cinfo, COL_FREQ_CHAN, "%u MHz", channel);
475         phdr.has_frequency = TRUE;
476         phdr.frequency = channel;
477         if (tree)
478           proto_tree_add_uint_format(wlan_tree, hf_wlancap_channel_frequency, tvb, offset,
479                                      4, channel, "Frequency: %u MHz", channel);
480         calc_channel = ieee80211_mhz_to_chan(channel);
481         if (calc_channel != -1) {
482           phdr.has_channel = TRUE;
483           phdr.channel = calc_channel;
484         }
485       } else {
486         col_add_fstr(pinfo->cinfo, COL_FREQ_CHAN, "%u KHz", channel);
487         if (tree)
488           proto_tree_add_uint_format(wlan_tree, hf_wlancap_channel_frequency, tvb, offset,
489                                      4, channel, "Frequency: %u KHz", channel);
490       }
491     }
492     offset+=4;
493 
494     datarate = tvb_get_ntohl(tvb, offset);
495     if (datarate < 100000) {
496       /* In units of 100 Kb/s; convert to b/s */
497       datarate *= 100000;
498     }
499 
500     col_add_fstr(pinfo->cinfo, COL_TX_RATE, "%u.%u",
501                    datarate / 1000000,
502                    ((datarate % 1000000) > 500000) ? 5 : 0);
503     if (datarate != 0) {
504       /* 0 is obviously bogus; it may be used for "unknown" */
505       /* Can this be expressed in .5 MHz units? */
506       if ((datarate % 500000) == 0) {
507         /* Yes. */
508         phdr.has_data_rate = TRUE;
509         phdr.data_rate = datarate / 500000;
510       }
511     }
512     if (tree) {
513       proto_tree_add_uint64_format_value(wlan_tree, hf_wlancap_data_rate, tvb, offset, 4,
514                                    datarate,
515                                    "%u.%u Mb/s",
516                                    datarate/1000000,
517                                    ((datarate % 1000000) > 500000) ? 5 : 0);
518     }
519     offset+=4;
520 
521     /*
522      * The phytype field in the header "identifies what type of PHY
523      * is employed by the WLAN device used to capture this frame";
524      * in at least one capture, it's phytype_ofdm_dot11_g for frames
525      * received using DSSS, so it may be usable to identify the
526      * type of PHY being used (except that "ofdm" isn't correct, as
527      * 11g supports both DSSS and OFDM), but it cannot be used to
528      * determine the modulation with which the packet was transmitted.
529      *
530      * The encoding field "specifies the encoding of the received packet".
531      * At least one capture using the AVS header specifies CCK for at
532      * least one frame with a 1 Mb/s data rate, which is technically
533      * incorrect (CCK is used only for 5.5 and 11 Mb/s DSSS packets) and
534      * it also specifies it for at least one frame with a 54 Mb/s data
535      * rate, which is *very* wrong (that's OFDM, not DSSS, and CCK is
536      * only used with DSSS), so that field cannot be trusted to indicate
537      * the modulation with which the packet was transmitted.
538      *
539      * We want an indication of how the frame was received, so, if we
540      * have the data rate for a purportedly 11g-OFDM packet, we use
541      * that to determine whether it's 11g-OFDM or 11g/11b-DSSS.
542      */
543     if (phdr.phy == PHDR_802_11_PHY_11G && phdr.has_data_rate) {
544       if (RATE_IS_DSSS(phdr.data_rate)) {
545         /* Presumably 11g using DSSS; we report that as 11b. */
546         phdr.phy = PHDR_802_11_PHY_11B;
547       }
548     }
549 
550     if (tree)
551       proto_tree_add_item(wlan_tree, hf_wlancap_antenna, tvb, offset, 4, ENC_BIG_ENDIAN);
552     offset+=4;
553 
554     if (tree)
555       proto_tree_add_item(wlan_tree, hf_wlancap_priority, tvb, offset, 4, ENC_BIG_ENDIAN);
556     offset+=4;
557 
558     ssi_type = tvb_get_ntohl(tvb, offset);
559     if (tree)
560       proto_tree_add_uint(wlan_tree, hf_wlancap_ssi_type, tvb, offset, 4, ssi_type);
561     offset+=4;
562     switch (ssi_type) {
563 
564     case SSI_NONE:
565     default:
566       /* either there is no SSI information, or we don't know what type it is */
567       break;
568 
569     case SSI_NORM_RSSI:
570       /* Normalized RSSI */
571       col_add_fstr(pinfo->cinfo, COL_RSSI, "%u (norm)", tvb_get_ntohl(tvb, offset));
572       if (tree)
573         proto_tree_add_item(wlan_tree, hf_wlancap_normrssi_antsignal, tvb, offset, 4, ENC_BIG_ENDIAN);
574       break;
575 
576     case SSI_DBM:
577       /* dBm */
578       dbm = tvb_get_ntohl(tvb, offset);
579       phdr.has_signal_dbm = TRUE;
580       phdr.signal_dbm = dbm;
581       col_add_fstr(pinfo->cinfo, COL_RSSI, "%d dBm", dbm);
582       if (tree)
583         proto_tree_add_item(wlan_tree, hf_wlancap_dbm_antsignal, tvb, offset, 4, ENC_BIG_ENDIAN);
584       break;
585 
586     case SSI_RAW_RSSI:
587       /* Raw RSSI */
588       col_add_fstr(pinfo->cinfo, COL_RSSI, "%u (raw)", tvb_get_ntohl(tvb, offset));
589       if (tree)
590         proto_tree_add_item(wlan_tree, hf_wlancap_rawrssi_antsignal, tvb, offset, 4, ENC_BIG_ENDIAN);
591       break;
592     }
593     offset+=4;
594 
595     antnoise = tvb_get_ntohl(tvb, offset);
596     /* 0xffffffff means "hardware does not provide noise data" */
597     if (antnoise != 0xffffffff) {
598       switch (ssi_type) {
599 
600       case SSI_NONE:
601       default:
602         /* either there is no SSI information, or we don't know what type it is */
603         break;
604 
605       case SSI_NORM_RSSI:
606         /* Normalized RSSI */
607         if (tree)
608           proto_tree_add_uint(wlan_tree, hf_wlancap_normrssi_antnoise, tvb, offset, 4, antnoise);
609         break;
610 
611       case SSI_DBM:
612         /* dBm */
613         if (antnoise != 0) {
614           /* The spec says use 0xffffffff, but some drivers appear to use 0. */
615           phdr.has_noise_dbm = TRUE;
616           phdr.noise_dbm = antnoise;
617         }
618         if (tree)
619           proto_tree_add_int(wlan_tree, hf_wlancap_dbm_antnoise, tvb, offset, 4, antnoise);
620         break;
621 
622       case SSI_RAW_RSSI:
623         /* Raw RSSI */
624         if (tree)
625           proto_tree_add_uint(wlan_tree, hf_wlancap_rawrssi_antnoise, tvb, offset, 4, antnoise);
626         break;
627       }
628     }
629     offset+=4;
630 
631     /*
632      * This only applies to packets received as DSSS (1b/11g-DSSS).
633      */
634     if (phdr.phy == PHDR_802_11_PHY_11B) {
635       switch (tvb_get_ntohl(tvb, offset)) {
636 
637       case 0:
638         /* Undefined, so we don't know if there's a short preamble */
639         phdr.phy_info.info_11b.has_short_preamble = FALSE;
640         break;
641 
642       case 1:
643         /* Short preamble. */
644         phdr.phy_info.info_11b.has_short_preamble = TRUE;
645         phdr.phy_info.info_11b.short_preamble = TRUE;
646         break;
647 
648       case 2:
649         /* Long preamble. */
650         phdr.phy_info.info_11b.has_short_preamble = TRUE;
651         phdr.phy_info.info_11b.short_preamble = FALSE;
652         break;
653 
654       default:
655         /* Invalid, so we don't know if there's a short preamble. */
656         phdr.phy_info.info_11b.has_short_preamble = FALSE;
657         break;
658       }
659     }
660     if (tree)
661       proto_tree_add_item(wlan_tree, hf_wlancap_preamble, tvb, offset, 4, ENC_BIG_ENDIAN);
662     offset+=4;
663 
664     if (tree)
665       proto_tree_add_item(wlan_tree, hf_wlancap_encoding, tvb, offset, 4, ENC_BIG_ENDIAN);
666     offset+=4;
667 
668     if (version > 1) {
669       if (tree)
670         proto_tree_add_item(wlan_tree, hf_wlancap_sequence, tvb, offset, 4, ENC_BIG_ENDIAN);
671       offset+=4;
672 
673       if (tree)
674         proto_tree_add_item(wlan_tree, hf_wlancap_drops, tvb, offset, 4, ENC_BIG_ENDIAN);
675       offset+=4;
676 
677       if (tree)
678         proto_tree_add_item(wlan_tree, hf_wlancap_receiver_addr, tvb, offset, 6, ENC_NA);
679       offset+=6;
680 
681       if (tree)
682         proto_tree_add_item(wlan_tree, hf_wlancap_padding, tvb, offset, 2, ENC_NA);
683       /*offset+=2;*/
684     }
685 
686 
687  skip:
688     offset = length;
689 
690     /* dissect the 802.11 header next */
691     next_tvb = tvb_new_subset_remaining(tvb, offset);
692     call_dissector_with_data(ieee80211_radio_handle, next_tvb, pinfo, tree, (void *)&phdr);
693     return tvb_captured_length(tvb);
694 }
695 
696 static const value_string phy_type[] = {
697     { 0, "Unknown" },
698     { 1, "FHSS 802.11 '97" },
699     { 2, "DSSS 802.11 '97" },
700     { 3, "IR Baseband" },
701     { 4, "DSSS 802.11b" },
702     { 5, "PBCC 802.11b" },
703     { 6, "OFDM 802.11g" },
704     { 7, "PBCC 802.11g" },
705     { 8, "OFDM 802.11a" },
706     { 0, NULL }
707 };
708 
709 static const value_string encoding_type[] = {
710     { 0, "Unknown" },
711     { 1, "CCK" },
712     { 2, "PBCC" },
713     { 3, "OFDM" },
714     { 4, "DSS-OFDM" },
715     { 5, "BPSK" },
716     { 6, "QPSK" },
717     { 7, "16QAM" },
718     { 8, "64QAM" },
719     { 0, NULL }
720 };
721 
722 static const value_string ssi_type[] = {
723     { SSI_NONE, "None" },
724     { SSI_NORM_RSSI, "Normalized RSSI" },
725     { SSI_DBM, "dBm" },
726     { SSI_RAW_RSSI, "Raw RSSI" },
727     { 0, NULL }
728 };
729 
730 static const value_string preamble_type[] = {
731     { 0, "Unknown" },
732     { 1, "Short" },
733     { 2, "Long" },
734     { 0, NULL }
735 };
736 
737 static hf_register_info hf_wlancap[] = {
738     {&hf_wlancap_magic,
739      {"Header magic", "wlancap.magic", FT_UINT32, BASE_HEX, NULL, 0xFFFFFFF0,
740       NULL, HFILL }},
741 
742     {&hf_wlancap_version,
743      {"Header revision", "wlancap.version", FT_UINT32, BASE_DEC, NULL, 0xF,
744       NULL, HFILL }},
745 
746     {&hf_wlancap_length,
747      {"Header length", "wlancap.length", FT_UINT32, BASE_DEC, NULL, 0x0,
748       NULL, HFILL }},
749 
750     {&hf_wlancap_mactime,
751      {"MAC timestamp", "wlancap.mactime", FT_UINT64, BASE_DEC, NULL, 0x0,
752       "Value in microseconds of the MAC's Time Synchronization Function timer when the first bit of the MPDU arrived at the MAC", HFILL }},
753 
754     {&hf_wlancap_hosttime,
755      {"Host timestamp", "wlancap.hosttime", FT_UINT64, BASE_DEC, NULL, 0x0,
756       NULL, HFILL }},
757 
758     {&hf_wlancap_phytype,
759      {"PHY type", "wlancap.phytype", FT_UINT32, BASE_DEC, VALS(phy_type), 0x0,
760       NULL, HFILL }},
761 
762     {&hf_wlancap_hop_set,
763      {"Hop set", "wlancap.fhss.hop_set", FT_UINT8, BASE_HEX, NULL, 0x0,
764       NULL, HFILL }},
765 
766     {&hf_wlancap_hop_pattern,
767      {"Hop pattern", "wlancap.fhss.hop_pattern", FT_UINT8, BASE_HEX, NULL, 0x0,
768       NULL, HFILL }},
769 
770     {&hf_wlancap_hop_index,
771      {"Hop index", "wlancap.fhss.hop_index", FT_UINT8, BASE_HEX, NULL, 0x0,
772       NULL, HFILL }},
773 
774     {&hf_wlancap_channel,
775      {"Channel", "wlancap.channel", FT_UINT8, BASE_DEC, NULL, 0x0,
776       "802.11 channel number that this frame was sent/received on", HFILL }},
777 
778     {&hf_wlancap_channel_frequency,
779      {"Channel frequency", "wlancap.channel_frequency", FT_UINT32, BASE_DEC, NULL, 0x0,
780       "Channel frequency in megahertz that this frame was sent/received on", HFILL }},
781 
782     {&hf_wlancap_data_rate,
783      {"Data Rate", "wlancap.data_rate", FT_UINT64, BASE_DEC, NULL, 0x0,
784       "Data rate (b/s)", HFILL }},
785 
786     {&hf_wlancap_antenna,
787      {"Antenna", "wlancap.antenna", FT_UINT32, BASE_DEC, NULL, 0x0,
788       "Antenna number this frame was sent/received over (starting at 0)", HFILL } },
789 
790     {&hf_wlancap_priority,
791      {"Priority", "wlancap.priority", FT_UINT32, BASE_DEC, NULL, 0x0,
792       NULL, HFILL }},
793 
794     {&hf_wlancap_ssi_type,
795      {"SSI Type", "wlancap.ssi_type", FT_UINT32, BASE_DEC, VALS(ssi_type), 0x0,
796       NULL, HFILL }},
797 
798     {&hf_wlancap_normrssi_antsignal,
799      {"Normalized RSSI Signal", "wlancap.normrssi_antsignal", FT_UINT32, BASE_DEC, NULL, 0x0,
800       "RF signal power at the antenna, normalized to the range 0-1000", HFILL }},
801 
802     {&hf_wlancap_dbm_antsignal,
803      {"SSI Signal (dBm)", "wlancap.dbm_antsignal", FT_INT32, BASE_DEC, NULL, 0x0,
804       "RF signal power at the antenna from a fixed, arbitrary value in decibels from one milliwatt", HFILL }},
805 
806     {&hf_wlancap_rawrssi_antsignal,
807      {"Raw RSSI Signal", "wlancap.rawrssi_antsignal", FT_UINT32, BASE_DEC, NULL, 0x0,
808       "RF signal power at the antenna, reported as RSSI by the adapter", HFILL }},
809 
810     {&hf_wlancap_normrssi_antnoise,
811      {"Normalized RSSI Noise", "wlancap.normrssi_antnoise", FT_UINT32, BASE_DEC, NULL, 0x0,
812       "RF noise power at the antenna, normalized to the range 0-1000", HFILL }},
813 
814     {&hf_wlancap_dbm_antnoise,
815      {"SSI Noise (dBm)", "wlancap.dbm_antnoise", FT_INT32, BASE_DEC, NULL, 0x0,
816       "RF noise power at the antenna from a fixed, arbitrary value in decibels per one milliwatt", HFILL }},
817 
818     {&hf_wlancap_rawrssi_antnoise,
819      {"Raw RSSI Noise", "wlancap.rawrssi_antnoise", FT_UINT32, BASE_DEC, NULL, 0x0,
820       "RF noise power at the antenna, reported as RSSI by the adapter", HFILL }},
821 
822     {&hf_wlancap_preamble,
823      {"Preamble", "wlancap.preamble", FT_UINT32, BASE_DEC, VALS(preamble_type), 0x0,
824       NULL, HFILL }},
825 
826     {&hf_wlancap_encoding,
827      {"Encoding Type", "wlancap.encoding", FT_UINT32, BASE_DEC, VALS(encoding_type), 0x0,
828       NULL, HFILL }},
829 
830     {&hf_wlancap_sequence,
831      {"Receive sequence", "wlancap.sequence", FT_UINT32, BASE_DEC, NULL, 0x0,
832       NULL, HFILL }},
833 
834     {&hf_wlancap_drops,
835      {"Known Dropped Frames", "wlancap.drops", FT_UINT32, BASE_DEC, NULL, 0x0,
836       NULL, HFILL }},
837 
838     {&hf_wlancap_receiver_addr,
839      {"Receiver Address", "wlancap.receiver_addr", FT_ETHER, BASE_NONE, NULL, 0x0,
840       "Receiver Hardware Address", HFILL }},
841 
842     {&hf_wlancap_padding,
843      {"Padding", "wlancap.padding", FT_BYTES, BASE_NONE, NULL, 0x0,
844       NULL, HFILL }}
845 };
846 
847 static gint *tree_array[] = {
848   &ett_wlancap
849 };
850 
851 void proto_register_ieee80211_wlancap(void)
852 {
853   proto_wlancap = proto_register_protocol("AVS WLAN Capture header",
854                                           "AVS WLANCAP", "wlancap");
855   proto_register_field_array(proto_wlancap, hf_wlancap,
856                              array_length(hf_wlancap));
857   register_dissector("wlancap", dissect_wlancap, proto_wlancap);
858 
859   wlancap_handle = create_dissector_handle(dissect_wlancap, proto_wlancap);
860   dissector_add_uint("wtap_encap", WTAP_ENCAP_IEEE_802_11_AVS,
861                      wlancap_handle);
862   proto_register_subtree_array(tree_array, array_length(tree_array));
863 
864   wlancap_cap_handle = register_capture_dissector("wlancap", capture_wlancap, proto_wlancap);
865 }
866 
867 void proto_reg_handoff_ieee80211_wlancap(void)
868 {
869   ieee80211_radio_handle = find_dissector_add_dependency("wlan_radio", proto_wlancap);
870   capture_dissector_add_uint("wtap_encap", WTAP_ENCAP_IEEE_802_11_AVS, wlancap_cap_handle);
871 
872   ieee80211_cap_handle = find_capture_dissector("ieee80211");
873 }
874 
875 /*
876  * Editor modelines
877  *
878  * Local Variables:
879  * c-basic-offset: 2
880  * tab-width: 8
881  * indent-tabs-mode: nil
882  * End:
883  *
884  * ex: set shiftwidth=2 tabstop=8 expandtab:
885  * :indentSize=2:tabSize=8:noTabs=true:
886  */
887