Introduce preferences to set the strictness of Invoke/response
[obnox/wireshark/wip.git] / epan / dissectors / packet-ansi_tcap.c
index 0f040f04ed33aae9e4ac65367629d8c71bb2a443..232e231fabd65d2105e7927ce280b22aad8fbe28 100644 (file)
@@ -38,6 +38,7 @@
 
 #include <glib.h>
 #include <epan/packet.h>
+#include <epan/prefs.h>
 #include <epan/oids.h>
 #include <epan/emem.h>
 #include <epan/asn1.h>
 #define PSNAME "ANSI_TCAP"
 #define PFNAME "ansi_tcap"
 
+
+/* Preferences defaults */
+gint ansi_tcap_response_matching_type = 0;
+
 /* Initialize the protocol and registered fields */
 static int proto_ansi_tcap = -1;
 
@@ -118,7 +123,7 @@ static int hf_ansi_tcap_paramSequence = -1;       /* T_paramSequence */
 static int hf_ansi_tcap_paramSet = -1;            /* T_paramSet */
 
 /*--- End of included file: packet-ansi_tcap-hf.c ---*/
-#line 58 "packet-ansi_tcap-template.c"
+#line 63 "packet-ansi_tcap-template.c"
 
 /* Initialize the subtree pointers */
 static gint ett_tcap = -1;
@@ -160,7 +165,7 @@ static gint ett_ansi_tcap_T_paramSequence = -1;
 static gint ett_ansi_tcap_T_paramSet = -1;
 
 /*--- End of included file: packet-ansi_tcap-ett.c ---*/
-#line 73 "packet-ansi_tcap-template.c"
+#line 78 "packet-ansi_tcap-template.c"
 
 #define MAX_SSN 254
 
