/* packet-dis-fields.c * Routines and definitions for DIS field parsing. * Copyright 2005, Scientific Research Corporation * Initial implementation by Jeremy Ouellette * * $Id$ * * Wireshark - Network traffic analyzer * By Gerald Combs * 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 "config.h" #include #include "packet-dis-fields.h" #include "packet-dis-enums.h" #include "packet-dis-pdus.h" /* all of these variables are assigned by reference */ /* *(parserNode.outputVar) = value */ guint32 disProtocolVersion; guint32 pduType; guint32 protocolFamily; guint32 persistentObjectPduType; guint32 entityKind; guint32 entityDomain; guint32 category; guint32 radioID; guint32 disRadioTransmitState; guint32 encodingScheme; guint32 numSamples; guint32 numFixed; guint32 numVariable; guint32 numBeams; guint32 numTrackJamTargets; guint32 numShafts; guint32 numApas; guint32 numUAEmitter; guint32 numUABeams; guint32 variableDatumLength; guint32 variableParameterType; guint32 variableRecordLength; guint32 variableRecordType; guint32 majorModulation; guint32 systemModulation; guint32 modulationParamLength; guint32 disAntennaPattern; /* Headers */ DIS_ParserNode DIS_FIELDS_PDU_HEADER[] = { { DIS_FIELDTYPE_PROTOCOL_VERSION, "Protocol Version",0,0,0,&disProtocolVersion }, { DIS_FIELDTYPE_EXERCISE_ID, "Exercise ID",0,0,0,0 }, { DIS_FIELDTYPE_PDU_TYPE, "PDU Type",0,0,0,&pduType }, { DIS_FIELDTYPE_PROTOCOL_FAMILY, "Protocol Family",0,0,0,&protocolFamily }, { DIS_FIELDTYPE_TIMESTAMP, "Timestamp",0,0,0,0 }, { DIS_FIELDTYPE_PDU_LENGTH, "Length",0,0,0,0 }, { DIS_FIELDTYPE_PAD16, "Padding",0,0,0,0 }, { DIS_FIELDTYPE_END, NULL,0,0,0,0 } }; DIS_ParserNode DIS_FIELDS_PERSISTENT_OBJECT_HEADER[] = { { DIS_FIELDTYPE_UINT8, "Protocol Version",0,0,0,0 }, { DIS_FIELDTYPE_PERSISTENT_OBJECT_TYPE, "PO PDU Type",0,0,0,&persistentObjectPduType }, { DIS_FIELDTYPE_UINT8, "Exercise ID",0,0,0,0 }, { DIS_FIELDTYPE_UINT8, "PO Database ID",0,0,0,0 }, { DIS_FIELDTYPE_UINT16, "Length",0,0,0,0 }, { DIS_FIELDTYPE_UINT16, "PDU Count",0,0,0,0 }, { DIS_FIELDTYPE_END, NULL,0,0,0,0 } }; /* Composite types */ DIS_ParserNode DIS_FIELDS_BURST_DESCRIPTOR[] = { { DIS_FIELDTYPE_ENTITY_TYPE, "Munition",0,0,0,0 }, { DIS_FIELDTYPE_WARHEAD, "Warhead",0,0,0,0 }, { DIS_FIELDTYPE_FUSE, "Fuse",0,0,0,0 }, { DIS_FIELDTYPE_UINT16, "Quantity",0,0,0,0 }, { DIS_FIELDTYPE_UINT16, "Rate",0,0,0,0 }, { DIS_FIELDTYPE_END, NULL,0,0,0,0 } }; DIS_ParserNode DIS_FIELDS_CLOCK_TIME[] = { { DIS_FIELDTYPE_UINT32, "Hour",0,0,0,0 }, { DIS_FIELDTYPE_TIMESTAMP, "Time Past The Hour",0,0,0,0 }, { DIS_FIELDTYPE_END, NULL,0,0,0,0 } }; DIS_ParserNode DIS_FIELDS_ENTITY_ID[] = { { DIS_FIELDTYPE_SITE, "Site",0,0,0,0 }, { DIS_FIELDTYPE_APPLICATION, "Application",0,0,0,0 }, { DIS_FIELDTYPE_ENTITY, "Entity",0,0,0,0 }, { DIS_FIELDTYPE_END, NULL,0,0,0,0 } }; DIS_ParserNode DIS_FIELDS_ENTITY_TYPE[] = { { DIS_FIELDTYPE_ENTITY_KIND, "Entity Kind",0,0,0,&entityKind }, { DIS_FIELDTYPE_DOMAIN, "Domain",0,0,0,&entityDomain }, { DIS_FIELDTYPE_COUNTRY, "Country",0,0,0,0 }, { DIS_FIELDTYPE_CATEGORY, "Category",0,0,0,&category }, { DIS_FIELDTYPE_SUBCATEGORY, "Subcategory",0,0,0,0 }, { DIS_FIELDTYPE_SPECIFIC, "Specific",0,0,0,0 }, { DIS_FIELDTYPE_EXTRA, "Extra",0,0,0,0 }, { DIS_FIELDTYPE_END, NULL,0,0,0,0 } }; DIS_ParserNode DIS_FIELDS_RADIO_ENTITY_TYPE[] = { { DIS_FIELDTYPE_ENTITY_KIND, "Entity Kind",0,0,0,&entityKind }, { DIS_FIELDTYPE_DOMAIN, "Domain",0,0,0,&entityDomain }, { DIS_FIELDTYPE_COUNTRY, "Country",0,0,0,0 }, { DIS_FIELDTYPE_RADIO_CATEGORY, "Radio Category",0,0,0,&category }, { DIS_FIELDTYPE_NOMENCLATURE_VERSION, "Nomenclature Version",0,0,0,0 }, { DIS_FIELDTYPE_NOMENCLATURE, "Nomenclature",0,0,0,0 }, { DIS_FIELDTYPE_END, NULL,0,0,0,0 } }; DIS_ParserNode DIS_FIELDS_MODULATION_TYPE[] = { { DIS_FIELDTYPE_SPREAD_SPECTRUM, "Spread Spectrum",0,0,0,0 }, { DIS_FIELDTYPE_MODULATION_MAJOR, "Major",0,0,0,&majorModulation }, { DIS_FIELDTYPE_MODULATION_DETAIL, "Detail",0,0,0,0 }, { DIS_FIELDTYPE_MODULATION_SYSTEM, "System",0,0,0,&systemModulation }, { DIS_FIELDTYPE_END, NULL,0,0,0,0 } }; DIS_ParserNode DIS_FIELDS_EVENT_ID[] = { { DIS_FIELDTYPE_UINT16, "Site",0,0,0,0 }, { DIS_FIELDTYPE_UINT16, "Application",0,0,0,0 }, { DIS_FIELDTYPE_UINT16, "Event Number",0,0,0,0 }, { DIS_FIELDTYPE_END, NULL,0,0,0,0 } }; DIS_ParserNode DIS_FIELDS_ORIENTATION[] = { { DIS_FIELDTYPE_FLOAT32, "Psi",0,0,0,0 }, { DIS_FIELDTYPE_FLOAT32, "Theta",0,0,0,0 }, { DIS_FIELDTYPE_FLOAT32, "Phi",0,0,0,0 }, { DIS_FIELDTYPE_END, NULL,0,0,0,0 } }; DIS_ParserNode DIS_FIELDS_SIMULATION_ADDRESS[] = { { DIS_FIELDTYPE_UINT16, "Site",0,0,0,0 }, { DIS_FIELDTYPE_UINT16, "Application",0,0,0,0 }, { DIS_FIELDTYPE_END, NULL,0,0,0,0 } }; DIS_ParserNode DIS_FIELDS_VECTOR_FLOAT_32[] = { { DIS_FIELDTYPE_FLOAT32, "X",0,0,0,0 }, { DIS_FIELDTYPE_FLOAT32, "Y",0,0,0,0 }, { DIS_FIELDTYPE_FLOAT32, "Z",0,0,0,0 }, { DIS_FIELDTYPE_END, NULL,0,0,0,0 } }; DIS_ParserNode DIS_FIELDS_VECTOR_FLOAT_64[] = { { DIS_FIELDTYPE_FLOAT64, "X",0,0,0,0 }, { DIS_FIELDTYPE_FLOAT64, "Y",0,0,0,0 }, { DIS_FIELDTYPE_FLOAT64, "Z",0,0,0,0 }, { DIS_FIELDTYPE_END, NULL,0,0,0,0 } }; DIS_ParserNode DIS_FIELDS_MOD_PARAMS_CCTT_SINCGARS[] = { { DIS_FIELDTYPE_FH_NETWORK_ID, "Frequency Hopping Network ID",0,0,0,0 }, { DIS_FIELDTYPE_FH_SET_ID, "Frequency Set ID",0,0,0,0 }, { DIS_FIELDTYPE_LO_SET_ID, "Lockout Set ID",0,0,0,0 }, { DIS_FIELDTYPE_FH_MSG_START, "Frequency Hopping Message Start",0,0,0,0 }, { DIS_FIELDTYPE_RESERVED, "Reserved",0,0,0,0 }, { DIS_FIELDTYPE_FH_SYNC_TIME_OFFSET, "FH Synchronization Time Offset",0,0,0,0 }, { DIS_FIELDTYPE_FH_SECURITY_KEY, "Transmission Security Key",0,0,0,0 }, { DIS_FIELDTYPE_FH_CLEAR_CHANNEL, "Clear Channel",0,0,0,0 }, { DIS_FIELDTYPE_PAD8, "Padding",0,0,0,0 }, { DIS_FIELDTYPE_END, NULL,0,0,0,0 } }; DIS_ParserNode DIS_FIELDS_MOD_PARAMS_JTIDS_MIDS[] = { { DIS_FIELDTYPE_TS_ALLOCATION_MODE, "Time Slot Allocaton Mode",0,0,0,0 }, { DIS_FIELDTYPE_TRANSMITTER_PRIMARY_MODE, "Transmitter Primary Mode",0,0,0,0 }, { DIS_FIELDTYPE_TRANSMITTER_SECONDARY_MODE, "Transmitter Secondary Mode",0,0,0,0 }, { DIS_FIELDTYPE_JTIDS_SYNC_STATE, "Synchronization State",0,0,0,0 }, { DIS_FIELDTYPE_NETWORK_SYNC_ID, "Network Sync ID",0,0,0,0 }, { DIS_FIELDTYPE_END, NULL,0,0,0,0 } }; /* Array records */ DIS_ParserNode DIS_FIELDS_FIXED_DATUM[] = { { DIS_FIELDTYPE_DATUM_ID, "Datum ID",0,0,0,0 }, { DIS_FIELDTYPE_FIXED_DATUM_VALUE, "Datum value",0,0,0,0 }, { DIS_FIELDTYPE_END, NULL,0,0,0,0 } }; DIS_ParserNode DIS_FIELDS_VARIABLE_DATUM[] = { { DIS_FIELDTYPE_DATUM_ID, "Datum ID",0,0,0,0 }, { DIS_FIELDTYPE_DATUM_LENGTH, "Datum length",0,0,0,&variableDatumLength }, { DIS_FIELDTYPE_VARIABLE_DATUM_VALUE, "Datum value",0,0,0,0 }, { DIS_FIELDTYPE_END, NULL,0,0,0,0 } }; DIS_ParserNode DIS_FIELDS_DATUM_IDS[] = { { DIS_FIELDTYPE_DATUM_ID, "Datum ID",0,0,0,0 }, { DIS_FIELDTYPE_END, NULL,0,0,0,0 } }; DIS_ParserNode DIS_FIELDS_EMITTER_SYSTEM[] = { { DIS_FIELDTYPE_EMITTER_NAME, "Emitter Name",0,0,0,0 }, { DIS_FIELDTYPE_EMISSION_FUNCTION, "Function",0,0,0,0 }, { DIS_FIELDTYPE_UINT8, "Emitter ID Number",0,0,0,0 }, { DIS_FIELDTYPE_END, NULL,0,0,0,0 } }; DIS_ParserNode DIS_FIELDS_VR_UA_SHAFT[] = { { DIS_FIELDTYPE_INT16, "Current Shaft RPM",0,0,0,0 }, { DIS_FIELDTYPE_INT16, "Ordered Shaft RPM",0,0,0,0 }, { DIS_FIELDTYPE_INT32, "Shaft RPM Rate of Change",0,0,0,0 }, { DIS_FIELDTYPE_END, NULL,0,0,0,0 } }; DIS_ParserNode DIS_FIELDS_VR_APA[] = { { DIS_FIELDTYPE_INT16, "Parameter Index",0,0,0,0 }, /*FIXME enum*/ { DIS_FIELDTYPE_INT16, "Value", 0,0,0,0 }, { DIS_FIELDTYPE_END, NULL,0,0,0,0 } }; DIS_ParserNode DIS_FIELDS_UA_EMITTER_SYSTEM[] = { { DIS_FIELDTYPE_UINT16, "Acoustic Emitter Name",0,0,0,0 }, /*FIXME enum*/ { DIS_FIELDTYPE_UINT8, "Function",0,0,0,0 }, /*FIXME enum*/ { DIS_FIELDTYPE_UINT8, "Acoustic ID Number",0,0,0,0 }, { DIS_FIELDTYPE_END, NULL,0,0,0,0 } }; DIS_ParserNode DIS_FIELDS_FUNDAMENTAL_PARAMETER_DATA[] = { { DIS_FIELDTYPE_FLOAT32, "Frequency",0,0,0,0 }, { DIS_FIELDTYPE_FLOAT32, "Frequency Range",0,0,0,0 }, { DIS_FIELDTYPE_FLOAT32, "Effective Radiated Power",0,0,0,0 }, { DIS_FIELDTYPE_FLOAT32, "Pulse Repetition Frequency",0,0,0,0 }, { DIS_FIELDTYPE_FLOAT32, "Pulse Width",0,0,0,0 }, { DIS_FIELDTYPE_FLOAT32, "Beam Azimuth Center",0,0,0,0 }, { DIS_FIELDTYPE_FLOAT32, "Beam Azimuth Sweep",0,0,0,0 }, { DIS_FIELDTYPE_FLOAT32, "Beam Elevation Center",0,0,0,0 }, { DIS_FIELDTYPE_FLOAT32, "Beam Elevation Sweep",0,0,0,0 }, { DIS_FIELDTYPE_FLOAT32, "Beam Sweep Sync",0,0,0,0 }, { DIS_FIELDTYPE_END, NULL,0,0,0,0 } }; DIS_ParserNode DIS_FIELDS_TRACK_JAM[] = { { DIS_FIELDTYPE_SITE, "Site",0,0,0,0 }, { DIS_FIELDTYPE_APPLICATION, "Application",0,0,0,0 }, { DIS_FIELDTYPE_ENTITY, "Entity",0,0,0,0 }, { DIS_FIELDTYPE_UINT8, "Emitter ID",0,0,0,0 }, { DIS_FIELDTYPE_UINT8, "Beam ID",0,0,0,0 }, { DIS_FIELDTYPE_END, NULL,0,0,0,0 } }; /* Variable Parameters */ DIS_ParserNode DIS_FIELDS_VP_TYPE[] = { { DIS_FIELDTYPE_PARAMETER_TYPE_DESIGNATOR, "Variable Parameter Type",0,0,0,&variableParameterType }, { DIS_FIELDTYPE_END, NULL,0,0,0,0 } }; /* Array record contents - variable parameter records */ DIS_ParserNode DIS_FIELDS_VP_GENERIC[] = { { DIS_FIELDTYPE_FIXED_LEN_STR, "Data",15,0,0,0 }, { DIS_FIELDTYPE_END, NULL,0,0,0,0 } }; DIS_ParserNode DIS_FIELDS_VP_ARTICULATED_PART[] = { { DIS_FIELDTYPE_UINT8, "Change",0,0,0,0 }, { DIS_FIELDTYPE_UINT16, "Part Attached To ID",0,0,0,0 }, { DIS_FIELDTYPE_ARTIC_PARAM_TYPE, "Parameter Type",0,0,0,0 }, { DIS_FIELDTYPE_UINT64, "Parameter Value",0,0,0,0 }, { DIS_FIELDTYPE_END, NULL,0,0,0,0 } }; DIS_ParserNode DIS_FIELDS_VP_ATTACHED_PART[] = { { DIS_FIELDTYPE_UINT8, "Attached Indicator",0,0,0,0 }, { DIS_FIELDTYPE_UINT16, "Part Attached To ID",0,0,0,0 }, { DIS_FIELDTYPE_ARTIC_PARAM_TYPE, "Parameter Type",0,0,0,0 }, { DIS_FIELDTYPE_ENTITY_TYPE, "Part Type",0,0,0,0 }, { DIS_FIELDTYPE_END, NULL,0,0,0,0 } }; DIS_ParserNode DIS_FIELDS_VP_ENTITY_OFFSET[] = { { DIS_FIELDTYPE_UINT8, "Offset Type",0,0,0,0 }, { DIS_FIELDTYPE_PAD8, "Padding",2,0,0,0 }, { DIS_FIELDTYPE_VECTOR_32, "Offset",0,0,0,0 }, { DIS_FIELDTYPE_END, NULL,0,0,0,0 } }; DIS_ParserNode DIS_FIELDS_VP_ENTITY_ASSOCIATION[] = { { DIS_FIELDTYPE_UINT8, "Change Indicator",0,0,0,0 }, { DIS_FIELDTYPE_UINT8, "Association Status",0,0,0,0 }, { DIS_FIELDTYPE_UINT8, "Association Type",0,0,0,0 }, { DIS_FIELDTYPE_ENTITY_ID, "Object Identifier",2,0,0,0 }, { DIS_FIELDTYPE_UINT16, "Own Station Location",0,0,0,0 }, { DIS_FIELDTYPE_UINT8, "Physical Connection Type",0,0,0,0 }, { DIS_FIELDTYPE_UINT8, "Group Member Type",0,0,0,0 }, { DIS_FIELDTYPE_UINT16, "Group Number",0,0,0,0 }, { DIS_FIELDTYPE_END, NULL,0,0,0,0 } }; /* Variable Records */ DIS_ParserNode DIS_FIELDS_VR_TYPE[] = { { DIS_FIELDTYPE_UINT32, "Record Type",0,0,0,&variableRecordType }, { DIS_FIELDTYPE_UINT16, "Record Length",0,0,0,&variableRecordLength }, { DIS_FIELDTYPE_END, NULL,0,0,0,0 } }; DIS_ParserNode DIS_FIELDS_VR_APPLICATION_HEALTH_STATUS[] = { { DIS_FIELDTYPE_PAD8, "Padding",2,0,0,0 }, { DIS_FIELDTYPE_APPLICATION_STATUS_TYPE, "Status Type",0,0,0,0 }, { DIS_FIELDTYPE_APPLICATION_GENERAL_STATUS, "General Status",0,0,0,0 }, { DIS_FIELDTYPE_UINT8, "Specific Status",0,0,0,0 }, { DIS_FIELDTYPE_INT32, "Status Value Int",0,0,0,0 }, { DIS_FIELDTYPE_FLOAT64, "Status Value Float",0,0,0,0 }, { DIS_FIELDTYPE_END, NULL,0,0,0,0 } }; DIS_ParserNode DIS_FIELDS_VR_APPLICATION_INITIALIZATION[] = { { DIS_FIELDTYPE_UINT8, "Exercise ID",0,0,0,0 }, { DIS_FIELDTYPE_PAD8, "Padding",0,0,0,0 }, { DIS_FIELDTYPE_FIXED_LEN_STR, "Exercise File Path",256,0,0,0 }, { DIS_FIELDTYPE_FIXED_LEN_STR, "Exercise File Name",128,0,0,0 }, { DIS_FIELDTYPE_FIXED_LEN_STR, "Application Role",64,0,0,0 }, { DIS_FIELDTYPE_END, NULL,0,0,0,0 } }; DIS_ParserNode DIS_FIELDS_VR_DATA_QUERY[] = { { DIS_FIELDTYPE_UINT16, "Num Records",0,0,0,&numFixed }, { DIS_FIELDTYPE_FIXED_DATUM_IDS, "Record",0,0,0,0 }, { DIS_FIELDTYPE_END, NULL,0,0,0,0 } }; DIS_ParserNode DIS_FIELDS_VR_ELECTROMAGNETIC_EMISSION_SYSTEM_BEAM[] = { { DIS_FIELDTYPE_UINT8, "Beam Data Length",0,0,0,0 }, { DIS_FIELDTYPE_UINT8, "Beam ID Number",0,0,0,0 }, { DIS_FIELDTYPE_UINT16, "Beam Parameter Index",0,0,0,0 }, { DIS_FIELDTYPE_FUNDAMENTAL_PARAMETER_DATA, "Fundamental Parameter Data",0,0,0,0 }, { DIS_FIELDTYPE_BEAM_FUNCTION, "Beam Function",0,0,0,0 }, { DIS_FIELDTYPE_UINT8, "Number of Targets in Track/Jam Field",0,0,0,&numTrackJamTargets }, { DIS_FIELDTYPE_UINT8, "High Density Track/Jam",0,0,0,0 }, { DIS_FIELDTYPE_PAD8, "Padding",0,0,0,0 }, { DIS_FIELDTYPE_UINT32, "Jamming Mode Sequence",0,0,0,0 }, { DIS_FIELDTYPE_TRACK_JAM, "Track/Jam Entity",0,0,0,0 }, { DIS_FIELDTYPE_END, NULL,0,0,0,0 } }; DIS_ParserNode DIS_FIELDS_VR_ELECTROMAGNETIC_EMISSION_SYSTEM[] = { { DIS_FIELDTYPE_UINT8, "System Data Length",0,0,0,0 }, { DIS_FIELDTYPE_UINT8, "Number of Beams (M)",0,0,0,&numBeams }, { DIS_FIELDTYPE_PAD16, "Padding",0,0,0,0 }, { DIS_FIELDTYPE_EMITTER_SYSTEM, "Emitter System",0,0,0,0 }, { DIS_FIELDTYPE_VECTOR_32, "Location",0,0,0,0 }, { DIS_FIELDTYPE_ELECTROMAGNETIC_EMISSION_SYSTEM_BEAM, "Beam",0,0,0,0 }, { DIS_FIELDTYPE_END, NULL,0,0,0,0 } }; DIS_ParserNode DIS_FIELDS_UA_BEAM_FUNDAMENTAL_PARAMETER_DATA[] = { { DIS_FIELDTYPE_UINT16, "Active Emission Parameter Index",0,0,0,0 }, /*FIXME enum!!!*/ { DIS_FIELDTYPE_UINT16, "Scan Pattern",0,0,0,0 }, /*FIXME enum!!!*/ { DIS_FIELDTYPE_FLOAT32, "Beam Center Azimuth (Horizontal Bearing)",0,0,0,0 }, { DIS_FIELDTYPE_FLOAT32, "Azimuthal Beamwidth (Horizontal Beamwidth)",0,0,0,0 }, { DIS_FIELDTYPE_FLOAT32, "Beam Center D/E",0,0,0,0 }, { DIS_FIELDTYPE_FLOAT32, "D/E Beamwidth (Vertical Beamwidth)",0,0,0,0 }, { DIS_FIELDTYPE_END, NULL,0,0,0,0 } }; DIS_ParserNode DIS_FIELDS_VR_UA_BEAM[] = { { DIS_FIELDTYPE_UINT8, "Beam Data Length",0,0,0,0 }, { DIS_FIELDTYPE_UINT8, "Beam ID Number",0,0,0,0 }, { DIS_FIELDTYPE_PAD16, "Padding",0,0,0,0 }, { DIS_FIELDTYPE_UA_BEAM_FUNDAMENTAL_PARAMETER_DATA, "Fundamental Data Parameters",0,0,0,0 }, { DIS_FIELDTYPE_END, NULL,0,0,0,0 } }; DIS_ParserNode DIS_FIELDS_VR_UA_EMITTER_SYSTEM[] = { { DIS_FIELDTYPE_UINT8, "Emitter System Data Length",0,0,0,0 }, { DIS_FIELDTYPE_NUM_OF_UA_EMITTER_SYSTEM_BEAMS, "Number of Beams (m)",0,0,0,0 }, { DIS_FIELDTYPE_PAD16, "Padding",0,0,0,0 }, { DIS_FIELDTYPE_UA_EMITTER_SYSTEM, "Acoustic Emitter System",0,0,0,0 }, { DIS_FIELDTYPE_VECTOR_32, "Location (with respect to entity)",0,0,0,0 }, { DIS_FIELDTYPE_END, NULL,0,0,0,0 } }; /* Bit fields */ DIS_ParserNode DIS_FIELDS_NONE[] = { { DIS_FIELDTYPE_END, NULL, 0,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 } } } }; /* Initialize the field parsers that are not explicitly included in any * specific PDU. These fields are only accessed and used if a variant * field indicates they are to be used. */ void initializeFieldParsers(void) { initializeParser(DIS_FIELDS_VP_GENERIC); initializeParser(DIS_FIELDS_VP_ARTICULATED_PART); initializeParser(DIS_FIELDS_VP_ATTACHED_PART); initializeParser(DIS_FIELDS_VP_ENTITY_OFFSET); initializeParser(DIS_FIELDS_VP_ENTITY_ASSOCIATION); initializeParser(DIS_FIELDS_VR_APPLICATION_HEALTH_STATUS); initializeParser(DIS_FIELDS_VR_APPLICATION_INITIALIZATION); initializeParser(DIS_FIELDS_VR_DATA_QUERY); initializeParser(DIS_FIELDS_VR_ELECTROMAGNETIC_EMISSION_SYSTEM_BEAM); initializeParser(DIS_FIELDS_VR_ELECTROMAGNETIC_EMISSION_SYSTEM); initializeParser(DIS_FIELDS_VR_UA_SHAFT); initializeParser(DIS_FIELDS_VR_UA_EMITTER_SYSTEM); initializeParser(DIS_FIELDS_VR_UA_BEAM); initializeParser(DIS_FIELDS_MOD_PARAMS_CCTT_SINCGARS); initializeParser(DIS_FIELDS_MOD_PARAMS_JTIDS_MIDS); } /* Adjust an offset variable for proper alignment for a specified field length. */ static 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 (%" G_GINT64_MODIFIER "u)", 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 = %" G_GINT64_MODIFIER "u", 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) { gint64 intVal = 0; offset = alignOffset(offset, numBytes); switch(numBytes) { case 1: intVal = (gint8)tvb_get_guint8(tvb, offset); break; case 2: intVal = (gint16)tvb_get_ntohs(tvb, offset); break; case 4: intVal = (gint32)tvb_get_ntohl(tvb, offset); break; case 8: intVal = (gint64)tvb_get_ntoh64(tvb, offset); break; default: /* assert */ break; } proto_tree_add_text(tree, tvb, offset, numBytes, "%s = %" G_GINT64_MODIFIER "d", parserNode.fieldLabel, intVal); 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 _U_, 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; #if 0 proto_item *pi; #endif int dis_hf_id = -1; offset = alignOffset(offset, numBytes); switch(parserNode.fieldType) { case DIS_FIELDTYPE_ACKNOWLEDGE_FLAG: enumStrings = DIS_PDU_AcknowledgeFlag_Strings; break; case DIS_FIELDTYPE_ACTION_ID: enumStrings = DIS_PDU_ActionId_Strings; break; case DIS_FIELDTYPE_APPLICATION_GENERAL_STATUS: enumStrings = DIS_PDU_ApplicationGeneralStatus_Strings; break; case DIS_FIELDTYPE_APPLICATION_STATUS_TYPE: enumStrings = DIS_PDU_ApplicationStatusType_Strings; break; case DIS_FIELDTYPE_APPLICATION_TYPE: enumStrings = DIS_PDU_ApplicationType_Strings; break; case DIS_FIELDTYPE_CONTROL_ID: enumStrings = DIS_PDU_ControlId_Strings; break; case DIS_FIELDTYPE_PROTOCOL_VERSION: enumStrings = DIS_PDU_ProtocolVersion_Strings; dis_hf_id = hf_dis_proto_ver; break; case DIS_FIELDTYPE_PROTOCOL_FAMILY: enumStrings = DIS_PDU_ProtocolFamily_Strings; dis_hf_id = hf_dis_proto_fam; break; case DIS_FIELDTYPE_PDU_TYPE: enumStrings = DIS_PDU_Type_Strings; dis_hf_id = hf_dis_pdu_type; break; case DIS_FIELDTYPE_ENTITY_KIND: enumStrings = DIS_PDU_EntityKind_Strings; dis_hf_id = hf_dis_entityKind; break; case DIS_FIELDTYPE_DOMAIN: enumStrings = DIS_PDU_Domain_Strings; dis_hf_id = hf_dis_entityDomain; break; case DIS_FIELDTYPE_DETONATION_RESULT: enumStrings = DIS_PDU_DetonationResult_Strings; break; case DIS_FIELDTYPE_FROZEN_BEHAVIOR: enumStrings = DIS_PDU_FrozenBehavior_Strings; break; case DIS_FIELDTYPE_RADIO_CATEGORY: enumStrings = DIS_PDU_RadioCategory_Strings; dis_hf_id = hf_dis_category_radio; break; case DIS_FIELDTYPE_NOMENCLATURE_VERSION: enumStrings = DIS_PDU_NomenclatureVersion_Strings; break; case DIS_FIELDTYPE_NOMENCLATURE: enumStrings = DIS_PDU_Nomenclature_Strings; break; case DIS_FIELDTYPE_CATEGORY: if (entityKind == DIS_ENTITYKIND_PLATFORM) { switch(entityDomain) { case DIS_DOMAIN_LAND: enumStrings = DIS_PDU_Category_LandPlatform_Strings; dis_hf_id = hf_dis_category_land; break; case DIS_DOMAIN_AIR: enumStrings = DIS_PDU_Category_AirPlatform_Strings; dis_hf_id = hf_dis_category_air; break; case DIS_DOMAIN_SURFACE: enumStrings = DIS_PDU_Category_SurfacePlatform_Strings; dis_hf_id = hf_dis_category_surface; break; case DIS_DOMAIN_SUBSURFACE: enumStrings = DIS_PDU_Category_SubsurfacePlatform_Strings; dis_hf_id = hf_dis_category_subsurface; break; case DIS_DOMAIN_SPACE: enumStrings = DIS_PDU_Category_SpacePlatform_Strings; dis_hf_id = hf_dis_category_space; break; default: enumStrings = 0; break; } } break; case DIS_FIELDTYPE_EMITTER_NAME: enumStrings = DIS_PDU_EmitterName_Strings; dis_hf_id = hf_dis_emitter_name; break; case DIS_FIELDTYPE_EMISSION_FUNCTION: enumStrings = DIS_PDU_EmissionFunction_Strings; dis_hf_id = hf_dis_emission_function; break; case DIS_FIELDTYPE_BEAM_FUNCTION: enumStrings = DIS_PDU_BeamFunction_Strings; dis_hf_id = hf_dis_beam_function; break; case DIS_FIELDTYPE_PARAMETER_TYPE_DESIGNATOR: enumStrings = DIS_PDU_ParameterTypeDesignator_Strings; break; case DIS_FIELDTYPE_PERSISTENT_OBJECT_TYPE: enumStrings = DIS_PDU_PersistentObjectType_Strings; break; case DIS_FIELDTYPE_PERSISTENT_OBJECT_CLASS: enumStrings = DIS_PDU_PO_ObjectClass_Strings; break; case DIS_FIELDTYPE_REASON: enumStrings = DIS_PDU_Reason_Strings; break; case DIS_FIELDTYPE_REQUEST_STATUS: enumStrings = DIS_PDU_RequestStatus_Strings; break; case DIS_FIELDTYPE_REQUIRED_RELIABILITY_SERVICE: enumStrings = DIS_PDU_RequiredReliabilityService_Strings; break; case DIS_FIELDTYPE_RESPONSE_FLAG: enumStrings = DIS_PDU_DisResponseFlag_Strings; break; case DIS_FIELDTYPE_MODULATION_DETAIL: switch (majorModulation) { case DIS_MAJOR_MOD_AMPLITUDE: enumStrings = DIS_PDU_DetailModulationAmplitude_Strings; break; case DIS_MAJOR_MOD_AMPLITUDE_AND_ANGLE: enumStrings = DIS_PDU_DetailModulationAmpAndAngle_Strings; break; case DIS_MAJOR_MOD_ANGLE: enumStrings = DIS_PDU_DetailModulationAngle_Strings; break; case DIS_MAJOR_MOD_COMBINATION: enumStrings = DIS_PDU_DetailModulationCombination_Strings; break; case DIS_MAJOR_MOD_PULSE: enumStrings = DIS_PDU_DetailModulationPulse_Strings; break; case DIS_MAJOR_MOD_UNMODULATED: enumStrings = DIS_PDU_DetailModulationUnmodulated_Strings; break; case DIS_MAJOR_MOD_CPSM: /* CPSM only has "other" defined */ case DIS_MAJOR_MOD_OTHER: default: enumStrings = DIS_PDU_DetailModulationCPSM_Strings; 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; } enumStr = val_to_str(enumVal, enumStrings, "Unknown Enumeration (%d)"); if (dis_hf_id != -1) { #if 0 pi = proto_tree_add_item(tree, dis_hf_id, tvb, offset, numBytes, ENC_BIG_ENDIAN); proto_item_set_text(pi, "%s = %s", parserNode.fieldLabel, enumStr); #else proto_tree_add_item(tree, dis_hf_id, tvb, offset, numBytes, ENC_BIG_ENDIAN); #endif } else { 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; } #if 0 /* Parse a 4-byte floating-point value, given text label. */ static gint parseField_Float_Text(tvbuff_t *tvb, proto_tree *tree, gint offset, gchar *charStr) { gfloat floatVal; offset = alignOffset(offset, 4); floatVal = tvb_get_ntohieee_float(tvb, offset); proto_tree_add_text(tree, tvb, offset, 4, "%s = %f", charStr, floatVal); offset += 4; return offset; } #endif /* 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 = %f", parserNode.fieldLabel, doubleVal); offset += 8; return offset; } /* Parse the Timestamp */ gint parseField_Timestamp(tvbuff_t *tvb, proto_tree *tree, gint offset, DIS_ParserNode parserNode) { /* some consts */ static double MSEC_PER_SECOND = 1000.0; static double MSEC_PER_MINUTE = 60.0 * 1000.0 ; static double MSEC_PER_HOUR = 60.0 * 60.0 * 1000.0; static double FSV = 0x7fffffff; /* variables */ guint isAbsolute = 0; guint32 uintVal; guint minutes; guint seconds; guint milliseconds; double ms; offset = alignOffset(offset, 4); /* convert to host value */ uintVal = tvb_get_ntohl(tvb, offset); /* determine absolute vis sim time */ if( uintVal & 1 ) isAbsolute = 1; /* convert TS to MS */ ms = (uintVal >> 1) * MSEC_PER_HOUR / FSV; ms += 0.5; /* calc minutes and reduce ms */ minutes = (guint) (ms / MSEC_PER_MINUTE); ms -= (minutes * MSEC_PER_MINUTE); /* calc seconds and reduce ms */ seconds = (guint) (ms / MSEC_PER_SECOND); ms -= (seconds * MSEC_PER_SECOND); /* truncate milliseconds */ milliseconds = (guint) ms; /* push out the values */ if( isAbsolute ) { proto_tree_add_text(tree, tvb, offset, 4, "%s = %02d:%02d %03d absolute (UTM)", parserNode.fieldLabel, minutes, seconds, milliseconds); } else { proto_tree_add_text(tree, tvb, offset, 4, "%s = %02d:%02d %03d relative", parserNode.fieldLabel, minutes, seconds, milliseconds); } offset += 4; return offset; } /* Parse a variable parameter field. */ gint parseField_VariableParameter(tvbuff_t *tvb, proto_tree *tree, gint offset) { DIS_ParserNode *paramParser = 0; /* Determine the parser to use based on the type */ switch (variableParameterType) { case DIS_PARAM_TYPE_DESIG_ARTICULATED_PART: paramParser = DIS_FIELDS_VP_ARTICULATED_PART; break; case DIS_PARAM_TYPE_DESIG_ATTACHED_PART: paramParser = DIS_FIELDS_VP_ATTACHED_PART; break; case DIS_PARAM_TYPE_DESIG_ENTITY_OFFSET: paramParser = DIS_FIELDS_VP_ENTITY_OFFSET; break; case DIS_PARAM_TYPE_DESIG_ENTITY_ASSOCIATION: paramParser = DIS_FIELDS_VP_ENTITY_ASSOCIATION; break; default: paramParser = DIS_FIELDS_VP_GENERIC; break; } /* Parse the variable parameter fields */ if (paramParser) { offset = parseFields(tvb, tree, offset, paramParser); } return offset; } /* Parse a variable record field. */ gint parseField_VariableRecord(tvbuff_t *tvb, proto_tree *tree, gint offset) { DIS_ParserNode *paramParser = 0; /* Determine the parser to use based on the type */ switch (variableRecordType) { case 47200: paramParser = DIS_FIELDS_VR_APPLICATION_HEALTH_STATUS; break; case 47300: paramParser = DIS_FIELDS_VR_APPLICATION_INITIALIZATION; break; case 47600: paramParser = DIS_FIELDS_VR_DATA_QUERY; break; default: { guint32 dataLength = variableRecordLength - 6; if (dataLength > 0) { proto_tree_add_text(tree, tvb, offset, dataLength, "Record Data (%d bytes)", dataLength); offset += dataLength; } } break; } /* Parse the variable record fields */ if (paramParser) { offset = parseFields(tvb, tree, offset, paramParser); } /* Should alignment padding be added */ if (variableRecordLength % 8) { guint32 alignmentPadding = (8 - (variableRecordLength % 8)); proto_tree_add_text(tree, tvb, offset, alignmentPadding, "Alignment Padding (%d bytes)", alignmentPadding); offset += alignmentPadding; } return offset; } /* Parse a variable electromagnetic emission system beam. */ gint parseField_ElectromagneticEmissionSystemBeam( tvbuff_t *tvb, proto_tree *tree, gint offset) { DIS_ParserNode *paramParser = 0; /* Determine the parser to use based on the PDU type */ if (pduType == DIS_PDUTYPE_ELECTROMAGNETIC_EMISSION) paramParser = DIS_FIELDS_VR_ELECTROMAGNETIC_EMISSION_SYSTEM_BEAM; /* Parse the variable parameter fields */ if (paramParser) { offset = parseFields(tvb, tree, offset, paramParser); } return offset; }