Revert "TODO epan/dissectors/asn1/kerberos/packet-kerberos-template.c new GSS flags"
[wireshark-sm.git] / epan / dissectors / packet-rftap.c
blob6a034bc4d44cc60bcee9a962c3819bc3dcd4afba
1 /*
2 * packet-rftap.c
3 * Decode packets with a RFtap header
4 * Copyright 2016, Jonathan Brucker <jonathan.brucke@gmail.com>
6 * Wireshark - Network traffic analyzer
7 * By Gerald Combs <gerald@wireshark.org>
8 * Copyright 1998 Gerald Combs
10 * SPDX-License-Identifier: GPL-2.0-or-later
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.
21 * Official specification:
22 * https://rftap.github.io
25 #include <config.h>
27 #include <epan/packet.h>
28 #include <epan/unit_strings.h>
30 #include <wsutil/array.h>
32 /* Prototypes */
33 /* (Required to prevent [-Wmissing-prototypes] warnings */
34 void proto_reg_handoff_rftap(void);
35 void proto_register_rftap(void);
37 /* protocols */
38 static int proto_rftap;
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;
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;
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;
81 /* rftap tag IDs >= 16 */
82 static int hf_rftap_subdissector_name;
84 /* subtree pointers */
85 static int ett_rftap;
86 static int ett_rftap_fixed_header;
87 static int ett_rftap_flags;
89 static dissector_handle_t pcap_pktdata_handle;
91 #define RFTAP_MAGIC 0x61744652UL /* "RFta" */
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
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));
123 /* dissect the rftap header part of the packet
124 * returns Data Link Type (dlt) and subdissector name
126 static void
127 dissect_rftap_header(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, uint32_t *dlt, const uint8_t **subdissector_name)
129 proto_item *ti_header;
130 proto_tree *header_tree;
131 int32_t offset;
132 int32_t len;
133 uint64_t flags;
134 uint32_t flag_bit;
135 uint32_t tag_id;
136 int32_t tag_len;
137 uint32_t tag_flags;
138 double double_val;
139 float float_val;
140 char *power_units;
142 static int * const flag_fields[] = {
143 &hf_rftap_present_dlt,
144 &hf_rftap_present_freq,
145 &hf_rftap_present_nomfreq,
146 &hf_rftap_present_freqofs,
147 &hf_rftap_power_is_in_dbm,
148 &hf_rftap_present_signal_power,
149 &hf_rftap_present_noise_power,
150 &hf_rftap_present_snr,
151 &hf_rftap_present_signal_quality,
152 &hf_rftap_time_is_unix_time,
153 &hf_rftap_present_time,
154 &hf_rftap_present_duration,
155 &hf_rftap_present_location,
156 &hf_rftap_present_reserved_field_13,
157 &hf_rftap_present_reserved_field_14,
158 &hf_rftap_present_reserved_field_15,
159 NULL
162 *dlt = 0xffffffff;
163 *subdissector_name = NULL;
165 /* rftap fixed header sub-tree */
167 ti_header = proto_tree_add_item(tree, hf_rftap_fixed_header, tvb, 0, 8, ENC_NA);
168 header_tree = proto_item_add_subtree(ti_header, ett_rftap_fixed_header);
170 proto_tree_add_item(header_tree, hf_rftap_magic, tvb, 0, 4, ENC_LITTLE_ENDIAN);
171 len = 4 * (int32_t) tvb_get_letohs(tvb, 4); /* convert to length in bytes */
172 proto_tree_add_uint(header_tree, hf_rftap_len, tvb, 4, 2, len); /* show length in bytes */
173 proto_tree_add_bitmask_ret_uint64(header_tree, tvb, 6, hf_rftap_flags,
174 ett_rftap_flags, flag_fields, ENC_LITTLE_ENDIAN, &flags);
176 /* rftap parameter fields */
178 power_units = (flags & (1 << RFTAP_TAG_POWER_IS_IN_DBM)) ? "dBm" : "dB";
180 offset = 8;
181 flag_bit = 1;
182 for (tag_id = 0; tag_id < 16; tag_id++, flag_bit<<=1) {
184 if (!(flags & flag_bit))
185 continue; /* parameter is not present, skip */
187 switch (tag_id) {
188 case RFTAP_TAG_DLT:
189 proto_tree_add_item_ret_uint(tree, hf_rftap_dlt, tvb, offset, 4, ENC_LITTLE_ENDIAN, dlt);
190 offset += 4;
191 break;
192 case RFTAP_TAG_FREQ:
193 proto_tree_add_item(tree, hf_rftap_freq, tvb, offset, 8, ENC_LITTLE_ENDIAN);
194 offset += 8;
195 break;
196 case RFTAP_TAG_NOM_FREQ:
197 proto_tree_add_item(tree, hf_rftap_nomfreq, tvb, offset, 8, ENC_LITTLE_ENDIAN);
198 offset += 8;
199 break;
200 case RFTAP_TAG_FREQ_OFS:
201 proto_tree_add_item(tree, hf_rftap_freqofs, tvb, offset, 8, ENC_LITTLE_ENDIAN);
202 offset += 8;
203 break;
204 case RFTAP_TAG_POWER_IS_IN_DBM:
205 /* do nothing, it's already decoded in flags bit-field */
206 break;
207 case RFTAP_TAG_SIGNAL_POWER:
208 float_val = tvb_get_letohieee_float(tvb, offset);
209 proto_tree_add_float_format_value(tree, hf_rftap_signal_power, tvb, offset, 4, float_val, "%.2f %s", float_val, power_units);
210 offset += 4;
211 break;
212 case RFTAP_TAG_NOISE_POWER:
213 float_val = tvb_get_letohieee_float(tvb, offset);
214 proto_tree_add_float_format_value(tree, hf_rftap_noise_power, tvb, offset, 4, float_val, "%.2f %s", float_val, power_units);
215 offset += 4;
216 break;
217 case RFTAP_TAG_SNR:
218 float_val = tvb_get_letohieee_float(tvb, offset);
219 proto_tree_add_float_format_value(tree, hf_rftap_snr, tvb, offset, 4, float_val, "%.2f dB", float_val);
220 offset += 4;
221 break;
222 case RFTAP_TAG_SIGNAL_QUALITY:
223 proto_tree_add_item(tree, hf_rftap_signal_quality, tvb, offset, 4, ENC_LITTLE_ENDIAN);
224 offset += 4;
225 break;
226 case RFTAP_TAG_TIME_IS_UNIX_TIME:
227 /* do nothing, it's already decoded in flags bit-field */
228 break;
229 case RFTAP_TAG_TIME:
230 double_val = tvb_get_letohieee_double(tvb, offset);
231 proto_tree_add_double_format_value(tree, hf_rftap_time_int, tvb, offset, 8, double_val, "%.0f seconds", double_val);
232 double_val = tvb_get_letohieee_double(tvb, offset + 8);
233 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 double_val += tvb_get_letohieee_double(tvb, offset);
236 proto_tree_add_double_format_value(tree, hf_rftap_time, tvb, offset, 16, double_val, "%.6f seconds", double_val);
237 offset += 16;
238 break;
239 case RFTAP_TAG_DURATION:
240 proto_tree_add_item(tree, hf_rftap_duration, tvb, offset, 8, ENC_LITTLE_ENDIAN);
241 offset += 8;
242 break;
243 case RFTAP_TAG_LOCATION:
244 proto_tree_add_item(tree, hf_rftap_latitude, tvb, offset, 8, ENC_LITTLE_ENDIAN);
245 proto_tree_add_item(tree, hf_rftap_longitude, tvb, offset+8, 8, ENC_LITTLE_ENDIAN);
246 proto_tree_add_item(tree, hf_rftap_altitude, tvb, offset+16, 8, ENC_LITTLE_ENDIAN);
247 offset += 24;
248 break;
249 default:
250 return; /* we've hit a parameter we can't decode, abort */
254 if (offset >= len)
255 return; /* there are no tagged parameters to decode, goodbye */
257 /* rftap tagged parameter fields */
259 tag_id = tvb_get_letohs(tvb, offset);
260 tag_len = tvb_get_uint8(tvb, offset+2);
261 tag_flags = tvb_get_uint8(tvb, offset+3);
263 if ((tag_id != RFTAP_TAG_DISSECTOR_NAME) || (tag_len == 0) || (tag_len == 255) || (tag_flags != 255))
264 return; /* we've hit a tagged parameter we can't decode, abort */
266 proto_tree_add_item_ret_string(tree, hf_rftap_subdissector_name, tvb,
267 offset+4, tag_len, ENC_ASCII, pinfo->pool, subdissector_name);
270 /* Main entry point to dissect the packets.
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.
276 static int
277 dissect_rftap(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
278 void *data _U_)
280 proto_item *ti;
281 proto_tree *rftap_tree;
283 tvbuff_t *rftap_tvb; /* the first part of the packet */
284 tvbuff_t *subdissector_tvb; /* the second part of the packet */
286 int32_t rftap_len; /* length in bytes */
287 dissector_handle_t subdissector_handle;
288 uint32_t subdissector_dlt;
289 const uint8_t *subdissector_name;
291 /* heuristics */
293 if (tvb_captured_length(tvb) < 8) /* 4 magic + 2 len + 2 flags = 8 bytes */
294 return 0;
296 if (tvb_get_letohl(tvb, 0) != RFTAP_MAGIC)
297 return 0;
299 /* column info */
301 col_set_str(pinfo->cinfo, COL_PROTOCOL, "RFTAP");
302 col_clear(pinfo->cinfo, COL_INFO);
303 clear_address(&pinfo->src);
304 clear_address(&pinfo->dst);
306 /* dissect part 1: rftap header */
308 rftap_len = 4 * (int32_t) tvb_get_letohs(tvb, 4);
309 rftap_tvb = tvb_new_subset_length_caplen(tvb, 0, rftap_len, rftap_len);
311 ti = proto_tree_add_protocol_format(tree, proto_rftap, rftap_tvb, 0, -1,
312 "RFtap Protocol (%d bytes)", rftap_len);
313 rftap_tree = proto_item_add_subtree(ti, ett_rftap);
315 dissect_rftap_header(rftap_tvb, rftap_tree, pinfo, &subdissector_dlt, &subdissector_name);
317 /* dissect part 2: data packet */
319 subdissector_tvb = tvb_new_subset_remaining(tvb, rftap_len);
321 /* try using data link type (DLT) */
322 if (subdissector_dlt != 0xffffffff) {
323 call_dissector_with_data(pcap_pktdata_handle, subdissector_tvb, pinfo, tree, &subdissector_dlt);
324 return tvb_captured_length(tvb);
327 /* try using dissector name */
328 if (subdissector_name) {
329 subdissector_handle = find_dissector(subdissector_name);
330 if (subdissector_handle) {
331 call_dissector_with_data(subdissector_handle, subdissector_tvb, pinfo, tree, NULL);
332 return tvb_captured_length(tvb);
336 /* fallback using plain data dissector */
337 call_data_dissector(subdissector_tvb, pinfo, tree);
338 return tvb_captured_length(tvb);
341 static bool
342 dissect_rftap_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
344 return dissect_rftap(tvb, pinfo, tree, data) != 0;
347 /* Register the protocol with Wireshark. */
348 void
349 proto_register_rftap(void)
351 /* Setup protocol subtree array */
352 static int *ett[] = {
353 &ett_rftap,
354 &ett_rftap_fixed_header,
355 &ett_rftap_flags
358 /* Setup list of header fields */
359 static hf_register_info hf[] = {
361 /* rftap fixed header */
363 { &hf_rftap_fixed_header, {
364 "RFtap Fixed header",
365 "rftap.fixedheader",
366 FT_NONE, BASE_NONE, NULL, 0,
367 "RFtap Fixed 8-byte Header", HFILL }},
369 { &hf_rftap_magic, {
370 "Magic",
371 "rftap.magic",
372 FT_UINT32, BASE_HEX, NULL, 0,
373 "RFtap signature: wikipedia.org/wiki/File_format#Magic_number", HFILL }},
374 { &hf_rftap_len, {
375 "Length",
376 "rftap.len",
377 FT_UINT32, BASE_DEC, NULL, 0,
378 "Length (in bytes) of entire rftap header, including tagged (optional) parameters", HFILL }},
379 { &hf_rftap_flags, {
380 "Flags",
381 "rftap.flags",
382 FT_UINT16, BASE_HEX, NULL, 0,
383 "RFtap flags", HFILL }},
385 /* flags bit-field */
387 {&hf_rftap_present_dlt, {
388 "DLT Present",
389 "rftap.present.dlt",
390 FT_BOOLEAN, 16, NULL, 0x0001,
391 "Specifies if the DLT (Data Link Type) field is present", HFILL }},
392 {&hf_rftap_present_freq, {
393 "Frequency Present",
394 "rftap.present.freq",
395 FT_BOOLEAN, 16, NULL, 0x0002,
396 "Specifies if the Frequency field is present", HFILL }},
397 {&hf_rftap_present_nomfreq, {
398 "Nominal Frequency Present",
399 "rftap.present.nomfreq",
400 FT_BOOLEAN, 16, NULL, 0x0004,
401 "Specifies if the Nominal Frequency field is present", HFILL }},
402 {&hf_rftap_present_freqofs, {
403 "Frequency Offset Present",
404 "rftap.present.freqofs",
405 FT_BOOLEAN, 16, NULL, 0x0008,
406 "Specifies if the Frequency Offset field is present", HFILL }},
407 {&hf_rftap_power_is_in_dbm, {
408 "Power is in dBm Units",
409 "rftap.isdbm",
410 FT_BOOLEAN, 16, NULL, 0x0010,
411 "Specifies if the Power is specified in dBm units", HFILL }},
412 {&hf_rftap_present_signal_power, {
413 "Signal Power Present",
414 "rftap.present.power",
415 FT_BOOLEAN, 16, NULL, 0x0020,
416 "Specifies if the Signal Power field is present", HFILL }},
417 {&hf_rftap_present_noise_power, {
418 "Noise Power Present",
419 "rftap.present.noise",
420 FT_BOOLEAN, 16, NULL, 0x0040,
421 "Specifies if the Noise Power field is present", HFILL }},
422 {&hf_rftap_present_snr, {
423 "SNR Present",
424 "rftap.present.snr",
425 FT_BOOLEAN, 16, NULL, 0x0080,
426 "Specifies if the SNR field is present", HFILL }},
427 {&hf_rftap_present_signal_quality, {
428 "Signal Quality Present",
429 "rftap.present.qual",
430 FT_BOOLEAN, 16, NULL, 0x0100,
431 "Specifies if the Signal Quality field is present", HFILL }},
432 {&hf_rftap_time_is_unix_time, {
433 "Time standard is Unix Time",
434 "rftap.isunixtime",
435 FT_BOOLEAN, 16, NULL, 0x0200,
436 "Specifies if the time standard is Unix Time: wikipedia.org/wiki/Unix_time", HFILL }},
437 {&hf_rftap_present_time, {
438 "Time Present",
439 "rftap.present.time",
440 FT_BOOLEAN, 16, NULL, 0x0400,
441 "Specifies if the Time field is present", HFILL }},
442 {&hf_rftap_present_duration, {
443 "Duration Present",
444 "rftap.present.duration",
445 FT_BOOLEAN, 16, NULL, 0x0800,
446 "Specifies if the Duration field is present", HFILL }},
447 {&hf_rftap_present_location, {
448 "Location Present",
449 "rftap.present.location",
450 FT_BOOLEAN, 16, NULL, 0x1000,
451 "Specifies if the Location field is present", HFILL }},
452 {&hf_rftap_present_reserved_field_13, {
453 "Reserved Field 13 Present",
454 "rftap.present.field13",
455 FT_BOOLEAN, 16, NULL, 0x2000,
456 "Specifies if the Reserved Field 13 is present", HFILL }},
457 {&hf_rftap_present_reserved_field_14, {
458 "Reserved Field 14 Present",
459 "rftap.present.field14",
460 FT_BOOLEAN, 16, NULL, 0x4000,
461 "Specifies if the Reserved Field 14 is present", HFILL }},
462 {&hf_rftap_present_reserved_field_15, {
463 "Reserved Field 15 Present",
464 "rftap.present.field15",
465 FT_BOOLEAN, 16, NULL, 0x8000,
466 "Specifies if the Reserved Field 15 is present", HFILL }},
468 /* rftap parameters */
470 { &hf_rftap_dlt, {
471 "Data Link Type (DLT)",
472 "rftap.dlt",
473 FT_UINT32, BASE_DEC, NULL, 0,
474 "Data Link Type (DLT) of the encapsulated packet: www.tcpdump.org/linktypes.html", HFILL }},
475 { &hf_rftap_freq, {
476 "Frequency",
477 "rftap.freq",
478 FT_DOUBLE, BASE_NONE|BASE_UNIT_STRING, UNS(&units_hz), 0,
479 "Actual (measured) carrier frequency, in Hertz (not necessarily center frequency)", HFILL }},
480 { &hf_rftap_nomfreq, {
481 "Nominal Frequency",
482 "rftap.nomfreq",
483 FT_DOUBLE, BASE_NONE|BASE_UNIT_STRING, UNS(&units_hz), 0,
484 "Nominal carrier frequency, in Hertz (the ideal frequency, ignoring freq errors)", HFILL }},
485 { &hf_rftap_freqofs, {
486 "Frequency Offset",
487 "rftap.freqofs",
488 FT_DOUBLE, BASE_NONE|BASE_UNIT_STRING, UNS(&units_hz), 0,
489 "Carrier frequency offset, in Hertz: wikipedia.org/wiki/Carrier_frequency_offset", HFILL }},
490 { &hf_rftap_signal_power, {
491 "Signal Power",
492 "rftap.power",
493 FT_FLOAT, BASE_NONE, NULL, 0,
494 "Signal power, in dB or dBm units: wikipedia.org/wiki/DBm", HFILL }},
495 { &hf_rftap_noise_power, {
496 "Noise Power",
497 "rftap.noise",
498 FT_FLOAT, BASE_NONE, NULL, 0,
499 "Noise power, in dB or dBm units: wikipedia.org/wiki/DBm", HFILL }},
500 { &hf_rftap_snr, {
501 "SNR",
502 "rftap.snr",
503 FT_FLOAT, BASE_NONE, NULL, 0,
504 "Signal to Noise ratio (decibel units): wikipedia.org/wiki/Signal-to-noise_ratio", HFILL }},
505 { &hf_rftap_signal_quality, {
506 "Signal Quality",
507 "rftap.qual",
508 FT_FLOAT, BASE_NONE, NULL, 0,
509 "Signal quality, arbitrary units from 0.0 (worst) to 1.0 (best)", HFILL }},
510 { &hf_rftap_time_int, {
511 "Time (integer part)",
512 "rftap.timeint",
513 FT_DOUBLE, BASE_NONE, NULL, 0,
514 "The integer part of event time, in seconds, since epoch: wikipedia.org/wiki/Epoch_(reference_date)", HFILL }},
515 { &hf_rftap_time_frac, {
516 "Time (fractional part)",
517 "rftap.timefrac",
518 FT_DOUBLE, BASE_NONE, NULL, 0,
519 "The fractional part of event time, in seconds, since epoch: wikipedia.org/wiki/Epoch_(reference_date)", HFILL }},
520 { &hf_rftap_time, {
521 "Time",
522 "rftap.time",
523 FT_DOUBLE, BASE_NONE, NULL, 0,
524 "The event time, in seconds, since epoch: wikipedia.org/wiki/Epoch_(reference_date)", HFILL }},
525 { &hf_rftap_duration, {
526 "Duration",
527 "rftap.duration",
528 FT_DOUBLE, BASE_NONE|BASE_UNIT_STRING, UNS(&units_second_seconds), 0,
529 "The duration of the event (packet), in seconds", HFILL }},
530 { &hf_rftap_latitude, {
531 "Latitude",
532 "rftap.lat",
533 FT_DOUBLE, BASE_NONE|BASE_UNIT_STRING, UNS(&units_degree_degrees), 0,
534 "Latitude of receiver (-90..90 degrees), using WGS 84 datum: wikipedia.org/wiki/World_Geodetic_System", HFILL }},
535 { &hf_rftap_longitude, {
536 "Longitude",
537 "rftap.lon",
538 FT_DOUBLE, BASE_NONE|BASE_UNIT_STRING, UNS(&units_degree_degrees), 0,
539 "Longitude of receiver (-180..180 degrees), using WGS 84 datum: wikipedia.org/wiki/World_Geodetic_System", HFILL }},
540 { &hf_rftap_altitude, {
541 "Altitude",
542 "rftap.alt",
543 FT_DOUBLE, BASE_NONE|BASE_UNIT_STRING, UNS(&units_meter_meters), 0,
544 "Altitude of receiver, in meters, using WGS 84 datum: wikipedia.org/wiki/World_Geodetic_System", HFILL }},
546 /* rftap tagged parameters */
548 { &hf_rftap_subdissector_name, {
549 "Dissector Name",
550 "rftap.dissector",
551 FT_STRING, BASE_NONE, NULL, 0,
552 "Name of sub-dissector used for packet data (alternative to DLT field)", HFILL }}
555 /* Register the protocol name and description */
556 proto_rftap = proto_register_protocol("RFtap Protocol", "RFtap", "rftap");
558 /* Register the header fields and subtrees */
559 proto_register_field_array(proto_rftap, hf, array_length(hf));
560 proto_register_subtree_array(ett, array_length(ett));
562 register_dissector("rftap", dissect_rftap, proto_rftap);
566 /* Protocol registration routine. This function is also called by
567 * Wireshark's preferences manager whenever "Apply" or "OK" are pressed.
569 void
570 proto_reg_handoff_rftap(void)
572 pcap_pktdata_handle = find_dissector_add_dependency("pcap_pktdata", proto_rftap);
573 heur_dissector_add("udp", dissect_rftap_heur, "RFtap over UDP", "rftap", proto_rftap, HEURISTIC_ENABLE);
577 * Editor modelines - https://www.wireshark.org/tools/modelines.html
579 * Local variables:
580 * c-basic-offset: 4
581 * tab-width: 8
582 * indent-tabs-mode: nil
583 * End:
585 * vi: set shiftwidth=4 tabstop=8 expandtab:
586 * :indentSize=4:tabSize=8:noTabs=true: