Coverage Report

Created: 2025-08-04 07:15

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