Coverage Report

Created: 2026-07-12 07:10

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
5.13k
#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
2.20k
{
129
2.20k
    proto_item *ti_header;
130
2.20k
    proto_tree *header_tree;
131
2.20k
    int32_t offset;
132
2.20k
    int32_t len;
133
2.20k
    uint64_t flags;
134
2.20k
    uint32_t flag_bit;
135
2.20k
    uint32_t tag_id;
136
2.20k
    int32_t tag_len;
137
2.20k
    uint32_t tag_flags;
138
2.20k
    double double_val;
139
2.20k
    float   float_val;
140
2.20k
    char    *power_units;
141
142
2.20k
    static int * const flag_fields[] = {
143
2.20k
        &hf_rftap_present_dlt,
144
2.20k
        &hf_rftap_present_freq,
145
2.20k
        &hf_rftap_present_nomfreq,
146
2.20k
        &hf_rftap_present_freqofs,
147
2.20k
        &hf_rftap_power_is_in_dbm,
148
2.20k
        &hf_rftap_present_signal_power,
149
2.20k
        &hf_rftap_present_noise_power,
150
2.20k
        &hf_rftap_present_snr,
151
2.20k
        &hf_rftap_present_signal_quality,
152
2.20k
        &hf_rftap_time_is_unix_time,
153
2.20k
        &hf_rftap_present_time,
154
2.20k
        &hf_rftap_present_duration,
155
2.20k
        &hf_rftap_present_location,
156
2.20k
        &hf_rftap_present_reserved_field_13,
157
2.20k
        &hf_rftap_present_reserved_field_14,
158
2.20k
        &hf_rftap_present_reserved_field_15,
159
2.20k
        NULL
160
2.20k
    };
161
162
2.20k
    *dlt = 0xffffffff;
163
2.20k
    *subdissector_name = NULL;
164
165
    /* rftap fixed header sub-tree */
166
167
2.20k
    ti_header = proto_tree_add_item(tree, hf_rftap_fixed_header, tvb, 0, 8, ENC_NA);
168
2.20k
    header_tree = proto_item_add_subtree(ti_header, ett_rftap_fixed_header);
169
170
2.20k
    proto_tree_add_item(header_tree, hf_rftap_magic, tvb, 0, 4, ENC_LITTLE_ENDIAN);
171
2.20k
    len = 4 * (int32_t) tvb_get_letohs(tvb, 4);  /* convert to length in bytes */
172
2.20k
    proto_tree_add_uint(header_tree, hf_rftap_len, tvb, 4, 2, len);  /* show length in bytes */
173
2.20k
    proto_tree_add_bitmask_ret_uint64(header_tree, tvb, 6, hf_rftap_flags,
174
2.20k
        ett_rftap_flags, flag_fields, ENC_LITTLE_ENDIAN, &flags);
175
176
    /* rftap parameter fields */
177
178
2.20k
    power_units = (flags & (1 << RFTAP_TAG_POWER_IS_IN_DBM)) ? "dBm" : "dB";
179
180
2.20k
    offset = 8;
181
2.20k
    flag_bit = 1;
182
32.2k
    for (tag_id = 0; tag_id < 16; tag_id++, flag_bit<<=1) {
183
184
31.7k
        if (!(flags & flag_bit))
185
19.7k
            continue;  /* parameter is not present, skip */
186
187
12.0k
        switch (tag_id) {
188
2.19k
        case RFTAP_TAG_DLT:
189
2.19k
            proto_tree_add_item_ret_uint(tree, hf_rftap_dlt, tvb, offset, 4, ENC_LITTLE_ENDIAN, dlt);
190
2.19k
            offset += 4;
191
2.19k
            break;
192
132
        case RFTAP_TAG_FREQ:
193
132
            proto_tree_add_item(tree, hf_rftap_freq, tvb, offset, 8, ENC_LITTLE_ENDIAN);
194
132
            offset += 8;
195
132
            break;
196
1.75k
        case RFTAP_TAG_NOM_FREQ:
197
1.75k
            proto_tree_add_item(tree, hf_rftap_nomfreq, tvb, offset, 8, ENC_LITTLE_ENDIAN);
198
1.75k
            offset += 8;
199
1.75k
            break;
200
13
        case RFTAP_TAG_FREQ_OFS:
201
13
            proto_tree_add_item(tree, hf_rftap_freqofs, tvb, offset, 8, ENC_LITTLE_ENDIAN);
202
13
            offset += 8;
203
13
            break;
204
1.53k
        case RFTAP_TAG_POWER_IS_IN_DBM:
205
            /* do nothing, it's already decoded in flags bit-field */
206
1.53k
            break;
207
1.55k
        case RFTAP_TAG_SIGNAL_POWER:
208
1.55k
            float_val = tvb_get_letohieee_float(tvb, offset);
209
1.55k
            proto_tree_add_float_format_value(tree, hf_rftap_signal_power, tvb, offset, 4, float_val, "%.2f %s", float_val, power_units);
210
1.55k
            offset += 4;
211
1.55k
            break;
212
10
        case RFTAP_TAG_NOISE_POWER:
213
10
            float_val = tvb_get_letohieee_float(tvb, offset);
214
10
            proto_tree_add_float_format_value(tree, hf_rftap_noise_power, tvb, offset, 4, float_val, "%.2f %s", float_val, power_units);
215
10
            offset += 4;
216
10
            break;
217
2.05k
        case RFTAP_TAG_SNR:
218
2.05k
            float_val = tvb_get_letohieee_float(tvb, offset);
219
2.05k
            proto_tree_add_float_format_value(tree, hf_rftap_snr, tvb, offset, 4, float_val, "%.2f dB", float_val);
220
2.05k
            offset += 4;
221
2.05k
            break;
222
625
        case RFTAP_TAG_SIGNAL_QUALITY:
223
625
            proto_tree_add_item(tree, hf_rftap_signal_quality, tvb, offset, 4, ENC_LITTLE_ENDIAN);
224
625
            offset += 4;
225
625
            break;
226
263
        case RFTAP_TAG_TIME_IS_UNIX_TIME:
227
            /* do nothing, it's already decoded in flags bit-field */
228
263
            break;
229
193
        case RFTAP_TAG_TIME:
230
193
            double_val = tvb_get_letohieee_double(tvb, offset);
231
193
            proto_tree_add_double_format_value(tree, hf_rftap_time_int, tvb, offset, 8, double_val, "%.0f seconds", double_val);
232
193
            double_val = tvb_get_letohieee_double(tvb, offset + 8);
233
193
            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
193
            double_val += tvb_get_letohieee_double(tvb, offset);
236
193
            proto_tree_add_double_format_value(tree, hf_rftap_time, tvb, offset, 16, double_val, "%.6f seconds", double_val);
237
193
            offset += 16;
238
193
            break;
239
1
        case RFTAP_TAG_DURATION:
240
1
            proto_tree_add_item(tree, hf_rftap_duration, tvb, offset, 8, ENC_LITTLE_ENDIAN);
241
1
            offset += 8;
242
1
            break;
243
2
        case RFTAP_TAG_LOCATION:
244
2
            proto_tree_add_item(tree, hf_rftap_latitude, tvb, offset, 8, ENC_LITTLE_ENDIAN);
245
2
            proto_tree_add_item(tree, hf_rftap_longitude, tvb, offset+8, 8, ENC_LITTLE_ENDIAN);
246
2
            proto_tree_add_item(tree, hf_rftap_altitude, tvb, offset+16, 8, ENC_LITTLE_ENDIAN);
247
2
            offset += 24;
248
2
            break;
249
1.71k
        default:
250
1.71k
            return;  /* we've hit a parameter we can't decode, abort */
251
12.0k
        }
252
12.0k
    }
253
254
478
    if (offset >= len)
255
20
        return;  /* there are no tagged parameters to decode, goodbye */
256
257
    /* rftap tagged parameter fields */
258
259
458
    tag_id = tvb_get_letohs(tvb, offset);
260
458
    tag_len = tvb_get_uint8(tvb, offset+2);
261
458
    tag_flags = tvb_get_uint8(tvb, offset+3);
262
263
458
    if ((tag_id != RFTAP_TAG_DISSECTOR_NAME) || (tag_len == 0) || (tag_len == 255) || (tag_flags != 255))
264
458
        return;  /* we've hit a tagged parameter we can't decode, abort */
265
266
0
    proto_tree_add_item_ret_string(tree, hf_rftap_subdissector_name, tvb,
267
0
        offset+4, tag_len, ENC_ASCII, pinfo->pool, (const uint8_t**)&subdissector_name);
268
0
}
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
5.50k
{
280
5.50k
    proto_item *ti;
281
5.50k
    proto_tree *rftap_tree;
282
283
5.50k
    tvbuff_t   *rftap_tvb;  /* the first part of the packet */
284
5.50k
    tvbuff_t   *subdissector_tvb;  /* the second part of the packet */
285
286
5.50k
    int32_t     rftap_len;  /* length in bytes */
287
5.50k
    dissector_handle_t subdissector_handle;
288
5.50k
    uint32_t    subdissector_dlt;
289
5.50k
    const char *subdissector_name;
290
291
    /* heuristics */
292
293
5.50k
    if (tvb_captured_length(tvb) < 8)  /* 4 magic + 2 len + 2 flags = 8 bytes */
294
371
        return 0;
295
296
5.13k
    if (tvb_get_letohl(tvb, 0) != RFTAP_MAGIC)
297
2.92k
        return 0;
298
299
    /* column info */
300
301
2.20k
    col_set_str(pinfo->cinfo, COL_PROTOCOL, "RFTAP");
302
2.20k
    col_clear(pinfo->cinfo, COL_INFO);
303
2.20k
    clear_address(&pinfo->src);
304
2.20k
    clear_address(&pinfo->dst);
305
306
    /* dissect part 1: rftap header */
307
308
2.20k
    rftap_len = 4 * (int32_t) tvb_get_letohs(tvb, 4);
309
2.20k
    rftap_tvb = tvb_new_subset_length(tvb, 0, rftap_len);
310
311
2.20k
    ti = proto_tree_add_protocol_format(tree, proto_rftap, rftap_tvb, 0, -1,
312
2.20k
        "RFtap Protocol (%d bytes)", rftap_len);
313
2.20k
    rftap_tree = proto_item_add_subtree(ti, ett_rftap);
314
315
2.20k
    dissect_rftap_header(rftap_tvb, rftap_tree, pinfo, &subdissector_dlt, &subdissector_name);
316
317
    /* dissect part 2: data packet */
318
319
2.20k
    subdissector_tvb = tvb_new_subset_remaining(tvb, rftap_len);
320
321
    /* try using data link type (DLT) */
322
2.20k
    if (subdissector_dlt != 0xffffffff) {
323
2.18k
        call_dissector_with_data(pcap_pktdata_handle, subdissector_tvb, pinfo, tree, &subdissector_dlt);
324
2.18k
        return tvb_captured_length(tvb);
325
2.18k
    }
326
327
    /* try using dissector name */
328
23
    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
23
    call_data_dissector(subdissector_tvb, pinfo, tree);
338
23
    return tvb_captured_length(tvb);
339
23
}
340
341
static bool
342
dissect_rftap_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
343
5.50k
{
344
5.50k
    return dissect_rftap(tvb, pinfo, tree, data) != 0;
345
5.50k
}
346
347
/* Register the protocol with Wireshark. */
348
void
349
proto_register_rftap(void)
350
15
{
351
    /* Setup protocol subtree array */
352
15
    static int *ett[] = {
353
15
        &ett_rftap,
354
15
        &ett_rftap_fixed_header,
355
15
        &ett_rftap_flags
356
15
    };
357
358
    /* Setup list of header fields */
359
15
    static hf_register_info hf[] = {
360
361
        /* rftap fixed header */
362
363
15
        { &hf_rftap_fixed_header, {
364
15
            "RFtap Fixed header",
365
15
            "rftap.fixedheader",
366
15
            FT_NONE, BASE_NONE, NULL, 0,
367
15
            "RFtap Fixed 8-byte Header", HFILL }},
368
369
15
        { &hf_rftap_magic, {
370
15
            "Magic",
371
15
            "rftap.magic",
372
15
            FT_UINT32, BASE_HEX, NULL, 0,
373
15
            "RFtap signature: wikipedia.org/wiki/File_format#Magic_number", HFILL }},
374
15
        { &hf_rftap_len, {
375
15
            "Length",
376
15
            "rftap.len",
377
15
            FT_UINT32, BASE_DEC, NULL, 0,
378
15
            "Length (in bytes) of entire rftap header, including tagged (optional) parameters", HFILL }},
379
15
        { &hf_rftap_flags, {
380
15
            "Flags",
381
15
            "rftap.flags",
382
15
            FT_UINT16, BASE_HEX, NULL, 0,
383
15
            "RFtap flags", HFILL }},
384
385
        /* flags bit-field */
386
387
15
        {&hf_rftap_present_dlt, {
388
15
            "DLT Present",
389
15
            "rftap.present.dlt",
390
15
            FT_BOOLEAN, 16, NULL, 0x0001,
391
15
            "Specifies if the DLT (Data Link Type) field is present", HFILL }},
392
15
        {&hf_rftap_present_freq, {
393
15
            "Frequency Present",
394
15
            "rftap.present.freq",
395
15
            FT_BOOLEAN, 16, NULL, 0x0002,
396
15
            "Specifies if the Frequency field is present", HFILL }},
397
15
        {&hf_rftap_present_nomfreq, {
398
15
            "Nominal Frequency Present",
399
15
            "rftap.present.nomfreq",
400
15
            FT_BOOLEAN, 16, NULL, 0x0004,
401
15
            "Specifies if the Nominal Frequency field is present", HFILL }},
402
15
        {&hf_rftap_present_freqofs, {
403
15
            "Frequency Offset Present",
404
15
            "rftap.present.freqofs",
405
15
            FT_BOOLEAN, 16, NULL, 0x0008,
406
15
            "Specifies if the Frequency Offset field is present", HFILL }},
407
15
        {&hf_rftap_power_is_in_dbm, {
408
15
            "Power is in dBm Units",
409
15
            "rftap.isdbm",
410
15
            FT_BOOLEAN, 16, NULL, 0x0010,
411
15
            "Specifies if the Power is specified in dBm units", HFILL }},
412
15
        {&hf_rftap_present_signal_power, {
413
15
            "Signal Power Present",
414
15
            "rftap.present.power",
415
15
            FT_BOOLEAN, 16, NULL, 0x0020,
416
15
            "Specifies if the Signal Power field is present", HFILL }},
417
15
        {&hf_rftap_present_noise_power, {
418
15
            "Noise Power Present",
419
15
            "rftap.present.noise",
420
15
            FT_BOOLEAN, 16, NULL, 0x0040,
421
15
            "Specifies if the Noise Power field is present", HFILL }},
422
15
        {&hf_rftap_present_snr, {
423
15
            "SNR Present",
424
15
            "rftap.present.snr",
425
15
            FT_BOOLEAN, 16, NULL, 0x0080,
426
15
            "Specifies if the SNR field is present", HFILL }},
427
15
        {&hf_rftap_present_signal_quality, {
428
15
            "Signal Quality Present",
429
15
            "rftap.present.qual",
430
15
            FT_BOOLEAN, 16, NULL, 0x0100,
431
15
            "Specifies if the Signal Quality field is present", HFILL }},
432
15
        {&hf_rftap_time_is_unix_time, {
433
15
            "Time standard is Unix Time",
434
15
            "rftap.isunixtime",
435
15
            FT_BOOLEAN, 16, NULL, 0x0200,
436
15
            "Specifies if the time standard is Unix Time: wikipedia.org/wiki/Unix_time", HFILL }},
437
15
        {&hf_rftap_present_time, {
438
15
            "Time Present",
439
15
            "rftap.present.time",
440
15
            FT_BOOLEAN, 16, NULL, 0x0400,
441
15
            "Specifies if the Time field is present", HFILL }},
442
15
        {&hf_rftap_present_duration, {
443
15
            "Duration Present",
444
15
            "rftap.present.duration",
445
15
            FT_BOOLEAN, 16, NULL, 0x0800,
446
15
            "Specifies if the Duration field is present", HFILL }},
447
15
        {&hf_rftap_present_location, {
448
15
            "Location Present",
449
15
            "rftap.present.location",
450
15
            FT_BOOLEAN, 16, NULL, 0x1000,
451
15
            "Specifies if the Location field is present", HFILL }},
452
15
        {&hf_rftap_present_reserved_field_13, {
453
15
            "Reserved Field 13 Present",
454
15
            "rftap.present.field13",
455
15
            FT_BOOLEAN, 16, NULL, 0x2000,
456
15
            "Specifies if the Reserved Field 13 is present", HFILL }},
457
15
        {&hf_rftap_present_reserved_field_14, {
458
15
            "Reserved Field 14 Present",
459
15
            "rftap.present.field14",
460
15
            FT_BOOLEAN, 16, NULL, 0x4000,
461
15
            "Specifies if the Reserved Field 14 is present", HFILL }},
462
15
        {&hf_rftap_present_reserved_field_15, {
463
15
            "Reserved Field 15 Present",
464
15
            "rftap.present.field15",
465
15
            FT_BOOLEAN, 16, NULL, 0x8000,
466
15
            "Specifies if the Reserved Field 15 is present", HFILL }},
467
468
        /* rftap parameters */
469
470
15
        { &hf_rftap_dlt, {
471
15
            "Data Link Type (DLT)",
472
15
            "rftap.dlt",
473
15
            FT_UINT32, BASE_DEC, NULL, 0,
474
15
            "Data Link Type (DLT) of the encapsulated packet: www.tcpdump.org/linktypes.html", HFILL }},
475
15
        { &hf_rftap_freq, {
476
15
            "Frequency",
477
15
            "rftap.freq",
478
15
            FT_DOUBLE, BASE_NONE|BASE_UNIT_STRING, UNS(&units_hz), 0,
479
15
            "Actual (measured) carrier frequency, in Hertz (not necessarily center frequency)", HFILL }},
480
15
        { &hf_rftap_nomfreq, {
481
15
            "Nominal Frequency",
482
15
            "rftap.nomfreq",
483
15
            FT_DOUBLE, BASE_NONE|BASE_UNIT_STRING, UNS(&units_hz), 0,
484
15
            "Nominal carrier frequency, in Hertz (the ideal frequency, ignoring freq errors)", HFILL }},
485
15
        { &hf_rftap_freqofs, {
486
15
            "Frequency Offset",
487
15
            "rftap.freqofs",
488
15
            FT_DOUBLE, BASE_NONE|BASE_UNIT_STRING, UNS(&units_hz), 0,
489
15
            "Carrier frequency offset, in Hertz: wikipedia.org/wiki/Carrier_frequency_offset", HFILL }},
490
15
        { &hf_rftap_signal_power, {
491
15
            "Signal Power",
492
15
            "rftap.power",
493
15
            FT_FLOAT, BASE_NONE, NULL, 0,
494
15
            "Signal power, in dB or dBm units: wikipedia.org/wiki/DBm", HFILL }},
495
15
        { &hf_rftap_noise_power, {
496
15
            "Noise Power",
497
15
            "rftap.noise",
498
15
            FT_FLOAT, BASE_NONE, NULL, 0,
499
15
            "Noise power, in dB or dBm units: wikipedia.org/wiki/DBm", HFILL }},
500
15
        { &hf_rftap_snr, {
501
15
            "SNR",
502
15
            "rftap.snr",
503
15
            FT_FLOAT, BASE_NONE, NULL, 0,
504
15
            "Signal to Noise ratio (decibel units): wikipedia.org/wiki/Signal-to-noise_ratio", HFILL }},
505
15
        { &hf_rftap_signal_quality, {
506
15
            "Signal Quality",
507
15
            "rftap.qual",
508
15
            FT_FLOAT, BASE_NONE, NULL, 0,
509
15
            "Signal quality, arbitrary units from 0.0 (worst) to 1.0 (best)", HFILL }},
510
15
        { &hf_rftap_time_int, {
511
15
            "Time (integer part)",
512
15
            "rftap.timeint",
513
15
            FT_DOUBLE, BASE_NONE, NULL, 0,
514
15
            "The integer part of event time, in seconds, since epoch: wikipedia.org/wiki/Epoch_(reference_date)", HFILL }},
515
15
        { &hf_rftap_time_frac, {
516
15
            "Time (fractional part)",
517
15
            "rftap.timefrac",
518
15
            FT_DOUBLE, BASE_NONE, NULL, 0,
519
15
            "The fractional part of event time, in seconds, since epoch: wikipedia.org/wiki/Epoch_(reference_date)", HFILL }},
520
15
        { &hf_rftap_time, {
521
15
            "Time",
522
15
            "rftap.time",
523
15
            FT_DOUBLE, BASE_NONE, NULL, 0,
524
15
            "The event time, in seconds, since epoch: wikipedia.org/wiki/Epoch_(reference_date)", HFILL }},
525
15
        { &hf_rftap_duration, {
526
15
            "Duration",
527
15
            "rftap.duration",
528
15
            FT_DOUBLE, BASE_NONE|BASE_UNIT_STRING, UNS(&units_second_seconds), 0,
529
15
            "The duration of the event (packet), in seconds", HFILL }},
530
15
        { &hf_rftap_latitude, {
531
15
            "Latitude",
532
15
            "rftap.lat",
533
15
            FT_DOUBLE, BASE_NONE|BASE_UNIT_STRING, UNS(&units_degree_degrees), 0,
534
15
            "Latitude of receiver (-90..90 degrees), using WGS 84 datum: wikipedia.org/wiki/World_Geodetic_System", HFILL }},
535
15
        { &hf_rftap_longitude, {
536
15
            "Longitude",
537
15
            "rftap.lon",
538
15
            FT_DOUBLE, BASE_NONE|BASE_UNIT_STRING, UNS(&units_degree_degrees), 0,
539
15
            "Longitude of receiver (-180..180 degrees), using WGS 84 datum: wikipedia.org/wiki/World_Geodetic_System", HFILL }},
540
15
        { &hf_rftap_altitude, {
541
15
            "Altitude",
542
15
            "rftap.alt",
543
15
            FT_DOUBLE, BASE_NONE|BASE_UNIT_STRING, UNS(&units_meter_meters), 0,
544
15
            "Altitude of receiver, in meters, using WGS 84 datum: wikipedia.org/wiki/World_Geodetic_System", HFILL }},
545
546
        /* rftap tagged parameters */
547
548
15
        { &hf_rftap_subdissector_name, {
549
15
            "Dissector Name",
550
15
            "rftap.dissector",
551
15
            FT_STRING, BASE_NONE, NULL, 0,
552
15
            "Name of sub-dissector used for packet data (alternative to DLT field)", HFILL }}
553
15
    };
554
555
    /* Register the protocol name and description */
556
15
    proto_rftap = proto_register_protocol("RFtap Protocol", "RFtap", "rftap");
557
558
    /* Register the header fields and subtrees */
559
15
    proto_register_field_array(proto_rftap, hf, array_length(hf));
560
15
    proto_register_subtree_array(ett, array_length(ett));
561
562
15
    register_dissector("rftap", dissect_rftap, proto_rftap);
563
15
}
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
15
{
572
15
    pcap_pktdata_handle = find_dissector_add_dependency("pcap_pktdata", proto_rftap);
573
15
    heur_dissector_add("udp", dissect_rftap_heur, "RFtap over UDP", "rftap", proto_rftap, HEURISTIC_ENABLE);
574
15
}
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
 */