From 2c38bcf4b85d5ea3e32b8bbb69427f2cdef81a3d Mon Sep 17 00:00:00 2001 From: etxrab Date: Wed, 12 Sep 2007 16:45:53 +0000 Subject: Use the new ANSI TCAP dissector. git-svn-id: http://anonsvn.wireshark.org/wireshark/trunk@22854 f5534014-38df-0310-8fa8-9805f1628bb7 --- epan/dissectors/packet-ansi_tcap.c | 186 ++++++++++++++++++++++++++++++++----- 1 file changed, 164 insertions(+), 22 deletions(-) (limited to 'epan/dissectors/packet-ansi_tcap.c') diff --git a/epan/dissectors/packet-ansi_tcap.c b/epan/dissectors/packet-ansi_tcap.c index 55661bba3d..d5b3059c2b 100644 --- a/epan/dissectors/packet-ansi_tcap.c +++ b/epan/dissectors/packet-ansi_tcap.c @@ -1,6 +1,6 @@ /* Do not modify this file. */ /* It is created automatically by the ASN.1 to Wireshark dissector compiler */ -/* .\packet-ansi_tcap.c */ +/* ./packet-ansi_tcap.c */ /* ../../tools/asn2wrs.py -b -X -T -e -p ansi_tcap -c ansi_tcap.cnf -s packet-ansi_tcap-template TCAP-Remote-Operations-Information-Objects.asn TCAPPackage.asn */ /* Input file: packet-ansi_tcap-template.c */ @@ -196,7 +196,7 @@ struct ansi_tcap_private_t ansi_tcap_private; static void ansi_tcap_ctx_init(struct ansi_tcap_private_t *a_tcap_ctx) { memset(a_tcap_ctx, '\0', sizeof(*a_tcap_ctx)); a_tcap_ctx->signature = ANSI_TCAP_CTX_SIGNATURE; - ansi_tcap_private.oid_is_present = FALSE; + a_tcap_ctx->oid_is_present = FALSE; } static void dissect_ansi_tcap(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree); @@ -216,6 +216,124 @@ dissector_handle_t get_ansi_tcap_subdissector(guint32 ssn) { } */ +/* Transaction tracking */ +/* Transaction table */ +struct ansi_tcap_invokedata_t { + gint OperationCode; + /* + 0 : national, + 1 : private + */ + gint32 OperationCode_private; + gint32 OperationCode_national; +}; + +static GHashTable *TransactionId_table=NULL; + +static void +TransactionId_table_cleanup(gpointer key , gpointer value, gpointer user_data _U_){ + + struct ansi_tcap_invokedata_t *ansi_tcap_saved_invokedata = value; + gchar *TransactionId_str = key; + + if ( TransactionId_str ){ + g_free(TransactionId_str); + } + if (ansi_tcap_saved_invokedata){ + g_free(ansi_tcap_saved_invokedata); + } + +} + +void +ansi_tcap_init_transaction_table(void){ + + /* Destroy any existing memory chunks / hashes. */ + if (TransactionId_table){ + g_hash_table_foreach(TransactionId_table, TransactionId_table_cleanup, NULL); + g_hash_table_destroy(TransactionId_table); + TransactionId_table = NULL; + } + + TransactionId_table = g_hash_table_new(g_str_hash, g_str_equal); + +} + +static void +ansi_tcap_init_protocol(void) +{ + ansi_tcap_init_transaction_table(); +} + +/* Store Invoke information needed for the corresponding reply */ +static void +save_invoke_data(packet_info *pinfo, proto_tree *tree _U_, tvbuff_t *tvb _U_){ + struct ansi_tcap_invokedata_t *ansi_tcap_saved_invokedata; + address* src = &(pinfo->src); + address* dst = &(pinfo->dst); + guint8 *src_str; + guint8 *dst_str; + char *buf; + + buf=ep_alloc(1024); + + src_str = address_to_str(src); + dst_str = address_to_str(dst); + + + if ((!pinfo->fd->flags.visited)&&(ansi_tcap_private.TransactionID_str)){ + /* Only do this once XXX I hope its the right thing to do */ + ansi_tcap_saved_invokedata = g_malloc(sizeof(ansi_tcap_saved_invokedata)); + ansi_tcap_saved_invokedata->OperationCode = ansi_tcap_private.d.OperationCode; + + ansi_tcap_saved_invokedata->OperationCode_national = ansi_tcap_private.d.OperationCode_national; + ansi_tcap_saved_invokedata->OperationCode_private = ansi_tcap_private.d.OperationCode_private; + + strcpy(buf, ansi_tcap_private.TransactionID_str); + /* The hash string needs to contain src and dest to distiguish differnt flows */ + strcat(buf,src_str); + strcat(buf,dst_str); + strcat(buf,"\0"); + g_hash_table_insert(TransactionId_table, + g_strdup(buf), + ansi_tcap_saved_invokedata); + /* + g_warning("Tcap Invoke Hash string %s",buf); + */ + } +} + +static gboolean +find_saved_invokedata(packet_info *pinfo, proto_tree *tree _U_, tvbuff_t *tvb _U_){ + struct ansi_tcap_invokedata_t *ansi_tcap_saved_invokedata; + address* src = &(pinfo->src); + address* dst = &(pinfo->dst); + guint8 *src_str; + guint8 *dst_str; + char *buf; + + buf=ep_alloc(1024); + src_str = address_to_str(src); + dst_str = address_to_str(dst); + + /* The hash string needs to contain src and dest to distiguish differnt flows */ + src_str = address_to_str(src); + dst_str = address_to_str(dst); + strcpy(buf, ansi_tcap_private.TransactionID_str); + /* Reverse order to invoke */ + strcat(buf,dst_str); + strcat(buf,src_str); + strcat(buf,"\0"); + ansi_tcap_saved_invokedata = g_hash_table_lookup(TransactionId_table, buf); + if(ansi_tcap_saved_invokedata){ + ansi_tcap_private.d.OperationCode = ansi_tcap_saved_invokedata->OperationCode; + ansi_tcap_private.d.OperationCode_national = ansi_tcap_saved_invokedata->OperationCode_national; + ansi_tcap_private.d.OperationCode_private = ansi_tcap_saved_invokedata->OperationCode_private; + return TRUE; + } + return FALSE; +} + /* As currently ANSI MAP is the only possible sub dissector this function * must be improved to handle general cases. * @@ -234,6 +352,7 @@ dissector_handle_t get_ansi_tcap_subdissector(guint32 ssn) { */ static gboolean find_tcap_subdisector(tvbuff_t *tvb, asn1_ctx_t *actx, proto_tree *tree){ + proto_item *item; /* If "DialoguePortion objectApplicationId ObjectIDApplicationContext * points to the subdissector this code can be used. @@ -243,18 +362,36 @@ find_tcap_subdisector(tvbuff_t *tvb, asn1_ctx_t *actx, proto_tree *tree){ return TRUE; } */ + if(ansi_tcap_private.d.pdu == 1){ + /* Save Invoke data for this transaction */ + save_invoke_data(actx->pinfo, tree, tvb); + }else{ + /* Get saved data for this transaction */ + if(find_saved_invokedata(actx->pinfo, tree, tvb)){ + if(ansi_tcap_private.d.OperationCode == 0){ + /* national */ + item = proto_tree_add_int(tree, hf_ansi_tcap_national, tvb, 0, 0, ansi_tcap_private.d.OperationCode_national); + }else{ + item = proto_tree_add_int(tree, hf_ansi_tcap_private, tvb, 0, 0, ansi_tcap_private.d.OperationCode_private); + } + PROTO_ITEM_SET_GENERATED(item); + ansi_tcap_private.d.OperationCode_item = item; + } + } if(ansi_tcap_private.d.OperationCode == 0){ /* national */ - proto_tree_add_text(tree, tvb, 0, -1, + item = proto_tree_add_text(tree, tvb, 0, -1, "Dissector for ANSI TCAP NATIONAL code:%u not implemented. Contact Wireshark developers if you want this supported", ansi_tcap_private.d.OperationCode_national); + PROTO_ITEM_SET_GENERATED(item); return FALSE; }else if(ansi_tcap_private.d.OperationCode == 1){ /* private */ if((ansi_tcap_private.d.OperationCode_private & 0x0900) != 0x0900){ - proto_tree_add_text(tree, tvb, 0, -1, + item = proto_tree_add_text(tree, tvb, 0, -1, "Dissector for ANSI TCAP PRIVATE code:%u not implemented. Contact Wireshark developers if you want this supported", ansi_tcap_private.d.OperationCode_private); + PROTO_ITEM_SET_GENERATED(item); return FALSE; } } @@ -267,10 +404,9 @@ find_tcap_subdisector(tvbuff_t *tvb, asn1_ctx_t *actx, proto_tree *tree){ * Operation Family is coded as decimal 9. Bit H of the Operation Family is always * coded as 0. */ + call_dissector(ansi_map_handle, tvb, actx->pinfo, tcap_top_tree); - call_dissector(ansi_map_handle, tvb, actx->pinfo, tree); - - return FALSE; + return TRUE; } @@ -640,7 +776,7 @@ tvbuff_t *parameter_tvb; if(!parameter_tvb) return offset; - find_tcap_subdisector(parameter_tvb, actx, tcap_top_tree); + find_tcap_subdisector(parameter_tvb, actx, tree); @@ -657,14 +793,14 @@ static const ber_sequence_t Invoke_sequence[] = { static int dissect_ansi_tcap_Invoke(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) { - offset = dissect_ber_sequence(implicit_tag, actx, tree, tvb, offset, - Invoke_sequence, hf_index, ett_ansi_tcap_Invoke); - #line 30 "ansi_tcap.cnf" ansi_tcap_private.d.pdu = 1; + offset = dissect_ber_sequence(implicit_tag, actx, tree, tvb, offset, + Invoke_sequence, hf_index, ett_ansi_tcap_Invoke); + return offset; } @@ -691,7 +827,7 @@ tvbuff_t *parameter_tvb; if(!parameter_tvb) return offset; - find_tcap_subdisector(parameter_tvb, actx, tcap_top_tree); + find_tcap_subdisector(parameter_tvb, actx, tree); @@ -707,15 +843,15 @@ static const ber_sequence_t ReturnResult_sequence[] = { static int dissect_ansi_tcap_ReturnResult(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) { - offset = dissect_ber_sequence(implicit_tag, actx, tree, tvb, offset, - ReturnResult_sequence, hf_index, ett_ansi_tcap_ReturnResult); - #line 49 "ansi_tcap.cnf" ansi_tcap_private.d.pdu = 2; + offset = dissect_ber_sequence(implicit_tag, actx, tree, tvb, offset, + ReturnResult_sequence, hf_index, ett_ansi_tcap_ReturnResult); + return offset; } @@ -741,7 +877,7 @@ tvbuff_t *parameter_tvb; if(!parameter_tvb) return offset; - find_tcap_subdisector(parameter_tvb, actx, tcap_top_tree); + find_tcap_subdisector(parameter_tvb, actx, tree); @@ -758,13 +894,13 @@ static const ber_sequence_t ReturnError_sequence[] = { static int dissect_ansi_tcap_ReturnError(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) { - offset = dissect_ber_sequence(implicit_tag, actx, tree, tvb, offset, - ReturnError_sequence, hf_index, ett_ansi_tcap_ReturnError); - #line 68 "ansi_tcap.cnf" ansi_tcap_private.d.pdu = 3; + offset = dissect_ber_sequence(implicit_tag, actx, tree, tvb, offset, + ReturnError_sequence, hf_index, ett_ansi_tcap_ReturnError); + return offset; } @@ -1184,7 +1320,7 @@ dissect_ansi_tcap_PackageType(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int /*--- End of included file: packet-ansi_tcap-fn.c ---*/ -#line 186 "packet-ansi_tcap-template.c" +#line 322 "packet-ansi_tcap-template.c" @@ -1197,8 +1333,10 @@ dissect_ansi_tcap(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree) proto_item *stat_item=NULL; proto_tree *stat_tree=NULL; gint offset = 0; +#if 0 struct tcaphash_context_t * p_tcap_context; dissector_handle_t subdissector_handle; +#endif asn1_ctx_t asn1_ctx; asn1_ctx_init(&asn1_ctx, ASN1_ENC_BER, TRUE, pinfo); @@ -1226,6 +1364,8 @@ dissect_ansi_tcap(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree) gp_tcap_context=NULL; dissect_ansi_tcap_PackageType(FALSE, tvb, 0, &asn1_ctx, tree, -1); +#if 0 /* Skipp this part for now it will be rewritten */ + if (g_ansi_tcap_HandleSRT && !tcap_subdissector_used ) { if (gtcap_DisplaySRT && tree) { stat_item = proto_tree_add_text(tree, tvb, 0, 0, "Stat"); @@ -1252,6 +1392,7 @@ dissect_ansi_tcap(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree) (p_tcap_context->callback)(tvb, pinfo, stat_tree, p_tcap_context); } } +#endif } @@ -1512,7 +1653,7 @@ proto_register_ansi_tcap(void) "ansi_tcap.T_paramSet", HFILL }}, /*--- End of included file: packet-ansi_tcap-hfarr.c ---*/ -#line 305 "packet-ansi_tcap-template.c" +#line 446 "packet-ansi_tcap-template.c" }; /* Setup protocol subtree array */ @@ -1549,7 +1690,7 @@ proto_register_ansi_tcap(void) &ett_ansi_tcap_T_paramSet, /*--- End of included file: packet-ansi_tcap-ettarr.c ---*/ -#line 315 "packet-ansi_tcap-template.c" +#line 456 "packet-ansi_tcap-template.c" }; /*static enum_val_t tcap_options[] = { @@ -1568,6 +1709,7 @@ proto_register_ansi_tcap(void) proto_register_subtree_array(ett, array_length(ett)); + register_init_routine(&ansi_tcap_init_protocol); } -- cgit v1.2.3