1 /* Do not modify this file. Changes will be overwritten. */
2 /* Generated automatically by the ASN.1 to Wireshark dissector compiler */
4 /* asn2wrs.py -b -q -L -p tcap -c ./tcap.cnf -s ./packet-tcap-template -D . -O ../.. tcap.asn UnidialoguePDUs.asn DialoguePDUs.asn */
6 /* packet-tcap-template.c
8 * Copyright 2004 - 2005, Tim Endean <endeant@hotmail.com>
9 * Built from the gsm-map dissector Copyright 2004 - 2005, Anders Broman <anders.broman@ericsson.com>
11 * Wireshark - Network traffic analyzer
12 * By Gerald Combs <gerald@wireshark.org>
13 * Copyright 1998 Gerald Combs
15 * SPDX-License-Identifier: GPL-2.0-or-later
16 * References: ETSI 300 374
21 #include <epan/packet.h>
22 #include <epan/exceptions.h>
23 #include <epan/prefs.h>
24 #include <epan/oids.h>
25 #include <epan/asn1.h>
26 #include <epan/address_types.h>
27 #include <epan/strutil.h>
28 #include <epan/show_exception.h>
29 #include <wsutil/array.h>
31 #include "packet-ber.h"
32 #include "packet-tcap.h"
33 #include "packet-mtp3.h"
36 #define PNAME "Transaction Capabilities Application Part"
40 /* Initialize the protocol and registered fields */
41 static int proto_tcap
;
42 static int hf_tcap_tag
;
43 static int hf_tcap_length
;
44 static int hf_tcap_data
;
45 static int hf_tcap_tid
;
46 static int hf_tcap_constructor_eoc
;
48 int hf_tcapsrt_SessionId
;
49 int hf_tcapsrt_Duplicate
;
50 int hf_tcapsrt_BeginSession
;
51 int hf_tcapsrt_EndSession
;
52 int hf_tcapsrt_SessionTime
;
54 static int hf_tcap_UniDialoguePDU_PDU
; /* UniDialoguePDU */
55 static int hf_tcap_DialoguePDU_PDU
; /* DialoguePDU */
56 static int hf_tcap_oid
; /* OBJECT_IDENTIFIER */
57 static int hf_tcap_dialog
; /* Dialog1 */
58 static int hf_tcap_unidirectional
; /* Unidirectional */
59 static int hf_tcap_begin
; /* Begin */
60 static int hf_tcap_end
; /* End */
61 static int hf_tcap_continue
; /* Continue */
62 static int hf_tcap_abort
; /* Abort */
63 static int hf_tcap_dialoguePortion
; /* DialoguePortion */
64 static int hf_tcap_components
; /* ComponentPortion */
65 static int hf_tcap_otid
; /* OrigTransactionID */
66 static int hf_tcap_dtid
; /* DestTransactionID */
67 static int hf_tcap_reason
; /* Reason */
68 static int hf_tcap_p_abortCause
; /* P_AbortCause */
69 static int hf_tcap_u_abortCause
; /* DialoguePortion */
70 static int hf_tcap__untag_item
; /* Component */
71 static int hf_tcap_invoke
; /* Invoke */
72 static int hf_tcap_returnResultLast
; /* ReturnResult */
73 static int hf_tcap_returnError
; /* ReturnError */
74 static int hf_tcap_reject
; /* Reject */
75 static int hf_tcap_returnResultNotLast
; /* ReturnResult */
76 static int hf_tcap_invokeID
; /* InvokeIdType */
77 static int hf_tcap_linkedID
; /* InvokeIdType */
78 static int hf_tcap_opCode
; /* OPERATION */
79 static int hf_tcap_parameter
; /* Parameter */
80 static int hf_tcap_resultretres
; /* T_resultretres */
81 static int hf_tcap_errorCode
; /* ErrorCode */
82 static int hf_tcap_invokeIDRej
; /* T_invokeIDRej */
83 static int hf_tcap_derivable
; /* InvokeIdType */
84 static int hf_tcap_not_derivable
; /* NULL */
85 static int hf_tcap_problem
; /* T_problem */
86 static int hf_tcap_generalProblem
; /* GeneralProblem */
87 static int hf_tcap_invokeProblem
; /* InvokeProblem */
88 static int hf_tcap_returnResultProblem
; /* ReturnResultProblem */
89 static int hf_tcap_returnErrorProblem
; /* ReturnErrorProblem */
90 static int hf_tcap_localValue
; /* INTEGER */
91 static int hf_tcap_globalValue
; /* OBJECT_IDENTIFIER */
92 static int hf_tcap_nationaler
; /* INTEGER_M32768_32767 */
93 static int hf_tcap_privateer
; /* INTEGER */
94 static int hf_tcap_unidialoguePDU
; /* AUDT_apdu */
95 static int hf_tcap_audt_protocol_version
; /* AUDT_protocol_version */
96 static int hf_tcap_audt_application_context_name
; /* AUDT_application_context_name */
97 static int hf_tcap_audt_user_information
; /* AUDT_user_information */
98 static int hf_tcap_audt_user_information_item
; /* EXTERNAL */
99 static int hf_tcap_dialogueRequest
; /* AARQ_apdu */
100 static int hf_tcap_dialogueResponse
; /* AARE_apdu */
101 static int hf_tcap_dialogueAbort
; /* ABRT_apdu */
102 static int hf_tcap_aarq_protocol_version
; /* AARQ_protocol_version */
103 static int hf_tcap_aarq_application_context_name
; /* AARQ_application_context_name */
104 static int hf_tcap_aarq_user_information
; /* AARQ_user_information */
105 static int hf_tcap_aarq_user_information_item
; /* EXTERNAL */
106 static int hf_tcap_aare_protocol_version
; /* AARE_protocol_version */
107 static int hf_tcap_aare_application_context_name
; /* AARE_application_context_name */
108 static int hf_tcap_result
; /* Associate_result */
109 static int hf_tcap_result_source_diagnostic
; /* Associate_source_diagnostic */
110 static int hf_tcap_aare_user_information
; /* AARE_user_information */
111 static int hf_tcap_aare_user_information_item
; /* EXTERNAL */
112 static int hf_tcap_abort_source
; /* ABRT_source */
113 static int hf_tcap_abrt_user_information
; /* ABRT_user_information */
114 static int hf_tcap_abrt_user_information_item
; /* EXTERNAL */
115 static int hf_tcap_dialogue_service_user
; /* T_dialogue_service_user */
116 static int hf_tcap_dialogue_service_provider
; /* T_dialogue_service_provider */
118 static int hf_tcap_AUDT_protocol_version_version1
;
119 static int hf_tcap_AARQ_protocol_version_version1
;
120 static int hf_tcap_AARE_protocol_version_version1
;
122 /* Initialize the subtree pointers */
124 static int ett_param
;
130 static struct tcapsrt_info_t
* gp_tcapsrt_info
;
131 static bool tcap_subdissector_used
=false;
132 static dissector_handle_t requested_subdissector_handle
;
134 static int ss7pc_address_type
= -1;
136 static struct tcaphash_context_t
* gp_tcap_context
;
138 static int ett_tcap_ExternalPDU_U
;
139 static int ett_tcap_TCMessage
;
140 static int ett_tcap_Unidirectional
;
141 static int ett_tcap_Begin
;
142 static int ett_tcap_End
;
143 static int ett_tcap_Continue
;
144 static int ett_tcap_Abort
;
145 static int ett_tcap_Reason
;
146 static int ett_tcap_SEQUENCE_SIZE_1_MAX_OF_Component
;
147 static int ett_tcap_Component
;
148 static int ett_tcap_Invoke
;
149 static int ett_tcap_ReturnResult
;
150 static int ett_tcap_T_resultretres
;
151 static int ett_tcap_ReturnError
;
152 static int ett_tcap_Reject
;
153 static int ett_tcap_T_invokeIDRej
;
154 static int ett_tcap_T_problem
;
155 static int ett_tcap_OPERATION
;
156 static int ett_tcap_ErrorCode
;
157 static int ett_tcap_UniDialoguePDU
;
158 static int ett_tcap_AUDT_apdu_U
;
159 static int ett_tcap_AUDT_protocol_version
;
160 static int ett_tcap_AUDT_user_information
;
161 static int ett_tcap_DialoguePDU
;
162 static int ett_tcap_AARQ_apdu_U
;
163 static int ett_tcap_AARQ_protocol_version
;
164 static int ett_tcap_AARQ_user_information
;
165 static int ett_tcap_AARE_apdu_U
;
166 static int ett_tcap_AARE_protocol_version
;
167 static int ett_tcap_AARE_user_information
;
168 static int ett_tcap_ABRT_apdu_U
;
169 static int ett_tcap_ABRT_user_information
;
170 static int ett_tcap_Associate_source_diagnostic
;
172 /* When several Tcap components are received in a single TCAP message,
173 we have to use several buffers for the stored parameters
174 because else this data are erased during TAP dissector call */
175 #define MAX_TCAP_INSTANCE 10
176 static int tcapsrt_global_current
=0;
177 static struct tcapsrt_info_t tcapsrt_global_info
[MAX_TCAP_INSTANCE
];
180 static range_t
*global_ssn_range
;
181 static range_t
*ssn_range
;
183 /* These two timeout (in second) are used when some message are lost,
184 or when the same TCAP transcation identifier is reused */
185 static unsigned gtcap_RepetitionTimeout
= 10;
186 static unsigned gtcap_LostTimeout
= 30;
187 static bool gtcap_PersistentSRT
=false;
188 bool gtcap_DisplaySRT
=false;
189 bool gtcap_StatSRT
=false;
191 /* Global hash tables*/
192 static wmem_map_t
*tcaphash_context
;
193 static wmem_map_t
*tcaphash_begin
;
194 static wmem_map_t
*tcaphash_cont
;
195 static wmem_map_t
*tcaphash_end
;
196 static wmem_map_t
*tcaphash_ansi
;
198 static uint32_t tcapsrt_global_SessionId
=1;
200 static dissector_handle_t tcap_handle
;
201 static dissector_table_t ber_oid_dissector_table
;
202 static const char * cur_oid
;
203 static const char * tcapext_oid
;
204 static proto_tree
* tcap_top_tree
;
205 static proto_tree
* tcap_stat_tree
;
207 static dissector_handle_t data_handle
;
208 static dissector_handle_t ansi_tcap_handle
;
210 static int dissect_tcap_param(asn1_ctx_t
*actx
, proto_tree
*tree
, tvbuff_t
*tvb
, int offset
);
211 static bool dissect_tcap_ITU_ComponentPDU(bool implicit_tag _U_
, tvbuff_t
*tvb
, int offset
, asn1_ctx_t
*actx
, proto_tree
*tree
, int hf_index _U_
);
213 static dissector_table_t ansi_sub_dissectors
;
214 static dissector_table_t itu_sub_dissectors
;
216 extern void add_ansi_tcap_subdissector(uint32_t ssn
, dissector_handle_t dissector
) {
217 dissector_add_uint("ansi_tcap.ssn",ssn
,dissector
);
218 dissector_add_uint("sccp.ssn",ssn
,tcap_handle
);
221 extern void add_itu_tcap_subdissector(uint32_t ssn
, dissector_handle_t dissector
) {
222 dissector_add_uint("itu_tcap.ssn",ssn
,dissector
);
223 dissector_add_uint("sccp.ssn",ssn
,tcap_handle
);
226 extern void delete_ansi_tcap_subdissector(uint32_t ssn
, dissector_handle_t dissector
) {
227 dissector_delete_uint("ansi_tcap.ssn",ssn
,dissector
);
228 if (!get_itu_tcap_subdissector(ssn
))
229 dissector_delete_uint("sccp.ssn",ssn
,tcap_handle
);
231 extern void delete_itu_tcap_subdissector(uint32_t ssn
, dissector_handle_t dissector _U_
) {
232 dissector_delete_uint("itu_tcap.ssn",ssn
,dissector
);
233 if (!get_ansi_tcap_subdissector(ssn
))
234 dissector_delete_uint("sccp.ssn", ssn
,tcap_handle
);
237 dissector_handle_t
get_ansi_tcap_subdissector(uint32_t ssn
) {
238 return dissector_get_uint_handle(ansi_sub_dissectors
, ssn
);
241 dissector_handle_t
get_itu_tcap_subdissector(uint32_t ssn
) {
242 return dissector_get_uint_handle(itu_sub_dissectors
, ssn
);
248 dissect_tcap_OBJECT_IDENTIFIER(bool implicit_tag _U_
, tvbuff_t
*tvb _U_
, int offset _U_
, asn1_ctx_t
*actx _U_
, proto_tree
*tree _U_
, int hf_index _U_
) {
249 offset
= dissect_ber_object_identifier(implicit_tag
, actx
, tree
, tvb
, offset
, hf_index
, NULL
);
257 dissect_tcap_Dialog1(bool implicit_tag _U_
, tvbuff_t
*tvb _U_
, int offset _U_
, asn1_ctx_t
*actx _U_
, proto_tree
*tree _U_
, int hf_index _U_
) {
259 offset
= dissect_tcap_DialoguePDU(true, tvb
, offset
, actx
, tree
, -1);
266 static const ber_sequence_t ExternalPDU_U_sequence
[] = {
267 { &hf_tcap_oid
, BER_CLASS_UNI
, BER_UNI_TAG_OID
, BER_FLAGS_NOOWNTAG
, dissect_tcap_OBJECT_IDENTIFIER
},
268 { &hf_tcap_dialog
, BER_CLASS_CON
, 0, BER_FLAGS_IMPLTAG
, dissect_tcap_Dialog1
},
269 { NULL
, 0, 0, 0, NULL
}
273 dissect_tcap_ExternalPDU_U(bool implicit_tag _U_
, tvbuff_t
*tvb _U_
, int offset _U_
, asn1_ctx_t
*actx _U_
, proto_tree
*tree _U_
, int hf_index _U_
) {
274 offset
= dissect_ber_sequence(implicit_tag
, actx
, tree
, tvb
, offset
,
275 ExternalPDU_U_sequence
, hf_index
, ett_tcap_ExternalPDU_U
);
283 dissect_tcap_ExternalPDU(bool implicit_tag _U_
, tvbuff_t
*tvb _U_
, int offset _U_
, asn1_ctx_t
*actx _U_
, proto_tree
*tree _U_
, int hf_index _U_
) {
285 offset
= dissect_ber_tagged_type(implicit_tag
, actx
, tree
, tvb
, offset
,
286 hf_index
, BER_CLASS_UNI
, 8, true, dissect_tcap_ExternalPDU_U
);
296 dissect_tcap_DialogueOC(bool implicit_tag _U_
, tvbuff_t
*tvb _U_
, int offset _U_
, asn1_ctx_t
*actx _U_
, proto_tree
*tree _U_
, int hf_index _U_
) {
298 offset
= dissect_tcap_ExternalPDU(false /*implicit_tag*/, tvb
, offset
, actx
, tree
, -1);
307 dissect_tcap_DialoguePortion(bool implicit_tag _U_
, tvbuff_t
*tvb _U_
, int offset _U_
, asn1_ctx_t
*actx _U_
, proto_tree
*tree _U_
, int hf_index _U_
) {
308 offset
= dissect_ber_tagged_type(implicit_tag
, actx
, tree
, tvb
, offset
,
309 hf_index
, BER_CLASS_APP
, 11, true, dissect_tcap_DialogueOC
);
317 dissect_tcap_InvokeIdType(bool implicit_tag _U_
, tvbuff_t
*tvb _U_
, int offset _U_
, asn1_ctx_t
*actx _U_
, proto_tree
*tree _U_
, int hf_index _U_
) {
318 offset
= dissect_ber_integer(implicit_tag
, actx
, tree
, tvb
, offset
, hf_index
,
327 dissect_tcap_INTEGER(bool implicit_tag _U_
, tvbuff_t
*tvb _U_
, int offset _U_
, asn1_ctx_t
*actx _U_
, proto_tree
*tree _U_
, int hf_index _U_
) {
328 offset
= dissect_ber_integer(implicit_tag
, actx
, tree
, tvb
, offset
, hf_index
,
335 static const value_string tcap_OPERATION_vals
[] = {
337 { 1, "globalValue" },
341 static const ber_choice_t OPERATION_choice
[] = {
342 { 0, &hf_tcap_localValue
, BER_CLASS_UNI
, BER_UNI_TAG_INTEGER
, BER_FLAGS_NOOWNTAG
, dissect_tcap_INTEGER
},
343 { 1, &hf_tcap_globalValue
, BER_CLASS_UNI
, BER_UNI_TAG_OID
, BER_FLAGS_NOOWNTAG
, dissect_tcap_OBJECT_IDENTIFIER
},
344 { 0, NULL
, 0, 0, 0, NULL
}
348 dissect_tcap_OPERATION(bool implicit_tag _U_
, tvbuff_t
*tvb _U_
, int offset _U_
, asn1_ctx_t
*actx _U_
, proto_tree
*tree _U_
, int hf_index _U_
) {
349 offset
= dissect_ber_choice(actx
, tree
, tvb
, offset
,
350 OPERATION_choice
, hf_index
, ett_tcap_OPERATION
,
359 dissect_tcap_Parameter(bool implicit_tag _U_
, tvbuff_t
*tvb _U_
, int offset _U_
, asn1_ctx_t
*actx _U_
, proto_tree
*tree _U_
, int hf_index _U_
) {
361 offset
= dissect_tcap_param(actx
,tree
,tvb
,offset
);
368 static const ber_sequence_t Invoke_sequence
[] = {
369 { &hf_tcap_invokeID
, BER_CLASS_UNI
, BER_UNI_TAG_INTEGER
, BER_FLAGS_NOOWNTAG
, dissect_tcap_InvokeIdType
},
370 { &hf_tcap_linkedID
, BER_CLASS_CON
, 0, BER_FLAGS_OPTIONAL
|BER_FLAGS_IMPLTAG
, dissect_tcap_InvokeIdType
},
371 { &hf_tcap_opCode
, BER_CLASS_ANY
/*choice*/, -1/*choice*/, BER_FLAGS_NOOWNTAG
|BER_FLAGS_NOTCHKTAG
, dissect_tcap_OPERATION
},
372 { &hf_tcap_parameter
, BER_CLASS_ANY
, 0, BER_FLAGS_OPTIONAL
|BER_FLAGS_NOOWNTAG
, dissect_tcap_Parameter
},
373 { NULL
, 0, 0, 0, NULL
}
377 dissect_tcap_Invoke(bool implicit_tag _U_
, tvbuff_t
*tvb _U_
, int offset _U_
, asn1_ctx_t
*actx _U_
, proto_tree
*tree _U_
, int hf_index _U_
) {
378 offset
= dissect_ber_sequence(implicit_tag
, actx
, tree
, tvb
, offset
,
379 Invoke_sequence
, hf_index
, ett_tcap_Invoke
);
385 static const ber_sequence_t T_resultretres_sequence
[] = {
386 { &hf_tcap_opCode
, BER_CLASS_ANY
/*choice*/, -1/*choice*/, BER_FLAGS_NOOWNTAG
|BER_FLAGS_NOTCHKTAG
, dissect_tcap_OPERATION
},
387 { &hf_tcap_parameter
, BER_CLASS_ANY
, 0, BER_FLAGS_OPTIONAL
|BER_FLAGS_NOOWNTAG
, dissect_tcap_Parameter
},
388 { NULL
, 0, 0, 0, NULL
}
392 dissect_tcap_T_resultretres(bool implicit_tag _U_
, tvbuff_t
*tvb _U_
, int offset _U_
, asn1_ctx_t
*actx _U_
, proto_tree
*tree _U_
, int hf_index _U_
) {
393 offset
= dissect_ber_sequence(implicit_tag
, actx
, tree
, tvb
, offset
,
394 T_resultretres_sequence
, hf_index
, ett_tcap_T_resultretres
);
400 static const ber_sequence_t ReturnResult_sequence
[] = {
401 { &hf_tcap_invokeID
, BER_CLASS_UNI
, BER_UNI_TAG_INTEGER
, BER_FLAGS_NOOWNTAG
, dissect_tcap_InvokeIdType
},
402 { &hf_tcap_resultretres
, BER_CLASS_UNI
, BER_UNI_TAG_SEQUENCE
, BER_FLAGS_OPTIONAL
|BER_FLAGS_NOOWNTAG
, dissect_tcap_T_resultretres
},
403 { NULL
, 0, 0, 0, NULL
}
407 dissect_tcap_ReturnResult(bool implicit_tag _U_
, tvbuff_t
*tvb _U_
, int offset _U_
, asn1_ctx_t
*actx _U_
, proto_tree
*tree _U_
, int hf_index _U_
) {
408 offset
= dissect_ber_sequence(implicit_tag
, actx
, tree
, tvb
, offset
,
409 ReturnResult_sequence
, hf_index
, ett_tcap_ReturnResult
);
417 dissect_tcap_INTEGER_M32768_32767(bool implicit_tag _U_
, tvbuff_t
*tvb _U_
, int offset _U_
, asn1_ctx_t
*actx _U_
, proto_tree
*tree _U_
, int hf_index _U_
) {
418 offset
= dissect_ber_integer(implicit_tag
, actx
, tree
, tvb
, offset
, hf_index
,
425 static const value_string tcap_ErrorCode_vals
[] = {
426 { 19, "nationaler" },
431 static const ber_choice_t ErrorCode_choice
[] = {
432 { 19, &hf_tcap_nationaler
, BER_CLASS_PRI
, 19, BER_FLAGS_IMPLTAG
, dissect_tcap_INTEGER_M32768_32767
},
433 { 20, &hf_tcap_privateer
, BER_CLASS_PRI
, 20, BER_FLAGS_IMPLTAG
, dissect_tcap_INTEGER
},
434 { 0, NULL
, 0, 0, 0, NULL
}
438 dissect_tcap_ErrorCode(bool implicit_tag _U_
, tvbuff_t
*tvb _U_
, int offset _U_
, asn1_ctx_t
*actx _U_
, proto_tree
*tree _U_
, int hf_index _U_
) {
439 offset
= dissect_ber_choice(actx
, tree
, tvb
, offset
,
440 ErrorCode_choice
, hf_index
, ett_tcap_ErrorCode
,
447 static const ber_sequence_t ReturnError_sequence
[] = {
448 { &hf_tcap_invokeID
, BER_CLASS_UNI
, BER_UNI_TAG_INTEGER
, BER_FLAGS_NOOWNTAG
, dissect_tcap_InvokeIdType
},
449 { &hf_tcap_errorCode
, BER_CLASS_ANY
/*choice*/, -1/*choice*/, BER_FLAGS_NOOWNTAG
|BER_FLAGS_NOTCHKTAG
, dissect_tcap_ErrorCode
},
450 { &hf_tcap_parameter
, BER_CLASS_ANY
, 0, BER_FLAGS_OPTIONAL
|BER_FLAGS_NOOWNTAG
, dissect_tcap_Parameter
},
451 { NULL
, 0, 0, 0, NULL
}
455 dissect_tcap_ReturnError(bool implicit_tag _U_
, tvbuff_t
*tvb _U_
, int offset _U_
, asn1_ctx_t
*actx _U_
, proto_tree
*tree _U_
, int hf_index _U_
) {
456 offset
= dissect_ber_sequence(implicit_tag
, actx
, tree
, tvb
, offset
,
457 ReturnError_sequence
, hf_index
, ett_tcap_ReturnError
);
465 dissect_tcap_NULL(bool implicit_tag _U_
, tvbuff_t
*tvb _U_
, int offset _U_
, asn1_ctx_t
*actx _U_
, proto_tree
*tree _U_
, int hf_index _U_
) {
466 offset
= dissect_ber_null(implicit_tag
, actx
, tree
, tvb
, offset
, hf_index
);
472 static const value_string tcap_T_invokeIDRej_vals
[] = {
474 { 1, "not-derivable" },
478 static const ber_choice_t T_invokeIDRej_choice
[] = {
479 { 0, &hf_tcap_derivable
, BER_CLASS_UNI
, BER_UNI_TAG_INTEGER
, BER_FLAGS_NOOWNTAG
, dissect_tcap_InvokeIdType
},
480 { 1, &hf_tcap_not_derivable
, BER_CLASS_UNI
, BER_UNI_TAG_NULL
, BER_FLAGS_NOOWNTAG
, dissect_tcap_NULL
},
481 { 0, NULL
, 0, 0, 0, NULL
}
485 dissect_tcap_T_invokeIDRej(bool implicit_tag _U_
, tvbuff_t
*tvb _U_
, int offset _U_
, asn1_ctx_t
*actx _U_
, proto_tree
*tree _U_
, int hf_index _U_
) {
486 offset
= dissect_ber_choice(actx
, tree
, tvb
, offset
,
487 T_invokeIDRej_choice
, hf_index
, ett_tcap_T_invokeIDRej
,
494 static const value_string tcap_GeneralProblem_vals
[] = {
495 { 0, "unrecognizedComponent" },
496 { 1, "mistypedComponent" },
497 { 2, "badlyStructuredComponent" },
503 dissect_tcap_GeneralProblem(bool implicit_tag _U_
, tvbuff_t
*tvb _U_
, int offset _U_
, asn1_ctx_t
*actx _U_
, proto_tree
*tree _U_
, int hf_index _U_
) {
504 offset
= dissect_ber_integer(implicit_tag
, actx
, tree
, tvb
, offset
, hf_index
,
511 static const value_string tcap_InvokeProblem_vals
[] = {
512 { 0, "duplicateInvokeID" },
513 { 1, "unrecognizedOperation" },
514 { 2, "mistypedParameter" },
515 { 3, "resourceLimitation" },
516 { 4, "initiatingRelease" },
517 { 5, "unrecognizedLinkedID" },
518 { 6, "linkedResponseUnexpected" },
519 { 7, "unexpectedLinkedOperation" },
525 dissect_tcap_InvokeProblem(bool implicit_tag _U_
, tvbuff_t
*tvb _U_
, int offset _U_
, asn1_ctx_t
*actx _U_
, proto_tree
*tree _U_
, int hf_index _U_
) {
526 offset
= dissect_ber_integer(implicit_tag
, actx
, tree
, tvb
, offset
, hf_index
,
533 static const value_string tcap_ReturnResultProblem_vals
[] = {
534 { 0, "unrecognizedInvokeID" },
535 { 1, "returnResultUnexpected" },
536 { 2, "mistypedParameter" },
542 dissect_tcap_ReturnResultProblem(bool implicit_tag _U_
, tvbuff_t
*tvb _U_
, int offset _U_
, asn1_ctx_t
*actx _U_
, proto_tree
*tree _U_
, int hf_index _U_
) {
543 offset
= dissect_ber_integer(implicit_tag
, actx
, tree
, tvb
, offset
, hf_index
,
550 static const value_string tcap_ReturnErrorProblem_vals
[] = {
551 { 0, "unrecognizedInvokeID" },
552 { 1, "returnErrorUnexpected" },
553 { 2, "unrecognizedError" },
554 { 3, "unexpectedError" },
555 { 4, "mistypedParameter" },
561 dissect_tcap_ReturnErrorProblem(bool implicit_tag _U_
, tvbuff_t
*tvb _U_
, int offset _U_
, asn1_ctx_t
*actx _U_
, proto_tree
*tree _U_
, int hf_index _U_
) {
562 offset
= dissect_ber_integer(implicit_tag
, actx
, tree
, tvb
, offset
, hf_index
,
569 static const value_string tcap_T_problem_vals
[] = {
570 { 0, "generalProblem" },
571 { 1, "invokeProblem" },
572 { 2, "returnResultProblem" },
573 { 3, "returnErrorProblem" },
577 static const ber_choice_t T_problem_choice
[] = {
578 { 0, &hf_tcap_generalProblem
, BER_CLASS_CON
, 0, BER_FLAGS_IMPLTAG
, dissect_tcap_GeneralProblem
},
579 { 1, &hf_tcap_invokeProblem
, BER_CLASS_CON
, 1, BER_FLAGS_IMPLTAG
, dissect_tcap_InvokeProblem
},
580 { 2, &hf_tcap_returnResultProblem
, BER_CLASS_CON
, 2, BER_FLAGS_IMPLTAG
, dissect_tcap_ReturnResultProblem
},
581 { 3, &hf_tcap_returnErrorProblem
, BER_CLASS_CON
, 3, BER_FLAGS_IMPLTAG
, dissect_tcap_ReturnErrorProblem
},
582 { 0, NULL
, 0, 0, 0, NULL
}
586 dissect_tcap_T_problem(bool implicit_tag _U_
, tvbuff_t
*tvb _U_
, int offset _U_
, asn1_ctx_t
*actx _U_
, proto_tree
*tree _U_
, int hf_index _U_
) {
587 offset
= dissect_ber_choice(actx
, tree
, tvb
, offset
,
588 T_problem_choice
, hf_index
, ett_tcap_T_problem
,
595 static const ber_sequence_t Reject_sequence
[] = {
596 { &hf_tcap_invokeIDRej
, BER_CLASS_ANY
/*choice*/, -1/*choice*/, BER_FLAGS_NOOWNTAG
|BER_FLAGS_NOTCHKTAG
, dissect_tcap_T_invokeIDRej
},
597 { &hf_tcap_problem
, BER_CLASS_ANY
/*choice*/, -1/*choice*/, BER_FLAGS_NOOWNTAG
|BER_FLAGS_NOTCHKTAG
, dissect_tcap_T_problem
},
598 { NULL
, 0, 0, 0, NULL
}
602 dissect_tcap_Reject(bool implicit_tag _U_
, tvbuff_t
*tvb _U_
, int offset _U_
, asn1_ctx_t
*actx _U_
, proto_tree
*tree _U_
, int hf_index _U_
) {
603 offset
= dissect_ber_sequence(implicit_tag
, actx
, tree
, tvb
, offset
,
604 Reject_sequence
, hf_index
, ett_tcap_Reject
);
610 static const value_string tcap_Component_vals
[] = {
612 { 2, "returnResultLast" },
613 { 3, "returnError" },
615 { 7, "returnResultNotLast" },
619 static const ber_choice_t Component_choice
[] = {
620 { 1, &hf_tcap_invoke
, BER_CLASS_CON
, 1, BER_FLAGS_IMPLTAG
, dissect_tcap_Invoke
},
621 { 2, &hf_tcap_returnResultLast
, BER_CLASS_CON
, 2, BER_FLAGS_IMPLTAG
, dissect_tcap_ReturnResult
},
622 { 3, &hf_tcap_returnError
, BER_CLASS_CON
, 3, BER_FLAGS_IMPLTAG
, dissect_tcap_ReturnError
},
623 { 4, &hf_tcap_reject
, BER_CLASS_CON
, 4, BER_FLAGS_IMPLTAG
, dissect_tcap_Reject
},
624 { 7, &hf_tcap_returnResultNotLast
, BER_CLASS_CON
, 7, BER_FLAGS_IMPLTAG
, dissect_tcap_ReturnResult
},
625 { 0, NULL
, 0, 0, 0, NULL
}
629 dissect_tcap_Component(bool implicit_tag _U_
, tvbuff_t
*tvb _U_
, int offset _U_
, asn1_ctx_t
*actx _U_
, proto_tree
*tree _U_
, int hf_index _U_
) {
634 uint32_t len
, comp_offset
;
635 volatile uint32_t _offset
;
638 comp_offset
= dissect_ber_identifier(actx
->pinfo
, tree
, tvb
, offset
, &ber_class
, &pc
, &tag
);
639 comp_offset
= dissect_ber_length(actx
->pinfo
, tree
, tvb
, comp_offset
, &len
, &ind_field
);
640 /* we can believe the length now */
641 next_tvb
= tvb_new_subset_length(tvb
, offset
, len
+comp_offset
-offset
);
645 if(dissect_tcap_ITU_ComponentPDU(implicit_tag
, next_tvb
, 0, actx
, tcap_top_tree
, hf_index
)){
651 _offset
= dissect_ber_choice(actx
, tree
, tvb
, _offset
,
652 Component_choice
, hf_index
, ett_tcap_Component
,
655 CATCH_NONFATAL_ERRORS
{
656 show_exception(tvb
, actx
->pinfo
, tree
, EXCEPT_CODE
, GET_MESSAGE
);
661 /* return comp_offset+len; or return offset (will be automatically added) */
668 static const ber_sequence_t SEQUENCE_SIZE_1_MAX_OF_Component_sequence_of
[1] = {
669 { &hf_tcap__untag_item
, BER_CLASS_ANY
/*choice*/, -1/*choice*/, BER_FLAGS_NOOWNTAG
|BER_FLAGS_NOTCHKTAG
, dissect_tcap_Component
},
673 dissect_tcap_SEQUENCE_SIZE_1_MAX_OF_Component(bool implicit_tag _U_
, tvbuff_t
*tvb _U_
, int offset _U_
, asn1_ctx_t
*actx _U_
, proto_tree
*tree _U_
, int hf_index _U_
) {
674 offset
= dissect_ber_sequence_of(implicit_tag
, actx
, tree
, tvb
, offset
,
675 SEQUENCE_SIZE_1_MAX_OF_Component_sequence_of
, hf_index
, ett_tcap_SEQUENCE_SIZE_1_MAX_OF_Component
);
683 dissect_tcap_ComponentPortion(bool implicit_tag _U_
, tvbuff_t
*tvb _U_
, int offset _U_
, asn1_ctx_t
*actx _U_
, proto_tree
*tree _U_
, int hf_index _U_
) {
684 offset
= dissect_ber_tagged_type(implicit_tag
, actx
, tree
, tvb
, offset
,
685 hf_index
, BER_CLASS_APP
, 12, true, dissect_tcap_SEQUENCE_SIZE_1_MAX_OF_Component
);
691 static const ber_sequence_t Unidirectional_sequence
[] = {
692 { &hf_tcap_dialoguePortion
, BER_CLASS_APP
, 11, BER_FLAGS_OPTIONAL
|BER_FLAGS_NOOWNTAG
, dissect_tcap_DialoguePortion
},
693 { &hf_tcap_components
, BER_CLASS_APP
, 12, BER_FLAGS_NOOWNTAG
, dissect_tcap_ComponentPortion
},
694 { NULL
, 0, 0, 0, NULL
}
698 dissect_tcap_Unidirectional(bool implicit_tag _U_
, tvbuff_t
*tvb _U_
, int offset _U_
, asn1_ctx_t
*actx _U_
, proto_tree
*tree _U_
, int hf_index _U_
) {
699 offset
= dissect_ber_sequence(implicit_tag
, actx
, tree
, tvb
, offset
,
700 Unidirectional_sequence
, hf_index
, ett_tcap_Unidirectional
);
708 dissect_tcap_OCTET_STRING_SIZE_1_4(bool implicit_tag _U_
, tvbuff_t
*tvb _U_
, int offset _U_
, asn1_ctx_t
*actx _U_
, proto_tree
*tree _U_
, int hf_index _U_
) {
709 offset
= dissect_ber_octet_string(implicit_tag
, actx
, tree
, tvb
, offset
, hf_index
,
718 dissect_tcap_OrigTransactionID(bool implicit_tag _U_
, tvbuff_t
*tvb _U_
, int offset _U_
, asn1_ctx_t
*actx _U_
, proto_tree
*tree _U_
, int hf_index _U_
) {
719 tvbuff_t
*parameter_tvb
;
723 struct tcap_private_t
*p_tcap_private
= (struct tcap_private_t
*)actx
->value_ptr
;
725 hf_index
= hf_tcap_tid
;
726 saved_offset
= offset
;
727 offset
= dissect_ber_tagged_type(implicit_tag
, actx
, tree
, tvb
, offset
,
728 hf_index
, BER_CLASS_APP
, 8, true, dissect_tcap_OCTET_STRING_SIZE_1_4
);
730 proto_item_set_generated(actx
->created_item
);
731 offset
= saved_offset
;
733 subtree
= proto_tree_add_subtree(tree
, tvb
, offset
, -1, ett_otid
, NULL
, "Source Transaction ID");
734 offset
= dissect_ber_octet_string(implicit_tag
, actx
, subtree
, tvb
, offset
, hf_tcap_otid
,
738 len
= tvb_reported_length_remaining(parameter_tvb
, 0);
741 gp_tcapsrt_info
->src_tid
=tvb_get_uint8(parameter_tvb
, 0);
744 gp_tcapsrt_info
->src_tid
=tvb_get_ntohs(parameter_tvb
, 0);
747 gp_tcapsrt_info
->src_tid
=tvb_get_ntoh24(parameter_tvb
, 0);
750 gp_tcapsrt_info
->src_tid
=tvb_get_ntohl(parameter_tvb
, 0);
753 gp_tcapsrt_info
->src_tid
=0;
757 p_tcap_private
->src_tid
= gp_tcapsrt_info
->src_tid
;
760 col_append_str(actx
->pinfo
->cinfo
, COL_INFO
, "otid(");
761 for (i
= 0; i
< len
; i
++) {
762 col_append_fstr(actx
->pinfo
->cinfo
, COL_INFO
, "%02x",tvb_get_uint8(parameter_tvb
,i
));
764 col_append_str(actx
->pinfo
->cinfo
, COL_INFO
, ") ");
773 static const ber_sequence_t Begin_sequence
[] = {
774 { &hf_tcap_otid
, BER_CLASS_APP
, 8, BER_FLAGS_NOOWNTAG
, dissect_tcap_OrigTransactionID
},
775 { &hf_tcap_dialoguePortion
, BER_CLASS_APP
, 11, BER_FLAGS_OPTIONAL
|BER_FLAGS_NOOWNTAG
, dissect_tcap_DialoguePortion
},
776 { &hf_tcap_components
, BER_CLASS_APP
, 12, BER_FLAGS_OPTIONAL
|BER_FLAGS_NOOWNTAG
, dissect_tcap_ComponentPortion
},
777 { NULL
, 0, 0, 0, NULL
}
781 dissect_tcap_Begin(bool implicit_tag _U_
, tvbuff_t
*tvb _U_
, int offset _U_
, asn1_ctx_t
*actx _U_
, proto_tree
*tree _U_
, int hf_index _U_
) {
782 gp_tcapsrt_info
->ope
=TC_BEGIN
;
784 /* Do not change col_add_str() to col_append_str() here: we _want_ this call
785 * to overwrite whatever's currently in the INFO column (e.g., "UDT" from
786 * the SCCP dissector).
788 * If there's something there that should not be overwritten, whoever
789 * put that info there should call col_set_fence() to protect it.
791 col_set_str(actx
->pinfo
->cinfo
, COL_INFO
, "Begin ");
792 offset
= dissect_ber_sequence(implicit_tag
, actx
, tree
, tvb
, offset
,
793 Begin_sequence
, hf_index
, ett_tcap_Begin
);
801 dissect_tcap_DestTransactionID(bool implicit_tag _U_
, tvbuff_t
*tvb _U_
, int offset _U_
, asn1_ctx_t
*actx _U_
, proto_tree
*tree _U_
, int hf_index _U_
) {
802 tvbuff_t
*parameter_tvb
;
806 struct tcap_private_t
*p_tcap_private
= (struct tcap_private_t
*)actx
->value_ptr
;
808 hf_index
= hf_tcap_tid
;
809 saved_offset
= offset
;
810 offset
= dissect_ber_tagged_type(implicit_tag
, actx
, tree
, tvb
, offset
,
811 hf_index
, BER_CLASS_APP
, 9, true, dissect_tcap_OCTET_STRING_SIZE_1_4
);
813 proto_item_set_generated(actx
->created_item
);
814 offset
= saved_offset
;
816 subtree
= proto_tree_add_subtree(tree
, tvb
, offset
, -1, ett_dtid
, NULL
, "Destination Transaction ID");
817 offset
= dissect_ber_octet_string(implicit_tag
, actx
, subtree
, tvb
, offset
, hf_tcap_dtid
,
821 len
= tvb_reported_length_remaining(parameter_tvb
, 0);
824 gp_tcapsrt_info
->dst_tid
=tvb_get_uint8(parameter_tvb
, 0);
827 gp_tcapsrt_info
->dst_tid
=tvb_get_ntohs(parameter_tvb
, 0);
830 gp_tcapsrt_info
->dst_tid
=tvb_get_ntoh24(parameter_tvb
, 0);
833 gp_tcapsrt_info
->dst_tid
=tvb_get_ntohl(parameter_tvb
, 0);
836 gp_tcapsrt_info
->dst_tid
=0;
840 p_tcap_private
->dst_tid
= gp_tcapsrt_info
->dst_tid
;
843 col_append_str(actx
->pinfo
->cinfo
, COL_INFO
, "dtid(");
844 for(i
= 0; i
< len
; i
++) {
845 col_append_fstr(actx
->pinfo
->cinfo
, COL_INFO
, "%02x",tvb_get_uint8(parameter_tvb
,i
));
847 col_append_str(actx
->pinfo
->cinfo
, COL_INFO
, ") ");
855 static const ber_sequence_t End_sequence
[] = {
856 { &hf_tcap_dtid
, BER_CLASS_APP
, 9, BER_FLAGS_NOOWNTAG
, dissect_tcap_DestTransactionID
},
857 { &hf_tcap_dialoguePortion
, BER_CLASS_APP
, 11, BER_FLAGS_OPTIONAL
|BER_FLAGS_NOOWNTAG
, dissect_tcap_DialoguePortion
},
858 { &hf_tcap_components
, BER_CLASS_APP
, 12, BER_FLAGS_OPTIONAL
|BER_FLAGS_NOOWNTAG
, dissect_tcap_ComponentPortion
},
859 { NULL
, 0, 0, 0, NULL
}
863 dissect_tcap_End(bool implicit_tag _U_
, tvbuff_t
*tvb _U_
, int offset _U_
, asn1_ctx_t
*actx _U_
, proto_tree
*tree _U_
, int hf_index _U_
) {
864 gp_tcapsrt_info
->ope
=TC_END
;
866 col_set_str(actx
->pinfo
->cinfo
, COL_INFO
, "End ");
867 offset
= dissect_ber_sequence(implicit_tag
, actx
, tree
, tvb
, offset
,
868 End_sequence
, hf_index
, ett_tcap_End
);
874 static const ber_sequence_t Continue_sequence
[] = {
875 { &hf_tcap_otid
, BER_CLASS_APP
, 8, BER_FLAGS_NOOWNTAG
, dissect_tcap_OrigTransactionID
},
876 { &hf_tcap_dtid
, BER_CLASS_APP
, 9, BER_FLAGS_NOOWNTAG
, dissect_tcap_DestTransactionID
},
877 { &hf_tcap_dialoguePortion
, BER_CLASS_APP
, 11, BER_FLAGS_OPTIONAL
|BER_FLAGS_NOOWNTAG
, dissect_tcap_DialoguePortion
},
878 { &hf_tcap_components
, BER_CLASS_APP
, 12, BER_FLAGS_OPTIONAL
|BER_FLAGS_NOOWNTAG
, dissect_tcap_ComponentPortion
},
879 { NULL
, 0, 0, 0, NULL
}
883 dissect_tcap_Continue(bool implicit_tag _U_
, tvbuff_t
*tvb _U_
, int offset _U_
, asn1_ctx_t
*actx _U_
, proto_tree
*tree _U_
, int hf_index _U_
) {
884 gp_tcapsrt_info
->ope
=TC_CONT
;
886 col_set_str(actx
->pinfo
->cinfo
, COL_INFO
, "Continue ");
887 offset
= dissect_ber_sequence(implicit_tag
, actx
, tree
, tvb
, offset
,
888 Continue_sequence
, hf_index
, ett_tcap_Continue
);
894 static const value_string tcap_P_AbortCause_U_vals
[] = {
895 { 0, "unrecognizedMessageType" },
896 { 1, "unrecognizedTransactionID" },
897 { 2, "badlyFormattedTransactionPortion" },
898 { 3, "incorrectTransactionPortion" },
899 { 4, "resourceLimitation" },
905 dissect_tcap_P_AbortCause_U(bool implicit_tag _U_
, tvbuff_t
*tvb _U_
, int offset _U_
, asn1_ctx_t
*actx _U_
, proto_tree
*tree _U_
, int hf_index _U_
) {
906 offset
= dissect_ber_integer(implicit_tag
, actx
, tree
, tvb
, offset
, hf_index
,
915 dissect_tcap_P_AbortCause(bool implicit_tag _U_
, tvbuff_t
*tvb _U_
, int offset _U_
, asn1_ctx_t
*actx _U_
, proto_tree
*tree _U_
, int hf_index _U_
) {
916 offset
= dissect_ber_tagged_type(implicit_tag
, actx
, tree
, tvb
, offset
,
917 hf_index
, BER_CLASS_APP
, 10, true, dissect_tcap_P_AbortCause_U
);
923 static const value_string tcap_Reason_vals
[] = {
924 { 10, "p-abortCause" },
925 { 11, "u-abortCause" },
929 static const ber_choice_t Reason_choice
[] = {
930 { 10, &hf_tcap_p_abortCause
, BER_CLASS_APP
, 10, BER_FLAGS_NOOWNTAG
, dissect_tcap_P_AbortCause
},
931 { 11, &hf_tcap_u_abortCause
, BER_CLASS_APP
, 11, BER_FLAGS_NOOWNTAG
, dissect_tcap_DialoguePortion
},
932 { 0, NULL
, 0, 0, 0, NULL
}
936 dissect_tcap_Reason(bool implicit_tag _U_
, tvbuff_t
*tvb _U_
, int offset _U_
, asn1_ctx_t
*actx _U_
, proto_tree
*tree _U_
, int hf_index _U_
) {
937 offset
= dissect_ber_choice(actx
, tree
, tvb
, offset
,
938 Reason_choice
, hf_index
, ett_tcap_Reason
,
945 static const ber_sequence_t Abort_sequence
[] = {
946 { &hf_tcap_dtid
, BER_CLASS_APP
, 9, BER_FLAGS_NOOWNTAG
, dissect_tcap_DestTransactionID
},
947 { &hf_tcap_reason
, BER_CLASS_ANY
/*choice*/, -1/*choice*/, BER_FLAGS_OPTIONAL
|BER_FLAGS_NOOWNTAG
|BER_FLAGS_NOTCHKTAG
, dissect_tcap_Reason
},
948 { NULL
, 0, 0, 0, NULL
}
952 dissect_tcap_Abort(bool implicit_tag _U_
, tvbuff_t
*tvb _U_
, int offset _U_
, asn1_ctx_t
*actx _U_
, proto_tree
*tree _U_
, int hf_index _U_
) {
953 gp_tcapsrt_info
->ope
=TC_ABORT
;
955 col_set_str(actx
->pinfo
->cinfo
, COL_INFO
, "Abort ");
956 offset
= dissect_ber_sequence(implicit_tag
, actx
, tree
, tvb
, offset
,
957 Abort_sequence
, hf_index
, ett_tcap_Abort
);
963 static const ber_choice_t TCMessage_choice
[] = {
964 { 1, &hf_tcap_unidirectional
, BER_CLASS_APP
, 1, BER_FLAGS_IMPLTAG
, dissect_tcap_Unidirectional
},
965 { 2, &hf_tcap_begin
, BER_CLASS_APP
, 2, BER_FLAGS_IMPLTAG
, dissect_tcap_Begin
},
966 { 4, &hf_tcap_end
, BER_CLASS_APP
, 4, BER_FLAGS_IMPLTAG
, dissect_tcap_End
},
967 { 5, &hf_tcap_continue
, BER_CLASS_APP
, 5, BER_FLAGS_IMPLTAG
, dissect_tcap_Continue
},
968 { 7, &hf_tcap_abort
, BER_CLASS_APP
, 7, BER_FLAGS_IMPLTAG
, dissect_tcap_Abort
},
969 { 0, NULL
, 0, 0, 0, NULL
}
973 dissect_tcap_TCMessage(bool implicit_tag _U_
, tvbuff_t
*tvb _U_
, int offset _U_
, asn1_ctx_t
*actx _U_
, proto_tree
*tree _U_
, int hf_index _U_
) {
974 offset
= dissect_ber_choice(actx
, tree
, tvb
, offset
,
975 TCMessage_choice
, hf_index
, ett_tcap_TCMessage
,
982 static int * const AUDT_protocol_version_bits
[] = {
983 &hf_tcap_AUDT_protocol_version_version1
,
988 dissect_tcap_AUDT_protocol_version(bool implicit_tag _U_
, tvbuff_t
*tvb _U_
, int offset _U_
, asn1_ctx_t
*actx _U_
, proto_tree
*tree _U_
, int hf_index _U_
) {
989 offset
= dissect_ber_bitstring(implicit_tag
, actx
, tree
, tvb
, offset
,
990 AUDT_protocol_version_bits
, 1, hf_index
, ett_tcap_AUDT_protocol_version
,
999 dissect_tcap_AUDT_application_context_name(bool implicit_tag _U_
, tvbuff_t
*tvb _U_
, int offset _U_
, asn1_ctx_t
*actx _U_
, proto_tree
*tree _U_
, int hf_index _U_
) {
1000 struct tcap_private_t
*p_tcap_private
= (struct tcap_private_t
*)actx
->value_ptr
;
1001 offset
= dissect_ber_object_identifier_str(implicit_tag
, actx
, tree
, tvb
, offset
, hf_index
, &cur_oid
);
1003 if (p_tcap_private
) {
1004 p_tcap_private
->oid
= (const void*) cur_oid
;
1005 p_tcap_private
->acv
=true;
1014 dissect_tcap_EXTERNAL(bool implicit_tag _U_
, tvbuff_t
*tvb _U_
, int offset _U_
, asn1_ctx_t
*actx _U_
, proto_tree
*tree _U_
, int hf_index _U_
) {
1015 offset
= dissect_ber_external_type(implicit_tag
, tree
, tvb
, offset
, actx
, hf_index
, NULL
);
1021 static const ber_sequence_t AUDT_user_information_sequence_of
[1] = {
1022 { &hf_tcap_audt_user_information_item
, BER_CLASS_UNI
, BER_UNI_TAG_EXTERNAL
, BER_FLAGS_NOOWNTAG
, dissect_tcap_EXTERNAL
},
1026 dissect_tcap_AUDT_user_information(bool implicit_tag _U_
, tvbuff_t
*tvb _U_
, int offset _U_
, asn1_ctx_t
*actx _U_
, proto_tree
*tree _U_
, int hf_index _U_
) {
1027 offset
= dissect_ber_sequence_of(implicit_tag
, actx
, tree
, tvb
, offset
,
1028 AUDT_user_information_sequence_of
, hf_index
, ett_tcap_AUDT_user_information
);
1034 static const ber_sequence_t AUDT_apdu_U_sequence
[] = {
1035 { &hf_tcap_audt_protocol_version
, BER_CLASS_CON
, 0, BER_FLAGS_OPTIONAL
|BER_FLAGS_IMPLTAG
, dissect_tcap_AUDT_protocol_version
},
1036 { &hf_tcap_audt_application_context_name
, BER_CLASS_CON
, 1, 0, dissect_tcap_AUDT_application_context_name
},
1037 { &hf_tcap_audt_user_information
, BER_CLASS_CON
, 30, BER_FLAGS_OPTIONAL
|BER_FLAGS_IMPLTAG
, dissect_tcap_AUDT_user_information
},
1038 { NULL
, 0, 0, 0, NULL
}
1042 dissect_tcap_AUDT_apdu_U(bool implicit_tag _U_
, tvbuff_t
*tvb _U_
, int offset _U_
, asn1_ctx_t
*actx _U_
, proto_tree
*tree _U_
, int hf_index _U_
) {
1043 offset
= dissect_ber_sequence(implicit_tag
, actx
, tree
, tvb
, offset
,
1044 AUDT_apdu_U_sequence
, hf_index
, ett_tcap_AUDT_apdu_U
);
1052 dissect_tcap_AUDT_apdu(bool implicit_tag _U_
, tvbuff_t
*tvb _U_
, int offset _U_
, asn1_ctx_t
*actx _U_
, proto_tree
*tree _U_
, int hf_index _U_
) {
1053 offset
= dissect_ber_tagged_type(implicit_tag
, actx
, tree
, tvb
, offset
,
1054 hf_index
, BER_CLASS_APP
, 0, true, dissect_tcap_AUDT_apdu_U
);
1060 const value_string tcap_UniDialoguePDU_vals
[] = {
1061 { 0, "unidialoguePDU" },
1065 static const ber_choice_t UniDialoguePDU_choice
[] = {
1066 { 0, &hf_tcap_unidialoguePDU
, BER_CLASS_APP
, 0, BER_FLAGS_NOOWNTAG
, dissect_tcap_AUDT_apdu
},
1067 { 0, NULL
, 0, 0, 0, NULL
}
1071 dissect_tcap_UniDialoguePDU(bool implicit_tag _U_
, tvbuff_t
*tvb _U_
, int offset _U_
, asn1_ctx_t
*actx _U_
, proto_tree
*tree _U_
, int hf_index _U_
) {
1072 offset
= dissect_ber_choice(actx
, tree
, tvb
, offset
,
1073 UniDialoguePDU_choice
, hf_index
, ett_tcap_UniDialoguePDU
,
1080 static int * const AARQ_protocol_version_bits
[] = {
1081 &hf_tcap_AARQ_protocol_version_version1
,
1086 dissect_tcap_AARQ_protocol_version(bool implicit_tag _U_
, tvbuff_t
*tvb _U_
, int offset _U_
, asn1_ctx_t
*actx _U_
, proto_tree
*tree _U_
, int hf_index _U_
) {
1087 offset
= dissect_ber_bitstring(implicit_tag
, actx
, tree
, tvb
, offset
,
1088 AARQ_protocol_version_bits
, 1, hf_index
, ett_tcap_AARQ_protocol_version
,
1097 dissect_tcap_AARQ_application_context_name(bool implicit_tag _U_
, tvbuff_t
*tvb _U_
, int offset _U_
, asn1_ctx_t
*actx _U_
, proto_tree
*tree _U_
, int hf_index _U_
) {
1098 struct tcap_private_t
*p_tcap_private
= (struct tcap_private_t
*)actx
->value_ptr
;
1099 offset
= dissect_ber_object_identifier_str(implicit_tag
, actx
, tree
, tvb
, offset
, hf_index
, &cur_oid
);
1101 if (p_tcap_private
) {
1102 p_tcap_private
->oid
= (const void*) cur_oid
;
1103 p_tcap_private
->acv
=true;
1110 static const ber_sequence_t AARQ_user_information_sequence_of
[1] = {
1111 { &hf_tcap_aarq_user_information_item
, BER_CLASS_UNI
, BER_UNI_TAG_EXTERNAL
, BER_FLAGS_NOOWNTAG
, dissect_tcap_EXTERNAL
},
1115 dissect_tcap_AARQ_user_information(bool implicit_tag _U_
, tvbuff_t
*tvb _U_
, int offset _U_
, asn1_ctx_t
*actx _U_
, proto_tree
*tree _U_
, int hf_index _U_
) {
1116 offset
= dissect_ber_sequence_of(implicit_tag
, actx
, tree
, tvb
, offset
,
1117 AARQ_user_information_sequence_of
, hf_index
, ett_tcap_AARQ_user_information
);
1123 static const ber_sequence_t AARQ_apdu_U_sequence
[] = {
1124 { &hf_tcap_aarq_protocol_version
, BER_CLASS_CON
, 0, BER_FLAGS_OPTIONAL
|BER_FLAGS_IMPLTAG
, dissect_tcap_AARQ_protocol_version
},
1125 { &hf_tcap_aarq_application_context_name
, BER_CLASS_CON
, 1, 0, dissect_tcap_AARQ_application_context_name
},
1126 { &hf_tcap_aarq_user_information
, BER_CLASS_CON
, 30, BER_FLAGS_OPTIONAL
|BER_FLAGS_IMPLTAG
, dissect_tcap_AARQ_user_information
},
1127 { NULL
, 0, 0, 0, NULL
}
1131 dissect_tcap_AARQ_apdu_U(bool implicit_tag _U_
, tvbuff_t
*tvb _U_
, int offset _U_
, asn1_ctx_t
*actx _U_
, proto_tree
*tree _U_
, int hf_index _U_
) {
1132 offset
= dissect_ber_sequence(implicit_tag
, actx
, tree
, tvb
, offset
,
1133 AARQ_apdu_U_sequence
, hf_index
, ett_tcap_AARQ_apdu_U
);
1141 dissect_tcap_AARQ_apdu(bool implicit_tag _U_
, tvbuff_t
*tvb _U_
, int offset _U_
, asn1_ctx_t
*actx _U_
, proto_tree
*tree _U_
, int hf_index _U_
) {
1142 offset
= dissect_ber_tagged_type(implicit_tag
, actx
, tree
, tvb
, offset
,
1143 hf_index
, BER_CLASS_APP
, 0, true, dissect_tcap_AARQ_apdu_U
);
1149 static int * const AARE_protocol_version_bits
[] = {
1150 &hf_tcap_AARE_protocol_version_version1
,
1155 dissect_tcap_AARE_protocol_version(bool implicit_tag _U_
, tvbuff_t
*tvb _U_
, int offset _U_
, asn1_ctx_t
*actx _U_
, proto_tree
*tree _U_
, int hf_index _U_
) {
1156 offset
= dissect_ber_bitstring(implicit_tag
, actx
, tree
, tvb
, offset
,
1157 AARE_protocol_version_bits
, 1, hf_index
, ett_tcap_AARE_protocol_version
,
1166 dissect_tcap_AARE_application_context_name(bool implicit_tag _U_
, tvbuff_t
*tvb _U_
, int offset _U_
, asn1_ctx_t
*actx _U_
, proto_tree
*tree _U_
, int hf_index _U_
) {
1167 struct tcap_private_t
*p_tcap_private
= (struct tcap_private_t
*)actx
->value_ptr
;
1168 offset
= dissect_ber_object_identifier_str(implicit_tag
, actx
, tree
, tvb
, offset
, hf_index
, &cur_oid
);
1170 if (p_tcap_private
) {
1171 p_tcap_private
->oid
= (const void*) cur_oid
;
1172 p_tcap_private
->acv
=true;
1179 static const value_string tcap_Associate_result_vals
[] = {
1181 { 1, "reject-permanent" },
1187 dissect_tcap_Associate_result(bool implicit_tag _U_
, tvbuff_t
*tvb _U_
, int offset _U_
, asn1_ctx_t
*actx _U_
, proto_tree
*tree _U_
, int hf_index _U_
) {
1188 offset
= dissect_ber_integer(implicit_tag
, actx
, tree
, tvb
, offset
, hf_index
,
1195 static const value_string tcap_T_dialogue_service_user_vals
[] = {
1197 { 1, "no-reason-given" },
1198 { 2, "application-context-name-not-supported" },
1204 dissect_tcap_T_dialogue_service_user(bool implicit_tag _U_
, tvbuff_t
*tvb _U_
, int offset _U_
, asn1_ctx_t
*actx _U_
, proto_tree
*tree _U_
, int hf_index _U_
) {
1205 offset
= dissect_ber_integer(implicit_tag
, actx
, tree
, tvb
, offset
, hf_index
,
1212 static const value_string tcap_T_dialogue_service_provider_vals
[] = {
1214 { 1, "no-reason-given" },
1215 { 2, "no-common-dialogue-portion" },
1221 dissect_tcap_T_dialogue_service_provider(bool implicit_tag _U_
, tvbuff_t
*tvb _U_
, int offset _U_
, asn1_ctx_t
*actx _U_
, proto_tree
*tree _U_
, int hf_index _U_
) {
1222 offset
= dissect_ber_integer(implicit_tag
, actx
, tree
, tvb
, offset
, hf_index
,
1229 static const value_string tcap_Associate_source_diagnostic_vals
[] = {
1230 { 1, "dialogue-service-user" },
1231 { 2, "dialogue-service-provider" },
1235 static const ber_choice_t Associate_source_diagnostic_choice
[] = {
1236 { 1, &hf_tcap_dialogue_service_user
, BER_CLASS_CON
, 1, 0, dissect_tcap_T_dialogue_service_user
},
1237 { 2, &hf_tcap_dialogue_service_provider
, BER_CLASS_CON
, 2, 0, dissect_tcap_T_dialogue_service_provider
},
1238 { 0, NULL
, 0, 0, 0, NULL
}
1242 dissect_tcap_Associate_source_diagnostic(bool implicit_tag _U_
, tvbuff_t
*tvb _U_
, int offset _U_
, asn1_ctx_t
*actx _U_
, proto_tree
*tree _U_
, int hf_index _U_
) {
1243 offset
= dissect_ber_choice(actx
, tree
, tvb
, offset
,
1244 Associate_source_diagnostic_choice
, hf_index
, ett_tcap_Associate_source_diagnostic
,
1251 static const ber_sequence_t AARE_user_information_sequence_of
[1] = {
1252 { &hf_tcap_aare_user_information_item
, BER_CLASS_UNI
, BER_UNI_TAG_EXTERNAL
, BER_FLAGS_NOOWNTAG
, dissect_tcap_EXTERNAL
},
1256 dissect_tcap_AARE_user_information(bool implicit_tag _U_
, tvbuff_t
*tvb _U_
, int offset _U_
, asn1_ctx_t
*actx _U_
, proto_tree
*tree _U_
, int hf_index _U_
) {
1257 offset
= dissect_ber_sequence_of(implicit_tag
, actx
, tree
, tvb
, offset
,
1258 AARE_user_information_sequence_of
, hf_index
, ett_tcap_AARE_user_information
);
1264 static const ber_sequence_t AARE_apdu_U_sequence
[] = {
1265 { &hf_tcap_aare_protocol_version
, BER_CLASS_CON
, 0, BER_FLAGS_OPTIONAL
|BER_FLAGS_IMPLTAG
, dissect_tcap_AARE_protocol_version
},
1266 { &hf_tcap_aare_application_context_name
, BER_CLASS_CON
, 1, 0, dissect_tcap_AARE_application_context_name
},
1267 { &hf_tcap_result
, BER_CLASS_CON
, 2, 0, dissect_tcap_Associate_result
},
1268 { &hf_tcap_result_source_diagnostic
, BER_CLASS_CON
, 3, BER_FLAGS_NOTCHKTAG
, dissect_tcap_Associate_source_diagnostic
},
1269 { &hf_tcap_aare_user_information
, BER_CLASS_CON
, 30, BER_FLAGS_OPTIONAL
|BER_FLAGS_IMPLTAG
, dissect_tcap_AARE_user_information
},
1270 { NULL
, 0, 0, 0, NULL
}
1274 dissect_tcap_AARE_apdu_U(bool implicit_tag _U_
, tvbuff_t
*tvb _U_
, int offset _U_
, asn1_ctx_t
*actx _U_
, proto_tree
*tree _U_
, int hf_index _U_
) {
1275 offset
= dissect_ber_sequence(implicit_tag
, actx
, tree
, tvb
, offset
,
1276 AARE_apdu_U_sequence
, hf_index
, ett_tcap_AARE_apdu_U
);
1284 dissect_tcap_AARE_apdu(bool implicit_tag _U_
, tvbuff_t
*tvb _U_
, int offset _U_
, asn1_ctx_t
*actx _U_
, proto_tree
*tree _U_
, int hf_index _U_
) {
1285 offset
= dissect_ber_tagged_type(implicit_tag
, actx
, tree
, tvb
, offset
,
1286 hf_index
, BER_CLASS_APP
, 1, true, dissect_tcap_AARE_apdu_U
);
1292 static const value_string tcap_ABRT_source_vals
[] = {
1293 { 0, "dialogue-service-user" },
1294 { 1, "dialogue-service-provider" },
1300 dissect_tcap_ABRT_source(bool implicit_tag _U_
, tvbuff_t
*tvb _U_
, int offset _U_
, asn1_ctx_t
*actx _U_
, proto_tree
*tree _U_
, int hf_index _U_
) {
1301 offset
= dissect_ber_integer(implicit_tag
, actx
, tree
, tvb
, offset
, hf_index
,
1308 static const ber_sequence_t ABRT_user_information_sequence_of
[1] = {
1309 { &hf_tcap_abrt_user_information_item
, BER_CLASS_UNI
, BER_UNI_TAG_EXTERNAL
, BER_FLAGS_NOOWNTAG
, dissect_tcap_EXTERNAL
},
1313 dissect_tcap_ABRT_user_information(bool implicit_tag _U_
, tvbuff_t
*tvb _U_
, int offset _U_
, asn1_ctx_t
*actx _U_
, proto_tree
*tree _U_
, int hf_index _U_
) {
1314 offset
= dissect_ber_sequence_of(implicit_tag
, actx
, tree
, tvb
, offset
,
1315 ABRT_user_information_sequence_of
, hf_index
, ett_tcap_ABRT_user_information
);
1321 static const ber_sequence_t ABRT_apdu_U_sequence
[] = {
1322 { &hf_tcap_abort_source
, BER_CLASS_CON
, 0, BER_FLAGS_IMPLTAG
, dissect_tcap_ABRT_source
},
1323 { &hf_tcap_abrt_user_information
, BER_CLASS_CON
, 30, BER_FLAGS_OPTIONAL
|BER_FLAGS_IMPLTAG
, dissect_tcap_ABRT_user_information
},
1324 { NULL
, 0, 0, 0, NULL
}
1328 dissect_tcap_ABRT_apdu_U(bool implicit_tag _U_
, tvbuff_t
*tvb _U_
, int offset _U_
, asn1_ctx_t
*actx _U_
, proto_tree
*tree _U_
, int hf_index _U_
) {
1329 offset
= dissect_ber_sequence(implicit_tag
, actx
, tree
, tvb
, offset
,
1330 ABRT_apdu_U_sequence
, hf_index
, ett_tcap_ABRT_apdu_U
);
1338 dissect_tcap_ABRT_apdu(bool implicit_tag _U_
, tvbuff_t
*tvb _U_
, int offset _U_
, asn1_ctx_t
*actx _U_
, proto_tree
*tree _U_
, int hf_index _U_
) {
1339 offset
= dissect_ber_tagged_type(implicit_tag
, actx
, tree
, tvb
, offset
,
1340 hf_index
, BER_CLASS_APP
, 4, true, dissect_tcap_ABRT_apdu_U
);
1346 const value_string tcap_DialoguePDU_vals
[] = {
1347 { 0, "dialogueRequest" },
1348 { 1, "dialogueResponse" },
1349 { 4, "dialogueAbort" },
1353 static const ber_choice_t DialoguePDU_choice
[] = {
1354 { 0, &hf_tcap_dialogueRequest
, BER_CLASS_APP
, 0, BER_FLAGS_NOOWNTAG
, dissect_tcap_AARQ_apdu
},
1355 { 1, &hf_tcap_dialogueResponse
, BER_CLASS_APP
, 1, BER_FLAGS_NOOWNTAG
, dissect_tcap_AARE_apdu
},
1356 { 4, &hf_tcap_dialogueAbort
, BER_CLASS_APP
, 4, BER_FLAGS_NOOWNTAG
, dissect_tcap_ABRT_apdu
},
1357 { 0, NULL
, 0, 0, 0, NULL
}
1361 dissect_tcap_DialoguePDU(bool implicit_tag _U_
, tvbuff_t
*tvb _U_
, int offset _U_
, asn1_ctx_t
*actx _U_
, proto_tree
*tree _U_
, int hf_index _U_
) {
1362 offset
= dissect_ber_choice(actx
, tree
, tvb
, offset
,
1363 DialoguePDU_choice
, hf_index
, ett_tcap_DialoguePDU
,
1371 static int dissect_UniDialoguePDU_PDU(tvbuff_t
*tvb _U_
, packet_info
*pinfo _U_
, proto_tree
*tree _U_
, void *data _U_
) {
1373 asn1_ctx_t asn1_ctx
;
1374 asn1_ctx_init(&asn1_ctx
, ASN1_ENC_BER
, true, pinfo
);
1375 offset
= dissect_tcap_UniDialoguePDU(false, tvb
, offset
, &asn1_ctx
, tree
, hf_tcap_UniDialoguePDU_PDU
);
1378 static int dissect_DialoguePDU_PDU(tvbuff_t
*tvb _U_
, packet_info
*pinfo _U_
, proto_tree
*tree _U_
, void *data _U_
) {
1380 asn1_ctx_t asn1_ctx
;
1381 asn1_ctx_init(&asn1_ctx
, ASN1_ENC_BER
, true, pinfo
);
1382 offset
= dissect_tcap_DialoguePDU(false, tvb
, offset
, &asn1_ctx
, tree
, hf_tcap_DialoguePDU_PDU
);
1390 #undef DEBUG_TCAPSRT
1391 /* #define DEBUG_TCAPSRT */
1393 #ifdef DEBUG_TCAPSRT
1396 static unsigned debug_level
= 99;
1399 dbg(unsigned level
, const char* fmt
, ...)
1403 if (level
> debug_level
) return;
1405 vfprintf(stderr
, fmt
, ap
);
1411 tcaphash_context_equal(const void *k1
, const void *k2
)
1413 const struct tcaphash_context_key_t
*key1
= (const struct tcaphash_context_key_t
*) k1
;
1414 const struct tcaphash_context_key_t
*key2
= (const struct tcaphash_context_key_t
*) k2
;
1416 return (key1
->session_id
== key2
->session_id
);
1419 /* calculate a hash key */
1421 tcaphash_context_calchash(const void *k
)
1423 const struct tcaphash_context_key_t
*key
= (const struct tcaphash_context_key_t
*) k
;
1424 return key
->session_id
;
1429 tcaphash_begin_equal(const void *k1
, const void *k2
)
1431 const struct tcaphash_begin_info_key_t
*key1
= (const struct tcaphash_begin_info_key_t
*) k1
;
1432 const struct tcaphash_begin_info_key_t
*key2
= (const struct tcaphash_begin_info_key_t
*) k2
;
1434 if (key1
->hashKey
== key2
->hashKey
) {
1435 if ( (key1
->pc_hash
== key2
->pc_hash
) && (key1
->tid
== key2
->tid
) )
1441 /* calculate a hash key */
1443 tcaphash_begin_calchash(const void *k
)
1445 const struct tcaphash_begin_info_key_t
*key
= (const struct tcaphash_begin_info_key_t
*) k
;
1447 /* hashkey = key->opc_hash<<16 + key->dpc_hash<<8 + key->src_tid; */
1453 tcaphash_cont_equal(const void *k1
, const void *k2
)
1455 const struct tcaphash_cont_info_key_t
*key1
= (const struct tcaphash_cont_info_key_t
*) k1
;
1456 const struct tcaphash_cont_info_key_t
*key2
= (const struct tcaphash_cont_info_key_t
*) k2
;
1458 if (key1
->hashKey
== key2
->hashKey
) {
1460 if ( (key1
->opc_hash
== key2
->opc_hash
) &&
1461 (key1
->dpc_hash
== key2
->dpc_hash
) &&
1462 (key1
->src_tid
== key2
->src_tid
) &&
1463 (key1
->dst_tid
== key2
->dst_tid
) ) {
1466 else if ( (key1
->opc_hash
== key2
->dpc_hash
) &&
1467 (key1
->dpc_hash
== key2
->opc_hash
) &&
1468 (key1
->src_tid
== key2
->dst_tid
) &&
1469 (key1
->dst_tid
== key2
->src_tid
) ) {
1476 /* calculate a hash key */
1478 tcaphash_cont_calchash(const void *k
)
1480 const struct tcaphash_cont_info_key_t
*key
= (const struct tcaphash_cont_info_key_t
*) k
;
1482 hashkey
= key
->src_tid
+ key
->dst_tid
;
1488 tcaphash_end_equal(const void *k1
, const void *k2
)
1490 const struct tcaphash_end_info_key_t
*key1
= (const struct tcaphash_end_info_key_t
*) k1
;
1491 const struct tcaphash_end_info_key_t
*key2
= (const struct tcaphash_end_info_key_t
*) k2
;
1493 if (key1
->hashKey
== key2
->hashKey
) {
1494 if ( (key1
->opc_hash
== key2
->opc_hash
) &&
1495 (key1
->dpc_hash
== key2
->dpc_hash
) &&
1496 (key1
->tid
== key2
->tid
) )
1502 /* calculate a hash key */
1504 tcaphash_end_calchash(const void *k
)
1506 const struct tcaphash_end_info_key_t
*key
= (const struct tcaphash_end_info_key_t
*) k
;
1513 tcaphash_ansi_equal(const void *k1
, const void *k2
)
1515 const struct tcaphash_ansi_info_key_t
*key1
= (const struct tcaphash_ansi_info_key_t
*) k1
;
1516 const struct tcaphash_ansi_info_key_t
*key2
= (const struct tcaphash_ansi_info_key_t
*) k2
;
1518 if (key1
->hashKey
== key2
->hashKey
) {
1520 if ( ( (key1
->opc_hash
== key2
->opc_hash
) &&
1521 (key1
->dpc_hash
== key2
->dpc_hash
) &&
1522 (key1
->tid
== key2
->tid
) )
1524 ( (key1
->opc_hash
== key2
->dpc_hash
) &&
1525 (key1
->dpc_hash
== key2
->opc_hash
) &&
1526 (key1
->tid
== key2
->tid
) )
1533 /* calculate a hash key */
1535 tcaphash_ansi_calchash(const void *k
)
1537 const struct tcaphash_ansi_info_key_t
*key
= (const struct tcaphash_ansi_info_key_t
*) k
;
1539 /* hashkey = key->opc_hash<<16 + key->dpc_hash<<8 + key->src_tid; */
1545 * Update a record with the data of the Request
1548 update_tcaphash_begincall(struct tcaphash_begincall_t
*p_tcaphash_begincall
,
1551 p_tcaphash_begincall
->context
->first_frame
= pinfo
->num
;
1552 p_tcaphash_begincall
->context
->last_frame
= 0;
1553 p_tcaphash_begincall
->context
->responded
= false;
1554 p_tcaphash_begincall
->context
->begin_time
= pinfo
->abs_ts
;
1558 * Append a new dialogue, using the same Key, to the chained list
1559 * The time is stored too
1561 static struct tcaphash_begincall_t
*
1562 append_tcaphash_begincall(struct tcaphash_begincall_t
*prev_begincall
,
1563 struct tcaphash_context_t
*p_tcaphash_context
,
1566 struct tcaphash_begincall_t
*p_new_tcaphash_begincall
= NULL
;
1568 /* Append the transaction to the list, when the same key is found
1569 This should append when the tcap-transaction Id is reused */
1571 p_new_tcaphash_begincall
= wmem_new0(wmem_file_scope(), struct tcaphash_begincall_t
);
1572 p_new_tcaphash_begincall
->context
=p_tcaphash_context
;
1573 p_tcaphash_context
->begincall
=p_new_tcaphash_begincall
;
1574 p_new_tcaphash_begincall
->beginkey
=prev_begincall
->beginkey
;
1575 p_new_tcaphash_begincall
->context
->first_frame
= pinfo
->num
;
1576 p_new_tcaphash_begincall
->next_begincall
=NULL
;
1577 p_new_tcaphash_begincall
->previous_begincall
=prev_begincall
;
1578 p_new_tcaphash_begincall
->father
=false;
1580 #ifdef DEBUG_TCAPSRT
1581 dbg(10,"+B%d ", p_new_tcaphash_begincall
->context
->session_id
);
1583 /* Insert in the chained list */
1584 prev_begincall
->next_begincall
= p_new_tcaphash_begincall
;
1585 if (prev_begincall
->context
->last_frame
== 0) {
1586 #ifdef DEBUG_TCAPSRT
1589 prev_begincall
->context
->last_frame
= pinfo
->num
-1;
1591 return p_new_tcaphash_begincall
;
1595 * Update a record with the data of the Request
1598 update_tcaphash_ansicall(struct tcaphash_ansicall_t
*p_tcaphash_ansicall
,
1601 p_tcaphash_ansicall
->context
->first_frame
= pinfo
->num
;
1602 p_tcaphash_ansicall
->context
->last_frame
= 0;
1603 p_tcaphash_ansicall
->context
->responded
= false;
1604 p_tcaphash_ansicall
->context
->begin_time
= pinfo
->abs_ts
;
1608 * Append a new dialogue, using the same Key, to the chained list
1609 * The time is stored too
1611 static struct tcaphash_ansicall_t
*
1612 append_tcaphash_ansicall(struct tcaphash_ansicall_t
*prev_ansicall
,
1613 struct tcaphash_context_t
*p_tcaphash_context
,
1616 struct tcaphash_ansicall_t
*p_new_tcaphash_ansicall
= NULL
;
1618 /* Append the transaction to the list, when the same key is found
1619 This should append when the tcap-transaction Id is reused */
1621 p_new_tcaphash_ansicall
= wmem_new0(wmem_file_scope(), struct tcaphash_ansicall_t
);
1622 p_new_tcaphash_ansicall
->context
=p_tcaphash_context
;
1623 p_tcaphash_context
->ansicall
=p_new_tcaphash_ansicall
;
1624 p_new_tcaphash_ansicall
->ansikey
=prev_ansicall
->ansikey
;
1625 p_new_tcaphash_ansicall
->context
->first_frame
= pinfo
->num
;
1626 p_new_tcaphash_ansicall
->next_ansicall
=NULL
;
1627 p_new_tcaphash_ansicall
->previous_ansicall
=prev_ansicall
;
1628 p_new_tcaphash_ansicall
->father
=false;
1630 #ifdef DEBUG_TCAPSRT
1631 dbg(10,"+A%d ", p_new_tcaphash_ansicall
->context
->session_id
);
1633 /* Insert in the chained list */
1634 prev_ansicall
->next_ansicall
= p_new_tcaphash_ansicall
;
1635 if (prev_ansicall
->context
->last_frame
== 0) {
1636 #ifdef DEBUG_TCAPSRT
1639 prev_ansicall
->context
->last_frame
= pinfo
->num
-1;
1641 return p_new_tcaphash_ansicall
;
1645 static struct tcaphash_contcall_t
*
1646 append_tcaphash_contcall(struct tcaphash_contcall_t
*prev_contcall
,
1647 struct tcaphash_context_t
*p_tcaphash_context
)
1649 struct tcaphash_contcall_t
*p_new_tcaphash_contcall
= NULL
;
1651 /* Append the transaction to the list, when the same key is found
1652 This should append when the tcap-transaction Id is reused */
1654 p_new_tcaphash_contcall
= wmem_new0(wmem_file_scope(), struct tcaphash_contcall_t
);
1655 p_new_tcaphash_contcall
->context
=p_tcaphash_context
;
1656 p_tcaphash_context
->contcall
=p_new_tcaphash_contcall
;
1657 p_new_tcaphash_contcall
->contkey
=prev_contcall
->contkey
;
1658 p_new_tcaphash_contcall
->next_contcall
=NULL
;
1659 p_new_tcaphash_contcall
->previous_contcall
=prev_contcall
;
1660 p_new_tcaphash_contcall
->father
=false;
1662 #ifdef DEBUG_TCAPSRT
1663 dbg(10,"+C%d ", p_new_tcaphash_contcall
->context
->session_id
);
1665 /* Insert in the chained list */
1666 prev_contcall
->next_contcall
= p_new_tcaphash_contcall
;
1667 return p_new_tcaphash_contcall
;
1671 static struct tcaphash_endcall_t
*
1672 append_tcaphash_endcall(struct tcaphash_endcall_t
*prev_endcall
,
1673 struct tcaphash_context_t
*p_tcaphash_context
)
1675 struct tcaphash_endcall_t
*p_new_tcaphash_endcall
= NULL
;
1677 /* Append the transaction to the list, when the same key is found
1678 This should append when the tcap-transaction Id is reused */
1680 p_new_tcaphash_endcall
= wmem_new0(wmem_file_scope(), struct tcaphash_endcall_t
);
1681 p_new_tcaphash_endcall
->context
=p_tcaphash_context
;
1682 p_tcaphash_context
->endcall
=p_new_tcaphash_endcall
;
1683 p_new_tcaphash_endcall
->endkey
=prev_endcall
->endkey
;
1684 p_new_tcaphash_endcall
->next_endcall
=NULL
;
1685 p_new_tcaphash_endcall
->previous_endcall
=prev_endcall
;
1686 p_new_tcaphash_endcall
->father
=false;
1688 #ifdef DEBUG_TCAPSRT
1689 dbg(10,"+E%d ", p_new_tcaphash_endcall
->context
->session_id
);
1691 /* Insert in the chained list */
1692 prev_endcall
->next_endcall
= p_new_tcaphash_endcall
;
1693 return p_new_tcaphash_endcall
;
1698 * Find the dialog by Key and Time
1700 static struct tcaphash_begincall_t
*
1701 find_tcaphash_begin(struct tcaphash_begin_info_key_t
*p_tcaphash_begin_key
,
1702 packet_info
*pinfo
, bool isBegin
)
1704 struct tcaphash_begincall_t
*p_tcaphash_begincall
= NULL
;
1705 p_tcaphash_begincall
= (struct tcaphash_begincall_t
*)wmem_map_lookup(tcaphash_begin
, p_tcaphash_begin_key
);
1707 if(p_tcaphash_begincall
) {
1709 if ( p_tcaphash_begincall
->context
) {
1711 pinfo
->num
== p_tcaphash_begincall
->context
->first_frame
)
1714 pinfo
->num
>= p_tcaphash_begincall
->context
->first_frame
&&
1715 ( p_tcaphash_begincall
->context
->last_frame
?pinfo
->num
<= p_tcaphash_begincall
->context
->last_frame
:1 )
1718 /* We have a dialogue, with this key, opened before this request */
1719 #ifdef DEBUG_TCAPSRT
1720 dbg(10,"B%d ", p_tcaphash_begincall
->context
->session_id
);
1722 return p_tcaphash_begincall
;
1724 #ifdef DEBUG_TCAPSRT
1725 dbg(60,"[B%d] ", p_tcaphash_begincall
->context
->session_id
);
1728 /* Break when list end is reached */
1729 if(p_tcaphash_begincall
->next_begincall
== NULL
) {
1730 #ifdef DEBUG_TCAPSRT
1731 dbg(23,"End of Blist ");
1735 p_tcaphash_begincall
= p_tcaphash_begincall
->next_begincall
;
1736 } while (p_tcaphash_begincall
!= NULL
) ;
1738 #ifdef DEBUG_TCAPSRT
1739 dbg(23,"Not in Bhash ");
1747 static struct tcaphash_contcall_t
*
1748 find_tcaphash_cont(struct tcaphash_cont_info_key_t
*p_tcaphash_cont_key
,
1751 struct tcaphash_contcall_t
*p_tcaphash_contcall
= NULL
;
1752 p_tcaphash_contcall
= (struct tcaphash_contcall_t
*)wmem_map_lookup(tcaphash_cont
, p_tcaphash_cont_key
);
1754 if(p_tcaphash_contcall
) {
1756 if ( p_tcaphash_contcall
->context
) {
1757 if (pinfo
->num
>= p_tcaphash_contcall
->context
->first_frame
&&
1758 (p_tcaphash_contcall
->context
->last_frame
?pinfo
->num
<= p_tcaphash_contcall
->context
->last_frame
:1) ) {
1759 /* We have a dialogue, with this key, opened before this request */
1760 #ifdef DEBUG_TCAPSRT
1761 dbg(10,"C%d ", p_tcaphash_contcall
->context
->session_id
);
1763 return p_tcaphash_contcall
;
1765 #ifdef DEBUG_TCAPSRT
1766 dbg(60,"[C%d] ", p_tcaphash_contcall
->context
->session_id
);
1769 /* Break when list end is reached */
1770 if(p_tcaphash_contcall
->next_contcall
== NULL
) {
1771 #ifdef DEBUG_TCAPSRT
1772 dbg(23,"End of Clist ");
1776 p_tcaphash_contcall
= p_tcaphash_contcall
->next_contcall
;
1777 } while (p_tcaphash_contcall
!= NULL
) ;
1779 #ifdef DEBUG_TCAPSRT
1780 dbg(23,"Not in Chash ");
1786 static struct tcaphash_endcall_t
*
1787 find_tcaphash_end(struct tcaphash_end_info_key_t
*p_tcaphash_end_key
,
1788 packet_info
*pinfo
, bool isEnd
)
1790 struct tcaphash_endcall_t
*p_tcaphash_endcall
= NULL
;
1791 p_tcaphash_endcall
= (struct tcaphash_endcall_t
*)wmem_map_lookup(tcaphash_end
, p_tcaphash_end_key
);
1793 if(p_tcaphash_endcall
) {
1795 if ( p_tcaphash_endcall
->context
) {
1797 (p_tcaphash_endcall
->context
->last_frame
?pinfo
->num
== p_tcaphash_endcall
->context
->last_frame
:1)
1801 pinfo
->num
>= p_tcaphash_endcall
->context
->first_frame
&&
1802 (p_tcaphash_endcall
->context
->last_frame
?pinfo
->num
<= p_tcaphash_endcall
->context
->last_frame
:1)
1805 /* We have a dialogue, with this key, opened before this request */
1806 #ifdef DEBUG_TCAPSRT
1807 dbg(10,"E%d ", p_tcaphash_endcall
->context
->session_id
);
1809 return p_tcaphash_endcall
;
1811 #ifdef DEBUG_TCAPSRT
1812 dbg(60,"[E%d] ", p_tcaphash_endcall
->context
->session_id
);
1815 /* Break when list end is reached */
1816 if(p_tcaphash_endcall
->next_endcall
== NULL
) {
1817 #ifdef DEBUG_TCAPSRT
1818 dbg(23,"End of Elist ");
1822 p_tcaphash_endcall
= p_tcaphash_endcall
->next_endcall
;
1823 } while (p_tcaphash_endcall
!= NULL
) ;
1825 #ifdef DEBUG_TCAPSRT
1826 dbg(23,"Not in Ehash ");
1833 * New record to create, to identify a new transaction
1835 static struct tcaphash_context_t
*
1836 new_tcaphash_context(struct tcaphash_context_key_t
*p_tcaphash_context_key
,
1839 struct tcaphash_context_key_t
*p_new_tcaphash_context_key
;
1840 struct tcaphash_context_t
*p_new_tcaphash_context
= NULL
;
1842 /* Register the transaction in the hash table
1843 with the tcap transaction Id as Main Key
1844 Once created, this entry will be updated later */
1846 p_new_tcaphash_context_key
= wmem_new(wmem_file_scope(), struct tcaphash_context_key_t
);
1847 p_new_tcaphash_context_key
->session_id
= p_tcaphash_context_key
->session_id
;
1849 p_new_tcaphash_context
= wmem_new0(wmem_file_scope(), struct tcaphash_context_t
);
1850 p_new_tcaphash_context
->key
= p_new_tcaphash_context_key
;
1851 p_new_tcaphash_context
->session_id
= p_tcaphash_context_key
->session_id
;
1852 p_new_tcaphash_context
->first_frame
= pinfo
->num
;
1853 #ifdef DEBUG_TCAPSRT
1854 dbg(10,"S%d ", p_new_tcaphash_context
->session_id
);
1857 wmem_map_insert(tcaphash_context
, p_new_tcaphash_context_key
, p_new_tcaphash_context
);
1858 return p_new_tcaphash_context
;
1862 * New record to create, to identify a new transaction
1864 static struct tcaphash_begincall_t
*
1865 new_tcaphash_begin(struct tcaphash_begin_info_key_t
*p_tcaphash_begin_key
,
1866 struct tcaphash_context_t
*p_tcaphash_context
)
1868 struct tcaphash_begin_info_key_t
*p_new_tcaphash_begin_key
;
1869 struct tcaphash_begincall_t
*p_new_tcaphash_begincall
= NULL
;
1871 /* Register the transaction in the hash table
1872 with the tcap transaction Id as Main Key
1873 Once created, this entry will be updated later */
1875 p_new_tcaphash_begin_key
= wmem_new(wmem_file_scope(), struct tcaphash_begin_info_key_t
);
1876 p_new_tcaphash_begin_key
->hashKey
= p_tcaphash_begin_key
->hashKey
;
1877 p_new_tcaphash_begin_key
->tid
= p_tcaphash_begin_key
->tid
;
1878 p_new_tcaphash_begin_key
->pc_hash
= p_tcaphash_begin_key
->pc_hash
;
1880 p_new_tcaphash_begincall
= wmem_new0(wmem_file_scope(), struct tcaphash_begincall_t
);
1881 p_new_tcaphash_begincall
->beginkey
=p_new_tcaphash_begin_key
;
1882 p_new_tcaphash_begincall
->context
=p_tcaphash_context
;
1883 p_tcaphash_context
->begincall
=p_new_tcaphash_begincall
;
1884 p_new_tcaphash_begincall
->father
=true;
1885 p_new_tcaphash_begincall
->next_begincall
=NULL
;
1886 p_new_tcaphash_begincall
->previous_begincall
=NULL
;
1888 #ifdef DEBUG_TCAPSRT
1889 dbg(10,"B%d ", p_new_tcaphash_begincall
->context
->session_id
);
1892 wmem_map_insert(tcaphash_begin
, p_new_tcaphash_begin_key
, p_new_tcaphash_begincall
);
1893 return p_new_tcaphash_begincall
;
1899 * New record to create, to identify a new transaction
1901 static struct tcaphash_contcall_t
*
1902 new_tcaphash_cont(struct tcaphash_cont_info_key_t
*p_tcaphash_cont_key
,
1903 struct tcaphash_context_t
*p_tcaphash_context
)
1905 struct tcaphash_cont_info_key_t
*p_new_tcaphash_cont_key
;
1906 struct tcaphash_contcall_t
*p_new_tcaphash_contcall
= NULL
;
1908 /* Register the transaction in the hash table
1909 with the tcap transaction Id as Main Key
1910 Once created, this entry will be updated later */
1912 p_new_tcaphash_cont_key
= wmem_new(wmem_file_scope(), struct tcaphash_cont_info_key_t
);
1913 p_new_tcaphash_cont_key
->hashKey
= p_tcaphash_cont_key
->hashKey
;
1914 p_new_tcaphash_cont_key
->src_tid
= p_tcaphash_cont_key
->src_tid
;
1915 p_new_tcaphash_cont_key
->dst_tid
= p_tcaphash_cont_key
->dst_tid
;
1916 p_new_tcaphash_cont_key
->opc_hash
= p_tcaphash_cont_key
->opc_hash
;
1917 p_new_tcaphash_cont_key
->dpc_hash
= p_tcaphash_cont_key
->dpc_hash
;
1919 p_new_tcaphash_contcall
= wmem_new0(wmem_file_scope(), struct tcaphash_contcall_t
);
1920 p_new_tcaphash_contcall
->contkey
=p_new_tcaphash_cont_key
;
1921 p_new_tcaphash_contcall
->context
=p_tcaphash_context
;
1922 p_tcaphash_context
->contcall
=p_new_tcaphash_contcall
;
1923 p_new_tcaphash_contcall
->father
=true;
1924 p_new_tcaphash_contcall
->next_contcall
=NULL
;
1925 p_new_tcaphash_contcall
->previous_contcall
=NULL
;
1927 #ifdef DEBUG_TCAPSRT
1928 dbg(10,"C%d ", p_new_tcaphash_contcall
->context
->session_id
);
1931 wmem_map_insert(tcaphash_cont
, p_new_tcaphash_cont_key
, p_new_tcaphash_contcall
);
1932 return p_new_tcaphash_contcall
;
1937 * New record to create, to identify a new transaction
1939 static struct tcaphash_endcall_t
*
1940 new_tcaphash_end(struct tcaphash_end_info_key_t
*p_tcaphash_end_key
,
1941 struct tcaphash_context_t
*p_tcaphash_context
)
1943 struct tcaphash_end_info_key_t
*p_new_tcaphash_end_key
;
1944 struct tcaphash_endcall_t
*p_new_tcaphash_endcall
= NULL
;
1946 /* Register the transaction in the hash table
1947 with the tcap transaction Id as Main Key
1948 Once created, this entry will be updated later */
1950 p_new_tcaphash_end_key
= wmem_new(wmem_file_scope(), struct tcaphash_end_info_key_t
);
1951 p_new_tcaphash_end_key
->hashKey
= p_tcaphash_end_key
->hashKey
;
1952 p_new_tcaphash_end_key
->tid
= p_tcaphash_end_key
->tid
;
1953 p_new_tcaphash_end_key
->opc_hash
= p_tcaphash_end_key
->opc_hash
;
1954 p_new_tcaphash_end_key
->dpc_hash
= p_tcaphash_end_key
->dpc_hash
;
1956 p_new_tcaphash_endcall
= wmem_new0(wmem_file_scope(), struct tcaphash_endcall_t
);
1957 p_new_tcaphash_endcall
->endkey
=p_new_tcaphash_end_key
;
1958 p_new_tcaphash_endcall
->context
=p_tcaphash_context
;
1959 p_tcaphash_context
->endcall
=p_new_tcaphash_endcall
;
1960 p_new_tcaphash_endcall
->father
=true;
1961 p_new_tcaphash_endcall
->next_endcall
=NULL
;
1962 p_new_tcaphash_endcall
->previous_endcall
=NULL
;
1964 #ifdef DEBUG_TCAPSRT
1965 dbg(10,"E%d ", p_new_tcaphash_endcall
->context
->session_id
);
1968 wmem_map_insert(tcaphash_end
, p_new_tcaphash_end_key
, p_new_tcaphash_endcall
);
1969 return p_new_tcaphash_endcall
;
1972 * New record to create, to identify a new transaction
1974 static struct tcaphash_ansicall_t
*
1975 new_tcaphash_ansi(struct tcaphash_ansi_info_key_t
*p_tcaphash_ansi_key
,
1976 struct tcaphash_context_t
*p_tcaphash_context
)
1978 struct tcaphash_ansi_info_key_t
*p_new_tcaphash_ansi_key
;
1979 struct tcaphash_ansicall_t
*p_new_tcaphash_ansicall
= NULL
;
1981 /* Register the transaction in the hash table
1982 with the tcap transaction Id as Main Key
1983 Once created, this entry will be updated later */
1985 p_new_tcaphash_ansi_key
= wmem_new(wmem_file_scope(), struct tcaphash_ansi_info_key_t
);
1986 p_new_tcaphash_ansi_key
->hashKey
= p_tcaphash_ansi_key
->hashKey
;
1987 p_new_tcaphash_ansi_key
->tid
= p_tcaphash_ansi_key
->tid
;
1988 p_new_tcaphash_ansi_key
->opc_hash
= p_tcaphash_ansi_key
->opc_hash
;
1989 p_new_tcaphash_ansi_key
->dpc_hash
= p_tcaphash_ansi_key
->dpc_hash
;
1991 p_new_tcaphash_ansicall
= wmem_new0(wmem_file_scope(), struct tcaphash_ansicall_t
);
1992 p_new_tcaphash_ansicall
->ansikey
=p_new_tcaphash_ansi_key
;
1993 p_new_tcaphash_ansicall
->context
=p_tcaphash_context
;
1994 p_tcaphash_context
->ansicall
=p_new_tcaphash_ansicall
;
1995 p_new_tcaphash_ansicall
->father
=true;
1996 p_new_tcaphash_ansicall
->next_ansicall
=NULL
;
1997 p_new_tcaphash_ansicall
->previous_ansicall
=NULL
;
1999 #ifdef DEBUG_TCAPSRT
2000 dbg(10,"A%d ", p_new_tcaphash_ansicall
->context
->session_id
);
2003 wmem_map_insert(tcaphash_ansi
, p_new_tcaphash_ansi_key
, p_new_tcaphash_ansicall
);
2004 return p_new_tcaphash_ansicall
;
2007 static struct tcaphash_contcall_t
*
2008 create_tcaphash_cont(struct tcaphash_cont_info_key_t
*p_tcaphash_cont_key
,
2009 struct tcaphash_context_t
*p_tcaphash_context
)
2011 struct tcaphash_contcall_t
*p_tcaphash_contcall1
= NULL
;
2012 struct tcaphash_contcall_t
*p_tcaphash_contcall
= NULL
;
2014 p_tcaphash_contcall1
= (struct tcaphash_contcall_t
*)
2015 wmem_map_lookup(tcaphash_cont
, p_tcaphash_cont_key
);
2017 if (p_tcaphash_contcall1
) {
2018 /* Walk through list of transaction with identical keys */
2019 /* go to the end to insert new record */
2021 if (!p_tcaphash_contcall1
->next_contcall
) {
2022 p_tcaphash_contcall
=append_tcaphash_contcall(p_tcaphash_contcall1
,
2023 p_tcaphash_context
);
2026 p_tcaphash_contcall1
= p_tcaphash_contcall1
->next_contcall
;
2027 } while (p_tcaphash_contcall1
!= NULL
);
2029 p_tcaphash_contcall
= new_tcaphash_cont(p_tcaphash_cont_key
,
2030 p_tcaphash_context
);
2032 return p_tcaphash_contcall
;
2036 static struct tcaphash_endcall_t
*
2037 create_tcaphash_end(struct tcaphash_end_info_key_t
*p_tcaphash_end_key
,
2038 struct tcaphash_context_t
*p_tcaphash_context
)
2040 struct tcaphash_endcall_t
*p_tcaphash_endcall1
= NULL
;
2041 struct tcaphash_endcall_t
*p_tcaphash_endcall
= NULL
;
2043 p_tcaphash_endcall1
= (struct tcaphash_endcall_t
*)
2044 wmem_map_lookup(tcaphash_end
, p_tcaphash_end_key
);
2046 if (p_tcaphash_endcall1
) {
2047 /* Walk through list of transaction with identical keys */
2048 /* go to the end to insert new record */
2050 if (!p_tcaphash_endcall1
->next_endcall
) {
2051 p_tcaphash_endcall
=append_tcaphash_endcall(p_tcaphash_endcall1
,
2052 p_tcaphash_context
);
2055 p_tcaphash_endcall1
= p_tcaphash_endcall1
->next_endcall
;
2056 } while (p_tcaphash_endcall1
!= NULL
);
2058 p_tcaphash_endcall
= new_tcaphash_end(p_tcaphash_end_key
,
2059 p_tcaphash_context
);
2061 return p_tcaphash_endcall
;
2065 * Create the record identifiying the TCAP transaction
2066 * When the identifier for the transaction is reused, check
2067 * the following criteria before to append a new record:
2068 * - a timeout corresponding to a message retransmission is detected,
2069 * - a message hast been lost
2070 * - or the previous transaction has been be closed
2072 static struct tcaphash_context_t
*
2073 tcaphash_begin_matching(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
,
2074 struct tcapsrt_info_t
*p_tcapsrt_info
)
2076 struct tcaphash_context_t
*p_tcaphash_context
=NULL
;
2077 struct tcaphash_context_key_t tcaphash_context_key
;
2078 struct tcaphash_begincall_t
*p_tcaphash_begincall
, *p_new_tcaphash_begincall
=NULL
;
2079 struct tcaphash_begin_info_key_t tcaphash_begin_key
;
2081 proto_item
*stat_item
=NULL
;
2082 proto_tree
*stat_tree
=NULL
;
2084 #ifdef DEBUG_TCAPSRT
2085 dbg(51,"src %s srcTid %lx dst %s ", address_to_str(pinfo
->pool
, &pinfo
->src
), p_tcapsrt_info
->src_tid
, address_to_str(pinfo
->pool
, &pinfo
->dst
));
2088 /* prepare the key data */
2089 tcaphash_begin_key
.tid
= p_tcapsrt_info
->src_tid
;
2090 if (pinfo
->src
.type
== ss7pc_address_type
&& pinfo
->dst
.type
== ss7pc_address_type
)
2092 /* We have MTP3 PCs (so we can safely do this cast) */
2093 tcaphash_begin_key
.pc_hash
= mtp3_pc_hash((const mtp3_addr_pc_t
*)pinfo
->src
.data
);
2095 /* Don't have MTP3 PCs (have SCCP GT ?) */
2096 tcaphash_begin_key
.pc_hash
= g_str_hash(address_to_str(pinfo
->pool
, &pinfo
->src
));
2098 tcaphash_begin_key
.hashKey
=tcaphash_begin_calchash(&tcaphash_begin_key
);
2100 /* look up the request */
2101 #ifdef DEBUG_TCAPSRT
2102 dbg(10,"\n Hbegin #%u ", pinfo
->num
);
2103 dbg(11,"key %lx ",tcaphash_begin_key
.hashKey
);
2104 dbg(51,"addr %s ", address_to_str(pinfo
->pool
, &pinfo
->src
));
2105 dbg(51,"Tid %lx \n",tcaphash_begin_key
.tid
);
2108 p_tcaphash_begincall
= (struct tcaphash_begincall_t
*)
2109 wmem_map_lookup(tcaphash_begin
, &tcaphash_begin_key
);
2111 if (p_tcaphash_begincall
) {
2112 /* Walk through list of transaction with identical keys */
2114 /* Check if the request with this reqSeqNum has been seen, with the same Message Type */
2115 if (pinfo
->num
== p_tcaphash_begincall
->context
->first_frame
) {
2116 /* We have seen this request before -> do nothing */
2117 #ifdef DEBUG_TCAPSRT
2118 dbg(22,"Already seen ");
2120 p_tcaphash_context
=p_tcaphash_begincall
->context
;
2123 /* If the last record for Tcap transaction with identifier has not been reached */
2124 if (!p_tcaphash_begincall
->next_begincall
) {
2125 /* check if we have to create a new record or not */
2126 /* if last request has been responded (response number is known)
2127 and this request appears after last response (has bigger frame number)
2128 and last request occurred after the timeout for repetition,
2130 if last request hasn't been responded (so number unknown)
2131 and this request appears after last request (has bigger frame number)
2132 and this request occurred after the timeout for message lost */
2133 if ( ( p_tcaphash_begincall
->context
->last_frame
!= 0
2134 && pinfo
->num
> p_tcaphash_begincall
->context
->first_frame
2135 && (unsigned) pinfo
->abs_ts
.secs
> (unsigned)(p_tcaphash_begincall
->context
->begin_time
.secs
+ gtcap_RepetitionTimeout
)
2137 ( p_tcaphash_begincall
->context
->last_frame
== 0
2138 && pinfo
->num
> p_tcaphash_begincall
->context
->first_frame
2139 && (unsigned)pinfo
->abs_ts
.secs
> (unsigned)(p_tcaphash_begincall
->context
->begin_time
.secs
+ gtcap_LostTimeout
)
2143 /* we decide that we have a new request */
2144 /* Append new record to the list */
2145 #ifdef DEBUG_TCAPSRT
2146 dbg(12,"(timeout) Append key %lx ",tcaphash_begin_key
.hashKey
);
2147 dbg(12,"Frame %u rsp %u ",pinfo
->num
,p_tcaphash_begincall
->context
->last_frame
);
2149 tcaphash_context_key
.session_id
= tcapsrt_global_SessionId
++;
2150 p_tcaphash_context
= new_tcaphash_context(&tcaphash_context_key
, pinfo
);
2152 p_new_tcaphash_begincall
= append_tcaphash_begincall(p_tcaphash_begincall
,
2155 #ifdef DEBUG_TCAPSRT
2156 dbg(12,"Update key %lx ",tcaphash_begin_key
.hashKey
);
2158 update_tcaphash_begincall(p_new_tcaphash_begincall
, pinfo
);
2159 } else { /* timeout or message lost */
2161 /* If the Tid is reused for a closed Transaction */
2162 /* Or if we received an TC_BEGIN for a Transaction marked as "closed" */
2163 /* (this is the case, for pre-arranged END, the transaction is marked as closed */
2164 /* by the upper layer, thank to a callback method close) */
2165 if ( p_tcaphash_begincall
->context
->closed
) {
2166 #ifdef DEBUG_TCAPSRT
2167 dbg(12,"(closed) Append key %lu ",tcaphash_begin_key
.hashKey
);
2168 dbg(12,"Frame %u rsp %u ",pinfo
->num
,p_tcaphash_begincall
->context
->last_frame
);
2170 tcaphash_context_key
.session_id
= tcapsrt_global_SessionId
++;
2171 p_tcaphash_context
= new_tcaphash_context(&tcaphash_context_key
, pinfo
);
2172 p_new_tcaphash_begincall
= append_tcaphash_begincall(p_tcaphash_begincall
,
2176 #ifdef DEBUG_TCAPSRT
2177 dbg(12,"Update key %lu ",tcaphash_begin_key
.hashKey
);
2179 update_tcaphash_begincall(p_new_tcaphash_begincall
, pinfo
);
2182 /* the TCAP session is not closed, so, either messages have been lost */
2183 /* or it's a duplicate request. Mark it as such. */
2184 #ifdef DEBUG_TCAPSRT
2185 dbg(21,"Display_duplicate %d ",p_tcaphash_begincall
->context
->first_frame
);
2187 p_tcaphash_context
=p_tcaphash_begincall
->context
;
2188 if (gtcap_DisplaySRT
&& tree
) {
2189 stat_tree
= proto_tree_add_subtree(tree
, tvb
, 0, -1, ett_tcap_stat
, &stat_item
, "Stat");
2190 proto_item_set_generated(stat_item
);
2191 pi
= proto_tree_add_uint_format(stat_tree
, hf_tcapsrt_Duplicate
, tvb
, 0, 0,
2192 p_tcaphash_context
->first_frame
,
2193 "Duplicate with session %u in frame %u",
2194 p_tcaphash_context
->session_id
,p_tcaphash_context
->first_frame
);
2195 proto_item_set_generated(pi
);
2197 return p_tcaphash_context
;
2198 } /* Previous session closed */
2199 } /* test with Timeout or message Lost */
2201 } /* Next call is NULL */
2202 /* Repeat the tests for the next record with the same transaction identifier */
2203 p_tcaphash_begincall
= p_tcaphash_begincall
->next_begincall
;
2204 } while (p_tcaphash_begincall
!= NULL
);
2206 * End of analyze for the list be TC_BEGIN with same transaction ID
2208 } else { /* p_tcaphash_begincall has not been found */
2210 * Create a new TCAP context
2212 #ifdef DEBUG_TCAPSRT
2213 dbg(10,"New key %lx ",tcaphash_begin_key
.hashKey
);
2216 tcaphash_context_key
.session_id
= tcapsrt_global_SessionId
++;
2217 p_tcaphash_context
= new_tcaphash_context(&tcaphash_context_key
, pinfo
);
2218 p_tcaphash_begincall
= new_tcaphash_begin(&tcaphash_begin_key
, p_tcaphash_context
);
2220 #ifdef DEBUG_TCAPSRT
2221 dbg(11,"Update key %lx ",tcaphash_begin_key
.hashKey
);
2222 dbg(11,"Frame reqlink #%u ", pinfo
->num
);
2224 update_tcaphash_begincall(p_tcaphash_begincall
, pinfo
);
2227 /* display tcap session, if available */
2228 if ( gtcap_DisplaySRT
&& tree
&&
2229 p_tcaphash_context
&&
2230 p_tcaphash_context
->session_id
) {
2231 stat_tree
= proto_tree_add_subtree(tree
, tvb
, 0, 0, ett_tcap_stat
, &stat_item
, "Stat");
2232 proto_item_set_generated(stat_item
);
2233 pi
= proto_tree_add_uint(stat_tree
, hf_tcapsrt_SessionId
, tvb
, 0,0, p_tcaphash_context
->session_id
);
2234 proto_item_set_generated(pi
);
2236 /* add link to response frame, if available */
2237 /* p_tcaphash_begincall->context->last_frame) */
2238 if( p_tcaphash_context
->last_frame
!= 0 ){
2239 #ifdef DEBUG_TCAPSRT
2240 dbg(20,"Display_frameRsplink %d ",p_tcaphash_context
->last_frame
);
2242 pi
= proto_tree_add_uint_format(stat_tree
, hf_tcapsrt_BeginSession
, tvb
, 0, 0,
2243 p_tcaphash_context
->last_frame
,
2244 "End of session in frame %u",
2245 p_tcaphash_context
->last_frame
);
2246 proto_item_set_generated(pi
);
2249 return p_tcaphash_context
;
2253 * Try to find a TCAP session according to the source and destination
2254 * Identifier given in the TC_CONT
2255 * If nothing is found, it is probably a session in opening state, so try to find
2256 * a tcap session registered with a TC_BEGIN "key", matching the destination Id of the TC_CONT
2257 * Then associate the TC_CONT "key" to the TCAP context, and create a TC_END "key"
2258 * and display the available info for the TCAP context
2260 static struct tcaphash_context_t
*
2261 tcaphash_cont_matching(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
,
2262 struct tcapsrt_info_t
*p_tcapsrt_info
)
2264 struct tcaphash_context_t
*p_tcaphash_context
=NULL
;
2265 struct tcaphash_contcall_t
*p_tcaphash_contcall
;
2266 struct tcaphash_cont_info_key_t tcaphash_cont_key
;
2267 struct tcaphash_begin_info_key_t tcaphash_begin_key
;
2268 struct tcaphash_begincall_t
*p_tcaphash_begincall
;
2269 struct tcaphash_end_info_key_t tcaphash_end_key
;
2271 proto_item
*stat_item
=NULL
;
2272 proto_tree
*stat_tree
=NULL
;
2273 bool use_dst
= false;
2275 #ifdef DEBUG_TCAPSRT
2276 dbg(51,"src %s srcTid %lx dst %s dstTid %lx ", address_to_str(pinfo
->pool
, &pinfo
->src
), p_tcapsrt_info
->src_tid
, address_to_str(pinfo
->pool
, &pinfo
->dst
), p_tcapsrt_info
->dst_tid
);
2277 dbg(10,"\n Hcont #%u ", pinfo
->num
);
2280 /* look only for matching request, if matching conversation is available. */
2281 tcaphash_cont_key
.src_tid
= p_tcapsrt_info
->src_tid
;
2282 tcaphash_cont_key
.dst_tid
= p_tcapsrt_info
->dst_tid
;
2283 if (pinfo
->src
.type
== ss7pc_address_type
&& pinfo
->dst
.type
== ss7pc_address_type
)
2285 /* We have MTP3 PCs (so we can safely do this cast) */
2286 tcaphash_cont_key
.opc_hash
= mtp3_pc_hash((const mtp3_addr_pc_t
*)pinfo
->src
.data
);
2287 tcaphash_cont_key
.dpc_hash
= mtp3_pc_hash((const mtp3_addr_pc_t
*)pinfo
->dst
.data
);
2289 /* Don't have MTP3 PCs (have SCCP GT ?) */
2290 tcaphash_cont_key
.opc_hash
= g_str_hash(address_to_str(pinfo
->pool
, &pinfo
->src
));
2291 tcaphash_cont_key
.dpc_hash
= g_str_hash(address_to_str(pinfo
->pool
, &pinfo
->dst
));
2293 tcaphash_cont_key
.hashKey
=tcaphash_cont_calchash(&tcaphash_cont_key
);
2295 #ifdef DEBUG_TCAPSRT
2296 dbg(11,"Ckey %lx ", tcaphash_cont_key
.hashKey
);
2297 dbg(51,"addr %s %s ", address_to_str(pinfo
->pool
, &pinfo
->src
), address_to_str(pinfo
->pool
, &pinfo
->dst
));
2298 dbg(51,"Tid %lx %lx \n",tcaphash_cont_key
.src_tid
, tcaphash_cont_key
.dst_tid
);
2300 p_tcaphash_contcall
= find_tcaphash_cont(&tcaphash_cont_key
, pinfo
);
2301 if(p_tcaphash_contcall
) {
2302 #ifdef DEBUG_TCAPSRT
2305 p_tcaphash_context
=p_tcaphash_contcall
->context
;
2306 } else { /* cont not found */
2307 #ifdef DEBUG_TCAPSRT
2308 dbg(12,"CnotFound ");
2310 /* Find the TCAP transaction according to the TC_BEGIN (from dtid,dst) */
2311 tcaphash_begin_key
.tid
= p_tcapsrt_info
->dst_tid
;
2312 if (pinfo
->src
.type
== ss7pc_address_type
&& pinfo
->dst
.type
== ss7pc_address_type
)
2314 /* We have MTP3 PCs (so we can safely do this cast) */
2315 tcaphash_begin_key
.pc_hash
= mtp3_pc_hash((const mtp3_addr_pc_t
*)pinfo
->dst
.data
);
2317 /* Don't have MTP3 PCs (have SCCP GT ?) */
2318 tcaphash_begin_key
.pc_hash
= g_str_hash(address_to_str(pinfo
->pool
, &pinfo
->dst
));
2320 tcaphash_begin_key
.hashKey
=tcaphash_begin_calchash(&tcaphash_begin_key
);
2322 #ifdef DEBUG_TCAPSRT
2323 dbg(11,"Bkey %lx ", tcaphash_begin_key
.hashKey
);
2324 dbg(51,"addr %s ", address_to_str(pinfo
->pool
, &pinfo
->dst
));
2325 dbg(51,"Tid %lx \n",tcaphash_begin_key
.tid
);
2327 p_tcaphash_begincall
= find_tcaphash_begin(&tcaphash_begin_key
, pinfo
, false);
2328 if(!p_tcaphash_begincall
){
2330 /* can this actually happen? */
2331 #ifdef DEBUG_TCAPSRT
2332 dbg(12,"BNotFound trying stid,src");
2334 /* Do we have a continue from the same source? (stid,src) */
2336 tcaphash_begin_key
.tid
= p_tcapsrt_info
->src_tid
;
2337 if (pinfo
->src
.type
== ss7pc_address_type
&& pinfo
->dst
.type
== ss7pc_address_type
)
2339 /* We have MTP3 PCs (so we can safely do this cast) */
2340 tcaphash_begin_key
.pc_hash
= mtp3_pc_hash((const mtp3_addr_pc_t
*)pinfo
->src
.data
);
2342 /* Don't have MTP3 PCs (have SCCP GT ?) */
2343 tcaphash_begin_key
.pc_hash
= g_str_hash(address_to_str(pinfo
->pool
, &pinfo
->src
));
2345 tcaphash_begin_key
.hashKey
=tcaphash_begin_calchash(&tcaphash_begin_key
);
2346 #ifdef DEBUG_TCAPSRT
2347 dbg(11,"Bkey %lx ", tcaphash_begin_key
.hashKey
);
2348 dbg(51,"addr %s ", address_to_str(pinfo
->pool
, &pinfo
->src
));
2349 dbg(51,"Tid %lx \n",tcaphash_begin_key
.tid
);
2351 p_tcaphash_begincall
= find_tcaphash_begin(&tcaphash_begin_key
, pinfo
,false);
2353 if(p_tcaphash_begincall
&&
2354 !p_tcaphash_begincall
->context
->contcall
) {
2355 #ifdef DEBUG_TCAPSRT
2356 dbg(12,"BFound \n");
2358 p_tcaphash_context
=p_tcaphash_begincall
->context
;
2359 p_tcaphash_context
->responded
=true;
2361 #ifdef DEBUG_TCAPSRT
2362 dbg(10,"New Ckey %lx ",tcaphash_cont_key
.hashKey
);
2363 dbg(11,"Frame reqlink #%u \n", pinfo
->num
);
2365 create_tcaphash_cont(&tcaphash_cont_key
,
2366 p_tcaphash_begincall
->context
);
2368 /* Create END for (stid,src) or (dtid,dst) */
2369 tcaphash_end_key
.tid
= use_dst
? p_tcapsrt_info
->dst_tid
: p_tcapsrt_info
->src_tid
;
2370 if (pinfo
->src
.type
== ss7pc_address_type
&& pinfo
->dst
.type
== ss7pc_address_type
)
2372 /* We have MTP3 PCs (so we can safely do this cast) */
2373 tcaphash_end_key
.dpc_hash
= mtp3_pc_hash((const mtp3_addr_pc_t
*)(use_dst
? pinfo
->dst
.data
: pinfo
->src
.data
));
2374 tcaphash_end_key
.opc_hash
= mtp3_pc_hash((const mtp3_addr_pc_t
*)(use_dst
? pinfo
->src
.data
: pinfo
->dst
.data
));
2376 /* Don't have MTP3 PCs (have SCCP GT ?) */
2377 tcaphash_end_key
.dpc_hash
= g_str_hash(address_to_str(pinfo
->pool
, use_dst
? &pinfo
->dst
: &pinfo
->src
));
2378 tcaphash_end_key
.opc_hash
= g_str_hash(address_to_str(pinfo
->pool
, use_dst
? &pinfo
->src
: &pinfo
->dst
));
2380 tcaphash_end_key
.hashKey
=tcaphash_end_calchash(&tcaphash_end_key
);
2382 #ifdef DEBUG_TCAPSRT
2383 dbg(10,"New Ekey %lx ",tcaphash_end_key
.hashKey
);
2384 dbg(51,"addr %s ", address_to_str(pinfo
->pool
, use_dst
? &pinfo
->dst
: &pinfo
->src
));
2385 dbg(51,"Tid %lx ",tcaphash_end_key
.tid
);
2386 dbg(11,"Frame reqlink #%u ", pinfo
->num
);
2388 create_tcaphash_end(&tcaphash_end_key
,
2389 p_tcaphash_begincall
->context
);
2391 } else { /* Begin not found */
2392 #ifdef DEBUG_TCAPSRT
2393 dbg(12,"BnotFound ");
2396 /* make another try with src tid / address */
2401 /* display tcap session, if available */
2402 if (gtcap_DisplaySRT
&& tree
&&
2403 p_tcaphash_context
&&
2404 p_tcaphash_context
->session_id
) {
2405 stat_tree
= proto_tree_add_subtree(tree
, tvb
, 0, -1, ett_tcap_stat
, &stat_item
, "Stat");
2406 proto_item_set_generated(stat_item
);
2407 pi
= proto_tree_add_uint(stat_tree
, hf_tcapsrt_SessionId
, tvb
, 0,0, p_tcaphash_context
->session_id
);
2408 proto_item_set_generated(pi
);
2411 return p_tcaphash_context
;
2415 * Try to find a TCAP session according to the destination Identifier given in the TC_END/TC_ABORT
2416 * If nothing is found,
2417 * - either it is a session in opening state,
2418 * - or the session is closed/aborted by the remote, ( so we switch the src and dst tid )
2419 * so try to find a tcap session registered with a TC_BEGIN "key",
2420 * matching the destination Id of the TC_END
2421 * Then associate the TC_CONT "key" to the TCAP context
2422 * and display the available info for the TCAP context
2425 static struct tcaphash_context_t
*
2426 tcaphash_end_matching(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
,
2427 struct tcapsrt_info_t
*p_tcapsrt_info
)
2429 struct tcaphash_context_t
*p_tcaphash_context
=NULL
;
2431 struct tcaphash_end_info_key_t tcaphash_end_key
;
2432 struct tcaphash_endcall_t
*p_tcaphash_endcall
=NULL
;
2434 struct tcaphash_begin_info_key_t tcaphash_begin_key
;
2435 struct tcaphash_begincall_t
*p_tcaphash_begincall
=NULL
;
2438 proto_item
*stat_item
=NULL
;
2439 proto_tree
*stat_tree
=NULL
;
2441 #ifdef DEBUG_TCAPSRT
2442 dbg(51,"src %s dst %s dstTid %lx ", address_to_str(pinfo
->pool
, &pinfo
->src
), address_to_str(pinfo
->pool
, &pinfo
->dst
), p_tcapsrt_info
->dst_tid
);
2443 dbg(10,"\n Hend #%u ", pinfo
->num
);
2445 /* look only for matching request, if matching conversation is available. */
2446 tcaphash_end_key
.tid
= p_tcapsrt_info
->dst_tid
;
2447 if (pinfo
->src
.type
== ss7pc_address_type
&& pinfo
->dst
.type
== ss7pc_address_type
)
2449 /* We have MTP3 PCs (so we can safely do this cast) */
2450 tcaphash_end_key
.opc_hash
= mtp3_pc_hash((const mtp3_addr_pc_t
*)pinfo
->src
.data
);
2451 tcaphash_end_key
.dpc_hash
= mtp3_pc_hash((const mtp3_addr_pc_t
*)pinfo
->dst
.data
);
2453 /* Don't have MTP3 PCs (have SCCP GT ?) */
2454 tcaphash_end_key
.opc_hash
= g_str_hash(address_to_str(pinfo
->pool
, &pinfo
->src
));
2455 tcaphash_end_key
.dpc_hash
= g_str_hash(address_to_str(pinfo
->pool
, &pinfo
->dst
));
2457 tcaphash_end_key
.hashKey
=tcaphash_end_calchash(&tcaphash_end_key
);
2459 #ifdef DEBUG_TCAPSRT
2460 dbg(11,"Ekey %lx ",tcaphash_end_key
.hashKey
);
2461 dbg(11,"addr %s ", address_to_str(pinfo
->pool
, &pinfo
->dst
));
2462 dbg(51,"Tid %lx ",tcaphash_end_key
.tid
);
2464 p_tcaphash_endcall
= find_tcaphash_end(&tcaphash_end_key
, pinfo
,true);
2466 if(!p_tcaphash_endcall
) {
2467 #ifdef DEBUG_TCAPSRT
2468 dbg(12,"EnotFound ");
2470 tcaphash_begin_key
.tid
= p_tcapsrt_info
->dst_tid
;
2471 if (pinfo
->src
.type
== ss7pc_address_type
&& pinfo
->dst
.type
== ss7pc_address_type
)
2473 /* We have MTP3 PCs (so we can safely do this cast) */
2474 tcaphash_begin_key
.pc_hash
= mtp3_pc_hash((const mtp3_addr_pc_t
*)pinfo
->dst
.data
);
2476 /* Don't have MTP3 PCs (have SCCP GT ?) */
2477 tcaphash_begin_key
.pc_hash
= g_str_hash(address_to_str(pinfo
->pool
, &pinfo
->dst
));
2479 tcaphash_begin_key
.hashKey
=tcaphash_begin_calchash(&tcaphash_begin_key
);
2481 #ifdef DEBUG_TCAPSRT
2482 dbg(11,"Bkey %lx ", tcaphash_begin_key
.hashKey
);
2483 dbg(51,"addr %s ", address_to_str(pinfo
->pool
, &pinfo
->dst
));
2484 dbg(51,"Tid %lx ",tcaphash_begin_key
.tid
);
2486 p_tcaphash_begincall
= find_tcaphash_begin(&tcaphash_begin_key
, pinfo
,false);
2487 if(!p_tcaphash_begincall
) {
2488 #ifdef DEBUG_TCAPSRT
2489 dbg(12,"BnotFound ");
2493 if (p_tcaphash_endcall
) {
2494 /* Use the TC_BEGIN Destination reference */
2495 p_tcaphash_context
=p_tcaphash_endcall
->context
;
2496 } else if (p_tcaphash_begincall
) {
2497 /* Use the TC_BEGIN Source reference */
2498 p_tcaphash_context
=p_tcaphash_begincall
->context
;
2501 if (p_tcaphash_context
) {
2503 #ifdef DEBUG_TCAPSRT
2504 dbg(12,"Found, req=%d ",p_tcaphash_context
->first_frame
);
2506 if (gtcap_DisplaySRT
&& tree
) {
2507 stat_tree
= proto_tree_add_subtree(tree
, tvb
, 0, -1, ett_tcap_stat
, &stat_item
, "Stat");
2508 proto_item_set_generated(stat_item
);
2510 pi
= proto_tree_add_uint(stat_tree
, hf_tcapsrt_SessionId
, tvb
, 0,0, p_tcaphash_context
->session_id
);
2511 proto_item_set_generated(pi
);
2514 #ifdef DEBUG_TCAPSRT
2515 dbg(20,"Display framereqlink %d ",p_tcaphash_context
->first_frame
);
2517 /* Indicate the frame to which this is a reply. */
2518 if (gtcap_DisplaySRT
&& stat_tree
) {
2519 pi
= proto_tree_add_uint_format(stat_tree
, hf_tcapsrt_EndSession
, tvb
, 0, 0,
2520 p_tcaphash_context
->first_frame
,
2521 "Begin of session in frame %u",
2522 p_tcaphash_context
->first_frame
);
2523 proto_item_set_generated(pi
);
2524 /* Calculate Service Response Time */
2525 nstime_delta(&delta
, &pinfo
->abs_ts
, &p_tcaphash_context
->begin_time
);
2527 /* display Service Response Time and make it filterable */
2528 pi
= proto_tree_add_time(stat_tree
, hf_tcapsrt_SessionTime
, tvb
, 0, 0, &delta
);
2529 proto_item_set_generated(pi
);
2531 /* Close the context and remove it (if needed) */
2532 tcapsrt_close(p_tcaphash_context
,pinfo
);
2534 } else {/* context present */
2535 #ifdef DEBUG_TCAPSRT
2536 dbg(12,"Context notFound ");
2539 return p_tcaphash_context
;
2544 * Create the record identifiying the TCAP transaction
2545 * When the identifier for the transaction is reused, check
2546 * the following criteria before to append a new record:
2547 * - a timeout corresponding to a message retransmission is detected,
2548 * - a message hast been lost
2549 * - or the previous transaction has been be closed
2551 static struct tcaphash_context_t
*
2552 tcaphash_ansi_matching(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
,
2553 struct tcapsrt_info_t
*p_tcapsrt_info
)
2555 struct tcaphash_context_t
*p_tcaphash_context
=NULL
;
2556 struct tcaphash_context_key_t tcaphash_context_key
;
2557 struct tcaphash_ansicall_t
*p_tcaphash_ansicall
, *p_new_tcaphash_ansicall
;
2558 struct tcaphash_ansi_info_key_t tcaphash_ansi_key
;
2561 bool isResponse
=false;
2562 proto_tree
* stat_tree
=NULL
;
2563 proto_item
* stat_item
=NULL
;
2565 /* prepare the key data */
2566 tcaphash_ansi_key
.tid
= p_tcapsrt_info
->src_tid
;
2567 if (pinfo
->src
.type
== ss7pc_address_type
&& pinfo
->dst
.type
== ss7pc_address_type
)
2569 /* We have MTP3 PCs (so we can safely do this cast) */
2570 tcaphash_ansi_key
.opc_hash
= mtp3_pc_hash((const mtp3_addr_pc_t
*)pinfo
->src
.data
);
2571 tcaphash_ansi_key
.dpc_hash
= mtp3_pc_hash((const mtp3_addr_pc_t
*)pinfo
->dst
.data
);
2573 /* Don't have MTP3 PCs (have SCCP GT ?) */
2574 tcaphash_ansi_key
.opc_hash
= g_str_hash(address_to_str(pinfo
->pool
, &pinfo
->src
));
2575 tcaphash_ansi_key
.dpc_hash
= g_str_hash(address_to_str(pinfo
->pool
, &pinfo
->dst
));
2577 tcaphash_ansi_key
.hashKey
=tcaphash_ansi_calchash(&tcaphash_ansi_key
);
2579 /* look up the request */
2580 #ifdef DEBUG_TCAPSRT
2581 dbg(10,"\n Hansi #%u ", pinfo
->num
);
2582 dbg(11,"key %lx ",tcaphash_ansi_key
.hashKey
);
2583 dbg(51,"PC %s %s ",address_to_str(pinfo
->pool
, &pinfo
->src
), address_to_str(pinfo
->pool
, &pinfo
->dst
));
2584 dbg(51,"Tid %lx ",tcaphash_ansi_key
.tid
);
2586 p_tcaphash_ansicall
= (struct tcaphash_ansicall_t
*)
2587 wmem_map_lookup(tcaphash_ansi
, &tcaphash_ansi_key
);
2589 if (p_tcaphash_ansicall
) {
2590 /* Walk through list of transaction with identical keys */
2592 /* Check if the request with this reqSeqNum has been seen */
2593 if (pinfo
->num
== p_tcaphash_ansicall
->context
->first_frame
) {
2594 /* We have seen this request before -> do nothing */
2595 #ifdef DEBUG_TCAPSRT
2596 dbg(22,"Request already seen ");
2599 p_tcaphash_context
=p_tcaphash_ansicall
->context
;
2603 /* Check if the response with this reqSeqNum has been seen */
2604 if (pinfo
->num
== p_tcaphash_ansicall
->context
->last_frame
) {
2605 /* We have seen this response before -> do nothing */
2606 #ifdef DEBUG_TCAPSRT
2607 dbg(22,"Response already seen ");
2610 p_tcaphash_context
=p_tcaphash_ansicall
->context
;
2614 /* Check for the first Request without Response
2615 received before this frame */
2616 if ( pinfo
->num
> p_tcaphash_ansicall
->context
->first_frame
&&
2617 p_tcaphash_ansicall
->context
->last_frame
==0 ) {
2618 /* Take it, and update the context */
2620 #ifdef DEBUG_TCAPSRT
2621 dbg(12,"Update key %lx ",tcaphash_ansi_key
.hashKey
);
2623 p_tcaphash_ansicall
->context
->last_frame
= pinfo
->num
;
2624 p_tcaphash_ansicall
->context
->responded
= true;
2625 p_tcaphash_ansicall
->context
->closed
= true;
2626 p_tcaphash_context
=p_tcaphash_ansicall
->context
;
2629 if (gtcap_DisplaySRT
&& tree
) {
2630 stat_tree
= proto_tree_add_subtree(tree
, tvb
, 0, -1, ett_tcap_stat
, &stat_item
, "Stat");
2631 proto_item_set_generated(stat_item
);
2633 pi
= proto_tree_add_uint(stat_tree
, hf_tcapsrt_SessionId
, tvb
, 0,0, p_tcaphash_context
->session_id
);
2634 proto_item_set_generated(pi
);
2636 #ifdef DEBUG_TCAPSRT
2637 dbg(20,"Display framereqlink %d ",p_tcaphash_context
->first_frame
);
2639 /* Indicate the frame to which this is a reply. */
2640 pi
= proto_tree_add_uint_format(stat_tree
, hf_tcapsrt_EndSession
, tvb
, 0, 0,
2641 p_tcaphash_context
->first_frame
,
2642 "Begin of session in frame %u",
2643 p_tcaphash_context
->first_frame
);
2644 proto_item_set_generated(pi
);
2645 /* Calculate Service Response Time */
2646 nstime_delta(&delta
, &pinfo
->abs_ts
, &p_tcaphash_context
->begin_time
);
2648 /* display Service Response Time and make it filterable */
2649 pi
= proto_tree_add_time(stat_tree
, hf_tcapsrt_SessionTime
, tvb
, 0, 0, &delta
);
2650 proto_item_set_generated(pi
);
2653 } /* Lastframe=0, so take it */
2656 /* If the last record for Tcap transaction with identifier has been reached */
2657 if (!p_tcaphash_ansicall
->next_ansicall
) {
2658 /* check if we have to create a new record or not */
2659 /* if last request has been responded (response number in known)
2660 and this request appears after last response (has bigger frame number)
2661 and last request occurred after the timeout for repetition,
2663 if last request hasn't been responded (so number unknown)
2664 and this request appears after last request (has bigger frame number)
2665 and this request occurred after the timeout for message lost */
2666 if ( ( p_tcaphash_ansicall
->context
->last_frame
!= 0
2667 && pinfo
->num
> p_tcaphash_ansicall
->context
->first_frame
2668 && (unsigned) pinfo
->abs_ts
.secs
> (unsigned)(p_tcaphash_ansicall
->context
->begin_time
.secs
+ gtcap_RepetitionTimeout
)
2670 ( p_tcaphash_ansicall
->context
->last_frame
== 0
2671 && pinfo
->num
> p_tcaphash_ansicall
->context
->first_frame
2672 && (unsigned)pinfo
->abs_ts
.secs
> (unsigned)(p_tcaphash_ansicall
->context
->begin_time
.secs
+ gtcap_LostTimeout
)
2676 /* we decide that we have a new request */
2677 /* Append new record to the list */
2678 #ifdef DEBUG_TCAPSRT
2679 dbg(12,"(timeout) Append key %lx ",tcaphash_ansi_key
.hashKey
);
2680 dbg(12,"Frame %u rsp %u ",pinfo
->num
,p_tcaphash_ansicall
->context
->last_frame
);
2682 tcaphash_context_key
.session_id
= tcapsrt_global_SessionId
++;
2683 p_tcaphash_context
= new_tcaphash_context(&tcaphash_context_key
, pinfo
);
2684 p_new_tcaphash_ansicall
= append_tcaphash_ansicall(p_tcaphash_ansicall
,
2688 #ifdef DEBUG_TCAPSRT
2689 dbg(12,"Update key %lx ",tcaphash_ansi_key
.hashKey
);
2691 update_tcaphash_ansicall(p_new_tcaphash_ansicall
, pinfo
);
2692 p_tcaphash_ansicall
=p_new_tcaphash_ansicall
;
2695 /* If the Tid is reused for a closed Transaction */
2696 if ( p_tcaphash_ansicall
->context
->closed
) {
2697 #ifdef DEBUG_TCAPSRT
2698 dbg(12,"(closed) Append key %lu ",tcaphash_ansi_key
.hashKey
);
2699 dbg(12,"Frame %u rsp %u ",pinfo
->num
,p_tcaphash_ansicall
->context
->last_frame
);
2701 tcaphash_context_key
.session_id
= tcapsrt_global_SessionId
++;
2702 p_tcaphash_context
= new_tcaphash_context(&tcaphash_context_key
, pinfo
);
2703 p_new_tcaphash_ansicall
= append_tcaphash_ansicall(p_tcaphash_ansicall
,
2707 #ifdef DEBUG_TCAPSRT
2708 dbg(12,"Update key %lu ",tcaphash_ansi_key
.hashKey
);
2710 update_tcaphash_ansicall(p_new_tcaphash_ansicall
, pinfo
);
2711 p_tcaphash_ansicall
=p_new_tcaphash_ansicall
;
2714 /* the Tid is reused for an opened Transaction */
2715 /* so, this is the reply to the request of our context */
2716 p_tcaphash_context
=p_tcaphash_ansicall
->context
;
2717 #ifdef DEBUG_TCAPSRT
2718 dbg(12,"Found, req=%d ",p_tcaphash_context
->first_frame
);
2721 if (gtcap_DisplaySRT
&& tree
) {
2722 stat_tree
= proto_tree_add_subtree(tree
, tvb
, 0, -1, ett_tcap_stat
, &stat_item
, "Stat");
2723 proto_item_set_generated(stat_item
);
2725 pi
= proto_tree_add_uint(stat_tree
, hf_tcapsrt_SessionId
, tvb
, 0,0, p_tcaphash_context
->session_id
);
2726 proto_item_set_generated(pi
);
2728 #ifdef DEBUG_TCAPSRT
2729 dbg(20,"Display framereqlink %d ",p_tcaphash_context
->first_frame
);
2731 /* Indicate the frame to which this is a reply. */
2732 pi
= proto_tree_add_uint_format(stat_tree
, hf_tcapsrt_EndSession
, tvb
, 0, 0,
2733 p_tcaphash_context
->first_frame
,
2734 "Begin of session in frame %u",
2735 p_tcaphash_context
->first_frame
);
2736 proto_item_set_generated(pi
);
2737 /* Calculate Service Response Time */
2738 nstime_delta(&delta
, &pinfo
->abs_ts
, &p_tcaphash_context
->begin_time
);
2740 /* display Service Response Time and make it filterable */
2741 pi
= proto_tree_add_time(stat_tree
, hf_tcapsrt_SessionTime
, tvb
, 0, 0, &delta
);
2742 proto_item_set_generated(pi
);
2744 p_tcaphash_context
=p_tcaphash_ansicall
->context
;
2745 } /* test with Timeout */
2748 } /* Next call is NULL */
2749 p_tcaphash_ansicall
= p_tcaphash_ansicall
->next_ansicall
;
2750 } while (p_tcaphash_ansicall
!= NULL
);
2754 } else { /* p_tcaphash_ansicall has not been found */
2755 #ifdef DEBUG_TCAPSRT
2756 dbg(10,"New key %lx ",tcaphash_ansi_key
.hashKey
);
2759 tcaphash_context_key
.session_id
= tcapsrt_global_SessionId
++;
2760 p_tcaphash_context
= new_tcaphash_context(&tcaphash_context_key
, pinfo
);
2761 p_tcaphash_ansicall
= new_tcaphash_ansi(&tcaphash_ansi_key
, p_tcaphash_context
);
2763 #ifdef DEBUG_TCAPSRT
2764 dbg(11,"Update key %lx ",tcaphash_ansi_key
.hashKey
);
2765 dbg(11,"Frame reqlink #%u ", pinfo
->num
);
2767 update_tcaphash_ansicall(p_tcaphash_ansicall
, pinfo
);
2770 /* display tcap session, if available */
2771 if ( gtcap_DisplaySRT
&& tree
&&
2772 p_tcaphash_context
&&
2773 p_tcaphash_context
->session_id
) {
2774 stat_tree
= proto_tree_add_subtree(tree
, tvb
, 0, -1, ett_tcap_stat
, &stat_item
, "Stat");
2775 proto_item_set_generated(stat_item
);
2776 pi
= proto_tree_add_uint(stat_tree
, hf_tcapsrt_SessionId
, tvb
, 0,0, p_tcaphash_context
->session_id
);
2777 proto_item_set_generated(pi
);
2781 /* add link to response frame, if available */
2782 if( gtcap_DisplaySRT
&& stat_tree
&&
2783 p_tcaphash_ansicall
->context
->last_frame
!= 0){
2784 if (!isResponse
) { /* Request */
2785 #ifdef DEBUG_TCAPSRT
2786 dbg(20,"Display_frameRsplink %d ",p_tcaphash_ansicall
->context
->last_frame
);
2788 pi
= proto_tree_add_uint_format(stat_tree
, hf_tcapsrt_BeginSession
, tvb
, 0, 0,
2789 p_tcaphash_ansicall
->context
->last_frame
,
2790 "End of session in frame %u",
2791 p_tcaphash_ansicall
->context
->last_frame
);
2792 proto_item_set_generated(pi
);
2793 } else { /* Response */
2794 #ifdef DEBUG_TCAPSRT
2795 dbg(20,"Display framereqlink %d ",p_tcaphash_context
->first_frame
);
2797 /* Indicate the frame to which this is a reply. */
2798 if (gtcap_DisplaySRT
) {
2799 pi
= proto_tree_add_uint_format(stat_tree
, hf_tcapsrt_EndSession
, tvb
, 0, 0,
2800 p_tcaphash_context
->first_frame
,
2801 "Begin of session in frame %u",
2802 p_tcaphash_context
->first_frame
);
2803 proto_item_set_generated(pi
);
2804 /* Calculate Service Response Time */
2805 nstime_delta(&delta
, &pinfo
->abs_ts
, &p_tcaphash_context
->begin_time
);
2807 /* display Service Response Time and make it filterable */
2808 pi
= proto_tree_add_time(stat_tree
, hf_tcapsrt_SessionTime
, tvb
, 0, 0, &delta
);
2809 proto_item_set_generated(pi
);
2811 } /* Request or Response */
2813 return p_tcaphash_context
;
2817 * Service Response Time analyze
2818 * Called just after dissector call
2819 * Associate a TCAP context to a tcap session and display session related infomations
2820 * like the first frame, the last, the session duration,
2821 * and a uniq session identifier for the filtering
2823 * For ETSI tcap, the TCAP context can be reached through three keys
2824 * - a key (BEGIN) identifying the session according to the tcap source identifier
2825 * - a key (CONT) identifying the established session (src_id and dst_id)
2826 * - a key (END) identifying the session according to the tcap destination identifier
2828 * For ANSI tcap, the TCAP context is reached through a uniq key
2829 * - a key (ANSI) identifying the session according to the tcap identifier
2831 struct tcaphash_context_t
*
2832 tcapsrt_call_matching(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
,
2833 struct tcapsrt_info_t
*p_tcapsrt_info
)
2835 struct tcaphash_context_t
*tcap_context
=NULL
;
2837 /* if this packet isn't loaded because of a read filter, don't output anything */
2838 if(pinfo
== NULL
|| pinfo
->num
== 0) {
2842 switch (p_tcapsrt_info
->ope
) {
2845 #ifdef DEBUG_TCAPSRT
2846 dbg(1,"\nTC_BEGIN ");
2848 tcap_context
=tcaphash_begin_matching(tvb
, pinfo
, tree
, p_tcapsrt_info
);
2852 #ifdef DEBUG_TCAPSRT
2853 dbg(1,"\nTC_CONT ");
2855 tcap_context
=tcaphash_cont_matching(tvb
, pinfo
, tree
, p_tcapsrt_info
);
2859 #ifdef DEBUG_TCAPSRT
2860 dbg(1,"\nTC_ABORT ");
2862 tcap_context
=tcaphash_end_matching(tvb
, pinfo
, tree
, p_tcapsrt_info
);
2866 #ifdef DEBUG_TCAPSRT
2869 tcap_context
=tcaphash_end_matching(tvb
, pinfo
, tree
, p_tcapsrt_info
);
2874 #ifdef DEBUG_TCAPSRT
2875 dbg(1,"\nTC_ANSI ");
2877 tcap_context
=tcaphash_ansi_matching(tvb
, pinfo
, tree
, p_tcapsrt_info
);
2881 #ifdef DEBUG_TCAPSRT
2882 dbg(1,"\nUnknown %d ", p_tcapsrt_info
->ope
);
2885 } /* switch tcapop */
2886 #ifdef DEBUG_TCAPSRT
2888 dbg(1,"session %d ", tcap_context
->session_id
);
2890 return tcap_context
;
2894 * Initialize the Message Info used by the main dissector
2895 * Data are linked to a TCAP transaction
2897 struct tcapsrt_info_t
*
2898 tcapsrt_razinfo(void)
2900 struct tcapsrt_info_t
*p_tcapsrt_info
;
2902 /* Global buffer for packet extraction */
2903 tcapsrt_global_current
++;
2904 if(tcapsrt_global_current
==MAX_TCAP_INSTANCE
){
2905 tcapsrt_global_current
=0;
2908 p_tcapsrt_info
=&tcapsrt_global_info
[tcapsrt_global_current
];
2909 memset(p_tcapsrt_info
,0,sizeof(struct tcapsrt_info_t
));
2911 return p_tcapsrt_info
;
2915 tcapsrt_close(struct tcaphash_context_t
*p_tcaphash_context
,
2918 #ifdef DEBUG_TCAPSRT
2919 dbg(60,"Force close ");
2921 if (p_tcaphash_context
) {
2922 p_tcaphash_context
->responded
=true;
2923 p_tcaphash_context
->last_frame
= pinfo
->num
;
2924 p_tcaphash_context
->end_time
= pinfo
->abs_ts
;
2925 p_tcaphash_context
->closed
=true;
2927 /* If the endkey is present */
2928 if (p_tcaphash_context
->endcall
2929 && !gtcap_PersistentSRT
) {
2930 if (p_tcaphash_context
->endcall
->next_endcall
) {
2931 if (p_tcaphash_context
->endcall
->previous_endcall
) {
2932 #ifdef DEBUG_TCAPSRT
2933 dbg(20,"deplace Ehash ");
2935 p_tcaphash_context
->endcall
->previous_endcall
->next_endcall
2936 = p_tcaphash_context
->endcall
->next_endcall
;
2937 p_tcaphash_context
->endcall
->next_endcall
->previous_endcall
2938 = p_tcaphash_context
->endcall
->previous_endcall
;
2939 wmem_map_remove(tcaphash_end
, p_tcaphash_context
->endcall
->endkey
);
2941 /* cannot remove the father */
2942 #ifdef DEBUG_TCAPSRT
2943 dbg(20,"father Ehash ");
2945 } /* no previous link, so father */
2946 } else if (!gtcap_PersistentSRT
) {
2947 #ifdef DEBUG_TCAPSRT
2948 dbg(20,"remove Ehash ");
2950 wmem_map_remove(tcaphash_end
, p_tcaphash_context
->endcall
->endkey
);
2952 } /* endcall without chained string */
2956 /* If the contkey is present */
2957 if (p_tcaphash_context
->contcall
2958 && !gtcap_PersistentSRT
) {
2959 if (p_tcaphash_context
->contcall
->next_contcall
) {
2960 if (p_tcaphash_context
->contcall
->previous_contcall
) {
2961 #ifdef DEBUG_TCAPSRT
2962 dbg(20,"deplace Chash ");
2964 p_tcaphash_context
->contcall
->previous_contcall
->next_contcall
2965 = p_tcaphash_context
->contcall
->next_contcall
;
2966 p_tcaphash_context
->contcall
->next_contcall
->previous_contcall
2967 = p_tcaphash_context
->contcall
->previous_contcall
;
2968 wmem_map_remove(tcaphash_cont
, p_tcaphash_context
->contcall
->contkey
);
2970 /* cannot remove the father */
2971 #ifdef DEBUG_TCAPSRT
2972 dbg(20,"father Chash ");
2974 } /* no previous link, so father */
2975 } else if (!gtcap_PersistentSRT
) {
2976 #ifdef DEBUG_TCAPSRT
2977 dbg(20,"remove Chash ");
2979 wmem_map_remove(tcaphash_cont
, p_tcaphash_context
->contcall
->contkey
);
2980 } /* contcall without chained string */
2984 /* If the beginkey is present */
2985 if (p_tcaphash_context
->begincall
2986 && !gtcap_PersistentSRT
) {
2987 if (p_tcaphash_context
->begincall
->next_begincall
) {
2988 if (p_tcaphash_context
->begincall
->previous_begincall
) {
2989 #ifdef DEBUG_TCAPSRT
2990 dbg(20,"deplace Bhash ");
2992 p_tcaphash_context
->begincall
->previous_begincall
->next_begincall
2993 = p_tcaphash_context
->begincall
->next_begincall
;
2994 p_tcaphash_context
->begincall
->next_begincall
->previous_begincall
2995 = p_tcaphash_context
->begincall
->previous_begincall
;
2996 wmem_map_remove(tcaphash_begin
, p_tcaphash_context
->begincall
->beginkey
);
2998 /* cannot remove the father */
2999 #ifdef DEBUG_TCAPSRT
3000 dbg(20,"father Bhash ");
3003 } else if (!gtcap_PersistentSRT
) {
3004 #ifdef DEBUG_TCAPSRT
3005 dbg(20,"remove Bhash ");
3007 wmem_map_remove(tcaphash_begin
, p_tcaphash_context
->begincall
->beginkey
);
3008 } /* begincall without chained string */
3009 } /* no begincall */
3011 /* If the ansikey is present */
3012 if (p_tcaphash_context
->ansicall
3013 && !gtcap_PersistentSRT
) {
3014 if (p_tcaphash_context
->ansicall
->next_ansicall
) {
3015 if (p_tcaphash_context
->ansicall
->previous_ansicall
) {
3016 #ifdef DEBUG_TCAPSRT
3017 dbg(20,"deplace Ahash ");
3019 p_tcaphash_context
->ansicall
->previous_ansicall
->next_ansicall
3020 = p_tcaphash_context
->ansicall
->next_ansicall
;
3021 p_tcaphash_context
->ansicall
->next_ansicall
->previous_ansicall
3022 = p_tcaphash_context
->ansicall
->previous_ansicall
;
3023 wmem_map_remove(tcaphash_ansi
, p_tcaphash_context
->ansicall
->ansikey
);
3025 /* cannot remove the father */
3026 #ifdef DEBUG_TCAPSRT
3027 dbg(20,"father Ahash ");
3030 } else if (!gtcap_PersistentSRT
) {
3031 #ifdef DEBUG_TCAPSRT
3032 dbg(20,"remove Ahash ");
3034 wmem_map_remove(tcaphash_ansi
, p_tcaphash_context
->ansicall
->ansikey
);
3035 } /* ansicall without chained string */
3038 if (!gtcap_PersistentSRT
) {
3039 #ifdef DEBUG_TCAPSRT
3040 dbg(20,"remove context ");
3042 wmem_map_remove(tcaphash_context
, p_tcaphash_context
->key
);
3044 } else { /* no context */
3045 #ifdef DEBUG_TCAPSRT
3046 dbg(20,"No context to remove ");
3051 const value_string tcap_component_type_str
[] = {
3052 { TCAP_COMP_INVOKE
, "Invoke" },
3053 { TCAP_COMP_RRL
, "Return Result(L)" },
3054 { TCAP_COMP_RE
, "Return Error" },
3055 { TCAP_COMP_REJECT
, "Reject" },
3056 { TCAP_COMP_RRN
, "Return Result(NL)" },
3061 dissect_tcap(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*parent_tree
, void* data _U_
)
3063 proto_item
*item
=NULL
;
3064 proto_tree
*tree
=NULL
;
3066 struct tcaphash_context_t
* p_tcap_context
;
3067 dissector_handle_t subdissector_handle
;
3068 asn1_ctx_t asn1_ctx
;
3072 struct tcap_private_t
*p_tcap_private
;
3074 /* Check if ANSI TCAP and call the ANSI TCAP dissector if that's the case
3075 * PackageType ::= CHOICE { unidirectional [PRIVATE 1] IMPLICIT UniTransactionPDU,
3076 * queryWithPerm [PRIVATE 2] IMPLICIT TransactionPDU,
3077 * queryWithoutPerm [PRIVATE 3] IMPLICIT TransactionPDU,
3078 * response [PRIVATE 4] IMPLICIT TransactionPDU,
3079 * conversationWithPerm [PRIVATE 5] IMPLICIT TransactionPDU,
3080 * conversationWithoutPerm [PRIVATE 6] IMPLICIT TransactionPDU,
3081 * abort [PRIVATE 22] IMPLICIT Abort
3086 get_ber_identifier(tvb
, 0, &ber_class
, &pc
, &tag
);
3088 if(ber_class
== BER_CLASS_PRI
){
3098 return call_dissector(ansi_tcap_handle
, tvb
, pinfo
, parent_tree
);
3101 return tvb_captured_length(tvb
);
3106 asn1_ctx_init(&asn1_ctx
, ASN1_ENC_BER
, true, pinfo
);
3108 tcap_top_tree
= parent_tree
;
3109 tcap_stat_tree
= NULL
;
3111 col_set_str(pinfo
->cinfo
, COL_PROTOCOL
, "TCAP");
3113 /* create display subtree for the protocol */
3115 item
= proto_tree_add_item(parent_tree
, proto_tcap
, tvb
, 0, -1, ENC_NA
);
3116 tree
= proto_item_add_subtree(item
, ett_tcap
);
3117 tcap_stat_tree
=tree
;
3122 p_tcap_private
= wmem_new0(pinfo
->pool
, struct tcap_private_t
);
3123 asn1_ctx
.value_ptr
= p_tcap_private
;
3124 gp_tcapsrt_info
=tcapsrt_razinfo();
3125 tcap_subdissector_used
=false;
3126 gp_tcap_context
=NULL
;
3127 dissect_tcap_TCMessage(false, tvb
, 0, &asn1_ctx
, tree
, -1);
3129 if (!tcap_subdissector_used
) {
3130 p_tcap_context
=tcapsrt_call_matching(tvb
, pinfo
, tcap_stat_tree
, gp_tcapsrt_info
);
3131 p_tcap_private
->context
=p_tcap_context
;
3133 /* If the current message is TCAP only,
3134 * save the Application Context Name for the next messages
3136 if ( p_tcap_context
&& cur_oid
&& !p_tcap_context
->oid_present
) {
3137 /* Save the application context and the sub dissector */
3138 (void) g_strlcpy(p_tcap_context
->oid
, cur_oid
, sizeof(p_tcap_context
->oid
));
3139 p_tcap_context
->oid_present
=true;
3140 if ( (subdissector_handle
= dissector_get_string_handle(ber_oid_dissector_table
, cur_oid
)) ) {
3141 p_tcap_context
->subdissector_handle
=subdissector_handle
;
3142 p_tcap_context
->subdissector_present
=true;
3145 if (p_tcap_context
&& p_tcap_context
->callback
) {
3146 /* Callback function for the upper layer */
3147 (p_tcap_context
->callback
)(tvb
, pinfo
, tcap_stat_tree
, p_tcap_context
);
3150 return tvb_captured_length(tvb
);
3154 proto_reg_handoff_tcap(void)
3157 data_handle
= find_dissector("data");
3158 ansi_tcap_handle
= find_dissector_add_dependency("ansi_tcap", proto_tcap
);
3159 ber_oid_dissector_table
= find_dissector_table("ber.oid");
3161 ss7pc_address_type
= address_type_get_by_name("AT_SS7PC");
3163 register_ber_oid_dissector("0.0.17.773.1.1.1", dissect_DialoguePDU_PDU
, proto_tcap
, "id-as-dialogue");
3164 register_ber_oid_dissector("0.0.17.773.1.2.1", dissect_UniDialoguePDU_PDU
, proto_tcap
, "id-as-uniDialogue");
3168 static void init_tcap(void);
3169 static void cleanup_tcap(void);
3172 proto_register_tcap(void)
3175 /* Setup list of header fields See Section 1.6.1 for details*/
3176 static hf_register_info hf
[] = {
3180 FT_UINT8
, BASE_HEX
, NULL
, 0,
3186 FT_UINT8
, BASE_DEC
, NULL
, 0,
3192 FT_BYTES
, BASE_NONE
, NULL
, 0,
3198 FT_BYTES
, BASE_NONE
, NULL
, 0,
3201 { &hf_tcap_constructor_eoc
,
3202 { "CONSTRUCTOR EOC",
3203 "tcap.constructor_eoc",
3204 FT_UINT16
, BASE_HEX
, NULL
, 0,
3207 /* Tcap Service Response Time */
3208 { &hf_tcapsrt_SessionId
,
3210 "tcap.srt.session_id",
3211 FT_UINT32
, BASE_DEC
, NULL
, 0x0,
3214 { &hf_tcapsrt_BeginSession
,
3217 FT_FRAMENUM
, BASE_NONE
, NULL
, 0x0,
3218 "SRT Begin of Session", HFILL
}
3220 { &hf_tcapsrt_EndSession
,
3223 FT_FRAMENUM
, BASE_NONE
, NULL
, 0x0,
3224 "SRT End of Session", HFILL
}
3226 { &hf_tcapsrt_SessionTime
,
3227 { "Session duration",
3228 "tcap.srt.sessiontime",
3229 FT_RELATIVE_TIME
, BASE_NONE
, NULL
, 0x0,
3230 "Duration of the TCAP session", HFILL
}
3232 { &hf_tcapsrt_Duplicate
,
3233 { "Session Duplicate",
3234 "tcap.srt.duplicate",
3235 FT_FRAMENUM
, BASE_NONE
, NULL
, 0x0,
3236 "SRT Duplicated with Session", HFILL
}
3238 { &hf_tcap_UniDialoguePDU_PDU
,
3239 { "UniDialoguePDU", "tcap.UniDialoguePDU",
3240 FT_UINT32
, BASE_DEC
, VALS(tcap_UniDialoguePDU_vals
), 0,
3242 { &hf_tcap_DialoguePDU_PDU
,
3243 { "DialoguePDU", "tcap.DialoguePDU",
3244 FT_UINT32
, BASE_DEC
, VALS(tcap_DialoguePDU_vals
), 0,
3247 { "oid", "tcap.oid",
3248 FT_OID
, BASE_NONE
, NULL
, 0,
3249 "OBJECT_IDENTIFIER", HFILL
}},
3251 { "dialog", "tcap.dialog",
3252 FT_BYTES
, BASE_NONE
, NULL
, 0,
3253 "Dialog1", HFILL
}},
3254 { &hf_tcap_unidirectional
,
3255 { "unidirectional", "tcap.unidirectional_element",
3256 FT_NONE
, BASE_NONE
, NULL
, 0,
3259 { "begin", "tcap.begin_element",
3260 FT_NONE
, BASE_NONE
, NULL
, 0,
3263 { "end", "tcap.end_element",
3264 FT_NONE
, BASE_NONE
, NULL
, 0,
3266 { &hf_tcap_continue
,
3267 { "continue", "tcap.continue_element",
3268 FT_NONE
, BASE_NONE
, NULL
, 0,
3271 { "abort", "tcap.abort_element",
3272 FT_NONE
, BASE_NONE
, NULL
, 0,
3274 { &hf_tcap_dialoguePortion
,
3275 { "dialoguePortion", "tcap.dialoguePortion",
3276 FT_BYTES
, BASE_NONE
, NULL
, 0,
3278 { &hf_tcap_components
,
3279 { "components", "tcap.components",
3280 FT_UINT32
, BASE_DEC
, NULL
, 0,
3281 "ComponentPortion", HFILL
}},
3283 { "otid", "tcap.otid",
3284 FT_BYTES
, BASE_NONE
, NULL
, 0,
3285 "OrigTransactionID", HFILL
}},
3287 { "dtid", "tcap.dtid",
3288 FT_BYTES
, BASE_NONE
, NULL
, 0,
3289 "DestTransactionID", HFILL
}},
3291 { "reason", "tcap.reason",
3292 FT_UINT32
, BASE_DEC
, VALS(tcap_Reason_vals
), 0,
3294 { &hf_tcap_p_abortCause
,
3295 { "p-abortCause", "tcap.p_abortCause",
3296 FT_UINT32
, BASE_DEC
, VALS(tcap_P_AbortCause_U_vals
), 0,
3298 { &hf_tcap_u_abortCause
,
3299 { "u-abortCause", "tcap.u_abortCause",
3300 FT_BYTES
, BASE_NONE
, NULL
, 0,
3301 "DialoguePortion", HFILL
}},
3302 { &hf_tcap__untag_item
,
3303 { "Component", "tcap.Component",
3304 FT_UINT32
, BASE_DEC
, VALS(tcap_Component_vals
), 0,
3307 { "invoke", "tcap.invoke_element",
3308 FT_NONE
, BASE_NONE
, NULL
, 0,
3310 { &hf_tcap_returnResultLast
,
3311 { "returnResultLast", "tcap.returnResultLast_element",
3312 FT_NONE
, BASE_NONE
, NULL
, 0,
3313 "ReturnResult", HFILL
}},
3314 { &hf_tcap_returnError
,
3315 { "returnError", "tcap.returnError_element",
3316 FT_NONE
, BASE_NONE
, NULL
, 0,
3319 { "reject", "tcap.reject_element",
3320 FT_NONE
, BASE_NONE
, NULL
, 0,
3322 { &hf_tcap_returnResultNotLast
,
3323 { "returnResultNotLast", "tcap.returnResultNotLast_element",
3324 FT_NONE
, BASE_NONE
, NULL
, 0,
3325 "ReturnResult", HFILL
}},
3326 { &hf_tcap_invokeID
,
3327 { "invokeID", "tcap.invokeID",
3328 FT_INT32
, BASE_DEC
, NULL
, 0,
3329 "InvokeIdType", HFILL
}},
3330 { &hf_tcap_linkedID
,
3331 { "linkedID", "tcap.linkedID",
3332 FT_INT32
, BASE_DEC
, NULL
, 0,
3333 "InvokeIdType", HFILL
}},
3335 { "opCode", "tcap.opCode",
3336 FT_UINT32
, BASE_DEC
, VALS(tcap_OPERATION_vals
), 0,
3337 "OPERATION", HFILL
}},
3338 { &hf_tcap_parameter
,
3339 { "parameter", "tcap.parameter_element",
3340 FT_NONE
, BASE_NONE
, NULL
, 0,
3342 { &hf_tcap_resultretres
,
3343 { "resultretres", "tcap.resultretres_element",
3344 FT_NONE
, BASE_NONE
, NULL
, 0,
3346 { &hf_tcap_errorCode
,
3347 { "errorCode", "tcap.errorCode",
3348 FT_UINT32
, BASE_DEC
, VALS(tcap_ErrorCode_vals
), 0,
3350 { &hf_tcap_invokeIDRej
,
3351 { "invokeIDRej", "tcap.invokeIDRej",
3352 FT_UINT32
, BASE_DEC
, VALS(tcap_T_invokeIDRej_vals
), 0,
3354 { &hf_tcap_derivable
,
3355 { "derivable", "tcap.derivable",
3356 FT_INT32
, BASE_DEC
, NULL
, 0,
3357 "InvokeIdType", HFILL
}},
3358 { &hf_tcap_not_derivable
,
3359 { "not-derivable", "tcap.not_derivable_element",
3360 FT_NONE
, BASE_NONE
, NULL
, 0,
3363 { "problem", "tcap.problem",
3364 FT_UINT32
, BASE_DEC
, VALS(tcap_T_problem_vals
), 0,
3366 { &hf_tcap_generalProblem
,
3367 { "generalProblem", "tcap.generalProblem",
3368 FT_INT32
, BASE_DEC
, VALS(tcap_GeneralProblem_vals
), 0,
3370 { &hf_tcap_invokeProblem
,
3371 { "invokeProblem", "tcap.invokeProblem",
3372 FT_INT32
, BASE_DEC
, VALS(tcap_InvokeProblem_vals
), 0,
3374 { &hf_tcap_returnResultProblem
,
3375 { "returnResultProblem", "tcap.returnResultProblem",
3376 FT_INT32
, BASE_DEC
, VALS(tcap_ReturnResultProblem_vals
), 0,
3378 { &hf_tcap_returnErrorProblem
,
3379 { "returnErrorProblem", "tcap.returnErrorProblem",
3380 FT_INT32
, BASE_DEC
, VALS(tcap_ReturnErrorProblem_vals
), 0,
3382 { &hf_tcap_localValue
,
3383 { "localValue", "tcap.localValue",
3384 FT_INT32
, BASE_DEC
, NULL
, 0,
3385 "INTEGER", HFILL
}},
3386 { &hf_tcap_globalValue
,
3387 { "globalValue", "tcap.globalValue",
3388 FT_OID
, BASE_NONE
, NULL
, 0,
3389 "OBJECT_IDENTIFIER", HFILL
}},
3390 { &hf_tcap_nationaler
,
3391 { "nationaler", "tcap.nationaler",
3392 FT_INT32
, BASE_DEC
, NULL
, 0,
3393 "INTEGER_M32768_32767", HFILL
}},
3394 { &hf_tcap_privateer
,
3395 { "privateer", "tcap.privateer",
3396 FT_INT32
, BASE_DEC
, NULL
, 0,
3397 "INTEGER", HFILL
}},
3398 { &hf_tcap_unidialoguePDU
,
3399 { "unidialoguePDU", "tcap.unidialoguePDU_element",
3400 FT_NONE
, BASE_NONE
, NULL
, 0,
3401 "AUDT_apdu", HFILL
}},
3402 { &hf_tcap_audt_protocol_version
,
3403 { "protocol-version", "tcap.protocol_version",
3404 FT_BYTES
, BASE_NONE
, NULL
, 0,
3405 "AUDT_protocol_version", HFILL
}},
3406 { &hf_tcap_audt_application_context_name
,
3407 { "application-context-name", "tcap.application_context_name",
3408 FT_OID
, BASE_NONE
, NULL
, 0,
3409 "AUDT_application_context_name", HFILL
}},
3410 { &hf_tcap_audt_user_information
,
3411 { "user-information", "tcap.user_information",
3412 FT_UINT32
, BASE_DEC
, NULL
, 0,
3413 "AUDT_user_information", HFILL
}},
3414 { &hf_tcap_audt_user_information_item
,
3415 { "user-information item", "tcap.user_information_item_element",
3416 FT_NONE
, BASE_NONE
, NULL
, 0,
3417 "EXTERNAL", HFILL
}},
3418 { &hf_tcap_dialogueRequest
,
3419 { "dialogueRequest", "tcap.dialogueRequest_element",
3420 FT_NONE
, BASE_NONE
, NULL
, 0,
3421 "AARQ_apdu", HFILL
}},
3422 { &hf_tcap_dialogueResponse
,
3423 { "dialogueResponse", "tcap.dialogueResponse_element",
3424 FT_NONE
, BASE_NONE
, NULL
, 0,
3425 "AARE_apdu", HFILL
}},
3426 { &hf_tcap_dialogueAbort
,
3427 { "dialogueAbort", "tcap.dialogueAbort_element",
3428 FT_NONE
, BASE_NONE
, NULL
, 0,
3429 "ABRT_apdu", HFILL
}},
3430 { &hf_tcap_aarq_protocol_version
,
3431 { "protocol-version", "tcap.protocol_version",
3432 FT_BYTES
, BASE_NONE
, NULL
, 0,
3433 "AARQ_protocol_version", HFILL
}},
3434 { &hf_tcap_aarq_application_context_name
,
3435 { "application-context-name", "tcap.application_context_name",
3436 FT_OID
, BASE_NONE
, NULL
, 0,
3437 "AARQ_application_context_name", HFILL
}},
3438 { &hf_tcap_aarq_user_information
,
3439 { "user-information", "tcap.user_information",
3440 FT_UINT32
, BASE_DEC
, NULL
, 0,
3441 "AARQ_user_information", HFILL
}},
3442 { &hf_tcap_aarq_user_information_item
,
3443 { "user-information item", "tcap.user_information_item_element",
3444 FT_NONE
, BASE_NONE
, NULL
, 0,
3445 "EXTERNAL", HFILL
}},
3446 { &hf_tcap_aare_protocol_version
,
3447 { "protocol-version", "tcap.protocol_version",
3448 FT_BYTES
, BASE_NONE
, NULL
, 0,
3449 "AARE_protocol_version", HFILL
}},
3450 { &hf_tcap_aare_application_context_name
,
3451 { "application-context-name", "tcap.application_context_name",
3452 FT_OID
, BASE_NONE
, NULL
, 0,
3453 "AARE_application_context_name", HFILL
}},
3455 { "result", "tcap.result",
3456 FT_INT32
, BASE_DEC
, VALS(tcap_Associate_result_vals
), 0,
3457 "Associate_result", HFILL
}},
3458 { &hf_tcap_result_source_diagnostic
,
3459 { "result-source-diagnostic", "tcap.result_source_diagnostic",
3460 FT_UINT32
, BASE_DEC
, VALS(tcap_Associate_source_diagnostic_vals
), 0,
3461 "Associate_source_diagnostic", HFILL
}},
3462 { &hf_tcap_aare_user_information
,
3463 { "user-information", "tcap.user_information",
3464 FT_UINT32
, BASE_DEC
, NULL
, 0,
3465 "AARE_user_information", HFILL
}},
3466 { &hf_tcap_aare_user_information_item
,
3467 { "user-information item", "tcap.user_information_item_element",
3468 FT_NONE
, BASE_NONE
, NULL
, 0,
3469 "EXTERNAL", HFILL
}},
3470 { &hf_tcap_abort_source
,
3471 { "abort-source", "tcap.abort_source",
3472 FT_INT32
, BASE_DEC
, VALS(tcap_ABRT_source_vals
), 0,
3473 "ABRT_source", HFILL
}},
3474 { &hf_tcap_abrt_user_information
,
3475 { "user-information", "tcap.user_information",
3476 FT_UINT32
, BASE_DEC
, NULL
, 0,
3477 "ABRT_user_information", HFILL
}},
3478 { &hf_tcap_abrt_user_information_item
,
3479 { "user-information item", "tcap.user_information_item_element",
3480 FT_NONE
, BASE_NONE
, NULL
, 0,
3481 "EXTERNAL", HFILL
}},
3482 { &hf_tcap_dialogue_service_user
,
3483 { "dialogue-service-user", "tcap.dialogue_service_user",
3484 FT_INT32
, BASE_DEC
, VALS(tcap_T_dialogue_service_user_vals
), 0,
3486 { &hf_tcap_dialogue_service_provider
,
3487 { "dialogue-service-provider", "tcap.dialogue_service_provider",
3488 FT_INT32
, BASE_DEC
, VALS(tcap_T_dialogue_service_provider_vals
), 0,
3490 { &hf_tcap_AUDT_protocol_version_version1
,
3491 { "version1", "tcap.AUDT.protocol.version.version1",
3492 FT_BOOLEAN
, 8, NULL
, 0x80,
3494 { &hf_tcap_AARQ_protocol_version_version1
,
3495 { "version1", "tcap.AARQ.protocol.version.version1",
3496 FT_BOOLEAN
, 8, NULL
, 0x80,
3498 { &hf_tcap_AARE_protocol_version_version1
,
3499 { "version1", "tcap.AARE.protocol.version.version1",
3500 FT_BOOLEAN
, 8, NULL
, 0x80,
3504 /* Setup protocol subtree array */
3505 static int *ett
[] = {
3511 &ett_tcap_ExternalPDU_U
,
3512 &ett_tcap_TCMessage
,
3513 &ett_tcap_Unidirectional
,
3519 &ett_tcap_SEQUENCE_SIZE_1_MAX_OF_Component
,
3520 &ett_tcap_Component
,
3522 &ett_tcap_ReturnResult
,
3523 &ett_tcap_T_resultretres
,
3524 &ett_tcap_ReturnError
,
3526 &ett_tcap_T_invokeIDRej
,
3527 &ett_tcap_T_problem
,
3528 &ett_tcap_OPERATION
,
3529 &ett_tcap_ErrorCode
,
3530 &ett_tcap_UniDialoguePDU
,
3531 &ett_tcap_AUDT_apdu_U
,
3532 &ett_tcap_AUDT_protocol_version
,
3533 &ett_tcap_AUDT_user_information
,
3534 &ett_tcap_DialoguePDU
,
3535 &ett_tcap_AARQ_apdu_U
,
3536 &ett_tcap_AARQ_protocol_version
,
3537 &ett_tcap_AARQ_user_information
,
3538 &ett_tcap_AARE_apdu_U
,
3539 &ett_tcap_AARE_protocol_version
,
3540 &ett_tcap_AARE_user_information
,
3541 &ett_tcap_ABRT_apdu_U
,
3542 &ett_tcap_ABRT_user_information
,
3543 &ett_tcap_Associate_source_diagnostic
,
3546 /*static enum_val_t tcap_options[] = {
3547 { "itu", "ITU", ITU_TCAP_STANDARD },
3548 { "ansi", "ANSI", ANSI_TCAP_STANDARD },
3552 module_t
*tcap_module
;
3554 /* Register the protocol name and description */
3555 proto_tcap
= proto_register_protocol(PNAME
, PSNAME
, PFNAME
);
3557 /* Required function calls to register the header fields and subtrees used */
3558 proto_register_field_array(proto_tcap
, hf
, array_length(hf
));
3559 proto_register_subtree_array(ett
, array_length(ett
));
3561 ansi_sub_dissectors
= register_dissector_table("ansi_tcap.ssn", "ANSI SSN", proto_tcap
, FT_UINT8
, BASE_DEC
);
3562 itu_sub_dissectors
= register_dissector_table("itu_tcap.ssn", "ITU SSN", proto_tcap
, FT_UINT8
, BASE_DEC
);
3564 tcap_module
= prefs_register_protocol(proto_tcap
, NULL
);
3567 prefs_register_enum_preference(tcap_module
, "standard", "ITU TCAP standard",
3568 "The SS7 standard used in ITU TCAP packets",
3569 &tcap_standard
, tcap_options
, false);
3571 prefs_register_obsolete_preference(tcap_module
, "standard");
3575 prefs_register_bool_preference(tcap_module
, "lock_info_col", "Lock Info column",
3576 "Always show TCAP in Info column",
3579 prefs_register_obsolete_preference(tcap_module
, "lock_info_col");
3582 /* Set default SSNs */
3583 range_convert_str(wmem_epan_scope(), &global_ssn_range
, "", MAX_SSN
);
3585 prefs_register_range_preference(tcap_module
, "ssn", "SCCP SSNs",
3586 "SCCP (and SUA) SSNs to decode as TCAP",
3587 &global_ssn_range
, MAX_SSN
);
3589 prefs_register_obsolete_preference(tcap_module
, "srt");
3591 prefs_register_bool_preference(tcap_module
, "persistentsrt",
3592 "Persistent stats for SRT",
3593 "Statistics for Response Time",
3594 >cap_PersistentSRT
);
3596 prefs_register_uint_preference(tcap_module
, "repetitiontimeout",
3597 "Repetition timeout",
3598 "Maximal delay for message repetition",
3599 10, >cap_RepetitionTimeout
);
3601 prefs_register_uint_preference(tcap_module
, "losttimeout",
3603 "Maximal delay for message lost",
3604 10, >cap_LostTimeout
);
3606 /* 'globally' register dissector */
3607 tcap_handle
= register_dissector("tcap", dissect_tcap
, proto_tcap
);
3609 /* hash-tables for SRT */
3610 tcaphash_context
= wmem_map_new_autoreset(wmem_epan_scope(), wmem_file_scope(), tcaphash_context_calchash
, tcaphash_context_equal
);
3611 tcaphash_begin
= wmem_map_new_autoreset(wmem_epan_scope(), wmem_file_scope(), tcaphash_begin_calchash
, tcaphash_begin_equal
);
3612 tcaphash_cont
= wmem_map_new_autoreset(wmem_epan_scope(), wmem_file_scope(), tcaphash_cont_calchash
, tcaphash_cont_equal
);
3613 tcaphash_end
= wmem_map_new_autoreset(wmem_epan_scope(), wmem_file_scope(), tcaphash_end_calchash
, tcaphash_end_equal
);
3614 tcaphash_ansi
= wmem_map_new_autoreset(wmem_epan_scope(), wmem_file_scope(), tcaphash_ansi_calchash
, tcaphash_ansi_equal
);
3616 register_init_routine(&init_tcap
);
3617 register_cleanup_routine(&cleanup_tcap
);
3621 static void range_delete_callback(uint32_t ssn
, void *ptr _U_
)
3623 if ( ssn
&& !get_ansi_tcap_subdissector(ssn
) && !get_itu_tcap_subdissector(ssn
) ) {
3624 dissector_delete_uint("sccp.ssn", ssn
, tcap_handle
);
3628 static void range_add_callback(uint32_t ssn
, void *ptr _U_
)
3630 if (ssn
&& !get_ansi_tcap_subdissector(ssn
) && !get_itu_tcap_subdissector(ssn
) ) {
3631 dissector_add_uint("sccp.ssn", ssn
, tcap_handle
);
3636 static void init_tcap(void)
3638 ssn_range
= range_copy(wmem_epan_scope(), global_ssn_range
);
3639 range_foreach(ssn_range
, range_add_callback
, NULL
);
3641 /* Reset the session counter */
3642 tcapsrt_global_SessionId
=1;
3644 /* Display of SRT is enabled
3645 * 1) For wireshark only if Persistent Stat is enabled
3646 * 2) For tshark, if the CLI SRT tap is registered
3648 gtcap_DisplaySRT
=gtcap_PersistentSRT
|| gtcap_StatSRT
;
3651 static void cleanup_tcap(void)
3653 range_foreach(ssn_range
, range_delete_callback
, NULL
);
3654 wmem_free(wmem_epan_scope(), ssn_range
);
3658 // NOLINTNEXTLINE(misc-no-recursion)
3659 dissect_tcap_param(asn1_ctx_t
*actx
, proto_tree
*tree
, tvbuff_t
*tvb
, int offset
)
3661 int tag_offset
, saved_offset
, len_offset
;
3663 proto_tree
*subtree
;
3668 uint32_t tag_length
;
3669 uint32_t len_length
;
3672 while (tvb_reported_length_remaining(tvb
, offset
) > 0)
3674 saved_offset
= offset
;
3676 offset
= get_ber_identifier(tvb
, offset
, &ber_class
, &pc
, &tag
);
3677 tag_offset
= offset
;
3678 offset
= get_ber_length(tvb
, offset
, &len
, &ind_field
);
3679 len_offset
= offset
;
3681 tag_length
= tag_offset
- saved_offset
;
3682 len_length
= len_offset
- tag_offset
;
3686 subtree
= proto_tree_add_subtree(tree
, tvb
, saved_offset
,
3687 len
+ (len_offset
- saved_offset
), ett_param
, NULL
,
3689 proto_tree_add_uint_format(subtree
, hf_tcap_tag
, tvb
,
3690 saved_offset
, tag_length
, tag
,
3692 proto_tree_add_uint(subtree
, hf_tcap_tag
, tvb
, saved_offset
,
3693 tag_length
, ber_class
);
3695 proto_tree_add_uint(subtree
, hf_tcap_length
, tvb
, tag_offset
,
3698 if (len
- (ind_field
? 2 : 0)) /*should always be positive unless we get an empty constructor pointless? */
3700 next_tvb
= tvb_new_subset_length(tvb
, offset
, len
- (ind_field
? 2 : 0));
3701 increment_dissection_depth(actx
->pinfo
);
3702 dissect_tcap_param(actx
, subtree
,next_tvb
,0);
3703 decrement_dissection_depth(actx
->pinfo
);
3707 proto_tree_add_item(subtree
, hf_tcap_constructor_eoc
, tvb
, offset
+len
-2, 2, ENC_BIG_ENDIAN
);
3713 subtree
= proto_tree_add_subtree_format(tree
, tvb
, saved_offset
,
3714 len
+ (len_offset
- saved_offset
), ett_param
, NULL
,
3715 "Parameter (0x%.2x)", tag
);
3717 proto_tree_add_uint(subtree
, hf_tcap_tag
, tvb
, saved_offset
,
3720 proto_tree_add_uint(subtree
, hf_tcap_length
, tvb
,
3721 saved_offset
+tag_length
, len_length
, len
);
3723 if (len
) /* check for NULLS */
3725 next_tvb
= tvb_new_subset_length(tvb
, offset
, len
);
3726 dissect_ber_octet_string(true, actx
, tree
, next_tvb
, 0,
3727 hf_tcap_data
, NULL
);
3737 * Call ITU Subdissector to decode the Tcap Component
3740 dissect_tcap_ITU_ComponentPDU(bool implicit_tag _U_
, tvbuff_t
*tvb
, int offset _U_
, asn1_ctx_t
*actx
, proto_tree
*tree
, int hf_index _U_
)
3742 dissector_handle_t subdissector_handle
=NULL
;
3743 bool is_subdissector
=false;
3744 struct tcaphash_context_t
* p_tcap_context
=NULL
;
3745 struct tcap_private_t
*p_tcap_private
= (struct tcap_private_t
*)actx
->value_ptr
;
3748 * ok lets look at the oid and ssn and try and find a dissector, otherwise lets decode it.
3752 * Handle The TCAP Service Response Time
3754 if (!tcap_subdissector_used
) {
3755 p_tcap_context
=tcapsrt_call_matching(tvb
, actx
->pinfo
, tcap_stat_tree
, gp_tcapsrt_info
);
3756 tcap_subdissector_used
=false;
3757 gp_tcap_context
=p_tcap_context
;
3758 p_tcap_private
->context
=p_tcap_context
;
3760 /* Take the last TCAP context */
3761 p_tcap_context
= gp_tcap_context
;
3762 p_tcap_private
->context
=p_tcap_context
;
3764 if (p_tcap_context
) {
3766 if (p_tcap_context
->oid_present
) {
3767 /* We have already an Application Context, check if we have
3768 to fallback to a lower version */
3769 if (strncmp(p_tcap_context
->oid
, cur_oid
, sizeof(p_tcap_context
->oid
)) != 0) {
3770 /* ACN, changed, Fallback to lower version
3771 * and update the subdissector (purely formal)
3773 (void) g_strlcpy(p_tcap_context
->oid
, cur_oid
, sizeof(p_tcap_context
->oid
));
3774 if ((subdissector_handle
= dissector_get_string_handle(ber_oid_dissector_table
, cur_oid
))) {
3775 p_tcap_context
->subdissector_handle
= subdissector_handle
;
3776 p_tcap_context
->subdissector_present
= true;
3780 /* We do not have the OID in the TCAP context, so store it */
3781 (void) g_strlcpy(p_tcap_context
->oid
, cur_oid
, sizeof(p_tcap_context
->oid
));
3782 p_tcap_context
->oid_present
= true;
3783 /* Try to find a subdissector according to OID */
3784 if ((subdissector_handle
3785 = dissector_get_string_handle(ber_oid_dissector_table
, cur_oid
))) {
3786 p_tcap_context
->subdissector_handle
= subdissector_handle
;
3787 p_tcap_context
->subdissector_present
= true;
3789 /* Not found, so try to find a subdissector according to SSN */
3790 if ((subdissector_handle
= get_itu_tcap_subdissector(actx
->pinfo
->match_uint
))) {
3791 /* Found according to SSN */
3792 p_tcap_context
->subdissector_handle
= subdissector_handle
;
3793 p_tcap_context
->subdissector_present
= true;
3798 /* Copy the OID from the TCAP context to the current oid */
3799 if (p_tcap_context
->oid_present
) {
3800 p_tcap_private
->oid
= (void*)p_tcap_context
->oid
;
3801 p_tcap_private
->acv
= true;
3804 } /* no TCAP context */
3808 && p_tcap_context
->subdissector_present
) {
3809 /* Take the subdissector from the context */
3810 subdissector_handle
= p_tcap_context
->subdissector_handle
;
3811 is_subdissector
= true;
3814 /* Have SccpUsersTable protocol taking precedence over sccp.ssn table */
3815 if (!is_subdissector
&& requested_subdissector_handle
) {
3816 is_subdissector
= true;
3817 subdissector_handle
= requested_subdissector_handle
;
3820 if (!is_subdissector
) {
3822 * If we do not currently know the subdissector, we have to find it
3823 * - first, according to the OID
3824 * - then according to the SSN
3825 * - and at least, take the default Data handler
3827 if (ber_oid_dissector_table
&& cur_oid
) {
3828 /* Search if we can find the sub protocol according to the A.C.N */
3829 if ((subdissector_handle
3830 = dissector_get_string_handle(ber_oid_dissector_table
, cur_oid
))) {
3832 is_subdissector
= true;
3834 /* Search if we can found the sub protocol according to the SSN table */
3835 if ((subdissector_handle
3836 = get_itu_tcap_subdissector(actx
->pinfo
->match_uint
))) {
3837 /* Found according to SSN */
3838 is_subdissector
= true;
3840 /* Nothing found, take the Data handler */
3841 subdissector_handle
= data_handle
;
3842 is_subdissector
= true;
3846 /* There is no A.C.N for this transaction, so search in the SSN table */
3847 if ((subdissector_handle
= get_itu_tcap_subdissector(actx
->pinfo
->match_uint
))) {
3848 /* Found according to SSN */
3849 is_subdissector
= true;
3851 subdissector_handle
= data_handle
;
3852 is_subdissector
= true;
3856 /* We have it already */
3859 /* Call the sub dissector if present, and not already called */
3860 if (is_subdissector
) {
3861 bool is_active
= call_dissector_only(subdissector_handle
, tvb
, actx
->pinfo
, tree
, actx
->value_ptr
);
3862 col_set_fence(actx
->pinfo
->cinfo
, COL_INFO
);
3871 call_tcap_dissector(dissector_handle_t handle
, tvbuff_t
* tvb
, packet_info
* pinfo
, proto_tree
* tree
)
3873 requested_subdissector_handle
= handle
;
3876 dissect_tcap(tvb
, pinfo
, tree
, NULL
);
3878 requested_subdissector_handle
= NULL
;
3882 requested_subdissector_handle
= NULL
;
3891 * indent-tabs-mode: nil
3894 * ex: set shiftwidth=2 tabstop=8 expandtab:
3895 * :indentSize=2:tabSize=8:noTabs=true: