Coverage Report

Created: 2026-06-30 07:22

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/wireshark/epan/dissectors/packet-rftap.c
Line
Count
Source
1
/*
2
 *  packet-rftap.c
3
 *  Decode packets with a RFtap header
4
 *  Copyright 2016, Jonathan Brucker <jonathan.brucke@gmail.com>
5
 *
6
 * Wireshark - Network traffic analyzer
7
 * By Gerald Combs <gerald@wireshark.org>
8
 * Copyright 1998 Gerald Combs
9
 *
10
 * SPDX-License-Identifier: GPL-2.0-or-later
11
 */
12
13
/*
14
 * The RFtap header is a simple meta-data header designed to provide
15
 * RF (Radio Frequency) meta-data about frames, such as:
16
 * - Accurate signal and noise power
17
 * - Accurate timing and phase information
18
 * - Accurate carrier and Doppler frequencies, and more.
19
 * The RFtap protocol can be used to encapsulate any type of frame.
20
 *
21
 * Official specification:
22
 * https://rftap.github.io
23
 */
24
25
#include <config.h>
26
27
#include <epan/packet.h>
28
#include <epan/unit_strings.h>
29
30
#include <wsutil/array.h>
31
32
/* Prototypes */
33
/* (Required to prevent [-Wmissing-prototypes] warnings */
34
void proto_reg_handoff_rftap(void);
35
void proto_register_rftap(void);
36
37
/* protocols */
38
static int proto_rftap;
39
40
/* rftap fixed fields */
41
static int hf_rftap_fixed_header;
42
static int hf_rftap_magic;
43
static int hf_rftap_len;    /* length in bytes */
44
static int hf_rftap_flags;
45
46
/* rftap flags bit-field (16 bits) */
47
static int hf_rftap_present_dlt;
48
static int hf_rftap_present_freq;
49
static int hf_rftap_present_nomfreq;
50
static int hf_rftap_present_freqofs;
51
static int hf_rftap_power_is_in_dbm;
52
static int hf_rftap_present_signal_power;
53
static int hf_rftap_present_noise_power;
54
static int hf_rftap_present_snr;
55
static int hf_rftap_present_signal_quality;
56
static int hf_rftap_time_is_unix_time;
57
static int hf_rftap_present_time;
58
static int hf_rftap_present_duration;
59
static int hf_rftap_present_location;
60
static int hf_rftap_present_reserved_field_13;
61
static int hf_rftap_present_reserved_field_14;
62
static int hf_rftap_present_reserved_field_15;
63
64
/* rftap optional fields */
65
static int hf_rftap_dlt;
66
static int hf_rftap_freq;
67
static int hf_rftap_nomfreq;
68
static int hf_rftap_freqofs;
69
static int hf_rftap_signal_power;
70
static int hf_rftap_noise_power;
71
static int hf_rftap_snr;
72
static int hf_rftap_signal_quality;
73
static int hf_rftap_time_int;
74
static int hf_rftap_time_frac;
75
static int hf_rftap_time;
76
static int hf_rftap_duration;
77
static int hf_rftap_latitude;
78
static int hf_rftap_longitude;
79
static int hf_rftap_altitude;
80
81
/* rftap tag IDs >= 16 */
82
static int hf_rftap_subdissector_name;
83
84
/* subtree pointers */
85
static int ett_rftap;
86
static int ett_rftap_fixed_header;
87
static int ett_rftap_flags;
88
89
static dissector_handle_t pcap_pktdata_handle;
90
91
3.25k
#define RFTAP_MAGIC 0x61744652UL  /* "RFta" */
92
93
enum rftap_tag_id {
94
    RFTAP_TAG_DLT = 0,
95
    RFTAP_TAG_FREQ = 1,
96
    RFTAP_TAG_NOM_FREQ = 2,
97
    RFTAP_TAG_FREQ_OFS = 3,
98
    RFTAP_TAG_POWER_IS_IN_DBM = 4,
99
    RFTAP_TAG_SIGNAL_POWER = 5,
100
    RFTAP_TAG_NOISE_POWER = 6,
101
    RFTAP_TAG_SNR = 7,
102
    RFTAP_TAG_SIGNAL_QUALITY = 8,
103
    RFTAP_TAG_TIME_IS_UNIX_TIME = 9,
104
    RFTAP_TAG_TIME = 10,
105
    RFTAP_TAG_DURATION = 11,
106
    RFTAP_TAG_LOCATION = 12,
107
    RFTAP_TAG_RESERVED_13 = 13,
108
    RFTAP_TAG_RESERVED_14 = 14,
109
    RFTAP_TAG_RESERVED_15 = 15,
110
    RFTAP_TAG_DISSECTOR_NAME = 16
111
};
112
113
/* This is the header as it is used by rftap-generating software.
114
 * It is not used by the wireshark dissector and provided for reference only.
115
struct rftap_hdr {
116
    le32 magic;  // "RFta"
117
    le16 len32;  // sizeof(rftap_hdr) / sizeof(le32)
118
    le16 flags;  // bitfield indicating presence of parameters
119
    le32 data[];
120
} __attribute__((packed));
121
 */