@@ -198,12 +203,12 @@ static GHashTable* itu_sub_dissectors = NULL;
 
   extern void add_ansi_tcap_subdissector(guint32 ssn, dissector_handle_t dissector) {
     g_hash_table_insert(ansi_sub_dissectors,GUINT_TO_POINTER(ssn),dissector);
-    dissector_add("sccp.ssn",ssn,tcap_handle);
+    dissector_add_uint("sccp.ssn",ssn,tcap_handle);
 }
 
 extern void delete_ansi_tcap_subdissector(guint32 ssn, dissector_handle_t dissector _U_) {
     g_hash_table_remove(ansi_sub_dissectors,GUINT_TO_POINTER(ssn));
-    dissector_delete("sccp.ssn",ssn,tcap_handle);
+    dissector_delete_uint("sccp.ssn",ssn,tcap_handle);
 }
 
 dissector_handle_t get_ansi_tcap_subdissector(guint32 ssn) {
@@ -270,9 +275,17 @@ save_invoke_data(packet_info *pinfo, proto_tree *tree _U_, tvbuff_t *tvb _U_){
           /* The hash string needs to contain src and dest to distiguish differnt flows */
           buf = ep_alloc(MAX_TID_STR_LEN);
           buf[0] = '\0';
-          g_snprintf(buf, MAX_TID_STR_LEN, "%s%s%s",
-                ansi_tcap_private.TransactionID_str, ep_address_to_str(src),
-                ep_address_to_str(dst));
+                 switch(ansi_tcap_response_matching_type){
+                               case 0:
+                                       g_snprintf(buf,MAX_TID_STR_LEN,"%s",ansi_tcap_private.TransactionID_str);
+                                       break;
+                               case 1:
+                                       g_snprintf(buf,MAX_TID_STR_LEN,"%s%s",ansi_tcap_private.TransactionID_str,ep_address_to_str(src));
+                                       break;
+                               default:
+                                       g_snprintf(buf,MAX_TID_STR_LEN,"%s%s%s",ansi_tcap_private.TransactionID_str,ep_address_to_str(src),ep_address_to_str(dst));
+                                       break;
+                       }
 
           /* If the entry allready exists don't owervrite it */
           ansi_tcap_saved_invokedata = g_hash_table_lookup(TransactionId_table,buf);
@@ -311,6 +324,17 @@ find_saved_invokedata(packet_info *pinfo, proto_tree *tree _U_, tvbuff_t *tvb _U
   g_snprintf(buf, MAX_TID_STR_LEN, "%s%s%s",
         ansi_tcap_private.TransactionID_str, ep_address_to_str(dst),
         ep_address_to_str(src));
+  switch(ansi_tcap_response_matching_type){
+               case 0:
+                       g_snprintf(buf,MAX_TID_STR_LEN,"%s",ansi_tcap_private.TransactionID_str);
+                       break;
+               case 1:
+                       g_snprintf(buf,MAX_TID_STR_LEN,"%s%s",ansi_tcap_private.TransactionID_str,ep_address_to_str(dst));
+                       break;
+               default:
+                       g_snprintf(buf,MAX_TID_STR_LEN,"%s%s%s",ansi_tcap_private.TransactionID_str,ep_address_to_str(dst),ep_address_to_str(src));
+                       break;
+       }
 
   ansi_tcap_saved_invokedata = g_hash_table_lookup(TransactionId_table, buf);
   if(ansi_tcap_saved_invokedata){
@@ -491,7 +515,7 @@ dissect_ansi_tcap_ErrorCode(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int of
 
 static int
 dissect_ansi_tcap_TransactionID_U(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
-#line 113 "ansi_tcap.cnf"
+#line 90 "ansi_tcap.cnf"
 
 tvbuff_t *next_tvb;
 guint8 len;
@@ -590,7 +614,7 @@ dissect_ansi_tcap_OBJECT_IDENTIFIER(gboolean implicit_tag _U_, tvbuff_t *tvb _U_
 
 static int
 dissect_ansi_tcap_ObjectIDApplicationContext(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
-#line 77 "ansi_tcap.cnf"
+#line 54 "ansi_tcap.cnf"
 
  static const char * oid_str;
 
@@ -759,15 +783,11 @@ dissect_ansi_tcap_T_componentIDs(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, i
 
 static int
 dissect_ansi_tcap_T_parameter(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
-#line 25 "ansi_tcap.cnf"
-tvbuff_t       *parameter_tvb;
+#line 23 "ansi_tcap.cnf"
 
-  offset = dissect_ber_octet_string(TRUE, actx, tree, tvb, offset, hf_index,
-                                       &parameter_tvb);
-  if(!parameter_tvb)
-    return offset;
+  if(find_tcap_subdissector(tvb, actx, tree))
+    offset = tvb_length(tvb);
   
-  find_tcap_subdissector(parameter_tvb, actx, tree);
 
 
 
@@ -784,7 +804,7 @@ 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_) {
-#line 35 "ansi_tcap.cnf"
+#line 29 "ansi_tcap.cnf"
   ansi_tcap_private.d.pdu = 1;
 
 
@@ -809,16 +829,9 @@ dissect_ansi_tcap_T_componentID(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, in
 
 static int
 dissect_ansi_tcap_T_parameter_01(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
-#line 43 "ansi_tcap.cnf"
-tvbuff_t       *parameter_tvb;
-
-
-  offset = dissect_ber_octet_string(TRUE, actx, tree, tvb, offset, hf_index,
-                                       &parameter_tvb);
-  if(!parameter_tvb)
-    return offset;
-  
-  find_tcap_subdissector(parameter_tvb, actx, tree);
+#line 36 "ansi_tcap.cnf"
+  if(find_tcap_subdissector(tvb, actx, tree))
+    offset = tvb_length(tvb);
 
 
 
@@ -834,7 +847,7 @@ 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_) {
-#line 54 "ansi_tcap.cnf"
+#line 40 "ansi_tcap.cnf"
   ansi_tcap_private.d.pdu = 2;
 
 
@@ -860,15 +873,9 @@ dissect_ansi_tcap_T_componentID_01(gboolean implicit_tag _U_, tvbuff_t *tvb _U_,
 
 static int
 dissect_ansi_tcap_T_parameter_02(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
-#line 63 "ansi_tcap.cnf"
-tvbuff_t       *parameter_tvb;
-
-  offset = dissect_ber_octet_string(TRUE, actx, tree, tvb, offset, hf_index,
-                                       &parameter_tvb);
-  if(!parameter_tvb)
-    return offset;
-  
-  find_tcap_subdissector(parameter_tvb, actx, tree);
+#line 46 "ansi_tcap.cnf"
+  if(find_tcap_subdissector(tvb, actx, tree))
+    offset = tvb_length(tvb);
 
 
 
@@ -885,7 +892,7 @@ 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_) {
-#line 73 "ansi_tcap.cnf"
+#line 50 "ansi_tcap.cnf"
   ansi_tcap_private.d.pdu = 3;
 
 
@@ -1078,7 +1085,7 @@ dissect_ansi_tcap_UniTransactionPDU(gboolean implicit_tag _U_, tvbuff_t *tvb _U_
 
 static int
 dissect_ansi_tcap_T_unidirectional(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
-#line 85 "ansi_tcap.cnf"
+#line 62 "ansi_tcap.cnf"
 gp_tcapsrt_info->ope=TC_ANSI_ALL;
 col_set_str(actx->pinfo->cinfo, COL_INFO, "unidirectional ");
 
@@ -1108,7 +1115,7 @@ dissect_ansi_tcap_TransactionPDU(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, i
 
 static int
 dissect_ansi_tcap_T_queryWithPerm(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
-#line 89 "ansi_tcap.cnf"
+#line 66 "ansi_tcap.cnf"
 gp_tcapsrt_info->ope=TC_ANSI_ALL;
 col_set_str(actx->pinfo->cinfo, COL_INFO, "queryWithPerm ");
 
@@ -1122,7 +1129,7 @@ col_set_str(actx->pinfo->cinfo, COL_INFO, "queryWithPerm ");
 
 static int
 dissect_ansi_tcap_T_queryWithoutPerm(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
-#line 93 "ansi_tcap.cnf"
+#line 70 "ansi_tcap.cnf"
 gp_tcapsrt_info->ope=TC_ANSI_ALL;
 col_set_str(actx->pinfo->cinfo, COL_INFO, "queryWithoutPerm ");
 
@@ -1136,7 +1143,7 @@ col_set_str(actx->pinfo->cinfo, COL_INFO, "queryWithoutPerm ");
 
 static int
 dissect_ansi_tcap_T_response(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
-#line 97 "ansi_tcap.cnf"
+#line 74 "ansi_tcap.cnf"
 gp_tcapsrt_info->ope=TC_ANSI_ALL;
 col_set_str(actx->pinfo->cinfo, COL_INFO, "response ");
 
@@ -1150,7 +1157,7 @@ col_set_str(actx->pinfo->cinfo, COL_INFO, "response ");
 
 static int
 dissect_ansi_tcap_T_conversationWithPerm(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
-#line 101 "ansi_tcap.cnf"
+#line 78 "ansi_tcap.cnf"
 gp_tcapsrt_info->ope=TC_ANSI_ALL;
 col_set_str(actx->pinfo->cinfo, COL_INFO, "conversationWithPerm ");
 
@@ -1164,7 +1171,7 @@ col_set_str(actx->pinfo->cinfo, COL_INFO, "conversationWithPerm ");
 
 static int
 dissect_ansi_tcap_T_conversationWithoutPerm(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
-#line 105 "ansi_tcap.cnf"
+#line 82 "ansi_tcap.cnf"
 gp_tcapsrt_info->ope=TC_ANSI_ALL;
 col_set_str(actx->pinfo->cinfo, COL_INFO, "conversationWithoutPerm ");
 
@@ -1260,7 +1267,7 @@ dissect_ansi_tcap_Abort(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset
 
 static int
 dissect_ansi_tcap_T_abort(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
-#line 109 "ansi_tcap.cnf"
+#line 86 "ansi_tcap.cnf"
 gp_tcapsrt_info->ope=TC_ANSI_ABORT;
 col_set_str(actx->pinfo->cinfo, COL_INFO, "Abort ");
 
@@ -1304,7 +1311,7 @@ dissect_ansi_tcap_PackageType(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int
 
 
 /*--- End of included file: packet-ansi_tcap-fn.c ---*/
-#line 310 "packet-ansi_tcap-template.c"
+#line 334 "packet-ansi_tcap-template.c"
 
 
 
@@ -1360,7 +1367,7 @@ dissect_ansi_tcap(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree)
                  */
                 if ( p_tcap_context && cur_oid && !p_tcap_context->oid_present ) {
                         /* Save the application context and the sub dissector */
-                        g_strlcpy(p_tcap_context->oid,cur_oid, LENGTH_OID);
+                        g_strlcpy(p_tcap_context->oid, cur_oid, sizeof(p_tcap_context->oid));
                         if ( (subdissector_handle = dissector_get_string_handle(ber_oid_dissector_table, cur_oid)) ) {
                                 p_tcap_context->subdissector_handle=subdissector_handle;
                                 p_tcap_context->oid_present=TRUE;
@@ -1388,6 +1395,8 @@ proto_reg_handoff_ansi_tcap(void)
 void
 proto_register_ansi_tcap(void)
 {
+    module_t    *ansi_tcap_module;
+
 
 /* Setup list of header fields  See Section 1.6.1 for details*/
     static hf_register_info hf[] = {
@@ -1428,11 +1437,11 @@ proto_register_ansi_tcap(void)
     { &hf_ansi_tcap_national,
       { "national", "ansi_tcap.national",
         FT_INT32, BASE_DEC, NULL, 0,
-        "T_national", HFILL }},
+        NULL, HFILL }},
     { &hf_ansi_tcap_private,
       { "private", "ansi_tcap.private",
         FT_INT32, BASE_DEC, NULL, 0,
-        "T_private", HFILL }},
+        NULL, HFILL }},
     { &hf_ansi_tcap_national_01,
       { "national", "ansi_tcap.national",
         FT_INT32, BASE_DEC, NULL, 0,
@@ -1444,31 +1453,31 @@ proto_register_ansi_tcap(void)
     { &hf_ansi_tcap_unidirectional,
       { "unidirectional", "ansi_tcap.unidirectional",
         FT_NONE, BASE_NONE, NULL, 0,
-        "T_unidirectional", HFILL }},
+        NULL, HFILL }},
     { &hf_ansi_tcap_queryWithPerm,
       { "queryWithPerm", "ansi_tcap.queryWithPerm",
         FT_NONE, BASE_NONE, NULL, 0,
-        "T_queryWithPerm", HFILL }},
+        NULL, HFILL }},
     { &hf_ansi_tcap_queryWithoutPerm,
       { "queryWithoutPerm", "ansi_tcap.queryWithoutPerm",
         FT_NONE, BASE_NONE, NULL, 0,
-        "T_queryWithoutPerm", HFILL }},
+        NULL, HFILL }},
     { &hf_ansi_tcap_response,
       { "response", "ansi_tcap.response",
         FT_NONE, BASE_NONE, NULL, 0,
-        "T_response", HFILL }},
+        NULL, HFILL }},
     { &hf_ansi_tcap_conversationWithPerm,
       { "conversationWithPerm", "ansi_tcap.conversationWithPerm",
         FT_NONE, BASE_NONE, NULL, 0,
-        "T_conversationWithPerm", HFILL }},
+        NULL, HFILL }},
     { &hf_ansi_tcap_conversationWithoutPerm,
       { "conversationWithoutPerm", "ansi_tcap.conversationWithoutPerm",
         FT_NONE, BASE_NONE, NULL, 0,
-        "T_conversationWithoutPerm", HFILL }},
+        NULL, HFILL }},
     { &hf_ansi_tcap_abort,
       { "abort", "ansi_tcap.abort",
         FT_NONE, BASE_NONE, NULL, 0,
-        "T_abort", HFILL }},
+        NULL, HFILL }},
     { &hf_ansi_tcap_identifier,
       { "identifier", "ansi_tcap.identifier",
         FT_BYTES, BASE_NONE, NULL, 0,
@@ -1488,7 +1497,7 @@ proto_register_ansi_tcap(void)
     { &hf_ansi_tcap_causeInformation,
       { "causeInformation", "ansi_tcap.causeInformation",
         FT_UINT32, BASE_DEC, VALS(ansi_tcap_T_causeInformation_vals), 0,
-        "T_causeInformation", HFILL }},
+        NULL, HFILL }},
     { &hf_ansi_tcap_abortCause,
       { "abortCause", "ansi_tcap.abortCause",
         FT_INT32, BASE_DEC, VALS(ansi_tcap_P_Abort_cause_U_vals), 0,
@@ -1504,7 +1513,7 @@ proto_register_ansi_tcap(void)
     { &hf_ansi_tcap_applicationContext,
       { "applicationContext", "ansi_tcap.applicationContext",
         FT_UINT32, BASE_DEC, VALS(ansi_tcap_T_applicationContext_vals), 0,
-        "T_applicationContext", HFILL }},
+        NULL, HFILL }},
     { &hf_ansi_tcap_integerApplicationId,
       { "integerApplicationId", "ansi_tcap.integerApplicationId",
         FT_INT32, BASE_DEC, NULL, 0,
@@ -1520,7 +1529,7 @@ proto_register_ansi_tcap(void)
     { &hf_ansi_tcap_securityContext,
       { "securityContext", "ansi_tcap.securityContext",
         FT_UINT32, BASE_DEC, VALS(ansi_tcap_T_securityContext_vals), 0,
-        "T_securityContext", HFILL }},
+        NULL, HFILL }},
     { &hf_ansi_tcap_integerSecurityId,
       { "integerSecurityId", "ansi_tcap.integerSecurityId",
         FT_INT32, BASE_DEC, NULL, 0,
@@ -1540,7 +1549,7 @@ proto_register_ansi_tcap(void)
     { &hf_ansi_tcap_confidentialityId,
       { "confidentialityId", "ansi_tcap.confidentialityId",
         FT_UINT32, BASE_DEC, VALS(ansi_tcap_T_confidentialityId_vals), 0,
-        "T_confidentialityId", HFILL }},
+        NULL, HFILL }},
     { &hf_ansi_tcap_integerConfidentialityId,
       { "integerConfidentialityId", "ansi_tcap.integerConfidentialityId",
         FT_INT32, BASE_DEC, NULL, 0,
@@ -1580,22 +1589,22 @@ proto_register_ansi_tcap(void)
     { &hf_ansi_tcap_componentIDs,
       { "componentIDs", "ansi_tcap.componentIDs",
         FT_BYTES, BASE_NONE, NULL, 0,
-        "T_componentIDs", HFILL }},
+        NULL, HFILL }},
     { &hf_ansi_tcap_operationCode,
       { "operationCode", "ansi_tcap.operationCode",
         FT_UINT32, BASE_DEC, VALS(ansi_tcap_OperationCode_vals), 0,
         NULL, HFILL }},
     { &hf_ansi_tcap_parameter,
       { "parameter", "ansi_tcap.parameter",
-        FT_BYTES, BASE_NONE, NULL, 0,
-        "T_parameter", HFILL }},
+        FT_NONE, BASE_NONE, NULL, 0,
+        NULL, HFILL }},
     { &hf_ansi_tcap_componentID,
       { "componentID", "ansi_tcap.componentID",
         FT_BYTES, BASE_NONE, NULL, 0,
-        "T_componentID", HFILL }},
+        NULL, HFILL }},
     { &hf_ansi_tcap_parameter_01,
       { "parameter", "ansi_tcap.parameter",
-        FT_BYTES, BASE_NONE, NULL, 0,
+        FT_NONE, BASE_NONE, NULL, 0,
         "T_parameter_01", HFILL }},
     { &hf_ansi_tcap_componentID_01,
       { "componentID", "ansi_tcap.componentID",
@@ -1607,7 +1616,7 @@ proto_register_ansi_tcap(void)
         NULL, HFILL }},
     { &hf_ansi_tcap_parameter_02,
       { "parameter", "ansi_tcap.parameter",
-        FT_BYTES, BASE_NONE, NULL, 0,
+        FT_NONE, BASE_NONE, NULL, 0,
         "T_parameter_02", HFILL }},
     { &hf_ansi_tcap_componentID_02,
       { "componentID", "ansi_tcap.componentID",
@@ -1624,14 +1633,14 @@ proto_register_ansi_tcap(void)
     { &hf_ansi_tcap_paramSequence,
       { "paramSequence", "ansi_tcap.paramSequence",
         FT_NONE, BASE_NONE, NULL, 0,
-        "T_paramSequence", HFILL }},
+        NULL, HFILL }},
     { &hf_ansi_tcap_paramSet,
       { "paramSet", "ansi_tcap.paramSet",
         FT_NONE, BASE_NONE, NULL, 0,
-        "T_paramSet", HFILL }},
+        NULL, HFILL }},
 
 /*--- End of included file: packet-ansi_tcap-hfarr.c ---*/
-#line 428 "packet-ansi_tcap-template.c"
+#line 454 "packet-ansi_tcap-template.c"
     };
 
 /* Setup protocol subtree array */
@@ -1668,14 +1677,15 @@ proto_register_ansi_tcap(void)
     &ett_ansi_tcap_T_paramSet,
 
 /*--- End of included file: packet-ansi_tcap-ettarr.c ---*/
-#line 438 "packet-ansi_tcap-template.c"
+#line 464 "packet-ansi_tcap-template.c"
     };
 
-    /*static enum_val_t tcap_options[] = {
-        { "itu", "ITU",  ITU_TCAP_STANDARD },
-        { "ansi", "ANSI", ANSI_TCAP_STANDARD },
-        { NULL, NULL, 0 }
-    };*/
+       static enum_val_t ansi_tcap_response_matching_type_values[] = {
+               {"Only Transaction ID will be used in Invoke/response matching",                                        "Transaction ID only", 0},
+               {"Transaction ID and Source will be used in Invoke/response matching",                          "Transaction ID and Source", 1}, 
+               {"Transaction ID Source and Destination will be used in Invoke/response matching",      "Transaction ID Source and Destination", 2},
+               {NULL, NULL, -1}
+       };
 
 
 /* Register the protocol name and description */
@@ -1686,6 +1696,12 @@ proto_register_ansi_tcap(void)
     proto_register_field_array(proto_ansi_tcap, hf, array_length(hf));
     proto_register_subtree_array(ett, array_length(ett));
 
+    ansi_tcap_module = prefs_register_protocol(proto_ansi_tcap, proto_reg_handoff_ansi_tcap);
+
+       prefs_register_enum_preference(ansi_tcap_module, "transaction.matchtype",
+                                      "Type of matching invoke/response",
+                                      "Type of matching invoke/response, risk of missmatch if loose matching choosen",
+                                      &ansi_tcap_response_matching_type, ansi_tcap_response_matching_type_values, FALSE);
 
     register_init_routine(&ansi_tcap_init_protocol);
 }