#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;
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;
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
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) {
/* 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);
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){
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;
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;
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,
- ¶meter_tvb);
- if(!parameter_tvb)
- return offset;
+ if(find_tcap_subdissector(tvb, actx, tree))
+ offset = tvb_length(tvb);
- find_tcap_subdissector(parameter_tvb, actx, tree);
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;
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,
- ¶meter_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);
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;
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,
- ¶meter_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);
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;
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 ");
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 ");
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 ");
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 ");
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 ");
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 ");
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 ");
/*--- End of included file: packet-ansi_tcap-fn.c ---*/
-#line 310 "packet-ansi_tcap-template.c"
+#line 334 "packet-ansi_tcap-template.c"
*/
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;
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[] = {
{ &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,
{ &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,
{ &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,
{ &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,
{ &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,
{ &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,
{ &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",
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",
{ &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 */
&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 */
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);
}