aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAnders Broman <anders.broman@ericsson.com>2005-07-11 22:23:15 +0000
committerAnders Broman <anders.broman@ericsson.com>2005-07-11 22:23:15 +0000
commita063532343ff5e5f7d4795471ef2b29eaae9e43d (patch)
tree5939f89af9f4cfb3f31a494f853e89819e60c70a
parenteba6c1a70fdbf900255e5a0c45c90b7d98c443cf (diff)
From Jeremy j Ouellette:
DIS dissection. svn path=/trunk/; revision=14899
-rw-r--r--epan/dissectors/packet-dis-enums.c295
-rw-r--r--epan/dissectors/packet-dis-enums.h306
-rw-r--r--epan/dissectors/packet-dis-fields.c503
-rw-r--r--epan/dissectors/packet-dis-fields.h166
-rw-r--r--epan/dissectors/packet-dis-pdus.c401
-rw-r--r--epan/dissectors/packet-dis-pdus.h49
-rw-r--r--epan/dissectors/packet-dis.c196
7 files changed, 1916 insertions, 0 deletions
diff --git a/epan/dissectors/packet-dis-enums.c b/epan/dissectors/packet-dis-enums.c
new file mode 100644
index 0000000000..4795636ddc
--- /dev/null
+++ b/epan/dissectors/packet-dis-enums.c
@@ -0,0 +1,295 @@
+/* packet-dis-enums.c
+ * String definitions for DIS enumerations.
+ * 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include "packet-dis-enums.h"
+#include <epan/value_string.h>
+
+const value_string DIS_PDU_ProtocolVersion_Strings[] =
+{
+ { DIS_VERSION_OTHER, "Other" },
+ { DIS_VERSION_1_0, "DIS PDU version 1.0 (May 92)" },
+ { DIS_VERSION_IEEE_1278_1993, "IEEE 1278-1993" },
+ { DIS_VERSION_2_0_3RD_DRAFT, "DIS PDU version 2.0 - third draft (May 93)" },
+ { DIS_VERSION_2_0_4TH_DRAFT, "DIS PDU version 2.0 - fourth draft (revised) March 16, 1994" },
+ { DIS_VERSION_IEEE_1278_1_1995, "IEEE 1278.1-1995" },
+ { DIS_VERSION_IEEE_1278_1A_1998, "IEEE 1278.1A-1998" },
+ { 0, NULL }
+};
+
+const value_string DIS_PDU_ProtocolFamily_Strings[] =
+{
+ { DIS_PROTOCOLFAMILY_OTHER, "Other" },
+ { DIS_PROTOCOLFAMILY_ENTITY_INFORMATION_INTERACTION, "Entity information / interaction" },
+ { DIS_PROTOCOLFAMILY_WARFARE, "Warfare" },
+ { DIS_PROTOCOLFAMILY_LOGISTICS, "Logistics" },
+ { DIS_PROTOCOLFAMILY_RADIO_COMMUNICATIONS, "Radio communications" },
+ { DIS_PROTOCOLFAMILY_SIMULATION_MANAGEMENT, "Simulation management" },
+ { DIS_PROTOCOLFAMILY_DISTRIBUTED_EMISSION_REGENERATION, "Distributed emission regeneration" },
+ { DIS_PROTOCOLFAMILY_ENTITY_MANAGEMENT, "Entity management" },
+ { DIS_PROTOCOLFAMILY_MINEFIELD, "Minefield" },
+ { DIS_PROTOCOLFAMILY_SYNTHETIC_ENVIRONMENT, "Synthetic environment" },
+ { DIS_PROTOCOLFAMILY_SIMULATION_MANAGEMENT_WITH_RELIABILITY, "Simulation management with reliability" },
+ { DIS_PROTOCOLFAMILY_LIVE_ENTITY, "Live entity" },
+ { DIS_PROTOCOLFAMILY_NON_REAL_TIME, "Non-real time" },
+ { DIS_PROTOCOLFAMILY_EXPERIMENTAL_COMPUTER_GENERATED_FORCES, "Experimental - Computer Generated Forces" },
+ { DIS_PROTOCOLFAMILY_PERSISTENT_OBJECT, "Persistent object" },
+ { DIS_PROTOCOLFAMILY_EXPERIMENTAL, "Experimental" },
+ { 0, NULL }
+};
+
+const value_string DIS_PDU_Type_Strings[] =
+{
+ { DIS_PDUTYPE_OTHER, "Other" },
+ { DIS_PDUTYPE_ENTITY_STATE, "Entity State" },
+ { DIS_PDUTYPE_FIRE, "Fire" },
+ { DIS_PDUTYPE_DETONATION, "Detonation" },
+ { DIS_PDUTYPE_COLLISION, "Collision" },
+ { DIS_PDUTYPE_SERVICE_REQUEST, "Service Request" },
+ { DIS_PDUTYPE_RESUPPLY_OFFER, "Resupply Offer" },
+ { DIS_PDUTYPE_RESUPPLY_RECEIVED, "Resupply Received" },
+ { DIS_PDUTYPE_RESUPPLY_CANCEL, "Resupply Cancel" },
+ { DIS_PDUTYPE_REPAIR_COMPLETE, "Repair Complete" },
+ { DIS_PDUTYPE_REPAIR_RESPONSE, "Repair Response" },
+ { DIS_PDUTYPE_CREATE_ENTITY, "Create Entity" },
+ { DIS_PDUTYPE_REMOVE_ENTITY, "Remove Entity" },
+ { DIS_PDUTYPE_START_RESUME, "Start / Resume" },
+ { DIS_PDUTYPE_STOP_FREEZE, "Stop / Freeze" },
+ { DIS_PDUTYPE_ACKNOWLEDGE, "Acknowledge" },
+ { DIS_PDUTYPE_ACTION_REQUEST, "Action Request" },
+ { DIS_PDUTYPE_ACTION_RESPONSE, "Action Response" },
+ { DIS_PDUTYPE_DATA_QUERY, "Data Query" },
+ { DIS_PDUTYPE_SET_DATA, "Set Data" },
+ { DIS_PDUTYPE_DATA, "Data" },
+ { DIS_PDUTYPE_EVENT_REPORT, "Event Report" },
+ { DIS_PDUTYPE_COMMENT, "Comment" },
+ { DIS_PDUTYPE_ELECTROMAGNETIC_EMISSION, "Electromagnetic Emission" },
+ { DIS_PDUTYPE_DESIGNATOR, "Designator" },
+ { DIS_PDUTYPE_TRANSMITTER, "Transmitter" },
+ { DIS_PDUTYPE_SIGNAL, "Signal" },
+ { DIS_PDUTYPE_RECEIVER, "Receiver" },
+ { DIS_PDUTYPE_IFF_ATC_NAVAIDS, "IFF / ATC / NAVAIDS" },
+ { DIS_PDUTYPE_UNDERWATER_ACOUSTIC, "Underwater Acoustic" },
+ { DIS_PDUTYPE_SUPPLEMENTAL_EMISSION_ENTITY_STATE, "Supplemental Emission Entity State" },
+ { DIS_PDUTYPE_INTERCOM_SIGNAL, "Intercom Signal" },
+ { DIS_PDUTYPE_INTERCOM_CONTROL, "Intercom Control" },
+ { DIS_PDUTYPE_AGGREGATE_STATE, "Aggregate State" },
+ { DIS_PDUTYPE_IS_GROUP_OF, "IsGroupOf" },
+ { DIS_PDUTYPE_TRANSFER_CONTROL, "Transfer Control" },
+ { DIS_PDUTYPE_IS_PART_OF, "IsPartOf" },
+ { DIS_PDUTYPE_MINEFIELD_STATE, "Minefield State" },
+ { DIS_PDUTYPE_MINEFIELD_QUERY, "Minefield Query" },
+ { DIS_PDUTYPE_MINEFIELD_DATA, "Minefield Data" },
+ { DIS_PDUTYPE_MINEFIELD_RESPONSE_NAK, "Minefield Response NAK" },
+ { DIS_PDUTYPE_ENVIRONMENTAL_PROCESS, "Environmental Process" },
+ { DIS_PDUTYPE_GRIDDED_DATA, "Gridded Data" },
+ { DIS_PDUTYPE_POINT_OBJECT_STATE, "Point Object State" },
+ { DIS_PDUTYPE_LINEAR_OBJECT_STATE, "Linear Object State" },
+ { DIS_PDUTYPE_AREAL_OBJECT_STATE, "Areal Object State" },
+ { DIS_PDUTYPE_TSPI, "TSPI" },
+ { DIS_PDUTYPE_APPEARANCE, "Appearance" },
+ { DIS_PDUTYPE_ARTICULATED_PARTS, "Articulated Parts" },
+ { DIS_PDUTYPE_LE_FIRE, "LE Fire" },
+ { DIS_PDUTYPE_LE_DETONATION, "LE Detonation" },
+ { DIS_PDUTYPE_CREATE_ENTITY_R, "Create Entity-R" },
+ { DIS_PDUTYPE_REMOVE_ENTITY_R, "Remove Entity-R" },
+ { DIS_PDUTYPE_START_RESUME_R, "Start / Resume-R" },
+ { DIS_PDUTYPE_STOP_FREEZE_R, "Stop / Freeze-R" },
+ { DIS_PDUTYPE_ACKNOWLEDGE_R, "Acknowledge-R" },
+ { DIS_PDUTYPE_ACTION_REQUEST_R, "Action Request-R" },
+ { DIS_PDUTYPE_ACTION_RESPONSE_R, "Action Response-R" },
+ { DIS_PDUTYPE_DATA_QUERY_R, "Data Query-R" },
+ { DIS_PDUTYPE_SET_DATA_R, "Set Data-R" },
+ { DIS_PDUTYPE_DATA_R, "Data-R" },
+ { DIS_PDUTYPE_EVENT_REPORT_R, "Event Report-R" },
+ { DIS_PDUTYPE_COMMENT_R, "Comment-R" },
+ { DIS_PDUTYPE_RECORD_R, "Record-R" },
+ { DIS_PDUTYPE_SET_RECORD_R, "Set Record-R" },
+ { DIS_PDUTYPE_RECORD_QUERY_R, "Record Query-R" },
+ { DIS_PDUTYPE_COLLISION_ELASTIC, "Collision Elastic" },
+ { DIS_PDUTYPE_ENTITY_STATE_UPDATE, "Entity State Update" },
+ { DIS_PDUTYPE_ANNOUNCE_OBJECT, "Announce Object" },
+ { DIS_PDUTYPE_DELETE_OBJECT, "Delete Object" },
+ { DIS_PDUTYPE_DESCRIBE_APPLICATION, "Describe Application" },
+ { DIS_PDUTYPE_DESCRIBE_EVENT, "Describe Event" },
+ { DIS_PDUTYPE_DESCRIBE_OBJECT, "Describe Object" },
+ { DIS_PDUTYPE_REQUEST_EVENT, "Request Event" },
+ { DIS_PDUTYPE_REQUEST_OBJECT, "Request Object" },
+ { 0, NULL }
+};
+
+const value_string DIS_PDU_EntityKind_Strings[] =
+{
+ { DIS_ENTITYKIND_OTHER, "Other" },
+ { DIS_ENTITYKIND_PLATFORM, "Platform" },
+ { DIS_ENTITYKIND_MUNITION, "Munition" },
+ { DIS_ENTITYKIND_LIFE_FORM, "Life form" },
+ { DIS_ENTITYKIND_ENVIRONMENTAL, "Environmental" },
+ { DIS_ENTITYKIND_CULTURAL_FEATURE, "Cultural feature" },
+ { DIS_ENTITYKIND_SUPPLY, "Supply" },
+ { DIS_ENTITYKIND_RADIO, "Radio" },
+ { DIS_ENTITYKIND_EXPENDABLE, "Expendable" },
+ { DIS_ENTITYKIND_SENSOR_EMITTER, "Sensor/Emitter" },
+ { 0, NULL }
+};
+
+const value_string DIS_PDU_Domain_Strings[] =
+{
+ { DIS_DOMAIN_OTHER, "Other" },
+ { DIS_DOMAIN_LAND, "Land" },
+ { DIS_DOMAIN_AIR, "Air" },
+ { DIS_DOMAIN_SURFACE, "Surface" },
+ { DIS_DOMAIN_SUBSURFACE, "Sursurface" },
+ { DIS_DOMAIN_SPACE, "Space" },
+ { 0, NULL }
+};
+
+const value_string DIS_PDU_Category_LandPlatform_Strings[] =
+{
+ { DIS_CATEGORY_LANDPLATFORM_OTHER, "Other" },
+ { DIS_CATEGORY_LANDPLATFORM_TANK, "Tank" },
+ { DIS_CATEGORY_LANDPLATFORM_ARMORED_FIGHTING_VEHICLE, "Armored fighting vehicle" },
+ { DIS_CATEGORY_LANDPLATFORM_ARMORED_UTILITY_VEHICLE, "Armored utility vehicle" },
+ { DIS_CATEGORY_LANDPLATFORM_SELF_PROPELLED_ARTILLERY, "Self-propelled artillery" },
+ { DIS_CATEGORY_LANDPLATFORM_TOWED_ARTILLERY, "Towed artillery" },
+ { DIS_CATEGORY_LANDPLATFORM_SMALL_WHEELED_UTILITY_VEHICLE, "Small wheeled utility vehicle" },
+ { DIS_CATEGORY_LANDPLATFORM_LARGE_WHEELED_UTILITY_VEHICLE, "Large wheeled utility vehicle" },
+ { DIS_CATEGORY_LANDPLATFORM_SMALL_TRACKED_UTILITY_VEHICLE, "Small tracked utility vehicle" },
+ { DIS_CATEGORY_LANDPLATFORM_LARGE_TRACKED_UTILITY_VEHICLE, "Large tracked utility vehicle" },
+ { DIS_CATEGORY_LANDPLATFORM_MORTAR, "Mortar" },
+ { DIS_CATEGORY_LANDPLATFORM_MINE_PLOW, "Mine plow" },
+ { DIS_CATEGORY_LANDPLATFORM_MINE_RAKE, "Mine rake" },
+ { DIS_CATEGORY_LANDPLATFORM_MINE_ROLLER, "Mine roller" },
+ { DIS_CATEGORY_LANDPLATFORM_CARGO_TRAILER, "Cargo trailer" },
+ { DIS_CATEGORY_LANDPLATFORM_FUEL_TRAILER, "Fuel trailer" },
+ { DIS_CATEGORY_LANDPLATFORM_GENERATOR_TRAILER, "Generator trailer" },
+ { DIS_CATEGORY_LANDPLATFORM_WATER_TRAILER, "Water trailer" },
+ { DIS_CATEGORY_LANDPLATFORM_ENGINEER_EQUIPMENT, "Engineer equipment" },
+ { DIS_CATEGORY_LANDPLATFORM_HEAVY_EQUIPMENT_TRANSPORT_TRAILER, "Heavy equipment transport trailer" },
+ { DIS_CATEGORY_LANDPLATFORM_MAINTENANCE_EQUIPMENT_TRAILER, "Maintenance equipment trailer" },
+ { DIS_CATEGORY_LANDPLATFORM_LIMBER, "Limber" },
+ { DIS_CATEGORY_LANDPLATFORM_CHEMICAL_DECONTAMINATION_TRAILER, "Chemical decontamination trailer" },
+ { DIS_CATEGORY_LANDPLATFORM_WARNING_SYSTEM, "Warning system" },
+ { DIS_CATEGORY_LANDPLATFORM_TRAIN_ENGINE, "Train engine" },
+ { DIS_CATEGORY_LANDPLATFORM_TRAIN_CAR, "Train car" },
+ { DIS_CATEGORY_LANDPLATFORM_TRAIN_CABOOSE, "Train caboose" },
+ { DIS_CATEGORY_LANDPLATFORM_CIVILIAN_VEHICLE, "Civilian vehicle" },
+ { DIS_CATEGORY_LANDPLATFORM_AIR_DEFENSE_MISSILE_DEFENSE_UNIT_EQUIPMENT, "Air defense / missile defense unit equipment" },
+ { DIS_CATEGORY_LANDPLATFORM_C3I_SYSTEM, "C3I system" },
+ { DIS_CATEGORY_LANDPLATFORM_OPERATIONS_FACILITY, "Operations facility" },
+ { DIS_CATEGORY_LANDPLATFORM_INTELLIGENCE_FACILITY, "Intelligence facility" },
+ { DIS_CATEGORY_LANDPLATFORM_SURVEILLANCE_FACILITY, "Surveillance facility" },
+ { DIS_CATEGORY_LANDPLATFORM_COMMUNICATIONS_FACILITY, "Communications facility" },
+ { DIS_CATEGORY_LANDPLATFORM_COMMAND_FACILITY, "Command facility" },
+ { DIS_CATEGORY_LANDPLATFORM_C4I_FACILITY, "C4I facility" },
+ { DIS_CATEGORY_LANDPLATFORM_CONTROL_FACILITY, "Control facility" },
+ { DIS_CATEGORY_LANDPLATFORM_FIRE_CONTROL_FACILITY, "Fire control facility" },
+ { DIS_CATEGORY_LANDPLATFORM_MISSILE_DEFENSE_FACILITY, "Missile defense facility" },
+ { DIS_CATEGORY_LANDPLATFORM_FIELD_COMMAND_POST, "Field command post" },
+ { DIS_CATEGORY_LANDPLATFORM_OBSERVATION_POST, "Field observation post" },
+ { 0, NULL }
+};
+
+const value_string DIS_PDU_Category_AirPlatform_Strings[] =
+{
+ { DIS_CATEGORY_AIRPLATFORM_OTHER, "Other" },
+ { DIS_CATEGORY_AIRPLATFORM_FIGHTER_AIR_DEFENSE, "Fighter / air defense" },
+ { DIS_CATEGORY_AIRPLATFORM_ATTACK_STRIKE, "Attack / strike" },
+ { DIS_CATEGORY_AIRPLATFORM_BOMBER, "Bomber" },
+ { DIS_CATEGORY_AIRPLATFORM_CARGO_TANKER, "Cargo tanker" },
+ { DIS_CATEGORY_AIRPLATFORM_ASW_PATROL_OBSERVATION, "ASW / patrol / observation" },
+ { DIS_CATEGORY_AIRPLATFORM_ELECTRONIC_WARFARE, "Electronic warfare" },
+ { DIS_CATEGORY_AIRPLATFORM_RECONAISSANCE, "Reconaissance" },
+ { DIS_CATEGORY_AIRPLATFORM_SURVEILLANCE_C2, "Surveillance / C2" },
+ { DIS_CATEGORY_AIRPLATFORM_ATTACK_HELICOPTER, "Attack helicopter" },
+ { DIS_CATEGORY_AIRPLATFORM_UTILITY_HELICOPTER, "Utility helicopter" },
+ { DIS_CATEGORY_AIRPLATFORM_ANTISUB_WARFARE_PATROL_HELICOPTER, "Antisubmarine warfare / patrol helicopter" },
+ { DIS_CATEGORY_AIRPLATFORM_CARGO_HELICOPTER, "Cargo helicopter" },
+ { DIS_CATEGORY_AIRPLATFORM_OBSERVATION_HELICOPTER, "Observation helicopter" },
+ { DIS_CATEGORY_AIRPLATFORM_SPECIAL_OPERATIONS_HELICOPTER, "Special operations helicopter" },
+ { DIS_CATEGORY_AIRPLATFORM_TRAINER, "Trainer" },
+ { DIS_CATEGORY_AIRPLATFORM_UNMANNED, "Unmanned" },
+ { DIS_CATEGORY_AIRPLATFORM_NON_COMBATANT_COMMERCIAL_AIRCRAFT, "Non-combatant commercial aircraft" },
+ { 0, NULL }
+};
+
+const value_string DIS_PDU_Category_SurfacePlatform_Strings[] =
+{
+ { DIS_CATEGORY_SURFACEPLATFORM_OTHER, "Other" },
+ { 0, NULL}
+};
+
+const value_string DIS_PDU_Category_SubsurfacePlatform_Strings[] =
+{
+ { DIS_CATEGORY_SUBSURFACEPLATFORM_OTHER, "Other" },
+ { 0, NULL }
+};
+
+const value_string DIS_PDU_Category_SpacePlatform_Strings[] =
+{
+ { DIS_CATEGORY_SPACEPLATFORM_OTHER, "Other" },
+ { 0, NULL }
+};
+
+const value_string DIS_PDU_DetonationResult_Strings[] =
+{
+ { DIS_DETONATION_RESULT_OTHER, "Other" },
+ { DIS_DETONATION_RESULT_ENTITY_IMPACT, "Entity impact" },
+ { DIS_DETONATION_RESULT_ENTITY_PROXIMATE_DETONATION, "Entity proximate detonation" },
+ { DIS_DETONATION_RESULT_GROUND_IMPACT, "Ground impact" },
+ { DIS_DETONATION_RESULT_GROUND_PROXIMATE_DETONATION, "Ground proximate detonation" },
+ { DIS_DETONATION_RESULT_DETONATION, "Detonation" },
+ { DIS_DETONATION_RESULT_NONE_DUD, "None or no detonation (dud)" },
+ { DIS_DETONATION_RESULT_HE_HIT_SMALL, "HE hit, small" },
+ { DIS_DETONATION_RESULT_HE_HIT_MEDIUM, "HE hit, medium" },
+ { DIS_DETONATION_RESULT_HE_HIT_LARGE, "HE hit, large" },
+ { DIS_DETONATION_RESULT_ARMOR_PIERCING_HIT, "Armor-piercing hit" },
+ { DIS_DETONATION_RESULT_DIRT_BLAST_SMALL, "Dirt blast, small" },
+ { DIS_DETONATION_RESULT_DIRT_BLAST_MEDIUM, "Dirt blast, medium" },
+ { DIS_DETONATION_RESULT_DIRT_BLAST_LARGE, "Dirt blast, large" },
+ { DIS_DETONATION_RESULT_WATER_BLAST_SMALL, "Water blast, small" },
+ { DIS_DETONATION_RESULT_WATER_BLAST_MEDIUM, "Water blast, medium" },
+ { DIS_DETONATION_RESULT_WATER_BLAST_LARGE, "Water blast, large" },
+ { DIS_DETONATION_RESULT_AIR_HIT, "Air hit" },
+ { DIS_DETONATION_RESULT_BUILDING_HIT_SMALL, "Building hit, small" },
+ { DIS_DETONATION_RESULT_BUILDING_HIT_MEDIUM, "Building hit, medium" },
+ { DIS_DETONATION_RESULT_BUILDING_HIT_LARGE, "Building hit, large" },
+ { DIS_DETONATION_RESULT_MINE_CLEARING_LINE_CHARGE, "Mine-clearing line charge" },
+ { DIS_DETONATION_RESULT_ENVIRONMENT_OBJECT_IMPACT, "Environment object impact" },
+ { DIS_DETONATION_RESULT_ENVIRONMENT_OBJECT_PROXIMATE_DETONATION, "Environment object proximate detonation" },
+ { DIS_DETONATION_RESULT_WATER_IMPACT, "Water impact" },
+ { DIS_DETONATION_RESULT_AIR_BURST, "Air burst" },
+ { DIS_DETONATION_RESULT_KILL_WITH_FRAGMENT_TYPE_1, "Kill with fragment type 1" },
+ { DIS_DETONATION_RESULT_KILL_WITH_FRAGMENT_TYPE_2, "Kill with fragment type 2" },
+ { DIS_DETONATION_RESULT_KILL_WITH_FRAGMENT_TYPE_3, "Kill with fragment type 3" },
+ { DIS_DETONATION_RESULT_KILL_WITH_FRAGMENT_TYPE_1_AFTER_FOF, "Kill with fragment type 1 after fly-out failure" },
+ { DIS_DETONATION_RESULT_KILL_WITH_FRAGMENT_TYPE_2_AFTER_FOF, "Kill with fragment type 2 after fly-out failure" },
+ { DIS_DETONATION_RESULT_MISS_DUE_TO_FOF, "Miss due to fly-out failure" },
+ { DIS_DETONATION_RESULT_MISS_DUE_TO_ENDGAME_FAILURE, "Miss due to end-game failure" },
+ { DIS_DETONATION_RESULT_MISS_DUE_TO_FOF_AND_ENDGAME_FAILURE, "Miss due to fly-out and end-game failure" },
+ { 0, NULL }
+};
diff --git a/epan/dissectors/packet-dis-enums.h b/epan/dissectors/packet-dis-enums.h
new file mode 100644
index 0000000000..df13af5739
--- /dev/null
+++ b/epan/dissectors/packet-dis-enums.h
@@ -0,0 +1,306 @@
+/* packet-dis-enums.h
+ * Enumerated values and string array declarations for DIS enum parsing.
+ * 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.
+ */
+
+#ifndef __PACKET_DIS_ENUMS_H__
+#define __PACKET_DIS_ENUMS_H__
+
+#include <epan/value_string.h>
+
+typedef enum
+{
+ DIS_VERSION_OTHER = 0,
+ DIS_VERSION_1_0 = 1,
+ DIS_VERSION_IEEE_1278_1993 = 2,
+ DIS_VERSION_2_0_3RD_DRAFT = 3,
+ DIS_VERSION_2_0_4TH_DRAFT = 4,
+ DIS_VERSION_IEEE_1278_1_1995 = 5,
+ DIS_VERSION_IEEE_1278_1A_1998 = 6
+} DIS_PDU_ProtocolVersion;
+
+extern const value_string DIS_PDU_ProtocolVersion_Strings[];
+
+typedef enum
+{
+ DIS_PROTOCOLFAMILY_OTHER = 0,
+ DIS_PROTOCOLFAMILY_ENTITY_INFORMATION_INTERACTION = 1,
+ DIS_PROTOCOLFAMILY_WARFARE = 2,
+ DIS_PROTOCOLFAMILY_LOGISTICS = 3,
+ DIS_PROTOCOLFAMILY_RADIO_COMMUNICATIONS = 4,
+ DIS_PROTOCOLFAMILY_SIMULATION_MANAGEMENT = 5,
+ DIS_PROTOCOLFAMILY_DISTRIBUTED_EMISSION_REGENERATION = 6,
+ DIS_PROTOCOLFAMILY_ENTITY_MANAGEMENT = 7,
+ DIS_PROTOCOLFAMILY_MINEFIELD = 8,
+ DIS_PROTOCOLFAMILY_SYNTHETIC_ENVIRONMENT = 9,
+ DIS_PROTOCOLFAMILY_SIMULATION_MANAGEMENT_WITH_RELIABILITY = 10,
+ DIS_PROTOCOLFAMILY_LIVE_ENTITY = 11,
+ DIS_PROTOCOLFAMILY_NON_REAL_TIME = 12,
+ DIS_PROTOCOLFAMILY_EXPERIMENTAL_COMPUTER_GENERATED_FORCES = 129,
+ DIS_PROTOCOLFAMILY_PERSISTENT_OBJECT = 140,
+ DIS_PROTOCOLFAMILY_EXPERIMENTAL = 150
+} DIS_PDU_ProtocolFamily;
+
+extern const value_string DIS_PDU_ProtocolFamily_Strings[];
+
+typedef enum
+{
+ DIS_PDUTYPE_OTHER = 0,
+ DIS_PDUTYPE_ENTITY_STATE = 1,
+ DIS_PDUTYPE_FIRE = 2,
+ DIS_PDUTYPE_DETONATION = 3,
+ DIS_PDUTYPE_COLLISION = 4,
+ DIS_PDUTYPE_SERVICE_REQUEST = 5,
+ DIS_PDUTYPE_RESUPPLY_OFFER = 6,
+ DIS_PDUTYPE_RESUPPLY_RECEIVED = 7,
+ DIS_PDUTYPE_RESUPPLY_CANCEL = 8,
+ DIS_PDUTYPE_REPAIR_COMPLETE = 9,
+ DIS_PDUTYPE_REPAIR_RESPONSE = 10,
+ DIS_PDUTYPE_CREATE_ENTITY = 11,
+ DIS_PDUTYPE_REMOVE_ENTITY = 12,
+ DIS_PDUTYPE_START_RESUME = 13,
+ DIS_PDUTYPE_STOP_FREEZE = 14,
+ DIS_PDUTYPE_ACKNOWLEDGE = 15,
+ DIS_PDUTYPE_ACTION_REQUEST = 16,
+ DIS_PDUTYPE_ACTION_RESPONSE = 17,
+ DIS_PDUTYPE_DATA_QUERY = 18,
+ DIS_PDUTYPE_SET_DATA = 19,
+ DIS_PDUTYPE_DATA = 20,
+ DIS_PDUTYPE_EVENT_REPORT = 21,
+ DIS_PDUTYPE_COMMENT = 22,
+ DIS_PDUTYPE_ELECTROMAGNETIC_EMISSION = 23,
+ DIS_PDUTYPE_DESIGNATOR = 24,
+ DIS_PDUTYPE_TRANSMITTER = 25,
+ DIS_PDUTYPE_SIGNAL = 26,
+ DIS_PDUTYPE_RECEIVER = 27,
+ DIS_PDUTYPE_IFF_ATC_NAVAIDS = 28,
+ DIS_PDUTYPE_UNDERWATER_ACOUSTIC = 29,
+ DIS_PDUTYPE_SUPPLEMENTAL_EMISSION_ENTITY_STATE = 30,
+ DIS_PDUTYPE_INTERCOM_SIGNAL = 31,
+ DIS_PDUTYPE_INTERCOM_CONTROL = 32,
+ DIS_PDUTYPE_AGGREGATE_STATE = 33,
+ DIS_PDUTYPE_IS_GROUP_OF = 34,
+ DIS_PDUTYPE_TRANSFER_CONTROL = 35,
+ DIS_PDUTYPE_IS_PART_OF = 36,
+ DIS_PDUTYPE_MINEFIELD_STATE = 37,
+ DIS_PDUTYPE_MINEFIELD_QUERY = 38,
+ DIS_PDUTYPE_MINEFIELD_DATA = 39,
+ DIS_PDUTYPE_MINEFIELD_RESPONSE_NAK = 40,
+ DIS_PDUTYPE_ENVIRONMENTAL_PROCESS = 41,
+ DIS_PDUTYPE_GRIDDED_DATA = 42,
+ DIS_PDUTYPE_POINT_OBJECT_STATE = 43,
+ DIS_PDUTYPE_LINEAR_OBJECT_STATE = 44,
+ DIS_PDUTYPE_AREAL_OBJECT_STATE = 45,
+ DIS_PDUTYPE_TSPI = 46,
+ DIS_PDUTYPE_APPEARANCE = 47,
+ DIS_PDUTYPE_ARTICULATED_PARTS = 48,
+ DIS_PDUTYPE_LE_FIRE = 49,
+ DIS_PDUTYPE_LE_DETONATION = 50,
+ DIS_PDUTYPE_CREATE_ENTITY_R = 51,
+ DIS_PDUTYPE_REMOVE_ENTITY_R = 52,
+ DIS_PDUTYPE_START_RESUME_R = 53,
+ DIS_PDUTYPE_STOP_FREEZE_R = 54,
+ DIS_PDUTYPE_ACKNOWLEDGE_R = 55,
+ DIS_PDUTYPE_ACTION_REQUEST_R = 56,
+ DIS_PDUTYPE_ACTION_RESPONSE_R = 57,
+ DIS_PDUTYPE_DATA_QUERY_R = 58,
+ DIS_PDUTYPE_SET_DATA_R = 59,
+ DIS_PDUTYPE_DATA_R = 60,
+ DIS_PDUTYPE_EVENT_REPORT_R = 61,
+ DIS_PDUTYPE_COMMENT_R = 62,
+ DIS_PDUTYPE_RECORD_R = 63,
+ DIS_PDUTYPE_SET_RECORD_R = 64,
+ DIS_PDUTYPE_RECORD_QUERY_R = 65,
+ DIS_PDUTYPE_COLLISION_ELASTIC = 66,
+ DIS_PDUTYPE_ENTITY_STATE_UPDATE = 67,
+ DIS_PDUTYPE_ANNOUNCE_OBJECT = 129,
+ DIS_PDUTYPE_DELETE_OBJECT = 130,
+ DIS_PDUTYPE_DESCRIBE_APPLICATION = 131,
+ DIS_PDUTYPE_DESCRIBE_EVENT = 132,
+ DIS_PDUTYPE_DESCRIBE_OBJECT = 133,
+ DIS_PDUTYPE_REQUEST_EVENT = 134,
+ DIS_PDUTYPE_REQUEST_OBJECT = 135
+} DIS_PDU_Type;
+
+extern const value_string DIS_PDU_Type_Strings[];
+
+typedef enum
+{
+ DIS_ENTITYKIND_OTHER = 0,
+ DIS_ENTITYKIND_PLATFORM = 1,
+ DIS_ENTITYKIND_MUNITION = 2,
+ DIS_ENTITYKIND_LIFE_FORM = 3,
+ DIS_ENTITYKIND_ENVIRONMENTAL = 4,
+ DIS_ENTITYKIND_CULTURAL_FEATURE = 5,
+ DIS_ENTITYKIND_SUPPLY = 6,
+ DIS_ENTITYKIND_RADIO = 7,
+ DIS_ENTITYKIND_EXPENDABLE = 8,
+ DIS_ENTITYKIND_SENSOR_EMITTER = 9
+} DIS_PDU_EntityKind;
+
+extern const value_string DIS_PDU_EntityKind_Strings[];
+
+typedef enum
+{
+ DIS_DOMAIN_OTHER = 0,
+ DIS_DOMAIN_LAND = 1,
+ DIS_DOMAIN_AIR = 2,
+ DIS_DOMAIN_SURFACE = 3,
+ DIS_DOMAIN_SUBSURFACE = 4,
+ DIS_DOMAIN_SPACE = 5
+} DIS_PDU_Domain;
+
+extern const value_string DIS_PDU_Domain_Strings[];
+
+typedef enum
+{
+ DIS_CATEGORY_LANDPLATFORM_OTHER = 0,
+ DIS_CATEGORY_LANDPLATFORM_TANK = 1,
+ DIS_CATEGORY_LANDPLATFORM_ARMORED_FIGHTING_VEHICLE = 2,
+ DIS_CATEGORY_LANDPLATFORM_ARMORED_UTILITY_VEHICLE = 3,
+ DIS_CATEGORY_LANDPLATFORM_SELF_PROPELLED_ARTILLERY = 4,
+ DIS_CATEGORY_LANDPLATFORM_TOWED_ARTILLERY = 5,
+ DIS_CATEGORY_LANDPLATFORM_SMALL_WHEELED_UTILITY_VEHICLE = 6,
+ DIS_CATEGORY_LANDPLATFORM_LARGE_WHEELED_UTILITY_VEHICLE = 7,
+ DIS_CATEGORY_LANDPLATFORM_SMALL_TRACKED_UTILITY_VEHICLE = 8,
+ DIS_CATEGORY_LANDPLATFORM_LARGE_TRACKED_UTILITY_VEHICLE = 9,
+ DIS_CATEGORY_LANDPLATFORM_MORTAR = 10,
+ DIS_CATEGORY_LANDPLATFORM_MINE_PLOW = 11,
+ DIS_CATEGORY_LANDPLATFORM_MINE_RAKE = 12,
+ DIS_CATEGORY_LANDPLATFORM_MINE_ROLLER = 13,
+ DIS_CATEGORY_LANDPLATFORM_CARGO_TRAILER = 14,
+ DIS_CATEGORY_LANDPLATFORM_FUEL_TRAILER = 15,
+ DIS_CATEGORY_LANDPLATFORM_GENERATOR_TRAILER = 16,
+ DIS_CATEGORY_LANDPLATFORM_WATER_TRAILER = 17,
+ DIS_CATEGORY_LANDPLATFORM_ENGINEER_EQUIPMENT = 18,
+ DIS_CATEGORY_LANDPLATFORM_HEAVY_EQUIPMENT_TRANSPORT_TRAILER = 19,
+ DIS_CATEGORY_LANDPLATFORM_MAINTENANCE_EQUIPMENT_TRAILER = 20,
+ DIS_CATEGORY_LANDPLATFORM_LIMBER = 21,
+ DIS_CATEGORY_LANDPLATFORM_CHEMICAL_DECONTAMINATION_TRAILER = 22,
+ DIS_CATEGORY_LANDPLATFORM_WARNING_SYSTEM = 23,
+ DIS_CATEGORY_LANDPLATFORM_TRAIN_ENGINE = 24,
+ DIS_CATEGORY_LANDPLATFORM_TRAIN_CAR = 25,
+ DIS_CATEGORY_LANDPLATFORM_TRAIN_CABOOSE = 26,
+ DIS_CATEGORY_LANDPLATFORM_CIVILIAN_VEHICLE = 27,
+ DIS_CATEGORY_LANDPLATFORM_AIR_DEFENSE_MISSILE_DEFENSE_UNIT_EQUIPMENT = 28,
+ DIS_CATEGORY_LANDPLATFORM_C3I_SYSTEM = 29,
+ DIS_CATEGORY_LANDPLATFORM_OPERATIONS_FACILITY = 30,
+ DIS_CATEGORY_LANDPLATFORM_INTELLIGENCE_FACILITY = 31,
+ DIS_CATEGORY_LANDPLATFORM_SURVEILLANCE_FACILITY = 32,
+ DIS_CATEGORY_LANDPLATFORM_COMMUNICATIONS_FACILITY = 33,
+ DIS_CATEGORY_LANDPLATFORM_COMMAND_FACILITY = 34,
+ DIS_CATEGORY_LANDPLATFORM_C4I_FACILITY = 35,
+ DIS_CATEGORY_LANDPLATFORM_CONTROL_FACILITY = 36,
+ DIS_CATEGORY_LANDPLATFORM_FIRE_CONTROL_FACILITY = 37,
+ DIS_CATEGORY_LANDPLATFORM_MISSILE_DEFENSE_FACILITY = 38,
+ DIS_CATEGORY_LANDPLATFORM_FIELD_COMMAND_POST = 39,
+ DIS_CATEGORY_LANDPLATFORM_OBSERVATION_POST = 40
+} DIS_PDU_Category_LandPlatform;
+
+extern const value_string DIS_PDU_Category_LandPlatform_Strings[];
+
+typedef enum
+{
+ DIS_CATEGORY_AIRPLATFORM_OTHER = 0,
+ DIS_CATEGORY_AIRPLATFORM_FIGHTER_AIR_DEFENSE = 1,
+ DIS_CATEGORY_AIRPLATFORM_ATTACK_STRIKE = 2,
+ DIS_CATEGORY_AIRPLATFORM_BOMBER = 3,
+ DIS_CATEGORY_AIRPLATFORM_CARGO_TANKER = 4,
+ DIS_CATEGORY_AIRPLATFORM_ASW_PATROL_OBSERVATION = 5,
+ DIS_CATEGORY_AIRPLATFORM_ELECTRONIC_WARFARE = 6,
+ DIS_CATEGORY_AIRPLATFORM_RECONAISSANCE = 7,
+ DIS_CATEGORY_AIRPLATFORM_SURVEILLANCE_C2 = 8,
+ DIS_CATEGORY_AIRPLATFORM_ATTACK_HELICOPTER = 20,
+ DIS_CATEGORY_AIRPLATFORM_UTILITY_HELICOPTER = 21,
+ DIS_CATEGORY_AIRPLATFORM_ANTISUB_WARFARE_PATROL_HELICOPTER = 22,
+ DIS_CATEGORY_AIRPLATFORM_CARGO_HELICOPTER = 23,
+ DIS_CATEGORY_AIRPLATFORM_OBSERVATION_HELICOPTER = 24,
+ DIS_CATEGORY_AIRPLATFORM_SPECIAL_OPERATIONS_HELICOPTER = 25,
+ DIS_CATEGORY_AIRPLATFORM_TRAINER = 40,
+ DIS_CATEGORY_AIRPLATFORM_UNMANNED = 50,
+ DIS_CATEGORY_AIRPLATFORM_NON_COMBATANT_COMMERCIAL_AIRCRAFT = 57
+} DIS_PDU_Category_AirPlatform;
+
+extern const value_string DIS_PDU_Category_AirPlatform_Strings[];
+
+typedef enum
+{
+ DIS_CATEGORY_SURFACEPLATFORM_OTHER = 0,
+} DIS_PDU_Category_SurfacePlatform;
+
+extern const value_string DIS_PDU_Category_SurfacePlatform_Strings[];
+
+typedef enum
+{
+ DIS_CATEGORY_SUBSURFACEPLATFORM_OTHER = 0
+} DIS_PDU_Category_SubsurfacePlatform;
+
+extern const value_string DIS_PDU_Category_SubsurfacePlatform_Strings[];
+
+typedef enum
+{
+ DIS_CATEGORY_SPACEPLATFORM_OTHER = 0
+} DIS_PDU_Category_SpacePlatform;
+
+extern const value_string DIS_PDU_Category_SpacePlatform_Strings[];
+
+typedef enum
+{
+ DIS_DETONATION_RESULT_OTHER = 0,
+ DIS_DETONATION_RESULT_ENTITY_IMPACT = 1,
+ DIS_DETONATION_RESULT_ENTITY_PROXIMATE_DETONATION = 2,
+ DIS_DETONATION_RESULT_GROUND_IMPACT = 3,
+ DIS_DETONATION_RESULT_GROUND_PROXIMATE_DETONATION = 4,
+ DIS_DETONATION_RESULT_DETONATION = 5,
+ DIS_DETONATION_RESULT_NONE_DUD = 6,
+ DIS_DETONATION_RESULT_HE_HIT_SMALL = 7,
+ DIS_DETONATION_RESULT_HE_HIT_MEDIUM = 8,
+ DIS_DETONATION_RESULT_HE_HIT_LARGE = 9,
+ DIS_DETONATION_RESULT_ARMOR_PIERCING_HIT = 10,
+ DIS_DETONATION_RESULT_DIRT_BLAST_SMALL = 11,
+ DIS_DETONATION_RESULT_DIRT_BLAST_MEDIUM = 12,
+ DIS_DETONATION_RESULT_DIRT_BLAST_LARGE = 13,
+ DIS_DETONATION_RESULT_WATER_BLAST_SMALL = 14,
+ DIS_DETONATION_RESULT_WATER_BLAST_MEDIUM = 15,
+ DIS_DETONATION_RESULT_WATER_BLAST_LARGE = 16,
+ DIS_DETONATION_RESULT_AIR_HIT = 17,
+ DIS_DETONATION_RESULT_BUILDING_HIT_SMALL = 18,
+ DIS_DETONATION_RESULT_BUILDING_HIT_MEDIUM = 19,
+ DIS_DETONATION_RESULT_BUILDING_HIT_LARGE = 20,
+ DIS_DETONATION_RESULT_MINE_CLEARING_LINE_CHARGE = 21,
+ DIS_DETONATION_RESULT_ENVIRONMENT_OBJECT_IMPACT = 22,
+ DIS_DETONATION_RESULT_ENVIRONMENT_OBJECT_PROXIMATE_DETONATION = 23,
+ DIS_DETONATION_RESULT_WATER_IMPACT = 24,
+ DIS_DETONATION_RESULT_AIR_BURST = 25,
+ DIS_DETONATION_RESULT_KILL_WITH_FRAGMENT_TYPE_1 = 26,
+ DIS_DETONATION_RESULT_KILL_WITH_FRAGMENT_TYPE_2 = 27,
+ DIS_DETONATION_RESULT_KILL_WITH_FRAGMENT_TYPE_3 = 28,
+ DIS_DETONATION_RESULT_KILL_WITH_FRAGMENT_TYPE_1_AFTER_FOF = 29,
+ DIS_DETONATION_RESULT_KILL_WITH_FRAGMENT_TYPE_2_AFTER_FOF = 30,
+ DIS_DETONATION_RESULT_MISS_DUE_TO_FOF = 31,
+ DIS_DETONATION_RESULT_MISS_DUE_TO_ENDGAME_FAILURE = 32,
+ DIS_DETONATION_RESULT_MISS_DUE_TO_FOF_AND_ENDGAME_FAILURE = 33
+} DIS_PDU_DetonationResult;
+
+extern const value_string DIS_PDU_DetonationResult_Strings[];
+
+#endif /* packet-dis-enums.h */
diff --git a/epan/dissectors/packet-dis-fields.c b/epan/dissectors/packet-dis-fields.c
new file mode 100644
index 0000000000..52e34b7e3a
--- /dev/null
+++ b/epan/dissectors/packet-dis-fields.c
@@ -0,0 +1,503 @@
+/* packet-dis-fields.c
+ * Routines and definitions for DIS field parsing.
+ * 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <string.h>
+#include <epan/packet.h>
+#include "packet-dis-fields.h"
+#include "packet-dis-enums.h"
+
+guint32 pduType;
+guint32 entityKind;
+guint32 entityDomain;
+
+DIS_ParserNode DIS_FIELDS_PDU_HEADER[] =
+{
+ { DIS_FIELDTYPE_PROTOCOL_VERSION, "Protocol Version",0,0,0 },
+ { DIS_FIELDTYPE_UINT8, "Exercise ID",0,0,0 },
+ { DIS_FIELDTYPE_PDU_TYPE, "PDU Type",0,0,&pduType },
+ { DIS_FIELDTYPE_PROTOCOL_FAMILY, "Protocol Family",0,0,0 },
+ { DIS_FIELDTYPE_TIMESTAMP, "Timestamp",0,0,0 },
+ { DIS_FIELDTYPE_UINT16, "Length",0,0,0 },
+ { DIS_FIELDTYPE_PAD16, "Padding",0,0,0 },
+ { DIS_FIELDTYPE_END, NULL,0,0,0 }
+};
+
+DIS_ParserNode DIS_FIELDS_ENTITY_ID[] =
+{
+ { DIS_FIELDTYPE_UINT16, "Site",0,0,0 },
+ { DIS_FIELDTYPE_UINT16, "Application",0,0,0 },
+ { DIS_FIELDTYPE_UINT16, "Entity",0,0,0 },
+ { DIS_FIELDTYPE_END, NULL,0,0,0 }
+};
+
+DIS_ParserNode DIS_FIELDS_ENTITY_TYPE[] =
+{
+ { DIS_FIELDTYPE_ENTITY_KIND, "Entity Kind",0,0,&entityKind },
+ { DIS_FIELDTYPE_DOMAIN, "Domain",0,0,&entityDomain },
+ { DIS_FIELDTYPE_COUNTRY, "Country",0,0,0 },
+ { DIS_FIELDTYPE_CATEGORY, "Category",0,0,0 },
+ { DIS_FIELDTYPE_SUBCATEGORY, "Subcategory",0,0,0 },
+ { DIS_FIELDTYPE_SPECIFIC, "Specific",0,0,0 },
+ { DIS_FIELDTYPE_EXTRA, "Extra",0,0,0 },
+ { DIS_FIELDTYPE_END, NULL,0,0,0 }
+};
+
+DIS_ParserNode DIS_FIELDS_EVENT_ID[] =
+{
+ { DIS_FIELDTYPE_UINT16, "Site",0,0,0 },
+ { DIS_FIELDTYPE_UINT16, "Application",0,0,0 },
+ { DIS_FIELDTYPE_UINT16, "Event Number",0,0,0 },
+ { DIS_FIELDTYPE_END, NULL,0,0,0 }
+};
+
+DIS_ParserNode DIS_FIELDS_LINEAR_VELOCITY[] =
+{
+ { DIS_FIELDTYPE_FLOAT32, "X",0,0,0 },
+ { DIS_FIELDTYPE_FLOAT32, "Y",0,0,0 },
+ { DIS_FIELDTYPE_FLOAT32, "Z",0,0,0 },
+ { DIS_FIELDTYPE_END, NULL,0,0,0 }
+};
+
+DIS_ParserNode DIS_FIELDS_LOCATION_WORLD[] =
+{
+ { DIS_FIELDTYPE_FLOAT64, "X",0,0,0 },
+ { DIS_FIELDTYPE_FLOAT64, "Y",0,0,0 },
+ { DIS_FIELDTYPE_FLOAT64, "Z",0,0,0 },
+ { DIS_FIELDTYPE_END, NULL,0,0,0 }
+};
+
+DIS_ParserNode DIS_FIELDS_LOCATION_ENTITY[] =
+{
+ { DIS_FIELDTYPE_FLOAT32, "X",0,0,0 },
+ { DIS_FIELDTYPE_FLOAT32, "Y",0,0,0 },
+ { DIS_FIELDTYPE_FLOAT32, "Z",0,0,0 },
+ { DIS_FIELDTYPE_END, NULL,0,0,0 }
+};
+
+DIS_ParserNode DIS_FIELDS_ORIENTATION[] =
+{
+ { DIS_FIELDTYPE_FLOAT32, "Psi",0,0,0 },
+ { DIS_FIELDTYPE_FLOAT32, "Theta",0,0,0 },
+ { DIS_FIELDTYPE_FLOAT32, "Phi",0,0,0 },
+ { DIS_FIELDTYPE_END, NULL,0,0,0 }
+};
+
+DIS_ParserNode DIS_FIELDS_BURST_DESCRIPTOR[] =
+{
+ { DIS_FIELDTYPE_ENTITY_TYPE, "Munition",0,0,0 },
+ { DIS_FIELDTYPE_WARHEAD, "Warhead",0,0,0 },
+ { DIS_FIELDTYPE_FUSE, "Fuse",0,0,0 },
+ { DIS_FIELDTYPE_UINT16, "Quantity",0,0,0 },
+ { DIS_FIELDTYPE_UINT16, "Rate",0,0,0 },
+ { DIS_FIELDTYPE_END, NULL,0,0,0 }
+};
+
+DIS_ParserNode DIS_FIELDS_ARTICULATION_PARAMETER[] =
+{
+ { DIS_FIELDTYPE_ARTIC_PARAM_TYPE_DESIGNATOR, "Parameter Type Designator",0,0,0 },
+ { DIS_FIELDTYPE_UINT8, "Change",0,0,0 },
+ { DIS_FIELDTYPE_UINT16, "Part Attached To ID",0,0,0 },
+ { DIS_FIELDTYPE_ARTIC_PARAM_TYPE, "Parameter Type",0,0,0 },
+ { DIS_FIELDTYPE_UINT64, "Parameter Value",0,0,0 },
+ { DIS_FIELDTYPE_END, NULL,0,0,0 }
+};
+
+DIS_ParserNode DIS_FIELDS_NONE[] =
+{
+ { DIS_FIELDTYPE_END, NULL, 0,0,0 }
+};
+
+DIS_BitMask DIS_APPEARANCE_LANDPLATFORM[] =
+{
+ { 0x00000001, 0, "Paint Scheme", {
+ { 0, "Uniform color" },
+ { 1, "Camouflage" },
+ { 0,0 }
+ } },
+ { 0x00000002, 1, "Mobility", {
+ { 0, "No mobility kill" },
+ { 1, "Mobility kill" },
+ { 0,0 }
+ } },
+ { 0x00000004, 2, "Fire Power", {
+ { 0, "No fire-power kill" },
+ { 1, "Fire-power kill" },
+ { 0,0 }
+ } },
+ { 0x00000018, 3, "Damage", {
+ { 0, "No damage" },
+ { 1, "Slight damage" },
+ { 2, "Moderate damage" },
+ { 3, "Destroyed" },
+ { 0,0 }
+ } },
+ { 0, 0, 0, {
+ { 0, 0 }
+ } }
+};
+
+DIS_BitMask DIS_APPEARANCE_LIFEFORM[] =
+{
+ { 0x00000001, 0, "Paint Scheme", {
+ { 0, "Uniform color" },
+ { 1, "Camouflage" },
+ { 0,0 }
+ } },
+ { 0x00000018, 3, "Health", {
+ { 0, "No injury" },
+ { 1, "Slight injury" },
+ { 2, "Moderate injury" },
+ { 3, "Fatal injury" },
+ { 0,0 }
+ } },
+ { 0, 0, 0, {
+ { 0, 0 }
+ } }
+};
+
+/* Adjust an offset variable for proper alignment for a specified field length.
+ */
+gint alignOffset(gint offset, guint fieldLength)
+{
+ gint remainder = offset % fieldLength;
+ if (remainder != 0)
+ {
+ offset += fieldLength - remainder;
+ }
+ return offset;
+}
+
+/* Parse a field consisting of a specified number of bytes. This field parser
+ * doesn't perform any alignment.
+ */
+gint parseField_Bytes(tvbuff_t *tvb, proto_tree *tree, gint offset, DIS_ParserNode parserNode, guint numBytes)
+{
+ proto_tree_add_text(tree, tvb, offset, numBytes, "%s (%d bytes)",
+ parserNode.fieldLabel, numBytes);
+ offset += numBytes;
+ return offset;
+}
+
+/* Parse a bitmask field.
+ */
+gint parseField_Bitmask(tvbuff_t *tvb, proto_tree *tree, gint offset, DIS_ParserNode parserNode, guint numBytes)
+{
+ DIS_BitMask *bitMask = 0;
+ guint64 uintVal = 0;
+
+ offset = alignOffset(offset, numBytes);
+
+ switch(numBytes)
+ {
+ case 1:
+ uintVal = tvb_get_guint8(tvb, offset);
+ break;
+ case 2:
+ uintVal = tvb_get_ntohs(tvb, offset);
+ break;
+ case 4:
+ uintVal = tvb_get_ntohl(tvb, offset);
+ break;
+ case 8:
+ uintVal = tvb_get_ntoh64(tvb, offset);
+ break;
+ default:
+ /* assert */
+ break;
+ }
+
+ switch(parserNode.fieldType)
+ {
+ case DIS_FIELDTYPE_APPEARANCE:
+ if ((entityKind == DIS_ENTITYKIND_PLATFORM) &&
+ (entityDomain == DIS_DOMAIN_LAND))
+ {
+ bitMask = DIS_APPEARANCE_LANDPLATFORM;
+ }
+ else if (entityKind == DIS_ENTITYKIND_LIFE_FORM)
+ {
+ bitMask = DIS_APPEARANCE_LIFEFORM;
+ }
+ break;
+ default:
+ break;
+ }
+
+ if (bitMask != 0)
+ {
+ int maskIndex = 0;
+ while (bitMask[maskIndex].maskBits != 0)
+ {
+ int mapIndex = 0;
+ DIS_BitMaskMapping *bitMaskMap = bitMask[maskIndex].bitMappings;
+
+ while (bitMaskMap[mapIndex].label != 0)
+ {
+ if (((bitMask[maskIndex].maskBits & uintVal) >> bitMask[maskIndex].shiftBits) ==
+ bitMaskMap[mapIndex].value)
+ {
+ proto_tree_add_text(tree, tvb, offset, numBytes,
+ "%s = %s", bitMask[maskIndex].label,
+ bitMaskMap[mapIndex].label);
+ break;
+ }
+ ++mapIndex;
+ }
+ ++maskIndex;
+ }
+ }
+ else
+ {
+ proto_tree_add_text(tree, tvb, offset, numBytes,
+ "Unknown Appearance Type (%" PRIu64 ")", uintVal);
+ }
+
+ offset += numBytes;
+
+ return offset;
+}
+
+/* Parse an unsigned integer field of a specified number of bytes.
+ */
+gint parseField_UInt(tvbuff_t *tvb, proto_tree *tree, gint offset, DIS_ParserNode parserNode, guint numBytes)
+{
+ guint64 uintVal = 0;
+
+ offset = alignOffset(offset, numBytes);
+
+ switch(numBytes)
+ {
+ case 1:
+ uintVal = tvb_get_guint8(tvb, offset);
+ break;
+ case 2:
+ uintVal = tvb_get_ntohs(tvb, offset);
+ break;
+ case 4:
+ uintVal = tvb_get_ntohl(tvb, offset);
+ break;
+ case 8:
+ uintVal = tvb_get_ntoh64(tvb, offset);
+ break;
+ default:
+ /* assert */
+ break;
+ }
+
+ proto_tree_add_text(tree, tvb, offset, numBytes, "%s = %" PRIu64,
+ parserNode.fieldLabel, uintVal);
+
+ if (parserNode.outputVar != 0)
+ {
+ *(parserNode.outputVar) = (guint32)uintVal;
+ }
+
+ offset += numBytes;
+
+ return offset;
+}
+
+/* Parse a signed integer field of a specified number of bytes.
+ */
+gint parseField_Int(tvbuff_t *tvb, proto_tree *tree, gint offset, DIS_ParserNode parserNode, guint numBytes)
+{
+ guint64 uintVal = 0;
+
+ offset = alignOffset(offset, numBytes);
+
+ switch(numBytes)
+ {
+ case 1:
+ uintVal = tvb_get_guint8(tvb, offset);
+ break;
+ case 2:
+ uintVal = tvb_get_ntohs(tvb, offset);
+ break;
+ case 4:
+ uintVal = tvb_get_ntohl(tvb, offset);
+ break;
+ case 8:
+ uintVal = tvb_get_ntoh64(tvb, offset);
+ break;
+ default:
+ /* assert */
+ break;
+ }
+
+ proto_tree_add_text(tree, tvb, offset, numBytes, "%s = %" PRId64,
+ parserNode.fieldLabel, uintVal);
+
+ offset += numBytes;
+
+ return offset;
+}
+
+/* Parse a field that explicitly specified a number of pad bytes (vs implicit
+ * padding, which occurs whenever padding is inserted to properly align the
+ * field.
+ */
+gint parseField_Pad(tvbuff_t *tvb, proto_tree *tree, gint offset, DIS_ParserNode parserNode, guint numBytes)
+{
+ proto_tree_add_text(tree, tvb, offset, numBytes,
+ "Explicit Padding (%d bytes)", numBytes);
+
+ offset += numBytes;
+
+ return offset;
+}
+
+/* Parse an enumerated type field.
+ */
+gint parseField_Enum(tvbuff_t *tvb, proto_tree *tree, gint offset, DIS_ParserNode parserNode, guint numBytes)
+{
+ const value_string *enumStrings = 0;
+ guint32 enumVal = 0;
+ const gchar *enumStr = 0;
+
+ offset = alignOffset(offset, numBytes);
+
+ switch(parserNode.fieldType)
+ {
+ case DIS_FIELDTYPE_PROTOCOL_VERSION:
+ enumStrings = DIS_PDU_ProtocolVersion_Strings;
+ break;
+ case DIS_FIELDTYPE_PROTOCOL_FAMILY:
+ enumStrings = DIS_PDU_ProtocolFamily_Strings;
+ break;
+ case DIS_FIELDTYPE_PDU_TYPE:
+ enumStrings = DIS_PDU_Type_Strings;
+ break;
+ case DIS_FIELDTYPE_ENTITY_KIND:
+ enumStrings = DIS_PDU_EntityKind_Strings;
+ break;
+ case DIS_FIELDTYPE_DOMAIN:
+ enumStrings = DIS_PDU_Domain_Strings;
+ break;
+ case DIS_FIELDTYPE_DETONATION_RESULT:
+ enumStrings = DIS_PDU_DetonationResult_Strings;
+ break;
+ case DIS_FIELDTYPE_CATEGORY:
+ if (entityKind == DIS_ENTITYKIND_PLATFORM)
+ {
+ switch(entityDomain)
+ {
+ case DIS_DOMAIN_LAND:
+ enumStrings = DIS_PDU_Category_LandPlatform_Strings;
+ break;
+ case DIS_DOMAIN_AIR:
+ enumStrings = DIS_PDU_Category_AirPlatform_Strings;
+ break;
+ case DIS_DOMAIN_SURFACE:
+ enumStrings = DIS_PDU_Category_SurfacePlatform_Strings;
+ break;
+ case DIS_DOMAIN_SUBSURFACE:
+ enumStrings = DIS_PDU_Category_SubsurfacePlatform_Strings;
+ break;
+ case DIS_DOMAIN_SPACE:
+ enumStrings = DIS_PDU_Category_SpacePlatform_Strings;
+ break;
+ default:
+ enumStrings = 0;
+ break;
+ }
+ }
+ break;
+ default:
+ enumStrings = 0;
+ break;
+ }
+
+ switch(numBytes)
+ {
+ case 1:
+ enumVal = tvb_get_guint8(tvb, offset);
+ break;
+ case 2:
+ enumVal = tvb_get_ntohs(tvb, offset);
+ break;
+ case 4:
+ enumVal = tvb_get_ntohl(tvb, offset);
+ break;
+ default:
+ /* assert */
+ break;
+ }
+
+ if (enumStrings != 0)
+ {
+ enumStr = val_to_str(enumVal, enumStrings, "Unknown Enum Value");
+ }
+ else
+ {
+ enumStr = "Unknown Enum Type";
+ }
+
+ proto_tree_add_text(tree, tvb, offset, numBytes, "%s = %s",
+ parserNode.fieldLabel, enumStr);
+
+ if (parserNode.outputVar != 0)
+ {
+ *(parserNode.outputVar) = enumVal;
+ }
+
+ offset += numBytes;
+
+ return offset;
+}
+
+/* Parse a 4-byte floating-point value.
+ */
+gint parseField_Float(tvbuff_t *tvb, proto_tree *tree, gint offset, DIS_ParserNode parserNode)
+{
+ gfloat floatVal;
+
+ offset = alignOffset(offset, 4);
+ floatVal = tvb_get_ntohieee_float(tvb, offset);
+ proto_tree_add_text(tree, tvb, offset, 4, "%s = %f",
+ parserNode.fieldLabel, floatVal);
+
+ offset += 4;
+
+ return offset;
+}
+
+/* Parse an 8-byte floating-point value.
+ */
+gint parseField_Double(tvbuff_t *tvb, proto_tree *tree, gint offset, DIS_ParserNode parserNode)
+{
+ gdouble doubleVal;
+
+ offset = alignOffset(offset, 8);
+ doubleVal = tvb_get_ntohieee_double(tvb, offset);
+ proto_tree_add_text(tree, tvb, offset, 8, "%s = %lf",
+ parserNode.fieldLabel, doubleVal);
+
+ offset += 8;
+
+ return offset;
+}
diff --git a/epan/dissectors/packet-dis-fields.h b/epan/dissectors/packet-dis-fields.h
new file mode 100644
index 0000000000..71dfbd8c30
--- /dev/null
+++ b/epan/dissectors/packet-dis-fields.h
@@ -0,0 +1,166 @@
+/* packet-dis-fields.h
+ * Declarations for DIS field parsing.
+ * 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.
+ */
+
+#ifndef __PACKET_DIS_FIELDPARSERS_H__
+#define __PACKET_DIS_FIELDPARSERS_H__
+
+#include <epan/packet.h>
+
+/* enumeration of all field types used for DIS parsing. */
+typedef enum
+{
+ /* end marker to indicate the end of a parser sequence */
+ DIS_FIELDTYPE_END = 0,
+
+ /* basic numeric types */
+ DIS_FIELDTYPE_INT8,
+ DIS_FIELDTYPE_INT16,
+ DIS_FIELDTYPE_INT32,
+ DIS_FIELDTYPE_INT64,
+ DIS_FIELDTYPE_UINT8,
+ DIS_FIELDTYPE_UINT16,
+ DIS_FIELDTYPE_UINT32,
+ DIS_FIELDTYPE_UINT64,
+ DIS_FIELDTYPE_FLOAT32,
+ DIS_FIELDTYPE_FLOAT64,
+
+ /* padding */
+ DIS_FIELDTYPE_PAD8,
+ DIS_FIELDTYPE_PAD16,
+ DIS_FIELDTYPE_PAD32,
+
+ /* other atomic types, including enumerations */
+ DIS_FIELDTYPE_APPEARANCE,
+ DIS_FIELDTYPE_ARTIC_PARAM_TYPE_DESIGNATOR,
+ DIS_FIELDTYPE_ARTIC_PARAM_TYPE,
+ DIS_FIELDTYPE_CAPABILITIES,
+ DIS_FIELDTYPE_CATEGORY,
+ DIS_FIELDTYPE_COUNTRY,
+ DIS_FIELDTYPE_DEAD_RECKONING_PARAMS,
+ DIS_FIELDTYPE_DEAD_RECKONING_ALGORITHM,
+ DIS_FIELDTYPE_DEAD_RECKONING_OTHER_PARAMS,
+ DIS_FIELDTYPE_DETONATION_RESULT,
+ DIS_FIELDTYPE_DOMAIN,
+ DIS_FIELDTYPE_ENTITY_KIND,
+ DIS_FIELDTYPE_ENTITY_MARKING,
+ DIS_FIELDTYPE_EXTRA,
+ DIS_FIELDTYPE_FORCE_ID,
+ DIS_FIELDTYPE_FUSE,
+ DIS_FIELDTYPE_ORIENTATION,
+ DIS_FIELDTYPE_PDU_TYPE,
+ DIS_FIELDTYPE_PROTOCOL_FAMILY,
+ DIS_FIELDTYPE_PROTOCOL_VERSION,
+ DIS_FIELDTYPE_SPECIFIC,
+ DIS_FIELDTYPE_SUBCATEGORY,
+ DIS_FIELDTYPE_TIMESTAMP,
+ DIS_FIELDTYPE_WARHEAD,
+
+ /* composite types */
+ DIS_FIELDTYPE_ARTICULATION_PARAMETERS,
+ DIS_FIELDTYPE_BURST_DESCRIPTOR,
+ DIS_FIELDTYPE_ENTITY_ID,
+ DIS_FIELDTYPE_ENTITY_TYPE,
+ DIS_FIELDTYPE_EVENT_ID,
+ DIS_FIELDTYPE_LINEAR_VELOCITY,
+ DIS_FIELDTYPE_LOCATION_WORLD,
+ DIS_FIELDTYPE_LOCATION_ENTITY
+} DIS_FieldType;
+
+/* Struct which contains the data needed to parse a single DIS field.
+ */
+typedef struct DIS_ParserNode_T
+{
+ DIS_FieldType fieldType;
+ const char *fieldLabel;
+ int ettVar;
+ struct DIS_ParserNode_T *children;
+ guint32 *outputVar;
+} DIS_ParserNode;
+
+/* Struct which associates a name with a particular bit combination.
+ */
+typedef struct
+{
+ guint32 value;
+ const char *label;
+} DIS_BitMaskMapping;
+
+/* Struct which specifies all possible bit mappings associated with
+ * a particular bit mask.
+ */
+typedef struct
+{
+ guint32 maskBits;
+ guint32 shiftBits;
+ const char *label;
+ DIS_BitMaskMapping bitMappings[33];
+} DIS_BitMask;
+
+extern DIS_ParserNode DIS_FIELDS_PDU_HEADER[];
+
+extern DIS_ParserNode DIS_FIELDS_ENTITY_ID[];
+
+extern DIS_ParserNode DIS_FIELDS_ENTITY_TYPE[];
+
+extern DIS_ParserNode DIS_FIELDS_EVENT_ID[];
+
+extern DIS_ParserNode DIS_FIELDS_LINEAR_VELOCITY[];
+
+extern DIS_ParserNode DIS_FIELDS_LOCATION_WORLD[];
+
+extern DIS_ParserNode DIS_FIELDS_LOCATION_ENTITY[];
+
+extern DIS_ParserNode DIS_FIELDS_BURST_DESCRIPTOR[];
+
+extern DIS_ParserNode DIS_FIELDS_ARTICULATION_PARAMETER[];
+
+extern DIS_ParserNode DIS_FIELDS_ORIENTATION[];
+
+extern DIS_ParserNode DIS_FIELDS_NONE[];
+
+extern DIS_BitMask DIS_APPEARANCE_LANDPLATFORM[];
+
+extern DIS_BitMask DIS_APPEARANCE_LIFEFORM[];
+
+gint parseField_Bytes(tvbuff_t *tvb, proto_tree *tree, gint offset, DIS_ParserNode parserNode, guint numBytes);
+
+gint parseField_Bitmask(tvbuff_t *tvb, proto_tree *tree, gint offset, DIS_ParserNode parserNode, guint numBytes);
+
+gint parseField_UInt(tvbuff_t *tvb, proto_tree *tree, gint offset, DIS_ParserNode parserNode, guint numBytes);
+
+gint parseField_Int(tvbuff_t *tvb, proto_tree *tree, gint offset, DIS_ParserNode parserNode, guint numBytes);
+
+gint parseField_Enum(tvbuff_t *tvb, proto_tree *tree, gint offset, DIS_ParserNode parserNode, guint numBytes);
+
+gint parseField_Pad(tvbuff_t *tvb, proto_tree *tree, gint offset, DIS_ParserNode parserNode, guint numBytes);
+
+gint parseField_Float(tvbuff_t *tvb, proto_tree *tree, gint offset, DIS_ParserNode parserNode);
+
+gint parseField_Double(tvbuff_t *tvb, proto_tree *tree, gint offset, DIS_ParserNode parserNode);
+
+extern guint32 pduType;
+extern guint32 entityKind;
+extern guint32 entityDomain;
+
+#endif /* packet-dis-fieldparsers.h */
diff --git a/epan/dissectors/packet-dis-pdus.c b/epan/dissectors/packet-dis-pdus.c
new file mode 100644
index 0000000000..fb66a8b8d1
--- /dev/null
+++ b/epan/dissectors/packet-dis-pdus.c
@@ -0,0 +1,401 @@
+/* packet-dis-pdus.c
+ * Routines and definitions for DIS PDU parsing.
+ * 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <string.h>
+#include "packet-dis-pdus.h"
+#include "packet-dis-fields.h"
+
+guint32 numArticulations;
+gint ettArticulations[DIS_PDU_MAX_ARTICULATIONS];
+
+DIS_ParserNode DIS_PARSER_ENTITY_STATE_PDU[] =
+{
+ { DIS_FIELDTYPE_ENTITY_ID, "Entity ID",0,0,0 },
+ { DIS_FIELDTYPE_FORCE_ID, "Force ID",0,0,0 },
+ { DIS_FIELDTYPE_UINT8, "Number of Articulation Parameters",0,0,&numArticulations },
+ { DIS_FIELDTYPE_ENTITY_TYPE, "Entity Type",0,0,0 },
+ { DIS_FIELDTYPE_ENTITY_TYPE, "Alternative Entity Type",0,0,0 },
+ { DIS_FIELDTYPE_LINEAR_VELOCITY, "Entity Linear Velocity",0,0,0 },
+ { DIS_FIELDTYPE_LOCATION_WORLD, "Entity Location",0,0,0 },
+ { DIS_FIELDTYPE_ORIENTATION, "Entity Orientation",0,0,0 },
+ { DIS_FIELDTYPE_APPEARANCE, "Entity Appearance",0,0,0 },
+ { DIS_FIELDTYPE_DEAD_RECKONING_PARAMS, "Dead Reckoning Parameters",0,0,0 },
+ { DIS_FIELDTYPE_ENTITY_MARKING, "Entity Marking",0,0,0 },
+ { DIS_FIELDTYPE_CAPABILITIES, "Capabilities",0,0,0 },
+ { DIS_FIELDTYPE_ARTICULATION_PARAMETERS, "Articulation Parameters",0,0,0 },
+ { DIS_FIELDTYPE_END, NULL,0,0,0 }
+};
+
+DIS_ParserNode DIS_PARSER_FIRE_PDU[] =
+{
+ { DIS_FIELDTYPE_ENTITY_ID, "Firing Entity ID",0,0,0 },
+ { DIS_FIELDTYPE_ENTITY_ID, "Target Entity ID",0,0,0 },
+ { DIS_FIELDTYPE_ENTITY_ID, "Munition ID",0,0,0 },
+ { DIS_FIELDTYPE_EVENT_ID, "Event ID",0,0,0 },
+ { DIS_FIELDTYPE_UINT32, "Fire Mission Index",0,0,0 },
+ { DIS_FIELDTYPE_LOCATION_WORLD, "Location in World Coordinates",0,0,0 },
+ { DIS_FIELDTYPE_BURST_DESCRIPTOR, "Burst Descriptor",0,0,0 },
+ { DIS_FIELDTYPE_LINEAR_VELOCITY, "Velocity",0,0,0 },
+ { DIS_FIELDTYPE_FLOAT32, "Range",0,0,0 },
+ { DIS_FIELDTYPE_END, NULL,0,0,0 }
+};
+
+DIS_ParserNode DIS_PARSER_DETONATION_PDU[] =
+{
+ { DIS_FIELDTYPE_ENTITY_ID, "Firing Entity ID",0,0,0 },
+ { DIS_FIELDTYPE_ENTITY_ID, "Target Entity ID",0,0,0 },
+ { DIS_FIELDTYPE_ENTITY_ID, "Munition ID",0,0,0 },
+ { DIS_FIELDTYPE_EVENT_ID, "Event ID",0,0,0 },
+ { DIS_FIELDTYPE_LINEAR_VELOCITY, "Velocity",0,0,0 },
+ { DIS_FIELDTYPE_LOCATION_WORLD, "Location in World Coordinates",0,0,0 },
+ { DIS_FIELDTYPE_BURST_DESCRIPTOR, "Burst Descriptor",0,0,0 },
+ { DIS_FIELDTYPE_LOCATION_ENTITY, "Location in Entity Coordinates",0,0,0 },
+ { DIS_FIELDTYPE_DETONATION_RESULT, "Detonation Result",0,0,0 },
+ { DIS_FIELDTYPE_UINT8, "Number of Articulation Parameters",0,0,0 },
+ { DIS_FIELDTYPE_PAD16, "Padding",0,0,0 },
+ { DIS_FIELDTYPE_ARTICULATION_PARAMETERS, "Articulation Parameters",0,0,0 },
+ { DIS_FIELDTYPE_END, NULL,0,0,0 }
+};
+
+/* Initialize the parsers for each PDU type and the standard DIS header.
+ */
+void initializeParsers(void)
+{
+ initializeParser(DIS_PARSER_ENTITY_STATE_PDU);
+ initializeParser(DIS_PARSER_FIRE_PDU);
+ initializeParser(DIS_PARSER_DETONATION_PDU);
+ initializeParser(DIS_FIELDS_PDU_HEADER);
+}
+
+/* Create a specific subtree for a PDU or a composite PDU field.
+ */
+DIS_ParserNode *createSubtree(DIS_ParserNode parserNodes[], gint *ettVar)
+{
+ guint fieldIndex = 0;
+ guint fieldCount;
+ gint *ett[1];
+ DIS_ParserNode *newSubtree;
+
+ while (parserNodes[fieldIndex].fieldType != DIS_FIELDTYPE_END)
+ {
+ ++fieldIndex;
+ }
+
+ fieldCount = fieldIndex + 1;
+
+ newSubtree = (DIS_ParserNode*)g_malloc(sizeof(DIS_ParserNode) * fieldCount);
+
+ memcpy(newSubtree, parserNodes, sizeof(DIS_ParserNode) * fieldCount);
+
+ initializeParser(newSubtree);
+
+ ett[0] = ettVar;
+ proto_register_subtree_array(ett, array_length(ett));
+
+ return newSubtree;
+}
+
+/* Initialize an array of parser nodes.
+ */
+void initializeParser(DIS_ParserNode parserNodes[])
+{
+ guint parserIndex = 0;
+
+ /* Create the parser subtrees for each of the composite field types.
+ */
+ while (parserNodes[parserIndex].fieldType != DIS_FIELDTYPE_END)
+ {
+ switch (parserNodes[parserIndex].fieldType)
+ {
+ case DIS_FIELDTYPE_APPEARANCE:
+ parserNodes[parserIndex].children = createSubtree(
+ DIS_FIELDS_NONE,
+ &parserNodes[parserIndex].ettVar);
+ break;
+ case DIS_FIELDTYPE_ARTICULATION_PARAMETERS:
+ parserNodes[parserIndex].children = createSubtree(
+ DIS_FIELDS_ARTICULATION_PARAMETER,
+ &parserNodes[parserIndex].ettVar);
+ break;
+ case DIS_FIELDTYPE_BURST_DESCRIPTOR:
+ parserNodes[parserIndex].children = createSubtree(
+ DIS_FIELDS_BURST_DESCRIPTOR,
+ &parserNodes[parserIndex].ettVar);
+ break;
+ case DIS_FIELDTYPE_ENTITY_ID:
+ parserNodes[parserIndex].children = createSubtree(
+ DIS_FIELDS_ENTITY_ID,
+ &parserNodes[parserIndex].ettVar);
+ break;
+ case DIS_FIELDTYPE_ENTITY_TYPE:
+ parserNodes[parserIndex].children = createSubtree(
+ DIS_FIELDS_ENTITY_TYPE,
+ &parserNodes[parserIndex].ettVar);
+ break;
+ case DIS_FIELDTYPE_EVENT_ID:
+ parserNodes[parserIndex].children = createSubtree(
+ DIS_FIELDS_EVENT_ID,
+ &parserNodes[parserIndex].ettVar);
+ break;
+ case DIS_FIELDTYPE_LINEAR_VELOCITY:
+ parserNodes[parserIndex].children = createSubtree(
+ DIS_FIELDS_LINEAR_VELOCITY,
+ &parserNodes[parserIndex].ettVar);
+ break;
+ case DIS_FIELDTYPE_LOCATION_WORLD:
+ parserNodes[parserIndex].children = createSubtree(
+ DIS_FIELDS_LOCATION_WORLD,
+ &parserNodes[parserIndex].ettVar);
+ break;
+ case DIS_FIELDTYPE_LOCATION_ENTITY:
+ parserNodes[parserIndex].children = createSubtree(
+ DIS_FIELDS_LOCATION_ENTITY,
+ &parserNodes[parserIndex].ettVar);
+ break;
+ case DIS_FIELDTYPE_ORIENTATION:
+ parserNodes[parserIndex].children = createSubtree(
+ DIS_FIELDS_ORIENTATION,
+ &parserNodes[parserIndex].ettVar);
+ break;
+ default:
+ break;
+ }
+ ++parserIndex;
+ }
+}
+
+/* Parse packet data based on a specified array of DIS_ParserNodes.
+ */
+gint parseFields(tvbuff_t *tvb, proto_tree *tree, gint offset, DIS_ParserNode parserNodes[])
+{
+ guint fieldIndex = 0;
+
+ while (parserNodes[fieldIndex].fieldType != DIS_FIELDTYPE_END)
+ {
+ proto_item *newField = 0;
+ switch(parserNodes[fieldIndex].fieldType)
+ {
+ case DIS_FIELDTYPE_INT8:
+ offset = parseField_Int(tvb, tree, offset,
+ parserNodes[fieldIndex], 1);
+ break;
+ case DIS_FIELDTYPE_INT16:
+ offset = parseField_Int(tvb, tree, offset,
+ parserNodes[fieldIndex], 2);
+ break;
+ case DIS_FIELDTYPE_INT32:
+ offset = parseField_Int(tvb, tree, offset,
+ parserNodes[fieldIndex], 4);
+ break;
+ case DIS_FIELDTYPE_INT64:
+ offset = parseField_Int(tvb, tree, offset,
+ parserNodes[fieldIndex], 8);
+ break;
+ case DIS_FIELDTYPE_UINT8:
+ offset = parseField_UInt(tvb, tree, offset,
+ parserNodes[fieldIndex], 1);
+ break;
+ case DIS_FIELDTYPE_UINT16:
+ offset = parseField_UInt(tvb, tree, offset,
+ parserNodes[fieldIndex], 2);
+ break;
+ case DIS_FIELDTYPE_UINT32:
+ offset = parseField_UInt(tvb, tree, offset,
+ parserNodes[fieldIndex], 4);
+ break;
+ case DIS_FIELDTYPE_UINT64:
+ offset = parseField_UInt(tvb, tree, offset,
+ parserNodes[fieldIndex], 8);
+ break;
+ case DIS_FIELDTYPE_FLOAT32:
+ offset = parseField_Float(tvb, tree, offset,
+ parserNodes[fieldIndex]);
+ break;
+ case DIS_FIELDTYPE_FLOAT64:
+ offset = parseField_Double(tvb, tree, offset,
+ parserNodes[fieldIndex]);
+ break;
+ case DIS_FIELDTYPE_PAD8:
+ offset = parseField_Pad(tvb, tree, offset,
+ parserNodes[fieldIndex], 1);
+ break;
+ case DIS_FIELDTYPE_PAD16:
+ offset = parseField_Pad(tvb, tree, offset,
+ parserNodes[fieldIndex], 2);
+ break;
+ case DIS_FIELDTYPE_PAD32:
+ offset = parseField_Pad(tvb, tree, offset,
+ parserNodes[fieldIndex], 4);
+ break;
+ case DIS_FIELDTYPE_APPEARANCE:
+ {
+ proto_item *newSubtree;
+ newField = proto_tree_add_text(tree, tvb, offset, 4,
+ parserNodes[fieldIndex].fieldLabel);
+ newSubtree = proto_item_add_subtree(newField,
+ parserNodes[fieldIndex].ettVar);
+ offset = parseField_Bitmask(tvb, newSubtree, offset,
+ parserNodes[fieldIndex], 4);
+ }
+ break;
+ case DIS_FIELDTYPE_ARTIC_PARAM_TYPE_DESIGNATOR:
+ offset = parseField_UInt(tvb, tree, offset,
+ parserNodes[fieldIndex], 1);
+ break;
+ case DIS_FIELDTYPE_ARTIC_PARAM_TYPE:
+ offset = parseField_UInt(tvb, tree, offset,
+ parserNodes[fieldIndex], 4);
+ break;
+ case DIS_FIELDTYPE_CAPABILITIES:
+ offset = parseField_UInt(tvb, tree, offset,
+ parserNodes[fieldIndex], 4);
+ break;
+ case DIS_FIELDTYPE_CATEGORY:
+ offset = parseField_Enum(tvb, tree, offset,
+ parserNodes[fieldIndex], 1);
+ break;
+ case DIS_FIELDTYPE_COUNTRY:
+ offset = parseField_UInt(tvb, tree, offset,
+ parserNodes[fieldIndex], 2);
+ break;
+ case DIS_FIELDTYPE_DEAD_RECKONING_PARAMS:
+ /* This is really a struct... needs a field parser.
+ * For now, just skip the 12 bytes.
+ */
+ offset = parseField_Bytes(tvb, tree, offset,
+ parserNodes[fieldIndex], 40);
+ break;
+ case DIS_FIELDTYPE_DETONATION_RESULT:
+ offset = parseField_Enum(tvb, tree, offset,
+ parserNodes[fieldIndex], 1);
+ break;
+ case DIS_FIELDTYPE_DOMAIN:
+ offset = parseField_Enum(tvb, tree, offset,
+ parserNodes[fieldIndex], 1);
+ break;
+ case DIS_FIELDTYPE_ENTITY_KIND:
+ offset = parseField_Enum(tvb, tree, offset,
+ parserNodes[fieldIndex], 1);
+ break;
+ case DIS_FIELDTYPE_ENTITY_MARKING:
+ /* This is really a struct... needs a field parser.
+ * For now, just skip the 12 bytes.
+ */
+ offset = parseField_Bytes(tvb, tree, offset,
+ parserNodes[fieldIndex], 12);
+ break;
+ case DIS_FIELDTYPE_EXTRA:
+ offset = parseField_UInt(tvb, tree, offset,
+ parserNodes[fieldIndex], 1);
+ break;
+ case DIS_FIELDTYPE_FORCE_ID:
+ offset = parseField_UInt(tvb, tree, offset,
+ parserNodes[fieldIndex], 1);
+ break;
+ case DIS_FIELDTYPE_FUSE:
+ offset = parseField_UInt(tvb, tree, offset,
+ parserNodes[fieldIndex], 2);
+ break;
+ case DIS_FIELDTYPE_PDU_TYPE:
+ offset = parseField_Enum(tvb, tree, offset,
+ parserNodes[fieldIndex], 1);
+ break;
+ case DIS_FIELDTYPE_PROTOCOL_FAMILY:
+ offset = parseField_Enum(tvb, tree, offset,
+ parserNodes[fieldIndex], 1);
+ break;
+ case DIS_FIELDTYPE_PROTOCOL_VERSION:
+ offset = parseField_Enum(tvb, tree, offset,
+ parserNodes[fieldIndex], 1);
+ break;
+ case DIS_FIELDTYPE_SPECIFIC:
+ offset = parseField_UInt(tvb, tree, offset,
+ parserNodes[fieldIndex], 1);
+ break;
+ case DIS_FIELDTYPE_SUBCATEGORY:
+ offset = parseField_UInt(tvb, tree, offset,
+ parserNodes[fieldIndex], 1);
+ break;
+ case DIS_FIELDTYPE_TIMESTAMP:
+ offset = parseField_UInt(tvb, tree, offset,
+ parserNodes[fieldIndex], 4);
+ break;
+ case DIS_FIELDTYPE_WARHEAD:
+ offset = parseField_UInt(tvb, tree, offset,
+ parserNodes[fieldIndex], 2);
+ break;
+ case DIS_FIELDTYPE_BURST_DESCRIPTOR:
+ case DIS_FIELDTYPE_ENTITY_ID:
+ case DIS_FIELDTYPE_EVENT_ID:
+ case DIS_FIELDTYPE_LINEAR_VELOCITY:
+ case DIS_FIELDTYPE_LOCATION_WORLD:
+ case DIS_FIELDTYPE_LOCATION_ENTITY:
+ case DIS_FIELDTYPE_ENTITY_TYPE:
+ case DIS_FIELDTYPE_ORIENTATION:
+ newField = proto_tree_add_text(tree, tvb, offset, -1,
+ parserNodes[fieldIndex].fieldLabel);
+ if (parserNodes[fieldIndex].children != 0)
+ {
+ proto_item *newSubtree = proto_item_add_subtree(newField,
+ parserNodes[fieldIndex].ettVar);
+ offset = parseFields(tvb, newSubtree, offset,
+ parserNodes[fieldIndex].children);
+ }
+ proto_item_set_end(newField, tvb, offset);
+ break;
+ case DIS_FIELDTYPE_ARTICULATION_PARAMETERS:
+ {
+ guint i;
+
+ if (numArticulations > DIS_PDU_MAX_ARTICULATIONS)
+ {
+ numArticulations = DIS_PDU_MAX_ARTICULATIONS;
+ }
+
+ for (i = 0; i < numArticulations; ++i)
+ {
+ proto_item *newSubtree;
+ newField = proto_tree_add_text(tree, tvb, offset, -1,
+ parserNodes[fieldIndex].fieldLabel);
+ newSubtree = proto_item_add_subtree(newField,
+ ettArticulations[i]);
+ offset = parseFields(tvb, newSubtree, offset,
+ parserNodes[fieldIndex].children);
+ proto_item_set_end(newField, tvb, offset);
+ }
+ }
+ break;
+ default:
+ break;
+ }
+
+ ++fieldIndex;
+ }
+
+ return offset;
+}
diff --git a/epan/dissectors/packet-dis-pdus.h b/epan/dissectors/packet-dis-pdus.h
new file mode 100644
index 0000000000..4222bac5fc
--- /dev/null
+++ b/epan/dissectors/packet-dis-pdus.h
@@ -0,0 +1,49 @@
+/* packet-dis-pdus.h
+ * Declarations for DIS PDU parsing.
+ * 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.
+ */
+
+#ifndef __PACKET_DIS_PDUPARSERS_H__
+#define __PACKET_DIS_PDUPARSERS_H__
+
+#include "packet-dis-fields.h"
+
+extern DIS_ParserNode DIS_PARSER_ENTITY_STATE_PDU[];
+
+extern DIS_ParserNode DIS_PARSER_FIRE_PDU[];
+
+extern DIS_ParserNode DIS_PARSER_DETONATION_PDU[];
+
+DIS_ParserNode *createSubtree(DIS_ParserNode parserNodes[], gint *ettVar);
+
+void initializeParser(DIS_ParserNode parserNodes[]);
+
+void initializeParsers(void);
+
+gint parseFields(tvbuff_t *tvb, proto_tree *tree, gint offset, DIS_ParserNode parserNodes[]);
+
+extern guint32 numArticulations;
+extern int ettArticulations[];
+
+#define DIS_PDU_MAX_ARTICULATIONS 16
+
+#endif /* packet-dis-pduparsers.h */
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();
+}