diff options
author | etxrab <etxrab@f5534014-38df-0310-8fa8-9805f1628bb7> | 2005-07-11 22:23:15 +0000 |
---|---|---|
committer | etxrab <etxrab@f5534014-38df-0310-8fa8-9805f1628bb7> | 2005-07-11 22:23:15 +0000 |
commit | e503ab17a48805853bb7852fea9c85781a49901e (patch) | |
tree | 5939f89af9f4cfb3f31a494f853e89819e60c70a /epan/dissectors/packet-dis.c | |
parent | f605e125d79ed438c031b9ef92fb66a41261ce36 (diff) |
From Jeremy j Ouellette:
DIS dissection.
git-svn-id: http://anonsvn.wireshark.org/wireshark/trunk@14899 f5534014-38df-0310-8fa8-9805f1628bb7
Diffstat (limited to 'epan/dissectors/packet-dis.c')
-rw-r--r-- | epan/dissectors/packet-dis.c | 196 |
1 files changed, 196 insertions, 0 deletions
diff --git a/epan/dissectors/packet-dis.c b/epan/dissectors/packet-dis.c new file mode 100644 index 0000000000..d2e2b43aa6 --- /dev/null +++ b/epan/dissectors/packet-dis.c @@ -0,0 +1,196 @@ +/* packet-dis.c + * Routines for Distributed Interactive Simulation packet + * disassembly (IEEE-1278). + * Copyright 2005, Scientific Research Corporation + * Initial implementation by Jeremy Ouellette <jouellet@scires.com> + * + * Ethereal - Network traffic analyzer + * By Gerald Combs <gerald@ethereal.com> + * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +/* TODO / NOTES: + * Field handling isn't ideal; this dissector should probably register + * each individual field via the proto_register_field_array mechanism. + * This would lead to better PDML output (instead of requiring the end user + * to manually parse out the key/value pairs) and better searchability in + * interactive mode. + * + * Lots more PDUs to implement. Only the basic engagement events are currently + * handled (Fire, Detonation, Entity State). Most of the basic field types are + * complete, however, so declaring new PDUs should be fairly simple. + * + * Lots more enumerations to implement. + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include <stdio.h> +#include <epan/packet.h> +#include <epan/value_string.h> +#include <epan/prefs.h> +#include "packet-dis-enums.h" +#include "packet-dis-pdus.h" +#include "packet-dis-fields.h" + +#define DEFAULT_DIS_UDP_PORT 3000 + +static gint proto_dis = -1; +static gint ett_dis = -1; +static gint ett_dis_header = -1; +static gint ett_dis_payload = -1; + +static dissector_handle_t dis_dissector_handle; +static guint dis_udp_port = DEFAULT_DIS_UDP_PORT; + +static char* dis_proto_name = "Distributed Interactive Simulation"; +static char* dis_proto_name_short = "DIS"; + +/* Main dissector routine to be invoked for a DIS PDU. + */ +static void dissect_dis(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) +{ + proto_item *dis_tree = 0; + proto_item *dis_node = 0; + proto_item *dis_header_tree = 0; + proto_item *dis_header_node = 0; + proto_item *dis_payload_tree = 0; + proto_item *dis_payload_node = 0; + gint offset = 0; + const gchar *pduString = 0; + DIS_ParserNode *pduParser = 0; + + /* Reset the global PDU type variable -- this will be parsed as part of + * the DIS header. + */ + pduType = DIS_PDUTYPE_OTHER; + numArticulations = 0; + + if (check_col(pinfo->cinfo, COL_PROTOCOL)) + { + col_set_str(pinfo->cinfo, COL_PROTOCOL, dis_proto_name_short); + } + + /* Add the top-level DIS node under which the rest of the fields will be + * displayed. + */ + dis_node = proto_tree_add_protocol_format(tree, proto_dis, tvb, offset, + -1, "Distributed Interactive Simulation"); + dis_tree = proto_item_add_subtree(dis_node, ett_dis); + + /* Add a node to contain the DIS header fields. + */ + dis_header_node = proto_tree_add_text(dis_tree, tvb, offset, -1, "Header"); + dis_header_tree = proto_item_add_subtree(dis_header_node, ett_dis_header); + offset = parseFields(tvb, dis_header_tree, offset, DIS_FIELDS_PDU_HEADER); + proto_item_set_end(dis_header_node, tvb, offset); + + /* Locate the appropriate PDU parser, if type is known. + */ + switch (pduType) + { + case DIS_PDUTYPE_ENTITY_STATE: + pduParser = DIS_PARSER_ENTITY_STATE_PDU; + break; + case DIS_PDUTYPE_FIRE: + pduParser = DIS_PARSER_FIRE_PDU; + break; + case DIS_PDUTYPE_DETONATION: + pduParser = DIS_PARSER_DETONATION_PDU; + break; + default: + pduParser = 0; + break; + } + + /* Locate the string name for the PDU type enumeration, or default to + * "Unknown". + */ + pduString = val_to_str(pduType, DIS_PDU_Type_Strings, "Unknown"); + + /* Add a node to contain the DIS PDU fields. + */ + dis_payload_node = proto_tree_add_text(dis_tree, tvb, offset, -1, + "%s PDU", pduString); + + /* If a parser was located, invoke it on the data packet. + */ + if (pduParser != 0) + { + dis_payload_tree = proto_item_add_subtree(dis_payload_node, + ett_dis_payload); + offset = parseFields(tvb, dis_payload_tree, offset, pduParser); + proto_item_set_end(dis_payload_node, tvb, offset); + } +} + +/* Register handoff routine for DIS dissector. This will be invoked initially + * and when the preferences are changed, to handle changing the UDP port for + * which this dissector is registered. + */ +void proto_reg_handoff_dis(void) +{ + static gboolean dis_prefs_initialized = FALSE; + + if (!dis_prefs_initialized) + { + dis_dissector_handle = create_dissector_handle(dissect_dis, proto_dis); + } + else + { + dissector_delete("udp.port", dis_udp_port, dis_dissector_handle); + } + + dissector_add("udp.port", dis_udp_port, dis_dissector_handle); +} + +/* Registration routine for the DIS protocol. + */ +void proto_register_dis(void) +{ + /* Only these 3 ett variables will be present for every DIS PDU -- + * the rest are dynamic based on PDU type. + */ + static gint *ett[] = + { + &ett_dis, + &ett_dis_header, + &ett_dis_payload + }; + + module_t *dis_module; + + proto_dis = proto_register_protocol(dis_proto_name, dis_proto_name_short, + "dis"); + proto_register_subtree_array(ett, array_length(ett)); + + dis_module = prefs_register_protocol(proto_dis, proto_reg_handoff_dis); + + /* Create an unsigned integer preference to allow the user to specify the + * UDP port on which to capture DIS packets. + */ + prefs_register_uint_preference(dis_module, "udp.port", + "DIS UDP Port", + "Set the UDP port for DIS messages", + 10, &dis_udp_port); + + /* Perform the one-time initialization of the DIS parsers. + */ + initializeParsers(); +} |