From df2dc9222b2e7d05367e3ef5d125100e8a2cb903 Mon Sep 17 00:00:00 2001 From: Peter Ross Date: Sat, 10 May 2014 11:35:41 -0400 Subject: packet-dis: SISO-J Link 16 PDU dissector (SISO-STD-002) Change-Id: Id2ed7b7786705ad5fa345b0d1904cec508d3161e Reviewed-on: https://code.wireshark.org/review/1552 Reviewed-by: Michael Mann --- epan/dissectors/packet-dis-enums.c | 20 +++++ epan/dissectors/packet-dis-enums.h | 16 ++++ epan/dissectors/packet-dis-fields.c | 33 ++++++-- epan/dissectors/packet-dis-fields.h | 28 ++++++- epan/dissectors/packet-dis-pdus.c | 163 ++++++++++++++++++++++++++++++------ epan/dissectors/packet-dis-pdus.h | 2 +- epan/dissectors/packet-dis.c | 91 +++++++++++++++++--- 7 files changed, 307 insertions(+), 46 deletions(-) diff --git a/epan/dissectors/packet-dis-enums.c b/epan/dissectors/packet-dis-enums.c index b141d36187..9643d83ff3 100644 --- a/epan/dissectors/packet-dis-enums.c +++ b/epan/dissectors/packet-dis-enums.c @@ -451,6 +451,25 @@ const value_string DIS_PDU_MajorModulation_Strings[] = {0, NULL } }; +const range_string DIS_PDU_Link16_CVLL_Strings[] = { + { 0, 127, "Crypto Variable" }, + { 255, 255, "NO STATEMENT" }, + { 0, 0, NULL } +}; + +const value_string DIS_PDU_Link16_MessageType_Strings[] = +{ + { DIS_MESSAGE_TYPE_JTIDS_HEADER_MESSAGES, "JTIDS Header/Messages" }, + { DIS_MESSAGE_TYPE_RTT_A_B, "RTT A/B" }, + { DIS_MESSAGE_TYPE_RTT_REPLY, "RTT Reply" }, + { DIS_MESSAGE_TYPE_JTIDS_VOICE_CVSD, "JTIDS Voice CVSD" }, + { DIS_MESSAGE_TYPE_JTIDS_VOICE_LPC10, "JTIDS Voice LPC10" }, + { DIS_MESSAGE_TYPE_JTIDS_VOICE_LPC12, "JTIDS Voice LPC12" }, + { DIS_MESSAGE_TYPE_JTIDS_LET, "JTIDS LET" }, + { DIS_MESSAGE_TYPE_VMF, "VMF" }, + { 0, NULL } +}; + const value_string DIS_PDU_EmissionFunction_Strings[] = { {DIS_EMISSION_FUNCTION_OTHER, "Other" }, @@ -661,6 +680,7 @@ const value_string DIS_PDU_TerminalSecondaryMode_Strings[] = {0, NULL } }; +/* http://discussions.sisostds.org/threadview.aspx?fid=18&threadid=53172 */ const value_string DIS_PDU_ModParamSyncState_Strings[] = { {2, "Coarse Synchronization" }, diff --git a/epan/dissectors/packet-dis-enums.h b/epan/dissectors/packet-dis-enums.h index 6ab54dcb40..d55ad2da4c 100644 --- a/epan/dissectors/packet-dis-enums.h +++ b/epan/dissectors/packet-dis-enums.h @@ -46,6 +46,8 @@ extern const value_string DIS_PDU_TSAllocationFidelity_Strings[]; extern const value_string DIS_PDU_TerminalPrimaryMode_Strings[]; extern const value_string DIS_PDU_TerminalSecondaryMode_Strings[]; extern const value_string DIS_PDU_ModParamSyncState_Strings[]; +extern const range_string DIS_PDU_Link16_CVLL_Strings[]; +extern const value_string DIS_PDU_Link16_MessageType_Strings[]; typedef enum @@ -434,6 +436,20 @@ typedef enum extern const value_string DIS_PDU_MajorModulation_Strings[]; +typedef enum +{ + DIS_MESSAGE_TYPE_JTIDS_HEADER_MESSAGES = 0, + DIS_MESSAGE_TYPE_RTT_A_B, + DIS_MESSAGE_TYPE_RTT_REPLY, + DIS_MESSAGE_TYPE_JTIDS_VOICE_CVSD, + DIS_MESSAGE_TYPE_JTIDS_VOICE_LPC10, + DIS_MESSAGE_TYPE_JTIDS_VOICE_LPC12, + DIS_MESSAGE_TYPE_JTIDS_LET, + DIS_MESSAGE_TYPE_VMF +} DIS_PDU_MessageType; + +extern const value_string DIS_PDU_JTIDS_MessageType_Strings[]; + typedef enum { DIS_EMISSION_FUNCTION_OTHER = 0, diff --git a/epan/dissectors/packet-dis-fields.c b/epan/dissectors/packet-dis-fields.c index 9d0088e8b3..60c4c5bf81 100644 --- a/epan/dissectors/packet-dis-fields.c +++ b/epan/dissectors/packet-dis-fields.c @@ -41,7 +41,9 @@ guint32 category; guint32 radioID; guint32 disRadioTransmitState; guint32 encodingScheme; +guint32 tdlType; guint32 numSamples; +guint32 messageType; guint32 numFixed; guint32 numVariable; guint32 numBeams; @@ -207,6 +209,20 @@ DIS_ParserNode DIS_FIELDS_MOD_PARAMS_JTIDS_MIDS[] = { DIS_FIELDTYPE_END, NULL,0,0,0,0 } }; +DIS_ParserNode DIS_FIELDS_SIGNAL_LINK16_NETWORK_HEADER[] = +{ + { DIS_FIELDTYPE_LINK16_NPG, "Network Participant Group",0,0,0,0 }, + { DIS_FIELDTYPE_UINT8, "Network Number",0,0,0,0 }, + { DIS_FIELDTYPE_LINK16_TSEC_CVLL, "TSEC CVLL",0,0,0,0 }, + { DIS_FIELDTYPE_LINK16_MSEC_CVLL, "MSEC CVLL",0,0,0,0 }, + { DIS_FIELDTYPE_LINK16_MESSAGE_TYPE, "Message Type",0,0,0,&messageType }, + { DIS_FIELDTYPE_UINT16, "Padding",0,0,0,0 }, + { DIS_FIELDTYPE_UINT32, "Time Slot ID",0,0,0,0 }, + { DIS_FIELDTYPE_LINK16_PTT, "Perceived Transmit Time",0,0,0,0 }, + { DIS_FIELDTYPE_LINK16_MESSAGE_DATA, "Message Data",0,0,0,0 }, + { DIS_FIELDTYPE_END, NULL,0,0,0,0 } +}; + /* Array records */ DIS_ParserNode DIS_FIELDS_FIXED_DATUM[] = @@ -511,6 +527,7 @@ void initializeFieldParsers(void) initializeParser(DIS_FIELDS_VR_UA_BEAM); initializeParser(DIS_FIELDS_MOD_PARAMS_CCTT_SINCGARS); initializeParser(DIS_FIELDS_MOD_PARAMS_JTIDS_MIDS); + initializeParser(DIS_FIELDS_SIGNAL_LINK16_NETWORK_HEADER); } @@ -866,6 +883,10 @@ gint parseField_Enum(tvbuff_t *tvb, proto_tree *tree, gint offset, DIS_ParserNod break; } break; + case DIS_FIELDTYPE_LINK16_MESSAGE_TYPE: + enumStrings = DIS_PDU_Link16_MessageType_Strings; + dis_hf_id = hf_dis_signal_link16_message_type; + break; default: enumStrings = 0; break; @@ -1017,7 +1038,7 @@ gint parseField_Timestamp(tvbuff_t *tvb, proto_tree *tree, gint offset, DIS_Pars /* Parse a variable parameter field. */ -gint parseField_VariableParameter(tvbuff_t *tvb, proto_tree *tree, gint offset) +gint parseField_VariableParameter(tvbuff_t *tvb, proto_tree *tree, gint offset, packet_info *pinfo) { DIS_ParserNode *paramParser = 0; @@ -1043,7 +1064,7 @@ gint parseField_VariableParameter(tvbuff_t *tvb, proto_tree *tree, gint offset) /* Parse the variable parameter fields */ if (paramParser) { - offset = parseFields(tvb, tree, offset, paramParser); + offset = parseFields(tvb, tree, offset, paramParser, pinfo); } return offset; @@ -1051,7 +1072,7 @@ gint parseField_VariableParameter(tvbuff_t *tvb, proto_tree *tree, gint offset) /* Parse a variable record field. */ -gint parseField_VariableRecord(tvbuff_t *tvb, proto_tree *tree, gint offset) +gint parseField_VariableRecord(tvbuff_t *tvb, proto_tree *tree, gint offset, packet_info *pinfo) { DIS_ParserNode *paramParser = 0; @@ -1084,7 +1105,7 @@ gint parseField_VariableRecord(tvbuff_t *tvb, proto_tree *tree, gint offset) /* Parse the variable record fields */ if (paramParser) { - offset = parseFields(tvb, tree, offset, paramParser); + offset = parseFields(tvb, tree, offset, paramParser, pinfo); } /* Should alignment padding be added */ @@ -1103,7 +1124,7 @@ gint parseField_VariableRecord(tvbuff_t *tvb, proto_tree *tree, gint offset) /* Parse a variable electromagnetic emission system beam. */ gint parseField_ElectromagneticEmissionSystemBeam( - tvbuff_t *tvb, proto_tree *tree, gint offset) + tvbuff_t *tvb, proto_tree *tree, gint offset, packet_info *pinfo) { DIS_ParserNode *paramParser = 0; @@ -1114,7 +1135,7 @@ gint parseField_ElectromagneticEmissionSystemBeam( /* Parse the variable parameter fields */ if (paramParser) { - offset = parseFields(tvb, tree, offset, paramParser); + offset = parseFields(tvb, tree, offset, paramParser, pinfo); } return offset; diff --git a/epan/dissectors/packet-dis-fields.h b/epan/dissectors/packet-dis-fields.h index 28b86f6d83..d72b9963c6 100644 --- a/epan/dissectors/packet-dis-fields.h +++ b/epan/dissectors/packet-dis-fields.h @@ -52,6 +52,7 @@ extern int hf_dis_radio_id; extern int hf_dis_ens; extern int hf_dis_ens_class; extern int hf_dis_ens_type; +extern int hf_dis_ens_type_audio; extern int hf_dis_tdl_type; extern int hf_dis_sample_rate; extern int hf_dis_data_length; @@ -94,9 +95,21 @@ extern int hf_dis_antenna_pattern_parameter_dump; extern int hf_dis_num_shafts; extern int hf_dis_num_apas; extern int hf_dis_num_ua_emitter_systems; +extern int hf_dis_signal_link16_npg; +extern int hf_dis_signal_link16_tsec_cvll; +extern int hf_dis_signal_link16_msec_cvll; +extern int hf_dis_signal_link16_message_type; +extern int hf_dis_signal_link16_ptt; +extern int hf_dis_signal_link16_time_slot_type; +extern int hf_dis_signal_link16_rti; +extern int hf_dis_signal_link16_stn; +extern int hf_dis_signal_link16_sdusn; extern int ett_dis_ens; extern int ett_dis_crypto_key; +extern int ett_dis_signal_link16_network_header; +extern int ett_dis_signal_link16_message_data; +extern int ett_dis_signal_link16_jtids_header; @@ -212,6 +225,10 @@ typedef enum DIS_FIELDTYPE_TRANSMITTER_SECONDARY_MODE, DIS_FIELDTYPE_JTIDS_SYNC_STATE, DIS_FIELDTYPE_NETWORK_SYNC_ID, + DIS_FIELDTYPE_LINK16_NPG, + DIS_FIELDTYPE_LINK16_TSEC_CVLL, + DIS_FIELDTYPE_LINK16_MSEC_CVLL, + DIS_FIELDTYPE_LINK16_MESSAGE_TYPE, DIS_FIELDTYPE_NUM_ELECTROMAGNETIC_EMISSION_SYSTEMS, DIS_FIELDTYPE_NUM_OF_SHAFTS, DIS_FIELDTYPE_NUM_OF_APAS, @@ -242,6 +259,8 @@ typedef enum DIS_FIELDTYPE_ANTENNA_PATTERN_PARAMETERS, DIS_FIELDTYPE_MOD_PARAMS_CCTT_SINCGARS, DIS_FIELDTYPE_MOD_PARAMS_JTIDS_MIDS, + DIS_FIELDTYPE_LINK16_MESSAGE_DATA, + DIS_FIELDTYPE_LINK16_PTT, DIS_FIELDTYPE_ELECTROMAGNETIC_EMISSION_SYSTEM_BEAM, DIS_FIELDTYPE_ELECTROMAGNETIC_EMISSION_SYSTEM, DIS_FIELDTYPE_EMITTER_SYSTEM, @@ -314,6 +333,7 @@ extern DIS_ParserNode DIS_FIELDS_VECTOR_FLOAT_32[]; extern DIS_ParserNode DIS_FIELDS_VECTOR_FLOAT_64[]; extern DIS_ParserNode DIS_FIELDS_MOD_PARAMS_CCTT_SINCGARS[]; extern DIS_ParserNode DIS_FIELDS_MOD_PARAMS_JTIDS_MIDS[]; +extern DIS_ParserNode DIS_FIELDS_SIGNAL_LINK16_NETWORK_HEADER[]; extern DIS_ParserNode DIS_FIELDS_EMITTER_SYSTEM[]; extern DIS_ParserNode DIS_FIELDS_FUNDAMENTAL_PARAMETER_DATA[]; extern DIS_ParserNode DIS_FIELDS_TRACK_JAM[]; @@ -358,11 +378,11 @@ extern gint parseField_Double(tvbuff_t *tvb, proto_tree *tree, gint offset, DIS_ extern gint parseField_Timestamp(tvbuff_t *tvb, proto_tree *tree, gint offset, DIS_ParserNode parserNode); -extern gint parseField_VariableParameter(tvbuff_t *tvb, proto_tree *tree, gint offset); +extern gint parseField_VariableParameter(tvbuff_t *tvb, proto_tree *tree, gint offset, packet_info *pinfo); -extern gint parseField_VariableRecord(tvbuff_t *tvb, proto_tree *tree, gint offset); +extern gint parseField_VariableRecord(tvbuff_t *tvb, proto_tree *tree, gint offset, packet_info *pinfo); -extern gint parseField_ElectromagneticEmissionSystemBeam(tvbuff_t *tvb, proto_tree *tree, gint offset); +extern gint parseField_ElectromagneticEmissionSystemBeam(tvbuff_t *tvb, proto_tree *tree, gint offset, packet_info *pinfo); extern guint32 disProtocolVersion; extern guint32 pduType; @@ -373,7 +393,9 @@ extern guint32 entityDomain; extern guint32 radioID; extern guint32 disRadioTransmitState; extern guint32 encodingScheme; +extern guint32 tdlType; extern guint32 numSamples; +extern guint32 messageType; extern guint32 numFixed; extern guint32 numVariable; extern guint32 numBeams; diff --git a/epan/dissectors/packet-dis-pdus.c b/epan/dissectors/packet-dis-pdus.c index 3d1df520af..10b6d997d8 100644 --- a/epan/dissectors/packet-dis-pdus.c +++ b/epan/dissectors/packet-dis-pdus.c @@ -27,6 +27,7 @@ #include "packet-dis-pdus.h" #include "packet-dis-fields.h" #include "packet-dis-enums.h" +#include "packet-link16.h" #define DIS_PDU_MAX_VARIABLE_PARAMETERS 16 #define DIS_PDU_MAX_VARIABLE_RECORDS 16 @@ -129,7 +130,7 @@ DIS_ParserNode DIS_PARSER_SIGNAL_PDU[] = { DIS_FIELDTYPE_ENTITY_ID, "Entity ID",0,0,0,0 }, { DIS_FIELDTYPE_RADIO_ID, "Radio ID",0,0,0,&radioID }, { DIS_FIELDTYPE_ENCODING_SCHEME, "Encoding Scheme",0,0,0,&encodingScheme }, - { DIS_FIELDTYPE_TDL_TYPE, "TDL Type",0,0,0,0 }, + { DIS_FIELDTYPE_TDL_TYPE, "TDL Type",0,0,0,&tdlType }, { DIS_FIELDTYPE_SAMPLE_RATE, "Sample Rate",0,0,0,0 }, { DIS_FIELDTYPE_DATA_LENGTH, "Data Length",0,0,0,0 }, { DIS_FIELDTYPE_NUMBER_OF_SAMPLES, "Number of Samples",0,0,0,&numSamples }, @@ -730,9 +731,87 @@ void initializeParser(DIS_ParserNode parserNodes[]) } } +static const int * jtids_message_header_fields[] = { + &hf_dis_signal_link16_time_slot_type, + &hf_dis_signal_link16_rti, + &hf_dis_signal_link16_stn, + NULL +}; + +/* Parse Link 16 Message Data record (SISO-STD-002, Tables 5.2.5 through 5.2.12) + */ +static gint parse_Link16_Message_Data(proto_tree *tree, tvbuff_t *tvb, gint offset, packet_info *pinfo) +{ + guint32 cache, value, i; + Link16State state; + tvbuff_t *newtvb; + + switch (messageType) { + case DIS_MESSAGE_TYPE_JTIDS_HEADER_MESSAGES: + proto_tree_add_bitmask_text(tree, tvb, offset, 4, "JTIDS Header", NULL, ett_dis_signal_link16_jtids_header, jtids_message_header_fields, ENC_BIG_ENDIAN, BMT_NO_APPEND); + + cache = tvb_get_ntohl(tvb, offset); + value = (cache >> 4) & 0x7FFF; + col_append_fstr(pinfo->cinfo, COL_INFO, ", STN=0%o, Link 16 Words:", value); + + value = (cache >> 19); + offset += 4; + cache = tvb_get_ntohl(tvb, offset); + value |= (cache & 0x7) << 13; + proto_tree_add_uint(tree, hf_dis_signal_link16_sdusn, tvb, offset - 4, 8, value); + offset += 4; + + memset(&state, 0, sizeof(state)); + + for (i = 0; i < (encodingScheme & 0x3FFF); i++) { + gint8 *word = (gint8 *)g_malloc(10); + if (!(i & 1)) { + word[0] = (cache >> 16) & 0xFF; + word[1] = (cache >> 24) & 0xFF; + cache = tvb_get_ntohl(tvb, offset); + offset += 4; + word[2] = cache & 0xFF; + word[3] = (cache >> 8) & 0xFF; + word[4] = (cache >> 16) & 0xFF; + word[5] = (cache >> 24) & 0xFF; + cache = tvb_get_ntohl(tvb, offset); + offset += 4; + word[6] = cache & 0xFF; + word[7] = (cache >> 8) & 0xFF; + word[8] = (cache >> 16) & 0xFF; + word[9] = (cache >> 24) & 0xFF; + } else { + cache = tvb_get_ntohl(tvb, offset); + offset += 4; + word[0] = cache & 0xFF; + word[1] = (cache >> 8) & 0xFF; + word[2] = (cache >> 16) & 0xFF; + word[3] = (cache >> 24) & 0xFF; + cache = tvb_get_ntohl(tvb, offset); + offset += 4; + word[4] = cache & 0xFF; + word[5] = (cache >> 8) & 0xFF; + word[6] = (cache >> 16) & 0xFF; + word[7] = (cache >> 24) & 0xFF; + cache = tvb_get_ntohl(tvb, offset); + offset += 4; + word[8] = cache & 0xFF; + word[9] = (cache >> 8) & 0xFF; + } + + newtvb = tvb_new_child_real_data(tvb, word, 10, 10); + tvb_set_free_cb(newtvb, g_free); + add_new_data_source(pinfo, newtvb, "Link 16 Word"); + call_dissector_with_data(find_dissector("link16"), newtvb, pinfo, tree, &state); + } + break; + } + return offset; +} + /* Parse packet data based on a specified array of DIS_ParserNodes. */ -gint parseFields(tvbuff_t *tvb, proto_tree *tree, gint offset, DIS_ParserNode parserNodes[]) +gint parseFields(tvbuff_t *tvb, proto_tree *tree, gint offset, DIS_ParserNode parserNodes[], packet_info *pinfo) { guint fieldIndex = 0; guint fieldRepeatLen = 0; @@ -837,13 +916,17 @@ gint parseFields(tvbuff_t *tvb, proto_tree *tree, gint offset, DIS_ParserNode pa pi = proto_tree_add_item(tree, hf_dis_ens, tvb, offset, 2, ENC_BIG_ENDIAN); sub_tree = proto_item_add_subtree(pi, ett_dis_ens); proto_tree_add_item(sub_tree, hf_dis_ens_class, tvb, offset, 2, ENC_BIG_ENDIAN); - proto_tree_add_item(sub_tree, hf_dis_ens_type, tvb, offset, 2, ENC_BIG_ENDIAN); + proto_tree_add_item(sub_tree, + (uintVal >> 14) == DIS_ENCODING_CLASS_ENCODED_AUDIO ? hf_dis_ens_type_audio : hf_dis_ens_type, + tvb, offset, 2, ENC_BIG_ENDIAN); proto_item_set_end(pi, tvb, offset); *(parserNodes[fieldIndex].outputVar) = (guint32)uintVal; offset += 2; break; case DIS_FIELDTYPE_TDL_TYPE: + uintVal = tvb_get_ntohs(tvb, offset); proto_tree_add_item(tree, hf_dis_tdl_type, tvb, offset, 2, ENC_BIG_ENDIAN); + *(parserNodes[fieldIndex].outputVar) = (guint32)uintVal; offset += 2; break; case DIS_FIELDTYPE_SAMPLE_RATE: @@ -860,12 +943,30 @@ gint parseFields(tvbuff_t *tvb, proto_tree *tree, gint offset, DIS_ParserNode pa *(parserNodes[fieldIndex].outputVar) = (guint32)uintVal; offset += 2; break; - case DIS_FIELDTYPE_RADIO_DATA: - newtvb = tvb_new_subset_remaining(tvb, offset); - proto_tree_add_item(tree, hf_dis_signal_data, newtvb, 0, -1, ENC_NA ); + if (tdlType == DIS_TDL_TYPE_LINK16_STD) { + pi = proto_tree_add_text(tree, tvb, offset, 16, "Link 16 Network Header"); + sub_tree = proto_item_add_subtree(pi, ett_dis_signal_link16_network_header); + offset = parseFields(tvb, sub_tree, offset, DIS_FIELDS_SIGNAL_LINK16_NETWORK_HEADER, pinfo); + proto_item_set_end(pi, tvb, offset); + + pi = proto_tree_add_text(tree, tvb, offset, -1, "Link 16 Message Data: %s", + val_to_str(messageType, DIS_PDU_Link16_MessageType_Strings, "")); + sub_tree = proto_item_add_subtree(pi, ett_dis_signal_link16_message_data); + offset = parse_Link16_Message_Data(sub_tree, tvb, offset, pinfo); + proto_item_set_end(pi, tvb, offset); + } else { + proto_tree_add_item(tree, hf_dis_signal_data, tvb, offset, -1, ENC_NA ); + } /* ****ck******* need to look for padding bytes */ break; + case DIS_FIELDTYPE_LINK16_PTT: + if (tvb_get_ntohl(tvb, offset) == 0xFFFFFFFF) + proto_tree_add_text(tree, tvb, offset, 8, "%s: NO STATEMENT", parserNodes[fieldIndex].fieldLabel); + else + proto_tree_add_item(tree, hf_dis_signal_link16_ptt, tvb, offset, 8, ENC_TIME_NTP|ENC_BIG_ENDIAN); + offset += 8; + break; case DIS_FIELDTYPE_RADIO_CATEGORY: proto_tree_add_item(tree, hf_dis_radio_category, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; @@ -1001,7 +1102,7 @@ gint parseFields(tvbuff_t *tvb, proto_tree *tree, gint offset, DIS_ParserNode pa pi = proto_tree_add_text(tree, tvb, offset, -1, "%s", parserNodes[fieldIndex].fieldLabel); sub_tree = proto_item_add_subtree(pi, parserNodes[fieldIndex].ettVar); - offset = parseFields(tvb, sub_tree, offset, DIS_FIELDS_MOD_PARAMS_CCTT_SINCGARS); + offset = parseFields(tvb, sub_tree, offset, DIS_FIELDS_MOD_PARAMS_CCTT_SINCGARS, pinfo); proto_item_set_end(pi, tvb, offset); break; } @@ -1009,7 +1110,7 @@ gint parseFields(tvbuff_t *tvb, proto_tree *tree, gint offset, DIS_ParserNode pa pi = proto_tree_add_text(tree, tvb, offset, -1, "%s", parserNodes[fieldIndex].fieldLabel); sub_tree = proto_item_add_subtree(pi, parserNodes[fieldIndex].ettVar); - offset = parseFields(tvb, sub_tree, offset, DIS_FIELDS_MOD_PARAMS_JTIDS_MIDS); + offset = parseFields(tvb, sub_tree, offset, DIS_FIELDS_MOD_PARAMS_JTIDS_MIDS, pinfo); proto_item_set_end(pi, tvb, offset); break; } @@ -1026,7 +1127,18 @@ gint parseFields(tvbuff_t *tvb, proto_tree *tree, gint offset, DIS_ParserNode pa newtvb = tvb_new_subset_remaining(tvb, offset); proto_tree_add_item(tree, hf_dis_antenna_pattern_parameter_dump, newtvb, 0, -1, ENC_NA ); break; - + case DIS_FIELDTYPE_LINK16_NPG: + proto_tree_add_item(tree, hf_dis_signal_link16_npg, tvb, offset, 2, ENC_BIG_ENDIAN); + offset += 2; + break; + case DIS_FIELDTYPE_LINK16_TSEC_CVLL: + proto_tree_add_item(tree, hf_dis_signal_link16_tsec_cvll, tvb, offset, 1, ENC_NA); + offset++; + break; + case DIS_FIELDTYPE_LINK16_MSEC_CVLL: + proto_tree_add_item(tree, hf_dis_signal_link16_msec_cvll, tvb, offset, 1, ENC_NA); + offset++; + break; /* padding */ case DIS_FIELDTYPE_PAD8: @@ -1064,6 +1176,7 @@ gint parseFields(tvbuff_t *tvb, proto_tree *tree, gint offset, DIS_ParserNode pa case DIS_FIELDTYPE_PERSISTENT_OBJECT_TYPE: case DIS_FIELDTYPE_EMISSION_FUNCTION: case DIS_FIELDTYPE_BEAM_FUNCTION: + case DIS_FIELDTYPE_LINK16_MESSAGE_TYPE: offset = parseField_Enum(tvb, tree, offset, parserNodes[fieldIndex], 1); break; @@ -1208,7 +1321,7 @@ gint parseFields(tvbuff_t *tvb, proto_tree *tree, gint offset, DIS_ParserNode pa proto_item *newSubtree = proto_item_add_subtree(newField, parserNodes[fieldIndex].ettVar); offset = parseFields(tvb, newSubtree, offset, - parserNodes[fieldIndex].children); + parserNodes[fieldIndex].children, pinfo); } proto_item_set_end(newField, tvb, offset); break; @@ -1246,7 +1359,7 @@ gint parseFields(tvbuff_t *tvb, proto_tree *tree, gint offset, DIS_ParserNode pa parserNodes[fieldIndex].fieldLabel); newSubtree = proto_item_add_subtree(newField, ettFixedData); offset = parseFields (tvb, newSubtree, offset, - parserNodes[fieldIndex].children); + parserNodes[fieldIndex].children, pinfo); proto_item_set_end(newField, tvb, offset); } } @@ -1272,7 +1385,7 @@ gint parseFields(tvbuff_t *tvb, proto_tree *tree, gint offset, DIS_ParserNode pa /* XXX is this really necessary? */ tvb_ensure_length_remaining(tvb, offset+4); offset = parseFields (tvb, newSubtree, offset, - parserNodes[fieldIndex].children); + parserNodes[fieldIndex].children, pinfo); } proto_item_set_end(newField, tvb, offset); } @@ -1294,7 +1407,7 @@ gint parseFields(tvbuff_t *tvb, proto_tree *tree, gint offset, DIS_ParserNode pa (newField, ettVariableData); offset = parseFields (tvb, newSubtree, offset, - parserNodes[fieldIndex].children); + parserNodes[fieldIndex].children, pinfo); proto_item_set_end(newField, tvb, offset); } @@ -1319,7 +1432,7 @@ gint parseFields(tvbuff_t *tvb, proto_tree *tree, gint offset, DIS_ParserNode pa { offset = parseFields (tvb, newSubtree, offset, - parserNodes[fieldIndex].children); + parserNodes[fieldIndex].children, pinfo); } proto_item_set_end(newField, tvb, offset); } @@ -1342,9 +1455,9 @@ gint parseFields(tvbuff_t *tvb, proto_tree *tree, gint offset, DIS_ParserNode pa ettVariableParameters[i]); offset = parseFields (tvb, newSubtree, offset, - parserNodes[fieldIndex].children); + parserNodes[fieldIndex].children, pinfo); offset = parseField_VariableParameter - (tvb, newSubtree, offset); + (tvb, newSubtree, offset, pinfo); proto_item_set_end(newField, tvb, offset); } } @@ -1367,9 +1480,9 @@ gint parseFields(tvbuff_t *tvb, proto_tree *tree, gint offset, DIS_ParserNode pa ettVariableRecords[i]); offset = parseFields (tvb, newSubtree, offset, - parserNodes[fieldIndex].children); + parserNodes[fieldIndex].children, pinfo); offset = parseField_VariableRecord - (tvb, newSubtree, offset); + (tvb, newSubtree, offset, pinfo); proto_item_set_end(newField, tvb, offset); } } @@ -1388,7 +1501,7 @@ gint parseFields(tvbuff_t *tvb, proto_tree *tree, gint offset, DIS_ParserNode pa proto_item_add_subtree(newField, parserNodes[fieldIndex].ettVar); offset = parseFields(tvb, newSubtree, offset, - parserNodes[fieldIndex].children); + parserNodes[fieldIndex].children, pinfo); } proto_item_set_end(newField, tvb, offset); } @@ -1408,7 +1521,7 @@ gint parseFields(tvbuff_t *tvb, proto_tree *tree, gint offset, DIS_ParserNode pa proto_item_add_subtree(newField, parserNodes[fieldIndex].ettVar); offset = parseFields(tvb, newSubtree, offset, - parserNodes[fieldIndex].children); + parserNodes[fieldIndex].children, pinfo); } proto_item_set_end(newField, tvb, offset); } @@ -1439,7 +1552,7 @@ gint parseFields(tvbuff_t *tvb, proto_tree *tree, gint offset, DIS_ParserNode pa proto_item_add_subtree(newField, parserNodes[fieldIndex].ettVar); offset = parseFields(tvb, newSubtree, offset, - parserNodes[fieldIndex].children); + parserNodes[fieldIndex].children, pinfo); } proto_item_set_end(newField, tvb, offset); } @@ -1472,7 +1585,7 @@ gint parseFields(tvbuff_t *tvb, proto_tree *tree, gint offset, DIS_ParserNode pa proto_item_add_subtree(newField, parserNodes[fieldIndex].ettVar); offset = parseFields(tvb, newSubtree, offset, - parserNodes[fieldIndex].children); + parserNodes[fieldIndex].children, pinfo); } proto_item_set_end(newField, tvb, offset); } @@ -1505,7 +1618,7 @@ gint parseFields(tvbuff_t *tvb, proto_tree *tree, gint offset, DIS_ParserNode pa proto_item_add_subtree(newField, parserNodes[fieldIndex].ettVar); offset = parseFields(tvb, newSubtree, offset, - parserNodes[fieldIndex].children); + parserNodes[fieldIndex].children, pinfo); } proto_item_set_end(newField, tvb, offset); } @@ -1545,7 +1658,7 @@ gint parseFields(tvbuff_t *tvb, proto_tree *tree, gint offset, DIS_ParserNode pa proto_item_add_subtree(newField, parserNodes[fieldIndex].ettVar); offset = parseFields(tvb, newSubtree, offset, - parserNodes[fieldIndex].children); + parserNodes[fieldIndex].children, pinfo); } proto_item_set_end(newField, tvb, offset); } @@ -1570,7 +1683,7 @@ gint parseFields(tvbuff_t *tvb, proto_tree *tree, gint offset, DIS_ParserNode pa proto_item_add_subtree(newField, parserNodes[fieldIndex].ettVar); offset = parseFields(tvb, newSubtree, offset, - parserNodes[fieldIndex].children); + parserNodes[fieldIndex].children, pinfo); } proto_item_set_end(newField, tvb, offset); } diff --git a/epan/dissectors/packet-dis-pdus.h b/epan/dissectors/packet-dis-pdus.h index 6bcda41730..cc861df1ea 100644 --- a/epan/dissectors/packet-dis-pdus.h +++ b/epan/dissectors/packet-dis-pdus.h @@ -109,6 +109,6 @@ void initializeParser(DIS_ParserNode parserNodes[]); void initializeParsers(void); -gint parseFields(tvbuff_t *tvb, proto_tree *tree, gint offset, DIS_ParserNode parserNodes[]); +gint parseFields(tvbuff_t *tvb, proto_tree *tree, gint offset, DIS_ParserNode parserNodes[], packet_info *pinfo); #endif /* packet-dis-pduparsers.h */ diff --git a/epan/dissectors/packet-dis.c b/epan/dissectors/packet-dis.c index d43b7bb0ae..6a47a6a116 100644 --- a/epan/dissectors/packet-dis.c +++ b/epan/dissectors/packet-dis.c @@ -44,6 +44,7 @@ #include "packet-dis-enums.h" #include "packet-dis-pdus.h" #include "packet-dis-fields.h" +#include "packet-link16.h" #define DEFAULT_DIS_UDP_PORT 3000 @@ -78,6 +79,7 @@ int hf_dis_radio_id = -1; int hf_dis_ens = -1; int hf_dis_ens_class = -1; int hf_dis_ens_type = -1; +int hf_dis_ens_type_audio = -1; int hf_dis_tdl_type = -1; int hf_dis_sample_rate = -1; int hf_dis_data_length = -1; @@ -120,6 +122,15 @@ int hf_dis_antenna_pattern_parameter_dump = -1; int hf_dis_num_shafts = -1; int hf_dis_num_apas = -1; int hf_dis_num_ua_emitter_systems = -1; +int hf_dis_signal_link16_npg = -1; +int hf_dis_signal_link16_tsec_cvll = -1; +int hf_dis_signal_link16_msec_cvll = -1; +int hf_dis_signal_link16_message_type = -1; +int hf_dis_signal_link16_ptt = -1; +int hf_dis_signal_link16_time_slot_type = - 1; +int hf_dis_signal_link16_rti = -1; +int hf_dis_signal_link16_stn = -1; +int hf_dis_signal_link16_sdusn = -1; /* Initialize the subtree pointers */ static gint ett_dis = -1; @@ -128,6 +139,9 @@ static gint ett_dis_po_header = -1; static gint ett_dis_payload = -1; int ett_dis_ens = -1; int ett_dis_crypto_key = -1; +int ett_dis_signal_link16_network_header = -1; +int ett_dis_signal_link16_message_data = -1; +int ett_dis_signal_link16_jtids_header = -1; static const true_false_string dis_modulation_spread_spectrum = { "Spread Spectrum modulation in use", @@ -204,7 +218,7 @@ static gint dissect_dis(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, voi */ 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); + offset = parseFields(tvb, dis_header_tree, offset, DIS_FIELDS_PDU_HEADER, pinfo); proto_item_set_end(dis_header_node, tvb, offset); @@ -228,7 +242,7 @@ static gint dissect_dis(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, voi (dis_po_header_node, ett_dis_po_header); offset = parseFields (tvb, dis_po_header_tree, offset, - DIS_FIELDS_PERSISTENT_OBJECT_HEADER); + DIS_FIELDS_PERSISTENT_OBJECT_HEADER, pinfo); proto_item_set_end(dis_po_header_node, tvb, offset); /* Locate the appropriate PO PDU parser, if type is known. @@ -398,13 +412,15 @@ static gint dissect_dis(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, voi break; } + col_clear(pinfo->cinfo, COL_INFO); + /* 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); + offset = parseFields(tvb, dis_payload_tree, offset, pduParser, pinfo); proto_item_set_end(dis_payload_node, tvb, offset); } @@ -432,13 +448,17 @@ static gint dissect_dis(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, voi ); break; case DIS_PDUTYPE_SIGNAL: - col_add_fstr( pinfo->cinfo, COL_INFO, - "PDUType: %s, RadioID=%u, Encoding Type=%s, Number of Samples=%u", - pduString, - radioID, - val_to_str_const(DIS_ENCODING_TYPE(encodingScheme), DIS_PDU_Encoding_Type_Strings, "Unknown Encoding Type"), - numSamples - ); + if (numSamples) + col_prepend_fstr(pinfo->cinfo, COL_INFO, ", Number of Samples=%u", + numSamples); + + if ((encodingScheme & 0xC000) >> 14 == DIS_ENCODING_CLASS_ENCODED_AUDIO) + col_prepend_fstr(pinfo->cinfo, COL_INFO,", Encoding Type=%s", + val_to_str_const(DIS_ENCODING_TYPE(encodingScheme), + DIS_PDU_Encoding_Type_Strings, "Unknown")); + + col_prepend_fstr( pinfo->cinfo, COL_INFO, + "PDUType: %s, RadioID=%u", pduString, radioID); break; case DIS_PDUTYPE_TRANSMITTER: col_add_fstr( pinfo->cinfo, COL_INFO, @@ -591,6 +611,11 @@ void proto_register_dis(void) }, { &hf_dis_ens_type, { "Encoding Type", "dis.radio.encoding_type", + FT_UINT16, BASE_DEC, NULL, 0x3fff, + NULL, HFILL } + }, + { &hf_dis_ens_type_audio, + { "Encoding Type", "dis.radio.encoding_type.audio", FT_UINT16, BASE_DEC, VALS(DIS_PDU_Encoding_Type_Strings), 0x3fff, NULL, HFILL } }, @@ -789,6 +814,47 @@ void proto_register_dis(void) FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL} }, + { &hf_dis_signal_link16_npg, + { "NPG Number", "dis.signal.link16.npg", + FT_UINT16, BASE_DEC, VALS(Link16_NPG_Strings), 0x0, + NULL, HFILL } + }, + { &hf_dis_signal_link16_tsec_cvll, + { "TSEC CVLL", "dis.signal.link16.tsec_cvll", + FT_UINT8, BASE_RANGE_STRING | BASE_DEC, RVALS(DIS_PDU_Link16_CVLL_Strings), 0x0, + NULL, HFILL } + }, + { &hf_dis_signal_link16_msec_cvll, + { "MSEC CVLL", "dis.signal.link16.msec_cvll", + FT_UINT8, BASE_RANGE_STRING | BASE_DEC, RVALS(DIS_PDU_Link16_CVLL_Strings), 0x0, + NULL, HFILL } + }, + { &hf_dis_signal_link16_message_type, + { "Message Type", "dis.signal.link16.message_type", + FT_UINT8, BASE_DEC, VALS(DIS_PDU_Link16_MessageType_Strings), 0x0, + NULL, HFILL } + }, + { &hf_dis_signal_link16_ptt, + { "Perceived Transmit Time", "dis.signal.link16.ptt", + FT_ABSOLUTE_TIME, ABSOLUTE_TIME_UTC, NULL, 0x0, + NULL, HFILL } + }, + { &hf_dis_signal_link16_time_slot_type, + { "Time Slot Type", "dis.signal.link16.time_slot_type", FT_UINT32, BASE_DEC, NULL, 0x7, + NULL, HFILL}, + }, + { &hf_dis_signal_link16_rti, + { "Relay Transmission Indicator", "dis.signal.link16.relay", FT_BOOLEAN, 32, NULL, 0x8, + NULL, HFILL}, + }, + { &hf_dis_signal_link16_stn, + { "Source Track Number", "dis.signal.link16.stn", FT_UINT32, BASE_OCT, NULL, 0x7FFF0, + NULL, HFILL }, + }, + { &hf_dis_signal_link16_sdusn, + { "Secure Data Unit Serial Number", "dis.signal.link16.sdusn", FT_UINT16, BASE_DEC, NULL, 0x0, + NULL, HFILL }, + }, { &hf_dis_num_shafts, { "Number of Shafts", "dis.ua.number_of_shafts", FT_UINT8, BASE_DEC, NULL, 0x0, @@ -814,7 +880,10 @@ void proto_register_dis(void) &ett_dis_po_header, &ett_dis_ens, &ett_dis_crypto_key, - &ett_dis_payload + &ett_dis_payload, + &ett_dis_signal_link16_network_header, + &ett_dis_signal_link16_message_data, + &ett_dis_signal_link16_jtids_header, }; module_t *dis_module; -- cgit v1.2.3