diff options
-rw-r--r-- | epan/dissectors/packet-sua.c | 72 |
1 files changed, 55 insertions, 17 deletions
diff --git a/epan/dissectors/packet-sua.c b/epan/dissectors/packet-sua.c index 48993923ed..7091c93c63 100644 --- a/epan/dissectors/packet-sua.c +++ b/epan/dissectors/packet-sua.c @@ -33,6 +33,7 @@ # include "config.h" #endif +#include <string.h> #include <epan/packet.h> #include <epan/prefs.h> #include <epan/sctpppids.h> @@ -350,6 +351,9 @@ static int sua_tap = -1; static mtp3_addr_pc_t *sua_dpc; static mtp3_addr_pc_t *sua_opc; +static guint16 sua_ri; +static gchar *sua_source_gt; +static gchar *sua_destination_gt; static dissector_handle_t data_handle; static dissector_table_t sccp_ssn_dissector_table; @@ -364,6 +368,7 @@ typedef enum { } Version_Type; static gint version = SUA_RFC; +static gint set_addresses = FALSE; static void dissect_parameters(tvbuff_t *tlv_tvb, proto_tree *tree, tvbuff_t **data_tvb, guint8 *source_ssn, guint8 *dest_ssn); @@ -730,6 +735,8 @@ dissect_source_address_parameter(tvbuff_t *parameter_tvb, proto_tree *parameter_ proto_tree *address_indicator_tree; tvbuff_t *parameters_tvb; + sua_ri = tvb_get_ntohs(parameter_tvb, ROUTING_INDICATOR_OFFSET); + if(parameter_tree) { proto_tree_add_item(parameter_tree, hf_source_address_routing_indicator, parameter_tvb, ROUTING_INDICATOR_OFFSET, ROUTING_INDICATOR_LENGTH, ENC_BIG_ENDIAN); address_indicator_item = proto_tree_add_text(parameter_tree, parameter_tvb, ADDRESS_INDICATOR_OFFSET, ADDRESS_INDICATOR_LENGTH, "Address Indicator"); @@ -751,6 +758,8 @@ dissect_destination_address_parameter(tvbuff_t *parameter_tvb, proto_tree *param proto_tree *address_indicator_tree; tvbuff_t *parameters_tvb; + sua_ri = tvb_get_ntohs(parameter_tvb, ROUTING_INDICATOR_OFFSET); + if(parameter_tree) { proto_tree_add_item(parameter_tree, hf_destination_address_routing_indicator, parameter_tvb, ROUTING_INDICATOR_OFFSET, ROUTING_INDICATOR_LENGTH, ENC_BIG_ENDIAN); address_indicator_item = proto_tree_add_text(parameter_tree, parameter_tvb, ADDRESS_INDICATOR_OFFSET, ADDRESS_INDICATOR_LENGTH, "Address Indicator"); @@ -1194,14 +1203,16 @@ static const value_string nature_of_address_values[] = { { 0, NULL } }; static void -dissect_global_title_parameter(tvbuff_t *parameter_tvb, proto_tree *parameter_tree) +dissect_global_title_parameter(tvbuff_t *parameter_tvb, proto_tree *parameter_tree, gboolean source) { guint16 global_title_length; guint16 offset; gboolean even_length; guint8 odd_signal, even_signal; guint8 number_of_digits; - char gt_digits[GT_MAX_SIGNALS+1] = { 0 }; + char *gt_digits; + + gt_digits = ep_alloc0(GT_MAX_SIGNALS+1); global_title_length = tvb_get_ntohs(parameter_tvb, PARAMETER_LENGTH_OFFSET) - (PARAMETER_HEADER_LENGTH + RESERVED_3_LENGTH + GTI_LENGTH + NO_OF_DIGITS_LENGTH + TRANSLATION_TYPE_LENGTH + NUMBERING_PLAN_LENGTH + NATURE_OF_ADDRESS_LENGTH); @@ -1236,6 +1247,14 @@ dissect_global_title_parameter(tvbuff_t *parameter_tvb, proto_tree *parameter_tr parameter_tvb, GLOBAL_TITLE_OFFSET, global_title_length, gt_digits, "Address information (digits): %s", gt_digits); + + if (sua_ri == ROUTE_ON_GT_ROUTING_INDICATOR) { + if (source) { + sua_source_gt = gt_digits; + } else { + sua_destination_gt = gt_digits; + } + } } #define POINT_CODE_LENGTH 4 @@ -1248,12 +1267,14 @@ dissect_point_code_parameter(tvbuff_t *parameter_tvb, proto_tree *parameter_tree pc = tvb_get_ntohl(parameter_tvb, POINT_CODE_OFFSET); - if (source) { - sua_opc->type = mtp3_standard; - sua_opc->pc = pc; - } else { - sua_dpc->type = mtp3_standard; - sua_dpc->pc = pc; + if (sua_ri == ROUTE_ON_SSN_PC_ROUTING_INDICATOR) { + if (source) { + sua_opc->type = mtp3_standard; + sua_opc->pc = pc; + } else { + sua_dpc->type = mtp3_standard; + sua_dpc->pc = pc; + } } proto_tree_add_item(parameter_tree, hf_point_code_dpc, parameter_tvb, POINT_CODE_OFFSET, POINT_CODE_LENGTH, ENC_BIG_ENDIAN); @@ -1556,7 +1577,8 @@ dissect_v8_parameter(tvbuff_t *parameter_tvb, proto_tree *tree, tvbuff_t **data_ dissect_drn_label_parameter(parameter_tvb, parameter_tree); break; case V8_GLOBAL_TITLE_PARAMETER_TAG: - dissect_global_title_parameter(parameter_tvb, parameter_tree); + /* Reuse whether we have source_ssn or not to determine which address we're looking at */ + dissect_global_title_parameter(parameter_tvb, parameter_tree, (source_ssn != NULL)); break; case V8_POINT_CODE_PARAMETER_TAG: /* Reuse whether we have source_ssn or not to determine which address we're looking at */ @@ -1713,13 +1735,16 @@ dissect_parameter(tvbuff_t *parameter_tvb, proto_tree *tree, tvbuff_t **data_tvb } /* - ** If no tree, only the data and ssn parameters in the source and destination - ** address need to be dissected. This in order to make dissection of the data - ** possible when there is no tree. + ** If no tree, only the data, ssn, PC, and GT parameters in the source and destination + ** addresses need to be dissected. This in order to make dissection of the data + ** possible and to allow us to set the source and destination addresses when there is + ** no tree. */ if (!tree && tag != DATA_PARAMETER_TAG && tag != SOURCE_ADDRESS_PARAMETER_TAG && tag != DESTINATION_ADDRESS_PARAMETER_TAG + && tag != POINT_CODE_PARAMETER_TAG + && tag != GLOBAL_TITLE_PARAMETER_TAG && tag != SUBSYSTEM_NUMBER_PARAMETER_TAG) return; /* Nothing to do here */ @@ -1842,7 +1867,8 @@ dissect_parameter(tvbuff_t *parameter_tvb, proto_tree *tree, tvbuff_t **data_tvb dissect_drn_label_parameter(parameter_tvb, parameter_tree); break; case GLOBAL_TITLE_PARAMETER_TAG: - dissect_global_title_parameter(parameter_tvb, parameter_tree); + /* Reuse whether we have source_ssn or not to determine which address we're looking at */ + dissect_global_title_parameter(parameter_tvb, parameter_tree, (source_ssn != NULL)); break; case POINT_CODE_PARAMETER_TAG: /* Reuse whether we have source_ssn or not to determine which address we're looking at */ @@ -1919,6 +1945,8 @@ dissect_sua_message(tvbuff_t *message_tvb, packet_info *pinfo, proto_tree *sua_t sua_opc = ep_alloc0(sizeof(mtp3_addr_pc_t)); sua_dpc = ep_alloc0(sizeof(mtp3_addr_pc_t)); + sua_source_gt = NULL; + sua_destination_gt = NULL; common_header_tvb = tvb_new_subset(message_tvb, COMMON_HEADER_OFFSET, COMMON_HEADER_LENGTH, COMMON_HEADER_LENGTH); dissect_common_header(common_header_tvb, pinfo, sua_tree); @@ -1942,10 +1970,17 @@ dissect_sua_message(tvbuff_t *message_tvb, packet_info *pinfo, proto_tree *sua_t pinfo->sccp_info = NULL; } - if (sua_opc->type) - SET_ADDRESS(&pinfo->src, AT_SS7PC, sizeof(mtp3_addr_pc_t), (guint8 *) sua_opc); - if (sua_dpc->type) - SET_ADDRESS(&pinfo->dst, AT_SS7PC, sizeof(mtp3_addr_pc_t), (guint8 *) sua_dpc); + if (set_addresses) { + if (sua_opc->type) + SET_ADDRESS(&pinfo->src, AT_SS7PC, sizeof(mtp3_addr_pc_t), (guint8 *) sua_opc); + if (sua_dpc->type) + SET_ADDRESS(&pinfo->dst, AT_SS7PC, sizeof(mtp3_addr_pc_t), (guint8 *) sua_dpc); + + if (sua_source_gt) + SET_ADDRESS(&pinfo->src, AT_STRINGZ, 1+(int)strlen(sua_source_gt), sua_source_gt); + if (sua_destination_gt) + SET_ADDRESS(&pinfo->dst, AT_STRINGZ, 1+(int)strlen(sua_destination_gt), sua_destination_gt); + } /* If there was SUA data it could be dissected */ if(data_tvb) @@ -2150,6 +2185,9 @@ proto_register_sua(void) sua_module = prefs_register_protocol(proto_sua, NULL); prefs_register_obsolete_preference(sua_module, "sua_version"); prefs_register_enum_preference(sua_module, "version", "SUA Version", "Version used by Wireshark", &version, options, FALSE); + prefs_register_bool_preference(sua_module, "set_address", "Set source and destination addresses", + "Set the source and destination addresses to the PC or GT digits, depending on the routing indicator." + " This may affect TCAP's ability to recognize which messages belong to which TCAP session.", &set_addresses); register_heur_dissector_list("sua", &heur_subdissector_list); sua_tap = register_tap("sua"); |