/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 | | */ |