Coverage Report

Created: 2026-08-14 06:45

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/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
 */