/src/wireshark/epan/dissectors/packet-peekremote.c
Line | Count | Source |
1 | | /* packet-peekremote.c |
2 | | * |
3 | | * Routines for the disassembly of packets sent from Cisco WLAN |
4 | | * Controllers, possibly other Cisco access points, and possibly |
5 | | * other devices such as Aruba access points. See |
6 | | * |
7 | | * https://web.archive.org/web/20130117041444/http://www.wildpackets.com/elements/omnipeek/OmniPeek_UserGuide.pdf |
8 | | * |
9 | | * which speaks of Aruba access points supporting remote capture and |
10 | | * defaulting to port 5000 for this, and also speaks of Cisco access |
11 | | * points supporting remote capture without any reference to a port |
12 | | * number. The two types of remote capture are described separately; |
13 | | * there's no indication of whether they use the same protocol for |
14 | | * streaming packets but perhaps other protocols for, for example, |
15 | | * discovery and setup, or whether they use different protocols |
16 | | * for streaming packets. |
17 | | * |
18 | | * A later manual at |
19 | | * |
20 | | * https://community.liveaction.com/wp-content/uploads/2020/02/Omnipeek-UserGuide-2-20.pdf |
21 | | * |
22 | | * speaks of Aruba and Cisco access points together, mentioning port 5000. |
23 | | * |
24 | | * Apparently Aruba supports several protocols, including Peek remote. |
25 | | * See the packet-aruba-erm dissector. |
26 | | * |
27 | | * Tested with frames captured from a Cisco WCS. |
28 | | * |
29 | | * Copyright 2007 Joerg Mayer (see AUTHORS file) |
30 | | * |
31 | | * Wireshark - Network traffic analyzer |
32 | | * By Gerald Combs <gerald@wireshark.org> |
33 | | * Copyright 1998 Gerald Combs |
34 | | * |
35 | | * SPDX-License-Identifier: GPL-2.0-or-later |
36 | | */ |
37 | | |
38 | | /* |
39 | | * TODO: Decode meta information. |
40 | | * Check on fillup bytes in capture (fcs sometimes wrong) |
41 | | * From: |
42 | | * http://www.cisco.com/univercd/cc/td/doc/product/wireless/pahcont/oweb.pdf |
43 | | * "It will include information on timestamp, signal strength, packet size |
44 | | * and so on" |
45 | | */ |
46 | | #include "config.h" |
47 | | |
48 | | #include <wiretap/wtap.h> |
49 | | |
50 | | #include <epan/packet.h> |
51 | | #include <epan/expert.h> |
52 | | #include <epan/tfs.h> |
53 | | #include <wsutil/array.h> |
54 | | #include <wsutil/802_11-utils.h> |
55 | | #include <packet-ieee80211-radiotap-defs.h> |
56 | | |
57 | 0 | #define IS_ARUBA 0x01 |
58 | | |
59 | 16 | #define PEEKREMOTE_PORT 5000 /* Not IANA registered */ |
60 | | |
61 | 6 | #define PEEKREMOTE_V3 3 |
62 | 8 | #define PEEKRMEOTE_NEW_BASE_LEN 9 |
63 | 6 | #define PEEKREMOTE_V3_HDR_LEN 13 |
64 | | |
65 | 0 | #define PEEKREMOTE_V0_6GHZ_BAND_VALID 0x08 |
66 | 0 | #define PEEKREMOTE_V0_IS_6GHZ_BAND 0x10 |
67 | | |
68 | | |
69 | | void proto_register_peekremote(void); |
70 | | void proto_reg_handoff_peekremote(void); |
71 | | |
72 | | static int proto_peekremote; |
73 | | static dissector_handle_t peekremote_handle; |
74 | | |
75 | | /* |
76 | | * XXX - we don't have all the MCS index values here. |
77 | | * We should probably just show the MCS index as a number (those |
78 | | * numbers are used in 802.11), and have separate items for the |
79 | | * number of spatial streams, the modulation type, and the coding rate. |
80 | | * Note that some modes with more than one spatial stream use *different* |
81 | | * modulation types for the different streams. See section 20.6 |
82 | | * "Parameters for HT MCSs" in 802.11-2012. |
83 | | */ |
84 | | static const value_string peekremote_mcs_index_vals[] = { |
85 | | { 0, "Spatial streams: 1, Modulation type: BPSK, Codingrate: 1/2" }, |
86 | | { 1, "Spatial streams: 1, Modulation type: QPSK, Codingrate: 1/2" }, |
87 | | { 2, "Spatial streams: 1, Modulation type: QPSK, Codingrate: 3/4" }, |
88 | | { 3, "Spatial streams: 1, Modulation type: 16-QAM, Codingrate: 1/2" }, |
89 | | { 4, "Spatial streams: 1, Modulation type: 16-QAM, Codingrate: 3/4" }, |
90 | | { 5, "Spatial streams: 1, Modulation type: 64-QAM, Codingrate: 2/3" }, |
91 | | { 6, "Spatial streams: 1, Modulation type: 64-QAM, Codingrate: 3/4" }, |
92 | | { 7, "Spatial streams: 1, Modulation type: 64-QAM, Codingrate: 5/6" }, |
93 | | { 8, "Spatial streams: 2, Modulation type: BPSK, Codingrate: 1/2" }, |
94 | | { 9, "Spatial streams: 2, Modulation type: QPSK, Codingrate: 1/2" }, |
95 | | { 10, "Spatial streams: 2, Modulation type: QPSK, Codingrate: 3/4" }, |
96 | | { 11, "Spatial streams: 2, Modulation type: 16-QAM, Codingrate: 1/2" }, |
97 | | { 12, "Spatial streams: 2, Modulation type: 16-QAM, Codingrate: 3/4" }, |
98 | | { 13, "Spatial streams: 2, Modulation type: 64-QAM, Codingrate: 2/3" }, |
99 | | { 14, "Spatial streams: 2, Modulation type: 64-QAM, Codingrate: 3/4" }, |
100 | | { 15, "Spatial streams: 2, Modulation type: 64-QAM, Codingrate: 5/6" }, |
101 | | { 16, "Spatial streams: 3, Modulation type: BPSK, Codingrate: 1/2" }, |
102 | | { 17, "Spatial streams: 3, Modulation type: QPSK, Codingrate: 1/2" }, |
103 | | { 18, "Spatial streams: 3, Modulation type: QPSK, Codingrate: 3/4" }, |
104 | | { 19, "Spatial streams: 3, Modulation type: 16-QAM, Codingrate: 1/2" }, |
105 | | { 20, "Spatial streams: 3, Modulation type: 16-QAM, Codingrate: 3/4" }, |
106 | | { 21, "Spatial streams: 3, Modulation type: 64-QAM, Codingrate: 2/3" }, |
107 | | { 22, "Spatial streams: 3, Modulation type: 64-QAM, Codingrate: 3/4" }, |
108 | | { 23, "Spatial streams: 3, Modulation type: 64-QAM, Codingrate: 5/6" }, |
109 | | { 24, "Spatial streams: 4, Modulation type: BPSK, Codingrate: 1/2" }, |
110 | | { 25, "Spatial streams: 4, Modulation type: QPSK, Codingrate: 1/2" }, |
111 | | { 26, "Spatial streams: 4, Modulation type: QPSK, Codingrate: 3/4" }, |
112 | | { 27, "Spatial streams: 4, Modulation type: 16-QAM, Codingrate: 1/2" }, |
113 | | { 28, "Spatial streams: 4, Modulation type: 16-QAM, Codingrate: 3/4" }, |
114 | | { 29, "Spatial streams: 4, Modulation type: 64-QAM, Codingrate: 2/3" }, |
115 | | { 30, "Spatial streams: 4, Modulation type: 64-QAM, Codingrate: 3/4" }, |
116 | | { 31, "Spatial streams: 4, Modulation type: 64-QAM, Codingrate: 5/6" }, |
117 | | { 0, NULL } |
118 | | }; |
119 | | |
120 | | static value_string_ext peekremote_mcs_index_vals_ext = VALUE_STRING_EXT_INIT(peekremote_mcs_index_vals); |
121 | | /* There is no reason to define a separate set of constants for HE(11ax) as it only adds a MCS 10 and 11. MCS0-9 stay the same. We could even imagine an 11ac implementation with MCS10 and 11 (nonstandard) |
122 | | * Also defining mcs rates for 11be in the same table. */ |
123 | | static const value_string peekremote_mcs_index_vals_ac[] = { |
124 | | { 0, "Modulation type: BPSK, Codingrate: 1/2" }, |
125 | | { 1, "Modulation type: QPSK, Codingrate: 1/2" }, |
126 | | { 2, "Modulation type: QPSK, Codingrate: 3/4" }, |
127 | | { 3, "Modulation type: 16-QAM, Codingrate: 1/2" }, |
128 | | { 4, "Modulation type: 16-QAM, Codingrate: 3/4" }, |
129 | | { 5, "Modulation type: 64-QAM, Codingrate: 2/3" }, |
130 | | { 6, "Modulation type: 64-QAM, Codingrate: 3/4" }, |
131 | | { 7, "Modulation type: 64-QAM, Codingrate: 5/6" }, |
132 | | { 8, "Modulation type: 256-QAM, Codingrate: 3/4" }, |
133 | | { 9, "Modulation type: 256-QAM, Codingrate: 5/6" }, |
134 | | { 10, "Modulation type: 1024-QAM, Codingrate: 3/4" }, |
135 | | { 11, "Modulation type: 1024-QAM, Codingrate: 5/6" }, |
136 | | { 12, "Modulation type: 4096-QAM, Codingrate: 3/4" }, |
137 | | { 13, "Modulation type: 4096-QAM, Codingrate: 5/6" }, |
138 | | { 14, "Modulation type: BPSK-DCM-DUP, Codingrate: 1/2" }, |
139 | | { 15, "Modulation type: BPSK-DCM, Codingrate: 1/2" }, |
140 | | { 0, NULL} |
141 | | }; |
142 | | |
143 | | |
144 | | static const value_string spatialstreams_vals[] = { |
145 | | { 0, "1" }, |
146 | | { 1, "2" }, |
147 | | { 2, "3" }, |
148 | | { 3, "4" }, |
149 | | { 4, "5" }, |
150 | | { 5, "6" }, |
151 | | { 6, "7" }, |
152 | | { 7, "8" }, |
153 | | { 0, NULL } |
154 | | }; |
155 | | |
156 | | static const value_string peekremote_type_vals[] = { |
157 | | { 6, "kMediaSpecificHdrType_Wireless3" }, |
158 | | { 0, NULL } |
159 | | }; |
160 | | |
161 | | /* |
162 | | * Extended flags. |
163 | | * |
164 | | * Some determined from bug 10637, some determined from bug 9586, |
165 | | * and the ones present in both agree, so we're assuming that |
166 | | * the "remote Peek" protocol and the "Peek tagged" file format |
167 | | * use the same bits (which wouldn't be too surprising, as they |
168 | | * both come from Wildpackets). |
169 | | */ |
170 | 16 | #define EXT_FLAG_20_MHZ_LOWER 0x00000001 |
171 | 16 | #define EXT_FLAG_20_MHZ_UPPER 0x00000002 |
172 | 16 | #define EXT_FLAG_40_MHZ 0x00000004 |
173 | | #define EXT_FLAGS_BANDWIDTH 0x00000007 |
174 | 16 | #define EXT_FLAG_HALF_GI 0x00000008 |
175 | 16 | #define EXT_FLAG_FULL_GI 0x00000010 |
176 | 0 | #define EXT_FLAGS_GI 0x00200018 |
177 | 16 | #define EXT_FLAG_AMPDU 0x00000020 |
178 | 16 | #define EXT_FLAG_AMSDU 0x00000040 |
179 | 16 | #define EXT_FLAG_802_11ac 0x00000080 |
180 | 16 | #define EXT_FLAG_MCS_INDEX_USED 0x00000100 |
181 | 16 | #define EXT_FLAG_80MHZ 0x00000200 |
182 | 16 | #define EXT_FLAG_SHORTPREAMBLE 0x00000400 |
183 | 16 | #define EXT_FLAG_SPATIALSTREAMS 0x0001C000 |
184 | 16 | #define EXT_FLAG_HEFLAG 0x00020000 |
185 | 16 | #define EXT_FLAG_160MHZ 0x00040000 |
186 | 16 | #define EXT_FLAG_EHTFLAG 0x00080000 |
187 | 16 | #define EXT_FLAG_320MHZ 0x00100000 |
188 | 16 | #define EXT_FLAG_QUARTER_GI 0x00200000 |
189 | 16 | #define EXT_FLAGS_RESERVED 0xFFC00000 |
190 | | |
191 | 0 | #define EXT_FLAG_SPATIALSTREAMS_SHIFT 14 |
192 | | |
193 | | static int hf_peekremote_band; |
194 | | static int hf_peekremote_channel; |
195 | | static int hf_peekremote_extflags; |
196 | | static int hf_peekremote_extflags_11ac; |
197 | | static int hf_peekremote_extflags_160mhz; |
198 | | static int hf_peekremote_extflags_320mhz; |
199 | | static int hf_peekremote_extflags_20mhz_lower; |
200 | | static int hf_peekremote_extflags_20mhz_upper; |
201 | | static int hf_peekremote_extflags_40mhz; |
202 | | static int hf_peekremote_extflags_80mhz; |
203 | | static int hf_peekremote_extflags_ampdu; |
204 | | static int hf_peekremote_extflags_amsdu; |
205 | | static int hf_peekremote_extflags_full_gi; |
206 | | static int hf_peekremote_extflags_future_use; |
207 | | static int hf_peekremote_extflags_half_gi; |
208 | | static int hf_peekremote_extflags_heflag; |
209 | | static int hf_peekremote_extflags_ehtflag; |
210 | | static int hf_peekremote_extflags_quarter_gi; |
211 | | static int hf_peekremote_extflags_reserved; |
212 | | static int hf_peekremote_extflags_shortpreamble; |
213 | | static int hf_peekremote_extflags_spatialstreams; |
214 | | static int hf_peekremote_flags; |
215 | | static int hf_peekremote_flags_control_frame; |
216 | | static int hf_peekremote_flags_crc_error; |
217 | | static int hf_peekremote_flags_frame_error; |
218 | | static int hf_peekremote_flags_6ghz_band_valid; |
219 | | static int hf_peekremote_flags_6ghz; |
220 | | static int hf_peekremote_flags_reserved; |
221 | | static int hf_peekremote_frequency; |
222 | | static int hf_peekremote_header_size; |
223 | | static int hf_peekremote_header_version; |
224 | | static int hf_peekremote_magic_number; |
225 | | static int hf_peekremote_mcs_index; |
226 | | static int hf_peekremote_mcs_index_ac; |
227 | | static int hf_peekremote_noise_1_dbm; |
228 | | static int hf_peekremote_noise_2_dbm; |
229 | | static int hf_peekremote_noise_3_dbm; |
230 | | static int hf_peekremote_noise_4_dbm; |
231 | | static int hf_peekremote_noise_dbm; |
232 | | static int hf_peekremote_noise_percent; |
233 | | static int hf_peekremote_packetlength; |
234 | | static int hf_peekremote_signal_1_dbm; |
235 | | static int hf_peekremote_signal_2_dbm; |
236 | | static int hf_peekremote_signal_3_dbm; |
237 | | static int hf_peekremote_signal_4_dbm; |
238 | | static int hf_peekremote_signal_dbm; |
239 | | static int hf_peekremote_signal_percent; |
240 | | static int hf_peekremote_slicelength; |
241 | | static int hf_peekremote_speed; |
242 | | static int hf_peekremote_status; |
243 | | static int hf_peekremote_status_protected; |
244 | | static int hf_peekremote_status_reserved; |
245 | | static int hf_peekremote_status_with_decrypt_error; |
246 | | static int hf_peekremote_status_with_short_preamble; |
247 | | static int hf_peekremote_timestamp; |
248 | | static int hf_peekremote_type; |
249 | | |
250 | | static expert_field ei_peekremote_unknown_header_version; |
251 | | static expert_field ei_peekremote_invalid_header_size; |
252 | | |
253 | | static int ett_peekremote; |
254 | | static int ett_peekremote_flags; |
255 | | static int ett_peekremote_status; |
256 | | static int ett_peekremote_extflags; |
257 | | |
258 | | static dissector_handle_t wlan_radio_handle; |
259 | | static dissector_handle_t radiotap_handle; |
260 | | |
261 | | static int |
262 | | dissect_peekremote_extflags(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset) |
263 | 0 | { |
264 | 0 | proto_tree *extflags_tree; |
265 | 0 | proto_item *ti_extflags, *item=NULL; |
266 | |
|
267 | 0 | uint32_t extflags = tvb_get_ntohl(tvb, offset); |
268 | |
|
269 | 0 | ti_extflags = proto_tree_add_item(tree, hf_peekremote_extflags, tvb, offset, 4, ENC_BIG_ENDIAN); |
270 | 0 | extflags_tree = proto_item_add_subtree(ti_extflags, ett_peekremote_extflags); |
271 | 0 | proto_tree_add_item(extflags_tree, hf_peekremote_extflags_20mhz_lower, tvb, offset, 4, ENC_BIG_ENDIAN); |
272 | 0 | proto_tree_add_item(extflags_tree, hf_peekremote_extflags_20mhz_upper, tvb, offset, 4, ENC_BIG_ENDIAN); |
273 | 0 | proto_tree_add_item(extflags_tree, hf_peekremote_extflags_40mhz, tvb, offset, 4, ENC_BIG_ENDIAN); |
274 | 0 | item = proto_tree_add_item(extflags_tree, hf_peekremote_extflags_half_gi, tvb, offset, 4, ENC_BIG_ENDIAN); |
275 | 0 | if ((extflags & EXT_FLAG_HEFLAG) || (extflags & EXT_FLAG_EHTFLAG)) { |
276 | 0 | proto_item_append_text(item, " (1.6uS)"); |
277 | 0 | } else { |
278 | 0 | proto_item_append_text(item, " (0.4uS)"); |
279 | 0 | } |
280 | 0 | item = proto_tree_add_item(extflags_tree, hf_peekremote_extflags_full_gi, tvb, offset, 4, ENC_BIG_ENDIAN); |
281 | 0 | if ((extflags & EXT_FLAG_HEFLAG) || (extflags & EXT_FLAG_EHTFLAG)) { |
282 | 0 | proto_item_append_text(item, " (3.2uS)"); |
283 | 0 | } else { |
284 | 0 | proto_item_append_text(item, " (0.8uS)"); |
285 | 0 | } |
286 | 0 | proto_tree_add_item(extflags_tree, hf_peekremote_extflags_ampdu, tvb, offset, 4, ENC_BIG_ENDIAN); |
287 | 0 | proto_tree_add_item(extflags_tree, hf_peekremote_extflags_amsdu, tvb, offset, 4, ENC_BIG_ENDIAN); |
288 | 0 | proto_tree_add_item(extflags_tree, hf_peekremote_extflags_11ac, tvb, offset, 4, ENC_BIG_ENDIAN); |
289 | 0 | proto_tree_add_item(extflags_tree, hf_peekremote_extflags_future_use, tvb, offset, 4, ENC_BIG_ENDIAN); |
290 | 0 | proto_tree_add_item(extflags_tree, hf_peekremote_extflags_80mhz, tvb, offset, 4, ENC_BIG_ENDIAN); |
291 | 0 | proto_tree_add_item(extflags_tree, hf_peekremote_extflags_shortpreamble, tvb, offset, 4, ENC_BIG_ENDIAN); |
292 | 0 | proto_tree_add_item(extflags_tree, hf_peekremote_extflags_spatialstreams, tvb, offset, 4, ENC_BIG_ENDIAN); |
293 | 0 | proto_tree_add_item(extflags_tree, hf_peekremote_extflags_heflag, tvb, offset, 4, ENC_BIG_ENDIAN); |
294 | 0 | proto_tree_add_item(extflags_tree, hf_peekremote_extflags_160mhz, tvb, offset, 4, ENC_BIG_ENDIAN); |
295 | 0 | proto_tree_add_item(extflags_tree, hf_peekremote_extflags_ehtflag, tvb, offset, 4, ENC_BIG_ENDIAN); |
296 | 0 | proto_tree_add_item(extflags_tree, hf_peekremote_extflags_320mhz, tvb, offset, 4, ENC_BIG_ENDIAN); |
297 | 0 | if ((extflags & EXT_FLAG_HEFLAG) || (extflags & EXT_FLAG_EHTFLAG)) { |
298 | 0 | item = proto_tree_add_item(extflags_tree, hf_peekremote_extflags_quarter_gi, tvb, offset, 4, ENC_BIG_ENDIAN); |
299 | 0 | proto_item_append_text(item, " (0.8uS)"); |
300 | 0 | } |
301 | 0 | proto_tree_add_item(extflags_tree, hf_peekremote_extflags_reserved, tvb, offset, 4, ENC_BIG_ENDIAN); |
302 | |
|
303 | 0 | return 4; |
304 | 0 | } |
305 | | |
306 | | static int |
307 | | dissect_peekremote_flags(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset) |
308 | 0 | { |
309 | 0 | proto_tree *flags_tree; |
310 | 0 | proto_item *ti_flags; |
311 | |
|
312 | 0 | ti_flags = proto_tree_add_item(tree, hf_peekremote_flags, tvb, offset, 1, ENC_NA); |
313 | 0 | flags_tree = proto_item_add_subtree(ti_flags, ett_peekremote_flags); |
314 | 0 | proto_tree_add_item(flags_tree, hf_peekremote_flags_control_frame, tvb, offset, 1, ENC_NA); |
315 | 0 | proto_tree_add_item(flags_tree, hf_peekremote_flags_crc_error, tvb, offset, 1, ENC_NA); |
316 | 0 | proto_tree_add_item(flags_tree, hf_peekremote_flags_frame_error, tvb, offset, 1, ENC_NA); |
317 | 0 | proto_tree_add_item(flags_tree, hf_peekremote_flags_6ghz_band_valid, tvb, offset, 1, ENC_NA); |
318 | 0 | proto_tree_add_item(flags_tree, hf_peekremote_flags_6ghz, tvb, offset, 1, ENC_NA); |
319 | 0 | proto_tree_add_item(flags_tree, hf_peekremote_flags_reserved, tvb, offset, 1, ENC_NA); |
320 | |
|
321 | 0 | return 1; |
322 | 0 | } |
323 | | |
324 | | static int |
325 | | dissect_peekremote_status(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset) |
326 | 0 | { |
327 | 0 | proto_tree *status_tree; |
328 | 0 | proto_item *ti_status; |
329 | |
|
330 | 0 | ti_status = proto_tree_add_item(tree, hf_peekremote_status, tvb, offset, 1, ENC_NA); |
331 | 0 | status_tree = proto_item_add_subtree(ti_status, ett_peekremote_status); |
332 | 0 | proto_tree_add_item(status_tree, hf_peekremote_status_protected, tvb, offset, 1, ENC_NA); |
333 | 0 | proto_tree_add_item(status_tree, hf_peekremote_status_with_decrypt_error, tvb, offset, 1, ENC_NA); |
334 | 0 | proto_tree_add_item(status_tree, hf_peekremote_status_with_short_preamble, tvb, offset, 1, ENC_NA); |
335 | 0 | proto_tree_add_item(status_tree, hf_peekremote_status_reserved, tvb, offset, 1, ENC_NA); |
336 | |
|
337 | 0 | return 1; |
338 | 0 | } |
339 | | |
340 | | static bool |
341 | | dissect_peekremote_new(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *u _U_) |
342 | 3.95k | { |
343 | 3.95k | static const uint8_t magic[4] = { 0x00, 0xFF, 0xAB, 0xCD }; |
344 | 3.95k | int offset = 0; |
345 | 3.95k | proto_tree *peekremote_tree = NULL; |
346 | 3.95k | proto_item *ti = NULL; |
347 | 3.95k | proto_item *ti_header_version, *ti_header_size; |
348 | 3.95k | uint8_t header_version; |
349 | 3.95k | int header_size; |
350 | 3.95k | struct ieee_802_11_phdr phdr; |
351 | 3.95k | uint32_t extflags; |
352 | 3.95k | uint16_t frequency; |
353 | 3.95k | uint16_t mcs_index; |
354 | 3.95k | uint8_t nss; |
355 | 3.95k | tvbuff_t *next_tvb; |
356 | | |
357 | 3.95k | if (tvb_memeql(tvb, 0, magic, 4) == -1) { |
358 | | /* |
359 | | * Not big enough to hold the magic number, or doesn't start |
360 | | * with the magic number. |
361 | | */ |
362 | 3.25k | return false; |
363 | 3.25k | } |
364 | | |
365 | | /* We don't have any 802.11 metadata yet. */ |
366 | 698 | memset(&phdr, 0, sizeof(phdr)); |
367 | 698 | phdr.fcs_len = 4; /* has an FCS */ |
368 | 698 | phdr.decrypted = false; |
369 | 698 | phdr.datapad = false; |
370 | 698 | phdr.phy = PHDR_802_11_PHY_UNKNOWN; |
371 | | |
372 | 698 | col_set_str(pinfo->cinfo, COL_PROTOCOL, "PEEKREMOTE"); |
373 | 698 | col_clear(pinfo->cinfo, COL_INFO); |
374 | | |
375 | 698 | ti = proto_tree_add_item(tree, proto_peekremote, tvb, 0, -1, ENC_NA); |
376 | 698 | peekremote_tree = proto_item_add_subtree(ti, ett_peekremote); |
377 | | |
378 | 698 | proto_tree_add_item(peekremote_tree, hf_peekremote_magic_number, tvb, offset, 4, ENC_BIG_ENDIAN); |
379 | 698 | offset += 4; |
380 | 698 | header_version = tvb_get_uint8(tvb, offset); |
381 | 698 | ti_header_version = proto_tree_add_uint(peekremote_tree, hf_peekremote_header_version, tvb, offset, 1, header_version); |
382 | 698 | offset += 1; |
383 | 698 | header_size = tvb_get_ntohl(tvb, offset); |
384 | 698 | ti_header_size = proto_tree_add_uint(peekremote_tree, hf_peekremote_header_size, tvb, offset, 4, header_size); |
385 | 698 | offset += 4; |
386 | 698 | switch (header_version) { |
387 | | |
388 | 11 | case 2: |
389 | 11 | if (header_size != 55) { |
390 | 11 | expert_add_info(pinfo, ti_header_size, &ei_peekremote_invalid_header_size); |
391 | 11 | if (header_size > 9) |
392 | 2 | offset += (header_size - 9); |
393 | 11 | } else { |
394 | | /* Initialize bandwidth as 20Mhz, overwrite later based on extflags, if needed*/ |
395 | 0 | int bandwidth_vht = IEEE80211_RADIOTAP_VHT_BW_20; |
396 | 0 | int bandwidth_he = IEEE80211_RADIOTAP_HE_DATA_BANDWIDTH_RU_20; |
397 | 0 | int bandwidth_eht = IEEE80211_RADIOTAP_USIG_BW_20; |
398 | |
|
399 | 0 | proto_tree_add_item(peekremote_tree, hf_peekremote_type, tvb, offset, 4, ENC_BIG_ENDIAN); |
400 | 0 | offset += 4; |
401 | 0 | mcs_index = tvb_get_ntohs(tvb, offset); |
402 | 0 | extflags = tvb_get_ntohl(tvb, offset+12); |
403 | | /* Encoded value is NSS - 1 */ |
404 | 0 | nss = ((extflags & EXT_FLAG_SPATIALSTREAMS) >> EXT_FLAG_SPATIALSTREAMS_SHIFT) + 1; |
405 | |
|
406 | 0 | if (extflags & EXT_FLAG_40_MHZ) { |
407 | 0 | bandwidth_vht = IEEE80211_RADIOTAP_VHT_BW_40; |
408 | 0 | bandwidth_he = IEEE80211_RADIOTAP_HE_DATA_BANDWIDTH_RU_40; |
409 | 0 | bandwidth_eht = IEEE80211_RADIOTAP_USIG_BW_40; |
410 | 0 | } else if (extflags & EXT_FLAG_80MHZ) { |
411 | 0 | bandwidth_vht = IEEE80211_RADIOTAP_VHT_BW_80; |
412 | 0 | bandwidth_he = IEEE80211_RADIOTAP_HE_DATA_BANDWIDTH_RU_80; |
413 | 0 | bandwidth_eht = IEEE80211_RADIOTAP_USIG_BW_80; |
414 | 0 | } else if (extflags & EXT_FLAG_160MHZ) { |
415 | 0 | bandwidth_vht = IEEE80211_RADIOTAP_VHT_BW_160; |
416 | 0 | bandwidth_he = IEEE80211_RADIOTAP_HE_DATA_BANDWIDTH_RU_160; |
417 | 0 | bandwidth_eht = IEEE80211_RADIOTAP_USIG_BW_160; |
418 | 0 | } else if (extflags & EXT_FLAG_320MHZ) { |
419 | 0 | bandwidth_eht = IEEE80211_RADIOTAP_USIG_BW_320_1; |
420 | 0 | } |
421 | |
|
422 | 0 | if (extflags & EXT_FLAG_EHTFLAG) { |
423 | 0 | proto_tree_add_item(peekremote_tree, hf_peekremote_mcs_index_ac, tvb, offset, 2, ENC_BIG_ENDIAN); |
424 | 0 | phdr.phy = PHDR_802_11_PHY_11BE; |
425 | 0 | if (extflags & EXT_FLAGS_GI) { |
426 | | /* Quarter GI : 0.8uS |
427 | | Half GI : 1.6uS |
428 | | Full GI : 3.2uS */ |
429 | 0 | phdr.phy_info.info_11be.has_gi = true; |
430 | 0 | phdr.phy_info.info_11be.gi = ((extflags & EXT_FLAG_FULL_GI) != 0) ? 2 : |
431 | 0 | ((extflags & EXT_FLAG_HALF_GI) != 0) ? 1 : |
432 | 0 | 0; |
433 | 0 | } |
434 | 0 | phdr.phy_info.info_11be.has_bandwidth = true; |
435 | 0 | phdr.phy_info.info_11be.bandwidth = bandwidth_eht; |
436 | | /* Peekremote does not have per-user fields, so fill data as if it is SU and for user0 */ |
437 | 0 | phdr.phy_info.info_11be.num_users = 1; |
438 | 0 | phdr.phy_info.info_11be.user[0].mcs_known = true; |
439 | 0 | phdr.phy_info.info_11be.user[0].mcs = mcs_index; |
440 | 0 | phdr.phy_info.info_11be.user[0].nsts_known = true; |
441 | 0 | phdr.phy_info.info_11be.user[0].nsts = nss; |
442 | |
|
443 | 0 | } else if (extflags & EXT_FLAG_HEFLAG) { |
444 | 0 | proto_tree_add_item(peekremote_tree, hf_peekremote_mcs_index_ac, tvb, offset, 2, ENC_BIG_ENDIAN); |
445 | 0 | phdr.phy = PHDR_802_11_PHY_11AX; |
446 | 0 | if (extflags & EXT_FLAGS_GI) { |
447 | | /* Quarter GI : 0.8uS |
448 | | Half GI : 1.6uS |
449 | | Full GI : 3.2uS */ |
450 | 0 | phdr.phy_info.info_11ax.has_gi = true; |
451 | 0 | phdr.phy_info.info_11ax.gi = ((extflags & EXT_FLAG_FULL_GI) != 0) ? 2 : |
452 | 0 | ((extflags & EXT_FLAG_HALF_GI) != 0) ? 1 : |
453 | 0 | 0; |
454 | 0 | } |
455 | 0 | phdr.phy_info.info_11ax.has_bwru = true; |
456 | 0 | phdr.phy_info.info_11ax.bwru = bandwidth_he; |
457 | 0 | phdr.phy_info.info_11ax.has_mcs_index = true; |
458 | 0 | phdr.phy_info.info_11ax.mcs = (uint8_t)mcs_index; |
459 | 0 | phdr.phy_info.info_11ax.nsts = nss; |
460 | |
|
461 | 0 | } else { |
462 | 0 | if (extflags & EXT_FLAG_802_11ac) { |
463 | 0 | proto_tree_add_item(peekremote_tree, hf_peekremote_mcs_index_ac, tvb, offset, 2, ENC_BIG_ENDIAN); |
464 | 0 | phdr.phy = PHDR_802_11_PHY_11AC; |
465 | 0 | if (extflags & EXT_FLAGS_GI) { |
466 | | /* Half GI : 0.4uS |
467 | | Full GI : 0.8uS */ |
468 | 0 | phdr.phy_info.info_11ac.has_short_gi = true; |
469 | 0 | phdr.phy_info.info_11ac.short_gi = ((extflags & EXT_FLAG_HALF_GI) != 0); |
470 | 0 | } |
471 | |
|
472 | 0 | phdr.phy_info.info_11ac.has_bandwidth = true; |
473 | 0 | phdr.phy_info.info_11ac.bandwidth = bandwidth_vht; |
474 | | /* Set FEC/ STBC to defaults to suppress warnings in 80211-radio dissector */ |
475 | 0 | phdr.phy_info.info_11ac.has_fec = true; |
476 | 0 | phdr.phy_info.info_11ac.fec = 0; |
477 | 0 | phdr.phy_info.info_11ac.has_stbc = true; |
478 | 0 | phdr.phy_info.info_11ac.stbc = 0; |
479 | | /* Peekremote does not have per-user fields, so fill data as if it is SU and for user0 */ |
480 | 0 | phdr.phy_info.info_11ac.mcs[0] = (uint8_t)mcs_index; |
481 | 0 | phdr.phy_info.info_11ac.nss[0] = nss; |
482 | |
|
483 | 0 | } else { /* 11n */ |
484 | 0 | proto_tree_add_item(peekremote_tree, hf_peekremote_mcs_index, tvb, offset, 2, ENC_BIG_ENDIAN); |
485 | 0 | phdr.phy = PHDR_802_11_PHY_11N; |
486 | 0 | if (extflags & EXT_FLAGS_GI) { |
487 | | /* Half GI : 0.4uS |
488 | | Full GI : 0.8uS */ |
489 | 0 | phdr.phy_info.info_11ac.has_short_gi = true; |
490 | 0 | phdr.phy_info.info_11ac.short_gi = ((extflags & EXT_FLAG_HALF_GI) != 0); |
491 | 0 | } |
492 | 0 | phdr.phy_info.info_11n.has_bandwidth = true; |
493 | 0 | if (extflags & EXT_FLAG_40_MHZ) { |
494 | 0 | phdr.phy_info.info_11n.bandwidth = IEEE80211_RADIOTAP_MCS_BW_40; |
495 | 0 | } else { |
496 | 0 | phdr.phy_info.info_11n.bandwidth = IEEE80211_RADIOTAP_MCS_BW_20; |
497 | 0 | } |
498 | | /* Set FEC/ STBC/ Greenfield to defaults to suppress warnings in 80211-radio dissector */ |
499 | 0 | phdr.phy_info.info_11n.has_fec = true; |
500 | 0 | phdr.phy_info.info_11n.fec = 0; |
501 | 0 | phdr.phy_info.info_11n.has_stbc_streams = true; |
502 | 0 | phdr.phy_info.info_11n.stbc_streams = 0; |
503 | 0 | phdr.phy_info.info_11n.has_greenfield = true; |
504 | 0 | phdr.phy_info.info_11n.greenfield = false; |
505 | 0 | phdr.phy_info.info_11n.has_ness = true; |
506 | 0 | phdr.phy_info.info_11n.ness = 0; |
507 | |
|
508 | 0 | phdr.phy_info.info_11n.has_mcs_index = true; |
509 | 0 | phdr.phy_info.info_11n.mcs_index = mcs_index; |
510 | 0 | } |
511 | 0 | } |
512 | 0 | offset += 2; |
513 | 0 | phdr.has_channel = true; |
514 | 0 | phdr.channel = tvb_get_ntohs(tvb, offset); |
515 | 0 | proto_tree_add_item(peekremote_tree, hf_peekremote_channel, tvb, offset, 2, ENC_BIG_ENDIAN); |
516 | 0 | offset += 2; |
517 | 0 | frequency = tvb_get_ntohl(tvb, offset); |
518 | 0 | if (frequency != 0) { |
519 | 0 | phdr.has_frequency = true; |
520 | 0 | phdr.frequency = frequency; |
521 | 0 | } |
522 | 0 | proto_tree_add_item(peekremote_tree, hf_peekremote_frequency, tvb, offset, 4, ENC_BIG_ENDIAN); |
523 | 0 | offset += 4; |
524 | 0 | proto_tree_add_item(peekremote_tree, hf_peekremote_band, tvb, offset, 4, ENC_BIG_ENDIAN); |
525 | 0 | offset +=4; |
526 | 0 | offset += dissect_peekremote_extflags(tvb, pinfo, peekremote_tree, offset); |
527 | 0 | phdr.has_signal_percent = true; |
528 | 0 | phdr.signal_percent = tvb_get_uint8(tvb, offset); |
529 | 0 | proto_tree_add_item(peekremote_tree, hf_peekremote_signal_percent, tvb, offset, 1, ENC_NA); |
530 | 0 | offset += 1; |
531 | 0 | phdr.has_noise_percent = true; |
532 | 0 | phdr.noise_percent = tvb_get_uint8(tvb, offset); |
533 | 0 | proto_tree_add_item(peekremote_tree, hf_peekremote_noise_percent, tvb, offset, 1, ENC_NA); |
534 | 0 | offset += 1; |
535 | 0 | phdr.has_signal_dbm = true; |
536 | 0 | phdr.signal_dbm = tvb_get_uint8(tvb, offset); |
537 | 0 | proto_tree_add_item(peekremote_tree, hf_peekremote_signal_dbm, tvb, offset, 1, ENC_NA); |
538 | 0 | offset += 1; |
539 | 0 | phdr.has_noise_dbm = true; |
540 | 0 | phdr.noise_dbm = tvb_get_uint8(tvb, offset); |
541 | 0 | proto_tree_add_item(peekremote_tree, hf_peekremote_noise_dbm, tvb, offset, 1, ENC_NA); |
542 | 0 | offset += 1; |
543 | 0 | proto_tree_add_item(peekremote_tree, hf_peekremote_signal_1_dbm, tvb, offset, 1, ENC_NA); |
544 | 0 | offset += 1; |
545 | 0 | proto_tree_add_item(peekremote_tree, hf_peekremote_signal_2_dbm, tvb, offset, 1, ENC_NA); |
546 | 0 | offset += 1; |
547 | 0 | proto_tree_add_item(peekremote_tree, hf_peekremote_signal_3_dbm, tvb, offset, 1, ENC_NA); |
548 | 0 | offset += 1; |
549 | 0 | proto_tree_add_item(peekremote_tree, hf_peekremote_signal_4_dbm, tvb, offset, 1, ENC_NA); |
550 | 0 | offset += 1; |
551 | 0 | proto_tree_add_item(peekremote_tree, hf_peekremote_noise_1_dbm, tvb, offset, 1, ENC_NA); |
552 | 0 | offset += 1; |
553 | 0 | proto_tree_add_item(peekremote_tree, hf_peekremote_noise_2_dbm, tvb, offset, 1, ENC_NA); |
554 | 0 | offset += 1; |
555 | 0 | proto_tree_add_item(peekremote_tree, hf_peekremote_noise_3_dbm, tvb, offset, 1, ENC_NA); |
556 | 0 | offset += 1; |
557 | 0 | proto_tree_add_item(peekremote_tree, hf_peekremote_noise_4_dbm, tvb, offset, 1, ENC_NA); |
558 | 0 | offset += 1; |
559 | 0 | proto_tree_add_item(peekremote_tree, hf_peekremote_packetlength, tvb, offset, 2, ENC_BIG_ENDIAN); |
560 | 0 | offset += 2; |
561 | 0 | proto_tree_add_item(peekremote_tree, hf_peekremote_slicelength, tvb, offset, 2, ENC_BIG_ENDIAN); |
562 | 0 | offset += 2; |
563 | 0 | offset += dissect_peekremote_flags(tvb, pinfo, peekremote_tree, offset); |
564 | 0 | offset += dissect_peekremote_status(tvb, pinfo, peekremote_tree, offset); |
565 | 0 | proto_tree_add_item(peekremote_tree, hf_peekremote_timestamp, tvb, offset, 8, ENC_BIG_ENDIAN); |
566 | 0 | phdr.has_tsf_timestamp = true; |
567 | 0 | phdr.tsf_timestamp = tvb_get_ntoh64(tvb, offset); |
568 | 0 | offset += 8; |
569 | 0 | } |
570 | 11 | break; |
571 | | /* With LiveAction's consent (via Issue #19533) new version Peekremote v3 encapsulation is defined as: |
572 | | * [ UDP [ PEEKREMOTE v3 [ RADIOTAP [ 80211 ]]]] |
573 | | */ |
574 | 6 | case PEEKREMOTE_V3: |
575 | 6 | if (header_size != PEEKREMOTE_V3_HDR_LEN) { |
576 | 6 | expert_add_info(pinfo, ti_header_size, &ei_peekremote_invalid_header_size); |
577 | 6 | if (header_size > PEEKRMEOTE_NEW_BASE_LEN) { |
578 | 2 | offset += (header_size - PEEKRMEOTE_NEW_BASE_LEN); |
579 | 2 | } |
580 | 6 | } else { |
581 | 0 | proto_tree_add_item(peekremote_tree, hf_peekremote_type, tvb, offset, 4, ENC_BIG_ENDIAN); |
582 | 0 | offset += 4; |
583 | 0 | proto_item_set_end(ti, tvb, offset); |
584 | 0 | next_tvb = tvb_new_subset_remaining(tvb, offset); |
585 | 0 | call_dissector(radiotap_handle, next_tvb, pinfo, tree); |
586 | 0 | return true; |
587 | 0 | } |
588 | 6 | break; |
589 | 680 | default: |
590 | 680 | expert_add_info(pinfo, ti_header_version, &ei_peekremote_unknown_header_version); |
591 | 680 | if (header_size > 9) |
592 | 31 | offset += (header_size - 9); |
593 | 680 | break; |
594 | 698 | } |
595 | | |
596 | 697 | proto_item_set_end(ti, tvb, offset); |
597 | 697 | next_tvb = tvb_new_subset_remaining(tvb, offset); |
598 | 697 | call_dissector_with_data(wlan_radio_handle, next_tvb, pinfo, tree, &phdr); |
599 | 697 | return true; |
600 | 698 | } |
601 | | |
602 | | static int |
603 | | dissect_peekremote_legacy(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data) |
604 | 0 | { |
605 | 0 | tvbuff_t *next_tvb; |
606 | 0 | proto_tree *peekremote_tree = NULL; |
607 | 0 | proto_item *ti = NULL; |
608 | 0 | struct ieee_802_11_phdr phdr; |
609 | 0 | uint8_t signal_percent; |
610 | 0 | uint8_t flags = 0; |
611 | 0 | bool is_6ghz = false; |
612 | 0 | memset(&phdr, 0, sizeof(phdr)); |
613 | | |
614 | | /* |
615 | | * Check whether this is peekremote-ng, and dissect it as such if it |
616 | | * is. |
617 | | */ |
618 | 0 | if (dissect_peekremote_new(tvb, pinfo, tree, data)) { |
619 | | /* Yup, it was peekremote-ng, and it's been dissected as such. */ |
620 | 0 | return tvb_reported_length(tvb); |
621 | 0 | } |
622 | | |
623 | 0 | col_set_str(pinfo->cinfo, COL_PROTOCOL, "PEEKREMOTE"); |
624 | 0 | col_clear(pinfo->cinfo, COL_INFO); |
625 | |
|
626 | 0 | if (tree) { |
627 | 0 | ti = proto_tree_add_item(tree, proto_peekremote, tvb, 0, -1, ENC_NA); |
628 | 0 | peekremote_tree = proto_item_add_subtree(ti, ett_peekremote); |
629 | |
|
630 | 0 | proto_tree_add_item(peekremote_tree, hf_peekremote_signal_dbm, tvb, 0, 1, ENC_NA); |
631 | 0 | proto_tree_add_item(peekremote_tree, hf_peekremote_noise_dbm, tvb, 1, 1, ENC_NA); |
632 | 0 | proto_tree_add_item(peekremote_tree, hf_peekremote_packetlength, tvb, 2, 2, ENC_BIG_ENDIAN); |
633 | 0 | proto_tree_add_item(peekremote_tree, hf_peekremote_slicelength, tvb, 4, 2, ENC_BIG_ENDIAN); |
634 | 0 | dissect_peekremote_flags(tvb, pinfo, peekremote_tree, 6); |
635 | 0 | dissect_peekremote_status(tvb, pinfo, peekremote_tree, 7); |
636 | 0 | proto_tree_add_item(peekremote_tree, hf_peekremote_timestamp, tvb, 8, 8, ENC_BIG_ENDIAN); |
637 | 0 | proto_tree_add_item(peekremote_tree, hf_peekremote_speed, tvb, 16, 1, ENC_NA); |
638 | 0 | proto_tree_add_item(peekremote_tree, hf_peekremote_channel, tvb, 17, 1, ENC_BIG_ENDIAN); |
639 | 0 | proto_tree_add_item(peekremote_tree, hf_peekremote_signal_percent, tvb, 18, 1, ENC_NA); |
640 | 0 | proto_tree_add_item(peekremote_tree, hf_peekremote_noise_percent, tvb, 19, 1, ENC_NA); |
641 | 0 | } |
642 | 0 | signal_percent = tvb_get_uint8(tvb, 18); |
643 | 0 | proto_item_set_end(ti, tvb, 20); |
644 | 0 | next_tvb = tvb_new_subset_remaining(tvb, 20); |
645 | | /* When signal = 100 % and coming from ARUBA ERM, it is TX packet and there is no FCS */ |
646 | 0 | if (GPOINTER_TO_INT(data) == IS_ARUBA && signal_percent == 100) { |
647 | 0 | phdr.fcs_len = 0; /* TX packet, no FCS */ |
648 | 0 | } else { |
649 | 0 | phdr.fcs_len = 4; /* We have an FCS */ |
650 | 0 | } |
651 | 0 | phdr.decrypted = false; |
652 | 0 | phdr.phy = PHDR_802_11_PHY_UNKNOWN; |
653 | 0 | phdr.has_channel = true; |
654 | 0 | phdr.channel = tvb_get_uint8(tvb, 17); |
655 | 0 | phdr.has_data_rate = true; |
656 | 0 | phdr.data_rate = tvb_get_uint8(tvb, 16); |
657 | 0 | phdr.has_signal_percent = true; |
658 | 0 | phdr.signal_percent = tvb_get_uint8(tvb, 18); |
659 | 0 | phdr.has_noise_percent = true; |
660 | 0 | phdr.noise_percent = tvb_get_uint8(tvb, 18); |
661 | 0 | phdr.has_signal_dbm = true; |
662 | 0 | phdr.signal_dbm = tvb_get_uint8(tvb, 0); |
663 | 0 | phdr.has_noise_dbm = true; |
664 | 0 | phdr.noise_dbm = tvb_get_uint8(tvb, 1); |
665 | 0 | phdr.has_tsf_timestamp = true; |
666 | 0 | phdr.tsf_timestamp = tvb_get_ntoh64(tvb, 8); |
667 | |
|
668 | 0 | flags = tvb_get_uint8(tvb, 6); |
669 | 0 | if (flags & PEEKREMOTE_V0_6GHZ_BAND_VALID) { |
670 | 0 | bool is_bg; |
671 | 0 | is_6ghz = flags & PEEKREMOTE_V0_IS_6GHZ_BAND; |
672 | 0 | is_bg = is_6ghz ? false : CHAN_IS_BG(phdr.channel); |
673 | 0 | phdr.has_frequency = true; |
674 | 0 | phdr.frequency = ieee80211_chan_band_to_mhz(phdr.channel, is_bg, is_6ghz); |
675 | 0 | } |
676 | | /* |
677 | | * We don't know they PHY, but we do have the data rate; |
678 | | * try to guess the PHY based on the data rate and channel. |
679 | | */ |
680 | 0 | if (RATE_IS_DSSS(phdr.data_rate)) { |
681 | | /* 11b */ |
682 | 0 | phdr.phy = PHDR_802_11_PHY_11B; |
683 | 0 | phdr.phy_info.info_11b.has_short_preamble = false; |
684 | 0 | } else if (RATE_IS_OFDM(phdr.data_rate)) { |
685 | | /* 11a or 11g, depending on the band. */ |
686 | 0 | if (CHAN_IS_BG(phdr.channel) && !is_6ghz) { |
687 | | /* 11g */ |
688 | 0 | phdr.phy = PHDR_802_11_PHY_11G; |
689 | 0 | phdr.phy_info.info_11g.has_mode = false; |
690 | 0 | } else { |
691 | | /* 11a */ |
692 | 0 | phdr.phy = PHDR_802_11_PHY_11A; |
693 | 0 | phdr.phy_info.info_11a.has_channel_type = false; |
694 | 0 | phdr.phy_info.info_11a.has_turbo_type = false; |
695 | 0 | } |
696 | 0 | } |
697 | |
|
698 | 0 | return 20 + call_dissector_with_data(wlan_radio_handle, next_tvb, pinfo, tree, &phdr); |
699 | 0 | } |
700 | | |
701 | | void |
702 | | proto_register_peekremote(void) |
703 | 16 | { |
704 | 16 | static hf_register_info hf[] = { |
705 | 16 | { &hf_peekremote_channel, |
706 | 16 | { "Channel", "peekremote.channel", |
707 | 16 | FT_UINT16, BASE_DEC, NULL, 0x0, |
708 | 16 | NULL, HFILL } |
709 | 16 | }, |
710 | 16 | { &hf_peekremote_signal_dbm, |
711 | 16 | { "Signal [dBm]", "peekremote.signal_dbm", |
712 | 16 | FT_INT8, BASE_DEC, NULL, 0x0, |
713 | 16 | NULL, HFILL } |
714 | 16 | }, |
715 | 16 | { &hf_peekremote_noise_dbm, |
716 | 16 | { "Noise [dBm]", "peekremote.noise_dbm", |
717 | 16 | FT_INT8, BASE_DEC, NULL, 0x0, |
718 | 16 | NULL, HFILL } |
719 | 16 | }, |
720 | 16 | { &hf_peekremote_packetlength, |
721 | 16 | { "Packet length", "peekremote.packetlength", |
722 | 16 | FT_UINT16, BASE_DEC, NULL, 0x0, |
723 | 16 | NULL, HFILL } |
724 | 16 | }, |
725 | 16 | { &hf_peekremote_slicelength, |
726 | 16 | { "Slice length", "peekremote.slicelength", |
727 | 16 | FT_UINT16, BASE_DEC, NULL, 0x0, |
728 | 16 | NULL, HFILL } |
729 | 16 | }, |
730 | 16 | { &hf_peekremote_flags, |
731 | 16 | { "Flags", "peekremote.flags", |
732 | 16 | FT_UINT8, BASE_HEX, NULL, 0x0, |
733 | 16 | NULL, HFILL } |
734 | 16 | }, |
735 | 16 | { &hf_peekremote_flags_control_frame, |
736 | 16 | { "Is a Control frame", "peekremote.flags.control_frame", |
737 | 16 | FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x01, |
738 | 16 | NULL, HFILL } |
739 | 16 | }, |
740 | 16 | { &hf_peekremote_flags_crc_error, |
741 | 16 | { "Has CRC error", "peekremote.flags.has_crc_error", |
742 | 16 | FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x02, |
743 | 16 | NULL, HFILL } |
744 | 16 | }, |
745 | 16 | { &hf_peekremote_flags_frame_error, |
746 | 16 | { "Has frame error", "peekremote.flags.has_frame_error", |
747 | 16 | FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x04, |
748 | 16 | NULL, HFILL } |
749 | 16 | }, |
750 | 16 | { &hf_peekremote_flags_6ghz_band_valid, |
751 | 16 | { "Is 6GHz band flag valid", "peekremote.flags.6ghzband_valid", |
752 | 16 | FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x08, |
753 | 16 | NULL, HFILL } |
754 | 16 | }, |
755 | 16 | { &hf_peekremote_flags_6ghz, |
756 | 16 | { "6GHz band", "peekremote.flags.6ghz", |
757 | 16 | FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x10, |
758 | 16 | NULL, HFILL } |
759 | 16 | }, |
760 | 16 | { &hf_peekremote_flags_reserved, |
761 | 16 | { "Reserved", "peekremote.flags.reserved", |
762 | 16 | FT_UINT8, BASE_HEX, NULL, 0xE0, |
763 | 16 | "Must be zero", HFILL } |
764 | 16 | }, |
765 | 16 | { &hf_peekremote_status, |
766 | 16 | { "Status", "peekremote.status", |
767 | 16 | FT_UINT8, BASE_HEX, NULL, 0x0, |
768 | 16 | NULL, HFILL } |
769 | 16 | }, |
770 | 16 | { &hf_peekremote_status_protected, |
771 | 16 | { "Protected", "peekremote.status.protected", |
772 | 16 | FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x04, |
773 | 16 | NULL, HFILL } |
774 | 16 | }, |
775 | 16 | { &hf_peekremote_status_with_decrypt_error, |
776 | 16 | { "With decrypt error", "peekremote.status.with_decrypt_error", |
777 | 16 | FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x08, |
778 | 16 | NULL, HFILL } |
779 | 16 | }, |
780 | 16 | { &hf_peekremote_status_with_short_preamble, |
781 | 16 | { "With short preamble", "peekremote.status.with_short_preamble", |
782 | 16 | FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x40, |
783 | 16 | NULL, HFILL } |
784 | 16 | }, |
785 | 16 | { &hf_peekremote_status_reserved, |
786 | 16 | { "Reserved", "peekremote.status.reserved", |
787 | 16 | FT_UINT8, BASE_HEX, NULL, 0xB3, |
788 | 16 | "Must be zero", HFILL } |
789 | 16 | }, |
790 | 16 | { &hf_peekremote_timestamp, |
791 | 16 | { "TSF timestamp", "peekremote.timestamp", |
792 | 16 | FT_UINT64, BASE_DEC, NULL, 0x0, |
793 | 16 | NULL, HFILL } |
794 | 16 | }, |
795 | 16 | { &hf_peekremote_mcs_index, |
796 | 16 | { "MCS index", "peekremote.mcs_index", |
797 | 16 | FT_UINT16, BASE_DEC|BASE_EXT_STRING, &peekremote_mcs_index_vals_ext, 0x0, |
798 | 16 | NULL, HFILL } |
799 | 16 | }, |
800 | 16 | { &hf_peekremote_mcs_index_ac, |
801 | 16 | { "11ac/11ax/11be MCS index", "peekremote.mcs_index_ac", |
802 | 16 | FT_UINT16, BASE_DEC, VALS(peekremote_mcs_index_vals_ac), 0x0, |
803 | 16 | NULL, HFILL } |
804 | 16 | }, |
805 | 16 | { &hf_peekremote_signal_percent, |
806 | 16 | { "Signal [percent]", "peekremote.signal_percent", |
807 | 16 | FT_UINT8, BASE_DEC, NULL, 0x0, |
808 | 16 | NULL, HFILL } |
809 | 16 | }, |
810 | 16 | { &hf_peekremote_noise_percent, |
811 | 16 | { "Noise [percent]", "peekremote.noise_percent", |
812 | 16 | FT_UINT8, BASE_DEC, NULL, 0x0, |
813 | 16 | NULL, HFILL } |
814 | 16 | }, |
815 | 16 | { &hf_peekremote_speed, |
816 | 16 | { "Data rate [500kHz]", "peekremote.data_rate", |
817 | 16 | FT_UINT8, BASE_DEC, NULL, 0x0, |
818 | 16 | NULL, HFILL } |
819 | 16 | }, |
820 | 16 | { &hf_peekremote_magic_number, |
821 | 16 | { "Magic number", "peekremote.magic_number", |
822 | 16 | FT_UINT32, BASE_HEX, NULL, 0x0, |
823 | 16 | NULL, HFILL } |
824 | 16 | }, |
825 | 16 | { &hf_peekremote_header_version, |
826 | 16 | { "Header version", "peekremote.header_version", |
827 | 16 | FT_UINT8, BASE_DEC, NULL, 0x0, |
828 | 16 | NULL, HFILL } |
829 | 16 | }, |
830 | 16 | { &hf_peekremote_header_size, |
831 | 16 | { "Header size", "peekremote.header_size", |
832 | 16 | FT_UINT32, BASE_DEC, NULL, 0x0, |
833 | 16 | NULL, HFILL } |
834 | 16 | }, |
835 | 16 | { &hf_peekremote_type, |
836 | 16 | { "Type", "peekremote.type", |
837 | 16 | FT_UINT32, BASE_DEC, VALS(peekremote_type_vals), 0x0, |
838 | 16 | NULL, HFILL } |
839 | 16 | }, |
840 | 16 | { &hf_peekremote_frequency, |
841 | 16 | { "Frequency [Mhz]", "peekremote.frequency", |
842 | 16 | FT_UINT32, BASE_DEC, NULL, 0x0, |
843 | 16 | NULL, HFILL } |
844 | 16 | }, |
845 | 16 | { &hf_peekremote_band, |
846 | 16 | { "Band", "peekremote.band", |
847 | 16 | FT_UINT32, BASE_DEC, NULL, 0x0, |
848 | 16 | NULL, HFILL } |
849 | 16 | }, |
850 | 16 | { &hf_peekremote_extflags, |
851 | 16 | { "Extended flags", "peekremote.extflags", |
852 | 16 | FT_UINT32, BASE_HEX, NULL, 0x0, |
853 | 16 | NULL, HFILL } |
854 | 16 | }, |
855 | 16 | { &hf_peekremote_extflags_20mhz_lower, |
856 | 16 | { "20 MHz Lower", "peekremote.extflags.20mhz_lower", |
857 | 16 | FT_BOOLEAN, 32, TFS(&tfs_yes_no), EXT_FLAG_20_MHZ_LOWER, |
858 | 16 | NULL, HFILL } |
859 | 16 | }, |
860 | 16 | { &hf_peekremote_extflags_20mhz_upper, |
861 | 16 | { "20 MHz Upper", "peekremote.extflags.20mhz_upper", |
862 | 16 | FT_BOOLEAN, 32, TFS(&tfs_yes_no), EXT_FLAG_20_MHZ_UPPER, |
863 | 16 | NULL, HFILL } |
864 | 16 | }, |
865 | 16 | { &hf_peekremote_extflags_40mhz, |
866 | 16 | { "40 MHz", "peekremote.extflags.40mhz", |
867 | 16 | FT_BOOLEAN, 32, TFS(&tfs_yes_no), EXT_FLAG_40_MHZ, |
868 | 16 | NULL, HFILL } |
869 | 16 | }, |
870 | 16 | { &hf_peekremote_extflags_half_gi, |
871 | 16 | { "Half Guard Interval", "peekremote.extflags.half_gi", |
872 | 16 | FT_BOOLEAN, 32, TFS(&tfs_yes_no), EXT_FLAG_HALF_GI, |
873 | 16 | NULL, HFILL } |
874 | 16 | }, |
875 | 16 | { &hf_peekremote_extflags_full_gi, |
876 | 16 | { "Full Guard Interval", "peekremote.extflags.full_gi", |
877 | 16 | FT_BOOLEAN, 32, TFS(&tfs_yes_no), EXT_FLAG_FULL_GI, |
878 | 16 | NULL, HFILL } |
879 | 16 | }, |
880 | 16 | { &hf_peekremote_extflags_ampdu, |
881 | 16 | { "AMPDU", "peekremote.extflags.ampdu", |
882 | 16 | FT_BOOLEAN, 32, TFS(&tfs_yes_no), EXT_FLAG_AMPDU, |
883 | 16 | NULL, HFILL } |
884 | 16 | }, |
885 | 16 | { &hf_peekremote_extflags_amsdu, |
886 | 16 | { "AMSDU", "peekremote.extflags.amsdu", |
887 | 16 | FT_BOOLEAN, 32, TFS(&tfs_yes_no), EXT_FLAG_AMSDU, |
888 | 16 | NULL, HFILL } |
889 | 16 | }, |
890 | 16 | { &hf_peekremote_extflags_11ac, |
891 | 16 | { "802.11ac", "peekremote.extflags.11ac", |
892 | 16 | FT_BOOLEAN, 32, TFS(&tfs_yes_no), EXT_FLAG_802_11ac, |
893 | 16 | NULL, HFILL } |
894 | 16 | }, |
895 | 16 | { &hf_peekremote_extflags_future_use, |
896 | 16 | { "MCS index used", "peekremote.extflags.future_use", |
897 | 16 | FT_BOOLEAN, 32, TFS(&tfs_yes_no), EXT_FLAG_MCS_INDEX_USED, |
898 | 16 | NULL, HFILL } |
899 | 16 | }, |
900 | 16 | { &hf_peekremote_extflags_80mhz, |
901 | 16 | { "80 Mhz", "peekremote.extflags.80mhz", |
902 | 16 | FT_BOOLEAN, 32, TFS(&tfs_yes_no), EXT_FLAG_80MHZ, |
903 | 16 | NULL, HFILL } |
904 | 16 | }, |
905 | 16 | { &hf_peekremote_extflags_shortpreamble, |
906 | 16 | { "Short preamble", "peekremote.extflags.shortpreamble", |
907 | 16 | FT_BOOLEAN, 32, TFS(&tfs_yes_no), EXT_FLAG_SHORTPREAMBLE, |
908 | 16 | NULL, HFILL } |
909 | 16 | }, |
910 | 16 | { &hf_peekremote_extflags_spatialstreams, |
911 | 16 | { "Spatial streams", "peekremote.extflags.spatialstreams", |
912 | 16 | FT_UINT32, BASE_DEC, VALS(spatialstreams_vals), EXT_FLAG_SPATIALSTREAMS, |
913 | 16 | NULL, HFILL } |
914 | 16 | }, |
915 | 16 | { &hf_peekremote_extflags_heflag, |
916 | 16 | { "802.11ax", "peekremote.extflags.11ax", |
917 | 16 | FT_BOOLEAN, 32, TFS(&tfs_yes_no), EXT_FLAG_HEFLAG, |
918 | 16 | NULL, HFILL } |
919 | 16 | }, |
920 | 16 | { &hf_peekremote_extflags_160mhz, |
921 | 16 | { "160Mhz", "peekremote.extflags.160mhz", |
922 | 16 | FT_BOOLEAN, 32, TFS(&tfs_yes_no), EXT_FLAG_160MHZ, |
923 | 16 | NULL, HFILL } |
924 | 16 | }, |
925 | 16 | { &hf_peekremote_extflags_ehtflag, |
926 | 16 | { "802.11be", "peekremote.extflags.11be", |
927 | 16 | FT_BOOLEAN, 32, TFS(&tfs_yes_no), EXT_FLAG_EHTFLAG, |
928 | 16 | NULL, HFILL } |
929 | 16 | }, |
930 | 16 | { &hf_peekremote_extflags_320mhz, |
931 | 16 | { "320Mhz", "peekremote.extflags.320mhz", |
932 | 16 | FT_BOOLEAN, 32, TFS(&tfs_yes_no), EXT_FLAG_320MHZ, |
933 | 16 | NULL, HFILL } |
934 | 16 | }, |
935 | 16 | { &hf_peekremote_extflags_quarter_gi, |
936 | 16 | { "Quarter Guard Interval", "peekremote.extflags.quarter_gi", |
937 | 16 | FT_BOOLEAN, 32, TFS(&tfs_yes_no), EXT_FLAG_QUARTER_GI, |
938 | 16 | NULL, HFILL } |
939 | 16 | }, |
940 | 16 | { &hf_peekremote_extflags_reserved, |
941 | 16 | { "Reserved", "peekremote.extflags.reserved", |
942 | 16 | FT_UINT32, BASE_HEX, NULL, EXT_FLAGS_RESERVED, |
943 | 16 | "Must be zero", HFILL } |
944 | 16 | }, |
945 | 16 | { &hf_peekremote_signal_1_dbm, |
946 | 16 | { "Signal 1 [dBm]", "peekremote.signal_1_dbm", |
947 | 16 | FT_INT8, BASE_DEC, NULL, 0x0, |
948 | 16 | NULL, HFILL } |
949 | 16 | }, |
950 | 16 | { &hf_peekremote_signal_2_dbm, |
951 | 16 | { "Signal 2 [dBm]", "peekremote.signal_2_dbm", |
952 | 16 | FT_INT8, BASE_DEC, NULL, 0x0, |
953 | 16 | NULL, HFILL } |
954 | 16 | }, |
955 | 16 | { &hf_peekremote_signal_3_dbm, |
956 | 16 | { "Signal 3 [dBm]", "peekremote.signal_3_dbm", |
957 | 16 | FT_INT8, BASE_DEC, NULL, 0x0, |
958 | 16 | NULL, HFILL } |
959 | 16 | }, |
960 | 16 | { &hf_peekremote_signal_4_dbm, |
961 | 16 | { "Signal 4 [dBm]", "peekremote.signal_4_dbm", |
962 | 16 | FT_INT8, BASE_DEC, NULL, 0x0, |
963 | 16 | NULL, HFILL } |
964 | 16 | }, |
965 | 16 | { &hf_peekremote_noise_1_dbm, |
966 | 16 | { "Noise 1 [dBm]", "peekremote.noise_1_dbm", |
967 | 16 | FT_INT8, BASE_DEC, NULL, 0x0, |
968 | 16 | NULL, HFILL } |
969 | 16 | }, |
970 | 16 | { &hf_peekremote_noise_2_dbm, |
971 | 16 | { "Noise 2 [dBm]", "peekremote.noise_2_dbm", |
972 | 16 | FT_INT8, BASE_DEC, NULL, 0x0, |
973 | 16 | NULL, HFILL } |
974 | 16 | }, |
975 | 16 | { &hf_peekremote_noise_3_dbm, |
976 | 16 | { "Noise 3 [dBm]", "peekremote.noise_3_dbm", |
977 | 16 | FT_INT8, BASE_DEC, NULL, 0x0, |
978 | 16 | NULL, HFILL } |
979 | 16 | }, |
980 | 16 | { &hf_peekremote_noise_4_dbm, |
981 | 16 | { "Noise 4 [dBm]", "peekremote.noise_4_dbm", |
982 | 16 | FT_INT8, BASE_DEC, NULL, 0x0, |
983 | 16 | NULL, HFILL } |
984 | 16 | }, |
985 | 16 | }; |
986 | 16 | static int *ett[] = { |
987 | 16 | &ett_peekremote, |
988 | 16 | &ett_peekremote_flags, |
989 | 16 | &ett_peekremote_status, |
990 | 16 | &ett_peekremote_extflags |
991 | 16 | }; |
992 | 16 | static ei_register_info ei[] = { |
993 | 16 | { &ei_peekremote_unknown_header_version, { "peekremote.unknown_header_version", PI_UNDECODED, PI_ERROR, "Unknown header version", EXPFILL }}, |
994 | 16 | { &ei_peekremote_invalid_header_size, { "peekremote.invalid_header_size", PI_UNDECODED, PI_ERROR, "Invalid header size for that header version", EXPFILL }}, |
995 | 16 | }; |
996 | 16 | expert_module_t *expert_peekremote; |
997 | | |
998 | 16 | proto_peekremote = proto_register_protocol("AiroPeek/OmniPeek encapsulated IEEE 802.11", "PEEKREMOTE", "peekremote"); |
999 | 16 | proto_register_field_array(proto_peekremote, hf, array_length(hf)); |
1000 | 16 | proto_register_subtree_array(ett, array_length(ett)); |
1001 | 16 | expert_peekremote = expert_register_protocol(proto_peekremote); |
1002 | 16 | expert_register_field_array(expert_peekremote, ei, array_length(ei)); |
1003 | | |
1004 | 16 | peekremote_handle = register_dissector("peekremote", dissect_peekremote_legacy, proto_peekremote); |
1005 | 16 | } |
1006 | | |
1007 | | void |
1008 | | proto_reg_handoff_peekremote(void) |
1009 | 16 | { |
1010 | | /* Peekremote V0/V2 */ |
1011 | 16 | wlan_radio_handle = find_dissector_add_dependency("wlan_radio", proto_peekremote); |
1012 | | /* Peekremote V3 */ |
1013 | 16 | radiotap_handle = find_dissector_add_dependency("radiotap", proto_peekremote); |
1014 | 16 | dissector_add_uint_with_preference("udp.port", PEEKREMOTE_PORT, peekremote_handle); |
1015 | | |
1016 | 16 | heur_dissector_add("udp", dissect_peekremote_new, "OmniPeek Remote over UDP", "peekremote_udp", proto_peekremote, HEURISTIC_ENABLE); |
1017 | 16 | } |
1018 | | |
1019 | | /* |
1020 | | * Editor modelines - https://www.wireshark.org/tools/modelines.html |
1021 | | * |
1022 | | * Local variables: |
1023 | | * c-basic-offset: 2 |
1024 | | * tab-width: 8 |
1025 | | * indent-tabs-mode: nil |
1026 | | * End: |
1027 | | * |
1028 | | * vi: set shiftwidth=2 tabstop=8 expandtab: |
1029 | | * :indentSize=2:tabSize=8:noTabs=true: |
1030 | | */ |