epan/dissectors/pidl/ C99 drsuapi
[wireshark-sm.git] / epan / dissectors / packet-ansi_tcap.c
blobc5ec4a4d541e3842a53a62bcaf87e90612dabb8a
1 /* Do not modify this file. Changes will be overwritten. */
2 /* Generated automatically by the ASN.1 to Wireshark dissector compiler */
3 /* packet-ansi_tcap.c */
4 /* asn2wrs.py -b -q -L -p ansi_tcap -c ./ansi_tcap.cnf -s ./packet-ansi_tcap-template -D . -O ../.. TCAP-Remote-Operations-Information-Objects.asn TCAPPackage.asn */
6 /* packet-ansi_tcap-template.c
7 * Routines for ANSI TCAP
8 * Copyright 2007 Anders Broman <anders.broman@ericsson.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: T1.114
19 #include "config.h"
21 #include <epan/packet.h>
22 #include <epan/prefs.h>
23 #include <epan/expert.h>
24 #include <epan/oids.h>
25 #include <epan/asn1.h>
26 #include <epan/strutil.h>
27 #include <wsutil/array.h>
29 #include "packet-ber.h"
30 #include "packet-tcap.h"
31 #include "packet-ansi_tcap.h"
33 #define PNAME "ANSI Transaction Capabilities Application Part"
34 #define PSNAME "ANSI_TCAP"
35 #define PFNAME "ansi_tcap"
37 void proto_register_ansi_tcap(void);
38 void proto_reg_handoff_ansi_tcap(void);
40 /* Preference settings */
41 #define ANSI_TCAP_TID_ONLY 0
42 #define ANSI_TCAP_TID_AND_SOURCE 1
43 #define ANSI_TCAP_TID_SOURCE_AND_DEST 2
44 static int ansi_tcap_response_matching_type = ANSI_TCAP_TID_ONLY;
46 /* Initialize the protocol and registered fields */
47 static int proto_ansi_tcap;
49 #if 0
50 static int hf_ansi_tcapsrt_SessionId;
51 static int hf_ansi_tcapsrt_Duplicate;
52 static int hf_ansi_tcapsrt_BeginSession;
53 static int hf_ansi_tcapsrt_EndSession;
54 static int hf_ansi_tcapsrt_SessionTime;
55 #endif
56 static int hf_ansi_tcap_bit_h;
57 static int hf_ansi_tcap_op_family;
58 static int hf_ansi_tcap_op_specifier;
60 static int hf_ansi_tcap_national; /* T_national */
61 static int hf_ansi_tcap_private; /* T_private */
62 static int hf_ansi_tcap_national_01; /* INTEGER_M128_127 */
63 static int hf_ansi_tcap_ec_private; /* ANSIMAPPrivateErrorcode */
64 static int hf_ansi_tcap_unidirectional; /* T_unidirectional */
65 static int hf_ansi_tcap_queryWithPerm; /* T_queryWithPerm */
66 static int hf_ansi_tcap_queryWithoutPerm; /* T_queryWithoutPerm */
67 static int hf_ansi_tcap_response; /* T_response */
68 static int hf_ansi_tcap_conversationWithPerm; /* T_conversationWithPerm */
69 static int hf_ansi_tcap_conversationWithoutPerm; /* T_conversationWithoutPerm */
70 static int hf_ansi_tcap_abort; /* T_abort */
71 static int hf_ansi_tcap_identifier; /* TransactionID */
72 static int hf_ansi_tcap_dialoguePortion; /* DialoguePortion */
73 static int hf_ansi_tcap_componentPortion; /* ComponentSequence */
74 static int hf_ansi_tcap_dialogPortion; /* DialoguePortion */
75 static int hf_ansi_tcap_causeInformation; /* T_causeInformation */
76 static int hf_ansi_tcap_abortCause; /* P_Abort_cause */
77 static int hf_ansi_tcap_abort_userInformation; /* UserAbortInformation */
78 static int hf_ansi_tcap_version; /* ProtocolVersion */
79 static int hf_ansi_tcap_applicationContext; /* T_applicationContext */
80 static int hf_ansi_tcap_integerApplicationId; /* IntegerApplicationContext */
81 static int hf_ansi_tcap_objectApplicationId; /* ObjectIDApplicationContext */
82 static int hf_ansi_tcap_userInformation; /* UserInformation */
83 static int hf_ansi_tcap_securityContext; /* T_securityContext */
84 static int hf_ansi_tcap_integerSecurityId; /* INTEGER */
85 static int hf_ansi_tcap_objectSecurityId; /* OBJECT_IDENTIFIER */
86 static int hf_ansi_tcap_confidentiality; /* Confidentiality */
87 static int hf_ansi_tcap__untag_item; /* EXTERNAL */
88 static int hf_ansi_tcap_confidentialityId; /* T_confidentialityId */
89 static int hf_ansi_tcap_integerConfidentialityId; /* INTEGER */
90 static int hf_ansi_tcap_objectConfidentialityId; /* OBJECT_IDENTIFIER */
91 static int hf_ansi_tcap__untag_item_01; /* ComponentPDU */
92 static int hf_ansi_tcap_invokeLast; /* Invoke */
93 static int hf_ansi_tcap_returnResultLast; /* ReturnResult */
94 static int hf_ansi_tcap_returnError; /* ReturnError */
95 static int hf_ansi_tcap_reject; /* Reject */
96 static int hf_ansi_tcap_invokeNotLast; /* Invoke */
97 static int hf_ansi_tcap_returnResultNotLast; /* ReturnResult */
98 static int hf_ansi_tcap_componentIDs; /* T_componentIDs */
99 static int hf_ansi_tcap_operationCode; /* OperationCode */
100 static int hf_ansi_tcap_invoke_parameter; /* T_invoke_parameter */
101 static int hf_ansi_tcap_componentID; /* T_componentID */
102 static int hf_ansi_tcap_returnResult_parameter; /* T_returnResult_parameter */
103 static int hf_ansi_tcap_componentID_01; /* T_componentID_01 */
104 static int hf_ansi_tcap_errorCode; /* ErrorCode */
105 static int hf_ansi_tcap_returnError_parameter; /* T_returnError_parameter */
106 static int hf_ansi_tcap_componentID_02; /* OCTET_STRING_SIZE_0_1 */
107 static int hf_ansi_tcap_rejectProblem; /* Problem */
108 static int hf_ansi_tcap_reject_parameter; /* T_reject_parameter */
109 static int hf_ansi_tcap_paramSequence; /* T_paramSequence */
110 static int hf_ansi_tcap_paramSet; /* T_paramSet */
112 /* Initialize the subtree pointers */
113 static int ett_tcap;
114 static int ett_param;
115 static int ett_ansi_tcap_op_code_nat;
117 static int ett_otid;
118 static int ett_dtid;
119 static int ett_ansi_tcap_stat;
121 static expert_field ei_ansi_tcap_dissector_not_implemented;
123 static struct tcapsrt_info_t * gp_tcapsrt_info;
124 static bool tcap_subdissector_used=false;
126 static struct tcaphash_context_t * gp_tcap_context;
128 /* Note the high bit should be masked off when registering in this table (0x7fff)*/
129 static dissector_table_t ansi_tcap_national_opcode_table; /* National Operation Codes */
131 static int ett_ansi_tcap_OperationCode;
132 static int ett_ansi_tcap_ErrorCode;
133 static int ett_ansi_tcap_PackageType;
134 static int ett_ansi_tcap_UniTransactionPDU;
135 static int ett_ansi_tcap_TransactionPDU;
136 static int ett_ansi_tcap_Abort;
137 static int ett_ansi_tcap_T_causeInformation;
138 static int ett_ansi_tcap_DialoguePortion_U;
139 static int ett_ansi_tcap_T_applicationContext;
140 static int ett_ansi_tcap_T_securityContext;
141 static int ett_ansi_tcap_UserInformation_U;
142 static int ett_ansi_tcap_Confidentiality;
143 static int ett_ansi_tcap_T_confidentialityId;
144 static int ett_ansi_tcap_SEQUENCE_OF_ComponentPDU;
145 static int ett_ansi_tcap_ComponentPDU;
146 static int ett_ansi_tcap_Invoke;
147 static int ett_ansi_tcap_ReturnResult;
148 static int ett_ansi_tcap_ReturnError;
149 static int ett_ansi_tcap_Reject;
150 static int ett_ansi_tcap_T_reject_parameter;
151 static int ett_ansi_tcap_T_paramSequence;
152 static int ett_ansi_tcap_T_paramSet;
154 #define MAX_SSN 254
156 /* When several Tcap components are received in a single TCAP message,
157 we have to use several buffers for the stored parameters
158 because else this data are erased during TAP dissector call */
159 #define MAX_TCAP_INSTANCE 10
160 int tcapsrt_global_current=0;
161 struct tcapsrt_info_t tcapsrt_global_info[MAX_TCAP_INSTANCE];
163 static dissector_table_t ber_oid_dissector_table;
164 static const char * cur_oid;
165 static const char * tcapext_oid;
167 static dissector_handle_t ansi_map_handle;
168 static dissector_handle_t ain_handle;
170 struct ansi_tcap_private_t ansi_tcap_private;
171 #define MAX_TID_STR_LEN 1024
173 static void ansi_tcap_ctx_init(struct ansi_tcap_private_t *a_tcap_ctx) {
174 memset(a_tcap_ctx, '\0', sizeof(*a_tcap_ctx));
175 a_tcap_ctx->signature = ANSI_TCAP_CTX_SIGNATURE;
176 a_tcap_ctx->oid_is_present = false;
177 a_tcap_ctx->TransactionID_str = NULL;
180 static const value_string ansi_tcap_national_op_code_family_vals[] = {
181 { 0x0, "All Families" },
182 { 0x1, "Parameter" },
183 { 0x2, "Charging" },
184 { 0x3, "Provide Instructions" },
185 { 0x4, "Connection Control" },
186 { 0x5, "Caller Interaction" },
187 { 0x6, "Send Notification" },
188 { 0x7, "Network Management" },
189 { 0x8, "Procedural" },
190 { 0x9, "Operation Control" },
191 { 0xa, "Report Event" },
192 /* Spare */
193 { 0x7e, "Miscellaneous" },
194 { 0x7f, "Reserved" },
195 { 0, NULL }
198 /* Transaction tracking */
199 /* Transaction table */
200 struct ansi_tcap_invokedata_t {
201 int OperationCode;
203 0 : national,
204 1 : private
206 int32_t OperationCode_private;
207 int32_t OperationCode_national;
210 static wmem_multimap_t *TransactionId_table;
212 /* Store Invoke information needed for the corresponding reply */
213 static void
214 save_invoke_data(packet_info *pinfo, proto_tree *tree _U_, tvbuff_t *tvb _U_){
215 struct ansi_tcap_invokedata_t *ansi_tcap_saved_invokedata;
216 char *src, *dst;
217 char *buf;
219 src = address_to_str(pinfo->pool, &(pinfo->src));
220 dst = address_to_str(pinfo->pool, &(pinfo->dst));
222 if ((!pinfo->fd->visited)&&(ansi_tcap_private.TransactionID_str)){
224 /* Only do this once XXX I hope it's the right thing to do */
225 /* The hash string needs to contain src and dest to distinguish different flows */
226 switch(ansi_tcap_response_matching_type){
227 case ANSI_TCAP_TID_ONLY:
228 buf = wmem_strdup(pinfo->pool, ansi_tcap_private.TransactionID_str);
229 break;
230 case ANSI_TCAP_TID_AND_SOURCE:
231 buf = wmem_strdup_printf(pinfo->pool, "%s%s",ansi_tcap_private.TransactionID_str,src);
232 break;
233 case ANSI_TCAP_TID_SOURCE_AND_DEST:
234 default:
235 buf = wmem_strdup_printf(pinfo->pool, "%s%s%s",ansi_tcap_private.TransactionID_str,src,dst);
236 break;
239 ansi_tcap_saved_invokedata = wmem_new(wmem_file_scope(), struct ansi_tcap_invokedata_t);
240 ansi_tcap_saved_invokedata->OperationCode = ansi_tcap_private.d.OperationCode;
241 ansi_tcap_saved_invokedata->OperationCode_national = ansi_tcap_private.d.OperationCode_national;
242 ansi_tcap_saved_invokedata->OperationCode_private = ansi_tcap_private.d.OperationCode_private;
244 wmem_multimap_insert32(TransactionId_table,
245 wmem_strdup(wmem_file_scope(), buf),
246 pinfo->num,
247 ansi_tcap_saved_invokedata);
249 ws_warning("Tcap Invoke Hash string %s",buf);
254 static bool
255 find_saved_invokedata(packet_info *pinfo, proto_tree *tree _U_, tvbuff_t *tvb _U_){
256 struct ansi_tcap_invokedata_t *ansi_tcap_saved_invokedata;
257 char *src, *dst;
258 char *buf;
260 if (!ansi_tcap_private.TransactionID_str) {
261 return false;
264 src = address_to_str(pinfo->pool, &(pinfo->src));
265 dst = address_to_str(pinfo->pool, &(pinfo->dst));
267 /* The hash string needs to contain src and dest to distinguish different flows */
268 buf = (char *)wmem_alloc(pinfo->pool, MAX_TID_STR_LEN);
269 buf[0] = '\0';
270 /* Reverse order to invoke */
271 switch(ansi_tcap_response_matching_type){
272 case ANSI_TCAP_TID_ONLY:
273 snprintf(buf,MAX_TID_STR_LEN,"%s",ansi_tcap_private.TransactionID_str);
274 break;
275 case ANSI_TCAP_TID_AND_SOURCE:
276 snprintf(buf,MAX_TID_STR_LEN,"%s%s",ansi_tcap_private.TransactionID_str,dst);
277 break;
278 case ANSI_TCAP_TID_SOURCE_AND_DEST:
279 default:
280 snprintf(buf,MAX_TID_STR_LEN,"%s%s%s",ansi_tcap_private.TransactionID_str,dst,src);
281 break;
284 ansi_tcap_saved_invokedata = (struct ansi_tcap_invokedata_t *)wmem_multimap_lookup32_le(TransactionId_table, buf, pinfo->num);
285 if(ansi_tcap_saved_invokedata){
286 ansi_tcap_private.d.OperationCode = ansi_tcap_saved_invokedata->OperationCode;
287 ansi_tcap_private.d.OperationCode_national = ansi_tcap_saved_invokedata->OperationCode_national;
288 ansi_tcap_private.d.OperationCode_private = ansi_tcap_saved_invokedata->OperationCode_private;
289 return true;
291 return false;
294 /* As currently ANSI MAP is the only possible sub dissector this function
295 * must be improved to handle general cases.
299 * TODO:
300 * 1)Handle national codes
301 * Design option
302 * - Create a ansi.tcap.national dissector table and have dissectors for
303 * national codes register there and let ansi tcap call them.
304 * 2)Handle Private codes properly
305 * Design question
306 * Unclear how to differentiate between different private "code sets".
307 * Use SCCP SSN table as before? or a ansi.tcap.private dissector table?
310 static bool
311 find_tcap_subdissector(tvbuff_t *tvb, asn1_ctx_t *actx, proto_tree *tree){
312 proto_item *item;
314 /* If "DialoguePortion objectApplicationId ObjectIDApplicationContext
315 * points to the subdissector this code can be used.
317 if(ansi_tcap_private.d.oid_is_present){
318 call_ber_oid_callback(ansi_tcap_private.objectApplicationId_oid, tvb, 0, actx-pinfo, tree, NULL);
319 return true;
322 if(ansi_tcap_private.d.pdu == 1){
323 /* Save Invoke data for this transaction */
324 save_invoke_data(actx->pinfo, tree, tvb);
325 }else{
326 /* Get saved data for this transaction */
327 if(find_saved_invokedata(actx->pinfo, tree, tvb)){
328 if(ansi_tcap_private.d.OperationCode == 0){
329 /* national */
330 item = proto_tree_add_int(tree, hf_ansi_tcap_national, tvb, 0, 0, ansi_tcap_private.d.OperationCode_national);
331 }else{
332 item = proto_tree_add_int(tree, hf_ansi_tcap_private, tvb, 0, 0, ansi_tcap_private.d.OperationCode_private);
334 proto_item_set_generated(item);
335 ansi_tcap_private.d.OperationCode_item = item;
338 if(ansi_tcap_private.d.OperationCode == 0){
339 /* national */
340 uint8_t family = (ansi_tcap_private.d.OperationCode_national & 0x7f00)>>8;
341 uint8_t specifier = (uint8_t)(ansi_tcap_private.d.OperationCode_national & 0xff);
342 if(!dissector_try_uint(ansi_tcap_national_opcode_table, ansi_tcap_private.d.OperationCode_national, tvb, actx->pinfo, actx->subtree.top_tree)){
343 proto_tree_add_expert_format(tree, actx->pinfo, &ei_ansi_tcap_dissector_not_implemented, tvb, 0, -1,
344 "Dissector for ANSI TCAP NATIONAL code:0x%x(Family %u, Specifier %u) \n"
345 "not implemented. Contact Wireshark developers if you want this supported(Spec required)",
346 ansi_tcap_private.d.OperationCode_national, family, specifier);
347 return false;
349 return true;
350 }else if(ansi_tcap_private.d.OperationCode == 1){
351 /* private */
352 if((ansi_tcap_private.d.OperationCode_private & 0xff00) == 0x0900){
353 /* This is abit of a hack as it assumes the private codes with a "family" of 0x09 is ANSI MAP
354 * See TODO above.
355 * N.S0005-0 v 1.0 TCAP Formats and Procedures 5-16 Application Services
356 * 6.3.2 Component Portion
357 * The Operation Code is partitioned into an Operation Family followed by a
358 * Specifier associated with each Operation Family member. For TIA/EIA-41 the
359 * Operation Family is coded as decimal 9. Bit H of the Operation Family is always
360 * coded as 0.
362 call_dissector_with_data(ansi_map_handle, tvb, actx->pinfo, actx->subtree.top_tree, &ansi_tcap_private);
364 return true;
365 } else if ((ansi_tcap_private.d.OperationCode_private & 0xf000) == 0x6000) {
366 call_dissector_with_data(ain_handle, tvb, actx->pinfo, actx->subtree.top_tree, &ansi_tcap_private);
367 return true;
370 proto_tree_add_expert_format(tree, actx->pinfo, &ei_ansi_tcap_dissector_not_implemented, tvb, 0, -1,
371 "Dissector for ANSI TCAP PRIVATE code:%u not implemented.\n"
372 "Contact Wireshark developers if you want this supported(Spec required)",
373 ansi_tcap_private.d.OperationCode_private);
374 return false;
379 static int
380 dissect_ansi_tcap_T_national(bool implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
381 proto_tree *subtree;
382 proto_item *spcifier_item;
383 int start_offset = offset;
384 uint8_t family;
385 uint8_t specifier;
387 offset = dissect_ber_integer(implicit_tag, actx, tree, tvb, offset, hf_index,
388 &ansi_tcap_private.d.OperationCode_national);
390 /* mask off the H bit */
391 ansi_tcap_private.d.OperationCode_national = (ansi_tcap_private.d.OperationCode_national&0x7fff);
393 subtree = proto_item_add_subtree(actx->created_item, ett_ansi_tcap_op_code_nat);
394 /* Bit H is used to distinguish between Operations that require a reply and those that do not. A value of 1
395 * indicates that a reply is required; a value of 0 indicates that a reply is not required.
397 family = (ansi_tcap_private.d.OperationCode_national & 0x7f00)>>8;
398 specifier = (uint8_t)(ansi_tcap_private.d.OperationCode_national & 0xff);
399 proto_tree_add_item(subtree, hf_ansi_tcap_bit_h, tvb, start_offset, 2, ENC_BIG_ENDIAN);
400 proto_tree_add_item(subtree, hf_ansi_tcap_op_family, tvb, start_offset, 2, ENC_BIG_ENDIAN);
401 spcifier_item = proto_tree_add_item(subtree, hf_ansi_tcap_op_specifier, tvb, start_offset, 2, ENC_BIG_ENDIAN);
403 switch(family){
404 case 0:
405 /* All Families ( Not used ) */
406 break;
407 case 1:
408 /* Parameter */
409 if(specifier== 1){
410 proto_item_append_text(spcifier_item, " Provide Value");
411 }else if (specifier== 2){
412 proto_item_append_text(spcifier_item, " Set Value");
414 break;
415 case 2:
416 /* Charging */
417 if (specifier== 1){
418 proto_item_append_text(spcifier_item, " Bill Call");
420 break;
421 case 3:
422 /* Provide Instructions */
423 if (specifier== 1){
424 proto_item_append_text(spcifier_item, " Start");
425 }else if (specifier== 2){
426 proto_item_append_text(spcifier_item, " Assist");
428 break;
429 case 4:
430 /* Connection Control */
431 if (specifier== 1){
432 proto_item_append_text(spcifier_item, " Connect");
433 }else if (specifier== 2){
434 proto_item_append_text(spcifier_item, " Temporary Connect");
435 }else if (specifier== 3){
436 proto_item_append_text(spcifier_item, " Disconnect");
437 }else if (specifier== 4){
438 proto_item_append_text(spcifier_item, " Forward Disconnect");
440 break;
441 default:
442 break;
447 return offset;
452 static int
453 dissect_ansi_tcap_T_private(bool implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
454 offset = dissect_ber_integer(implicit_tag, actx, tree, tvb, offset, hf_index,
455 &ansi_tcap_private.d.OperationCode_private);
457 return offset;
461 static const value_string ansi_tcap_OperationCode_vals[] = {
462 { 16, "national" },
463 { 17, "private" },
464 { 0, NULL }
467 static const ber_choice_t OperationCode_choice[] = {
468 { 16, &hf_ansi_tcap_national , BER_CLASS_PRI, 16, BER_FLAGS_IMPLTAG, dissect_ansi_tcap_T_national },
469 { 17, &hf_ansi_tcap_private , BER_CLASS_PRI, 17, BER_FLAGS_IMPLTAG, dissect_ansi_tcap_T_private },
470 { 0, NULL, 0, 0, 0, NULL }
473 static int
474 dissect_ansi_tcap_OperationCode(bool implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
475 offset = dissect_ber_choice(actx, tree, tvb, offset,
476 OperationCode_choice, hf_index, ett_ansi_tcap_OperationCode,
477 &ansi_tcap_private.d.OperationCode);
479 ansi_tcap_private.d.OperationCode_item = actx->created_item;
480 return offset;
485 static int
486 dissect_ansi_tcap_INTEGER_M128_127(bool implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
487 offset = dissect_ber_integer(implicit_tag, actx, tree, tvb, offset, hf_index,
488 NULL);
490 return offset;
494 static const value_string ansi_tcap_ANSIMAPPrivateErrorcode_vals[] = {
495 { 129, "unrecognized-MIN" },
496 { 130, "unrecognized-ESN" },
497 { 131, "mINorHLR-Mismatch" },
498 { 132, "operation-Sequence-Problem" },
499 { 133, "resource-Shortage" },
500 { 134, "operation-Not-Supported" },
501 { 135, "trunk-Unavailable" },
502 { 136, "parameter-Error" },
503 { 137, "system-Failure" },
504 { 138, "unrecognized-Parameter-Value" },
505 { 139, "feature-Inactive" },
506 { 140, "missing-Parameter" },
507 { 0, NULL }
511 static int
512 dissect_ansi_tcap_ANSIMAPPrivateErrorcode(bool implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
513 offset = dissect_ber_integer(implicit_tag, actx, tree, tvb, offset, hf_index,
514 NULL);
516 return offset;
520 static const value_string ansi_tcap_ErrorCode_vals[] = {
521 { 19, "national" },
522 { 20, "private" },
523 { 0, NULL }
526 static const ber_choice_t ErrorCode_choice[] = {
527 { 19, &hf_ansi_tcap_national_01, BER_CLASS_PRI, 19, 0, dissect_ansi_tcap_INTEGER_M128_127 },
528 { 20, &hf_ansi_tcap_ec_private, BER_CLASS_PRI, 20, BER_FLAGS_IMPLTAG, dissect_ansi_tcap_ANSIMAPPrivateErrorcode },
529 { 0, NULL, 0, 0, 0, NULL }
532 static int
533 dissect_ansi_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_) {
534 offset = dissect_ber_choice(actx, tree, tvb, offset,
535 ErrorCode_choice, hf_index, ett_ansi_tcap_ErrorCode,
536 NULL);
538 return offset;
543 static int
544 dissect_ansi_tcap_TransactionID_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_) {
546 tvbuff_t *next_tvb;
547 uint8_t len;
549 offset = dissect_ber_octet_string(implicit_tag, actx, tree, tvb, offset, hf_index,
550 &next_tvb);
553 if(next_tvb) {
554 len = tvb_reported_length_remaining(next_tvb, 0);
555 if(len !=0){
556 /* 0 octets for the Unidirectional,
557 * 4 octets for Query, Response & Abort
558 * 8 octets for Conversation in the order Originating then Responding TID
560 * In order to match this it seems like we should only use the last 4 octets
561 * in the 8 octets case.
563 if (len > 4){
564 ansi_tcap_private.TransactionID_str = tvb_bytes_to_str(actx->pinfo->pool, next_tvb, 4,len-4);
565 }else{
566 ansi_tcap_private.TransactionID_str = tvb_bytes_to_str(actx->pinfo->pool, next_tvb, 0,len);
569 switch(len) {
570 case 1:
571 gp_tcapsrt_info->src_tid=tvb_get_uint8(next_tvb, 0);
572 break;
573 case 2:
574 gp_tcapsrt_info->src_tid=tvb_get_ntohs(next_tvb, 0);
575 break;
576 case 4:
577 gp_tcapsrt_info->src_tid=tvb_get_ntohl(next_tvb, 0);
578 break;
579 default:
580 gp_tcapsrt_info->src_tid=0;
581 break;
586 return offset;
591 static int
592 dissect_ansi_tcap_TransactionID(bool implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
593 offset = dissect_ber_tagged_type(implicit_tag, actx, tree, tvb, offset,
594 hf_index, BER_CLASS_PRI, 7, true, dissect_ansi_tcap_TransactionID_U);
596 return offset;
601 static int
602 dissect_ansi_tcap_OCTET_STRING_SIZE_1(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_octet_string(implicit_tag, actx, tree, tvb, offset, hf_index,
604 NULL);
606 return offset;
611 static int
612 dissect_ansi_tcap_ProtocolVersion(bool implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
613 offset = dissect_ber_tagged_type(implicit_tag, actx, tree, tvb, offset,
614 hf_index, BER_CLASS_PRI, 26, true, dissect_ansi_tcap_OCTET_STRING_SIZE_1);
616 return offset;
621 static int
622 dissect_ansi_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_) {
623 offset = dissect_ber_integer(implicit_tag, actx, tree, tvb, offset, hf_index,
624 NULL);
626 return offset;
631 static int
632 dissect_ansi_tcap_IntegerApplicationContext(bool implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
633 offset = dissect_ber_tagged_type(implicit_tag, actx, tree, tvb, offset,
634 hf_index, BER_CLASS_PRI, 27, true, dissect_ansi_tcap_INTEGER);
636 return offset;
641 static int
642 dissect_ansi_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_) {
643 offset = dissect_ber_object_identifier(implicit_tag, actx, tree, tvb, offset, hf_index, NULL);
645 return offset;
650 static int
651 dissect_ansi_tcap_ObjectIDApplicationContext(bool implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
653 static const char * oid_str;
655 offset = dissect_ber_tagged_type(implicit_tag, actx, tree, tvb, offset,
656 hf_index, BER_CLASS_PRI, 28, true, dissect_ansi_tcap_OBJECT_IDENTIFIER);
658 ansi_tcap_private.objectApplicationId_oid= (const void*) oid_str;
659 ansi_tcap_private.oid_is_present=true;
662 return offset;
666 static const value_string ansi_tcap_T_applicationContext_vals[] = {
667 { 27, "integerApplicationId" },
668 { 28, "objectApplicationId" },
669 { 0, NULL }
672 static const ber_choice_t T_applicationContext_choice[] = {
673 { 27, &hf_ansi_tcap_integerApplicationId, BER_CLASS_PRI, 27, BER_FLAGS_NOOWNTAG, dissect_ansi_tcap_IntegerApplicationContext },
674 { 28, &hf_ansi_tcap_objectApplicationId, BER_CLASS_PRI, 28, BER_FLAGS_NOOWNTAG, dissect_ansi_tcap_ObjectIDApplicationContext },
675 { 0, NULL, 0, 0, 0, NULL }
678 static int
679 dissect_ansi_tcap_T_applicationContext(bool implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
680 offset = dissect_ber_choice(actx, tree, tvb, offset,
681 T_applicationContext_choice, hf_index, ett_ansi_tcap_T_applicationContext,
682 NULL);
684 return offset;
689 static int
690 dissect_ansi_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_) {
691 offset = dissect_ber_external_type(implicit_tag, tree, tvb, offset, actx, hf_index, NULL);
693 return offset;
697 static const ber_sequence_t UserInformation_U_sequence_of[1] = {
698 { &hf_ansi_tcap__untag_item, BER_CLASS_UNI, BER_UNI_TAG_EXTERNAL, BER_FLAGS_NOOWNTAG, dissect_ansi_tcap_EXTERNAL },
701 static int
702 dissect_ansi_tcap_UserInformation_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_) {
703 offset = dissect_ber_sequence_of(implicit_tag, actx, tree, tvb, offset,
704 UserInformation_U_sequence_of, hf_index, ett_ansi_tcap_UserInformation_U);
706 return offset;
711 static int
712 dissect_ansi_tcap_UserInformation(bool implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
713 offset = dissect_ber_tagged_type(implicit_tag, actx, tree, tvb, offset,
714 hf_index, BER_CLASS_PRI, 29, true, dissect_ansi_tcap_UserInformation_U);
716 return offset;
720 static const value_string ansi_tcap_T_securityContext_vals[] = {
721 { 0, "integerSecurityId" },
722 { 1, "objectSecurityId" },
723 { 0, NULL }
726 static const ber_choice_t T_securityContext_choice[] = {
727 { 0, &hf_ansi_tcap_integerSecurityId, BER_CLASS_CON, 0, BER_FLAGS_IMPLTAG, dissect_ansi_tcap_INTEGER },
728 { 1, &hf_ansi_tcap_objectSecurityId, BER_CLASS_CON, 1, BER_FLAGS_IMPLTAG, dissect_ansi_tcap_OBJECT_IDENTIFIER },
729 { 0, NULL, 0, 0, 0, NULL }
732 static int
733 dissect_ansi_tcap_T_securityContext(bool implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
734 offset = dissect_ber_choice(actx, tree, tvb, offset,
735 T_securityContext_choice, hf_index, ett_ansi_tcap_T_securityContext,
736 NULL);
738 return offset;
742 static const value_string ansi_tcap_T_confidentialityId_vals[] = {
743 { 0, "integerConfidentialityId" },
744 { 1, "objectConfidentialityId" },
745 { 0, NULL }
748 static const ber_choice_t T_confidentialityId_choice[] = {
749 { 0, &hf_ansi_tcap_integerConfidentialityId, BER_CLASS_CON, 0, BER_FLAGS_IMPLTAG, dissect_ansi_tcap_INTEGER },
750 { 1, &hf_ansi_tcap_objectConfidentialityId, BER_CLASS_CON, 1, BER_FLAGS_IMPLTAG, dissect_ansi_tcap_OBJECT_IDENTIFIER },
751 { 0, NULL, 0, 0, 0, NULL }
754 static int
755 dissect_ansi_tcap_T_confidentialityId(bool implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
756 offset = dissect_ber_choice(actx, tree, tvb, offset,
757 T_confidentialityId_choice, hf_index, ett_ansi_tcap_T_confidentialityId,
758 NULL);
760 return offset;
764 static const ber_sequence_t Confidentiality_sequence[] = {
765 { &hf_ansi_tcap_confidentialityId, BER_CLASS_ANY/*choice*/, -1/*choice*/, BER_FLAGS_OPTIONAL|BER_FLAGS_NOOWNTAG|BER_FLAGS_NOTCHKTAG, dissect_ansi_tcap_T_confidentialityId },
766 { NULL, 0, 0, 0, NULL }
769 static int
770 dissect_ansi_tcap_Confidentiality(bool implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
771 offset = dissect_ber_sequence(implicit_tag, actx, tree, tvb, offset,
772 Confidentiality_sequence, hf_index, ett_ansi_tcap_Confidentiality);
774 return offset;
778 static const ber_sequence_t DialoguePortion_U_sequence[] = {
779 { &hf_ansi_tcap_version , BER_CLASS_PRI, 26, BER_FLAGS_OPTIONAL|BER_FLAGS_NOOWNTAG, dissect_ansi_tcap_ProtocolVersion },
780 { &hf_ansi_tcap_applicationContext, BER_CLASS_ANY/*choice*/, -1/*choice*/, BER_FLAGS_OPTIONAL|BER_FLAGS_NOOWNTAG|BER_FLAGS_NOTCHKTAG, dissect_ansi_tcap_T_applicationContext },
781 { &hf_ansi_tcap_userInformation, BER_CLASS_PRI, 29, BER_FLAGS_OPTIONAL|BER_FLAGS_NOOWNTAG, dissect_ansi_tcap_UserInformation },
782 { &hf_ansi_tcap_securityContext, BER_CLASS_ANY/*choice*/, -1/*choice*/, BER_FLAGS_OPTIONAL|BER_FLAGS_NOOWNTAG|BER_FLAGS_NOTCHKTAG, dissect_ansi_tcap_T_securityContext },
783 { &hf_ansi_tcap_confidentiality, BER_CLASS_CON, 2, BER_FLAGS_OPTIONAL|BER_FLAGS_IMPLTAG, dissect_ansi_tcap_Confidentiality },
784 { NULL, 0, 0, 0, NULL }
787 static int
788 dissect_ansi_tcap_DialoguePortion_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_) {
789 offset = dissect_ber_sequence(implicit_tag, actx, tree, tvb, offset,
790 DialoguePortion_U_sequence, hf_index, ett_ansi_tcap_DialoguePortion_U);
792 return offset;
797 static int
798 dissect_ansi_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_) {
799 offset = dissect_ber_tagged_type(implicit_tag, actx, tree, tvb, offset,
800 hf_index, BER_CLASS_PRI, 25, true, dissect_ansi_tcap_DialoguePortion_U);
802 return offset;
807 static int
808 dissect_ansi_tcap_T_componentIDs(bool implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
809 offset = dissect_ber_octet_string(implicit_tag, actx, tree, tvb, offset, hf_index,
810 NULL);
812 return offset;
817 static int
818 dissect_ansi_tcap_T_invoke_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_) {
820 if(find_tcap_subdissector(tvb, actx, tree))
821 offset = tvb_reported_length(tvb);
825 return offset;
829 static const ber_sequence_t Invoke_sequence[] = {
830 { &hf_ansi_tcap_componentIDs, BER_CLASS_PRI, 15, BER_FLAGS_OPTIONAL|BER_FLAGS_IMPLTAG, dissect_ansi_tcap_T_componentIDs },
831 { &hf_ansi_tcap_operationCode, BER_CLASS_ANY/*choice*/, -1/*choice*/, BER_FLAGS_NOOWNTAG|BER_FLAGS_NOTCHKTAG, dissect_ansi_tcap_OperationCode },
832 { &hf_ansi_tcap_invoke_parameter, BER_CLASS_ANY, 0, BER_FLAGS_OPTIONAL|BER_FLAGS_NOOWNTAG, dissect_ansi_tcap_T_invoke_parameter },
833 { NULL, 0, 0, 0, NULL }
836 static int
837 dissect_ansi_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_) {
838 ansi_tcap_private.d.pdu = 1;
841 offset = dissect_ber_sequence(implicit_tag, actx, tree, tvb, offset,
842 Invoke_sequence, hf_index, ett_ansi_tcap_Invoke);
844 return offset;
849 static int
850 dissect_ansi_tcap_T_componentID(bool implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
851 offset = dissect_ber_octet_string(implicit_tag, actx, tree, tvb, offset, hf_index,
852 NULL);
854 return offset;
859 static int
860 dissect_ansi_tcap_T_returnResult_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_) {
861 if(find_tcap_subdissector(tvb, actx, tree))
862 offset = tvb_reported_length(tvb);
865 return offset;
869 static const ber_sequence_t ReturnResult_sequence[] = {
870 { &hf_ansi_tcap_componentID, BER_CLASS_PRI, 15, BER_FLAGS_IMPLTAG, dissect_ansi_tcap_T_componentID },
871 { &hf_ansi_tcap_returnResult_parameter, BER_CLASS_ANY, 0, BER_FLAGS_OPTIONAL|BER_FLAGS_NOOWNTAG, dissect_ansi_tcap_T_returnResult_parameter },
872 { NULL, 0, 0, 0, NULL }
875 static int
876 dissect_ansi_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_) {
877 ansi_tcap_private.d.pdu = 2;
881 offset = dissect_ber_sequence(implicit_tag, actx, tree, tvb, offset,
882 ReturnResult_sequence, hf_index, ett_ansi_tcap_ReturnResult);
884 return offset;
889 static int
890 dissect_ansi_tcap_T_componentID_01(bool implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
891 offset = dissect_ber_octet_string(implicit_tag, actx, tree, tvb, offset, hf_index,
892 NULL);
894 return offset;
899 static int
900 dissect_ansi_tcap_T_returnError_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_) {
901 if(find_tcap_subdissector(tvb, actx, tree))
902 offset = tvb_reported_length(tvb);
905 return offset;
909 static const ber_sequence_t ReturnError_sequence[] = {
910 { &hf_ansi_tcap_componentID_01, BER_CLASS_PRI, 15, BER_FLAGS_IMPLTAG, dissect_ansi_tcap_T_componentID_01 },
911 { &hf_ansi_tcap_errorCode , BER_CLASS_ANY/*choice*/, -1/*choice*/, BER_FLAGS_NOOWNTAG|BER_FLAGS_NOTCHKTAG, dissect_ansi_tcap_ErrorCode },
912 { &hf_ansi_tcap_returnError_parameter, BER_CLASS_ANY, 0, BER_FLAGS_OPTIONAL|BER_FLAGS_NOOWNTAG, dissect_ansi_tcap_T_returnError_parameter },
913 { NULL, 0, 0, 0, NULL }
916 static int
917 dissect_ansi_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_) {
918 ansi_tcap_private.d.pdu = 3;
920 offset = dissect_ber_sequence(implicit_tag, actx, tree, tvb, offset,
921 ReturnError_sequence, hf_index, ett_ansi_tcap_ReturnError);
923 return offset;
928 static int
929 dissect_ansi_tcap_OCTET_STRING_SIZE_0_1(bool implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
930 offset = dissect_ber_octet_string(implicit_tag, actx, tree, tvb, offset, hf_index,
931 NULL);
933 return offset;
937 static const value_string ansi_tcap_Problem_vals[] = {
938 { 257, "general-unrecognisedComponentType" },
939 { 258, "general-incorrectComponentPortion" },
940 { 259, "general-badlyStructuredCompPortion" },
941 { 260, "general-incorrectComponentCoding" },
942 { 513, "invoke-duplicateInvocation" },
943 { 514, "invoke-unrecognisedOperation" },
944 { 515, "invoke-incorrectParameter" },
945 { 516, "invoke-unrecognisedCorrelationID" },
946 { 769, "returnResult-unrecognisedCorrelationID" },
947 { 770, "returnResult-unexpectedReturnResult" },
948 { 771, "returnResult-incorrectParameter" },
949 { 1025, "returnError-unrecognisedCorrelationID" },
950 { 1026, "returnError-unexpectedReturnError" },
951 { 1027, "returnError-unrecognisedError" },
952 { 1028, "returnError-unexpectedError" },
953 { 1029, "returnError-incorrectParameter" },
954 { 1281, "transaction-unrecognizedPackageType" },
955 { 1282, "transaction-incorrectTransPortion" },
956 { 1283, "transaction-badlyStructuredTransPortion" },
957 { 1284, "transaction-unassignedRespondingTransID" },
958 { 1285, "transaction-permissionToReleaseProblem" },
959 { 1286, "transaction-resourceUnavailable" },
960 { 0, NULL }
964 static int
965 dissect_ansi_tcap_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_) {
966 offset = dissect_ber_integer(implicit_tag, actx, tree, tvb, offset, hf_index,
967 NULL);
969 return offset;
973 static const ber_sequence_t T_paramSequence_sequence[] = {
974 { NULL, 0, 0, 0, NULL }
977 static int
978 dissect_ansi_tcap_T_paramSequence(bool implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
979 offset = dissect_ber_sequence(implicit_tag, actx, tree, tvb, offset,
980 T_paramSequence_sequence, hf_index, ett_ansi_tcap_T_paramSequence);
982 return offset;
986 static const ber_sequence_t T_paramSet_set[] = {
987 { NULL, 0, 0, 0, NULL }
990 static int
991 dissect_ansi_tcap_T_paramSet(bool implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
992 offset = dissect_ber_set(implicit_tag, actx, tree, tvb, offset,
993 T_paramSet_set, hf_index, ett_ansi_tcap_T_paramSet);
995 return offset;
999 static const value_string ansi_tcap_T_reject_parameter_vals[] = {
1000 { 16, "paramSequence" },
1001 { 18, "paramSet" },
1002 { 0, NULL }
1005 static const ber_choice_t T_reject_parameter_choice[] = {
1006 { 16, &hf_ansi_tcap_paramSequence, BER_CLASS_PRI, 16, BER_FLAGS_IMPLTAG, dissect_ansi_tcap_T_paramSequence },
1007 { 18, &hf_ansi_tcap_paramSet , BER_CLASS_PRI, 18, BER_FLAGS_IMPLTAG, dissect_ansi_tcap_T_paramSet },
1008 { 0, NULL, 0, 0, 0, NULL }
1011 static int
1012 dissect_ansi_tcap_T_reject_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_) {
1013 offset = dissect_ber_choice(actx, tree, tvb, offset,
1014 T_reject_parameter_choice, hf_index, ett_ansi_tcap_T_reject_parameter,
1015 NULL);
1017 return offset;
1021 static const ber_sequence_t Reject_sequence[] = {
1022 { &hf_ansi_tcap_componentID_02, BER_CLASS_PRI, 15, BER_FLAGS_IMPLTAG, dissect_ansi_tcap_OCTET_STRING_SIZE_0_1 },
1023 { &hf_ansi_tcap_rejectProblem, BER_CLASS_PRI, 21, BER_FLAGS_IMPLTAG, dissect_ansi_tcap_Problem },
1024 { &hf_ansi_tcap_reject_parameter, BER_CLASS_ANY/*choice*/, -1/*choice*/, BER_FLAGS_NOOWNTAG|BER_FLAGS_NOTCHKTAG, dissect_ansi_tcap_T_reject_parameter },
1025 { NULL, 0, 0, 0, NULL }
1028 static int
1029 dissect_ansi_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_) {
1030 offset = dissect_ber_sequence(implicit_tag, actx, tree, tvb, offset,
1031 Reject_sequence, hf_index, ett_ansi_tcap_Reject);
1033 return offset;
1037 static const value_string ansi_tcap_ComponentPDU_vals[] = {
1038 { 9, "invokeLast" },
1039 { 10, "returnResultLast" },
1040 { 11, "returnError" },
1041 { 12, "reject" },
1042 { 13, "invokeNotLast" },
1043 { 14, "returnResultNotLast" },
1044 { 0, NULL }
1047 static const ber_choice_t ComponentPDU_choice[] = {
1048 { 9, &hf_ansi_tcap_invokeLast, BER_CLASS_PRI, 9, BER_FLAGS_IMPLTAG, dissect_ansi_tcap_Invoke },
1049 { 10, &hf_ansi_tcap_returnResultLast, BER_CLASS_PRI, 10, BER_FLAGS_IMPLTAG, dissect_ansi_tcap_ReturnResult },
1050 { 11, &hf_ansi_tcap_returnError, BER_CLASS_PRI, 11, BER_FLAGS_IMPLTAG, dissect_ansi_tcap_ReturnError },
1051 { 12, &hf_ansi_tcap_reject , BER_CLASS_PRI, 12, BER_FLAGS_IMPLTAG, dissect_ansi_tcap_Reject },
1052 { 13, &hf_ansi_tcap_invokeNotLast, BER_CLASS_PRI, 13, BER_FLAGS_IMPLTAG, dissect_ansi_tcap_Invoke },
1053 { 14, &hf_ansi_tcap_returnResultNotLast, BER_CLASS_PRI, 14, BER_FLAGS_IMPLTAG, dissect_ansi_tcap_ReturnResult },
1054 { 0, NULL, 0, 0, 0, NULL }
1057 static int
1058 dissect_ansi_tcap_ComponentPDU(bool implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
1059 offset = dissect_ber_choice(actx, tree, tvb, offset,
1060 ComponentPDU_choice, hf_index, ett_ansi_tcap_ComponentPDU,
1061 NULL);
1063 return offset;
1067 static const ber_sequence_t SEQUENCE_OF_ComponentPDU_sequence_of[1] = {
1068 { &hf_ansi_tcap__untag_item_01, BER_CLASS_ANY/*choice*/, -1/*choice*/, BER_FLAGS_NOOWNTAG|BER_FLAGS_NOTCHKTAG, dissect_ansi_tcap_ComponentPDU },
1071 static int
1072 dissect_ansi_tcap_SEQUENCE_OF_ComponentPDU(bool implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
1073 offset = dissect_ber_sequence_of(implicit_tag, actx, tree, tvb, offset,
1074 SEQUENCE_OF_ComponentPDU_sequence_of, hf_index, ett_ansi_tcap_SEQUENCE_OF_ComponentPDU);
1076 return offset;
1081 static int
1082 dissect_ansi_tcap_ComponentSequence(bool implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
1083 offset = dissect_ber_tagged_type(implicit_tag, actx, tree, tvb, offset,
1084 hf_index, BER_CLASS_PRI, 8, true, dissect_ansi_tcap_SEQUENCE_OF_ComponentPDU);
1086 return offset;
1090 static const ber_sequence_t UniTransactionPDU_sequence[] = {
1091 { &hf_ansi_tcap_identifier, BER_CLASS_PRI, 7, BER_FLAGS_NOOWNTAG, dissect_ansi_tcap_TransactionID },
1092 { &hf_ansi_tcap_dialoguePortion, BER_CLASS_PRI, 25, BER_FLAGS_OPTIONAL|BER_FLAGS_NOOWNTAG, dissect_ansi_tcap_DialoguePortion },
1093 { &hf_ansi_tcap_componentPortion, BER_CLASS_PRI, 8, BER_FLAGS_NOOWNTAG, dissect_ansi_tcap_ComponentSequence },
1094 { NULL, 0, 0, 0, NULL }
1097 static int
1098 dissect_ansi_tcap_UniTransactionPDU(bool implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
1099 offset = dissect_ber_sequence(implicit_tag, actx, tree, tvb, offset,
1100 UniTransactionPDU_sequence, hf_index, ett_ansi_tcap_UniTransactionPDU);
1102 return offset;
1107 static int
1108 dissect_ansi_tcap_T_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_) {
1109 gp_tcapsrt_info->ope=TC_ANSI_ALL;
1110 col_set_str(actx->pinfo->cinfo, COL_INFO, "unidirectional ");
1112 offset = dissect_ansi_tcap_UniTransactionPDU(implicit_tag, tvb, offset, actx, tree, hf_index);
1114 return offset;
1118 static const ber_sequence_t TransactionPDU_sequence[] = {
1119 { &hf_ansi_tcap_identifier, BER_CLASS_PRI, 7, BER_FLAGS_NOOWNTAG, dissect_ansi_tcap_TransactionID },
1120 { &hf_ansi_tcap_dialoguePortion, BER_CLASS_PRI, 25, BER_FLAGS_OPTIONAL|BER_FLAGS_NOOWNTAG, dissect_ansi_tcap_DialoguePortion },
1121 { &hf_ansi_tcap_componentPortion, BER_CLASS_PRI, 8, BER_FLAGS_OPTIONAL|BER_FLAGS_NOOWNTAG, dissect_ansi_tcap_ComponentSequence },
1122 { NULL, 0, 0, 0, NULL }
1125 static int
1126 dissect_ansi_tcap_TransactionPDU(bool implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
1127 offset = dissect_ber_sequence(implicit_tag, actx, tree, tvb, offset,
1128 TransactionPDU_sequence, hf_index, ett_ansi_tcap_TransactionPDU);
1130 return offset;
1135 static int
1136 dissect_ansi_tcap_T_queryWithPerm(bool implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
1137 gp_tcapsrt_info->ope=TC_ANSI_ALL;
1138 col_set_str(actx->pinfo->cinfo, COL_INFO, "queryWithPerm ");
1140 offset = dissect_ansi_tcap_TransactionPDU(implicit_tag, tvb, offset, actx, tree, hf_index);
1142 return offset;
1147 static int
1148 dissect_ansi_tcap_T_queryWithoutPerm(bool implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
1149 gp_tcapsrt_info->ope=TC_ANSI_ALL;
1150 col_set_str(actx->pinfo->cinfo, COL_INFO, "queryWithoutPerm ");
1152 offset = dissect_ansi_tcap_TransactionPDU(implicit_tag, tvb, offset, actx, tree, hf_index);
1154 return offset;
1159 static int
1160 dissect_ansi_tcap_T_response(bool implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
1161 gp_tcapsrt_info->ope=TC_ANSI_ALL;
1162 col_set_str(actx->pinfo->cinfo, COL_INFO, "response ");
1164 offset = dissect_ansi_tcap_TransactionPDU(implicit_tag, tvb, offset, actx, tree, hf_index);
1166 return offset;
1171 static int
1172 dissect_ansi_tcap_T_conversationWithPerm(bool implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
1173 gp_tcapsrt_info->ope=TC_ANSI_ALL;
1174 col_set_str(actx->pinfo->cinfo, COL_INFO, "conversationWithPerm ");
1176 offset = dissect_ansi_tcap_TransactionPDU(implicit_tag, tvb, offset, actx, tree, hf_index);
1178 return offset;
1183 static int
1184 dissect_ansi_tcap_T_conversationWithoutPerm(bool implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
1185 gp_tcapsrt_info->ope=TC_ANSI_ALL;
1186 col_set_str(actx->pinfo->cinfo, COL_INFO, "conversationWithoutPerm ");
1188 offset = dissect_ansi_tcap_TransactionPDU(implicit_tag, tvb, offset, actx, tree, hf_index);
1190 return offset;
1194 static const value_string ansi_tcap_P_Abort_cause_U_vals[] = {
1195 { 1, "unrecognizedPackageType" },
1196 { 2, "incorrectTransactionPortion" },
1197 { 3, "badlyStructuredTransactionPortion" },
1198 { 4, "unassignedRespondingTransactionID" },
1199 { 5, "permissionToReleaseProblem" },
1200 { 6, "resourceUnavailable" },
1201 { 7, "unrecognizedDialoguePortionID" },
1202 { 8, "badlyStructuredDialoguePortion" },
1203 { 9, "missingDialoguePortion" },
1204 { 10, "inconsistentDialoguePortion" },
1205 { 0, NULL }
1209 static int
1210 dissect_ansi_tcap_P_Abort_cause_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_) {
1211 offset = dissect_ber_integer(implicit_tag, actx, tree, tvb, offset, hf_index,
1212 NULL);
1214 return offset;
1219 static int
1220 dissect_ansi_tcap_P_Abort_cause(bool implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
1221 offset = dissect_ber_tagged_type(implicit_tag, actx, tree, tvb, offset,
1222 hf_index, BER_CLASS_PRI, 23, true, dissect_ansi_tcap_P_Abort_cause_U);
1224 return offset;
1229 static int
1230 dissect_ansi_tcap_UserAbortInformation(bool implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
1231 offset = dissect_ber_tagged_type(implicit_tag, actx, tree, tvb, offset,
1232 hf_index, BER_CLASS_PRI, 24, false, dissect_ansi_tcap_EXTERNAL);
1234 return offset;
1238 static const value_string ansi_tcap_T_causeInformation_vals[] = {
1239 { 23, "abortCause" },
1240 { 24, "userInformation" },
1241 { 0, NULL }
1244 static const ber_choice_t T_causeInformation_choice[] = {
1245 { 23, &hf_ansi_tcap_abortCause, BER_CLASS_PRI, 23, BER_FLAGS_NOOWNTAG, dissect_ansi_tcap_P_Abort_cause },
1246 { 24, &hf_ansi_tcap_abort_userInformation, BER_CLASS_PRI, 24, BER_FLAGS_NOOWNTAG, dissect_ansi_tcap_UserAbortInformation },
1247 { 0, NULL, 0, 0, 0, NULL }
1250 static int
1251 dissect_ansi_tcap_T_causeInformation(bool implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
1252 offset = dissect_ber_choice(actx, tree, tvb, offset,
1253 T_causeInformation_choice, hf_index, ett_ansi_tcap_T_causeInformation,
1254 NULL);
1256 return offset;
1260 static const ber_sequence_t Abort_sequence[] = {
1261 { &hf_ansi_tcap_identifier, BER_CLASS_PRI, 7, BER_FLAGS_NOOWNTAG, dissect_ansi_tcap_TransactionID },
1262 { &hf_ansi_tcap_dialogPortion, BER_CLASS_PRI, 25, BER_FLAGS_OPTIONAL|BER_FLAGS_NOOWNTAG, dissect_ansi_tcap_DialoguePortion },
1263 { &hf_ansi_tcap_causeInformation, BER_CLASS_ANY/*choice*/, -1/*choice*/, BER_FLAGS_NOOWNTAG|BER_FLAGS_NOTCHKTAG, dissect_ansi_tcap_T_causeInformation },
1264 { NULL, 0, 0, 0, NULL }
1267 static int
1268 dissect_ansi_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_) {
1269 offset = dissect_ber_sequence(implicit_tag, actx, tree, tvb, offset,
1270 Abort_sequence, hf_index, ett_ansi_tcap_Abort);
1272 return offset;
1277 static int
1278 dissect_ansi_tcap_T_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_) {
1279 gp_tcapsrt_info->ope=TC_ANSI_ABORT;
1280 col_set_str(actx->pinfo->cinfo, COL_INFO, "Abort ");
1282 offset = dissect_ansi_tcap_Abort(implicit_tag, tvb, offset, actx, tree, hf_index);
1284 return offset;
1288 static const ber_choice_t PackageType_choice[] = {
1289 { 1, &hf_ansi_tcap_unidirectional, BER_CLASS_PRI, 1, BER_FLAGS_IMPLTAG, dissect_ansi_tcap_T_unidirectional },
1290 { 2, &hf_ansi_tcap_queryWithPerm, BER_CLASS_PRI, 2, BER_FLAGS_IMPLTAG, dissect_ansi_tcap_T_queryWithPerm },
1291 { 3, &hf_ansi_tcap_queryWithoutPerm, BER_CLASS_PRI, 3, BER_FLAGS_IMPLTAG, dissect_ansi_tcap_T_queryWithoutPerm },
1292 { 4, &hf_ansi_tcap_response , BER_CLASS_PRI, 4, BER_FLAGS_IMPLTAG, dissect_ansi_tcap_T_response },
1293 { 5, &hf_ansi_tcap_conversationWithPerm, BER_CLASS_PRI, 5, BER_FLAGS_IMPLTAG, dissect_ansi_tcap_T_conversationWithPerm },
1294 { 6, &hf_ansi_tcap_conversationWithoutPerm, BER_CLASS_PRI, 6, BER_FLAGS_IMPLTAG, dissect_ansi_tcap_T_conversationWithoutPerm },
1295 { 22, &hf_ansi_tcap_abort , BER_CLASS_PRI, 22, BER_FLAGS_IMPLTAG, dissect_ansi_tcap_T_abort },
1296 { 0, NULL, 0, 0, 0, NULL }
1299 static int
1300 dissect_ansi_tcap_PackageType(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_choice(actx, tree, tvb, offset,
1302 PackageType_choice, hf_index, ett_ansi_tcap_PackageType,
1303 NULL);
1305 return offset;
1312 static int
1313 dissect_ansi_tcap(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, void* data _U_)
1315 proto_item *item=NULL;
1316 proto_tree *tree=NULL;
1317 #if 0
1318 proto_item *stat_item=NULL;
1319 proto_tree *stat_tree=NULL;
1320 int offset = 0;
1321 struct tcaphash_context_t * p_tcap_context;
1322 dissector_handle_t subdissector_handle;
1323 #endif
1324 asn1_ctx_t asn1_ctx;
1326 asn1_ctx_init(&asn1_ctx, ASN1_ENC_BER, true, pinfo);
1327 ansi_tcap_ctx_init(&ansi_tcap_private);
1329 asn1_ctx.subtree.top_tree = parent_tree;
1330 col_set_str(pinfo->cinfo, COL_PROTOCOL, "ANSI TCAP");
1332 /* create display subtree for the protocol */
1333 if(parent_tree){
1334 item = proto_tree_add_item(parent_tree, proto_ansi_tcap, tvb, 0, -1, ENC_NA);
1335 tree = proto_item_add_subtree(item, ett_tcap);
1337 cur_oid = NULL;
1338 tcapext_oid = NULL;
1340 gp_tcapsrt_info=tcapsrt_razinfo();
1341 tcap_subdissector_used=false;
1342 gp_tcap_context=NULL;
1343 dissect_ansi_tcap_PackageType(false, tvb, 0, &asn1_ctx, tree, -1);
1345 #if 0 /* Skip this part for now it will be rewritten */
1346 if (g_ansi_tcap_HandleSRT && !tcap_subdissector_used ) {
1347 if (gtcap_DisplaySRT && tree) {
1348 stat_tree = proto_tree_add_subtree(tree, tvb, 0, 0, ett_ansi_tcap_stat, &stat_item, "Stat");
1349 proto_item_set_generated(stat_item);
1351 p_tcap_context=tcapsrt_call_matching(tvb, pinfo, stat_tree, gp_tcapsrt_info);
1352 ansi_tcap_private.context=p_tcap_context;
1354 /* If the current message is TCAP only,
1355 * save the Application contexte name for the next messages
1357 if ( p_tcap_context && cur_oid && !p_tcap_context->oid_present ) {
1358 /* Save the application context and the sub dissector */
1359 (void) g_strlcpy(p_tcap_context->oid, cur_oid, sizeof(p_tcap_context->oid));
1360 if ( (subdissector_handle = dissector_get_string_handle(ber_oid_dissector_table, cur_oid)) ) {
1361 p_tcap_context->subdissector_handle=subdissector_handle;
1362 p_tcap_context->oid_present=true;
1365 if (g_ansi_tcap_HandleSRT && p_tcap_context && p_tcap_context->callback) {
1366 /* Callback function for the upper layer */
1367 (p_tcap_context->callback)(tvb, pinfo, stat_tree, p_tcap_context);
1370 #endif
1371 return tvb_captured_length(tvb);
1375 void
1376 proto_reg_handoff_ansi_tcap(void)
1378 ansi_map_handle = find_dissector_add_dependency("ansi_map", proto_ansi_tcap);
1379 ain_handle = find_dissector_add_dependency("ain", proto_ansi_tcap);
1380 ber_oid_dissector_table = find_dissector_table("ber.oid");
1385 void
1386 proto_register_ansi_tcap(void)
1388 module_t *ansi_tcap_module;
1391 /* Setup list of header fields See Section 1.6.1 for details*/
1392 static hf_register_info hf[] = {
1393 #if 0
1394 /* Tcap Service Response Time */
1395 { &hf_ansi_tcapsrt_SessionId,
1396 { "Session Id",
1397 "ansi_tcap.srt.session_id",
1398 FT_UINT32, BASE_DEC, NULL, 0x0,
1399 NULL, HFILL }
1401 { &hf_ansi_tcapsrt_BeginSession,
1402 { "Begin Session",
1403 "ansi_tcap.srt.begin",
1404 FT_FRAMENUM, BASE_NONE, NULL, 0x0,
1405 "SRT Begin of Session", HFILL }
1407 { &hf_ansi_tcapsrt_EndSession,
1408 { "End Session",
1409 "ansi_tcap.srt.end",
1410 FT_FRAMENUM, BASE_NONE, NULL, 0x0,
1411 "SRT End of Session", HFILL }
1413 { &hf_ansi_tcapsrt_SessionTime,
1414 { "Session duration",
1415 "ansi_tcap.srt.sessiontime",
1416 FT_RELATIVE_TIME, BASE_NONE, NULL, 0x0,
1417 "Duration of the TCAP session", HFILL }
1419 { &hf_ansi_tcapsrt_Duplicate,
1420 { "Request Duplicate",
1421 "ansi_tcap.srt.duplicate",
1422 FT_UINT32, BASE_DEC, NULL, 0x0,
1423 NULL, HFILL }
1425 #endif
1426 { &hf_ansi_tcap_bit_h,
1427 { "Require Reply", "ansi_tcap.req_rep",
1428 FT_BOOLEAN, 16, NULL, 0x8000,
1429 NULL, HFILL }
1431 { &hf_ansi_tcap_op_family,
1432 { "Family",
1433 "ansi_tcap.op_family",
1434 FT_UINT16, BASE_DEC, VALS(ansi_tcap_national_op_code_family_vals), 0x7f00,
1435 NULL, HFILL }
1437 { &hf_ansi_tcap_op_specifier,
1438 { "Specifier",
1439 "ansi_tcap.op_specifier",
1440 FT_UINT16, BASE_DEC, NULL, 0x00ff,
1441 NULL, HFILL }
1443 { &hf_ansi_tcap_national,
1444 { "national", "ansi_tcap.national",
1445 FT_INT32, BASE_DEC, NULL, 0,
1446 NULL, HFILL }},
1447 { &hf_ansi_tcap_private,
1448 { "private", "ansi_tcap.private",
1449 FT_INT32, BASE_DEC, NULL, 0,
1450 NULL, HFILL }},
1451 { &hf_ansi_tcap_national_01,
1452 { "national", "ansi_tcap.national",
1453 FT_INT32, BASE_DEC, NULL, 0,
1454 "INTEGER_M128_127", HFILL }},
1455 { &hf_ansi_tcap_ec_private,
1456 { "private", "ansi_tcap.ec_private",
1457 FT_UINT32, BASE_DEC, VALS(ansi_tcap_ANSIMAPPrivateErrorcode_vals), 0,
1458 "ANSIMAPPrivateErrorcode", HFILL }},
1459 { &hf_ansi_tcap_unidirectional,
1460 { "unidirectional", "ansi_tcap.unidirectional_element",
1461 FT_NONE, BASE_NONE, NULL, 0,
1462 NULL, HFILL }},
1463 { &hf_ansi_tcap_queryWithPerm,
1464 { "queryWithPerm", "ansi_tcap.queryWithPerm_element",
1465 FT_NONE, BASE_NONE, NULL, 0,
1466 NULL, HFILL }},
1467 { &hf_ansi_tcap_queryWithoutPerm,
1468 { "queryWithoutPerm", "ansi_tcap.queryWithoutPerm_element",
1469 FT_NONE, BASE_NONE, NULL, 0,
1470 NULL, HFILL }},
1471 { &hf_ansi_tcap_response,
1472 { "response", "ansi_tcap.response_element",
1473 FT_NONE, BASE_NONE, NULL, 0,
1474 NULL, HFILL }},
1475 { &hf_ansi_tcap_conversationWithPerm,
1476 { "conversationWithPerm", "ansi_tcap.conversationWithPerm_element",
1477 FT_NONE, BASE_NONE, NULL, 0,
1478 NULL, HFILL }},
1479 { &hf_ansi_tcap_conversationWithoutPerm,
1480 { "conversationWithoutPerm", "ansi_tcap.conversationWithoutPerm_element",
1481 FT_NONE, BASE_NONE, NULL, 0,
1482 NULL, HFILL }},
1483 { &hf_ansi_tcap_abort,
1484 { "abort", "ansi_tcap.abort_element",
1485 FT_NONE, BASE_NONE, NULL, 0,
1486 NULL, HFILL }},
1487 { &hf_ansi_tcap_identifier,
1488 { "identifier", "ansi_tcap.identifier",
1489 FT_BYTES, BASE_NONE, NULL, 0,
1490 "TransactionID", HFILL }},
1491 { &hf_ansi_tcap_dialoguePortion,
1492 { "dialoguePortion", "ansi_tcap.dialoguePortion_element",
1493 FT_NONE, BASE_NONE, NULL, 0,
1494 NULL, HFILL }},
1495 { &hf_ansi_tcap_componentPortion,
1496 { "componentPortion", "ansi_tcap.componentPortion",
1497 FT_UINT32, BASE_DEC, NULL, 0,
1498 "ComponentSequence", HFILL }},
1499 { &hf_ansi_tcap_dialogPortion,
1500 { "dialogPortion", "ansi_tcap.dialogPortion_element",
1501 FT_NONE, BASE_NONE, NULL, 0,
1502 "DialoguePortion", HFILL }},
1503 { &hf_ansi_tcap_causeInformation,
1504 { "causeInformation", "ansi_tcap.causeInformation",
1505 FT_UINT32, BASE_DEC, VALS(ansi_tcap_T_causeInformation_vals), 0,
1506 NULL, HFILL }},
1507 { &hf_ansi_tcap_abortCause,
1508 { "abortCause", "ansi_tcap.abortCause",
1509 FT_INT32, BASE_DEC, VALS(ansi_tcap_P_Abort_cause_U_vals), 0,
1510 "P_Abort_cause", HFILL }},
1511 { &hf_ansi_tcap_abort_userInformation,
1512 { "userInformation", "ansi_tcap.userInformation_element",
1513 FT_NONE, BASE_NONE, NULL, 0,
1514 "UserAbortInformation", HFILL }},
1515 { &hf_ansi_tcap_version,
1516 { "version", "ansi_tcap.version",
1517 FT_BYTES, BASE_NONE, NULL, 0,
1518 "ProtocolVersion", HFILL }},
1519 { &hf_ansi_tcap_applicationContext,
1520 { "applicationContext", "ansi_tcap.applicationContext",
1521 FT_UINT32, BASE_DEC, VALS(ansi_tcap_T_applicationContext_vals), 0,
1522 NULL, HFILL }},
1523 { &hf_ansi_tcap_integerApplicationId,
1524 { "integerApplicationId", "ansi_tcap.integerApplicationId",
1525 FT_INT32, BASE_DEC, NULL, 0,
1526 "IntegerApplicationContext", HFILL }},
1527 { &hf_ansi_tcap_objectApplicationId,
1528 { "objectApplicationId", "ansi_tcap.objectApplicationId",
1529 FT_OID, BASE_NONE, NULL, 0,
1530 "ObjectIDApplicationContext", HFILL }},
1531 { &hf_ansi_tcap_userInformation,
1532 { "userInformation", "ansi_tcap.userInformation",
1533 FT_UINT32, BASE_DEC, NULL, 0,
1534 NULL, HFILL }},
1535 { &hf_ansi_tcap_securityContext,
1536 { "securityContext", "ansi_tcap.securityContext",
1537 FT_UINT32, BASE_DEC, VALS(ansi_tcap_T_securityContext_vals), 0,
1538 NULL, HFILL }},
1539 { &hf_ansi_tcap_integerSecurityId,
1540 { "integerSecurityId", "ansi_tcap.integerSecurityId",
1541 FT_INT32, BASE_DEC, NULL, 0,
1542 "INTEGER", HFILL }},
1543 { &hf_ansi_tcap_objectSecurityId,
1544 { "objectSecurityId", "ansi_tcap.objectSecurityId",
1545 FT_OID, BASE_NONE, NULL, 0,
1546 "OBJECT_IDENTIFIER", HFILL }},
1547 { &hf_ansi_tcap_confidentiality,
1548 { "confidentiality", "ansi_tcap.confidentiality_element",
1549 FT_NONE, BASE_NONE, NULL, 0,
1550 NULL, HFILL }},
1551 { &hf_ansi_tcap__untag_item,
1552 { "_untag item", "ansi_tcap._untag_item_element",
1553 FT_NONE, BASE_NONE, NULL, 0,
1554 "EXTERNAL", HFILL }},
1555 { &hf_ansi_tcap_confidentialityId,
1556 { "confidentialityId", "ansi_tcap.confidentialityId",
1557 FT_UINT32, BASE_DEC, VALS(ansi_tcap_T_confidentialityId_vals), 0,
1558 NULL, HFILL }},
1559 { &hf_ansi_tcap_integerConfidentialityId,
1560 { "integerConfidentialityId", "ansi_tcap.integerConfidentialityId",
1561 FT_INT32, BASE_DEC, NULL, 0,
1562 "INTEGER", HFILL }},
1563 { &hf_ansi_tcap_objectConfidentialityId,
1564 { "objectConfidentialityId", "ansi_tcap.objectConfidentialityId",
1565 FT_OID, BASE_NONE, NULL, 0,
1566 "OBJECT_IDENTIFIER", HFILL }},
1567 { &hf_ansi_tcap__untag_item_01,
1568 { "ComponentPDU", "ansi_tcap.ComponentPDU",
1569 FT_UINT32, BASE_DEC, VALS(ansi_tcap_ComponentPDU_vals), 0,
1570 NULL, HFILL }},
1571 { &hf_ansi_tcap_invokeLast,
1572 { "invokeLast", "ansi_tcap.invokeLast_element",
1573 FT_NONE, BASE_NONE, NULL, 0,
1574 "Invoke", HFILL }},
1575 { &hf_ansi_tcap_returnResultLast,
1576 { "returnResultLast", "ansi_tcap.returnResultLast_element",
1577 FT_NONE, BASE_NONE, NULL, 0,
1578 "ReturnResult", HFILL }},
1579 { &hf_ansi_tcap_returnError,
1580 { "returnError", "ansi_tcap.returnError_element",
1581 FT_NONE, BASE_NONE, NULL, 0,
1582 NULL, HFILL }},
1583 { &hf_ansi_tcap_reject,
1584 { "reject", "ansi_tcap.reject_element",
1585 FT_NONE, BASE_NONE, NULL, 0,
1586 NULL, HFILL }},
1587 { &hf_ansi_tcap_invokeNotLast,
1588 { "invokeNotLast", "ansi_tcap.invokeNotLast_element",
1589 FT_NONE, BASE_NONE, NULL, 0,
1590 "Invoke", HFILL }},
1591 { &hf_ansi_tcap_returnResultNotLast,
1592 { "returnResultNotLast", "ansi_tcap.returnResultNotLast_element",
1593 FT_NONE, BASE_NONE, NULL, 0,
1594 "ReturnResult", HFILL }},
1595 { &hf_ansi_tcap_componentIDs,
1596 { "componentIDs", "ansi_tcap.componentIDs",
1597 FT_BYTES, BASE_NONE, NULL, 0,
1598 NULL, HFILL }},
1599 { &hf_ansi_tcap_operationCode,
1600 { "operationCode", "ansi_tcap.operationCode",
1601 FT_UINT32, BASE_DEC, VALS(ansi_tcap_OperationCode_vals), 0,
1602 NULL, HFILL }},
1603 { &hf_ansi_tcap_invoke_parameter,
1604 { "parameter", "ansi_tcap.parameter_element",
1605 FT_NONE, BASE_NONE, NULL, 0,
1606 "T_invoke_parameter", HFILL }},
1607 { &hf_ansi_tcap_componentID,
1608 { "componentID", "ansi_tcap.componentID",
1609 FT_BYTES, BASE_NONE, NULL, 0,
1610 NULL, HFILL }},
1611 { &hf_ansi_tcap_returnResult_parameter,
1612 { "parameter", "ansi_tcap.parameter_element",
1613 FT_NONE, BASE_NONE, NULL, 0,
1614 "T_returnResult_parameter", HFILL }},
1615 { &hf_ansi_tcap_componentID_01,
1616 { "componentID", "ansi_tcap.componentID",
1617 FT_BYTES, BASE_NONE, NULL, 0,
1618 "T_componentID_01", HFILL }},
1619 { &hf_ansi_tcap_errorCode,
1620 { "errorCode", "ansi_tcap.errorCode",
1621 FT_UINT32, BASE_DEC, VALS(ansi_tcap_ErrorCode_vals), 0,
1622 NULL, HFILL }},
1623 { &hf_ansi_tcap_returnError_parameter,
1624 { "parameter", "ansi_tcap.parameter_element",
1625 FT_NONE, BASE_NONE, NULL, 0,
1626 "T_returnError_parameter", HFILL }},
1627 { &hf_ansi_tcap_componentID_02,
1628 { "componentID", "ansi_tcap.componentID",
1629 FT_BYTES, BASE_NONE, NULL, 0,
1630 "OCTET_STRING_SIZE_0_1", HFILL }},
1631 { &hf_ansi_tcap_rejectProblem,
1632 { "rejectProblem", "ansi_tcap.rejectProblem",
1633 FT_INT32, BASE_DEC, VALS(ansi_tcap_Problem_vals), 0,
1634 "Problem", HFILL }},
1635 { &hf_ansi_tcap_reject_parameter,
1636 { "parameter", "ansi_tcap.parameter",
1637 FT_UINT32, BASE_DEC, VALS(ansi_tcap_T_reject_parameter_vals), 0,
1638 "T_reject_parameter", HFILL }},
1639 { &hf_ansi_tcap_paramSequence,
1640 { "paramSequence", "ansi_tcap.paramSequence_element",
1641 FT_NONE, BASE_NONE, NULL, 0,
1642 NULL, HFILL }},
1643 { &hf_ansi_tcap_paramSet,
1644 { "paramSet", "ansi_tcap.paramSet_element",
1645 FT_NONE, BASE_NONE, NULL, 0,
1646 NULL, HFILL }},
1649 /* Setup protocol subtree array */
1650 static int *ett[] = {
1651 &ett_tcap,
1652 &ett_param,
1653 &ett_otid,
1654 &ett_dtid,
1655 &ett_ansi_tcap_stat,
1656 &ett_ansi_tcap_op_code_nat,
1657 &ett_ansi_tcap_OperationCode,
1658 &ett_ansi_tcap_ErrorCode,
1659 &ett_ansi_tcap_PackageType,
1660 &ett_ansi_tcap_UniTransactionPDU,
1661 &ett_ansi_tcap_TransactionPDU,
1662 &ett_ansi_tcap_Abort,
1663 &ett_ansi_tcap_T_causeInformation,
1664 &ett_ansi_tcap_DialoguePortion_U,
1665 &ett_ansi_tcap_T_applicationContext,
1666 &ett_ansi_tcap_T_securityContext,
1667 &ett_ansi_tcap_UserInformation_U,
1668 &ett_ansi_tcap_Confidentiality,
1669 &ett_ansi_tcap_T_confidentialityId,
1670 &ett_ansi_tcap_SEQUENCE_OF_ComponentPDU,
1671 &ett_ansi_tcap_ComponentPDU,
1672 &ett_ansi_tcap_Invoke,
1673 &ett_ansi_tcap_ReturnResult,
1674 &ett_ansi_tcap_ReturnError,
1675 &ett_ansi_tcap_Reject,
1676 &ett_ansi_tcap_T_reject_parameter,
1677 &ett_ansi_tcap_T_paramSequence,
1678 &ett_ansi_tcap_T_paramSet,
1681 static ei_register_info ei[] = {
1682 { &ei_ansi_tcap_dissector_not_implemented, { "ansi_tcap.dissector_not_implemented", PI_UNDECODED, PI_WARN, "Dissector not implemented", EXPFILL }},
1685 expert_module_t* expert_ansi_tcap;
1687 static const enum_val_t ansi_tcap_response_matching_type_values[] = {
1688 {"tid", "Transaction ID only", ANSI_TCAP_TID_ONLY},
1689 {"tid_source", "Transaction ID and Source", ANSI_TCAP_TID_AND_SOURCE},
1690 {"tid_source_dest", "Transaction ID Source and Destination", ANSI_TCAP_TID_SOURCE_AND_DEST},
1691 {NULL, NULL, -1}
1694 /* Register the protocol name and description */
1695 proto_ansi_tcap = proto_register_protocol(PNAME, PSNAME, PFNAME);
1696 register_dissector("ansi_tcap", dissect_ansi_tcap, proto_ansi_tcap);
1698 /* Note the high bit should be masked off when registering in this table (0x7fff)*/
1699 ansi_tcap_national_opcode_table = register_dissector_table("ansi_tcap.nat.opcode", "ANSI TCAP National Opcodes", proto_ansi_tcap, FT_UINT16, BASE_DEC);
1700 /* Required function calls to register the header fields and subtrees used */
1701 proto_register_field_array(proto_ansi_tcap, hf, array_length(hf));
1702 proto_register_subtree_array(ett, array_length(ett));
1703 expert_ansi_tcap = expert_register_protocol(proto_ansi_tcap);
1704 expert_register_field_array(expert_ansi_tcap, ei, array_length(ei));
1706 ansi_tcap_module = prefs_register_protocol(proto_ansi_tcap, proto_reg_handoff_ansi_tcap);
1708 prefs_register_enum_preference(ansi_tcap_module, "transaction.matchtype",
1709 "Type of matching invoke/response",
1710 "Type of matching invoke/response, risk of mismatch if loose matching chosen",
1711 &ansi_tcap_response_matching_type, ansi_tcap_response_matching_type_values, false);
1713 TransactionId_table = wmem_multimap_new_autoreset(wmem_epan_scope(), wmem_file_scope(), wmem_str_hash, g_str_equal);