122
123
/* dissect the rftap header part of the packet
124
 * returns Data Link Type (dlt) and subdissector name
125
 */
126
static void
127
dissect_rftap_header(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, uint32_t *dlt, const char **subdissector_name)
128
1.31k
{
129
1.31k
    proto_item *ti_header;
130
1.31k
    proto_tree *header_tree;
131
1.31k
    int32_t offset;
132
1.31k
    int32_t len;
133
1.31k
    uint64_t flags;
134
1.31k
    uint32_t flag_bit;
135
1.31k
    uint32_t tag_id;
136
1.31k
    int32_t tag_len;
137
1.31k
    uint32_t tag_flags;
138
1.31k
    double double_val;
139
1.31k
    float   float_val;
140
1.31k
    char    *power_units;
141
142
1.31k
    static int * const flag_fields[] = {
143
1.31k
        &hf_rftap_present_dlt,
144
1.31k
        &hf_rftap_present_freq,
145
1.31k
        &hf_rftap_present_nomfreq,
146
1.31k
        &hf_rftap_present_freqofs,
147
1.31k
        &hf_rftap_power_is_in_dbm,
148
1.31k
        &hf_rftap_present_signal_power,
149
1.31k
        &hf_rftap_present_noise_power,
150
1.31k
        &hf_rftap_present_snr,
151
1.31k
        &hf_rftap_present_signal_quality,
152
1.31k
        &hf_rftap_time_is_unix_time,
153
1.31k
        &hf_rftap_present_time,
154
1.31k
        &hf_rftap_present_duration,
155
1.31k
        &hf_rftap_present_location,
156
1.31k
        &hf_rftap_present_reserved_field_13,
157
1.31k
        &hf_rftap_present_reserved_field_14,
158
1.31k
        &hf_rftap_present_reserved_field_15,
159
1.31k
        NULL
160
1.31k
    };
161
162
1.31k
    *dlt = 0xffffffff;
163
1.31k
    *subdissector_name = NULL;
164
165
    /* rftap fixed header sub-tree */
166
167
1.31k
    ti_header = proto_tree_add_item(tree, hf_rftap_fixed_header, tvb, 0, 8, ENC_NA);
168
1.31k
    header_tree = proto_item_add_subtree(ti_header, ett_rftap_fixed_header);
169
170
1.31k
    proto_tree_add_item(header_tree, hf_rftap_magic, tvb, 0, 4, ENC_LITTLE_ENDIAN);
171
1.31k
    len = 4 * (int32_t) tvb_get_letohs(tvb, 4);  /* convert to length in bytes */
172
1.31k
    proto_tree_add_uint(header_tree, hf_rftap_len, tvb, 4, 2, len);  /* show length in bytes */
173
1.31k
    proto_tree_add_bitmask_ret_uint64(header_tree, tvb, 6, hf_rftap_flags,
174
1.31k
        ett_rftap_flags, flag_fields, ENC_LITTLE_ENDIAN, &flags);
175
176
    /* rftap parameter fields */
177
178
1.31k
    power_units = (flags & (1 << RFTAP_TAG_POWER_IS_IN_DBM)) ? "dBm" : "dB";
179
180
1.31k
    offset = 8;
181
1.31k
    flag_bit = 1;
182
19.0k
    for (tag_id = 0; tag_id < 16; tag_id++, flag_bit<<=1) {
183
184
18.8k
        if (!(flags & flag_bit))
185
11.8k
            continue;  /* parameter is not present, skip */
186
187
7.01k
        switch (tag_id) {
188
1.30k
        case RFTAP_TAG_DLT:
189
1.30k
            proto_tree_add_item_ret_uint(tree, hf_rftap_dlt, tvb, offset, 4, ENC_LITTLE_ENDIAN, dlt);
190
1.30k
            offset += 4;
191
1.30k
            break;
192
136
        case RFTAP_TAG_FREQ:
193
136
            proto_tree_add_item(tree, hf_rftap_freq, tvb, offset, 8, ENC_LITTLE_ENDIAN);
194
136
            offset += 8;
195
136
            break;
196
954
        case RFTAP_TAG_NOM_FREQ:
197
954
            proto_tree_add_item(tree, hf_rftap_nomfreq, tvb, offset, 8, ENC_LITTLE_ENDIAN);
198
954
            offset += 8;
199
954
            break;
200
15
        case RFTAP_TAG_FREQ_OFS:
201
15
            proto_tree_add_item(tree, hf_rftap_freqofs, tvb, offset, 8, ENC_LITTLE_ENDIAN);
202
15
            offset += 8;
203
15
            break;
204
851
        case RFTAP_TAG_POWER_IS_IN_DBM:
205
            /* do nothing, it's already decoded in flags bit-field */
206
851
            break;
207
865
        case RFTAP_TAG_SIGNAL_POWER:
208
865
            float_val = tvb_get_letohieee_float(tvb, offset);
209
865
            proto_tree_add_float_format_value(tree, hf_rftap_signal_power, tvb, offset, 4, float_val, "%.2f %s", float_val, power_units);
210
865
            offset += 4;
211
865
            break;
212
11
        case RFTAP_TAG_NOISE_POWER:
213
11
            float_val = tvb_get_letohieee_float(tvb, offset);
214
11
            proto_tree_add_float_format_value(tree, hf_rftap_noise_power, tvb, offset, 4, float_val, "%.2f %s", float_val, power_units);
215
11
            offset += 4;
216
11
            break;
217
1.17k
        case RFTAP_TAG_SNR:
218
1.17k
            float_val = tvb_get_letohieee_float(tvb, offset);
219
1.17k
            proto_tree_add_float_format_value(tree, hf_rftap_snr, tvb, offset, 4, float_val, "%.2f dB", float_val);
220
1.17k
            offset += 4;
221
1.17k
            break;
222
453
        case RFTAP_TAG_SIGNAL_QUALITY:
223
453
            proto_tree_add_item(tree, hf_rftap_signal_quality, tvb, offset, 4, ENC_LITTLE_ENDIAN);
224
453
            offset += 4;
225
453
            break;
226
119
        case RFTAP_TAG_TIME_IS_UNIX_TIME:
227
            /* do nothing, it's already decoded in flags bit-field */
228
119
            break;
229
94
        case RFTAP_TAG_TIME:
230
94
            double_val = tvb_get_letohieee_double(tvb, offset);
231
94
            proto_tree_add_double_format_value(tree, hf_rftap_time_int, tvb, offset, 8, double_val, "%.0f seconds", double_val);
232
94
            double_val = tvb_get_letohieee_double(tvb, offset + 8);
233
94
            proto_tree_add_double_format_value(tree, hf_rftap_time_frac, tvb, offset+8, 8, double_val, "%.9f seconds", double_val);
234
            /* compute combined time: (not accurate, error is > 300 nanoseconds) */
235
94
            double_val += tvb_get_letohieee_double(tvb, offset);
236
94
            proto_tree_add_double_format_value(tree, hf_rftap_time, tvb, offset, 16, double_val, "%.6f seconds", double_val);
237
94
            offset += 16;
238
94
            break;
239
4
        case RFTAP_TAG_DURATION:
240
4
            proto_tree_add_item(tree, hf_rftap_duration, tvb, offset, 8, ENC_LITTLE_ENDIAN);
241
4
            offset += 8;
242
4
            break;
243
4
        case RFTAP_TAG_LOCATION:
244
4
            proto_tree_add_item(tree, hf_rftap_latitude, tvb, offset, 8, ENC_LITTLE_ENDIAN);
245
4
            proto_tree_add_item(tree, hf_rftap_longitude, tvb, offset+8, 8, ENC_LITTLE_ENDIAN);
246
4
            proto_tree_add_item(tree, hf_rftap_altitude, tvb, offset+16, 8, ENC_LITTLE_ENDIAN);
247
4
            offset += 24;
248
4
            break;
249
1.03k
        default:
250
1.03k
            return;  /* we've hit a parameter we can't decode, abort */
251
7.01k
        }
252
7.01k
    }
253
254
263
    if (offset >= len)
255
11
        return;  /* there are no tagged parameters to decode, goodbye */
256
257
    /* rftap tagged parameter fields */
258
259
252
    tag_id = tvb_get_letohs(tvb, offset);
260
252
    tag_len = tvb_get_uint8(tvb, offset+2);
261
252
    tag_flags = tvb_get_uint8(tvb, offset+3);
262
263
252
    if ((tag_id != RFTAP_TAG_DISSECTOR_NAME) || (tag_len == 0) || (tag_len == 255) || (tag_flags != 255))
264
251
        return;  /* we've hit a tagged parameter we can't decode, abort */
265
266
1
    proto_tree_add_item_ret_string(tree, hf_rftap_subdissector_name, tvb,
267
1
        offset+4, tag_len, ENC_ASCII, pinfo->pool, (const uint8_t**)&subdissector_name);
268
1
}
269
270
/* Main entry point to dissect the packets.
271
 *
272
 * Each packet consists of two parts:
273
 * - The rftap header, containing all the RF metadata.
274
 * - The encapsulated data packet, decoded by a sub-dissector.
275
 */
