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-rtls.c
Line
Count
Source
1
/* packet-rtls.c
2
 * Routines for Real Time Location System dissection
3
 * Copyright 2016, Alexis La Goutte (See Authors)
4
 *
5
 * Wireshark - Network traffic analyzer
6
 * By Gerald Combs <gerald@wireshark.org>
7
 * Copyright 1998 Gerald Combs
8
 *
9
 * SPDX-License-Identifier: GPL-2.0-or-later
10
 */
11
12
/*
13
 * http://community.arubanetworks.com/aruba/attachments/aruba/unified-wired-wireless-access/23715/1/RTLS_integrationv6.docx
14
 */
15
16
#include <config.h>
17
18
#include <epan/packet.h>
19
#include <epan/expert.h>
20
21
void proto_reg_handoff_rtls(void);
22
void proto_register_rtls(void);
23
24
static dissector_handle_t rtls_handle;
25
26
static int proto_rtls;
27
static int hf_rtls_message_type;
28
static int hf_rtls_message_id;
29
static int hf_rtls_version_major;
30
static int hf_rtls_version_minor;
31
static int hf_rtls_data_length;
32
static int hf_rtls_ap_mac;
33
static int hf_rtls_padding;
34
static int hf_rtls_reserved;
35
static int hf_rtls_signature;
36
37
static int hf_rtls_as_tag_addr;
38
static int hf_rtls_sr_mac_address;
39
static int hf_rtls_nack_flags;
40
static int hf_rtls_nack_flags_internal_error;
41
static int hf_rtls_nack_flags_station_not_found;
42
static int hf_rtls_nack_flags_reserved;
43
static int hf_rtls_tr_bssid;
44
static int hf_rtls_tr_rssi;
45
static int hf_rtls_tr_rssi_calculated;
46
static int hf_rtls_tr_noise_floor;
47
static int hf_rtls_tr_timestamp;
48
static int hf_rtls_tr_tag_mac;
49
static int hf_rtls_tr_frame_control;
50
static int hf_rtls_tr_sequence;
51
static int hf_rtls_tr_data_rate;
52
static int hf_rtls_tr_tx_power;
53
static int hf_rtls_tr_channel;
54
static int hf_rtls_tr_battery;
55
static int hf_rtls_sr_mac;
56
static int hf_rtls_sr_noise_floor;
57
static int hf_rtls_sr_data_rate;
58
static int hf_rtls_sr_channel;
59
static int hf_rtls_sr_rssi;
60
static int hf_rtls_sr_rssi_calculated;
61
static int hf_rtls_sr_type;
62
static int hf_rtls_sr_associated;
63
static int hf_rtls_sr_radio_bssid;
64
static int hf_rtls_sr_mon_bssid;
65
static int hf_rtls_sr_age;
66
static int hf_rtls_ser_mac;
67
static int hf_rtls_ser_bssid;
68
static int hf_rtls_ser_essid;
69
static int hf_rtls_ser_channel;
70
static int hf_rtls_ser_phy_type;
71
static int hf_rtls_ser_rssi;
72
static int hf_rtls_ser_rssi_calculated;
73
static int hf_rtls_ser_duration;
74
static int hf_rtls_ser_num_packets;
75
static int hf_rtls_ser_noise_floor;
76
static int hf_rtls_ser_classification;
77
static int hf_rtls_aer_bssid;
78
static int hf_rtls_aer_essid;
79
static int hf_rtls_aer_channel;
80
static int hf_rtls_aer_phy_type;
81
static int hf_rtls_aer_rssi;
82
static int hf_rtls_aer_rssi_calculated;
83
static int hf_rtls_aer_duration;
84
static int hf_rtls_aer_num_packets;
85
static int hf_rtls_aer_noise_floor;
86
static int hf_rtls_aer_classification;
87
static int hf_rtls_aer_match_type;
88
static int hf_rtls_aer_match_method;
89
static int hf_rtls_cmr_messages;
90
91
static int * const rtls_nack_flags[] = {
92
    &hf_rtls_nack_flags_internal_error,
93
    &hf_rtls_nack_flags_station_not_found,
94
    &hf_rtls_nack_flags_reserved,
95
    NULL
96
};
97
98
static expert_field ei_rtls_undecoded;
99
static int ett_rtls;
100
static int ett_rtls_message;
101
static int ett_rtls_nack_flags;
102
103
0
#define RTLS_HDR_LENGTH 16
104
0
#define RTLS_SIGN_LENGTH 20
105
106
0
#define AR_AS_CONFIG_SET            0x0000
107
0
#define AR_STATION_REQUEST          0x0001
108
0
#define AR_ACK                      0x0010
109
0
#define AR_NACK                     0x0011
110
0
#define AR_TAG_REPORT               0x0012
111
0
#define AR_STATION_REPORT           0x0013
112
0
#define AR_COMPOUND_MESSAGE_REPORT  0x0014
113
0
#define AR_AP_NOTIFICATION          0x0015
114
#define AR_MMS_CONFIG_SET           0x0016
115
0
#define AR_STATION_EX_REPORT        0x0017
116
0
#define AR_AP_EX_REPORT             0x0018
117
118
static const value_string rtls_message_type_vals[] = {
119
    { AR_AS_CONFIG_SET, "AR_AS_CONFIG_SET" },
120
    { AR_STATION_REQUEST, "AR_STATION_REQUEST" },
121
    { AR_ACK, "AR_ACK"},
122
    { AR_NACK, "AR_NACK"},
123
    { AR_TAG_REPORT, "AR_TAG_REPORT"},
124
    { AR_STATION_REPORT, "AR_STATION_REPORT"},
125
    { AR_COMPOUND_MESSAGE_REPORT, "AR_COMPOUND_MESSAGE_REPORT"},
126
    { AR_AP_NOTIFICATION, "AR_AP_NOTIFICATION"},
127
    { AR_MMS_CONFIG_SET, "AR_MMS_CONFIG_SET"},
128
    { AR_STATION_EX_REPORT, "AR_STATION_EX_REPORT"},
129
    { AR_AP_EX_REPORT, "AR_AP_EX_REPORT"},
130
    { 0, NULL }
131
};
132
133
static const value_string rtls_sr_type_vals[] = {
134
    { 1, "AR_WLAN_CLIENT" },
135
    { 2, "AR_WLAN_AP" },
136
    {0, NULL}
137
};
138
139
static const value_string rtls_sr_associated_vals[] = {
140
    { 1, "AR_WLAN_ASSOCIATED (All APs and Associated Stations)" },
141
    { 2, "AR_WLAN_UNASSOCIATED (Unassociated Stations)" },
142
    {0, NULL}
143
};
144
145
static const value_string rtls_data_rate_vals[] = {
146
    { 0x00, "1 Mbits" },
147
    { 0x01, "2 Mbits" },
148
    { 0x02, "5.5 Mbits" },
149
    { 0x03, "6 Mbits" },
150
    { 0x04, "9 Mbits" },
151
    { 0x05, "11 Mbits" },
152
    { 0x06, "12 Mbits" },
153
    { 0x07, "18 Mbits" },
154
    { 0x08, "24 Mbits" },
155
    { 0x09, "36 Mbits" },
156
    { 0x0A, "48 Mbits" },
157
    { 0x0B, "54 Mbits" },
158
    {0, NULL}
159
};
160
161
static const value_string rtls_ex_phy_type_vals[] = {
162
    { 1, "802.11b" },
163
    { 2, "802.11a" },
164
    { 3, "802.11g" },
165
    { 4, "802.11ag" },
166
    {0, NULL}
167
};
168
169
static const value_string rtls_ex_classification_vals[] = {
170
    { 1, "Valid" },
171
    { 2, "interfering" },
172
    { 3, "DOS'ed" },
173
    {0, NULL}
174
};
175
176
static void
177
rssi_base_custom(char *result, uint32_t rssi)
178
0
{
179
    /* Convert Hex to decimal and subtract 256 to get the signal value */
180
0
    snprintf(result, ITEM_LABEL_LENGTH, "%d", rssi - 256);
181
182
0
}
183
184
static int
185
dissect_rtls_header(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *rtls_tree, unsigned offset, unsigned *data_length)
186
0
{
187
188
0
    proto_tree_add_item(rtls_tree, hf_rtls_message_type, tvb, offset, 2, ENC_BIG_ENDIAN);
189
0
    offset += 2;
190
191
0
    proto_tree_add_item(rtls_tree, hf_rtls_message_id, tvb, offset, 2, ENC_BIG_ENDIAN);
192
0
    offset += 2;
193
194
0
    proto_tree_add_item(rtls_tree, hf_rtls_version_major, tvb, offset, 1, ENC_BIG_ENDIAN);
195
0
    offset += 1;
196
197
0
    proto_tree_add_item(rtls_tree, hf_rtls_version_minor, tvb, offset, 1, ENC_BIG_ENDIAN);
198
0
    offset += 1;
199
200
0
    proto_tree_add_item(rtls_tree, hf_rtls_data_length, tvb, offset, 2, ENC_BIG_ENDIAN);
201
0
    if(data_length){
202
0
        *data_length = tvb_get_ntohs(tvb, offset);
203
0
    }
204
0
    offset += 2;
205
206
0
    proto_tree_add_item(rtls_tree, hf_rtls_ap_mac, tvb, offset, 6, ENC_NA);
207
0
    offset += 6;
208
209
0
    proto_tree_add_item(rtls_tree, hf_rtls_padding, tvb, offset, 2, ENC_NA);
210
0
    offset += 2;
211
212
0
    return offset;
213
0
}
214
215
static int
216
// NOLINTNEXTLINE(misc-no-recursion)
217
dissect_rtls_message_type(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *rtls_tree, unsigned offset, unsigned type)
218
0
{
219
0
    proto_item *ti_rssi;
220
221
0
    switch(type){
222
0
        case AR_AS_CONFIG_SET:
223
0
            proto_tree_add_item(rtls_tree, hf_rtls_as_tag_addr, tvb, offset, 6, ENC_NA);
224
0
            offset += 6;
225
0
            proto_tree_add_item(rtls_tree, hf_rtls_reserved, tvb, offset, 2, ENC_NA);
226
0
            offset += 2;
227
0
        break;
228
0
        case AR_STATION_REQUEST:
229
0
            proto_tree_add_item(rtls_tree, hf_rtls_sr_mac_address, tvb, offset, 6, ENC_NA);
230
0
            offset += 6;
231
0
            proto_tree_add_item(rtls_tree, hf_rtls_reserved, tvb, offset, 2, ENC_NA);
232
0
            offset += 2;
233
0
        break;
234
0
        case AR_ACK:
235
0
        case AR_AP_NOTIFICATION:
236
            /* No Payload */
237
0
        break;
238
0
        case AR_NACK:
239
0
            proto_tree_add_bitmask_with_flags(rtls_tree, tvb, offset,
240
0
hf_rtls_nack_flags, ett_rtls_nack_flags, rtls_nack_flags, ENC_BIG_ENDIAN, BMT_NO_APPEND);
241
0
            offset += 2;
242
0
            proto_tree_add_item(rtls_tree, hf_rtls_reserved, tvb, offset, 2, ENC_NA);
243
0
            offset += 2;
244
0
        break;
245
0
        case AR_TAG_REPORT:
246
0
            proto_tree_add_item(rtls_tree, hf_rtls_tr_bssid, tvb, offset, 6, ENC_NA);
247
0
            offset += 6;
248
0
            proto_tree_add_item(rtls_tree, hf_rtls_tr_rssi, tvb, offset, 1, ENC_BIG_ENDIAN);
249
0
            ti_rssi = proto_tree_add_item(rtls_tree, hf_rtls_tr_rssi_calculated, tvb, offset, 1, ENC_BIG_ENDIAN);
250
0
            proto_item_set_generated(ti_rssi);
251
0
            offset += 1;
252
0
            proto_tree_add_item(rtls_tree, hf_rtls_tr_noise_floor, tvb, offset, 1, ENC_BIG_ENDIAN);
253
0
            offset += 1;
254
0
            proto_tree_add_item(rtls_tree, hf_rtls_tr_timestamp, tvb, offset, 4, ENC_BIG_ENDIAN);
255
0
            offset += 4;
256
0
            proto_tree_add_item(rtls_tree, hf_rtls_tr_tag_mac, tvb, offset, 6, ENC_NA);
257
0
            offset += 6;
258
0
            proto_tree_add_item(rtls_tree, hf_rtls_tr_frame_control, tvb, offset, 2, ENC_BIG_ENDIAN);
259
0
            offset += 2;
260
0
            proto_tree_add_item(rtls_tree, hf_rtls_tr_sequence, tvb, offset, 2, ENC_BIG_ENDIAN);
261
0
            offset += 2;
262
0
            proto_tree_add_item(rtls_tree, hf_rtls_tr_data_rate, tvb, offset, 1, ENC_BIG_ENDIAN);
263
0
            offset += 1;
264
0
            proto_tree_add_item(rtls_tree, hf_rtls_tr_tx_power, tvb, offset, 1, ENC_BIG_ENDIAN);
265
0
            offset += 1;
266
0
            proto_tree_add_item(rtls_tree, hf_rtls_tr_channel, tvb, offset, 1, ENC_BIG_ENDIAN);
267
0
            offset += 1;
268
0
            proto_tree_add_item(rtls_tree, hf_rtls_tr_battery, tvb, offset, 1, ENC_BIG_ENDIAN);
269
0
            offset += 1;
270
0
            proto_tree_add_item(rtls_tree, hf_rtls_reserved, tvb, offset, 2, ENC_NA);
271
0
            offset += 2;
272
0
        break;
273
0
       case AR_STATION_REPORT:
274
0
            proto_tree_add_item(rtls_tree, hf_rtls_sr_mac, tvb, offset, 6, ENC_NA);
275
0
            offset += 6;
276
0
            proto_tree_add_item(rtls_tree, hf_rtls_sr_noise_floor, tvb, offset, 1, ENC_BIG_ENDIAN);
277
0
            offset += 1;
278
0
            proto_tree_add_item(rtls_tree, hf_rtls_sr_data_rate, tvb, offset, 1, ENC_BIG_ENDIAN);
279
0
            offset += 1;
280
0
            proto_tree_add_item(rtls_tree, hf_rtls_sr_channel, tvb, offset, 1, ENC_BIG_ENDIAN);
281
0
            offset += 1;
282
0
            proto_tree_add_item(rtls_tree, hf_rtls_sr_rssi, tvb, offset, 1, ENC_BIG_ENDIAN);
283
0
            ti_rssi = proto_tree_add_item(rtls_tree, hf_rtls_sr_rssi_calculated, tvb, offset, 1, ENC_BIG_ENDIAN);
284
0
            proto_item_set_generated(ti_rssi);
285
0
            offset += 1;
286
0
            proto_tree_add_item(rtls_tree, hf_rtls_sr_type, tvb, offset, 1, ENC_BIG_ENDIAN);
287
0
            offset += 1;
288
0
            proto_tree_add_item(rtls_tree, hf_rtls_sr_associated, tvb, offset, 1, ENC_BIG_ENDIAN);
289
0
            offset += 1;
290
0
            proto_tree_add_item(rtls_tree, hf_rtls_sr_radio_bssid, tvb, offset, 6, ENC_NA);
291
0
            offset += 6;
292
0
            proto_tree_add_item(rtls_tree, hf_rtls_sr_mon_bssid, tvb, offset, 6, ENC_NA);
293
0
            offset += 6;
294
0
            proto_tree_add_item(rtls_tree, hf_rtls_sr_age, tvb, offset, 4, ENC_BIG_ENDIAN);
295
0
            offset += 4;
296
0
        break;
297
0
       case AR_STATION_EX_REPORT:
298
0
            proto_tree_add_item(rtls_tree, hf_rtls_ser_mac, tvb, offset, 6, ENC_NA);
299
0
            offset += 6;
300
0
            proto_tree_add_item(rtls_tree, hf_rtls_ser_bssid, tvb, offset, 6, ENC_NA);
301
0
            offset += 6;
302
0
            proto_tree_add_item(rtls_tree, hf_rtls_ser_essid, tvb, offset, 33, ENC_ASCII);
303
0
            offset += 33;
304
0
            proto_tree_add_item(rtls_tree, hf_rtls_ser_channel, tvb, offset, 1, ENC_BIG_ENDIAN);
305
0
            offset += 1;
306
0
            proto_tree_add_item(rtls_tree, hf_rtls_ser_phy_type, tvb, offset, 1, ENC_BIG_ENDIAN);
307
0
            offset += 1;
308
0
            proto_tree_add_item(rtls_tree, hf_rtls_ser_rssi, tvb, offset, 1, ENC_BIG_ENDIAN);
309
0
            ti_rssi = proto_tree_add_item(rtls_tree, hf_rtls_ser_rssi_calculated, tvb, offset, 1, ENC_BIG_ENDIAN);
310
0
            proto_item_set_generated(ti_rssi);
311
0
            offset += 1;
312
0
            proto_tree_add_item(rtls_tree, hf_rtls_ser_duration, tvb, offset, 2, ENC_BIG_ENDIAN);
313
0
            offset += 2;
314
0
            proto_tree_add_item(rtls_tree, hf_rtls_ser_num_packets, tvb, offset, 2, ENC_BIG_ENDIAN);
315
0
            offset += 2;
316
0
            proto_tree_add_item(rtls_tree, hf_rtls_ser_noise_floor, tvb, offset, 1, ENC_BIG_ENDIAN);
317
0
            offset += 1;
318
0
            proto_tree_add_item(rtls_tree, hf_rtls_ser_classification, tvb, offset, 1, ENC_BIG_ENDIAN);
319
0
            offset += 1;
320
0
            proto_tree_add_item(rtls_tree, hf_rtls_reserved, tvb, offset, 2, ENC_NA);
321
0
            offset += 2;
322
0
        break;
323
0
       case AR_AP_EX_REPORT:
324
0
            proto_tree_add_item(rtls_tree, hf_rtls_aer_bssid, tvb, offset, 6, ENC_NA );
325
0
            offset += 6;
326
0
            proto_tree_add_item(rtls_tree, hf_rtls_aer_essid, tvb, offset, 33, ENC_ASCII);
327
0
            offset += 33;
328
0
            proto_tree_add_item(rtls_tree, hf_rtls_aer_channel, tvb, offset, 1, ENC_BIG_ENDIAN);
329
0
            offset += 1;
330
0
            proto_tree_add_item(rtls_tree, hf_rtls_aer_phy_type, tvb, offset, 1, ENC_BIG_ENDIAN);
331
0
            offset += 1;
332
0
            proto_tree_add_item(rtls_tree, hf_rtls_aer_rssi, tvb, offset, 1, ENC_BIG_ENDIAN);
333
0
            ti_rssi = proto_tree_add_item(rtls_tree, hf_rtls_aer_rssi_calculated, tvb, offset, 1, ENC_BIG_ENDIAN);
334
0
            proto_item_set_generated(ti_rssi);
335
0
            offset += 1;
336
0
            proto_tree_add_item(rtls_tree, hf_rtls_aer_duration, tvb, offset, 2, ENC_BIG_ENDIAN);
337
0
            offset += 2;
338
0
            proto_tree_add_item(rtls_tree, hf_rtls_aer_num_packets, tvb, offset, 2, ENC_BIG_ENDIAN);
339
0
            offset += 2;
340
0
            proto_tree_add_item(rtls_tree, hf_rtls_aer_noise_floor, tvb, offset, 1, ENC_BIG_ENDIAN);
341
0
            offset += 1;
342
0
            proto_tree_add_item(rtls_tree, hf_rtls_aer_classification, tvb, offset, 1, ENC_BIG_ENDIAN);
343
0
            offset += 1;
344
0
            proto_tree_add_item(rtls_tree, hf_rtls_aer_match_type, tvb, offset, 1, ENC_BIG_ENDIAN);
345
0
            offset += 1;
346
0
            proto_tree_add_item(rtls_tree, hf_rtls_aer_match_method, tvb, offset, 1, ENC_BIG_ENDIAN);
347
0
            offset += 1;
348
0
            proto_tree_add_item(rtls_tree, hf_rtls_reserved, tvb, offset, 2, ENC_NA);
349
0
            offset += 2;
350
0
        break;
351
0
       case AR_COMPOUND_MESSAGE_REPORT:{
352
0
            uint32_t cmr_messages;
353
0
            proto_tree *sub_tree;
354
355
0
            proto_tree_add_item_ret_uint(rtls_tree, hf_rtls_cmr_messages, tvb, offset, 2, ENC_BIG_ENDIAN, &cmr_messages);
356
0
            offset += 2;
357
0
            proto_tree_add_item(rtls_tree, hf_rtls_reserved, tvb, offset, 2, ENC_NA);
358
0
            offset += 2;
359
0
            while(cmr_messages){
360
0
                uint32_t data_length;
361
0
                type = tvb_get_ntohs(tvb, offset);
362
0
                sub_tree = proto_tree_add_subtree_format(rtls_tree, tvb, offset, -1, ett_rtls_message, NULL, "%s", val_to_str(pinfo->pool, type, rtls_message_type_vals, "(unknown %d)"));
363
364
0
                offset = dissect_rtls_header(tvb, pinfo, sub_tree, offset, &data_length);
365
366
                // We recurse here, but we'll run out of packet before we run out of stack.
367
0
                offset = dissect_rtls_message_type(tvb, pinfo, sub_tree, offset, type);
368
369
0
                proto_item_set_len(sub_tree, data_length + RTLS_HDR_LENGTH);
370
0
                cmr_messages--;
371
0
            }
372
0
            }
373
0
        break;
374
0
        default:{
375
0
            uint32_t remaining = tvb_reported_length_remaining(tvb, offset);
376
0
            if(remaining > RTLS_SIGN_LENGTH){
377
0
                proto_tree_add_expert(rtls_tree, pinfo, &ei_rtls_undecoded, tvb, offset, remaining - RTLS_SIGN_LENGTH);
378
0
                offset += remaining - RTLS_SIGN_LENGTH;
379
0
            }
380
0
            }
381
0
        break;
382
0
    }
383
384
0
    return offset;
385
0
}
386
387
static int
388
dissect_rtls(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
389
0
{
390
0
    proto_item *ti;
391
0
    proto_tree *rtls_tree;
392
0
    unsigned    offset = 0;
393
0
    uint32_t    type;
394
395
0
    if (tvb_reported_length(tvb) < RTLS_HDR_LENGTH + RTLS_SIGN_LENGTH)
396
0
        return 0;
397
398
0
    col_set_str(pinfo->cinfo, COL_PROTOCOL, "RTLS");
399
400
401
0
    ti = proto_tree_add_item(tree, proto_rtls, tvb, 0, -1, ENC_NA);
402
403
0
    rtls_tree = proto_item_add_subtree(ti, ett_rtls);
404
405
    /* RTLS Header */
406
0
    type = tvb_get_ntohs(tvb, offset);
407
0
    col_add_str(pinfo->cinfo, COL_INFO, val_to_str(pinfo->pool, type, rtls_message_type_vals, "(unknown %d)"));
408
409
0
    offset = dissect_rtls_header(tvb, pinfo, rtls_tree, offset, NULL);
410
411
0
    offset = dissect_rtls_message_type(tvb, pinfo, rtls_tree, offset, type);
412
413
    /* TODO: Check signature ? HMAC-SHA1 with shared key and RTLS packet data */
414
0
    proto_tree_add_item(rtls_tree, hf_rtls_signature, tvb, offset, RTLS_SIGN_LENGTH, ENC_NA);
415
0
    offset += 20;
416
417
0
    return offset;
418
0
}
419
420
void
421
proto_register_rtls(void)
422
16
{
423
16
    expert_module_t *expert_rtls;
424
425
16
    static hf_register_info hf[] = {
426
427
        /* RTLS Header*/
428
16
        { &hf_rtls_message_type,
429
16
          { "Message Type", "rtls.message_type",
430
16
            FT_UINT16, BASE_HEX, VALS(rtls_message_type_vals), 0x0,
431
16
            NULL, HFILL }
432
16
        },
433
16
        { &hf_rtls_message_id,
434
16
          { "Message Id", "rtls.message_id",
435
16
            FT_UINT16, BASE_DEC, NULL, 0x0,
436
16
            NULL, HFILL }
437
16
        },
438
16
        { &hf_rtls_version_major,
439
16
          { "Version Major", "rtls.version_major",
440
16
            FT_UINT8, BASE_DEC, NULL, 0x0,
441
16
            NULL, HFILL }
442
16
        },
443
16
        { &hf_rtls_version_minor,
444
16
          { "Version Minor", "rtls.version_minor",
445
16
            FT_UINT8, BASE_DEC, NULL, 0x0,
446
16
            NULL, HFILL }
447
16
        },
448
16
        { &hf_rtls_data_length,
449
16
          { "Data Length", "rtls.data_length",
450
16
            FT_UINT16, BASE_DEC, NULL, 0x0,
451
16
            NULL, HFILL }
452
16
        },
453
16
        { &hf_rtls_ap_mac,
454
16
          { "AP MAC Address", "rtls.ap_mac",
455
16
            FT_ETHER, BASE_NONE, NULL, 0x0,
456
16
            NULL, HFILL }
457
16
        },
458
16
        { &hf_rtls_padding,
459
16
          { "Padding", "rtls.padding",
460
16
            FT_BYTES, BASE_NONE, NULL, 0x0,
461
16
            NULL, HFILL }
462
16
        },
463
16
        { &hf_rtls_reserved,
464
16
          { "Reserved", "rtls.reserved",
465
16
            FT_BYTES, BASE_NONE, NULL, 0x0,
466
16
            NULL, HFILL }
467
16
        },
468
16
        { &hf_rtls_signature,
469
16
          { "Signature", "rtls.signature",
470
16
            FT_BYTES, BASE_NONE, NULL, 0x0,
471
16
            NULL, HFILL }
472
16
        },
473
474
        /* AR_AS_CONFIG_SET */
475
16
        { &hf_rtls_as_tag_addr,
476
16
          { "AS Tag Address", "rtls.as_tag_addr",
477
16
            FT_ETHER, BASE_NONE, NULL, 0x0,
478
16
            "Tag multicast address", HFILL }
479
16
        },
480
        /* AR_STATION_REQUEST */
481
16
        { &hf_rtls_sr_mac_address,
482
16
          { "MAC Address", "rtls.sr_mac_addr",
483
16
            FT_ETHER, BASE_NONE, NULL, 0x0,
484
16
            NULL, HFILL }
485
16
        },
486
        /* AR_NACK */
487
16
        { &hf_rtls_nack_flags,
488
16
          { "Flags", "rtls.nack.flags",
489
16
            FT_UINT16, BASE_HEX, NULL, 0x00,
490
16
            NULL, HFILL }
491
16
        },
492
16
        { &hf_rtls_nack_flags_internal_error,
493
16
          { "Internal Error", "rtls.nack.flags.internal_errors",
494
16
            FT_UINT16, BASE_HEX, NULL, 0x01,
495
16
            NULL, HFILL }
496
16
        },
497
16
        { &hf_rtls_nack_flags_station_not_found,
498
16
          { "Station Not found", "rtls.nack.flags.station_not_found",
499
16
            FT_UINT16, BASE_HEX, NULL, 0x02,
500
16
            NULL, HFILL }
501
16
        },
502
16
        { &hf_rtls_nack_flags_reserved,
503
16
          { "Reserved", "rtls.nack.flags.reserved",
504
16
            FT_UINT16, BASE_HEX, NULL, 0xFC,
505
16
            NULL, HFILL }
506
16
        },
507
508
        /* AR_TAG_REPORT */
509
16
        { &hf_rtls_tr_bssid,
510
16
          { "BSSID", "rtls.tr.bssid",
511
16
            FT_ETHER, BASE_NONE, NULL, 0x0,
512
16
            "MAC address of the radio where the frame was received", HFILL }
513
16
        },
514
16
        { &hf_rtls_tr_rssi,
515
16
          { "RSSI", "rtls.tr.rssi",
516
16
            FT_UINT8, BASE_DEC, NULL, 0x0,
517
16
            "Signal as a signed negative hex value", HFILL }
518
16
        },
519
16
        { &hf_rtls_tr_rssi_calculated,
520
16
          { "RSSI (calculated)", "rtls.tr.rssi.calculated",
521
16
            FT_UINT8, BASE_CUSTOM, CF_FUNC(rssi_base_custom), 0x0,
522
16
            NULL, HFILL }
523
16
        },
524
16
        { &hf_rtls_tr_noise_floor,
525
16
          { "Noise Floor", "rtls.tr.noise_floor",
526
16
            FT_UINT8, BASE_DEC, NULL, 0x0,
527
16
            "Noise floor of the radio", HFILL }
528
16
        },
529
16
        { &hf_rtls_tr_timestamp,
530
16
          { "Timestamp", "rtls.tr.timestamp",
531
16
            FT_UINT32, BASE_DEC, NULL, 0x0,
532
16
            "Millisecond granularity timestamp that represents local time in AP when message was sent", HFILL }
533
16
        },
534
16
        { &hf_rtls_tr_tag_mac,
535
16
          { "Tag Mac", "rtls.tr.tag_mac",
536
16
            FT_ETHER, BASE_NONE, NULL, 0x0,
537
16
            "MAC address of the tag", HFILL }
538
16
        },
539
16
        { &hf_rtls_tr_frame_control,
540
16
          { "Frame Control", "rtls.tr.frame_control",
541
16
            FT_UINT16, BASE_HEX, NULL, 0x0,
542
16
            "Frame control from 802.11 header", HFILL }
543
16
        },
544
16
        { &hf_rtls_tr_sequence,
545
16
          { "Sequence", "rtls.tr.sequence",
546
16
            FT_UINT16, BASE_DEC, NULL, 0x0,
547
16
            "Sequence number from the 802.11 header", HFILL }
548
16
        },
549
16
        { &hf_rtls_tr_data_rate,
550
16
          { "Data Rate", "rtls.tr.data_rate",
551
16
            FT_UINT8, BASE_DEC, VALS(rtls_data_rate_vals), 0x0,
552
16
            "Data rate of chirp frame", HFILL }
553
16
        },
554
16
        { &hf_rtls_tr_tx_power,
555
16
          { "Tx Power", "rtls.tr.tx_power",
556
16
            FT_UINT8, BASE_DEC, NULL, 0x0,
557
16
            "Transmit power in dbm", HFILL }
558
16
        },
559
16
        { &hf_rtls_tr_channel,
560
16
          { "Channel", "rtls.tr.channel",
561
16
            FT_UINT8, BASE_DEC, NULL, 0x0,
562
16
            "Channel of tag transmission", HFILL }
563
16
        },
564
16
        { &hf_rtls_tr_battery,
565
16
          { "Battery", "rtls.tr.battery",
566
16
            FT_UINT8, BASE_DEC, NULL, 0x0,
567
16
            "Batter level information from the chirp frame if present", HFILL }
568
16
        },
569
        /* AR_STATION_REPORT */
570
16
        { &hf_rtls_sr_mac,
571
16
          { "MAC", "rtls.sr.mac",
572
16
            FT_ETHER, BASE_NONE, NULL, 0x0,
573
16
            NULL, HFILL }
574
16
        },
575
16
        { &hf_rtls_sr_noise_floor,
576
16
          { "Noise Floor", "rtls.sr.noise_floor",
577
16
            FT_UINT8, BASE_DEC, NULL, 0x0,
578
16
            "Noise floor of the channel where the station was last heard", HFILL }
579
16
        },
580
16
        { &hf_rtls_sr_data_rate,
581
16
          { "Data Rate", "rtls.sr.data_rate",
582
16
            FT_UINT8, BASE_DEC, VALS(rtls_data_rate_vals), 0x0,
583
16
            "Data rate of chirp frame", HFILL }
584
16
        },
585
16
        { &hf_rtls_sr_channel,
586
16
          { "Channel", "rtls.sr.channel",
587
16
            FT_UINT8, BASE_DEC, NULL, 0x0,
588
16
            "Channel where station was last heard", HFILL }
589
16
        },
590
16
        { &hf_rtls_sr_rssi,
591
16
          { "RSSI", "rtls.sr.rssi",
592
16
            FT_UINT8, BASE_DEC, NULL, 0x0,
593
16
            "Signal as a signed negative hex value", HFILL }
594
16
        },
595
16
        { &hf_rtls_sr_rssi_calculated,
596
16
          { "RSSI (calculated)", "rtls.sr.rssi.calculated",
597
16
            FT_UINT8, BASE_CUSTOM, CF_FUNC(rssi_base_custom), 0x0,
598
16
            NULL, HFILL }
599
16
        },
600
16
        { &hf_rtls_sr_type,
601
16
          { "Type", "rtls.sr.type",
602
16
            FT_UINT8, BASE_DEC, VALS(rtls_sr_type_vals), 0x0,
603
16
            "Type of device", HFILL }
604
16
        },
605
16
        { &hf_rtls_sr_associated,
606
16
          { "Associated", "rtls.sr.associated",
607
16
            FT_UINT8, BASE_DEC, VALS(rtls_sr_associated_vals), 0x0,
608
16
            "Association status of station", HFILL }
609
16
        },
610
16
        { &hf_rtls_sr_radio_bssid,
611
16
          { "Radio BSSID", "rtls.sr.radio_bssids",
612
16
            FT_ETHER, BASE_NONE, NULL, 0x0,
613
16
            "Association status of station BSSID of the radio that detected the device", HFILL }
614
16
        },
615
16
        { &hf_rtls_sr_mon_bssid,
616
16
          { "Mon BSSID", "rtls.sr.mon_bssids",
617
16
            FT_ETHER, BASE_NONE, NULL, 0x0,
618
16
            "BSSID of the AP that the station is associated to", HFILL }
619
16
        },
620
16
        { &hf_rtls_sr_age,
621
16
          { "Age", "rtls.sr.age",
622
16
            FT_UINT32, BASE_DEC, NULL, 0x0,
623
16
            "The number of seconds since the last packet was heard from this station", HFILL }
624
16
        },
625
        /* AR_STATION_EX_REPORT */
626
16
        { &hf_rtls_ser_mac,
627
16
          { "MAC", "rtls.ser.mac",
628
16
            FT_ETHER, BASE_NONE, NULL, 0x0,
629
16
            "MAC address of station", HFILL }
630
16
        },
631
16
        { &hf_rtls_ser_bssid,
632
16
          { "BSSID", "rtls.ser.bssid",
633
16
            FT_ETHER, BASE_NONE, NULL, 0x0,
634
16
            "BSSID with which this station is associated", HFILL }
635
16
        },
636
16
        { &hf_rtls_ser_essid,
637
16
          { "ESSID", "rtls.ser.essid",
638
16
            FT_STRING, BASE_NONE, NULL, 0x0,
639
16
            "ESSID with which this station is associated", HFILL }
640
16
        },
641
16
        { &hf_rtls_ser_channel,
642
16
          { "Channel", "rtls.ser.channel",
643
16
            FT_UINT8, BASE_DEC, NULL, 0x0,
644
16
            "Channel where this station is active", HFILL }
645
16
        },
646
16
        { &hf_rtls_ser_phy_type,
647
16
          { "Phy type", "rtls.ser.phy_type",
648
16
            FT_UINT8, BASE_DEC, VALS(rtls_ex_phy_type_vals), 0x0,
649
16
            NULL, HFILL }
650
16
        },
651
16
        { &hf_rtls_ser_rssi,
652
16
          { "RSSI", "rtls.ser.rssi",
653
16
            FT_UINT8, BASE_DEC, NULL, 0x0,
654
16
            "Average RSSI during the duration", HFILL }
655
16
        },
656
16
        { &hf_rtls_ser_rssi_calculated,
657
16
          { "RSSI (calculated)", "rtls.ser.rssi.calculated",
658
16
            FT_UINT8, BASE_CUSTOM, CF_FUNC(rssi_base_custom), 0x0,
659
16
            NULL, HFILL }
660
16
        },
661
16
        { &hf_rtls_ser_duration,
662
16
          { "Duration", "rtls.ser.duration",
663
16
            FT_UINT16, BASE_DEC, NULL, 0x0,
664
16
            "Average calculation duration", HFILL }
665
16
        },
666
16
        { &hf_rtls_ser_num_packets,
667
16
          { "Num Packets", "rtls.ser.num_packets",
668
16
            FT_UINT16, BASE_DEC, NULL, 0x0,
669
16
            "Number of packets used in average RSSI calculation", HFILL }
670
16
        },
671
16
        { &hf_rtls_ser_noise_floor,
672
16
          { "Noise Floor", "rtls.ser.noise_floor",
673
16
            FT_UINT8, BASE_DEC, NULL, 0x0,
674
16
            "Noise floor of the radio", HFILL }
675
16
        },
676
16
        { &hf_rtls_ser_classification,
677
16
          { "Classification", "rtls.ser.classification",
678
16
            FT_UINT8, BASE_DEC, VALS(rtls_ex_classification_vals), 0x0,
679
16
            "Millisecond granularity timestamp that represents local time in AP when message was sent", HFILL }
680
16
        },
681
        /* AR_AP_EX_REPORT */
682
16
        { &hf_rtls_aer_bssid,
683
16
          { "BSSID", "rtls.aer.bssid",
684
16
            FT_ETHER, BASE_NONE, NULL, 0x0,
685
16
            "BSSID with which this station is associated", HFILL }
686
16
        },
687
16
        { &hf_rtls_aer_essid,
688
16
          { "ESSID", "rtls.aer.essid",
689
16
            FT_STRING, BASE_NONE, NULL, 0x0,
690
16
            "ESSID with which this station is associated", HFILL }
691
16
        },
692
16
        { &hf_rtls_aer_channel,
693
16
          { "Channel", "rtls.aer.channel",
694
16
            FT_UINT8, BASE_DEC, NULL, 0x0,
695
16
            "Channel where this station is active", HFILL }
696
16
        },
697
16
        { &hf_rtls_aer_phy_type,
698
16
          { "Phy type", "rtls.aer.phy_type",
699
16
            FT_UINT8, BASE_DEC, VALS(rtls_ex_phy_type_vals), 0x0,
700
16
            NULL, HFILL }
701
16
        },
702
16
        { &hf_rtls_aer_rssi,
703
16
          { "RSSI", "rtls.aer.rssi",
704
16
            FT_UINT8, BASE_DEC, NULL, 0x0,
705
16
            "Average RSSI during the duration", HFILL }
706
16
        },
707
16
        { &hf_rtls_aer_rssi_calculated,
708
16
          { "RSSI (calculated)", "rtls.aer.rssi.calculated",
709
16
            FT_UINT8, BASE_CUSTOM, CF_FUNC(rssi_base_custom), 0x0,
710
16
            NULL, HFILL }
711
16
        },
712
16
        { &hf_rtls_aer_duration,
713
16
          { "Duration", "rtls.aer.duration",
714
16
            FT_UINT16, BASE_DEC, NULL, 0x0,
715
16
            "Average calculation duration", HFILL }
716
16
        },
717
16
        { &hf_rtls_aer_num_packets,
718
16
          { "Num Packets", "rtls.aer.num_packets",
719
16
            FT_UINT16, BASE_DEC, NULL, 0x0,
720
16
            "Number of packets used in average RSSI calculation", HFILL }
721
16
        },
722
16
        { &hf_rtls_aer_noise_floor,
723
16
          { "Noise Floor", "rtls.aer.noise_floor",
724
16
            FT_UINT8, BASE_DEC, NULL, 0x0,
725
16
            "Noise floor of the radio", HFILL }
726
16
        },
727
16
        { &hf_rtls_aer_classification,
728
16
          { "Classification", "rtls.aer.classification",
729
16
            FT_UINT8, BASE_DEC, VALS(rtls_ex_classification_vals), 0x0,
730
16
            "Millisecond granularity timestamp that represents local time in AP when message was sent", HFILL }
731
16
        },
732
16
        { &hf_rtls_aer_match_type,
733
16
          { "Match Type", "rtls.aer.match_type",
734
16
            FT_UINT8, BASE_HEX, NULL, 0x0,
735
16
            "Internal Aruba use", HFILL }
736
16
        },
737
16
        { &hf_rtls_aer_match_method,
738
16
          { "Match Method", "rtls.aer.match_method",
739
16
            FT_UINT8, BASE_HEX, NULL, 0x0,
740
16
            "Internal Aruba use", HFILL }
741
16
        },
742
743
16
        { &hf_rtls_cmr_messages,
744
16
          { "Messages", "rtls.cmr_messages",
745
16
            FT_UINT16, BASE_DEC, NULL, 0x0,
746
16
            "number of messages", HFILL }
747
16
        },
748
749
16
    };
750
751
16
    static int *ett[] = {
752
16
        &ett_rtls,
753
16
        &ett_rtls_message,
754
16
        &ett_rtls_nack_flags,
755
16
    };
756
757
758
    /* Setup protocol expert items */
759
16
    static ei_register_info ei[] = {
760
16
        { &ei_rtls_undecoded,
761
16
          { "rtls.undecoded", PI_UNDECODED, PI_NOTE, "Undecoded Payload", EXPFILL }
762
16
        }
763
16
    };
764
765
766
16
    proto_rtls = proto_register_protocol("Real Time Location System", "RTLS", "rtls");
767
16
    rtls_handle = register_dissector("rtls", dissect_rtls, proto_rtls);
768
769
16
    proto_register_field_array(proto_rtls, hf, array_length(hf));
770
16
    proto_register_subtree_array(ett, array_length(ett));
771
772
16
    expert_rtls = expert_register_protocol(proto_rtls);
773
16
    expert_register_field_array(expert_rtls, ei, array_length(ei));
774
775
16
}
776
777
void
778
proto_reg_handoff_rtls(void)
779
16
{
780
    // If this is ever streamed (transported over TCP) we need to add recursion checks
781
16
    dissector_add_for_decode_as_with_preference("udp.port", rtls_handle);
782
16
}
783
784
/*
785
 * Editor modelines  -  https://www.wireshark.org/tools/modelines.html
786
 *
787
 * Local variables:
788
 * c-basic-offset: 4
789
 * tab-width: 8
790
 * indent-tabs-mode: nil
791
 * End:
792
 *
793
 * vi: set shiftwidth=4 tabstop=8 expandtab:
794
 * :indentSize=4:tabSize=8:noTabs=true:
795
 */