diff options
author | Stephen Fisher <steve@stephen-fisher.com> | 2010-11-18 20:54:14 +0000 |
---|---|---|
committer | Stephen Fisher <steve@stephen-fisher.com> | 2010-11-18 20:54:14 +0000 |
commit | dbf10b1dc8f1f98c42f9500769dcec9f9633b7d9 (patch) | |
tree | f13ac99fb8bcf68ace7cf3c95a2db4a6faa1de5e /epan/dissectors | |
parent | 1d42ee3ebba160fc76352ddbf9e7ef3da1d17879 (diff) |
From Jon Ellch via bug #5175: Add PPI-GPS protocol dissector patch
Minor changes by me as detailed in the bug's comment #8.
svn path=/trunk/; revision=34956
Diffstat (limited to 'epan/dissectors')
-rw-r--r-- | epan/dissectors/Makefile.common | 5 | ||||
-rw-r--r-- | epan/dissectors/packet-ppi-antenna.c | 535 | ||||
-rw-r--r-- | epan/dissectors/packet-ppi-geolocation-common.c | 74 | ||||
-rw-r--r-- | epan/dissectors/packet-ppi-geolocation-common.h | 92 | ||||
-rw-r--r-- | epan/dissectors/packet-ppi-gps.c | 624 | ||||
-rw-r--r-- | epan/dissectors/packet-ppi-vector.c | 929 | ||||
-rw-r--r-- | epan/dissectors/packet-ppi.c | 85 |
7 files changed, 2339 insertions, 5 deletions
diff --git a/epan/dissectors/Makefile.common b/epan/dissectors/Makefile.common index 8573a267a2..1c1e60b2bb 100644 --- a/epan/dissectors/Makefile.common +++ b/epan/dissectors/Makefile.common @@ -750,6 +750,10 @@ DISSECTOR_SRC = \ packet-portmap.c \ packet-pgsql.c \ packet-ppi.c \ + packet-ppi-antenna.c \ + packet-ppi-geolocation-common.c \ + packet-ppi-gps.c \ + packet-ppi-vector.c \ packet-ppp.c \ packet-pppoe.c \ packet-pptp.c \ @@ -1208,6 +1212,7 @@ DISSECTOR_INCLUDES = \ packet-pktc.h \ packet-portmap.h \ packet-ppi.h \ + packet-ppi-geolocation-common.h \ packet-ppp.h \ packet-pres.h \ packet-pw-atm.h \ diff --git a/epan/dissectors/packet-ppi-antenna.c b/epan/dissectors/packet-ppi-antenna.c new file mode 100644 index 0000000000..0e476f66d3 --- /dev/null +++ b/epan/dissectors/packet-ppi-antenna.c @@ -0,0 +1,535 @@ +/* packet-ppi-antenna.c + * Routines for PPI-GEOLOCATION-ANNTENNA dissection + * Copyright 2010, Harris Corp, jellch@harris.com + * + * $Id$ + * + * Wireshark - Network traffic analyzer + * By Gerald Combs <gerald@wireshark.org> + * Copyright 1998 Gerald Combs + * + * Copied from packet-radiotap.c + * + * 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. + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include <glib.h> +#include <string.h> + +#include <epan/packet.h> +#include <epan/ptvcursor.h> +#include <epan/prefs.h> +#include <epan/reassemble.h> +#include <epan/dissectors/packet-ppi-geolocation-common.h> + +enum ppi_antenna_type { + PPI_ANTENNA_ANTFLAGS = 0, /* Various flags about the antenna in use, Polarity, etc */ + PPI_ANTENNA_GAINDB = 1, /* Antenna gain, in dBi */ + PPI_ANTENNA_HORIZBW = 2, /* Antenna beamwidth, horizontal */ + PPI_ANTENNA_VERTBW = 3, /* Antenna beamwidth, vertical */ + PPI_ANTENNA_PGAIN = 4, /* precision gain */ + PPI_ANTENNA_BEAMID = 5, /* beam identifier (electrically steerable only) */ + PPI_ANTENNA_RES6 = 6, + PPI_ANTENNA_RES7 = 7, + PPI_ANTENNA_SERIALNUM = 26, + PPI_ANTENNA_MODELSTR = 27, /*32 bytes, fixed length, null terminated model of antenna */ + PPI_ANTENNA_DESCSTR = 28, /*32 bytes, fixed length, null terminated description of what the antenna is for */ + PPI_ANTENNA_APPID = 29, /*4-byte identifer*/ + PPI_ANTENNA_APPDATA = 30, /* 60-byte app-id specific data*/ + PPI_ANTENNA_EXT = 31 /* Indicates n extended bitmap follows */ +}; + + + +/* protocol */ +static int proto_ppi_antenna = -1; + +static int hf_ppi_antenna_version = -1; +static int hf_ppi_antenna_pad = -1; +static int hf_ppi_antenna_length = -1; +static int hf_ppi_antenna_present = -1; +static int hf_ppi_antenna_flags = -1; +static int hf_ppi_antenna_gaindb = -1; +static int hf_ppi_antenna_horizbw = -1; +static int hf_ppi_antenna_vertbw = -1; +static int hf_ppi_antenna_pgain= -1; +static int hf_ppi_antenna_beamid= -1; +static int hf_ppi_antenna_serialnum= -1; +static int hf_ppi_antenna_modelname = -1; +static int hf_ppi_antenna_descstr = -1; +static int hf_ppi_antenna_appspecific_num = -1; /* 4-byte tag no */ +static int hf_ppi_antenna_appspecific_data = -1; /* 60 byte arbitrary data */ + + +/* "Present" flags */ +/* These represent decoded-bits in the gui */ +static int hf_ppi_antenna_present_flags= -1; +static int hf_ppi_antenna_present_gaindb = -1; +static int hf_ppi_antenna_present_horizbw = -1; +static int hf_ppi_antenna_present_vertbw= -1; +static int hf_ppi_antenna_present_pgain= -1; +static int hf_ppi_antenna_present_beamid= -1; +static int hf_ppi_antenna_present_serialnum= -1; +static int hf_ppi_antenna_present_modelname = -1; +static int hf_ppi_antenna_present_descstr = -1; +static int hf_ppi_antenna_present_appspecific_num = -1; +static int hf_ppi_antenna_present_appspecific_data = -1; +static int hf_ppi_antenna_present_ext = -1; + +/*These are the few defined AntennaFlags bits*/ +static int hf_ppi_antennaflags_mimo= -1; +static int hf_ppi_antennaflags_horizpol= -1; +static int hf_ppi_antennaflags_vertpol= -1; +static int hf_ppi_antennaflags_circpol_l= -1; +static int hf_ppi_antennaflags_circpol_r= -1; +static int hf_ppi_antennaflags_steer_elec= -1; +static int hf_ppi_antennaflags_steer_mech= -1; + +/* These represent arrow-dropdownthings in the gui */ +static gint ett_ppi_antenna = -1; +static gint ett_ppi_antenna_present = -1; +static gint ett_ppi_antennaflags= -1; + + +static void +dissect_ppi_antenna(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree); + +void +proto_register_ppi_antenna(void) { + /* The following array initializes those header fields declared above to the values displayed */ + static hf_register_info hf[] = { + { &hf_ppi_antenna_version, + { "Header revision", "ppi_antenna.version", + FT_UINT8, BASE_DEC, NULL, 0x0, + "Version of ppi_antenna header format", HFILL } }, + { &hf_ppi_antenna_pad, + { "Header pad", "ppi_antenna.pad", + FT_UINT8, BASE_DEC, NULL, 0x0, + "Padding", HFILL } }, + { &hf_ppi_antenna_length, + { "Header length", "ppi_antenna.length", + FT_UINT16, BASE_DEC, NULL, 0x0, + "Length of header including version, pad, length and data fields", HFILL } }, + /* This setups the "Antenna flags" hex dropydown thing */ + { &hf_ppi_antenna_flags, + { "Antenna flags", "ppi_antenna.antenna_flags", + FT_UINT32, BASE_HEX, NULL, 0x0, "Bitmask indicating polarity, etc", HFILL } }, + { &hf_ppi_antenna_present, + { "Present", "ppi_antenna.present", + FT_UINT32, BASE_HEX, NULL, 0x0, "Bitmask indicating which fields are present", HFILL } }, + + /* This first set is for the base_tag_header.it_present bitfield */ +#define PPI_ANTENNA_MASK_FLAGS 0x00000001 /* 0 */ +#define PPI_ANTENNA_MASK_GAINDB 0x00000002 /* 1 */ +#define PPI_ANTENNA_MASK_HORIZBW 0x00000004 /* 2 */ +#define PPI_ANTENNA_MASK_VERTBW 0x00000008 /* 3 */ +#define PPI_ANTENNA_MASK_PGAIN 0x00000020 /* 5 */ +#define PPI_ANTENNA_MASK_BEAMID 0x00000040 /* 6 */ +#define PPI_ANTENNA_MASK_RES7 0x00000080 /* 7 */ +#define PPI_ANTENNA_MASK_SERIALNUM 0x04000000 /* 26 */ +#define PPI_ANTENNA_MASK_MODELSTR 0x08000000 /* 27 */ +#define PPI_ANTENNA_MASK_DESCSTR 0x10000000 /* 28 */ +#define PPI_ANTENNA_MASK_APPID 0x20000000 /* 29 */ +#define PPI_ANTENNA_MASK_APPDATA 0x40000000 /* 30 */ +#define PPI_ANTENNA_MASK_EXT 0x80000000 /* 31 */ + + /*This second set is for the AntennaFlags bitfield. */ +#define PPI_ANTENNAFLAGS_MASK_MIMO 0x00000001 /* 0 */ +#define PPI_ANTENNAFLAGS_MASK_HPOL 0x00000002 /* 1 */ +#define PPI_ANTENNAFLAGS_MASK_VPOL 0x00000004 /* 2 */ +#define PPI_ANTENNAFLAGS_MASK_CPOL_L 0x00000008 /* 3 */ +#define PPI_ANTENNAFLAGS_MASK_CPOL_R 0x00000010 /* 4 */ +#define PPI_ANTENNAFLAGS_MASK_STEER_ELEC 0x00010000 /* 16 */ +#define PPI_ANTENNAFLAGS_MASK_STEER_MECH 0x00020000 /* 17 */ + + + /* Boolean 'present' flags */ + { &hf_ppi_antenna_present_flags, + { "flags", "ppi_antenna.present.flags", + FT_BOOLEAN, 32, NULL, PPI_ANTENNA_MASK_FLAGS, + "Specifies if the flags bitfield is present", HFILL } }, + { &hf_ppi_antenna_present_gaindb, + { "gaindb", "ppi_antenna.present.gaindb", + FT_BOOLEAN, 32, NULL, PPI_ANTENNA_MASK_GAINDB, + "Specifies if the antenna gain field is present", HFILL } }, + { &hf_ppi_antenna_present_horizbw, + { "horizbw", "ppi_antenna.present.horizbw", + FT_BOOLEAN, 32, NULL, PPI_ANTENNA_MASK_HORIZBW, + "Specifies if the horizontal beamwidth field is present", HFILL } }, + { &hf_ppi_antenna_present_vertbw, + { "vertbw", "ppi_antenna.present.vertbw", + FT_BOOLEAN, 32, NULL, PPI_ANTENNA_MASK_VERTBW, + "Specifies if the vertical beamwidth field is present", HFILL } }, + { &hf_ppi_antenna_present_pgain, + { "pgain", "ppi_antenna.present.pgain", + FT_BOOLEAN, 32, NULL, PPI_ANTENNA_MASK_PGAIN, + "Specifies if the precision gain field is present", HFILL } }, + { &hf_ppi_antenna_present_beamid, + { "beamid", "ppi_antenna.present.beamid", + FT_BOOLEAN, 32, NULL, PPI_ANTENNA_MASK_BEAMID, + "Specifies if the BeamID field is present", HFILL } }, + { &hf_ppi_antenna_present_serialnum, + { "serialnum", "ppi_antenna.present.serialnum", + FT_BOOLEAN, 32, NULL, PPI_ANTENNA_MASK_SERIALNUM, + "Specifies if the serial num is present", HFILL } }, + { &hf_ppi_antenna_present_modelname, + { "modelname", "ppi_antenna.present.modelname", + FT_BOOLEAN, 32, NULL, PPI_ANTENNA_MASK_MODELSTR, + "Specifies if the model name is present", HFILL } }, + { &hf_ppi_antenna_present_descstr, + { "Description", "ppi_antenna.present.descr", + FT_BOOLEAN, 32, NULL, PPI_ANTENNA_MASK_DESCSTR, + "Specifies if the description string is present", HFILL } }, + + { &hf_ppi_antenna_present_appspecific_num, + { "appid", "ppi_antenna.present.appid", + FT_BOOLEAN, 32, NULL, PPI_ANTENNA_MASK_APPID, + "Specifies if the application specific field id is present", HFILL } }, + + { &hf_ppi_antenna_present_appspecific_data, + { "appdata", "ppi_antenna.present.appdata", + FT_BOOLEAN, 32, NULL, PPI_ANTENNA_MASK_APPDATA, + "Specifies if the application specific data field is present", HFILL } }, + + { &hf_ppi_antenna_present_ext, + { "ext", "ppi_antenna.present.ext", + FT_BOOLEAN, 32, NULL, PPI_ANTENNA_MASK_EXT, + "Specifies if there are any extensions to the header present ", HFILL } }, + + /*Here we switch to the antennflags bits*/ + /* Boolean AntennaFlags' flags */ + { &hf_ppi_antennaflags_mimo, + { "mimo", "ppi_antenna.antennaflags.mimo", + FT_BOOLEAN, 32, NULL, PPI_ANTENNAFLAGS_MASK_MIMO, + "Antena is part of MIMO system", HFILL } }, + { &hf_ppi_antennaflags_horizpol, + { "horizontally polarized", "ppi_antenna.antennaflags.horizpol", + FT_BOOLEAN, 32, NULL, PPI_ANTENNAFLAGS_MASK_HPOL, + "Specifies if the antenna is horizontally polarized", HFILL } }, + + { &hf_ppi_antennaflags_vertpol, + { "vertically polarized", "ppi_antenna.antennaflags.vertpol", + FT_BOOLEAN, 32, NULL, PPI_ANTENNAFLAGS_MASK_VPOL, + "Specifies if the antenna is vertically polarized", HFILL } }, + + { &hf_ppi_antennaflags_circpol_l, + { "circularly polarized left", "ppi_antenna.antennaflags.circpol_l", + FT_BOOLEAN, 32, NULL, PPI_ANTENNAFLAGS_MASK_CPOL_L, + "Specifies if the antenna is circulary polarized, left handed", HFILL } }, + + { &hf_ppi_antennaflags_circpol_r, + { "circularly polarized right", "ppi_antenna.antennaflags.circpol_r", + FT_BOOLEAN, 32, NULL, PPI_ANTENNAFLAGS_MASK_CPOL_R, + "Specifies if the antenna is circulary polarized, right handed", HFILL } }, + + { &hf_ppi_antennaflags_steer_elec, + { "electrically steerable", "ppi_antenna.antennaflags.steer_elec", + FT_BOOLEAN, 32, NULL, PPI_ANTENNAFLAGS_MASK_STEER_ELEC, + "Specifies if the antenna is electrically steerable", HFILL } }, + + { &hf_ppi_antennaflags_steer_mech, + { "mechanically steerable", "ppi_antenna.antennaflags.steer_mech", + FT_BOOLEAN, 32, NULL, PPI_ANTENNAFLAGS_MASK_STEER_MECH, + "Specifies if the antenna is mechanically steerable", HFILL } }, + + /* Now we get to the actual data fields */ + { &hf_ppi_antenna_gaindb, + { "Gain (dBi)", "ppi_antenna.gaindb", + FT_UINT8, BASE_DEC, NULL, 0x0, + "Gain of antenna (dBi)", HFILL } }, + { &hf_ppi_antenna_horizbw, + { "HorizBw", "ppi_antenna.horizbw", + FT_FLOAT, BASE_NONE, NULL, 0x0, + "Horizontal beamwidth", HFILL } }, + { &hf_ppi_antenna_vertbw, + { "VertBw", "ppi_antenna.vertbw", + FT_FLOAT, BASE_NONE, NULL, 0x0, + "Vertical beamwidth", HFILL } }, + { &hf_ppi_antenna_pgain, + { "Precision Gain (dBi)", "ppi_antenna.pgain", + FT_FLOAT, BASE_NONE, NULL, 0x0, + "Precision Gain", HFILL } }, + { &hf_ppi_antenna_beamid, + { "BeamID", "ppi_antenna.beamid", + FT_UINT16, BASE_HEX, NULL, 0x0, + "BeamID", HFILL } }, + + { &hf_ppi_antenna_serialnum, + { "SerialNumber", "ppi_antenna.serialnum", + FT_STRING, BASE_NONE, NULL, 0x0, + "Serial number", HFILL } } , + { &hf_ppi_antenna_modelname, + { "ModelName", "ppi_antenna.modelname", + FT_STRING, BASE_NONE, NULL, 0x0, + "Model name", HFILL } } , + { &hf_ppi_antenna_descstr, + { "Description", "ppi_antenna.descr", + FT_STRING, BASE_NONE, NULL, 0x0, + "Description", HFILL } } , + { &hf_ppi_antenna_appspecific_num, + { "Application Specific id", "ppi_antenna.appid", + FT_UINT32, BASE_HEX, NULL, 0x0, + "application specific identifier", HFILL } }, + { &hf_ppi_antenna_appspecific_data, + { "Application specific data", "ppi_antenna.appdata", + FT_BYTES, BASE_NONE, NULL, 0x0, + "application specific data", HFILL } }, + }; + static gint *ett[] = { + &ett_ppi_antenna, + &ett_ppi_antenna_present, + &ett_ppi_antennaflags + }; + + proto_ppi_antenna = proto_register_protocol("PPI antenna decoder", "PPI antenna Decoder", "ppi_antenna"); + proto_register_field_array(proto_ppi_antenna, hf, array_length(hf)); + proto_register_subtree_array(ett, array_length(ett)); + register_dissector("ppi_antenna", dissect_ppi_antenna, proto_ppi_antenna); + +} +void dissect_ppi_antenna(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { + /* The fixed values up front */ + guint32 version; + guint length; + guint length_remaining; + + proto_tree *ppi_antenna_tree = NULL; + proto_tree *present_tree = NULL; + proto_tree *antennaflags_tree = NULL; + proto_tree *pt, *my_pt; + proto_item *ti = NULL; + + + /* bits */ + int bit; + guint32 present, next_present; + /* values actually read out, for displaying */ + guint8 gaindb; + guint16 beamid; + guint32 t_hbw, t_vbw, t_pgain, t_appspecific_num; /* temporary conversions */ + gdouble horizbw, vertbw, pgain; + guint32 flags; + char *curr_str; /* used for modelname, serialnum, etc */ + + int offset = 0; + + /* Clear out stuff in the info column */ + if (check_col(pinfo->cinfo,COL_INFO)) { + col_clear(pinfo->cinfo,COL_INFO); + } + version = tvb_get_guint8(tvb, offset); + length = tvb_get_letohs(tvb, offset+2); + present = tvb_get_letohl(tvb, offset+4); + if (check_col(pinfo->cinfo, COL_INFO)) + col_add_fstr(pinfo->cinfo, COL_INFO, "PPI Antenna info v%u, Length %u", + version, length); + + /* Dissect the packet */ + if (tree) { + ti = proto_tree_add_protocol_format(tree, proto_ppi_antenna, + tvb, 0, length, "PPI Antenna Header v%u, Length %u", version, length); + ppi_antenna_tree= proto_item_add_subtree(ti, ett_ppi_antenna); + proto_tree_add_uint(ppi_antenna_tree, hf_ppi_antenna_version, + tvb, offset, 1, version); + proto_tree_add_item(ppi_antenna_tree, hf_ppi_antenna_pad, + tvb, offset + 1, 1, FALSE); + ti = proto_tree_add_uint(ppi_antenna_tree, hf_ppi_antenna_length, + tvb, offset + 2, 2, length); + } + length_remaining = length; + /* + * FIXME: This only works if there is exactly 1 it_present + * field in the header + */ + if (length_remaining < PPI_GEOBASE_MIN_HEADER_LEN) { + /* + * Radiotap header is shorter than the fixed-length portion + * plus one "present" bitset. + */ + if (tree) + proto_item_append_text(ti, " (bogus - minimum length is 8)"); + return; + } + /* Subtree for the "present flags" bitfield. */ + if (tree) { + pt = proto_tree_add_uint(ppi_antenna_tree, hf_ppi_antenna_present, tvb, offset + 4, 4, present); + present_tree = proto_item_add_subtree(pt, ett_ppi_antenna_present); + + proto_tree_add_item(present_tree, hf_ppi_antenna_present_flags, tvb, 4, 4, TRUE); + proto_tree_add_item(present_tree, hf_ppi_antenna_present_gaindb, tvb, 4, 4, TRUE); + proto_tree_add_item(present_tree, hf_ppi_antenna_present_horizbw, tvb, 4, 4, TRUE); + proto_tree_add_item(present_tree, hf_ppi_antenna_present_vertbw, tvb, 4, 4, TRUE); + proto_tree_add_item(present_tree, hf_ppi_antenna_present_pgain, tvb, 4, 4, TRUE); + proto_tree_add_item(present_tree, hf_ppi_antenna_present_beamid, tvb, 4, 4, TRUE); + proto_tree_add_item(present_tree, hf_ppi_antenna_present_serialnum, tvb, 4, 4, TRUE); + proto_tree_add_item(present_tree, hf_ppi_antenna_present_modelname, tvb, 4, 4, TRUE); + proto_tree_add_item(present_tree, hf_ppi_antenna_present_descstr, tvb, 4, 4, TRUE); + proto_tree_add_item(present_tree, hf_ppi_antenna_present_appspecific_num, tvb, 4, 4, TRUE); + proto_tree_add_item(present_tree, hf_ppi_antenna_present_appspecific_data, tvb, 4, 4, TRUE); + + proto_tree_add_item(present_tree, hf_ppi_antenna_present_ext, tvb, 4, 4, TRUE); + } + offset += PPI_GEOBASE_MIN_HEADER_LEN; + length_remaining -= PPI_GEOBASE_MIN_HEADER_LEN; + + /* Now all of the fixed length, fixed location stuff is over. Loop over the bits */ + for (; present; present = next_present) { + /* clear the least significant bit that is set */ + next_present = present & (present - 1); + /* extract the least significant bit that is set */ + bit = BITNO_32(present ^ next_present); + switch (bit) { + case PPI_ANTENNA_ANTFLAGS: + if (length_remaining < 4) + break; + flags = tvb_get_letohl(tvb, offset); + if (tree) { + my_pt = proto_tree_add_uint(ppi_antenna_tree, hf_ppi_antenna_flags, tvb, offset , 4, flags); + /*Add antenna_flags bitfields here */ + antennaflags_tree= proto_item_add_subtree(my_pt, ett_ppi_antennaflags); + + proto_tree_add_item(antennaflags_tree, hf_ppi_antennaflags_mimo, tvb, offset, 4, TRUE); + proto_tree_add_item(antennaflags_tree, hf_ppi_antennaflags_horizpol, tvb, offset, 4, TRUE); + proto_tree_add_item(antennaflags_tree, hf_ppi_antennaflags_vertpol, tvb, offset, 4, TRUE); + proto_tree_add_item(antennaflags_tree, hf_ppi_antennaflags_circpol_l, tvb, offset, 4, TRUE); + proto_tree_add_item(antennaflags_tree, hf_ppi_antennaflags_circpol_r, tvb, offset, 4, TRUE); + proto_tree_add_item(antennaflags_tree, hf_ppi_antennaflags_steer_elec, tvb, offset, 4, TRUE); + proto_tree_add_item(antennaflags_tree, hf_ppi_antennaflags_steer_mech, tvb, offset, 4, TRUE); + } + offset+=4; + length_remaining-=4; + break; + case PPI_ANTENNA_GAINDB: + if (length_remaining < 1) + break; + gaindb= tvb_get_guint8(tvb, offset); + if (tree) { + proto_tree_add_uint(ppi_antenna_tree, hf_ppi_antenna_gaindb, tvb, offset, 1, gaindb); + } + offset+=1; + length_remaining-=1; + break; + case PPI_ANTENNA_HORIZBW: + if (length_remaining < 4) + break; + t_hbw = tvb_get_letohl(tvb, offset); + horizbw = fixed3_6_to_gdouble(t_hbw); + if (tree) { + proto_tree_add_float(ppi_antenna_tree, hf_ppi_antenna_horizbw, tvb, offset, 4, horizbw); + } + offset+=4; + length_remaining-=4; + break; + case PPI_ANTENNA_VERTBW: + if (length_remaining < 4) + break; + t_vbw = tvb_get_letohl(tvb, offset); + vertbw = fixed3_6_to_gdouble(t_vbw); + if (tree) { + proto_tree_add_float(ppi_antenna_tree, hf_ppi_antenna_vertbw, tvb, offset, 4, vertbw); + } + offset+=4; + length_remaining-=4; + break; + case PPI_ANTENNA_PGAIN: + if (length_remaining < 4) + break; + t_pgain = tvb_get_letohl(tvb, offset); + pgain = fixed3_6_to_gdouble(t_pgain); + if (tree) { + proto_tree_add_float(ppi_antenna_tree, hf_ppi_antenna_pgain, tvb, offset, 4, pgain); + } + offset+=4; + length_remaining-=4; + break; + case PPI_ANTENNA_BEAMID: + if (length_remaining < 2) + break; + beamid= tvb_get_letohs(tvb, offset); /* convert endianess */ + if (tree) { + proto_tree_add_uint(ppi_antenna_tree, hf_ppi_antenna_beamid, tvb, offset, 2, beamid); + } + offset+=2; + length_remaining-=2; + break; + case PPI_ANTENNA_SERIALNUM: + if (length_remaining < 32) + break; + if (tree) { + curr_str= (char *) tvb_get_ptr(tvb, offset, 32); + proto_tree_add_string(ppi_antenna_tree, hf_ppi_antenna_serialnum, tvb, offset, 32, curr_str);; + } + offset+=32; + length_remaining-=32; + break; + + case PPI_ANTENNA_MODELSTR: + if (length_remaining < 32) + break; + if (tree) { + curr_str = (char *) tvb_get_ptr(tvb, offset, 32); + proto_tree_add_string(ppi_antenna_tree, hf_ppi_antenna_modelname, tvb, offset, 32, curr_str); + } + offset+=32; + length_remaining-=32; + break; + case PPI_ANTENNA_DESCSTR: + if (length_remaining < 32) + break; + if (tree) { + curr_str= (char *) tvb_get_ptr(tvb, offset, 32); + proto_tree_add_string(ppi_antenna_tree, hf_ppi_antenna_descstr, tvb, offset, 32, curr_str); + } + offset+=32; + length_remaining-=32; + break; + case PPI_ANTENNA_APPID: + if (length_remaining < 4) + break; + t_appspecific_num = tvb_get_letohl(tvb, offset); /* application specific parsers may switch on this later */ + if (tree) { + proto_tree_add_uint(ppi_antenna_tree, hf_ppi_antenna_appspecific_num, tvb, offset, 4, t_appspecific_num); + } + offset+=4; + length_remaining-=4; + break; + case PPI_ANTENNA_APPDATA: + if (length_remaining < 60) + break; + if (tree) { + proto_tree_add_item(ppi_antenna_tree, hf_ppi_antenna_appspecific_data, tvb, offset, 60, FALSE); + } + offset+=60; + length_remaining-=60; + break; + default: + /* + * This indicates a field whose size we do not + * know, so we cannot proceed. + */ + proto_tree_add_text(ppi_antenna_tree, tvb, offset, 0, "Error: PPI-ANTENNA: unknown bit (%d) set in present field.\n", bit); + next_present = 0; + continue; + } + + }; + return; +} + + diff --git a/epan/dissectors/packet-ppi-geolocation-common.c b/epan/dissectors/packet-ppi-geolocation-common.c new file mode 100644 index 0000000000..094c8fc5c9 --- /dev/null +++ b/epan/dissectors/packet-ppi-geolocation-common.c @@ -0,0 +1,74 @@ +/* packet-ppi-geolocation-common.c + * Routines for PPI-GEOLOCATION dissection + * Copyright 2010, Harris Corp, jellch@harris.com + * + * $Id$ + * + * 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. + */ + +#include "packet-ppi-geolocation-common.h" + +/* + * input: a unsigned 32-bit (native endian) value between 0 and 3600000000 (inclusive) + * output: a signed floating point value betwen -180.0000000 and + 180.0000000, inclusive) + */ +gdouble fixed3_7_to_gdouble(guint32 in) { + gint32 remapped_in = in - (180 * 10000000); + gdouble ret = (gdouble) ((gdouble) remapped_in / 10000000); + return ret; +} +/* + * input: a native 32 bit unsigned value between 0 and 999999999 + * output: a positive floating point value between 000.0000000 and 999.9999999 + */ + +gdouble fixed3_6_to_gdouble(guint32 in) { + gdouble ret = (gdouble) in / 1000000.0; + return ret; + +} +/* + * input: a native 32 bit unsigned value between 0 and 3600000000 + * output: a signed floating point value between -180000.0000 and +180000.0000 + */ +gdouble fixed6_4_to_gdouble(guint32 in) { + gint32 remapped_in = in - (180000 * 10000); + gdouble ret = (gdouble) ((gdouble) remapped_in / 10000); + return ret; +} + +gdouble ns_counter_to_gdouble(guint32 in) { + gdouble ret; + ret = (gdouble) in / 1000000000; + return ret; +} + +/* + * Editor modelines + * + * Local Variables: + * c-basic-offset: 4 + * tab-width: 8 + * indent-tabs-mode: nil + * End: + * + * ex: set shiftwidth=4 tabstop=8 expandtab + * :indentSize=4:tabSize=8:noTabs=true: + */ diff --git a/epan/dissectors/packet-ppi-geolocation-common.h b/epan/dissectors/packet-ppi-geolocation-common.h new file mode 100644 index 0000000000..d92a855569 --- /dev/null +++ b/epan/dissectors/packet-ppi-geolocation-common.h @@ -0,0 +1,92 @@ +/* packet-ppi-geolocation-common.h + * Routines for PPI-GEOLOCATION dissection + * Copyright 2010, Harris Corp, jellch@harris.com + * + * $Id$ + * + * 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. + */ + +#ifndef __PPI_GEOLOCATION_COMMON_H +#define __PPI_GEOLOCATION_COMMON_H +#include <glib.h> + +/* + * Declarations from shared PPI-GEOLOCATION functions. + * + */ + +/* + * these constants are offsets into base_geotag header, which is bitwise-compatible + * with a radiotap header + */ +#define PPI_GEOBASE_MIN_HEADER_LEN 8 /* minimum header length */ +#define PPI_GEOBASE_VERSION_OFFSET 0 /* offset of version field */ +#define PPI_GEOBASE_LENGTH_OFFSET 2 /* offset of length field */ +#define PPI_GEOBASE_PRESENT_OFFSET 4 /* offset of "present" field */ +/* + * These BITNO macros were accquired from the radiotap parser. maybe we can share them + * eventually + */ +#define BITNO_32(x) (((x) >> 16) ? 16 + BITNO_16((x) >> 16) : BITNO_16((x))) +#define BITNO_16(x) (((x) >> 8) ? 8 + BITNO_8((x) >> 8) : BITNO_8((x))) +#define BITNO_8(x) (((x) >> 4) ? 4 + BITNO_4((x) >> 4) : BITNO_4((x))) +#define BITNO_4(x) (((x) >> 2) ? 2 + BITNO_2((x) >> 2) : BITNO_2((x))) +#define BITNO_2(x) (((x) & 2) ? 1 : 0) +#define BIT(n) (1 << n) + + + +/* + * Floating point numbers are stored on disk in a handful of fixed-point formats (fixedX_Y) + * designed to preserve the appropriate amount of precision vs range. These functions convert + * the fixedX_Y fixed point values into 'native' gdoubles for displaying. + * Documentation on these formats can be found in the PPI-GEOLOCATION specification + */ +gdouble fixed3_7_to_gdouble(guint32 in); +gdouble fixed3_6_to_gdouble(guint32 in); +gdouble fixed6_4_to_gdouble(guint32 in); +/* + * Some values are encoded as 32-bit unsigned nano-second counters. + * Usually we want to display these values as doubles. + */ +gdouble ns_counter_to_gdouble(guint32 in); + + +typedef enum { + PPI_GEOLOCATION_HARRIS = 0x00485253 /* 00SRH */ +} ppi_geolocation_appstr_num; + + +#endif + +/* + * Editor modelines + * + * Local Variables: + * c-basic-offset: 4 + * tab-width: 8 + * indent-tabs-mode: nil + * End: + * + * ex: set shiftwidth=4 tabstop=8 expandtab + * :indentSize=4:tabSize=8:noTabs=true: + */ + + diff --git a/epan/dissectors/packet-ppi-gps.c b/epan/dissectors/packet-ppi-gps.c new file mode 100644 index 0000000000..d319303c41 --- /dev/null +++ b/epan/dissectors/packet-ppi-gps.c @@ -0,0 +1,624 @@ +/* packet-ppi-gps.c + * Routines for PPI-GEOLOCATION-GPS dissection + * Copyright 2010, Harris Corp, jellch@harris.com + * + * $Id$ + * + * Wireshark - Network traffic analyzer + * By Gerald Combs <gerald@wireshark.org> + * Copyright 1998 Gerald Combs + * + * Copied from packet-radiotap.c + * + * 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. + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include <glib.h> +#include <string.h> +#include <epan/packet.h> +#include <epan/ptvcursor.h> +#include <epan/prefs.h> +#include <epan/reassemble.h> +#include <epan/dissectors/packet-ppi-geolocation-common.h> +enum ppi_geotagging_type { + PPI_GEOTAG_GPSFLAGS = 0, + PPI_GEOTAG_LAT = 1, + PPI_GEOTAG_LON = 2, + PPI_GEOTAG_ALT = 3, + PPI_GEOTAG_ALT_G = 4, + PPI_GEOTAG_GPSTIME = 5, + PPI_GEOTAG_FRACTIONALTIME = 6, + PPI_GEOTAG_EPH = 7, + PPI_GEOTAG_EPV = 8, + PPI_GEOTAG_EPT = 9, + PPI_GEOTAG_DESCRIPTIONSTR = 28, + PPI_GEOTAG_APPID = 29, + PPI_GEOTAG_APPDATA = 30, + PPI_GEOTAG_EXT = 31 +}; +#define PPI_GPS_MAXTAGLEN 148 /* This increases as fields above are added */ + + +/* protocol */ +static int proto_ppi_gps = -1; + +static int hf_ppi_gps_version = -1; +static int hf_ppi_gps_pad = -1; +static int hf_ppi_gps_length = -1; +static int hf_ppi_gps_present = -1; +static int hf_ppi_gps_gpsflags_flags = -1; +static int hf_ppi_gps_lon = -1; +static int hf_ppi_gps_lat = -1; +static int hf_ppi_gps_alt = -1; +static int hf_ppi_gps_alt_gnd = -1; +static int hf_ppi_gps_gpstime = -1; +static int hf_ppi_gps_fractime = -1; +static int hf_ppi_gps_eph = -1; +static int hf_ppi_gps_epv = -1; +static int hf_ppi_gps_ept = -1; +static int hf_ppi_gps_descr = -1; +static int hf_ppi_gps_appspecific_num = -1; /* 4-byte tag no */ +static int hf_ppi_gps_appspecific_data = -1; /* 60 byte arbitrary data */ +/* "Present" flags, tese represent decoded-bits in the gui */ +static int hf_ppi_gps_present_gpsflags_flags = -1; +static int hf_ppi_gps_present_lon = -1; +static int hf_ppi_gps_present_lat = -1; +static int hf_ppi_gps_present_alt = -1; +static int hf_ppi_gps_present_alt_gnd = -1; +static int hf_ppi_gps_present_gpstime = -1; +static int hf_ppi_gps_present_fractime = -1; +static int hf_ppi_gps_present_eph = -1; +static int hf_ppi_gps_present_epv = -1; +static int hf_ppi_gps_present_ept = -1; +static int hf_ppi_gps_present_descr = -1; +static int hf_ppi_gps_present_appspecific_num = -1; +static int hf_ppi_gps_present_appspecific_data = -1; +static int hf_ppi_gps_present_ext = -1; + +/* Devicetype flags. not to be confused with "present" flags. These are optional */ +static int hf_ppi_gps_gpsflags_flag0_nofix = -1; +static int hf_ppi_gps_gpsflags_flag1_gpsfix = -1; +static int hf_ppi_gps_gpsflags_flag2_diffgps = -1; +static int hf_ppi_gps_gpsflags_flag3_PPS = -1; +static int hf_ppi_gps_gpsflags_flag4_RTK = -1; +static int hf_ppi_gps_gpsflags_flag5_floatRTK = -1; +static int hf_ppi_gps_gpsflags_flag6_dead_reck = -1; +static int hf_ppi_gps_gpsflags_flag7_manual = -1; +static int hf_ppi_gps_gpsflags_flag8_sim = -1; + +/* These represent arrow-dropdownthings in the gui */ +static gint ett_ppi_gps = -1; +static gint ett_ppi_gps_present = -1; +static gint ett_ppi_gps_gpsflags_flags= -1; + +static void +dissect_ppi_gps(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree); + +void +proto_register_ppi_gps(void) { + /* The following array initializes those header fields declared above to the values displayed */ + static hf_register_info hf[] = { + { &hf_ppi_gps_version, + { "Header revision", "ppi_gps.version", + FT_UINT8, BASE_DEC, NULL, 0x0, + "Version of ppi_gps header format", HFILL } }, + { &hf_ppi_gps_pad, + { "Header pad", "ppi_gps.pad", + FT_UINT8, BASE_DEC, NULL, 0x0, + "Padding", HFILL } }, + { &hf_ppi_gps_length, + { "Header length", "ppi_gps.length", + FT_UINT16, BASE_DEC, NULL, 0x0, + "Length of header including version, pad, length and data fields", HFILL } }, + { &hf_ppi_gps_present, /* these flag fields are composed of a uint32 on the display */ + { "Present", "ppi_gps.present", + FT_UINT32, BASE_HEX, NULL, 0x0, "Bitmask indicating which fields are present", HFILL } }, + +#define PPI_GPS_MASK_GPSFLAGS 0x00000001 +#define PPI_GPS_MASK_LAT 0x00000002 +#define PPI_GPS_MASK_LON 0x00000004 +#define PPI_GPS_MASK_ALT 0x00000008 +#define PPI_GPS_MASK_ALT_G 0x00000010 + +#define PPI_GPS_MASK_GPSTIME 0x00000020 +#define PPI_GPS_MASK_FRACTIME 0x00000040 +#define PPI_GPS_MASK_EPH 0x00000080 +#define PPI_GPS_MASK_EPV 0x00000100 +#define PPI_GPS_MASK_EPT 0x00000200 + +#define PPI_GPS_MASK_DESCRSTR 0x10000000 +#define PPI_GPS_MASK_APPID 0x20000000 +#define PPI_GPS_MASK_APPDATA 0x40000000 +#define PPI_GPS_MASK_EXT 0x80000000 + + /* Boolean 'present' flags */ + { &hf_ppi_gps_present_gpsflags_flags, /* followed by a lot of booleans */ + { "GPSFlags", "ppi_gps.present.gpsflagss", + FT_BOOLEAN, 32, NULL, PPI_GPS_MASK_GPSFLAGS, + "32-bit bitmask indicating type of GPS fix (GPS/INS/software/etc)", HFILL } }, + { &hf_ppi_gps_present_lat, + { "Lat", "ppi_gps.present.lat", + FT_BOOLEAN, 32, NULL, PPI_GPS_MASK_LAT, + "Specifies if the latitude field is present", HFILL } }, + + { &hf_ppi_gps_present_lon, + { "Lon", "ppi_gps.present.lon", + FT_BOOLEAN, 32, NULL, PPI_GPS_MASK_LON, + "Specifies if the longitude field is present", HFILL } }, + + { &hf_ppi_gps_present_alt, + { "Alt", "ppi_gps.present.alt", + FT_BOOLEAN, 32, NULL, PPI_GPS_MASK_ALT, + "Specifies if the altitude field is present", HFILL } }, + + { &hf_ppi_gps_present_alt_gnd, + { "Alt-gnd", "ppi_gps.present.alt_gnd", + FT_BOOLEAN, 32, NULL, PPI_GPS_MASK_ALT_G, + "Specifies if the altitude-g field is present", HFILL } }, + + { &hf_ppi_gps_present_gpstime, + { "GPStime", "ppi_gps.present.gpstime", + FT_BOOLEAN, 32, NULL, PPI_GPS_MASK_GPSTIME, + "Specifies if the GPS time field is present", HFILL } }, + + + { &hf_ppi_gps_present_fractime, + { "fractime", "ppi_gps.present.fractime", + FT_BOOLEAN, 32, NULL, PPI_GPS_MASK_FRACTIME, + "Specifies if the fractional time field is present", HFILL } }, + + + { &hf_ppi_gps_present_eph, + { "error_h", "ppi_gps.present.eph", + FT_BOOLEAN, 32, NULL, PPI_GPS_MASK_EPH, + "Specifies if the horizontal error field is present (eph)", HFILL } }, + + { &hf_ppi_gps_present_epv, + { "error_v", "ppi_gps.present.epv", + FT_BOOLEAN, 32, NULL, PPI_GPS_MASK_EPV, + "Specifies if the vertical error field present (epv)", HFILL } }, + + + { &hf_ppi_gps_present_ept, + { "error_t", "ppi_gps.present.ept", + FT_BOOLEAN, 32, NULL, PPI_GPS_MASK_EPT, + "Specifies if the estimed time error field is present (ept)", HFILL } }, + + { &hf_ppi_gps_present_descr, + { "Description", "ppi_gps.present.descr", + FT_BOOLEAN, 32, NULL, PPI_GPS_MASK_DESCRSTR, + "Specifies if the (ASCII) description is present", HFILL } }, + + { &hf_ppi_gps_present_appspecific_num, + { "AppId", "ppi_gps.present.appid", + FT_BOOLEAN, 32, NULL, PPI_GPS_MASK_APPID, + "Specifies if the application specific field id is present", HFILL } }, + + { &hf_ppi_gps_present_appspecific_data, + { "AppData", "ppi_gps.present.appdata", + FT_BOOLEAN, 32, NULL, PPI_GPS_MASK_APPDATA, + "Specifies if the application specific data field is present", HFILL } }, + + { &hf_ppi_gps_present_ext, + { "Ext", "ppi_gps.present.ext", + FT_BOOLEAN, 32, NULL, PPI_GPS_MASK_EXT, + "Specifies if there are any extensions to the header present", HFILL } }, + + /* ---Now we get to the actual data fields--- */ + + { &hf_ppi_gps_gpsflags_flags, + { "GPSFlags", "ppi_gps.gpsflags", + FT_UINT32, BASE_HEX, NULL, 0x0, "Bitmask indicating GPS/INS/manual fix", HFILL } }, + { &hf_ppi_gps_lat, + { "Latitude", "ppi_gps.lat", + FT_DOUBLE, BASE_NONE, NULL, 0x0, + "Latitude packet was received at", HFILL } }, + { &hf_ppi_gps_lon, + { "Longitude", "ppi_gps.lon", + FT_DOUBLE, BASE_NONE, NULL, 0x0, + "Longitude packet was received at", HFILL } }, + { &hf_ppi_gps_alt, + { "Altitude", "ppi_gps.alt", + FT_DOUBLE, BASE_NONE, NULL, 0x0, + "Altitude packet was received at", HFILL } }, + { &hf_ppi_gps_alt_gnd, + { "Altitude_gnd", "ppi_gps.alt_gnd", + FT_DOUBLE, BASE_NONE, NULL, 0x0, + "Altitude packet was received at (relative to ground)", HFILL } }, + { &hf_ppi_gps_gpstime, + { "GPSTimestamp", "ppi_gps.gpstime", + FT_ABSOLUTE_TIME, ABSOLUTE_TIME_UTC, NULL, 0x0, + "GPSTimestamp packet was received at", HFILL } }, + { &hf_ppi_gps_fractime, + { "fractional Timestamp", "ppi_gps.fractime", + FT_DOUBLE, BASE_NONE, NULL, 0x0, + "fractional GPSTimestamp packet was received at", HFILL } }, + { &hf_ppi_gps_eph, + { "Horizontal Error (m)", "ppi_gps.eph", + FT_DOUBLE, BASE_NONE, NULL, 0x0, + "Horizontal margin of error (meters)", HFILL } }, + { &hf_ppi_gps_epv, + { "Vertical Error (m)", "ppi_gps.epv", + FT_DOUBLE, BASE_NONE, NULL, 0x0, + "Vertical margin of error (meters) ", HFILL } }, + { &hf_ppi_gps_ept, + { "Time Error (s)", "ppi_gps.ept", + FT_DOUBLE, BASE_NONE, NULL, 0x0, + "Time margin of error (secs)", HFILL } }, + { &hf_ppi_gps_descr, + { "Description", "ppi_gps.descr", + FT_STRING, BASE_NONE, NULL, 0x0, + "Description", HFILL } }, + { &hf_ppi_gps_appspecific_num, + { "Application Specific id", "ppi_gps.appid", + FT_UINT32, BASE_HEX, NULL, 0x0, + "application specific identifier", HFILL } }, + { &hf_ppi_gps_appspecific_data, + { "Application specific data", "ppi_gps.appdata", + FT_BYTES, BASE_NONE, NULL, 0x0, + "application specific data", HFILL } }, + + /* --- moving on to the 'FixType' flags --- */ +#define PPI_GPS_GPSFLAGS_FLAG0_NOFIX 0x00000001 +#define PPI_GPS_GPSFLAGS_FLAG1_GPS 0x00000002 +#define PPI_GPS_GPSFLAGS_FLAG2_DIFFGPS 0x00000004 +#define PPI_GPS_GPSFLAGS_FLAG3_PPS 0x00000008 +#define PPI_GPS_GPSFLAGS_FLAG4_RTK 0x00000010 +#define PPI_GPS_GPSFLAGS_FLAG5_FLOATRTK 0x00000020 +#define PPI_GPS_GPSFLAGS_FLAG6_DEAD_RECK 0x00000040 +#define PPI_GPS_GPSFLAGS_FLAG7_MANUAL 0x00000080 +#define PPI_GPS_GPSFLAGS_FLAG8_SIM 0x00000100 + { &hf_ppi_gps_gpsflags_flag0_nofix, /* no fix available */ + { "No fix available", "ppi_gps.gpsflagss.nofix", + FT_BOOLEAN, 32, NULL, PPI_GPS_GPSFLAGS_FLAG0_NOFIX, + "No GPS fix available", HFILL } }, + { &hf_ppi_gps_gpsflags_flag1_gpsfix, /* GPSfix available */ + { "GPS provided fix", "ppi_gps.gpsflagss.gps", + FT_BOOLEAN, 32, NULL, PPI_GPS_GPSFLAGS_FLAG1_GPS, + "GPS provided fix", HFILL } }, + { &hf_ppi_gps_gpsflags_flag2_diffgps, /* Differential GPS fix available */ + { "Differential GPS provided fix", "ppi_gps.gpsflagss.diffgps", + FT_BOOLEAN, 32, NULL, PPI_GPS_GPSFLAGS_FLAG2_DIFFGPS, + "DGPS provided fix", HFILL } }, + { &hf_ppi_gps_gpsflags_flag3_PPS, /* PPS fix */ + { "PPS fix", "ppi_gps.gpsflagss.pps", + FT_BOOLEAN, 32, NULL, PPI_GPS_GPSFLAGS_FLAG3_PPS, + " PPS fix ", HFILL } }, + { &hf_ppi_gps_gpsflags_flag4_RTK, /* RTK fix*/ + { "RTK fix", "ppi_gps.gpsflagss.rtk", + FT_BOOLEAN, 32, NULL, PPI_GPS_GPSFLAGS_FLAG4_RTK, + "RTK fix ", HFILL } }, + { &hf_ppi_gps_gpsflags_flag5_floatRTK, /*float RTK */ + { "floatRTK fix", "ppi_gps.gpsflagss.frtk", + FT_BOOLEAN, 32, NULL, PPI_GPS_GPSFLAGS_FLAG5_FLOATRTK, + " floatRTK fix ", HFILL } }, + { &hf_ppi_gps_gpsflags_flag6_dead_reck, /*dead reckoning */ + { "dead reckoning fix", "ppi_gps.gpsflagss.dead_reck", + FT_BOOLEAN, 32, NULL, PPI_GPS_GPSFLAGS_FLAG6_DEAD_RECK, + "dead reckoning fix ", HFILL } }, + { &hf_ppi_gps_gpsflags_flag7_manual, /* manual */ + { "manual fix", "ppi_gps.gpsflagss.manual", + FT_BOOLEAN, 32, NULL, PPI_GPS_GPSFLAGS_FLAG7_MANUAL, + "manual fix available", HFILL } }, + { &hf_ppi_gps_gpsflags_flag8_sim, /* simulation */ + { "simulated fix", "ppi_gps.gpsflagss.simulation", + FT_BOOLEAN, 32, NULL, PPI_GPS_GPSFLAGS_FLAG8_SIM, + "simulated fix", HFILL } }, + + }; + static gint *ett[] = { + &ett_ppi_gps, + &ett_ppi_gps_present, + &ett_ppi_gps_gpsflags_flags + }; + + proto_ppi_gps = proto_register_protocol("PPI Geotagging GPS tag decoder", "PPI GPS Decoder", "ppi_gps"); + proto_register_field_array(proto_ppi_gps, hf, array_length(hf)); + proto_register_subtree_array(ett, array_length(ett)); + register_dissector("ppi_gps", dissect_ppi_gps, proto_ppi_gps); + +} +void dissect_ppi_gps(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { + /* These are locals used for processing the current tvb */ + guint length; + guint length_remaining; + int offset = 0; + + proto_tree *ppi_gps_tree = NULL; + proto_tree *pt, *present_tree = NULL; + proto_tree *my_pt, *gpsflags_flags_tree = NULL; /* used for DeviceType bitmask stuff */ + + proto_item *ti = NULL; + + + /* bits */ + int bit; + guint32 present, next_present; + /* values actually read out, for displaying */ + guint32 version, gpsflags_flags; + gdouble lat, lon, alt, alt_gnd; + nstime_t gps_timestamp; + int gps_time_size, already_processed_fractime; /* we use this internally to track if this is a 4 or 8 byte wide timestamp */ + gdouble eph, epv, ept; + + /* these are temporary intermediate values, used in the individual cases below */ + guint32 t_lat, t_lon, t_alt, t_alt_gnd; + guint32 t_herr, t_verr, t_terr; + guint32 t_appspecific_num; + /* initialize the timestamp value(s) */ + gps_timestamp.secs = gps_timestamp.nsecs = gps_time_size = already_processed_fractime = 0; + + /* Clear out stuff in the info column */ + if (check_col(pinfo->cinfo,COL_INFO)) + col_clear(pinfo->cinfo,COL_INFO); + /* pull out the first three fields of the BASE-GEOTAG-HEADER */ + version = tvb_get_guint8(tvb, offset); + length = tvb_get_letohs(tvb, offset+2); + present = tvb_get_letohl(tvb, offset+4); + + if (check_col(pinfo->cinfo, COL_INFO)) + col_add_fstr(pinfo->cinfo, COL_INFO, "PPI_GPS Capture v%u, Length %u", version, length); + + /* Dissect the packet */ + if (tree) { + ti = proto_tree_add_protocol_format(tree, proto_ppi_gps, + tvb, 0, length, "PPI GPS Header v%u, Length %u", version, length); + ppi_gps_tree= proto_item_add_subtree(ti, ett_ppi_gps); + proto_tree_add_uint(ppi_gps_tree, hf_ppi_gps_version, tvb, offset, 1, version); + proto_tree_add_item(ppi_gps_tree, hf_ppi_gps_pad, tvb, offset + 1, 1, FALSE); + ti = proto_tree_add_uint(ppi_gps_tree, hf_ppi_gps_length, tvb, offset + 2, 2, length); + } + /* basic length sanity checking */ + if (length > PPI_GPS_MAXTAGLEN ) { + if (tree) + proto_item_append_text(ti, "Invalid PPI-GPS length (got %d, %d max\n)", length, PPI_GPS_MAXTAGLEN); + return; + } + /* no minimum length check, technically zero is valid */ + + /* initialize the length of the actual tag contents */ + length_remaining = length; + if (version != 1) { + if (tree) + proto_item_append_text(ti, "invalid version (got %d, expected 1)", version); + return; + } + + /* + * This only works if there is exactly 1 present + * field in the header. This is not a problem as there are currently no extended bitmasks defined. + */ + if (length_remaining < PPI_GEOBASE_MIN_HEADER_LEN) { + /* + * Base-geotag-header (Radiotap lookalike) is shorter than the fixed-length portion + * plus one "present" bitset. + */ + if (tree) + proto_item_append_text(ti, " (bogus - minimum length is 8)"); + return; + } + /* Subtree for the "present flags" bitfield. */ + if (tree) { + pt = proto_tree_add_uint(ppi_gps_tree, hf_ppi_gps_present, tvb, offset + 4, 4, present); + present_tree = proto_item_add_subtree(pt, ett_ppi_gps_present); + + proto_tree_add_item(present_tree, hf_ppi_gps_present_gpsflags_flags, tvb, 4, 4, TRUE); + proto_tree_add_item(present_tree, hf_ppi_gps_present_lat, tvb, 4, 4, TRUE); + proto_tree_add_item(present_tree, hf_ppi_gps_present_lon, tvb, 4, 4, TRUE); + proto_tree_add_item(present_tree, hf_ppi_gps_present_alt, tvb, 4, 4, TRUE); + proto_tree_add_item(present_tree, hf_ppi_gps_present_alt_gnd, tvb, 4, 4, TRUE); + proto_tree_add_item(present_tree, hf_ppi_gps_present_gpstime, tvb, 4, 4, TRUE); + proto_tree_add_item(present_tree, hf_ppi_gps_present_fractime, tvb, 4, 4, TRUE); + proto_tree_add_item(present_tree, hf_ppi_gps_present_eph, tvb, 4, 4, TRUE); + proto_tree_add_item(present_tree, hf_ppi_gps_present_epv, tvb, 4, 4, TRUE); + proto_tree_add_item(present_tree, hf_ppi_gps_present_ept, tvb, 4, 4, TRUE); + proto_tree_add_item(present_tree, hf_ppi_gps_present_descr, tvb, 4, 4, TRUE); + proto_tree_add_item(present_tree, hf_ppi_gps_present_appspecific_num, tvb, 4, 4, TRUE); + proto_tree_add_item(present_tree, hf_ppi_gps_present_appspecific_data, tvb, 4, 4, TRUE); + proto_tree_add_item(present_tree, hf_ppi_gps_present_ext, tvb, 4, 4, TRUE); + } + offset += PPI_GEOBASE_MIN_HEADER_LEN; + length_remaining -= PPI_GEOBASE_MIN_HEADER_LEN; + + /* The fixed BASE-GEOTAG-HEADER has been handled at this point. move on to the individual fields */ + for (; present; present = next_present) { + /* clear the least significant bit that is set */ + next_present = present & (present - 1); + /* extract the least significant bit that is set */ + bit = BITNO_32(present ^ next_present); + switch (bit) { + case PPI_GEOTAG_GPSFLAGS: + if (length_remaining < 4) + break; + gpsflags_flags = tvb_get_letohl(tvb, offset); /* retrieve 32-bit gpsflags bitmask (-not- present bitmask) */ + if (tree) { + /* first we add the hex flags line */ + my_pt = proto_tree_add_uint(ppi_gps_tree, hf_ppi_gps_gpsflags_flags, tvb, offset , 4, gpsflags_flags); + /* then we add a subtree */ + gpsflags_flags_tree = proto_item_add_subtree(my_pt, ett_ppi_gps_gpsflags_flags); + /* to pin the individual bits on */ + proto_tree_add_item(gpsflags_flags_tree, hf_ppi_gps_gpsflags_flag0_nofix, tvb, offset, 4, TRUE); + proto_tree_add_item(gpsflags_flags_tree, hf_ppi_gps_gpsflags_flag1_gpsfix, tvb, offset, 4, TRUE); + proto_tree_add_item(gpsflags_flags_tree, hf_ppi_gps_gpsflags_flag2_diffgps, tvb, offset, 4, TRUE); + proto_tree_add_item(gpsflags_flags_tree, hf_ppi_gps_gpsflags_flag3_PPS, tvb, offset, 4, TRUE); + proto_tree_add_item(gpsflags_flags_tree, hf_ppi_gps_gpsflags_flag4_RTK, tvb, offset, 4, TRUE); + proto_tree_add_item(gpsflags_flags_tree, hf_ppi_gps_gpsflags_flag5_floatRTK, tvb, offset, 4, TRUE); + proto_tree_add_item(gpsflags_flags_tree, hf_ppi_gps_gpsflags_flag6_dead_reck, tvb, offset, 4, TRUE); + proto_tree_add_item(gpsflags_flags_tree, hf_ppi_gps_gpsflags_flag7_manual, tvb, offset, 4, TRUE); + proto_tree_add_item(gpsflags_flags_tree, hf_ppi_gps_gpsflags_flag8_sim, tvb, offset, 4, TRUE); + } + offset+=4; + length_remaining-=4; + break; + case PPI_GEOTAG_LAT: + if (length_remaining < 4) + break; + t_lat = tvb_get_letohl(tvb, offset); + lat = fixed3_7_to_gdouble(t_lat); + if (tree) + proto_tree_add_double(ppi_gps_tree, hf_ppi_gps_lat, tvb, offset, 4, lat); + offset+=4; + length_remaining-=4; + break; + case PPI_GEOTAG_LON: + if (length_remaining < 4) + break; + t_lon = tvb_get_letohl(tvb, offset); + lon = fixed3_7_to_gdouble(t_lon); + if (tree) + proto_tree_add_double(ppi_gps_tree, hf_ppi_gps_lon, tvb, offset, 4, lon); + offset+=4; + length_remaining-=4; + break; + case PPI_GEOTAG_ALT: + if (length_remaining < 4) + break; + t_alt = tvb_get_letohl(tvb, offset); + alt = fixed6_4_to_gdouble(t_alt); + if (tree) + proto_tree_add_double(ppi_gps_tree, hf_ppi_gps_alt, tvb, offset, 4, alt); + offset+=4; + length_remaining-=4; + break; + case PPI_GEOTAG_ALT_G: + if (length_remaining < 4) + break; + t_alt_gnd = tvb_get_letohl(tvb, offset); + alt_gnd = fixed6_4_to_gdouble(t_alt_gnd); + if (tree) + proto_tree_add_double(ppi_gps_tree, hf_ppi_gps_alt_gnd, tvb, offset, 4, alt_gnd); + offset+=4; + length_remaining-=4; + break; + case PPI_GEOTAG_GPSTIME: + if (length_remaining < 4) + break; + gps_timestamp.secs = tvb_get_letohl(tvb, offset); + gps_timestamp.nsecs = 0; + gps_time_size = 4; + /* This is somewhat tricky, inside the GPSTIME case we test if the optional fractional time */ + /* is present. If so, we pull it out, and combine it with GPSTime. */ + /* If we do this, we set already_processed_fractime to avoid hitting it below */ + if (length_remaining < 4 && (present & PPI_GPS_MASK_FRACTIME)) + break; + else if (present & PPI_GPS_MASK_FRACTIME) { + gps_timestamp.nsecs = tvb_get_letohl(tvb, offset + 4); /* manually offset seconds */ + already_processed_fractime = 1; + gps_time_size = 8; + } + if (tree) { + proto_tree_add_time(ppi_gps_tree, hf_ppi_gps_gpstime, tvb, offset, gps_time_size, &gps_timestamp); + } + offset += gps_time_size; + length_remaining -= gps_time_size; + break; + case PPI_GEOTAG_FRACTIONALTIME: + if (length_remaining < 4) + break; + if (already_processed_fractime) + break; + break; + case PPI_GEOTAG_EPH: + if (length_remaining < 4) + break; + t_herr = tvb_get_letohl(tvb, offset); + eph = fixed3_6_to_gdouble(t_herr); + if (tree) + proto_tree_add_double(ppi_gps_tree, hf_ppi_gps_eph, tvb, offset, 4, eph); + offset+=4; + length_remaining-=4; + break; + case PPI_GEOTAG_EPV: + if (length_remaining < 4) + break; + t_verr = tvb_get_letohl(tvb, offset); + epv = fixed3_6_to_gdouble(t_verr); + if (tree) + proto_tree_add_double(ppi_gps_tree, hf_ppi_gps_epv, tvb, offset, 4, epv); + offset+=4; + length_remaining-=4; + break; + case PPI_GEOTAG_EPT: + if (length_remaining < 4) + break; + t_terr = tvb_get_letohl(tvb, offset); + ept = ns_counter_to_gdouble(t_terr); + if (tree) + proto_tree_add_double(ppi_gps_tree, hf_ppi_gps_ept, tvb, offset, 4, ept); + offset+=4; + length_remaining-=4; + break; + case PPI_GEOTAG_DESCRIPTIONSTR: + if (length_remaining < 32) + break; + if (tree) + proto_tree_add_item(ppi_gps_tree, hf_ppi_gps_descr, tvb, offset, 32, FALSE); + offset+=32; + length_remaining-=32; + break; + case PPI_GEOTAG_APPID: + if (length_remaining < 4) + break; + t_appspecific_num = tvb_get_letohl(tvb, offset); /* application specific parsers may switch on this later */ + if (tree) { + proto_tree_add_uint(ppi_gps_tree, hf_ppi_gps_appspecific_num, tvb, offset, 4, t_appspecific_num); + } + offset+=4; + length_remaining-=4; + break; + case PPI_GEOTAG_APPDATA: + if (length_remaining < 60) + break; + if (tree) { + proto_tree_add_item(ppi_gps_tree, hf_ppi_gps_appspecific_data, tvb, offset, 60, FALSE); + } + offset+=60; + length_remaining-=60; + break; + + /* + * This indicates a field whose size we do not know, so we cannot proceed. + */ + default: + next_present = 0; /* this will terminate the loop */ + proto_tree_add_text(ppi_gps_tree, tvb, offset, 0, "Error: PPI-GEOLOCATION-GPS: unknown bit (%d) set in present field.\n", bit); + continue; + } /* switch (bit) */ + + } /* (for present..)*/ + + /* If there was any post processing of the elements, it could happen here. */ + return; +} + +/* + * Editor modelines + * + * Local Variables: + * c-basic-offset: 4 + * tab-width: 8 + * indent-tabs-mode: nil + * End: + * + * ex: set shiftwidth=4 tabstop=8 expandtab + * :indentSize=4:tabSize=8:noTabs=true: + */ + + + diff --git a/epan/dissectors/packet-ppi-vector.c b/epan/dissectors/packet-ppi-vector.c new file mode 100644 index 0000000000..d352052229 --- /dev/null +++ b/epan/dissectors/packet-ppi-vector.c @@ -0,0 +1,929 @@ +/* packet-ppi-vector.c + * Routines for PPI-GEOLOCATION-VECTOR dissection + * Copyright 2010, Harris Corp, jellch@harris.com + * + * $Id$ + * + * Wireshark - Network traffic analyzer + * By Gerald Combs <gerald@wireshark.org> + * Copyright 1998 Gerald Combs + * + * Copied from packet-radiotap.c + * + * 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. + */ +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include <glib.h> +#include <string.h> + +#include <epan/packet.h> +#include <epan/ptvcursor.h> +#include <epan/prefs.h> +#include <epan/reassemble.h> +#include "packet-ppi-geolocation-common.h" + +enum ppi_vector_type { + PPI_VECTOR_VFLAGS = 0, + PPI_VECTOR_VCHARS = 1, + PPI_VECTOR_ROTX = 2, + PPI_VECTOR_ROTY = 3, + PPI_VECTOR_ROTZ = 4, + PPI_VECTOR_OFF_R = 5, + PPI_VECTOR_OFF_F = 6, + PPI_VECTOR_OFF_U = 7, + PPI_VECTOR_VEL_R = 8, + PPI_VECTOR_VEL_F = 9, + PPI_VECTOR_VEL_U = 10, + PPI_VECTOR_VEL_T = 11, + PPI_VECTOR_ACC_R = 12, + PPI_VECTOR_ACC_F = 13, + PPI_VECTOR_ACC_U = 14, + PPI_VECTOR_ACC_T = 15, + PPI_VECTOR_ERR_ROT = 16, + PPI_VECTOR_ERR_OFF = 17, + PPI_VECTOR_ERR_VEL = 18, + PPI_VECTOR_ERR_ACC = 19, + + PPI_VECTOR_DESCSTR = 28, + PPI_VECTOR_APPID = 29, + PPI_VECTOR_APPDATA = 30, + PPI_VECTOR_EXT = 31 +}; + + +/* protocol */ +static int proto_ppi_vector = -1; + +/* "top" level fields */ +static int hf_ppi_vector_version = -1; +static int hf_ppi_vector_pad = -1; +static int hf_ppi_vector_length = -1; +static int hf_ppi_vector_present = -1; +static int hf_ppi_vector_vflags = -1; +static int hf_ppi_vector_vchars = -1; +static int hf_ppi_vector_rot_x = -1; +static int hf_ppi_vector_rot_y = -1; +static int hf_ppi_vector_rot_z = -1; +static int hf_ppi_vector_off_r = -1; +static int hf_ppi_vector_off_f = -1; +static int hf_ppi_vector_off_u = -1; +static int hf_ppi_vector_vel_r = -1; +static int hf_ppi_vector_vel_f = -1; +static int hf_ppi_vector_vel_u = -1; +static int hf_ppi_vector_vel_t = -1; +static int hf_ppi_vector_acc_r = -1; +static int hf_ppi_vector_acc_f = -1; +static int hf_ppi_vector_acc_u = -1; +static int hf_ppi_vector_acc_t = -1; + +static int hf_ppi_vector_err_rot= -1; +static int hf_ppi_vector_err_off= -1; +static int hf_ppi_vector_err_vel= -1; +static int hf_ppi_vector_err_acc= -1; +static int hf_ppi_vector_descstr= -1; +static int hf_ppi_vector_appspecific_num = -1; +static int hf_ppi_vector_appspecific_data = -1; + +/* "Present" flags */ +static int hf_ppi_vector_present_vflags = -1; +static int hf_ppi_vector_present_vchars = -1; +static int hf_ppi_vector_present_val_x = -1; +static int hf_ppi_vector_present_val_y = -1; +static int hf_ppi_vector_present_val_z = -1; +static int hf_ppi_vector_present_off_r = -1; +static int hf_ppi_vector_present_off_f = -1; +static int hf_ppi_vector_present_off_u = -1; +static int hf_ppi_vector_present_vel_r = -1; +static int hf_ppi_vector_present_vel_f = -1; +static int hf_ppi_vector_present_vel_u = -1; +static int hf_ppi_vector_present_vel_t = -1; +static int hf_ppi_vector_present_acc_r = -1; +static int hf_ppi_vector_present_acc_f = -1; +static int hf_ppi_vector_present_acc_u = -1; +static int hf_ppi_vector_present_acc_t = -1; +static int hf_ppi_vector_present_err_rot = -1; +static int hf_ppi_vector_present_err_off = -1; +static int hf_ppi_vector_present_err_vel = -1; +static int hf_ppi_vector_present_err_acc = -1; +static int hf_ppi_vector_present_descstr= -1; +static int hf_ppi_vector_presenappsecific_num = -1; +static int hf_ppi_vector_present_appspecific_data = -1; +static int hf_ppi_vector_present_ext = -1; + +/* VectorFlags bits */ +/* There are currently only three vector flags. +* These control the units/interpreration of a vector +*/ +static int hf_ppi_vector_vflags_defines_forward = -1; +static int hf_ppi_vector_vflags_rots_absolute = -1; /* different ways to display the same bit, hi or low */ +static int hf_ppi_vector_vflags_offsets_from_gps = -1; /* these are different ways to display the same bit, hi or low */ + +/* There are currently eight vector characteristics. +* These are purely descriptive (no mathematical importance) +*/ +static int hf_ppi_vector_vchars_antenna = -1; +static int hf_ppi_vector_vchars_dir_of_travel = -1; +static int hf_ppi_vector_vchars_front_of_veh = -1; + +static int hf_ppi_vector_vchars_gps_derived = -1; +static int hf_ppi_vector_vchars_ins_derived = -1; +static int hf_ppi_vector_vchars_compass_derived = -1; +static int hf_ppi_vector_vchars_accelerometer_derived = -1; +static int hf_ppi_vector_vchars_human_derived = -1; + +/*These represent arrow-dropdownthings in the gui */ +static gint ett_ppi_vector = -1; +static gint ett_ppi_vector_present = -1; +static gint ett_ppi_vectorflags= -1; +static gint ett_ppi_vectorchars= -1; + +static void dissect_ppi_vector(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree); + +void proto_register_ppi_vector(void) { + /* The following array initializes those header fields declared above to the values displayed */ + static hf_register_info hf[] = { + { &hf_ppi_vector_version, + { "Header revision", "ppi_vector.version", + FT_UINT8, BASE_DEC, NULL, 0x0, + "Version of ppi_vector header format", HFILL } }, + { &hf_ppi_vector_pad, + { "Header pad", "ppi_vector.pad", + FT_UINT8, BASE_DEC, NULL, 0x0, + "Padding", HFILL } }, + { &hf_ppi_vector_length, + { "Header length", "ppi_vector.length", + FT_UINT16, BASE_DEC, NULL, 0x0, + "Length of header including version, pad, length and data fields", HFILL } }, + { &hf_ppi_vector_present, + { "Present", "ppi_vector.present", + FT_UINT32, BASE_HEX, NULL, 0x0, "Bitmask indicating which fields are present", HFILL } }, + +#define PPI_VECTOR_MASK_VFLAGS 0x00000001 +#define PPI_VECTOR_MASK_VCHARS 0x00000002 +#define PPI_VECTOR_MASK_ROTX 0x00000004 +#define PPI_VECTOR_MASK_ROTY 0x00000008 +#define PPI_VECTOR_MASK_ROTZ 0x00000010 +#define PPI_VECTOR_MASK_OFF_R 0x00000020 +#define PPI_VECTOR_MASK_OFF_F 0x00000040 +#define PPI_VECTOR_MASK_OFF_U 0x00000080 +#define PPI_VECTOR_MASK_VEL_R 0x00000100 +#define PPI_VECTOR_MASK_VEL_F 0x00000200 +#define PPI_VECTOR_MASK_VEL_U 0x00000400 +#define PPI_VECTOR_MASK_VEL_T 0x00000800 +#define PPI_VECTOR_MASK_ACC_R 0x00001000 +#define PPI_VECTOR_MASK_ACC_F 0x00002000 +#define PPI_VECTOR_MASK_ACC_U 0x00004000 +#define PPI_VECTOR_MASK_ACC_T 0x00008000 + +#define PPI_VECTOR_MASK_ERR_ROT 0x00010000 +#define PPI_VECTOR_MASK_ERR_OFF 0x00020000 +#define PPI_VECTOR_MASK_ERR_VEL 0x00040000 +#define PPI_VECTOR_MASK_ERR_ACC 0x00080000 + +#define PPI_VECTOR_MASK_DESCSTR 0x10000000 /* 28 */ +#define PPI_VECTOR_MASK_APPID 0x20000000 /* 29 */ +#define PPI_VECTOR_MASK_APPDATA 0x40000000 /* 30 */ +#define PPI_VECTOR_MASK_EXT 0x80000000 /* 31 */ + + /* Boolean 'present' flags */ + { &hf_ppi_vector_present_vflags, + { "Vector flags", "ppi_vector.present.flags", + FT_BOOLEAN, 32, NULL, PPI_VECTOR_MASK_VFLAGS, + "Specifies if the Vector flags bitfield is present", HFILL } }, + + { &hf_ppi_vector_present_vchars, + { "Vector chararacteristics", "ppi_vector.present.chars", + FT_BOOLEAN, 32, NULL, PPI_VECTOR_MASK_VCHARS, + "Specifies if the Vector chars bitfield is present", HFILL } }, + + { &hf_ppi_vector_present_val_x, + { "Pitch", "ppi_vector.present.pitch", + FT_BOOLEAN, 32, NULL, PPI_VECTOR_MASK_ROTX, + "Specifies if the rotate-x field (pitch) is present", HFILL } }, + + { &hf_ppi_vector_present_val_y, + { "Roll", "ppi_vector.present.roll", + FT_BOOLEAN, 32, NULL, PPI_VECTOR_MASK_ROTY, + "Specifies if the rotate-y field (roll) is present", HFILL } }, + + { &hf_ppi_vector_present_val_z, + { "Heading", "ppi_vector.present.heading", + FT_BOOLEAN, 32, NULL, PPI_VECTOR_MASK_ROTZ, + "Specifies if the rotate-z field (heading) is present", HFILL } }, + + + { &hf_ppi_vector_present_off_r, + { "Offset_R", "ppi_vector.present.off_r", + FT_BOOLEAN, 32, NULL, PPI_VECTOR_MASK_OFF_R, + "Specifies if the offset-right field is present", HFILL } }, + + { &hf_ppi_vector_present_off_f, + { "Offset_F", "ppi_vector.present.off_f", + FT_BOOLEAN, 32, NULL, PPI_VECTOR_MASK_OFF_F, + "Specifies if the offset-forward field is present", HFILL } }, + + { &hf_ppi_vector_present_off_u, + { "Offset_U", "ppi_vector.present.off_u", + FT_BOOLEAN, 32, NULL, PPI_VECTOR_MASK_OFF_U, + "Specifies if the offset-up field is present", HFILL } }, + + { &hf_ppi_vector_present_vel_r, + { "Velocity_R", "ppi_vector.present.vel_r", + FT_BOOLEAN, 32, NULL, PPI_VECTOR_MASK_VEL_R, + "Specifies if the velocity-right field is present", HFILL } }, + + { &hf_ppi_vector_present_vel_f, + { "Velocity_F", "ppi_vector.present.vel_f", + FT_BOOLEAN, 32, NULL, PPI_VECTOR_MASK_VEL_F, + "Specifies if the velocity-forward field is present", HFILL } }, + + { &hf_ppi_vector_present_vel_u, + { "Velocity_U", "ppi_vector.present.vel_u", + FT_BOOLEAN, 32, NULL, PPI_VECTOR_MASK_VEL_U, + "Specifies if the velocity-up field is present", HFILL } }, + { &hf_ppi_vector_present_vel_t, + { "Velocity_T", "ppi_vector.present.vel_t", + FT_BOOLEAN, 32, NULL, PPI_VECTOR_MASK_VEL_T, + "Specifies if the total velocity field is present", HFILL } }, + + { &hf_ppi_vector_present_acc_r, + { "Acceleration_R", "ppi_vector.present.acc_r", + FT_BOOLEAN, 32, NULL, PPI_VECTOR_MASK_ACC_R, + "Specifies if the accel-right field is present", HFILL } }, + + { &hf_ppi_vector_present_acc_f, + { "Acceleration_F", "ppi_vector.present.acc_f", + FT_BOOLEAN, 32, NULL, PPI_VECTOR_MASK_ACC_F, + "Specifies if the accel-forward field is present", HFILL } }, + + { &hf_ppi_vector_present_acc_u, + { "Acceleration_U", "ppi_vector.present.acc_u", + FT_BOOLEAN, 32, NULL, PPI_VECTOR_MASK_ACC_U, + "Specifies if the accel-up field is present", HFILL } }, + { &hf_ppi_vector_present_acc_t, + { "Acceleration_T", "ppi_vector.present.acc_t", + FT_BOOLEAN, 32, NULL, PPI_VECTOR_MASK_ACC_T, + "Specifies if the total acceleration field is present", HFILL } }, + + { &hf_ppi_vector_present_err_rot, + { "err_rot", "ppi_vector.present.err_rot", + FT_BOOLEAN, 32, NULL, PPI_VECTOR_MASK_ERR_ROT, + "Specifies if the rotation error field is present", HFILL } }, + + { &hf_ppi_vector_present_err_off, + { "err_off", "ppi_vector.present.err_off", + FT_BOOLEAN, 32, NULL, PPI_VECTOR_MASK_ERR_OFF, + "Specifies if the offset error field is present", HFILL } }, + + { &hf_ppi_vector_present_err_vel, + { "err_vel", "ppi_vector.present.err_vel", + FT_BOOLEAN, 32, NULL, PPI_VECTOR_MASK_ERR_VEL, + "Specifies if the velocity error field is present", HFILL } }, + + { &hf_ppi_vector_present_err_acc, + { "err_acc", "ppi_vector.present.err_acc", + FT_BOOLEAN, 32, NULL, PPI_VECTOR_MASK_ERR_ACC, + "Specifies if the acceleration error field is present", HFILL } }, + + { &hf_ppi_vector_present_descstr, + { "descstr", "ppi_vector.present.descstr", + FT_BOOLEAN, 32, NULL, PPI_VECTOR_MASK_DESCSTR, + "Specifies if the acceleration error field is present", HFILL } }, + + { &hf_ppi_vector_presenappsecific_num, + { "appid", "ppi_vector.present.appid", + FT_BOOLEAN, 32, NULL, PPI_VECTOR_MASK_APPID, + "Specifies if the application specific field id is present", HFILL } }, + + { &hf_ppi_vector_present_appspecific_data, + { "appdata", "ppi_vector.present.appdata", + FT_BOOLEAN, 32, NULL, PPI_VECTOR_MASK_APPDATA, + "Specifies if the application specific data field is present", HFILL } }, + + { &hf_ppi_vector_present_ext, + { "Ext", "ppi_vector.present.ext", + FT_BOOLEAN, 32, NULL, PPI_VECTOR_MASK_EXT, + "Specifies if there are any extensions to the header present", HFILL } }, + + /* Now we get to the actual data fields */ + /* This setups the "Vector fflags" hex dropydown thing */ + { &hf_ppi_vector_vflags, + { "Vector flags", "ppi_vector.vector_flags", + FT_UINT32, BASE_HEX, NULL, 0x0, "Bitmask indicating coordinate sys, among others, etc", HFILL } }, + { &hf_ppi_vector_vchars, + { "Vector chars", "ppi_vector.vector_chars", + FT_UINT32, BASE_HEX, NULL, 0x0, "Bitmask indicating if vector tracks antenna, vehicle, motion, etc", HFILL } }, + { &hf_ppi_vector_rot_x, + { "Pitch", "ppi_vector.pitch", + FT_FLOAT, BASE_NONE, NULL, 0x0, + "Pitch (Rotation x) packet was receivd at", HFILL } }, + { &hf_ppi_vector_rot_y, + { "Roll", "ppi_vector.roll", + FT_FLOAT, BASE_NONE, NULL, 0x0, + "Roll (Rotation y) packet was receivd at", HFILL } }, + { &hf_ppi_vector_rot_z, + { "Heading", "ppi_vector.heading", + FT_FLOAT, BASE_NONE, NULL, 0x0, + "Heading (Rotation z) packet was receivd at", HFILL } }, + { &hf_ppi_vector_off_r, + { "Off-r", "ppi_vector.off_r", + FT_FLOAT, BASE_NONE, NULL, 0x0, + "Offset right", HFILL } }, + { &hf_ppi_vector_off_f, + { "Off-f", "ppi_vector.off_f", + FT_FLOAT, BASE_NONE, NULL, 0x0, + "Offation forward", HFILL } }, + { &hf_ppi_vector_off_u, + { "Off-u", "ppi_vector.off_u", + FT_FLOAT, BASE_NONE, NULL, 0x0, + "Offset up", HFILL } }, + { &hf_ppi_vector_vel_r, + { "Vel-r", "ppi_vector.vel_r", + FT_FLOAT, BASE_NONE, NULL, 0x0, + "Velocity-right", HFILL } }, + { &hf_ppi_vector_vel_f, + { "Vel-f", "ppi_vector.vel_f", + FT_FLOAT, BASE_NONE, NULL, 0x0, + "Velocity-forward", HFILL } }, + { &hf_ppi_vector_vel_u, + { "Vel-u", "ppi_vector.vel_u", + FT_FLOAT, BASE_NONE, NULL, 0x0, + "Velocity-up", HFILL } }, + { &hf_ppi_vector_vel_t, + { "Vel-t", "ppi_vector.vel_t", + FT_FLOAT, BASE_NONE, NULL, 0x0, + "Velocity-Total", HFILL } }, + + { &hf_ppi_vector_acc_r, + { "Accel-r", "ppi_vector.acc_r", + FT_FLOAT, BASE_NONE, NULL, 0x0, + "Acceleration-right", HFILL } }, + { &hf_ppi_vector_acc_f, + { "Accel-f", "ppi_vector.acc_f", + FT_FLOAT, BASE_NONE, NULL, 0x0, + "Acceleration-forward", HFILL } }, + { &hf_ppi_vector_acc_u, + { "Accel-u", "ppi_vector.acc_u", + FT_FLOAT, BASE_NONE, NULL, 0x0, + "Acceleration-up", HFILL } }, + { &hf_ppi_vector_acc_t, + { "Accel-t", "ppi_vector.acc_t", + FT_FLOAT, BASE_NONE, NULL, 0x0, + "Acceleration-Total", HFILL } }, + + { &hf_ppi_vector_err_rot, + { "Err-Rot", "ppi_vector.err_rot", + FT_FLOAT, BASE_NONE, NULL, 0x0, + "Rotation margin of error", HFILL } }, + { &hf_ppi_vector_err_off, + { "Err-Off", "ppi_vector.err_off", + FT_FLOAT, BASE_NONE, NULL, 0x0, + "Offset margin of error", HFILL } }, + { &hf_ppi_vector_err_vel, + { "Err-Vel", "ppi_vector.err_vel", + FT_FLOAT, BASE_NONE, NULL, 0x0, + "Velocity margin of error", HFILL } }, + { &hf_ppi_vector_err_acc, + { "Err-Accel", "ppi_vector.err_acc", + FT_FLOAT, BASE_NONE, NULL, 0x0, + "Acceleration margin of error", HFILL } }, + + { &hf_ppi_vector_descstr, + { "Description", "ppi_vector.descr", + FT_STRING, BASE_NONE, NULL, 0x0, + "Description", HFILL } } , + { &hf_ppi_vector_appspecific_num, + { "Application Specific id", "ppi_vector.appid", + FT_UINT32, BASE_HEX, NULL, 0x0, + "application specific identifier", HFILL } }, + { &hf_ppi_vector_appspecific_data, + { "Application specific data", "ppi_vector.appdata", + FT_BYTES, BASE_NONE, NULL, 0x0, + "application specific data", HFILL } }, + + /* There are currently only three vector flags. + * These control the units/interpreration of a vector + */ +#define PPI_VECTOR_VFLAGS_DEFINES_FORWARD 0x00000001 +#define PPI_VECTOR_VFLAGS_ROTS_ABSOLUTE 0x00000002 +#define PPI_VECTOR_VFLAGS_OFFSETS_FROM_GPS 0x00000004 + /* Boolean vector flags */ + { &hf_ppi_vector_vflags_defines_forward, + { "Defines forward", "ppi_vector.vflags.forward", + FT_BOOLEAN, 32, NULL, PPI_VECTOR_VFLAGS_DEFINES_FORWARD, + "Current vector indicates forward frame of reference", HFILL } }, + { &hf_ppi_vector_vflags_rots_absolute, + { "Absolute (E/N/U) rotations", "ppi_vector.vflags.abs_rots", + FT_BOOLEAN, 32, NULL, PPI_VECTOR_VFLAGS_ROTS_ABSOLUTE, + "Rotations are in East/North/Up coord. sys", HFILL } }, + { &hf_ppi_vector_vflags_offsets_from_gps, + { "Offsets from prev GPS TAG", "ppi_vector.vflags.offsets_from_gps", + FT_BOOLEAN, 32, NULL, PPI_VECTOR_VFLAGS_OFFSETS_FROM_GPS, + "Offsets fied rel. to Curr_Gps", HFILL } }, + + /* There are currently eight vector characteristics. + * These are purely descriptive (no mathematical importance) + */ +#define PPI_VECTOR_VCHARS_ANTENNA 0x00000001 +#define PPI_VECTOR_VCHARS_DIR_OF_TRAVEL 0x00000002 +#define PPI_VECTOR_VCHARS_FRONT_OF_VEH 0x00000004 + +#define PPI_VECTOR_VCHARS_GPS_DERIVED 0x00000100 +#define PPI_VECTOR_VCHARS_INS_DERIVED 0x00000200 +#define PPI_VECTOR_VCHARS_COMPASS_DERIVED 0x00000400 +#define PPI_VECTOR_VCHARS_ACCELEROMETER_DERIVED 0x00000800 +#define PPI_VECTOR_VCHARS_HUMAN_DERIVED 0x00001000 + /* Boolean vector chars */ + { &hf_ppi_vector_vchars_antenna, + { "Antenna", "ppi_vector.chars.antenna", + FT_BOOLEAN, 32, NULL, PPI_VECTOR_VCHARS_ANTENNA, + "Vector represents: Antenna", HFILL } }, + + { &hf_ppi_vector_vchars_dir_of_travel, + { "Dir of travel", "ppi_vector.chars.dir_of_travel", + FT_BOOLEAN, 32, NULL, PPI_VECTOR_VCHARS_DIR_OF_TRAVEL, + "Vector represents: Direction of travel", HFILL } }, + + { &hf_ppi_vector_vchars_front_of_veh, + { "Front of vehicle", "ppi_vector.chars.front_of_veh", + FT_BOOLEAN, 32, NULL, PPI_VECTOR_VCHARS_FRONT_OF_VEH, + "Vector represents: Front of vehicle", HFILL } }, + + { &hf_ppi_vector_vchars_gps_derived, + { "GPS Derived", "ppi_vector.vflags.gps_derived", + FT_BOOLEAN, 32, NULL, PPI_VECTOR_VCHARS_GPS_DERIVED, + "Vector derived from: gps", HFILL } }, + + { &hf_ppi_vector_vchars_ins_derived, + { "INS Derived", "ppi_vector.vflags.ins_derived", + FT_BOOLEAN, 32, NULL, PPI_VECTOR_VCHARS_INS_DERIVED, + "Vector derived from: inertial nav system", HFILL } }, + + { &hf_ppi_vector_vchars_compass_derived, + { "Compass derived", "ppi_vector.vflags.compass_derived", + FT_BOOLEAN, 32, NULL, PPI_VECTOR_VCHARS_COMPASS_DERIVED, + "Vector derived from: compass", HFILL } }, + + { &hf_ppi_vector_vchars_accelerometer_derived, + { "Accelerometer derived", "ppi_vector.vflags.accelerometer_derived", + FT_BOOLEAN, 32, NULL, PPI_VECTOR_VCHARS_ACCELEROMETER_DERIVED, + "Vector derived from: accelerometer", HFILL } }, + + { &hf_ppi_vector_vchars_human_derived, + { "Human derived", "ppi_vector.vflags.human_derived", + FT_BOOLEAN, 32, NULL, PPI_VECTOR_VCHARS_HUMAN_DERIVED, + "Vector derived from: human", HFILL } }, + + }; + static gint *ett[] = { + &ett_ppi_vector, + &ett_ppi_vector_present, + &ett_ppi_vectorflags, + &ett_ppi_vectorchars + }; + + proto_ppi_vector = proto_register_protocol("PPI vector decoder", "PPI vector Decoder", "ppi_vector"); + proto_register_field_array(proto_ppi_vector, hf, array_length(hf)); + proto_register_subtree_array(ett, array_length(ett)); + register_dissector("ppi_vector", dissect_ppi_vector, proto_ppi_vector); + +} +void dissect_ppi_vector(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { + proto_tree *ppi_vector_tree = NULL; + proto_tree *vectorflags_tree = NULL; + proto_tree *vectorchars_tree = NULL; + proto_tree *my_pt, *pt, *present_tree = NULL; + proto_item *ti = NULL; + guint length_remaining; + int offset = 0; + + + + /* bits */ + int bit; + guint32 present, next_present; + /* values actually read out, for displaying */ + guint32 version; + guint length; + gdouble rot_x, rot_y, rot_z; + gdouble off_r, off_f, off_u; + gdouble vel_r, vel_f, vel_u, vel_t; + gdouble acc_r, acc_f, acc_u, acc_t = 0; + gdouble err_rot, err_off, err_vel, err_acc; + char *curr_str; /* for description str */ + guint32 appsecific_num; /* appdata parser should add a subtree based on this value */ + guint32 flags=0, chars=0; + + /* temporary, conversion values */ + guint32 t_val; + + + /* Clear out stuff in the info column */ + if (check_col(pinfo->cinfo,COL_INFO)) { + col_clear(pinfo->cinfo,COL_INFO); + } + version = tvb_get_guint8(tvb, offset); + length = tvb_get_letohs(tvb, offset+2); + present = tvb_get_letohl(tvb, offset+4); + if (check_col(pinfo->cinfo, COL_INFO)) + col_add_fstr(pinfo->cinfo, COL_INFO, "PPI_Vector Capture v%u, Length %u", + version, length); + + /* Dissect the packet */ + if (tree) { + ti = proto_tree_add_protocol_format(tree, proto_ppi_vector, + tvb, 0, length, "PPI Vector Header v%u, Length %u", version, length); + ppi_vector_tree= proto_item_add_subtree(ti, ett_ppi_vector); + proto_tree_add_uint(ppi_vector_tree, hf_ppi_vector_version, + tvb, offset, 1, version); + proto_tree_add_item(ppi_vector_tree, hf_ppi_vector_pad, + tvb, offset + 1, 1, FALSE); + ti = proto_tree_add_uint(ppi_vector_tree, hf_ppi_vector_length, + tvb, offset + 2, 2, length); + } + length_remaining = length; + + /* + * FIXME: This only works if there is exactly 1 it_present + * field in the header + */ + if (length_remaining < PPI_GEOBASE_MIN_HEADER_LEN) { + /* + * Radiotap header is shorter than the fixed-length portion + * plus one "present" bitset. + */ + if (tree) + proto_item_append_text(ti, " (bogus - minimum length is 8)"); + return; + } + /* Subtree for the "present flags" bitfield. */ + if (tree) { + pt = proto_tree_add_uint(ppi_vector_tree, hf_ppi_vector_present, + tvb, offset + 4, 4, present); + present_tree = proto_item_add_subtree(pt, ett_ppi_vector_present); + + proto_tree_add_item(present_tree, hf_ppi_vector_present_vflags, tvb, 4, 4, TRUE); + proto_tree_add_item(present_tree, hf_ppi_vector_present_vchars, tvb, 4, 4, TRUE); + proto_tree_add_item(present_tree, hf_ppi_vector_present_val_x, tvb, 4, 4, TRUE); + proto_tree_add_item(present_tree, hf_ppi_vector_present_val_y, tvb, 4, 4, TRUE); + proto_tree_add_item(present_tree, hf_ppi_vector_present_val_z, tvb, 4, 4, TRUE); + proto_tree_add_item(present_tree, hf_ppi_vector_present_off_r, tvb, 4, 4, TRUE); + proto_tree_add_item(present_tree, hf_ppi_vector_present_off_f, tvb, 4, 4, TRUE); + proto_tree_add_item(present_tree, hf_ppi_vector_present_off_u, tvb, 4, 4, TRUE); + proto_tree_add_item(present_tree, hf_ppi_vector_present_vel_r, tvb, 4, 4, TRUE); + proto_tree_add_item(present_tree, hf_ppi_vector_present_vel_f, tvb, 4, 4, TRUE); + proto_tree_add_item(present_tree, hf_ppi_vector_present_vel_u, tvb, 4, 4, TRUE); + proto_tree_add_item(present_tree, hf_ppi_vector_present_vel_t, tvb, 4, 4, TRUE); + proto_tree_add_item(present_tree, hf_ppi_vector_present_acc_r, tvb, 4, 4, TRUE); + proto_tree_add_item(present_tree, hf_ppi_vector_present_acc_f, tvb, 4, 4, TRUE); + proto_tree_add_item(present_tree, hf_ppi_vector_present_acc_u, tvb, 4, 4, TRUE); + proto_tree_add_item(present_tree, hf_ppi_vector_present_acc_t, tvb, 4, 4, TRUE); + proto_tree_add_item(present_tree, hf_ppi_vector_present_err_rot, tvb, 4, 4, TRUE); + proto_tree_add_item(present_tree, hf_ppi_vector_present_err_off, tvb, 4, 4, TRUE); + proto_tree_add_item(present_tree, hf_ppi_vector_present_err_vel, tvb, 4, 4, TRUE); + proto_tree_add_item(present_tree, hf_ppi_vector_present_err_acc, tvb, 4, 4, TRUE); + proto_tree_add_item(present_tree, hf_ppi_vector_present_descstr, tvb, 4, 4, TRUE); + proto_tree_add_item(present_tree, hf_ppi_vector_presenappsecific_num, tvb, 4, 4, TRUE); + proto_tree_add_item(present_tree, hf_ppi_vector_present_appspecific_data, tvb, 4, 4, TRUE); + proto_tree_add_item(present_tree, hf_ppi_vector_present_ext, tvb, 4, 4, TRUE); + } + offset += PPI_GEOBASE_MIN_HEADER_LEN; + length_remaining -= PPI_GEOBASE_MIN_HEADER_LEN; + + + /* Now all of the fixed length, fixed location stuff is over. Loop over the bits */ + for (; present; present = next_present) { + /* clear the least significant bit that is set */ + next_present = present & (present - 1); + /* extract the least significant bit that is set */ + bit = BITNO_32(present ^ next_present); + switch (bit) { + case PPI_VECTOR_VFLAGS: + if (length_remaining < 4) + break; + flags = tvb_get_letohl(tvb, offset); + if (tree) { + my_pt = proto_tree_add_uint(ppi_vector_tree, hf_ppi_vector_vflags, tvb, offset , 4, flags); + vectorflags_tree= proto_item_add_subtree(my_pt, ett_ppi_vectorflags); + + proto_tree_add_item(vectorflags_tree, hf_ppi_vector_vflags_defines_forward, tvb, offset, 4, TRUE); + proto_tree_add_item(vectorflags_tree, hf_ppi_vector_vflags_rots_absolute, tvb, offset, 4, TRUE); + proto_tree_add_item(vectorflags_tree, hf_ppi_vector_vflags_offsets_from_gps, tvb, offset, 4, TRUE); + } + offset+=4; + length_remaining-=4; + break; + case PPI_VECTOR_VCHARS: + if (length_remaining < 4) + break; + chars = tvb_get_letohl(tvb, offset); + if (tree) { + my_pt = proto_tree_add_uint(ppi_vector_tree, hf_ppi_vector_vchars, tvb, offset , 4, chars); + vectorchars_tree= proto_item_add_subtree(my_pt, ett_ppi_vectorchars); + + proto_tree_add_item(vectorchars_tree, hf_ppi_vector_vchars_antenna, tvb, offset, 4, TRUE); + proto_tree_add_item(vectorchars_tree, hf_ppi_vector_vchars_dir_of_travel, tvb, offset, 4, TRUE); + proto_tree_add_item(vectorchars_tree, hf_ppi_vector_vchars_front_of_veh, tvb, offset, 4, TRUE); + proto_tree_add_item(vectorchars_tree, hf_ppi_vector_vchars_gps_derived, tvb, offset, 4, TRUE); + proto_tree_add_item(vectorchars_tree, hf_ppi_vector_vchars_ins_derived, tvb, offset, 4, TRUE); + proto_tree_add_item(vectorchars_tree, hf_ppi_vector_vchars_compass_derived, tvb, offset, 4, TRUE); + proto_tree_add_item(vectorchars_tree, hf_ppi_vector_vchars_accelerometer_derived, tvb, offset, 4, TRUE); + proto_tree_add_item(vectorchars_tree, hf_ppi_vector_vchars_human_derived, tvb, offset, 4, TRUE); + } + offset+=4; + length_remaining-=4; + break; + case PPI_VECTOR_ROTX: + if (length_remaining < 4) + break; + t_val = tvb_get_letohl(tvb, offset); + rot_x = fixed3_6_to_gdouble(t_val); + if (tree) { + ti = proto_tree_add_float(ppi_vector_tree, hf_ppi_vector_rot_x, tvb, offset, 4, rot_x); + if (flags & PPI_VECTOR_VFLAGS_ROTS_ABSOLUTE) + proto_item_append_text(ti, " Degrees (Absolute)"); + else + proto_item_append_text(ti, " Degrees (Rel to forward)"); + } + offset+=4; + length_remaining-=4; + break; + case PPI_VECTOR_ROTY: + if (length_remaining < 4) + break; + t_val = tvb_get_letohl(tvb, offset); + rot_y = fixed3_6_to_gdouble(t_val); + if (tree) { + ti = proto_tree_add_float(ppi_vector_tree, hf_ppi_vector_rot_y, tvb, offset, 4, rot_y); + if (flags & PPI_VECTOR_VFLAGS_ROTS_ABSOLUTE) + proto_item_append_text(ti, " Degrees (Absolute)"); + else + proto_item_append_text(ti, " Degrees (Rel to forward)"); + } + offset+=4; + length_remaining-=4; + break; + case PPI_VECTOR_ROTZ: + if (length_remaining < 4) + break; + t_val = tvb_get_letohl(tvb, offset); + rot_z = fixed3_6_to_gdouble(t_val); + if (tree) { + ti = proto_tree_add_float(ppi_vector_tree, hf_ppi_vector_rot_z, tvb, offset, 4, rot_z); + if (flags & PPI_VECTOR_VFLAGS_ROTS_ABSOLUTE) + proto_item_append_text(ti, " Degrees (Absolute) "); + else + proto_item_append_text(ti, " Degrees (Rel to forward)"); + } + offset+=4; + length_remaining-=4; + break; + case PPI_VECTOR_OFF_R: + if (length_remaining < 4) + break; + t_val = tvb_get_letohl(tvb, offset); + off_r = fixed6_4_to_gdouble(t_val); + if (tree) { + ti = proto_tree_add_float(ppi_vector_tree, hf_ppi_vector_off_r, tvb, offset, 4, off_r); + if (flags & PPI_VECTOR_VFLAGS_OFFSETS_FROM_GPS) + proto_item_append_text(ti, " m from Curr_GPS"); + else + proto_item_append_text(ti, " m from Curr_Pos"); + } + offset+=4; + length_remaining-=4; + break; + case PPI_VECTOR_OFF_F: + if (length_remaining < 4) + break; + t_val = tvb_get_letohl(tvb, offset); + off_f = fixed6_4_to_gdouble(t_val); + if (tree) { + ti = proto_tree_add_float(ppi_vector_tree, hf_ppi_vector_off_f, tvb, offset, 4, off_f); + if (flags & PPI_VECTOR_VFLAGS_OFFSETS_FROM_GPS) + proto_item_append_text(ti, " m from Curr_GPS"); + else + proto_item_append_text(ti, " m from Curr_Pos"); + } + offset+=4; + length_remaining-=4; + break; + case PPI_VECTOR_OFF_U: + if (length_remaining < 4) + break; + t_val = tvb_get_letohl(tvb, offset); + off_u = fixed6_4_to_gdouble(t_val); + if (tree) { + ti = proto_tree_add_float(ppi_vector_tree, hf_ppi_vector_off_u, tvb, offset, 4, off_u); + if (flags & PPI_VECTOR_VFLAGS_OFFSETS_FROM_GPS) + proto_item_append_text(ti, " m from Curr_GPS"); + else + proto_item_append_text(ti, " m from Curr_Pos"); + } + offset+=4; + length_remaining-=4; + break; + case PPI_VECTOR_VEL_R: + if (length_remaining < 4) + break; + t_val = tvb_get_letohl(tvb, offset); + vel_r = fixed6_4_to_gdouble(t_val); + if (tree) { + ti = proto_tree_add_float(ppi_vector_tree, hf_ppi_vector_vel_r, tvb, offset, 4, vel_r); + proto_item_append_text(ti, " m/s"); + } + offset+=4; + length_remaining-=4; + break; + case PPI_VECTOR_VEL_F: + if (length_remaining < 4) + break; + t_val = tvb_get_letohl(tvb, offset); + vel_f = fixed6_4_to_gdouble(t_val); + if (tree) { + ti = proto_tree_add_float(ppi_vector_tree, hf_ppi_vector_vel_f, tvb, offset, 4, vel_f); + proto_item_append_text(ti, " m/s"); + } + offset+=4; + length_remaining-=4; + break; + case PPI_VECTOR_VEL_U: + if (length_remaining < 4) + break; + t_val = tvb_get_letohl(tvb, offset); + vel_u = fixed6_4_to_gdouble(t_val); + if (tree) { + ti = proto_tree_add_float(ppi_vector_tree, hf_ppi_vector_vel_u, tvb, offset, 4, vel_u); + proto_item_append_text(ti, " m/s"); + } + offset+=4; + length_remaining-=4; + break; + case PPI_VECTOR_VEL_T: + if (length_remaining < 4) + break; + t_val = tvb_get_letohl(tvb, offset); + vel_t = fixed6_4_to_gdouble(t_val); + if (tree) { + ti = proto_tree_add_float(ppi_vector_tree, hf_ppi_vector_vel_t, tvb, offset, 4, vel_t); + proto_item_append_text(ti, " m/s"); + } + offset+=4; + length_remaining-=4; + break; + case PPI_VECTOR_ACC_R: + if (length_remaining < 4) + break; + t_val = tvb_get_letohl(tvb, offset); + acc_r = fixed6_4_to_gdouble(t_val); + if (tree) { + ti = proto_tree_add_float(ppi_vector_tree, hf_ppi_vector_acc_r, tvb, offset, 4, acc_r); + proto_item_append_text(ti, " (m/s)/s"); + } + offset+=4; + length_remaining-=4; + break; + case PPI_VECTOR_ACC_F: + if (length_remaining < 4) + break; + t_val = tvb_get_letohl(tvb, offset); + acc_f = fixed6_4_to_gdouble(t_val); + if (tree) { + ti = proto_tree_add_float(ppi_vector_tree, hf_ppi_vector_acc_f, tvb, offset, 4, acc_f); + proto_item_append_text(ti, " (m/s)/s"); + } + offset+=4; + length_remaining-=4; + break; + case PPI_VECTOR_ACC_U: + if (length_remaining < 4) + break; + t_val = tvb_get_letohl(tvb, offset); + acc_u = fixed6_4_to_gdouble(t_val); + if (tree) { + ti = proto_tree_add_float(ppi_vector_tree, hf_ppi_vector_acc_u, tvb, offset, 4, acc_u); + proto_item_append_text(ti, " (m/s)/s"); + } + offset+=4; + length_remaining-=4; + break; + case PPI_VECTOR_ACC_T: + if (length_remaining < 4) + break; + t_val = tvb_get_letohl(tvb, offset); + acc_t = fixed6_4_to_gdouble(t_val); + if (tree) { + ti = proto_tree_add_float(ppi_vector_tree, hf_ppi_vector_acc_t, tvb, offset, 4, acc_t); + proto_item_append_text(ti, " (m/s)/s"); + } + offset+=4; + length_remaining-=4; + break; + case PPI_VECTOR_ERR_ROT: + if (length_remaining < 4) + break; + t_val = tvb_get_letohl(tvb, offset); + err_rot = fixed3_6_to_gdouble(t_val); + if (tree) { + ti = proto_tree_add_float(ppi_vector_tree, hf_ppi_vector_err_rot, tvb, offset, 4, err_rot); + proto_item_append_text(ti, " degrees"); + } + offset+=4; + length_remaining-=4; + break; + case PPI_VECTOR_ERR_OFF: + if (length_remaining < 4) + break; + t_val = tvb_get_letohl(tvb, offset); + err_off = fixed6_4_to_gdouble(t_val); + if (tree) { + ti = proto_tree_add_float(ppi_vector_tree, hf_ppi_vector_err_off, tvb, offset, 4, err_off); + proto_item_append_text(ti, " meters"); + } + offset+=4; + length_remaining-=4; + break; + case PPI_VECTOR_ERR_VEL: + if (length_remaining < 4) + break; + t_val = tvb_get_letohl(tvb, offset); + err_vel = fixed6_4_to_gdouble(t_val); + if (tree) { + ti = proto_tree_add_float(ppi_vector_tree, hf_ppi_vector_err_vel, tvb, offset, 4, err_vel); + proto_item_append_text(ti, "m/s"); + } + offset+=4; + length_remaining-=4; + break; + case PPI_VECTOR_ERR_ACC: + if (length_remaining < 4) + break; + t_val = tvb_get_letohl(tvb, offset); + err_acc = fixed6_4_to_gdouble(t_val); + if (tree) { + ti = proto_tree_add_float(ppi_vector_tree, hf_ppi_vector_err_acc, tvb, offset, 4, err_acc); + proto_item_append_text(ti, " (m/s)/s"); + } + offset+=4; + length_remaining-=4; + break; + case PPI_VECTOR_DESCSTR: + if (length_remaining < 32) + break; + if (tree) { + curr_str= (char *) tvb_get_ptr(tvb, offset, 32); + proto_tree_add_string(ppi_vector_tree, hf_ppi_vector_descstr, tvb, offset, 32, curr_str); + } + offset+=32; + length_remaining-=32; + break; + case PPI_VECTOR_APPID: + if (length_remaining < 4) + break; + appsecific_num = tvb_get_letohl(tvb, offset); /* application specific parsers may switch on this later */ + if (tree) { + proto_tree_add_uint(ppi_vector_tree, hf_ppi_vector_appspecific_num, tvb, offset, 4, appsecific_num); + } + offset+=4; + length_remaining-=4; + break; + case PPI_VECTOR_APPDATA: + if (length_remaining < 60) + break; + if (tree) { + proto_tree_add_item(ppi_vector_tree, hf_ppi_vector_appspecific_data, tvb, offset, 60, FALSE); + } + offset+=60; + length_remaining-=60; + break; + + default: + /* + * This indicates a field whose size we do not + * know, so we cannot proceed. + */ + proto_tree_add_text(ppi_vector_tree, tvb, offset, 0, "Error: PPI-VECTOR: unknown bit (%d) set in present field.\n", bit); + next_present = 0; + continue; + } + + }; + return; +} + + diff --git a/epan/dissectors/packet-ppi.c b/epan/dissectors/packet-ppi.c index 67d75ce839..4c92819ed2 100644 --- a/epan/dissectors/packet-ppi.c +++ b/epan/dissectors/packet-ppi.c @@ -46,6 +46,7 @@ * May 7, 2008 - Added 'Aggregation Extension' and '802.3 Extension' */ + #ifdef HAVE_CONFIG_H # include "config.h" #endif @@ -94,8 +95,18 @@ * guint16 pfh_type; // Type * guint16 pfh_datalen; // Length of data * } ppi_fieldheader_t; + * + * Anyone looking to add their own PPI dissector would probably do well to imitate the GPS + * ones seperation into a distinct file. Here is a step by step guide: + * 1) add the number you received to the enum ppi_field_type declaration. + * 2) Add a value string for your number into vs_ppi_field_type + * 3) declare a dissector handle by the ppi_gps_handle, and initialize it inside proto_reg_handoff + * 4) add case inside dissect_ppi to call your new handle. + * 5) Write your parser, and get it loaded. + * Following these steps will result in less churn inside the ppi proper parser, and avoid namespace issues. */ + #define PPI_PADDED (1 << 0) #define PPI_V0_HEADER_LEN 8 @@ -167,10 +178,13 @@ typedef enum { /* 11 - 29999: RESERVED */ /* 30000 - 65535: Private types */ - INTEL_CORP_PRIVATE = 30000, - MOHAMED_THAGA_PRIVATE = 30001, - GPS_TAGGING_PRIVATE = 30002, - CACE_PRIVATE = 0xCACE + INTEL_CORP_PRIVATE = 30000, + MOHAMED_THAGA_PRIVATE = 30001, + PPI_GPS_INFO = 30002, /* 30002 - 30005 described in PPI-GEOLOCATION specifcation */ + PPI_VECTOR_INFO = 30003, /* currently available in draft from. jellch@harris.com */ + PPI_HARRIS_TEST0 = 30004, /* 30004 is used for testing geolocation tag enhancements */ + PPI_ANTENNA_INFO = 30005, + CACE_PRIVATE = 0xCACE /* All others RESERVED. Contact the WinPcap team for an assignment */ } ppi_field_type; @@ -308,6 +322,8 @@ static gint ett_8023_extension_errors = -1; static dissector_handle_t data_handle; static dissector_handle_t ieee80211_ht_handle; +static dissector_handle_t ppi_gps_handle, ppi_vector_handle, ppi_harris_test_handle, ppi_antenna_handle; + static const true_false_string tfs_ppi_head_flag_alignment = { "32-bit aligned", "Not aligned" }; static const true_false_string tfs_tsft_ms = { "milliseconds", "microseconds" }; @@ -327,7 +343,10 @@ static const value_string vs_ppi_field_type[] = { {INTEL_CORP_PRIVATE, "Intel Corporation (private)"}, {MOHAMED_THAGA_PRIVATE, "Mohamed Thaga (private)"}, - {GPS_TAGGING_PRIVATE, "GPS Tagging (private)"}, + {PPI_GPS_INFO, "GPS Tagging"}, + {PPI_VECTOR_INFO, "Vector Tagging"}, + {PPI_HARRIS_TEST0, "Harris geolocation-tag development"}, + {PPI_ANTENNA_INFO, "Antenna Tagging"}, {CACE_PRIVATE, "CACE Technologies (private)"}, {0, NULL} }; @@ -813,6 +832,58 @@ dissect_ppi(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) case PPI_8023_EXTENSION: dissect_8023_extension(tvb, pinfo, ppi_tree, offset, data_len); break; + case PPI_GPS_INFO: + if (ppi_gps_handle == NULL) + { + proto_tree_add_text(ppi_tree, tvb, offset, data_len, + "%s (%u bytes)", val_to_str(data_type, (value_string *)&vs_ppi_field_type, "GPS: "), data_len); + } + else /* we found a suitable dissector */ + { + /* skip over the ppi_fieldheader, and pass it off to the dedicated GPS dissetor */ + next_tvb = tvb_new_subset(tvb, offset + 4, data_len - 4 , -1); + call_dissector(ppi_gps_handle, next_tvb, pinfo, ppi_tree); + } + break; + case PPI_VECTOR_INFO: + if (ppi_vector_handle == NULL) + { + proto_tree_add_text(ppi_tree, tvb, offset, data_len, + "%s (%u bytes)", val_to_str(data_type, (value_string *)&vs_ppi_field_type, "VECTOR: "), data_len); + } + else /* we found a suitable dissector */ + { + /* skip over the ppi_fieldheader, and pass it off to the dedicated VECTOR dissetor */ + next_tvb = tvb_new_subset(tvb, offset + 4, data_len - 4 , -1); + call_dissector(ppi_vector_handle, next_tvb, pinfo, ppi_tree); + } + break; + case PPI_HARRIS_TEST0: + if (ppi_harris_test_handle == NULL) + { + proto_tree_add_text(ppi_tree, tvb, offset, data_len, + "%s (%u bytes)", val_to_str(data_type, (value_string *)&vs_ppi_field_type, "HARRIS: "), data_len); + } + else /* we found a suitable dissector */ + { + /* skip over the ppi_fieldheader, and pass it off to the dedicated ANTENNA_ORIENTATION dissetor */ + next_tvb = tvb_new_subset(tvb, offset + 4, data_len - 4 , -1); + call_dissector(ppi_harris_test_handle, next_tvb, pinfo, ppi_tree); + } + break; + case PPI_ANTENNA_INFO: + if (ppi_antenna_handle == NULL) + { + proto_tree_add_text(ppi_tree, tvb, offset, data_len, + "%s (%u bytes)", val_to_str(data_type, (value_string *)&vs_ppi_field_type, "ANTENNA: "), data_len); + } + else /* we found a suitable dissector */ + { + /* skip over the ppi_fieldheader, and pass it off to the dedicated ANTENNA dissetor */ + next_tvb = tvb_new_subset(tvb, offset + 4, data_len - 4 , -1); + call_dissector(ppi_antenna_handle, next_tvb, pinfo, ppi_tree); + } + break; default: if (tree) @@ -1291,6 +1362,10 @@ proto_reg_handoff_ppi(void) ppi_handle = create_dissector_handle(dissect_ppi, proto_ppi); data_handle = find_dissector("data"); ieee80211_ht_handle = find_dissector("wlan_ht"); + ppi_gps_handle = find_dissector("ppi_gps"); + ppi_vector_handle = find_dissector("ppi_vector"); + ppi_harris_test_handle = find_dissector("ppi_harris_test"); + ppi_antenna_handle = find_dissector("ppi_antenna"); dissector_add("wtap_encap", WTAP_ENCAP_PPI, ppi_handle); } |