276
static int
277
dissect_rftap(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
278
        void *data _U_)
279
3.54k
{
280
3.54k
    proto_item *ti;
281
3.54k
    proto_tree *rftap_tree;
282
283
3.54k
    tvbuff_t   *rftap_tvb;  /* the first part of the packet */
284
3.54k
    tvbuff_t   *subdissector_tvb;  /* the second part of the packet */
285
286
3.54k
    int32_t     rftap_len;  /* length in bytes */
287
3.54k
    dissector_handle_t subdissector_handle;
288
3.54k
    uint32_t    subdissector_dlt;
289
3.54k
    const char *subdissector_name;
290
291
    /* heuristics */
292
293
3.54k
    if (tvb_captured_length(tvb) < 8)  /* 4 magic + 2 len + 2 flags = 8 bytes */
294
287
        return 0;
295
296
3.25k
    if (tvb_get_letohl(tvb, 0) != RFTAP_MAGIC)
297
1.94k
        return 0;
298
299
    /* column info */
300
301
1.31k
    col_set_str(pinfo->cinfo, COL_PROTOCOL, "RFTAP");
302
1.31k
    col_clear(pinfo->cinfo, COL_INFO);
303
1.31k
    clear_address(&pinfo->src);
304
1.31k
    clear_address(&pinfo->dst);
305
306
    /* dissect part 1: rftap header */
307
308
1.31k
    rftap_len = 4 * (int32_t) tvb_get_letohs(tvb, 4);
309
1.31k
    rftap_tvb = tvb_new_subset_length(tvb, 0, rftap_len);
310
311
1.31k
    ti = proto_tree_add_protocol_format(tree, proto_rftap, rftap_tvb, 0, -1,
312
1.31k
        "RFtap Protocol (%d bytes)", rftap_len);
313
1.31k
    rftap_tree = proto_item_add_subtree(ti, ett_rftap);
314
315
1.31k
    dissect_rftap_header(rftap_tvb, rftap_tree, pinfo, &subdissector_dlt, &subdissector_name);
316
317
    /* dissect part 2: data packet */
318
319
1.31k
    subdissector_tvb = tvb_new_subset_remaining(tvb, rftap_len);
320
321
    /* try using data link type (DLT) */
322
1.31k
    if (subdissector_dlt != 0xffffffff) {
323
1.29k
        call_dissector_with_data(pcap_pktdata_handle, subdissector_tvb, pinfo, tree, &subdissector_dlt);
324
1.29k
        return tvb_captured_length(tvb);
325
1.29k
    }
326
327
    /* try using dissector name */
328
19
    if (subdissector_name) {
329
0
        subdissector_handle = find_dissector(subdissector_name);
330
0
        if (subdissector_handle) {
331
0
            call_dissector_with_data(subdissector_handle, subdissector_tvb, pinfo, tree, NULL);
332
0
            return tvb_captured_length(tvb);
333
0
        }
334
0
    }
335
336
    /* fallback using plain data dissector */
337
19
    call_data_dissector(subdissector_tvb, pinfo, tree);
338
19
    return tvb_captured_length(tvb);
339
19
}
340
341
static bool
342
dissect_rftap_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
343
3.54k
{
344
3.54k
    return dissect_rftap(tvb, pinfo, tree, data) != 0;
345
3.54k
}
346
347
/* Register the protocol with Wireshark. */
348
void
349
proto_register_rftap(void)
350
14
{
351
    /* Setup protocol subtree array */
352
14
    static int *ett[] = {
353
14
        &ett_rftap,
354
14
        &ett_rftap_fixed_header,
355
14
        &ett_rftap_flags
356
14
    };
357
358
    /* Setup list of header fields */
359
14
    static hf_register_info hf[] = {
360
361
        /* rftap fixed header */
362
363
14
        { &hf_rftap_fixed_header, {
364
14
            "RFtap Fixed header",
365
14
            "rftap.fixedheader",
366
14
            FT_NONE, BASE_NONE, NULL, 0,
367
14
            "RFtap Fixed 8-byte Header", HFILL }},
368
369
14
        { &hf_rftap_magic, {
370
14
            "Magic",
371
14
            "rftap.magic",
372
14
            FT_UINT32, BASE_HEX, NULL, 0,
373
14
            "RFtap signature: wikipedia.org/wiki/File_format#Magic_number", HFILL }},
374
14
        { &hf_rftap_len, {
375
14
            "Length",
376
14
            "rftap.len",
377
14
            FT_UINT32, BASE_DEC, NULL, 0,
378
14
            "Length (in bytes) of entire rftap header, including tagged (optional) parameters", HFILL }},
379
14
        { &hf_rftap_flags, {
380
14
            "Flags",
381
14
            "rftap.flags",
382
14
            FT_UINT16, BASE_HEX, NULL, 0,
383
14
            "RFtap flags", HFILL }},
384
385
        /* flags bit-field */
386
387
14
        {&hf_rftap_present_dlt, {
388
14
            "DLT Present",
389
14
            "rftap.present.dlt",
390
14
            FT_BOOLEAN, 16, NULL, 0x0001,
391
14
            "Specifies if the DLT (Data Link Type) field is present", HFILL }},
392
14
        {&hf_rftap_present_freq, {
393
14
            "Frequency Present",
394
14
            "rftap.present.freq",
395
14
            FT_BOOLEAN, 16, NULL, 0x0002,
396
14
            "Specifies if the Frequency field is present", HFILL }},
397
14
        {&hf_rftap_present_nomfreq, {
398
14
            "Nominal Frequency Present",
399
14
            "rftap.present.nomfreq",
400
14
            FT_BOOLEAN, 16, NULL, 0x0004,
401
14
            "Specifies if the Nominal Frequency field is present", HFILL }},
402
14
        {&hf_rftap_present_freqofs, {
403
14
            "Frequency Offset Present",
404
14
            "rftap.present.freqofs",
405
14
            FT_BOOLEAN, 16, NULL, 0x0008,
406
14
            "Specifies if the Frequency Offset field is present", HFILL }},
407
14
        {&hf_rftap_power_is_in_dbm, {
408
14
            "Power is in dBm Units",
409
14
            "rftap.isdbm",
410
14
            FT_BOOLEAN, 16, NULL, 0x0010,
411
14
            "Specifies if the Power is specified in dBm units", HFILL }},
412
14
        {&hf_rftap_present_signal_power, {
413
14
            "Signal Power Present",
414
14
            "rftap.present.power",
415
14
            FT_BOOLEAN, 16, NULL, 0x0020,
416
14
            "Specifies if the Signal Power field is present", HFILL }},
417
14
        {&hf_rftap_present_noise_power, {
418
14
            "Noise Power Present",
419
14
            "rftap.present.noise",
420
14
            FT_BOOLEAN, 16, NULL, 0x0040,
421
14
            "Specifies if the Noise Power field is present", HFILL }},
422
14
        {&hf_rftap_present_snr, {
423
14
            "SNR Present",
424
14
            "rftap.present.snr",
425
14
            FT_BOOLEAN, 16, NULL, 0x0080,
426
14
            "Specifies if the SNR field is present", HFILL }},
427
14
        {&hf_rftap_present_signal_quality, {
428
14
            "Signal Quality Present",
429
14
            "rftap.present.qual",
430
14
            FT_BOOLEAN, 16, NULL, 0x0100,
431
14
            "Specifies if the Signal Quality field is present", HFILL }},
432
14
        {&hf_rftap_time_is_unix_time, {
433
14
            "Time standard is Unix Time",
434
14
            "rftap.isunixtime",
435
14
            FT_BOOLEAN, 16, NULL, 0x0200,
436
14
            "Specifies if the time standard is Unix Time: wikipedia.org/wiki/Unix_time", HFILL }},
437
14
        {&hf_rftap_present_time, {
438
14
            "Time Present",
439
14
            "rftap.present.time",
440
14
            FT_BOOLEAN, 16, NULL, 0x0400,
441
14
            "Specifies if the Time field is present", HFILL }},
442
14
        {&hf_rftap_present_duration, {
443
14
            "Duration Present",
444
14
            "rftap.present.duration",
445
14
            FT_BOOLEAN, 16, NULL, 0x0800,
446
14
            "Specifies if the Duration field is present", HFILL }},
447
14
        {&hf_rftap_present_location, {
448
14
            "Location Present",
449
14
            "rftap.present.location",
450
14
            FT_BOOLEAN, 16, NULL, 0x1000,
451
14
            "Specifies if the Location field is present", HFILL }},
452
14
        {&hf_rftap_present_reserved_field_13, {
453
14
            "Reserved Field 13 Present",
454
14
            "rftap.present.field13",
455
14
            FT_BOOLEAN, 16, NULL, 0x2000,
456
14
            "Specifies if the Reserved Field 13 is present", HFILL }},
457
14
        {&hf_rftap_present_reserved_field_14, {
458
14
            "Reserved Field 14 Present",
459
14
            "rftap.present.field14",
460
14
            FT_BOOLEAN, 16, NULL, 0x4000,
461
14
            "Specifies if the Reserved Field 14 is present", HFILL }},
462
14
        {&hf_rftap_present_reserved_field_15, {
463
14
            "Reserved Field 15 Present",
464
14
            "rftap.present.field15",
465
14
            FT_BOOLEAN, 16, NULL, 0x8000,
466
14
            "Specifies if the Reserved Field 15 is present", HFILL }},
467
468
        /* rftap parameters */
469
470
14
        { &hf_rftap_dlt, {
471
14
            "Data Link Type (DLT)",
472
14
            "rftap.dlt",
473
14
            FT_UINT32, BASE_DEC, NULL, 0,
474
14
            "Data Link Type (DLT) of the encapsulated packet: www.tcpdump.org/linktypes.html", HFILL }},
475
14
        { &hf_rftap_freq, {
476
14
            "Frequency",
477
14
            "rftap.freq",
478
14
            FT_DOUBLE, BASE_NONE|BASE_UNIT_STRING, UNS(&units_hz), 0,
479
14
            "Actual (measured) carrier frequency, in Hertz (not necessarily center frequency)", HFILL }},
480
14
        { &hf_rftap_nomfreq, {
481
14
            "Nominal Frequency",
482
14
            "rftap.nomfreq",
483
14
            FT_DOUBLE, BASE_NONE|BASE_UNIT_STRING, UNS(&units_hz), 0,
484
14
            "Nominal carrier frequency, in Hertz (the ideal frequency, ignoring freq errors)", HFILL }},
485
14
        { &hf_rftap_freqofs, {
486
14
            "Frequency Offset",
487
14
            "rftap.freqofs",
488
14
            FT_DOUBLE, BASE_NONE|BASE_UNIT_STRING, UNS(&units_hz), 0,
489
14
            "Carrier frequency offset, in Hertz: wikipedia.org/wiki/Carrier_frequency_offset", HFILL }},
490
14
        { &hf_rftap_signal_power, {
491
14
            "Signal Power",
492
14
            "rftap.power",
493
14
            FT_FLOAT, BASE_NONE, NULL, 0,
494
14
            "Signal power, in dB or dBm units: wikipedia.org/wiki/DBm", HFILL }},
495
14
        { &hf_rftap_noise_power, {
496
14
            "Noise Power",
497
14
            "rftap.noise",
498
14
            FT_FLOAT, BASE_NONE, NULL, 0,
499
14
            "Noise power, in dB or dBm units: wikipedia.org/wiki/DBm", HFILL }},
500
14
        { &hf_rftap_snr, {
501
14
            "SNR",
502
14
            "rftap.snr",
503
14
            FT_FLOAT, BASE_NONE, NULL, 0,
504
14
            "Signal to Noise ratio (decibel units): wikipedia.org/wiki/Signal-to-noise_ratio", HFILL }},
505
14
        { &hf_rftap_signal_quality, {
506
14
            "Signal Quality",
507
14
            "rftap.qual",
508
14
            FT_FLOAT, BASE_NONE, NULL, 0,
509
14
            "Signal quality, arbitrary units from 0.0 (worst) to 1.0 (best)", HFILL }},
510
14
        { &hf_rftap_time_int, {
511
14
            "Time (integer part)",
512
14
            "rftap.timeint",
513
14
            FT_DOUBLE, BASE_NONE, NULL, 0,
514
14
            "The integer part of event time, in seconds, since epoch: wikipedia.org/wiki/Epoch_(reference_date)", HFILL }},
515
14
        { &hf_rftap_time_frac, {
516
14
            "Time (fractional part)",
517
14
            "rftap.timefrac",
518
14
            FT_DOUBLE, BASE_NONE, NULL, 0,
519
14
            "The fractional part of event time, in seconds, since epoch: wikipedia.org/wiki/Epoch_(reference_date)", HFILL }},
520
14
        { &hf_rftap_time, {
521
14
            "Time",
522
14
            "rftap.time",
523
14
            FT_DOUBLE, BASE_NONE, NULL, 0,
524
14
            "The event time, in seconds, since epoch: wikipedia.org/wiki/Epoch_(reference_date)", HFILL }},
525
14
        { &hf_rftap_duration, {
526
14
            "Duration",
527
14
            "rftap.duration",
528
14
            FT_DOUBLE, BASE_NONE|BASE_UNIT_STRING, UNS(&units_second_seconds), 0,
529
14
            "The duration of the event (packet), in seconds", HFILL }},
530
14
        { &hf_rftap_latitude, {
531
14
            "Latitude",
532
14
            "rftap.lat",
533
14
            FT_DOUBLE, BASE_NONE|BASE_UNIT_STRING, UNS(&units_degree_degrees), 0,
534
14
            "Latitude of receiver (-90..90 degrees), using WGS 84 datum: wikipedia.org/wiki/World_Geodetic_System", HFILL }},
535
14
        { &hf_rftap_longitude, {
536
14
            "Longitude",
537
14
            "rftap.lon",
538
14
            FT_DOUBLE, BASE_NONE|BASE_UNIT_STRING, UNS(&units_degree_degrees), 0,
539
14
            "Longitude of receiver (-180..180 degrees), using WGS 84 datum: wikipedia.org/wiki/World_Geodetic_System", HFILL }},
540
14
        { &hf_rftap_altitude, {
541
14
            "Altitude",
542
14
            "rftap.alt",
543
14
            FT_DOUBLE, BASE_NONE|BASE_UNIT_STRING, UNS(&units_meter_meters), 0,
544
14
            "Altitude of receiver, in meters, using WGS 84 datum: wikipedia.org/wiki/World_Geodetic_System", HFILL }},
545
546
        /* rftap tagged parameters */
547
548
14
        { &hf_rftap_subdissector_name, {
549
14
            "Dissector Name",
550
14
            "rftap.dissector",
551
14
            FT_STRING, BASE_NONE, NULL, 0,
552
14
            "Name of sub-dissector used for packet data (alternative to DLT field)", HFILL }}
553
14
    };
554
555
    /* Register the protocol name and description */
556
14
    proto_rftap = proto_register_protocol("RFtap Protocol", "RFtap", "rftap");
557
558
    /* Register the header fields and subtrees */
559
14
    proto_register_field_array(proto_rftap, hf, array_length(hf));
560
14
    proto_register_subtree_array(ett, array_length(ett));
561
562
14
    register_dissector("rftap", dissect_rftap, proto_rftap);
563
14
}
564
565
566
/* Protocol registration routine. This function is also called by
567
 * Wireshark's preferences manager whenever "Apply" or "OK" are pressed.
568
 */
569
void
570
proto_reg_handoff_rftap(void)
571
14
{
572
14
    pcap_pktdata_handle = find_dissector_add_dependency("pcap_pktdata", proto_rftap);
573
14
    heur_dissector_add("udp", dissect_rftap_heur, "RFtap over UDP", "rftap", proto_rftap, HEURISTIC_ENABLE);
574
14
}
575
576
/*
577
 * Editor modelines  -  https://www.wireshark.org/tools/modelines.html
578
 *
579
 * Local variables:
580
 * c-basic-offset: 4
581
 * tab-width: 8
582
 * indent-tabs-mode: nil
583
 * End:
584
 *
585
 * vi: set shiftwidth=4 tabstop=8 expandtab:
586
 * :indentSize=4:tabSize=8:noTabs=true:
587
 */