diff options
author | Jonathan Brucker <jonathan.brucke@gmail.com> | 2016-08-31 09:05:09 +0000 |
---|---|---|
committer | Michael Mann <mmann78@netscape.net> | 2016-08-31 11:41:03 +0000 |
commit | bccbae58a14c2cf635f5fd3c363b2c355215e0f9 (patch) | |
tree | a98afb3736672f7494674d5a1c9423ec801637c2 /epan/dissectors/packet-rftap.c | |
parent | 6362183825cb4a12fd091b78d88619606dec4554 (diff) |
rftap: add new dissector
The RFtap protocol is a simple metadata header designed to provide
Radio Frequency (RF) metadata about frames.
For official specifications see: https://rftap.github.io/
Signed-off-by: Jonathan Brucker <jonathan.brucke@gmail.com>
Change-Id: I0d008b2baadcc5cc9577113e9795eef2691b961a
Reviewed-on: https://code.wireshark.org/review/17355
Petri-Dish: Alexis La Goutte <alexis.lagoutte@gmail.com>
Tested-by: Petri Dish Buildbot <buildbot-no-reply@wireshark.org>
Reviewed-by: Alexis La Goutte <alexis.lagoutte@gmail.com>
Reviewed-by: Michael Mann <mmann78@netscape.net>
Diffstat (limited to 'epan/dissectors/packet-rftap.c')
-rw-r--r-- | epan/dissectors/packet-rftap.c | 608 |
1 files changed, 608 insertions, 0 deletions
diff --git a/epan/dissectors/packet-rftap.c b/epan/dissectors/packet-rftap.c new file mode 100644 index 0000000000..148d6a470f --- /dev/null +++ b/epan/dissectors/packet-rftap.c @@ -0,0 +1,608 @@ +/* + * packet-rftap.c + * Decode packets with a RFtap header + * Copyright 2016, Jonathan Brucker <jonathan.brucke@gmail.com> + * + * Wireshark - Network traffic analyzer + * By Gerald Combs <gerald@wireshark.org> + * Copyright 1998 Gerald Combs + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +/* + * The RFtap header is a simple meta-data header designed to provide + * RF (Radio Frequency) meta-data about frames, such as: + * - Accurate signal and noise power + * - Accurate timing and phase information + * - Accurate carrier and Doppler frequencies, and more. + * The RFtap protocol can be used to encapsulate any type of frame. + * + * Official specification: + * https://rftap.github.io + */ + +#include <config.h> + +#include <epan/packet.h> +#include <epan/prefs.h> + +/* Prototypes */ +/* (Required to prevent [-Wmissing-prototypes] warnings */ +void proto_reg_handoff_rftap(void); +void proto_register_rftap(void); + +/* protocols */ +static int proto_rftap = -1; + +/* rftap fixed fields */ +static int hf_rftap_fixed_header = -1; +static int hf_rftap_magic = -1; +static int hf_rftap_len = -1; /* length in bytes */ +static int hf_rftap_flags = -1; + +/* rftap flags bit-field (16 bits) */ +static int hf_rftap_present_dlt = -1; +static int hf_rftap_present_freq = -1; +static int hf_rftap_present_nomfreq = -1; +static int hf_rftap_present_freqofs = -1; +static int hf_rftap_power_is_in_dbm = -1; +static int hf_rftap_present_signal_power = -1; +static int hf_rftap_present_noise_power = -1; +static int hf_rftap_present_snr = -1; +static int hf_rftap_present_signal_quality = -1; +static int hf_rftap_time_is_unix_time = -1; +static int hf_rftap_present_time = -1; +static int hf_rftap_present_duration = -1; +static int hf_rftap_present_location = -1; +static int hf_rftap_present_reserved_field_13 = -1; +static int hf_rftap_present_reserved_field_14 = -1; +static int hf_rftap_present_reserved_field_15 = -1; + +/* rftap optional fields */ +static int hf_rftap_dlt = -1; +static int hf_rftap_freq = -1; +static int hf_rftap_nomfreq = -1; +static int hf_rftap_freqofs = -1; +static int hf_rftap_signal_power = -1; +static int hf_rftap_noise_power = -1; +static int hf_rftap_snr = -1; +static int hf_rftap_signal_quality = -1; +static int hf_rftap_time_int = -1; +static int hf_rftap_time_frac = -1; +static int hf_rftap_time = -1; +static int hf_rftap_duration = -1; +static int hf_rftap_latitude = -1; +static int hf_rftap_longitude = -1; +static int hf_rftap_altitude = -1; + +/* rftap tag IDs >= 16 */ +static int hf_rftap_subdissector_name = -1; + +/* subtree pointers */ +static gint ett_rftap = -1; +static gint ett_rftap_fixed_header = -1; +static gint ett_rftap_flags = -1; + +static dissector_handle_t pcap_pktdata_handle; + +#define RFTAP_MAGIC 0x61744652UL /* "RFta" */ + +enum rftap_tag_id { + RFTAP_TAG_DLT = 0, + RFTAP_TAG_FREQ = 1, + RFTAP_TAG_NOM_FREQ = 2, + RFTAP_TAG_FREQ_OFS = 3, + RFTAP_TAG_POWER_IS_IN_DBM = 4, + RFTAP_TAG_SIGNAL_POWER = 5, + RFTAP_TAG_NOISE_POWER = 6, + RFTAP_TAG_SNR = 7, + RFTAP_TAG_SIGNAL_QUALITY = 8, + RFTAP_TAG_TIME_IS_UNIX_TIME = 9, + RFTAP_TAG_TIME = 10, + RFTAP_TAG_DURATION = 11, + RFTAP_TAG_LOCATION = 12, + RFTAP_TAG_RESERVED_13 = 13, + RFTAP_TAG_RESERVED_14 = 14, + RFTAP_TAG_RESERVED_15 = 15, + RFTAP_TAG_DISSECTOR_NAME = 16 +}; + +/* This is the header as it is used by rftap-generating software. + * It is not used by the wireshark dissector and provided for reference only. +struct rftap_hdr { + le32 magic; // "RFta" + le16 len32; // sizeof(rftap_hdr) / sizeof(le32) + le16 flags; // bitfield indicating presence of parameters + le32 data[]; +} __attribute__((packed)); + */ + +/* dissect the rftap header part of the packet + * returns Data Link Type (dlt) and subdissector name + */ +static void +dissect_rftap_header(tvbuff_t *tvb, proto_tree *tree, guint32 *dlt, const guint8 **subdissector_name) +{ + proto_item *ti; + proto_item *ti_header; + proto_tree *header_tree; + gint32 offset; + gint32 len; + guint64 flags; + guint32 flag_bit; + guint32 tag_id; + gint32 tag_len; + guint32 tag_flags; + gdouble double_val; + gfloat float_val; + char *power_units; + + static const int *flag_fields[] = { + &hf_rftap_present_dlt, + &hf_rftap_present_freq, + &hf_rftap_present_nomfreq, + &hf_rftap_present_freqofs, + &hf_rftap_power_is_in_dbm, + &hf_rftap_present_signal_power, + &hf_rftap_present_noise_power, + &hf_rftap_present_snr, + &hf_rftap_present_signal_quality, + &hf_rftap_time_is_unix_time, + &hf_rftap_present_time, + &hf_rftap_present_duration, + &hf_rftap_present_location, + &hf_rftap_present_reserved_field_13, + &hf_rftap_present_reserved_field_14, + &hf_rftap_present_reserved_field_15, + NULL + }; + + *dlt = 0xffffffff; + *subdissector_name = NULL; + + /* rftap fixed header sub-tree */ + + ti_header = proto_tree_add_item(tree, hf_rftap_fixed_header, tvb, 0, 8, ENC_NA); + header_tree = proto_item_add_subtree(ti_header, ett_rftap_fixed_header); + + proto_tree_add_item(header_tree, hf_rftap_magic, tvb, 0, 4, ENC_LITTLE_ENDIAN); + len = 4 * (gint32) tvb_get_letohs(tvb, 4); /* convert to length in bytes */ + proto_tree_add_uint(header_tree, hf_rftap_len, tvb, 4, 2, len); /* show length in bytes */ + proto_tree_add_bitmask_ret_uint64(header_tree, tvb, 6, hf_rftap_flags, + ett_rftap_flags, flag_fields, ENC_LITTLE_ENDIAN, &flags); + + /* rftap parameter fields */ + + power_units = (flags & (1 << RFTAP_TAG_POWER_IS_IN_DBM)) ? "dBm" : "dB"; + + offset = 8; + flag_bit = 1; + for (tag_id = 0; tag_id < 16; tag_id++, flag_bit<<=1) { + + if (!(flags & flag_bit)) + continue; /* parameter is not present, skip */ + + switch (tag_id) { + case RFTAP_TAG_DLT: + proto_tree_add_item_ret_uint(tree, hf_rftap_dlt, tvb, offset, 4, ENC_LITTLE_ENDIAN, dlt); + offset += 4; + break; + case RFTAP_TAG_FREQ: + ti = proto_tree_add_item(tree, hf_rftap_freq, tvb, offset, 8, ENC_LITTLE_ENDIAN); + proto_item_append_text(ti, " Hz"); + offset += 8; + break; + case RFTAP_TAG_NOM_FREQ: + ti = proto_tree_add_item(tree, hf_rftap_nomfreq, tvb, offset, 8, ENC_LITTLE_ENDIAN); + proto_item_append_text(ti, " Hz"); + offset += 8; + break; + case RFTAP_TAG_FREQ_OFS: + ti = proto_tree_add_item(tree, hf_rftap_freqofs, tvb, offset, 8, ENC_LITTLE_ENDIAN); + proto_item_append_text(ti, " Hz"); + offset += 8; + break; + case RFTAP_TAG_POWER_IS_IN_DBM: + /* do nothing, it's already decoded in flags bit-field */ + break; + case RFTAP_TAG_SIGNAL_POWER: + float_val = tvb_get_letohieee_float(tvb, offset); + proto_tree_add_float_format_value(tree, hf_rftap_signal_power, tvb, offset, 4, float_val, "%.2f %s", float_val, power_units); + offset += 4; + break; + case RFTAP_TAG_NOISE_POWER: + float_val = tvb_get_letohieee_float(tvb, offset); + proto_tree_add_float_format_value(tree, hf_rftap_noise_power, tvb, offset, 4, float_val, "%.2f %s", float_val, power_units); + offset += 4; + break; + case RFTAP_TAG_SNR: + float_val = tvb_get_letohieee_float(tvb, offset); + proto_tree_add_float_format_value(tree, hf_rftap_snr, tvb, offset, 4, float_val, "%.2f dB", float_val); + offset += 4; + break; + case RFTAP_TAG_SIGNAL_QUALITY: + proto_tree_add_item(tree, hf_rftap_signal_quality, tvb, offset, 4, ENC_LITTLE_ENDIAN); + offset += 4; + break; + case RFTAP_TAG_TIME_IS_UNIX_TIME: + /* do nothing, it's already decoded in flags bit-field */ + break; + case RFTAP_TAG_TIME: + double_val = tvb_get_letohieee_double(tvb, offset); + proto_tree_add_double_format_value(tree, hf_rftap_time_int, tvb, offset, 8, double_val, "%.0f seconds", double_val); + double_val = tvb_get_letohieee_double(tvb, offset + 8); + proto_tree_add_double_format_value(tree, hf_rftap_time_frac, tvb, offset+8, 8, double_val, "%.9f seconds", double_val); + /* compute combined time: (not accurate, error is > 300 nanoseconds) */ + double_val += tvb_get_letohieee_double(tvb, offset); + proto_tree_add_double_format_value(tree, hf_rftap_time, tvb, offset, 16, double_val, "%.6f seconds", double_val); + offset += 16; + break; + case RFTAP_TAG_DURATION: + ti = proto_tree_add_item(tree, hf_rftap_duration, tvb, offset, 8, ENC_LITTLE_ENDIAN); + proto_item_append_text(ti, " seconds"); + offset += 8; + break; + case RFTAP_TAG_LOCATION: + ti = proto_tree_add_item(tree, hf_rftap_latitude, tvb, offset, 8, ENC_LITTLE_ENDIAN); + proto_item_append_text(ti, " degrees"); + ti = proto_tree_add_item(tree, hf_rftap_longitude, tvb, offset+8, 8, ENC_LITTLE_ENDIAN); + proto_item_append_text(ti, " degrees"); + ti = proto_tree_add_item(tree, hf_rftap_altitude, tvb, offset+16, 8, ENC_LITTLE_ENDIAN); + proto_item_append_text(ti, " meters"); + offset += 24; + break; + default: + return; /* we've hit a parameter we can't decode, abort */ + } + } + + if (offset >= len) + return; /* there are no tagged parameters to decode, goodbye */ + + /* rftap tagged parameter fields */ + + tag_id = tvb_get_letohs(tvb, offset); + tag_len = tvb_get_guint8(tvb, offset+2); + tag_flags = tvb_get_guint8(tvb, offset+3); + + if ((tag_id != RFTAP_TAG_DISSECTOR_NAME) || (tag_len == 0) || (tag_len == 255) || (tag_flags != 255)) + return; /* we've hit a tagged parameter we can't decode, abort */ + + proto_tree_add_item_ret_string(tree, hf_rftap_subdissector_name, tvb, + offset+4, tag_len, ENC_ASCII, wmem_packet_scope(), subdissector_name); +} + +/* Main entry point to dissect the packets. + * + * Each packet consists of two parts: + * - The rftap header, containing all the RF metadata. + * - The encapsulated data packet, decoded by a sub-dissector. + */ +static int +dissect_rftap(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, + void *data _U_) +{ + proto_item *ti; + proto_tree *rftap_tree; + + tvbuff_t *rftap_tvb; /* the first part of the packet */ + tvbuff_t *subdissector_tvb; /* the second part of the packet */ + + gint32 rftap_len; /* length in bytes */ + dissector_handle_t subdissector_handle; + guint32 subdissector_dlt; + const guint8 *subdissector_name; + + /* heuristics */ + + if (tvb_captured_length(tvb) < 8) /* 4 magic + 2 len + 2 flags = 8 bytes */ + return 0; + + if (tvb_get_letohl(tvb, 0) != RFTAP_MAGIC) + return 0; + + /* column info */ + + col_set_str(pinfo->cinfo, COL_PROTOCOL, "RFTAP"); + col_clear(pinfo->cinfo, COL_INFO); + clear_address(&pinfo->src); + clear_address(&pinfo->dst); + + /* dissect part 1: rftap header */ + + rftap_len = 4 * (gint32) tvb_get_letohs(tvb, 4); + rftap_tvb = tvb_new_subset(tvb, 0, rftap_len, rftap_len); + + ti = proto_tree_add_protocol_format(tree, proto_rftap, rftap_tvb, 0, -1, + "RFtap Protocol (%d bytes)", rftap_len); + rftap_tree = proto_item_add_subtree(ti, ett_rftap); + + dissect_rftap_header(rftap_tvb, rftap_tree, &subdissector_dlt, &subdissector_name); + + /* dissect part 2: data packet */ + + subdissector_tvb = tvb_new_subset_remaining(tvb, rftap_len); + + /* try using data link type (DLT) */ + if (subdissector_dlt != 0xffffffff) { + call_dissector_with_data(pcap_pktdata_handle, subdissector_tvb, pinfo, tree, &subdissector_dlt); + return tvb_captured_length(tvb); + } + + /* try using dissector name */ + if (subdissector_name) { + subdissector_handle = find_dissector(subdissector_name); + if (subdissector_handle) { + call_dissector_with_data(subdissector_handle, subdissector_tvb, pinfo, tree, NULL); + return tvb_captured_length(tvb); + } + } + + /* fallback using plain data dissector */ + call_data_dissector(subdissector_tvb, pinfo, tree); + return tvb_captured_length(tvb); +} + +static gboolean +dissect_rftap_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_) +{ + return dissect_rftap(tvb, pinfo, tree, data) != 0; +} + +/* Register the protocol with Wireshark. */ +void +proto_register_rftap(void) +{ + /* Setup protocol subtree array */ + static gint *ett[] = { + &ett_rftap, + &ett_rftap_fixed_header, + &ett_rftap_flags + }; + + /* Setup list of header fields */ + static hf_register_info hf[] = { + + /* rftap fixed header */ + + { &hf_rftap_fixed_header, { + "RFtap Fixed header", + "rftap.fixedheader", + FT_NONE, BASE_NONE, NULL, 0, + "RFtap Fixed 8-byte Header", HFILL }}, + + { &hf_rftap_magic, { + "Magic", + "rftap.magic", + FT_UINT32, BASE_HEX, NULL, 0, + "RFtap signature: wikipedia.org/wiki/File_format#Magic_number", HFILL }}, + { &hf_rftap_len, { + "Length", + "rftap.len", + FT_UINT32, BASE_DEC, NULL, 0, + "Length (in bytes) of entire rftap header, including tagged (optional) parameters", HFILL }}, + { &hf_rftap_flags, { + "Flags", + "rftap.flags", + FT_UINT16, BASE_HEX, NULL, 0, + "RFtap flags", HFILL }}, + + /* flags bit-field */ + + {&hf_rftap_present_dlt, { + "DLT Present", + "rftap.present.dlt", + FT_BOOLEAN, 16, NULL, 0x0001, + "Specifies if the DLT (Data Link Type) field is present", HFILL }}, + {&hf_rftap_present_freq, { + "Frequency Present", + "rftap.present.freq", + FT_BOOLEAN, 16, NULL, 0x0002, + "Specifies if the Frequency field is present", HFILL }}, + {&hf_rftap_present_nomfreq, { + "Nominal Frequency Present", + "rftap.present.nomfreq", + FT_BOOLEAN, 16, NULL, 0x0004, + "Specifies if the Nominal Frequency field is present", HFILL }}, + {&hf_rftap_present_freqofs, { + "Frequency Offset Present", + "rftap.present.freqofs", + FT_BOOLEAN, 16, NULL, 0x0008, + "Specifies if the Frequency Offset field is present", HFILL }}, + {&hf_rftap_power_is_in_dbm, { + "Power is in dBm Units", + "rftap.isdbm", + FT_BOOLEAN, 16, NULL, 0x0010, + "Specifies if the Power is specified in dBm units", HFILL }}, + {&hf_rftap_present_signal_power, { + "Signal Power Present", + "rftap.present.power", + FT_BOOLEAN, 16, NULL, 0x0020, + "Specifies if the Signal Power field is present", HFILL }}, + {&hf_rftap_present_noise_power, { + "Noise Power Present", + "rftap.present.noise", + FT_BOOLEAN, 16, NULL, 0x0040, + "Specifies if the Noise Power field is present", HFILL }}, + {&hf_rftap_present_snr, { + "SNR Present", + "rftap.present.snr", + FT_BOOLEAN, 16, NULL, 0x0080, + "Specifies if the SNR field is present", HFILL }}, + {&hf_rftap_present_signal_quality, { + "Signal Quality Present", + "rftap.present.qual", + FT_BOOLEAN, 16, NULL, 0x0100, + "Specifies if the Signal Quality field is present", HFILL }}, + {&hf_rftap_time_is_unix_time, { + "Time standard is Unix Time", + "rftap.isunixtime", + FT_BOOLEAN, 16, NULL, 0x0200, + "Specifies if the time standard is Unix Time: wikipedia.org/wiki/Unix_time", HFILL }}, + {&hf_rftap_present_time, { + "Time Present", + "rftap.present.time", + FT_BOOLEAN, 16, NULL, 0x0400, + "Specifies if the Time field is present", HFILL }}, + {&hf_rftap_present_duration, { + "Duration Present", + "rftap.present.duration", + FT_BOOLEAN, 16, NULL, 0x0800, + "Specifies if the Duration field is present", HFILL }}, + {&hf_rftap_present_location, { + "Location Present", + "rftap.present.location", + FT_BOOLEAN, 16, NULL, 0x1000, + "Specifies if the Location field is present", HFILL }}, + {&hf_rftap_present_reserved_field_13, { + "Reserved Field 13 Present", + "rftap.present.field13", + FT_BOOLEAN, 16, NULL, 0x2000, + "Specifies if the Reserved Field 13 is present", HFILL }}, + {&hf_rftap_present_reserved_field_14, { + "Reserved Field 14 Present", + "rftap.present.field14", + FT_BOOLEAN, 16, NULL, 0x4000, + "Specifies if the Reserved Field 14 is present", HFILL }}, + {&hf_rftap_present_reserved_field_15, { + "Reserved Field 15 Present", + "rftap.present.field15", + FT_BOOLEAN, 16, NULL, 0x8000, + "Specifies if the Reserved Field 15 is present", HFILL }}, + + /* rftap parameters */ + + { &hf_rftap_dlt, { + "Data Link Type (DLT)", + "rftap.dlt", + FT_UINT32, BASE_DEC, NULL, 0, + "Data Link Type (DLT) of the encapsulated packet: www.tcpdump.org/linktypes.html", HFILL }}, + { &hf_rftap_freq, { + "Frequency", + "rftap.freq", + FT_DOUBLE, BASE_NONE, NULL, 0, + "Actual (measured) carrier frequency, in Hertz (not necessarily center frequency)", HFILL }}, + { &hf_rftap_nomfreq, { + "Nominal Frequency", + "rftap.nomfreq", + FT_DOUBLE, BASE_NONE, NULL, 0, + "Nominal carrier frequency, in Hertz (the ideal frequency, ignoring freq errors)", HFILL }}, + { &hf_rftap_freqofs, { + "Frequency Offset", + "rftap.freqofs", + FT_DOUBLE, BASE_NONE, NULL, 0, + "Carrier frequency offset, in Hertz: wikipedia.org/wiki/Carrier_frequency_offset", HFILL }}, + { &hf_rftap_signal_power, { + "Signal Power", + "rftap.power", + FT_FLOAT, BASE_NONE, NULL, 0, + "Signal power, in dB or dBm units: wikipedia.org/wiki/DBm", HFILL }}, + { &hf_rftap_noise_power, { + "Noise Power", + "rftap.noise", + FT_FLOAT, BASE_NONE, NULL, 0, + "Noise power, in dB or dBm units: wikipedia.org/wiki/DBm", HFILL }}, + { &hf_rftap_snr, { + "SNR", + "rftap.snr", + FT_FLOAT, BASE_NONE, NULL, 0, + "Signal to Noise ratio (decibel units): wikipedia.org/wiki/Signal-to-noise_ratio", HFILL }}, + { &hf_rftap_signal_quality, { + "Signal Quality", + "rftap.qual", + FT_FLOAT, BASE_NONE, NULL, 0, + "Signal quality, arbitrary units from 0.0 (worst) to 1.0 (best)", HFILL }}, + { &hf_rftap_time_int, { + "Time (integer part)", + "rftap.timeint", + FT_DOUBLE, BASE_NONE, NULL, 0, + "The integer part of event time, in seconds, since epoch: wikipedia.org/wiki/Epoch_(reference_date)", HFILL }}, + { &hf_rftap_time_frac, { + "Time (fractional part)", + "rftap.timefrac", + FT_DOUBLE, BASE_NONE, NULL, 0, + "The fractional part of event time, in seconds, since epoch: wikipedia.org/wiki/Epoch_(reference_date)", HFILL }}, + { &hf_rftap_time, { + "Time", + "rftap.time", + FT_DOUBLE, BASE_NONE, NULL, 0, + "The event time, in seconds, since epoch: wikipedia.org/wiki/Epoch_(reference_date)", HFILL }}, + { &hf_rftap_duration, { + "Duration", + "rftap.duration", + FT_DOUBLE, BASE_NONE, NULL, 0, + "The duration of the event (packet), in seconds", HFILL }}, + { &hf_rftap_latitude, { + "Latitude", + "rftap.lat", + FT_DOUBLE, BASE_NONE, NULL, 0, + "Latitude of receiver (-90..90 degrees), using WGS 84 datum: wikipedia.org/wiki/World_Geodetic_System", HFILL }}, + { &hf_rftap_longitude, { + "Longitude", + "rftap.lon", + FT_DOUBLE, BASE_NONE, NULL, 0, + "Longitude of receiver (-180..180 degrees), using WGS 84 datum: wikipedia.org/wiki/World_Geodetic_System", HFILL }}, + { &hf_rftap_altitude, { + "Altitude", + "rftap.alt", + FT_DOUBLE, BASE_NONE, NULL, 0, + "Altitude of receiver, in meters, using WGS 84 datum: wikipedia.org/wiki/World_Geodetic_System", HFILL }}, + + /* rftap tagged parameters */ + + { &hf_rftap_subdissector_name, { + "Dissector Name", + "rftap.dissector", + FT_STRING, BASE_NONE, NULL, 0, + "Name of sub-dissector used for packet data (alternative to DLT field)", HFILL }} + }; + + /* Register the protocol name and description */ + proto_rftap = proto_register_protocol( + "RFtap Protocol", /* name */ + "RFtap", /* short_name */ + "rftap"); /* filter_name (used for display filter string) */ + + /* Register the header fields and subtrees */ + proto_register_field_array(proto_rftap, hf, array_length(hf)); + proto_register_subtree_array(ett, array_length(ett)); + + register_dissector("rftap", dissect_rftap, proto_rftap); +} + + +/* Protocol registration routine. This function is also called by + * Wireshark's preferences manager whenever "Apply" or "OK" are pressed. + */ +void +proto_reg_handoff_rftap(void) +{ + pcap_pktdata_handle = find_dissector_add_dependency("pcap_pktdata", proto_rftap); + heur_dissector_add("udp", dissect_rftap_heur, "RFtap over UDP", "rftap", proto_rftap, HEURISTIC_ENABLE); +} + +/* + * Editor modelines - https://www.wireshark.org/tools/modelines.html + * + * Local variables: + * c-basic-offset: 4 + * tab-width: 8 + * indent-tabs-mode: nil + * End: + * + * vi: set shiftwidth=4 tabstop=8 expandtab: + * :indentSize=4:tabSize=8:noTabs=true: + */ |