2 * Routines and definitions for DIS PDU parsing.
3 * Copyright 2005, Scientific Research Corporation
4 * Initial implementation by Jeremy Ouellette <jouellet@scires.com>
8 * Wireshark - Network traffic analyzer
9 * By Gerald Combs <gerald@wireshark.org>
10 * Copyright 1998 Gerald Combs
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
32 #include "packet-dis-pdus.h"
33 #include "packet-dis-fields.h"
34 #include "packet-dis-enums.h"
36 #define DIS_PDU_MAX_VARIABLE_PARAMETERS 16
37 #define DIS_PDU_MAX_VARIABLE_RECORDS 16
38 #define DIS_PDU_MAX_ELECTROMAGNETIC_EMISSION_SYSTEMS 16
41 gint ettVariableParameters[DIS_PDU_MAX_VARIABLE_PARAMETERS];
42 gint ettVariableRecords[DIS_PDU_MAX_VARIABLE_RECORDS];
44 gint ettFixedData = -1;
45 gint ettVariableData = -1;
47 /* DIS Entity Information / Interaction PDUs
49 DIS_ParserNode DIS_PARSER_ENTITY_STATE_PDU[] =
51 { DIS_FIELDTYPE_ENTITY_ID, "Entity ID",0,0,0,0 },
52 { DIS_FIELDTYPE_FORCE_ID, "Force ID",0,0,0,0 },
53 { DIS_FIELDTYPE_NUM_ARTICULATION_PARAMS, "Number of Articulation Parameters",0,0,0,&numVariable },
54 { DIS_FIELDTYPE_ENTITY_TYPE, "Entity Type",0,0,0,0 },
55 { DIS_FIELDTYPE_ENTITY_TYPE, "Alternative Entity Type",0,0,0,0 },
56 { DIS_FIELDTYPE_LINEAR_VELOCITY, "Entity Linear Velocity",0,0,0,0 },
57 { DIS_FIELDTYPE_LOCATION_WORLD, "Entity Location",0,0,0,0 },
58 { DIS_FIELDTYPE_ORIENTATION, "Entity Orientation",0,0,0,0 },
59 { DIS_FIELDTYPE_APPEARANCE, "Entity Appearance",0,0,0,0 },
60 { DIS_FIELDTYPE_DEAD_RECKONING_PARAMS, "Dead Reckoning Parameters",0,0,0,0 },
61 { DIS_FIELDTYPE_ENTITY_MARKING, "Entity Marking",0,0,0,0 },
62 { DIS_FIELDTYPE_CAPABILITIES, "Capabilities",0,0,0,0 },
63 { DIS_FIELDTYPE_VARIABLE_PARAMETERS, "Variable Parameter",0,0,0,0 },
64 { DIS_FIELDTYPE_END, NULL,0,0,0,0 }
67 /* DIS Distributed Emission Regeneration PDUs
69 DIS_ParserNode DIS_PARSER_ELECTROMAGNETIC_EMISSION_PDU[] =
71 { DIS_FIELDTYPE_ENTITY_ID, "Emitting Entity ID",0,0,0,0 },
72 { DIS_FIELDTYPE_ENTITY_ID, "Event ID",0,0,0,0 },
73 { DIS_FIELDTYPE_UINT8, "State Update Indicator",0,0,0,0 },
74 { DIS_FIELDTYPE_NUM_ELECTROMAGNETIC_EMISSION_SYSTEMS, "Number of Systems (N)",0,0,0,&numVariable },
75 { DIS_FIELDTYPE_PAD16, "Padding",0,0,0,0 },
76 { DIS_FIELDTYPE_ELECTROMAGNETIC_EMISSION_SYSTEM, "Emission System",0,0,0,0 },
77 { DIS_FIELDTYPE_END, NULL,0,0,0,0 }
81 /* DIS Radio Communications protocol (RCP) family PDUs
83 DIS_ParserNode DIS_PARSER_TRANSMITTER_PDU[] =
85 { DIS_FIELDTYPE_ENTITY_ID, "Entity ID",0,0,0,0 },
86 { DIS_FIELDTYPE_RADIO_ID, "Radio ID",0,0,0,&radioID },
87 { DIS_FIELDTYPE_RADIO_ENTITY_TYPE, "Radio Entity Type",0,0,0,0 },
88 { DIS_FIELDTYPE_RADIO_TRANSMIT_STATE, "Radio Transmit State",0,0,0,&disRadioTransmitState },
89 { DIS_FIELDTYPE_RADIO_INPUT_SOURCE, "Radio Input Source",0,0,0,0 },
90 { DIS_FIELDTYPE_PAD16, "Padding",0,0,0,0 },
91 { DIS_FIELDTYPE_ANTENNA_LOCATION, "Antenna Location",0,0,0,0 },
92 { DIS_FIELDTYPE_REL_ANTENNA_LOCATON, "Relative Antenna Location",0,0,0,0 },
93 { DIS_FIELDTYPE_ANTENNA_PATTERN_TYPE, "Antenna Pattern Type",0,0,0,&disAntennaPattern },
94 { DIS_FIELDTYPE_ANTENNA_PATTERN_LENGTH, "Antenna Pattern Length",0,0,0,0 },
95 { DIS_FIELDTYPE_TRANSMIT_FREQUENCY, "Transmit Frequency",0,0,0,0 },
96 { DIS_FIELDTYPE_FLOAT32, "Transmit Frequency Bandwidth",0,0,0,0 },
97 { DIS_FIELDTYPE_FLOAT32, "Transmit Power",0,0,0,0 },
98 { DIS_FIELDTYPE_MODULATION_TYPE, "Modulation Type",0,0,0,0 },
99 { DIS_FIELDTYPE_CRYPTO_SYSTEM, "Crypto System",0,0,0,0 },
100 { DIS_FIELDTYPE_CRYPTO_KEY_ID, "Crypto Key ID",0,0,0,0 },
101 { DIS_FIELDTYPE_MODULATION_PARAMETER_LENGTH, "Modulation Parameter Length",0,0,0,&modulationParamLength },
102 { DIS_FIELDTYPE_PAD24, "Padding",0,0,0,0 },
103 { DIS_FIELDTYPE_MODULATION_PARAMETERS, "Modulation Parameters",0,0,0,0 },
104 /* need to finish decoding this PDU */
105 { DIS_FIELDTYPE_END, NULL,0,0,0,0 }
108 DIS_ParserNode DIS_PARSER_SIGNAL_PDU[] =
110 { DIS_FIELDTYPE_ENTITY_ID, "Entity ID",0,0,0,0 },
111 { DIS_FIELDTYPE_RADIO_ID, "Radio ID",0,0,0,&radioID },
112 { DIS_FIELDTYPE_ENCODING_SCHEME, "Encoding Scheme",0,0,0,&encodingScheme },
113 { DIS_FIELDTYPE_TDL_TYPE, "TDL Type",0,0,0,0 },
114 { DIS_FIELDTYPE_SAMPLE_RATE, "Sample Rate",0,0,0,0 },
115 { DIS_FIELDTYPE_DATA_LENGTH, "Data Length",0,0,0,0 },
116 { DIS_FIELDTYPE_NUMBER_OF_SAMPLES, "Number of Samples",0,0,0,&numSamples },
117 { DIS_FIELDTYPE_RADIO_DATA, "Radio Data",0,0,0,0 },
118 { DIS_FIELDTYPE_END, NULL,0,0,0,0 }
123 DIS_ParserNode DIS_PARSER_FIRE_PDU[] =
125 { DIS_FIELDTYPE_ENTITY_ID, "Firing Entity ID",0,0,0,0 },
126 { DIS_FIELDTYPE_ENTITY_ID, "Target Entity ID",0,0,0,0 },
127 { DIS_FIELDTYPE_ENTITY_ID, "Munition ID",0,0,0,0 },
128 { DIS_FIELDTYPE_EVENT_ID, "Event ID",0,0,0,0 },
129 { DIS_FIELDTYPE_UINT32, "Fire Mission Index",0,0,0,0 },
130 { DIS_FIELDTYPE_LOCATION_WORLD, "Location in World Coordinates",0,0,0,0 },
131 { DIS_FIELDTYPE_BURST_DESCRIPTOR, "Burst Descriptor",0,0,0,0 },
132 { DIS_FIELDTYPE_LINEAR_VELOCITY, "Velocity",0,0,0,0 },
133 { DIS_FIELDTYPE_FLOAT32, "Range",0,0,0,0 },
134 { DIS_FIELDTYPE_END, NULL,0,0,0,0 }
137 DIS_ParserNode DIS_PARSER_DETONATION_PDU[] =
139 { DIS_FIELDTYPE_ENTITY_ID, "Firing Entity ID",0,0,0,0 },
140 { DIS_FIELDTYPE_ENTITY_ID, "Target Entity ID",0,0,0,0 },
141 { DIS_FIELDTYPE_ENTITY_ID, "Munition ID",0,0,0,0 },
142 { DIS_FIELDTYPE_EVENT_ID, "Event ID",0,0,0,0 },
143 { DIS_FIELDTYPE_LINEAR_VELOCITY, "Velocity",0,0,0,0 },
144 { DIS_FIELDTYPE_LOCATION_WORLD, "Location in World Coordinates",0,0,0,0 },
145 { DIS_FIELDTYPE_BURST_DESCRIPTOR, "Burst Descriptor",0,0,0,0 },
146 { DIS_FIELDTYPE_LOCATION_ENTITY, "Location in Entity Coordinates",0,0,0,0 },
147 { DIS_FIELDTYPE_DETONATION_RESULT, "Detonation Result",0,0,0,0 },
148 { DIS_FIELDTYPE_NUM_ARTICULATION_PARAMS, "Number of Articulation Parameters",0,0,0,&numVariable },
149 { DIS_FIELDTYPE_PAD16, "Padding",0,0,0,0 },
150 { DIS_FIELDTYPE_VARIABLE_PARAMETERS, "Variable Parameter",0,0,0,0 },
151 { DIS_FIELDTYPE_END, NULL,0,0,0,0 }
154 /* DIS Simulation Management PDUs
156 DIS_ParserNode DIS_PARSER_START_RESUME_PDU[] =
158 { DIS_FIELDTYPE_ENTITY_ID, "Originating Entity ID",0,0,0,0 },
159 { DIS_FIELDTYPE_ENTITY_ID, "Receiving Entity ID",0,0,0,0 },
160 { DIS_FIELDTYPE_CLOCK_TIME, "Real World Time",0,0,0,0 },
161 { DIS_FIELDTYPE_CLOCK_TIME, "Simulation Time",0,0,0,0 },
162 { DIS_FIELDTYPE_REQUEST_ID, "Request ID",0,0,0,0 },
163 { DIS_FIELDTYPE_END, NULL,0,0,0,0 }
166 DIS_ParserNode DIS_PARSER_STOP_FREEZE_PDU[] =
168 { DIS_FIELDTYPE_ENTITY_ID, "Originating Entity ID",0,0,0,0 },
169 { DIS_FIELDTYPE_ENTITY_ID, "Receiving Entity ID",0,0,0,0 },
170 { DIS_FIELDTYPE_CLOCK_TIME, "Real World Time",0,0,0,0 },
171 { DIS_FIELDTYPE_REASON, "Reason",0,0,0,0 },
172 { DIS_FIELDTYPE_FROZEN_BEHAVIOR, "Frozen Behavior",0,0,0,0 },
173 { DIS_FIELDTYPE_PAD16, "Padding",0,0,0,0 },
174 { DIS_FIELDTYPE_REQUEST_ID, "Request ID",0,0,0,0 },
175 { DIS_FIELDTYPE_END, NULL,0,0,0,0 }
178 DIS_ParserNode DIS_PARSER_ACKNOWLEDGE_PDU[] =
180 { DIS_FIELDTYPE_ENTITY_ID, "Originating Entity ID",0,0,0,0 },
181 { DIS_FIELDTYPE_ENTITY_ID, "Receiving Entity ID",0,0,0,0 },
182 { DIS_FIELDTYPE_ACKNOWLEDGE_FLAG, "Acknowledge Flag",0,0,0,0 },
183 { DIS_FIELDTYPE_RESPONSE_FLAG, "Response Flag",0,0,0,0 },
184 { DIS_FIELDTYPE_REQUEST_ID, "Request ID",0,0,0,0 },
185 { DIS_FIELDTYPE_END, NULL,0,0,0,0 }
188 DIS_ParserNode DIS_PARSER_ACTION_REQUEST_PDU[] =
190 { DIS_FIELDTYPE_ENTITY_ID, "Originating Entity ID",0,0,0,0 },
191 { DIS_FIELDTYPE_ENTITY_ID, "Receiving Entity ID",0,0,0,0 },
192 { DIS_FIELDTYPE_REQUEST_ID, "Request ID",0,0,0,0 },
193 { DIS_FIELDTYPE_ACTION_ID, "Action ID",0,0,0,0 },
194 { DIS_FIELDTYPE_NUM_FIXED_DATA, "Number of Fixed Data Fields",0,0,0,&numFixed },
195 { DIS_FIELDTYPE_NUM_VARIABLE_DATA, "Number of Variable Data Fields",0,0,0,&numVariable },
196 { DIS_FIELDTYPE_FIXED_DATUMS, "Fixed data",0,0,0,0 },
197 { DIS_FIELDTYPE_VARIABLE_DATUMS, "Variable data",0,0,0,0 },
198 { DIS_FIELDTYPE_END, NULL,0,0,0,0 }
201 DIS_ParserNode DIS_PARSER_ACTION_RESPONSE_PDU[] =
203 { DIS_FIELDTYPE_ENTITY_ID, "Originating Entity ID",0,0,0,0 },
204 { DIS_FIELDTYPE_ENTITY_ID, "Receiving Entity ID",0,0,0,0 },
205 { DIS_FIELDTYPE_REQUEST_ID, "Request ID",0,0,0,0 },
206 { DIS_FIELDTYPE_REQUEST_STATUS, "Request Status",0,0,0,0 },
207 { DIS_FIELDTYPE_NUM_FIXED_DATA, "Number of Fixed Data Fields",0,0,0,&numFixed },
208 { DIS_FIELDTYPE_NUM_VARIABLE_DATA, "Number of Variable Data Fields",0,0,0,&numVariable },
209 { DIS_FIELDTYPE_FIXED_DATUMS, "Fixed data",0,0,0,0 },
210 { DIS_FIELDTYPE_VARIABLE_DATUMS, "Variable data",0,0,0,0 },
211 { DIS_FIELDTYPE_END, NULL,0,0,0,0 }
214 DIS_ParserNode DIS_PARSER_DATA_PDU[] =
216 { DIS_FIELDTYPE_ENTITY_ID, "Originating Entity ID",0,0,0,0 },
217 { DIS_FIELDTYPE_ENTITY_ID, "Receiving Entity ID",0,0,0,0 },
218 { DIS_FIELDTYPE_REQUEST_ID, "Request ID",0,0,0,0 },
219 { DIS_FIELDTYPE_PAD32, "Padding",0,0,0,0 },
220 { DIS_FIELDTYPE_NUM_FIXED_DATA, "Number of Fixed Data Fields",0,0,0,&numFixed },
221 { DIS_FIELDTYPE_NUM_VARIABLE_DATA, "Number of Variable Data Fields",0,0,0,&numVariable },
222 { DIS_FIELDTYPE_FIXED_DATUMS, "Fixed data",0,0,0,0 },
223 { DIS_FIELDTYPE_VARIABLE_DATUMS, "Variable data",0,0,0,0 },
224 { DIS_FIELDTYPE_END, NULL,0,0,0,0 }
227 DIS_ParserNode DIS_PARSER_DATA_QUERY_PDU[] =
229 { DIS_FIELDTYPE_ENTITY_ID, "Originating Entity ID",0,0,0,0 },
230 { DIS_FIELDTYPE_ENTITY_ID, "Receiving Entity ID",0,0,0,0 },
231 { DIS_FIELDTYPE_REQUEST_ID, "Request ID",0,0,0,0 },
232 { DIS_FIELDTYPE_TIME_INTERVAL, "Time interval",0,0,0,0 },
233 { DIS_FIELDTYPE_NUM_FIXED_DATA, "Number of Fixed Datum Ids",0,0,0,&numFixed },
234 { DIS_FIELDTYPE_NUM_VARIABLE_DATA, "Number of Variable Datum Ids",0,0,0,&numVariable },
235 { DIS_FIELDTYPE_FIXED_DATUM_IDS, "Fixed datum ids",0,0,0,0 },
236 { DIS_FIELDTYPE_VARIABLE_DATUM_IDS, "Variable datum ids",0,0,0,0 },
237 { DIS_FIELDTYPE_END, NULL,0,0,0,0 }
240 DIS_ParserNode DIS_PARSER_COMMENT_PDU[] =
242 { DIS_FIELDTYPE_ENTITY_ID, "Originating Entity ID",0,0,0,0 },
243 { DIS_FIELDTYPE_ENTITY_ID, "Receiving Entity ID",0,0,0,0 },
244 { DIS_FIELDTYPE_NUM_FIXED_DATA, "Number of Fixed Data Fields",0,0,0,&numFixed },
245 { DIS_FIELDTYPE_NUM_VARIABLE_DATA, "Number of Variable Data Fields",0,0,0,&numVariable },
246 { DIS_FIELDTYPE_FIXED_DATUMS, "Fixed data",0,0,0,0 },
247 { DIS_FIELDTYPE_VARIABLE_DATUMS, "Variable data",0,0,0,0 },
248 { DIS_FIELDTYPE_END, NULL,0,0,0,0 }
251 DIS_ParserNode DIS_PARSER_SIMAN_ENTITY_PDU[] =
253 { DIS_FIELDTYPE_ENTITY_ID, "Originating Entity ID",0,0,0,0 },
254 { DIS_FIELDTYPE_ENTITY_ID, "Receiving Entity ID",0,0,0,0 },
255 { DIS_FIELDTYPE_REQUEST_ID, "Request ID",0,0,0,0 },
256 { DIS_FIELDTYPE_END, NULL,0,0,0,0 }
259 /* DIS Simulation Management with Reliability PDUs
261 DIS_ParserNode DIS_PARSER_START_RESUME_R_PDU[] =
263 { DIS_FIELDTYPE_ENTITY_ID, "Originating Entity ID",0,0,0,0 },
264 { DIS_FIELDTYPE_ENTITY_ID, "Receiving Entity ID",0,0,0,0 },
265 { DIS_FIELDTYPE_CLOCK_TIME, "Real World Time",0,0,0,0 },
266 { DIS_FIELDTYPE_CLOCK_TIME, "Simulation Time",0,0,0,0 },
267 { DIS_FIELDTYPE_REQUIRED_RELIABILITY_SERVICE, "Reliability",0,0,0,0 },
268 { DIS_FIELDTYPE_PAD8, "Padding",3,0,0,0 },
269 { DIS_FIELDTYPE_REQUEST_ID, "Request ID",0,0,0,0 },
270 { DIS_FIELDTYPE_END, NULL,0,0,0,0 }
273 DIS_ParserNode DIS_PARSER_STOP_FREEZE_R_PDU[] =
275 { DIS_FIELDTYPE_ENTITY_ID, "Originating Entity ID",0,0,0,0 },
276 { DIS_FIELDTYPE_ENTITY_ID, "Receiving Entity ID",0,0,0,0 },
277 { DIS_FIELDTYPE_CLOCK_TIME, "Real World Time",0,0,0,0 },
278 { DIS_FIELDTYPE_REASON, "Reason",0,0,0,0 },
279 { DIS_FIELDTYPE_FROZEN_BEHAVIOR, "Frozen Behavior",0,0,0,0 },
280 { DIS_FIELDTYPE_REQUIRED_RELIABILITY_SERVICE, "Reliability",0,0,0,0 },
281 { DIS_FIELDTYPE_PAD8, "Padding",0,0,0,0 },
282 { DIS_FIELDTYPE_REQUEST_ID, "Request ID",0,0,0,0 },
283 { DIS_FIELDTYPE_END, NULL,0,0,0,0 }
286 DIS_ParserNode DIS_PARSER_ACTION_REQUEST_R_PDU[] =
288 { DIS_FIELDTYPE_ENTITY_ID, "Originating Entity ID",0,0,0,0 },
289 { DIS_FIELDTYPE_ENTITY_ID, "Receiving Entity ID",0,0,0,0 },
290 { DIS_FIELDTYPE_REQUIRED_RELIABILITY_SERVICE, "Reliability",0,0,0,0 },
291 { DIS_FIELDTYPE_PAD8, "Padding",3,0,0,0 },
292 { DIS_FIELDTYPE_REQUEST_ID, "Request ID",0,0,0,0 },
293 { DIS_FIELDTYPE_ACTION_ID, "Action ID",0,0,0,0 },
294 { DIS_FIELDTYPE_NUM_FIXED_DATA, "Number of Fixed Data Fields",0,0,0,&numFixed },
295 { DIS_FIELDTYPE_NUM_VARIABLE_DATA, "Number of Variable Data Fields",0,0,0,&numVariable },
296 { DIS_FIELDTYPE_FIXED_DATUMS, "Fixed data",0,0,0,0 },
297 { DIS_FIELDTYPE_VARIABLE_DATUMS, "Variable data",0,0,0,0 },
298 { DIS_FIELDTYPE_END, NULL,0,0,0,0 }
301 DIS_ParserNode DIS_PARSER_DATA_R_PDU[] =
303 { DIS_FIELDTYPE_ENTITY_ID, "Originating Entity ID",0,0,0,0 },
304 { DIS_FIELDTYPE_ENTITY_ID, "Receiving Entity ID",0,0,0,0 },
305 { DIS_FIELDTYPE_REQUIRED_RELIABILITY_SERVICE, "Reliability",0,0,0,0 },
306 { DIS_FIELDTYPE_PAD8, "Padding",3,0,0,0 },
307 { DIS_FIELDTYPE_REQUEST_ID, "Request ID",0,0,0,0 },
308 { DIS_FIELDTYPE_NUM_FIXED_DATA, "Number of Fixed Data Fields",0,0,0,&numFixed },
309 { DIS_FIELDTYPE_NUM_VARIABLE_DATA, "Number of Variable Data Fields",0,0,0,&numVariable },
310 { DIS_FIELDTYPE_FIXED_DATUMS, "Fixed data",0,0,0,0 },
311 { DIS_FIELDTYPE_VARIABLE_DATUMS, "Variable data",0,0,0,0 },
312 { DIS_FIELDTYPE_END, NULL,0,0,0,0 }
315 DIS_ParserNode DIS_PARSER_DATA_QUERY_R_PDU[] =
317 { DIS_FIELDTYPE_ENTITY_ID, "Originating Entity ID",0,0,0,0 },
318 { DIS_FIELDTYPE_ENTITY_ID, "Receiving Entity ID",0,0,0,0 },
319 { DIS_FIELDTYPE_REQUIRED_RELIABILITY_SERVICE, "Reliability",0,0,0,0 },
320 { DIS_FIELDTYPE_PAD8, "Padding",3,0,0,0 },
321 { DIS_FIELDTYPE_REQUEST_ID, "Request ID",0,0,0,0 },
322 { DIS_FIELDTYPE_TIME_INTERVAL, "Time interval",0,0,0,0 },
323 { DIS_FIELDTYPE_NUM_FIXED_DATA, "Number of Fixed Datum Ids",0,0,0,&numFixed },
324 { DIS_FIELDTYPE_NUM_VARIABLE_DATA, "Number of Variable Datum Ids",0,0,0,&numVariable },
325 { DIS_FIELDTYPE_FIXED_DATUM_IDS, "Fixed datum ids",0,0,0,0 },
326 { DIS_FIELDTYPE_VARIABLE_DATUM_IDS, "Variable datum ids",0,0,0,0 },
327 { DIS_FIELDTYPE_END, NULL,0,0,0,0 }
330 DIS_ParserNode DIS_PARSER_SIMAN_ENTITY_R_PDU[] =
332 { DIS_FIELDTYPE_ENTITY_ID, "Originating Entity ID",0,0,0,0 },
333 { DIS_FIELDTYPE_ENTITY_ID, "Receiving Entity ID",0,0,0,0 },
334 { DIS_FIELDTYPE_REQUIRED_RELIABILITY_SERVICE, "Reliability",0,0,0,0 },
335 { DIS_FIELDTYPE_PAD8, "Padding",3,0,0,0 },
336 { DIS_FIELDTYPE_REQUEST_ID, "Request ID",0,0,0,0 },
337 { DIS_FIELDTYPE_END, NULL,0,0,0,0 }
340 /* DIS Experimental V-DIS PDUs
342 DIS_ParserNode DIS_PARSER_APPLICATION_CONTROL_PDU[] =
344 { DIS_FIELDTYPE_ENTITY_ID, "Originating Entity ID",0,0,0,0 },
345 { DIS_FIELDTYPE_ENTITY_ID, "Receiving Entity ID",0,0,0,0 },
346 { DIS_FIELDTYPE_REQUIRED_RELIABILITY_SERVICE, "Reliability",0,0,0,0 },
347 { DIS_FIELDTYPE_UINT8, "Time Interval",0,0,0,0 },
348 { DIS_FIELDTYPE_CONTROL_ID, "Control ID",0,0,0,0 },
349 { DIS_FIELDTYPE_PAD8, "Padding",0,0,0,0 },
350 { DIS_FIELDTYPE_APPLICATION_TYPE, "Originating App Type",0,0,0,0 },
351 { DIS_FIELDTYPE_APPLICATION_TYPE, "Receiving App Type",0,0,0,0 },
352 { DIS_FIELDTYPE_REQUEST_ID, "Request ID",0,0,0,0 },
353 { DIS_FIELDTYPE_UINT8, "Number of Parts",0,0,0,0 },
354 { DIS_FIELDTYPE_UINT8, "Current Part",0,0,0,0 },
355 { DIS_FIELDTYPE_UINT16, "Number of Variable Records",0,0,0,&numVariable },
356 { DIS_FIELDTYPE_VARIABLE_RECORDS, "Record",0,0,0,0 },
357 { DIS_FIELDTYPE_END, NULL,0,0,0,0 }
360 /* Persistent Object (PO) Family PDU parsers
362 DIS_ParserNode DIS_PARSER_SIMULATOR_PRESENT_PO_PDU[] =
364 { DIS_FIELDTYPE_SIMULATION_ADDRESS, "Simulator",0,0,0,0 },
365 { DIS_FIELDTYPE_UINT16, "Simulator Type",0,0,0,0 },
366 { DIS_FIELDTYPE_UINT32, "Database Sequence Number",0,0,0,0 },
367 { DIS_FIELDTYPE_UINT32, "Simulator Load",0,0,0,0 },
368 { DIS_FIELDTYPE_FLOAT32, "Simulation Load",0,0,0,0 },
369 { DIS_FIELDTYPE_UINT32, "Time",0,0,0,0 },
370 { DIS_FIELDTYPE_UINT32, "Packets Sent",0,0,0,0 },
371 { DIS_FIELDTYPE_UINT16, "Unit Database Version",0,0,0,0 },
372 { DIS_FIELDTYPE_UINT16, "Relative Battle Scheme",0,0,0,0 },
373 { DIS_FIELDTYPE_FIXED_LEN_STR, "Terrain Name",32,0,0,0 },
374 { DIS_FIELDTYPE_UINT16, "Terrain Version",0,0,0,0 },
375 { DIS_FIELDTYPE_FIXED_LEN_STR, "Host Name",32,0,0,0 },
376 { DIS_FIELDTYPE_END, NULL,0,0,0,0 }
379 DIS_ParserNode DIS_PARSER_DESCRIBE_OBJECT_PO_PDU[] =
381 { DIS_FIELDTYPE_UINT32, "Database Sequence Number",0,0,0,0 },
382 { DIS_FIELDTYPE_ENTITY_ID, "Object ID",0,0,0,0 },
383 { DIS_FIELDTYPE_ENTITY_ID, "World State ID",0,0,0,0 },
384 { DIS_FIELDTYPE_SIMULATION_ADDRESS, "Owner",0,0,0,0 },
385 { DIS_FIELDTYPE_UINT16, "Sequence Number",0,0,0,0 },
386 { DIS_FIELDTYPE_PERSISTENT_OBJECT_CLASS, "Object Class",0,0,0,0 },
387 { DIS_FIELDTYPE_UINT8, "Missing From World State",0,0,0,0 },
388 { DIS_FIELDTYPE_END, NULL,0,0,0,0 }
391 DIS_ParserNode DIS_PARSER_OBJECTS_PRESENT_PO_PDU[] =
393 { DIS_FIELDTYPE_SIMULATION_ADDRESS, "Owner",0,0,0,0 },
394 { DIS_FIELDTYPE_ENTITY_ID, "World State ID",0,0,0,0 },
395 { DIS_FIELDTYPE_UINT8, "Object Count",0,0,0,0 },
396 { DIS_FIELDTYPE_END, NULL,0,0,0,0 }
399 DIS_ParserNode DIS_PARSER_OBJECT_REQUEST_PO_PDU[] =
401 { DIS_FIELDTYPE_SIMULATION_ADDRESS, "Requesting Simulator",0,0,0,0 },
402 { DIS_FIELDTYPE_SIMULATION_ADDRESS, "Object Owner",0,0,0,0 },
403 { DIS_FIELDTYPE_ENTITY_ID, "World State ID",0,0,0,0 },
404 { DIS_FIELDTYPE_UINT8, "Object Count",0,0,0,0 },
405 { DIS_FIELDTYPE_END, NULL,0,0,0,0 }
408 DIS_ParserNode DIS_PARSER_DELETE_OBJECTS_PO_PDU[] =
410 { DIS_FIELDTYPE_SIMULATION_ADDRESS, "Requesting Simulator",0,0,0,0 },
411 { DIS_FIELDTYPE_UINT8, "Object Count",0,0,0,0 },
412 { DIS_FIELDTYPE_END, NULL,0,0,0,0 }
415 DIS_ParserNode DIS_PARSER_SET_WORLD_STATE_PO_PDU[] =
417 { DIS_FIELDTYPE_SIMULATION_ADDRESS, "Requesting Simulator",0,0,0,0 },
418 { DIS_FIELDTYPE_FLOAT32, "Clock Rate",0,0,0,0 },
419 { DIS_FIELDTYPE_UINT32, "Seconds Since 1970",0,0,0,0 },
420 { DIS_FIELDTYPE_ENTITY_ID, "World State ID",0,0,0,0 },
421 { DIS_FIELDTYPE_END, NULL,0,0,0,0 }
424 DIS_ParserNode DIS_PARSER_NOMINATION_PO_PDU[] =
426 { DIS_FIELDTYPE_SIMULATION_ADDRESS, "Nominated Simulator",0,0,0,0 },
427 { DIS_FIELDTYPE_SIMULATION_ADDRESS, "Nominating Simulator",0,0,0,0 },
428 { DIS_FIELDTYPE_SIMULATION_ADDRESS, "Missing Simulator",0,0,0,0 },
429 { DIS_FIELDTYPE_END, NULL,0,0,0,0 }
432 /* Initialize the parsers for each PDU type and the standard DIS header.
434 void initializeParsers(void)
436 gint *ett[DIS_PDU_MAX_VARIABLE_PARAMETERS+DIS_PDU_MAX_VARIABLE_RECORDS+2];
439 initializeParser(DIS_FIELDS_PDU_HEADER);
441 /* DIS Entity Information / Interaction PDUs */
442 initializeParser(DIS_PARSER_ENTITY_STATE_PDU);
444 /* DIS Distributed Emission Regeneration PDUs */
445 initializeParser(DIS_PARSER_ELECTROMAGNETIC_EMISSION_PDU);
447 /* DIS Radio Communications protocol (RCP) family PDUs */
448 initializeParser(DIS_PARSER_TRANSMITTER_PDU);
449 initializeParser(DIS_PARSER_SIGNAL_PDU);
451 /* DIS Warfare PDUs */
452 initializeParser(DIS_PARSER_FIRE_PDU);
453 initializeParser(DIS_PARSER_DETONATION_PDU);
455 /* DIS Simulation Management PDUs */
456 initializeParser(DIS_PARSER_START_RESUME_PDU);
457 initializeParser(DIS_PARSER_STOP_FREEZE_PDU);
458 initializeParser(DIS_PARSER_ACKNOWLEDGE_PDU);
459 initializeParser(DIS_PARSER_ACTION_REQUEST_PDU);
460 initializeParser(DIS_PARSER_ACTION_RESPONSE_PDU);
461 initializeParser(DIS_PARSER_DATA_PDU);
462 initializeParser(DIS_PARSER_DATA_QUERY_PDU);
463 initializeParser(DIS_PARSER_COMMENT_PDU);
464 initializeParser(DIS_PARSER_SIMAN_ENTITY_PDU);
466 /* DIS Simulation Management with Reliability PDUs */
467 initializeParser(DIS_PARSER_START_RESUME_R_PDU);
468 initializeParser(DIS_PARSER_STOP_FREEZE_R_PDU);
469 initializeParser(DIS_PARSER_ACTION_REQUEST_R_PDU);
470 initializeParser(DIS_PARSER_DATA_R_PDU);
471 initializeParser(DIS_PARSER_DATA_QUERY_R_PDU);
472 initializeParser(DIS_PARSER_SIMAN_ENTITY_R_PDU);
474 /* DIS Experimental V-DIS PDUs */
475 initializeParser(DIS_PARSER_APPLICATION_CONTROL_PDU);
477 /* Initialize the Persistent Object PDUs */
478 initializeParser(DIS_FIELDS_PERSISTENT_OBJECT_HEADER);
479 initializeParser(DIS_PARSER_DESCRIBE_OBJECT_PO_PDU);
480 initializeParser(DIS_PARSER_SIMULATOR_PRESENT_PO_PDU);
481 initializeParser(DIS_PARSER_OBJECTS_PRESENT_PO_PDU);
482 initializeParser(DIS_PARSER_OBJECT_REQUEST_PO_PDU);
483 initializeParser(DIS_PARSER_DELETE_OBJECTS_PO_PDU);
484 initializeParser(DIS_PARSER_SET_WORLD_STATE_PO_PDU);
485 initializeParser(DIS_PARSER_NOMINATION_PO_PDU);
487 /* Initialize the ett array */
489 for (i=0; i<DIS_PDU_MAX_VARIABLE_PARAMETERS; i++, ett_index++)
491 ettVariableParameters[i] = -1;
492 ett[ett_index] = &ettVariableParameters[i];
494 for (i=0; i<DIS_PDU_MAX_VARIABLE_RECORDS; i++, ett_index++)
496 ettVariableRecords[i] = -1;
497 ett[ett_index] = &ettVariableRecords[i];
499 ett[ett_index++] = &ettFixedData;
500 ett[ett_index++] = &ettVariableData;
501 proto_register_subtree_array(ett, array_length(ett));
504 /* Create a specific subtree for a PDU or a composite PDU field.
506 DIS_ParserNode *createSubtree(DIS_ParserNode parserNodes[], gint *ettVar)
508 guint fieldIndex = 0;
511 DIS_ParserNode *newSubtree;
513 while (parserNodes[fieldIndex].fieldType != DIS_FIELDTYPE_END)
518 fieldCount = fieldIndex + 1;
520 newSubtree = (DIS_ParserNode*)g_malloc(sizeof(DIS_ParserNode) * fieldCount);
522 memcpy(newSubtree, parserNodes, sizeof(DIS_ParserNode) * fieldCount);
524 initializeParser(newSubtree);
528 proto_register_subtree_array(ett, array_length(ett));
533 /* Initialize an array of parser nodes.
535 void initializeParser(DIS_ParserNode parserNodes[])
537 guint parserIndex = 0;
539 /* Create the parser subtrees for each of the composite field types.
541 while (parserNodes[parserIndex].fieldType != DIS_FIELDTYPE_END)
543 switch (parserNodes[parserIndex].fieldType)
546 case DIS_FIELDTYPE_APPEARANCE:
547 parserNodes[parserIndex].children = createSubtree(
549 &parserNodes[parserIndex].ettVar);
552 /* Composite types */
553 case DIS_FIELDTYPE_MOD_PARAMS_CCTT_SINCGARS:
554 parserNodes[parserIndex].children = createSubtree(
555 DIS_FIELDS_MOD_PARAMS_CCTT_SINCGARS,
556 &parserNodes[parserIndex].ettVar);
558 case DIS_FIELDTYPE_MOD_PARAMS_JTIDS_MIDS:
559 parserNodes[parserIndex].children = createSubtree(
560 DIS_FIELDS_MOD_PARAMS_JTIDS_MIDS,
561 &parserNodes[parserIndex].ettVar);
564 case DIS_FIELDTYPE_BURST_DESCRIPTOR:
565 parserNodes[parserIndex].children = createSubtree(
566 DIS_FIELDS_BURST_DESCRIPTOR,
567 &parserNodes[parserIndex].ettVar);
569 case DIS_FIELDTYPE_CLOCK_TIME:
570 parserNodes[parserIndex].children = createSubtree(
571 DIS_FIELDS_CLOCK_TIME,
572 &parserNodes[parserIndex].ettVar);
574 case DIS_FIELDTYPE_ENTITY_ID:
575 parserNodes[parserIndex].children = createSubtree(
576 DIS_FIELDS_ENTITY_ID,
577 &parserNodes[parserIndex].ettVar);
579 case DIS_FIELDTYPE_ENTITY_TYPE:
580 parserNodes[parserIndex].children = createSubtree(
581 DIS_FIELDS_ENTITY_TYPE,
582 &parserNodes[parserIndex].ettVar);
584 case DIS_FIELDTYPE_RADIO_ENTITY_TYPE:
585 parserNodes[parserIndex].children = createSubtree(
586 DIS_FIELDS_RADIO_ENTITY_TYPE,
587 &parserNodes[parserIndex].ettVar);
589 case DIS_FIELDTYPE_EVENT_ID:
590 parserNodes[parserIndex].children = createSubtree(
592 &parserNodes[parserIndex].ettVar);
594 case DIS_FIELDTYPE_ORIENTATION:
595 parserNodes[parserIndex].children = createSubtree(
596 DIS_FIELDS_ORIENTATION,
597 &parserNodes[parserIndex].ettVar);
599 case DIS_FIELDTYPE_SIMULATION_ADDRESS:
600 parserNodes[parserIndex].children = createSubtree(
601 DIS_FIELDS_SIMULATION_ADDRESS,
602 &parserNodes[parserIndex].ettVar);
604 case DIS_FIELDTYPE_LINEAR_VELOCITY:
605 case DIS_FIELDTYPE_LOCATION_ENTITY:
606 case DIS_FIELDTYPE_REL_ANTENNA_LOCATON:
607 case DIS_FIELDTYPE_VECTOR_32:
608 parserNodes[parserIndex].children = createSubtree(
609 DIS_FIELDS_VECTOR_FLOAT_32,
610 &parserNodes[parserIndex].ettVar);
612 case DIS_FIELDTYPE_LOCATION_WORLD:
613 case DIS_FIELDTYPE_ANTENNA_LOCATION:
614 case DIS_FIELDTYPE_VECTOR_64:
615 parserNodes[parserIndex].children = createSubtree(
616 DIS_FIELDS_VECTOR_FLOAT_64,
617 &parserNodes[parserIndex].ettVar);
619 case DIS_FIELDTYPE_MODULATION_TYPE:
620 parserNodes[parserIndex].children = createSubtree(
621 DIS_FIELDS_MODULATION_TYPE,
622 &parserNodes[parserIndex].ettVar);
624 case DIS_FIELDTYPE_ELECTROMAGNETIC_EMISSION_SYSTEM_BEAM:
625 parserNodes[parserIndex].children = createSubtree(
626 DIS_FIELDS_VR_ELECTROMAGNETIC_EMISSION_SYSTEM_BEAM,
627 &parserNodes[parserIndex].ettVar);
629 case DIS_FIELDTYPE_ELECTROMAGNETIC_EMISSION_SYSTEM:
630 parserNodes[parserIndex].children = createSubtree(
631 DIS_FIELDS_VR_ELECTROMAGNETIC_EMISSION_SYSTEM,
632 &parserNodes[parserIndex].ettVar);
634 case DIS_FIELDTYPE_EMITTER_SYSTEM:
635 parserNodes[parserIndex].children = createSubtree(
636 DIS_FIELDS_EMITTER_SYSTEM,
637 &parserNodes[parserIndex].ettVar);
639 case DIS_FIELDTYPE_FUNDAMENTAL_PARAMETER_DATA:
640 parserNodes[parserIndex].children = createSubtree(
641 DIS_FIELDS_FUNDAMENTAL_PARAMETER_DATA,
642 &parserNodes[parserIndex].ettVar);
644 case DIS_FIELDTYPE_TRACK_JAM:
645 parserNodes[parserIndex].children = createSubtree(
646 DIS_FIELDS_TRACK_JAM,
647 &parserNodes[parserIndex].ettVar);
650 case DIS_FIELDTYPE_FIXED_DATUMS:
651 parserNodes[parserIndex].children = createSubtree(
652 DIS_FIELDS_FIXED_DATUM,
653 &parserNodes[parserIndex].ettVar);
655 case DIS_FIELDTYPE_VARIABLE_DATUMS:
656 parserNodes[parserIndex].children = createSubtree(
657 DIS_FIELDS_VARIABLE_DATUM,
658 &parserNodes[parserIndex].ettVar);
660 case DIS_FIELDTYPE_FIXED_DATUM_IDS:
661 case DIS_FIELDTYPE_VARIABLE_DATUM_IDS:
662 parserNodes[parserIndex].children = createSubtree(
663 DIS_FIELDS_DATUM_IDS,
664 &parserNodes[parserIndex].ettVar);
666 case DIS_FIELDTYPE_VARIABLE_PARAMETERS:
667 parserNodes[parserIndex].children = createSubtree(
669 &parserNodes[parserIndex].ettVar);
671 case DIS_FIELDTYPE_VARIABLE_RECORDS:
672 parserNodes[parserIndex].children = createSubtree(
674 &parserNodes[parserIndex].ettVar);
683 /* Parse packet data based on a specified array of DIS_ParserNodes.
685 gint parseFields(tvbuff_t *tvb, proto_tree *tree, gint offset, DIS_ParserNode parserNodes[])
687 guint fieldIndex = 0;
688 guint fieldRepeatLen = 0;
690 proto_item *pi = NULL;
691 proto_tree *sub_tree = NULL;
692 tvbuff_t *newtvb = NULL;
694 guint16 spread_spectrum = 0;
697 length = tvb_length_remaining(tvb, offset);
699 while ((parserNodes[fieldIndex].fieldType != DIS_FIELDTYPE_END)
702 proto_item *newField = 0;
704 fieldRepeatLen = (guint) ((parserNodes[fieldIndex].fieldRepeatLen > 1) ?
705 parserNodes[fieldIndex].fieldRepeatLen : 1);
707 switch(parserNodes[fieldIndex].fieldType)
709 /* basic numeric types */
710 case DIS_FIELDTYPE_INT8:
711 offset = parseField_Int(tvb, tree, offset,
712 parserNodes[fieldIndex], 1);
714 case DIS_FIELDTYPE_INT16:
715 offset = parseField_Int(tvb, tree, offset,
716 parserNodes[fieldIndex], 2);
718 case DIS_FIELDTYPE_INT32:
719 offset = parseField_Int(tvb, tree, offset,
720 parserNodes[fieldIndex], 4);
722 case DIS_FIELDTYPE_INT64:
723 offset = parseField_Int(tvb, tree, offset,
724 parserNodes[fieldIndex], 8);
726 case DIS_FIELDTYPE_UINT8:
727 offset = parseField_UInt(tvb, tree, offset,
728 parserNodes[fieldIndex], 1);
730 case DIS_FIELDTYPE_UINT16:
731 offset = parseField_UInt(tvb, tree, offset,
732 parserNodes[fieldIndex], 2);
734 case DIS_FIELDTYPE_UINT32:
735 offset = parseField_UInt(tvb, tree, offset,
736 parserNodes[fieldIndex], 4);
738 case DIS_FIELDTYPE_UINT64:
739 offset = parseField_UInt(tvb, tree, offset,
740 parserNodes[fieldIndex], 8);
742 case DIS_FIELDTYPE_FLOAT32:
743 offset = parseField_Float(tvb, tree, offset,
744 parserNodes[fieldIndex]);
746 case DIS_FIELDTYPE_FLOAT64:
747 offset = parseField_Double(tvb, tree, offset,
748 parserNodes[fieldIndex]);
750 case DIS_FIELDTYPE_EXERCISE_ID:
751 pi = proto_tree_add_item(tree, hf_dis_exercise_id, tvb, offset, 1, FALSE);
754 case DIS_FIELDTYPE_NUM_ARTICULATION_PARAMS:
755 uintVal = tvb_get_guint8(tvb, offset);
756 pi = proto_tree_add_item(tree, hf_dis_num_art_params, tvb, offset, 1, FALSE);
758 *(parserNodes[fieldIndex].outputVar) = (guint32)uintVal;
760 case DIS_FIELDTYPE_PDU_LENGTH:
761 uintVal = tvb_get_ntohs(tvb, offset);
762 pi = proto_tree_add_item(tree, hf_dis_pdu_length, tvb, offset, 2, FALSE);
765 case DIS_FIELDTYPE_SITE:
766 uintVal = tvb_get_ntohs(tvb, offset);
767 pi = proto_tree_add_item(tree, hf_dis_entity_id_site, tvb, offset, 2, FALSE);
770 case DIS_FIELDTYPE_APPLICATION:
771 uintVal = tvb_get_ntohs(tvb, offset);
772 pi = proto_tree_add_item(tree, hf_dis_entity_id_application, tvb, offset, 2, FALSE);
775 case DIS_FIELDTYPE_ENTITY:
776 uintVal = tvb_get_ntohs(tvb, offset);
777 pi = proto_tree_add_item(tree, hf_dis_entity_id_entity, tvb, offset, 2, FALSE);
780 case DIS_FIELDTYPE_RADIO_ID:
781 uintVal = tvb_get_ntohs(tvb, offset);
782 pi = proto_tree_add_item(tree, hf_dis_radio_id, tvb, offset, 2, FALSE);
783 *(parserNodes[fieldIndex].outputVar) = (guint32)uintVal;
786 case DIS_FIELDTYPE_ENCODING_SCHEME:
787 uintVal = tvb_get_ntohs(tvb, offset);
788 pi = proto_tree_add_item(tree, hf_dis_ens, tvb, offset, 2, FALSE);
789 sub_tree = proto_item_add_subtree(pi, ett_dis_ens);
790 proto_tree_add_item(sub_tree, hf_dis_ens_class, tvb, offset, 2, FALSE);
791 proto_tree_add_item(sub_tree, hf_dis_ens_type, tvb, offset, 2, FALSE);
792 proto_item_set_end(pi, tvb, offset);
793 *(parserNodes[fieldIndex].outputVar) = (guint32)uintVal;
796 case DIS_FIELDTYPE_TDL_TYPE:
797 proto_tree_add_item(tree, hf_dis_tdl_type, tvb, offset, 2, FALSE);
800 case DIS_FIELDTYPE_SAMPLE_RATE:
801 proto_tree_add_item(tree, hf_dis_sample_rate, tvb, offset, 4, FALSE);
804 case DIS_FIELDTYPE_DATA_LENGTH:
805 proto_tree_add_item(tree, hf_dis_data_length, tvb, offset, 2, FALSE);
808 case DIS_FIELDTYPE_NUMBER_OF_SAMPLES:
809 uintVal = tvb_get_ntohs(tvb, offset);
810 proto_tree_add_item(tree, hf_dis_num_of_samples, tvb, offset, 2, FALSE);
811 *(parserNodes[fieldIndex].outputVar) = (guint32)uintVal;
815 case DIS_FIELDTYPE_RADIO_DATA:
816 newtvb = tvb_new_subset(tvb, offset,
817 tvb_length_remaining(tvb, offset),
818 tvb_reported_length_remaining(tvb, offset)
820 proto_tree_add_item(tree, hf_dis_signal_data, newtvb, 0, -1, FALSE );
821 /* ****ck******* need to look for padding bytes */
823 case DIS_FIELDTYPE_RADIO_CATEGORY:
824 proto_tree_add_item(tree, hf_dis_radio_category, tvb, offset, 1, FALSE);
827 case DIS_FIELDTYPE_NOMENCLATURE_VERSION:
828 proto_tree_add_item(tree, hf_dis_nomenclature_version, tvb, offset, 1, FALSE);
831 case DIS_FIELDTYPE_NOMENCLATURE:
832 proto_tree_add_item(tree, hf_dis_nomenclature, tvb, offset, 2, FALSE);
835 case DIS_FIELDTYPE_RADIO_TRANSMIT_STATE:
836 uintVal = tvb_get_guint8(tvb, offset);
837 proto_tree_add_item(tree, hf_dis_radio_transmit_state, tvb, offset, 1, FALSE);
838 *(parserNodes[fieldIndex].outputVar) = (guint32)uintVal;
841 case DIS_FIELDTYPE_RADIO_INPUT_SOURCE:
842 proto_tree_add_item(tree, hf_dis_radio_input_source, tvb, offset, 1, FALSE);
845 case DIS_FIELDTYPE_ANTENNA_PATTERN_TYPE:
846 uintVal = tvb_get_ntohs(tvb, offset);
847 proto_tree_add_item(tree, hf_dis_antenna_pattern_type, tvb, offset, 2, FALSE);
848 *(parserNodes[fieldIndex].outputVar) = (guint32)uintVal;
851 case DIS_FIELDTYPE_ANTENNA_PATTERN_LENGTH:
852 proto_tree_add_item(tree, hf_dis_antenna_pattern_length, tvb, offset, 2, FALSE);
855 case DIS_FIELDTYPE_TRANSMIT_FREQUENCY:
856 proto_tree_add_item(tree, hf_dis_transmit_frequency, tvb, offset, 8, FALSE);
859 case DIS_FIELDTYPE_SPREAD_SPECTRUM:
860 spread_spectrum = tvb_get_ntohs(tvb, offset);
861 proto_tree_add_boolean(tree, hf_dis_spread_spectrum_usage, tvb, offset, 2, spread_spectrum);
862 proto_tree_add_boolean(tree, hf_dis_frequency_hopping, tvb, offset, 2, spread_spectrum);
863 proto_tree_add_boolean(tree, hf_dis_pseudo_noise_modulation, tvb, offset, 2, spread_spectrum);
864 proto_tree_add_boolean(tree, hf_dis_time_hopping, tvb, offset, 2, spread_spectrum);
867 case DIS_FIELDTYPE_MODULATION_MAJOR:
868 uintVal = tvb_get_ntohs(tvb, offset);
869 proto_tree_add_item(tree, hf_dis_modulation_major, tvb, offset, 2, FALSE);
870 *(parserNodes[fieldIndex].outputVar) = (guint32)uintVal;
873 case DIS_FIELDTYPE_MODULATION_SYSTEM:
874 uintVal = tvb_get_ntohs(tvb, offset);
875 proto_tree_add_item(tree, hf_dis_modulation_system, tvb, offset, 2, FALSE);
876 *(parserNodes[fieldIndex].outputVar) = (guint32)uintVal;
879 case DIS_FIELDTYPE_CRYPTO_SYSTEM:
880 proto_tree_add_item(tree, hf_dis_crypto_system, tvb, offset, 2, FALSE);
883 case DIS_FIELDTYPE_CRYPTO_KEY_ID:
884 pi = proto_tree_add_item(tree, hf_dis_crypto_key, tvb, offset, 2, FALSE);
885 sub_tree = proto_item_add_subtree(pi, ett_dis_crypto_key);
886 proto_tree_add_item(sub_tree, hf_dis_encryption_mode, tvb, offset, 2, FALSE);
887 proto_tree_add_item(sub_tree, hf_dis_key_identifier, tvb, offset, 2, FALSE);
888 proto_item_set_end(pi, tvb, offset);
891 case DIS_FIELDTYPE_MODULATION_PARAMETER_LENGTH:
892 uintVal = tvb_get_guint8(tvb, offset);
893 proto_tree_add_item(tree, hf_dis_modulation_parameter_length, tvb, offset, 1, FALSE);
894 *(parserNodes[fieldIndex].outputVar) = (guint32)uintVal;
897 case DIS_FIELDTYPE_FH_NETWORK_ID:
898 proto_tree_add_item(tree, hf_dis_mod_param_fh_net_id, tvb, offset, 2, FALSE);
901 case DIS_FIELDTYPE_FH_SET_ID:
902 proto_tree_add_item(tree, hf_dis_mod_param_fh_set_id, tvb, offset, 2, FALSE);
905 case DIS_FIELDTYPE_LO_SET_ID:
906 proto_tree_add_item(tree, hf_dis_mod_param_fh_lo_set_id, tvb, offset, 2, FALSE);
909 case DIS_FIELDTYPE_FH_MSG_START:
910 proto_tree_add_item(tree, hf_dis_mod_param_fh_msg_start, tvb, offset, 1, FALSE);
913 case DIS_FIELDTYPE_RESERVED:
914 proto_tree_add_item(tree, hf_dis_mod_param_fh_reserved, tvb, offset, 1, FALSE);
917 case DIS_FIELDTYPE_FH_SYNC_TIME_OFFSET:
918 proto_tree_add_item(tree, hf_dis_mod_param_fh_sync_time_offset, tvb, offset, 4, FALSE);
921 case DIS_FIELDTYPE_FH_SECURITY_KEY:
922 proto_tree_add_item(tree, hf_dis_mod_param_fh_security_key, tvb, offset, 2, FALSE);
925 case DIS_FIELDTYPE_FH_CLEAR_CHANNEL:
926 proto_tree_add_item(tree, hf_dis_mod_param_fh_clear_channel, tvb, offset, 1, FALSE);
929 case DIS_FIELDTYPE_TS_ALLOCATION_MODE:
930 proto_tree_add_item(tree, hf_dis_mod_param_ts_allocation_mode, tvb, offset, 1, FALSE);
933 case DIS_FIELDTYPE_TRANSMITTER_PRIMARY_MODE:
934 proto_tree_add_item(tree, hf_dis_mod_param_transmitter_prim_mode, tvb, offset, 1, FALSE);
937 case DIS_FIELDTYPE_TRANSMITTER_SECONDARY_MODE:
938 proto_tree_add_item(tree, hf_dis_mod_param_transmitter_second_mode, tvb, offset, 1, FALSE);
941 case DIS_FIELDTYPE_JTIDS_SYNC_STATE:
942 proto_tree_add_item(tree, hf_dis_mod_param_sync_state, tvb, offset, 1, FALSE);
945 case DIS_FIELDTYPE_NETWORK_SYNC_ID:
946 proto_tree_add_item(tree, hf_dis_mod_param_network_sync_id, tvb, offset, 4, FALSE);
949 case DIS_FIELDTYPE_MODULATION_PARAMETERS:
950 /* need to check to see if mod parms length > 0 */
951 /* could get here when there are antenna pattern parameter but no mod params */
952 if (modulationParamLength > 0 ) { /* we do have a mod param */
953 if (systemModulation == DIS_SYSTEM_MOD_CCTT_SINCGARS)
955 pi = proto_tree_add_text(tree, tvb, offset, -1, "%s",
956 parserNodes[fieldIndex].fieldLabel);
957 sub_tree = proto_item_add_subtree(pi, parserNodes[fieldIndex].ettVar);
958 offset = parseFields(tvb, sub_tree, offset, DIS_FIELDS_MOD_PARAMS_CCTT_SINCGARS);
959 proto_item_set_end(pi, tvb, offset);
962 else if (systemModulation == DIS_SYSTEM_MOD_JTIDS_MIDS) {
963 pi = proto_tree_add_text(tree, tvb, offset, -1, "%s",
964 parserNodes[fieldIndex].fieldLabel);
965 sub_tree = proto_item_add_subtree(pi, parserNodes[fieldIndex].ettVar);
966 offset = parseFields(tvb, sub_tree, offset, DIS_FIELDS_MOD_PARAMS_JTIDS_MIDS);
967 proto_item_set_end(pi, tvb, offset);
970 else { /* just dump what is available */
971 newtvb = tvb_new_subset(tvb, offset,modulationParamLength, modulationParamLength);
972 proto_tree_add_item(tree, hf_dis_mod_param_dump, newtvb, 0, -1, FALSE );
973 offset += modulationParamLength;
976 } /* else, leave offset alone, and then check antenna pattern param field */
978 case DIS_FIELDTYPE_ANTENNA_PATTERN_PARAMETERS:
979 /* just dump the bytes for now. Need to do finish */
980 newtvb = tvb_new_subset(tvb, offset,
981 tvb_length_remaining(tvb, offset),
982 tvb_reported_length_remaining(tvb, offset)
984 proto_tree_add_item(tree, hf_dis_antenna_pattern_parameter_dump, newtvb, 0, -1, FALSE );
989 case DIS_FIELDTYPE_PAD8:
990 offset = parseField_Pad(tvb, tree, offset,
991 parserNodes[fieldIndex], 1 * fieldRepeatLen);
993 case DIS_FIELDTYPE_PAD16:
994 offset = parseField_Pad(tvb, tree, offset,
995 parserNodes[fieldIndex], 2 * fieldRepeatLen);
997 case DIS_FIELDTYPE_PAD24:
998 offset = parseField_Pad(tvb, tree, offset,
999 parserNodes[fieldIndex], 3 * fieldRepeatLen);
1001 case DIS_FIELDTYPE_PAD32:
1002 offset = parseField_Pad(tvb, tree, offset,
1003 parserNodes[fieldIndex], 4 * fieldRepeatLen);
1006 /* enumerations (1-byte) */
1007 case DIS_FIELDTYPE_APPLICATION_GENERAL_STATUS:
1008 case DIS_FIELDTYPE_CATEGORY:
1009 case DIS_FIELDTYPE_CONTROL_ID:
1010 case DIS_FIELDTYPE_DETONATION_RESULT:
1011 case DIS_FIELDTYPE_DOMAIN:
1012 case DIS_FIELDTYPE_ENTITY_KIND:
1013 case DIS_FIELDTYPE_FROZEN_BEHAVIOR:
1014 case DIS_FIELDTYPE_PARAMETER_TYPE_DESIGNATOR:
1015 case DIS_FIELDTYPE_PDU_TYPE:
1016 case DIS_FIELDTYPE_PROTOCOL_FAMILY:
1017 case DIS_FIELDTYPE_PROTOCOL_VERSION:
1018 case DIS_FIELDTYPE_REASON:
1019 case DIS_FIELDTYPE_REQUIRED_RELIABILITY_SERVICE:
1020 case DIS_FIELDTYPE_PERSISTENT_OBJECT_CLASS:
1021 case DIS_FIELDTYPE_PERSISTENT_OBJECT_TYPE:
1022 case DIS_FIELDTYPE_EMISSION_FUNCTION:
1023 case DIS_FIELDTYPE_BEAM_FUNCTION:
1024 offset = parseField_Enum(tvb, tree, offset,
1025 parserNodes[fieldIndex], 1);
1028 /* enumerations (2-bytes) */
1029 case DIS_FIELDTYPE_ACKNOWLEDGE_FLAG:
1030 case DIS_FIELDTYPE_APPLICATION_STATUS_TYPE:
1031 case DIS_FIELDTYPE_APPLICATION_TYPE:
1032 case DIS_FIELDTYPE_RESPONSE_FLAG:
1033 case DIS_FIELDTYPE_MODULATION_DETAIL:
1034 case DIS_FIELDTYPE_EMITTER_NAME:
1035 offset = parseField_Enum(tvb, tree, offset,
1036 parserNodes[fieldIndex], 2);
1039 /* enumerations (4-bytes) */
1040 case DIS_FIELDTYPE_ACTION_ID:
1041 case DIS_FIELDTYPE_REQUEST_STATUS:
1042 offset = parseField_Enum(tvb, tree, offset,
1043 parserNodes[fieldIndex], 4);
1046 /* other atomic types */
1047 case DIS_FIELDTYPE_APPEARANCE:
1049 proto_item *newSubtree;
1050 newField = proto_tree_add_text(tree, tvb, offset, 4, "%s",
1051 parserNodes[fieldIndex].fieldLabel);
1052 newSubtree = proto_item_add_subtree(newField,
1053 parserNodes[fieldIndex].ettVar);
1054 offset = parseField_Bitmask(tvb, newSubtree, offset,
1055 parserNodes[fieldIndex], 4);
1058 case DIS_FIELDTYPE_ARTIC_PARAM_TYPE:
1059 offset = parseField_UInt(tvb, tree, offset,
1060 parserNodes[fieldIndex], 4);
1062 case DIS_FIELDTYPE_CAPABILITIES:
1063 offset = parseField_UInt(tvb, tree, offset,
1064 parserNodes[fieldIndex], 4);
1066 case DIS_FIELDTYPE_COUNTRY:
1067 offset = parseField_UInt(tvb, tree, offset,
1068 parserNodes[fieldIndex], 2);
1070 case DIS_FIELDTYPE_DATUM_ID:
1071 case DIS_FIELDTYPE_DATUM_LENGTH:
1072 offset = parseField_UInt(tvb, tree, offset,
1073 parserNodes[fieldIndex], 4);
1075 case DIS_FIELDTYPE_DEAD_RECKONING_PARAMS:
1076 /* This is really a struct... needs a field parser.
1077 * For now, just skip the 12 bytes.
1079 offset = parseField_Bytes(tvb, tree, offset,
1080 parserNodes[fieldIndex], 40);
1082 case DIS_FIELDTYPE_ENTITY_MARKING:
1083 /* This is really a struct... needs a field parser.
1084 * For now, just skip the 12 bytes.
1086 offset = parseField_Bytes(tvb, tree, offset,
1087 parserNodes[fieldIndex], 12);
1089 case DIS_FIELDTYPE_EXTRA:
1090 offset = parseField_UInt(tvb, tree, offset,
1091 parserNodes[fieldIndex], 1);
1093 case DIS_FIELDTYPE_FIXED_DATUM_VALUE:
1094 offset = parseField_Bytes(tvb, tree, offset,
1095 parserNodes[fieldIndex], 4);
1097 case DIS_FIELDTYPE_FIXED_LEN_STR:
1098 offset = parseField_Bytes(tvb, tree, offset,
1099 parserNodes[fieldIndex],
1100 parserNodes[fieldIndex].fieldRepeatLen);
1102 case DIS_FIELDTYPE_FORCE_ID:
1103 offset = parseField_UInt(tvb, tree, offset,
1104 parserNodes[fieldIndex], 1);
1106 case DIS_FIELDTYPE_FUSE:
1107 offset = parseField_UInt(tvb, tree, offset,
1108 parserNodes[fieldIndex], 2);
1110 case DIS_FIELDTYPE_NUM_FIXED_DATA:
1111 case DIS_FIELDTYPE_NUM_VARIABLE_DATA:
1112 offset = parseField_UInt(tvb, tree, offset,
1113 parserNodes[fieldIndex], 4);
1115 case DIS_FIELDTYPE_REQUEST_ID:
1116 offset = parseField_UInt(tvb, tree, offset,
1117 parserNodes[fieldIndex], 4);
1119 case DIS_FIELDTYPE_SPECIFIC:
1120 offset = parseField_UInt(tvb, tree, offset,
1121 parserNodes[fieldIndex], 1);
1123 case DIS_FIELDTYPE_SUBCATEGORY:
1124 offset = parseField_UInt(tvb, tree, offset,
1125 parserNodes[fieldIndex], 1);
1127 case DIS_FIELDTYPE_TIME_INTERVAL:
1128 offset = parseField_UInt(tvb, tree, offset,
1129 parserNodes[fieldIndex], 4);
1131 case DIS_FIELDTYPE_TIMESTAMP:
1132 offset = parseField_Timestamp(tvb, tree, offset,
1133 parserNodes[fieldIndex]);
1135 case DIS_FIELDTYPE_WARHEAD:
1136 offset = parseField_UInt(tvb, tree, offset,
1137 parserNodes[fieldIndex], 2);
1140 /* composite types */
1141 case DIS_FIELDTYPE_BURST_DESCRIPTOR:
1142 case DIS_FIELDTYPE_CLOCK_TIME:
1143 case DIS_FIELDTYPE_ENTITY_ID:
1144 case DIS_FIELDTYPE_ENTITY_TYPE:
1145 case DIS_FIELDTYPE_RADIO_ENTITY_TYPE:
1146 case DIS_FIELDTYPE_ANTENNA_LOCATION:
1147 case DIS_FIELDTYPE_REL_ANTENNA_LOCATON:
1148 case DIS_FIELDTYPE_EVENT_ID:
1149 case DIS_FIELDTYPE_LINEAR_VELOCITY:
1150 case DIS_FIELDTYPE_LOCATION_ENTITY:
1151 case DIS_FIELDTYPE_LOCATION_WORLD:
1152 case DIS_FIELDTYPE_ORIENTATION:
1153 case DIS_FIELDTYPE_SIMULATION_ADDRESS:
1154 case DIS_FIELDTYPE_VECTOR_32:
1155 case DIS_FIELDTYPE_VECTOR_64:
1156 case DIS_FIELDTYPE_MODULATION_TYPE:
1157 case DIS_FIELDTYPE_EMITTER_SYSTEM:
1158 case DIS_FIELDTYPE_FUNDAMENTAL_PARAMETER_DATA:
1159 newField = proto_tree_add_text(tree, tvb, offset, -1, "%s",
1160 parserNodes[fieldIndex].fieldLabel);
1161 if (parserNodes[fieldIndex].children != 0)
1163 proto_item *newSubtree = proto_item_add_subtree(newField,
1164 parserNodes[fieldIndex].ettVar);
1165 offset = parseFields(tvb, newSubtree, offset,
1166 parserNodes[fieldIndex].children);
1168 proto_item_set_end(newField, tvb, offset);
1170 case DIS_FIELDTYPE_VARIABLE_DATUM_VALUE:
1172 guint lengthInBytes;
1173 lengthInBytes = variableDatumLength / 8;
1174 if (variableDatumLength % 8 > 0)
1176 lengthInBytes += (8 - (variableDatumLength % 8));
1178 offset = parseField_Bytes(tvb, tree, offset,
1179 parserNodes[fieldIndex], lengthInBytes);
1184 case DIS_FIELDTYPE_FIXED_DATUMS:
1187 if (numFixed > INT32_MAX)
1189 numFixed = INT32_MAX;
1192 for (i = 0; i < numFixed; ++i)
1194 /* is remaining length large enough for another fixed datum (ID & value) */
1195 length = tvb_length_remaining(tvb, offset);
1198 proto_item *newSubtree;
1199 newField = proto_tree_add_text(tree, tvb, offset, -1, "%s",
1200 parserNodes[fieldIndex].fieldLabel);
1201 newSubtree = proto_item_add_subtree(newField, ettFixedData);
1202 offset = parseFields
1203 (tvb, newSubtree, offset,
1204 parserNodes[fieldIndex].children);
1205 proto_item_set_end(newField, tvb, offset);
1208 THROW(ReportedBoundsError);
1214 case DIS_FIELDTYPE_FIXED_DATUM_IDS:
1218 proto_item *newSubtree;
1220 newField = proto_tree_add_text(tree, tvb, offset, -1, "%s",
1221 parserNodes[fieldIndex].fieldLabel);
1222 newSubtree = proto_item_add_subtree(newField, ettFixedData);
1224 if (numFixed > INT32_MAX)
1226 numFixed = INT32_MAX;
1229 for (i = 0; i < numFixed; ++i)
1231 /* is remaining length large enough for another fixed datum ID (32 bit int) */
1232 if (tvb_length_remaining(tvb, offset) >= 4 )
1234 offset = parseFields
1235 (tvb, newSubtree, offset,
1236 parserNodes[fieldIndex].children);
1239 THROW(ReportedBoundsError);
1243 proto_item_set_end(newField, tvb, offset);
1246 case DIS_FIELDTYPE_VARIABLE_DATUMS:
1249 if (numVariable > INT32_MAX)
1251 numVariable = INT32_MAX;
1254 for (i = 0; i < numVariable; ++i)
1256 proto_item *newSubtree;
1257 newField = proto_tree_add_text(tree, tvb, offset, -1, "%s",
1258 parserNodes[fieldIndex].fieldLabel);
1259 newSubtree = proto_item_add_subtree
1260 (newField, ettVariableData);
1261 offset = parseFields
1262 (tvb, newSubtree, offset,
1263 parserNodes[fieldIndex].children);
1264 proto_item_set_end(newField, tvb, offset);
1269 case DIS_FIELDTYPE_VARIABLE_DATUM_IDS:
1270 if (numVariable > 0)
1273 proto_item *newSubtree;
1275 newField = proto_tree_add_text(tree, tvb, offset, -1, "%s",
1276 parserNodes[fieldIndex].fieldLabel);
1277 newSubtree = proto_item_add_subtree(newField, ettVariableData);
1279 if (numVariable > INT32_MAX)
1281 numVariable = INT32_MAX;
1284 for (i = 0; i < numVariable; ++i)
1286 offset = parseFields
1287 (tvb, newSubtree, offset,
1288 parserNodes[fieldIndex].children);
1290 proto_item_set_end(newField, tvb, offset);
1293 case DIS_FIELDTYPE_VARIABLE_PARAMETERS:
1297 if (numVariable > DIS_PDU_MAX_VARIABLE_PARAMETERS)
1299 numVariable = DIS_PDU_MAX_VARIABLE_PARAMETERS;
1302 for (i = 0; i < numVariable; ++i)
1304 proto_item *newSubtree;
1305 newField = proto_tree_add_text(tree, tvb, offset, -1, "%s",
1306 parserNodes[fieldIndex].fieldLabel);
1307 newSubtree = proto_item_add_subtree(newField,
1308 ettVariableParameters[i]);
1309 offset = parseFields
1310 (tvb, newSubtree, offset,
1311 parserNodes[fieldIndex].children);
1312 offset = parseField_VariableParameter
1313 (tvb, newSubtree, offset);
1314 proto_item_set_end(newField, tvb, offset);
1318 case DIS_FIELDTYPE_VARIABLE_RECORDS:
1322 if (numVariable > DIS_PDU_MAX_VARIABLE_RECORDS)
1324 numVariable = DIS_PDU_MAX_VARIABLE_RECORDS;
1327 for (i = 0; i < numVariable; ++i)
1329 /* simple check to detect malformed, field parsers will detect specifics */
1330 length = tvb_length_remaining(tvb, offset);
1333 proto_item *newSubtree;
1334 newField = proto_tree_add_text(tree, tvb, offset, -1, "%s",
1335 parserNodes[fieldIndex].fieldLabel);
1336 newSubtree = proto_item_add_subtree(newField,
1337 ettVariableRecords[i]);
1338 offset = parseFields
1339 (tvb, newSubtree, offset,
1340 parserNodes[fieldIndex].children);
1341 offset = parseField_VariableRecord
1342 (tvb, newSubtree, offset);
1343 proto_item_set_end(newField, tvb, offset);
1346 THROW(ReportedBoundsError);
1352 case DIS_FIELDTYPE_ELECTROMAGNETIC_EMISSION_SYSTEM_BEAM:
1356 for (i = 0; i < numBeams; ++i)
1358 newField = proto_tree_add_text(tree, tvb, offset, -1, "%s",
1359 parserNodes[fieldIndex].fieldLabel);
1360 if (parserNodes[fieldIndex].children != 0)
1362 proto_item *newSubtree =
1363 proto_item_add_subtree(newField,
1364 parserNodes[fieldIndex].ettVar);
1365 offset = parseFields(tvb, newSubtree, offset,
1366 parserNodes[fieldIndex].children);
1368 proto_item_set_end(newField, tvb, offset);
1372 case DIS_FIELDTYPE_TRACK_JAM:
1376 for (i = 0; i < numTrackJamTargets; ++i)
1378 newField = proto_tree_add_text(tree, tvb, offset, -1, "%s",
1379 parserNodes[fieldIndex].fieldLabel);
1380 if (parserNodes[fieldIndex].children != 0)
1382 proto_item *newSubtree =
1383 proto_item_add_subtree(newField,
1384 parserNodes[fieldIndex].ettVar);
1385 offset = parseFields(tvb, newSubtree, offset,
1386 parserNodes[fieldIndex].children);
1388 proto_item_set_end(newField, tvb, offset);
1392 case DIS_FIELDTYPE_NUM_ELECTROMAGNETIC_EMISSION_SYSTEMS:
1393 uintVal = tvb_get_guint8(tvb, offset);
1394 pi = proto_tree_add_item(tree, hf_dis_num_electromagnetic_emission_systems, tvb, offset, 1, FALSE);
1396 *(parserNodes[fieldIndex].outputVar) = (guint32)uintVal;
1398 case DIS_FIELDTYPE_ELECTROMAGNETIC_EMISSION_SYSTEM:
1402 if (numVariable > DIS_PDU_MAX_ELECTROMAGNETIC_EMISSION_SYSTEMS)
1404 numVariable = DIS_PDU_MAX_ELECTROMAGNETIC_EMISSION_SYSTEMS;
1407 for (i = 0; i < numVariable; ++i)
1409 newField = proto_tree_add_text(tree, tvb, offset, -1, "%s",
1410 parserNodes[fieldIndex].fieldLabel);
1411 if (parserNodes[fieldIndex].children != 0)
1413 proto_item *newSubtree =
1414 proto_item_add_subtree(newField,
1415 parserNodes[fieldIndex].ettVar);
1416 offset = parseFields(tvb, newSubtree, offset,
1417 parserNodes[fieldIndex].children);
1419 proto_item_set_end(newField, tvb, offset);
1428 length = tvb_length_remaining(tvb, offset);