2 * Routines for TCAP dissection
4 * Copyright 2000, Samuel Qu <samuel.qu [AT] utstar.com>,
6 * Michael Lum <mlum [AT] telostech.com>,
7 * Modified for ANSI TCAP support and many changes for
10 * (append your name here for newer version)
12 * $Id: packet-tcap.c,v 1.8 2004/03/05 10:05:03 guy Exp $
14 * Ethereal - Network traffic analyzer
15 * By Gerald Combs <gerald@ethereal.com>
16 * Copyright 1998 Gerald Combs
18 * Copied from WHATEVER_FILE_YOU_USED (where "WHATEVER_FILE_YOU_USED"
19 * is a dissector file; if you just copied this from README.developer,
20 * don't bother with the "Copied from" - you don't even need to put
21 * in a "Copied from" if you copied an existing dissector, especially
22 * if the bulk of the code in the new dissector is your code)
24 * This program is free software; you can redistribute it and/or
25 * modify it under the terms of the GNU General Public License
26 * as published by the Free Software Foundation; either version 2
27 * of the License, or (at your option) any later version.
29 * This program is distributed in the hope that it will be useful,
30 * but WITHOUT ANY WARRANTY; without even the implied warranty of
31 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
32 * GNU General Public License for more details.
34 * You should have received a copy of the GNU General Public License
35 * along with this program; if not, write to the Free Software
36 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
48 #ifdef HAVE_SYS_TYPES_H
49 # include <sys/types.h>
52 #ifdef HAVE_NETINET_IN_H
53 # include <netinet/in.h>
58 #ifdef NEED_SNPRINTF_H
59 # include "snprintf.h"
62 #include <epan/packet.h>
64 #include "packet-tcap.h"
67 Tcap_Standard_Type tcap_standard = ITU_TCAP_STANDARD;
70 static packet_info *g_pinfo = NULL;
71 static proto_tree *g_tcap_tree = NULL;
72 static gboolean g_tcap_ends_def_len = FALSE;
74 /* Initialize the protocol and registered fields */
75 static int proto_tcap = -1;
76 static int hf_tcap_message_type = -1;
77 static int hf_ansi_tcap_message_type = -1;
78 static int hf_tcap_tag = -1;
79 static int hf_tcap_length = -1;
80 static int hf_tcap_bytes = -1;
81 static int hf_tcap_app_con_name = -1;
82 static int hf_tcap_id = -1;
83 static int hf_tcap_tid = -1;
84 static int hf_tcap_ssn = -1; /* faked */
85 static int hf_tcap_dlg_type = -1;
86 static int hf_tcap_int = -1;
88 /* Initialize the subtree pointers */
89 static gint ett_tcap = -1;
91 static gint ett_otid = -1;
92 static gint ett_dtid = -1;
93 static gint ett_dlg_portion = -1;
94 static gint ett_dlg_req = -1;
95 static gint ett_dlg_rsp = -1;
96 static gint ett_dlg_abort = -1;
97 static gint ett_comps_portion = -1;
98 static gint ett_reason = -1;
99 static gint ett_component = -1;
100 static gint ett_problem = -1;
101 static gint ett_error = -1;
102 static gint ett_params = -1;
103 static gint ett_param = -1;
105 static dissector_handle_t data_handle;
106 static dissector_table_t tcap_itu_ssn_dissector_table; /* map use ssn in sccp */
107 static dissector_table_t tcap_ansi_ssn_dissector_table; /* map use ssn in sccp */
108 static gboolean lock_info_col = TRUE;
110 #define TC_SEQ_TAG 0x30
111 #define TC_SET_TAG 0x31
113 #define TC_EOC_LEN 2 /* 0x00 0x00 */
115 /* TCAP transaction message type definition - Samuel */
116 #define ST_MSG_TYP_UNI 0x61 /*0b01100001*/
117 #define ST_MSG_TYP_BGN 0x62 /*0b01100010*/
118 #define ST_MSG_TYP_CNT 0x65 /*0b01100101*/
119 #define ST_MSG_TYP_END 0x64 /*0b01100100*/
120 #define ST_MSG_TYP_PABT 0x67 /*0b01100111*/
121 static const value_string msg_type_strings[] = {
122 { ST_MSG_TYP_UNI, "TC-UNI" },
123 { ST_MSG_TYP_BGN, "TC-BEGIN" },
124 { ST_MSG_TYP_CNT, "TC-CONTINUE" },
125 { ST_MSG_TYP_END, "TC-END" },
126 { ST_MSG_TYP_PABT, "TC-PABORT" },
130 /* ANSI TCAP transaction message type definition */
131 #define ANSI_ST_MSG_TYP_UNI 0xe1
132 #define ANSI_ST_MSG_TYP_QWP 0xe2
133 #define ANSI_ST_MSG_TYP_QWOP 0xe3
134 #define ANSI_ST_MSG_TYP_RSP 0xe4
135 #define ANSI_ST_MSG_TYP_CWP 0xe5
136 #define ANSI_ST_MSG_TYP_CWOP 0xe6
137 #define ANSI_ST_MSG_TYP_ABT 0xf6
138 static const value_string ansi_msg_type_strings[] = {
139 { ANSI_ST_MSG_TYP_UNI, "TC-UNI" },
140 { ANSI_ST_MSG_TYP_QWP, "TC-QUERY W PERM" },
141 { ANSI_ST_MSG_TYP_QWOP, "TC-QUERY WO PERM" },
142 { ANSI_ST_MSG_TYP_RSP, "TC-RESPONSE" },
143 { ANSI_ST_MSG_TYP_CWP, "TC-CONV W PERM" },
144 { ANSI_ST_MSG_TYP_CWOP, "TC-CONV WO PERM" },
145 { ANSI_ST_MSG_TYP_ABT, "TC-ABORT" },
149 #define ST_ANSI_CMP_TAG 0xe8
150 #define ST_ANSI_TID_TAG 0xc7
152 /* TCAP TID tag value - Samuel */
153 #define ST_TID_SOURCE 0
154 #define ST_TID_DEST 1
155 #define ST_ITU_ORG_TID_TAG 0x48 /*0b01001000*/
156 #define ST_ITU_DST_TID_TAG 0x49 /*0b01001001*/
157 #define ST_ITU_PABT_TAG 0x4a /*0b01001010*/
158 #define ST_ITU_DLG_TAG 0x6b
159 #define ST_ITU_CMP_TAG 0x6c
161 static const value_string tid_strings[] = {
162 { ST_ITU_ORG_TID_TAG, "Source Transaction ID" },
163 { ST_ITU_DST_TID_TAG, "Destination Transaction ID" },
167 /* TCAP dialog type */
168 #define TC_DLG_REQ 0x60
169 #define TC_DLG_RSP 0x61
170 #define TC_DLG_ABRT 0x64
172 static const value_string dlg_type_strings[] = {
173 { TC_DLG_REQ , "Dialogue Request" },
174 { TC_DLG_RSP , "Dialogue Response" },
175 { TC_DLG_ABRT, "Dialogue Abort" },
179 /* TCAP component type */
180 #define TC_INVOKE 0xa1
183 #define TC_REJECT 0xa4
186 /* ANSI TCAP component type */
187 #define ANSI_TC_INVOKE_L 0xe9
188 #define ANSI_TC_RRL 0xea
189 #define ANSI_TC_RE 0xeb
190 #define ANSI_TC_REJECT 0xec
191 #define ANSI_TC_INVOKE_N 0xed
192 #define ANSI_TC_RRN 0xee
199 find_eoc(ASN1_SCK *asn1)
206 saved_offset = asn1->offset;
208 while (!asn1_eoc(asn1, -1))
210 asn1_id_decode1(asn1, &tag);
211 asn1_length_decode(asn1, &def_len, &len);
219 asn1->offset += find_eoc(asn1);
220 asn1_eoc_decode(asn1, -1);
224 len = asn1->offset - saved_offset;
225 asn1->offset = saved_offset;
232 dissect_tcap_len(ASN1_SCK *asn1, proto_tree *tree, gboolean *def_len, guint *len)
237 saved_offset = asn1->offset;
240 ret = asn1_length_decode(asn1, def_len, len);
244 proto_tree_add_uint(tree, hf_tcap_length, asn1->tvb, saved_offset, asn1->offset - saved_offset, *len);
248 proto_tree_add_text(tree, asn1->tvb,
249 saved_offset, asn1->offset - saved_offset, "Length: Indefinite");
256 dissect_tcap_eoc(ASN1_SCK *asn1, proto_tree *tree)
258 guint saved_offset, ret;
260 saved_offset = asn1->offset;
262 if (tvb_length_remaining(asn1->tvb, saved_offset) <= 0)
267 if (!asn1_eoc(asn1, -1))
272 ret = asn1_eoc_decode(asn1, -1);
274 proto_tree_add_text(tree, asn1->tvb,
275 saved_offset, asn1->offset - saved_offset, "End of Contents");
281 dissect_tcap_tag(ASN1_SCK *asn1, proto_tree *tree, guint *tag, gchar * str)
283 guint saved_offset, real_tag;
285 saved_offset = asn1->offset;
286 asn1_id_decode1(asn1, &real_tag);
287 if ((*tag != (guint) -1) && (real_tag != *tag))
289 asn1->offset = saved_offset;
292 proto_tree_add_uint_format(tree, hf_tcap_tag, asn1->tvb, saved_offset, asn1->offset - saved_offset,
298 dissect_tcap_octet(ASN1_SCK *asn1, proto_tree *tree, gchar * str)
303 saved_offset = asn1->offset;
304 asn1_octet_decode(asn1, &my_oct);
305 proto_tree_add_uint_format(tree, hf_tcap_id, asn1->tvb, saved_offset, asn1->offset - saved_offset,
306 my_oct, "%s %d", str, my_oct);
311 dissect_tcap_integer(ASN1_SCK *asn1, proto_tree *tree, guint len, gchar * str)
316 saved_offset = asn1->offset;
317 asn1_int32_value_decode(asn1, len, &invokeId);
318 proto_tree_add_int_format(tree, hf_tcap_int, asn1->tvb, saved_offset, asn1->offset - saved_offset,
319 invokeId, "%s %d", str, invokeId);
324 check_tcap_tag(ASN1_SCK *asn1, guint tag)
326 guint saved_offset, real_tag;
328 if (tvb_length_remaining(asn1->tvb, asn1->offset) <= 0)
333 saved_offset = asn1->offset;
334 asn1_id_decode1(asn1, &real_tag);
335 asn1->offset = saved_offset;
336 return (tag == real_tag);
341 dissect_tcap_tid(ASN1_SCK *asn1, proto_tree *tcap_tree, proto_item *ti, int type)
343 guint saved_offset, org_offset = 0;
347 proto_item *tid_item;
353 org_offset = asn1->offset;
354 if ( ST_TID_SOURCE == type)
356 tid_item = proto_tree_add_text(tcap_tree, asn1->tvb, asn1->offset, -1, "Source Transaction ID");
357 subtree = proto_item_add_subtree(tid_item, ett_otid);
361 tid_item = proto_tree_add_text(tcap_tree, asn1->tvb, asn1->offset, -1, "Destination Transaction ID");
362 subtree = proto_item_add_subtree(tid_item, ett_dtid);
365 saved_offset = asn1->offset;
366 ret = asn1_id_decode1(asn1, &tag);
367 proto_tree_add_uint(subtree, hf_tcap_tid, asn1->tvb, saved_offset, asn1->offset - saved_offset, tag);
373 if (ST_ITU_ORG_TID_TAG != tag)
375 asn1->offset = saved_offset;
380 if (ST_ITU_DST_TID_TAG != tag)
382 asn1->offset = saved_offset;
391 dissect_tcap_len(asn1, subtree, &def_len, &len);
393 saved_offset = asn1->offset;
394 ret = asn1_string_value_decode(asn1, len, &poctets);
396 memcpy(&val, poctets, len);
398 ti = proto_tree_add_uint(subtree, hf_tcap_id, asn1->tvb, saved_offset, asn1->offset - saved_offset, val);
401 proto_item_set_len(tid_item, asn1->offset - org_offset);
403 if (type == ST_TID_DEST)
405 if (check_col(g_pinfo->cinfo, COL_INFO))
406 col_append_fstr(g_pinfo->cinfo, COL_INFO, "dtid(%x) ", val);
410 if (check_col(g_pinfo->cinfo, COL_INFO))
411 col_append_fstr(g_pinfo->cinfo, COL_INFO, "stid(%x) ", val);
418 /* dissect operation portion */
420 dissect_tcap_invokeId(ASN1_SCK *asn1, proto_tree *tree)
426 #define INVOKE_ID_TAG 0x2
427 if (check_tcap_tag(asn1, INVOKE_ID_TAG))
430 dissect_tcap_tag(asn1, tree, &tag, "Invoke ID Tag");
431 dissect_tcap_len(asn1, tree, &def_len, &len);
432 dissect_tcap_integer(asn1, tree, len, "Invoke ID:");
439 dissect_tcap_lnkId(ASN1_SCK *asn1, proto_tree *tree)
445 #define LINK_ID_TAG 0x80
446 if (check_tcap_tag(asn1, LINK_ID_TAG))
449 dissect_tcap_tag(asn1, tree, &tag, "Linked ID Tag");
450 dissect_tcap_len(asn1, tree, &def_len, &len);
451 dissect_tcap_integer(asn1, tree, len, "Linked ID:");
458 dissect_tcap_opr_code(ASN1_SCK *asn1, proto_tree *tree)
462 gboolean got_it = FALSE;
465 #define TCAP_LOC_OPR_CODE_TAG 0x02
466 if (check_tcap_tag(asn1, TCAP_LOC_OPR_CODE_TAG))
469 dissect_tcap_tag(asn1, tree, &tag, "Local Operation Code Tag");
472 #define TCAP_GLB_OPR_CODE_TAG 0x06
473 else if (check_tcap_tag(asn1, TCAP_GLB_OPR_CODE_TAG))
476 dissect_tcap_tag(asn1, tree, &tag, "Global Operation Code Tag");
482 dissect_tcap_len(asn1, tree, &def_len, &len);
484 proto_tree_add_text(tree, asn1->tvb, asn1->offset, len, "Operation Code");
491 dissect_tcap_param(ASN1_SCK *asn1, proto_tree *tree, guint exp_len)
493 guint orig_offset, saved_offset, len_offset;
499 orig_offset = asn1->offset;
501 #define TC_INVALID_TAG 0
502 while ((tvb_length_remaining(asn1->tvb, asn1->offset) > 0) &&
503 (!check_tcap_tag(asn1, 0)))
505 if ((exp_len != 0) &&
506 ((asn1->offset - orig_offset) >= exp_len))
511 saved_offset = asn1->offset;
512 asn1_id_decode1(asn1, &tag);
513 len_offset = asn1->offset;
514 asn1_length_decode(asn1, &def_len, &len);
516 if (tag == TC_SEQ_TAG)
519 proto_tree_add_text(tree, asn1->tvb, saved_offset, -1, "Sequence");
521 subtree = proto_item_add_subtree(item, ett_params);
523 proto_tree_add_uint_format(subtree, hf_tcap_tag, asn1->tvb,
524 saved_offset, len_offset - saved_offset, tag, "Sequence Tag");
528 proto_tree_add_uint(subtree, hf_tcap_length, asn1->tvb,
529 len_offset, asn1->offset - len_offset, len);
533 proto_tree_add_text(subtree, asn1->tvb,
534 len_offset, asn1->offset - len_offset, "Length: Indefinite");
536 len = find_eoc(asn1);
539 proto_item_set_len(item,
540 (asn1->offset - saved_offset) + len +
541 (def_len ? 0 : TC_EOC_LEN));
543 dissect_tcap_param(asn1, subtree, len);
547 dissect_tcap_eoc(asn1, subtree);
554 proto_tree_add_uint_format(tree, hf_tcap_tag, asn1->tvb,
555 saved_offset, len_offset - saved_offset, tag, "Parameter Tag");
557 proto_tree_add_text(tree, asn1->tvb,
558 len_offset, asn1->offset - len_offset, "Length: Indefinite");
560 len = find_eoc(asn1);
562 dissect_tcap_param(asn1, tree, len);
564 dissect_tcap_eoc(asn1, tree);
569 proto_tree_add_text(tree, asn1->tvb,
570 saved_offset, (asn1->offset - saved_offset) + len, "Parameter");
572 subtree = proto_item_add_subtree(item, ett_param);
574 proto_tree_add_uint_format(subtree, hf_tcap_tag, asn1->tvb,
575 saved_offset, len_offset - saved_offset, tag, "Parameter Tag");
577 proto_tree_add_uint(subtree, hf_tcap_length, asn1->tvb,
578 len_offset, asn1->offset - len_offset, len);
580 proto_tree_add_text(subtree, asn1->tvb,
581 asn1->offset, len, "Parameter Data");
590 dissect_tcap_component(ASN1_SCK *asn1, proto_tree *tree, guint *len_p)
599 saved_offset = asn1->offset;
600 asn1_id_decode1(asn1, &tag);
603 proto_tree_add_text(tree, asn1->tvb, saved_offset, -1, "Component ID");
605 subtree = proto_item_add_subtree(item, ett_component);
607 proto_tree_add_uint_format(subtree, hf_tcap_tag, asn1->tvb,
608 saved_offset, asn1->offset - saved_offset, tag,
609 "Component ID Identifier");
611 dissect_tcap_len(asn1, subtree, &def_len, len_p);
613 proto_item_set_len(item, (asn1->offset - saved_offset) + *len_p);
619 dissect_tcap_problem(ASN1_SCK *asn1, proto_tree *tree)
621 guint orig_offset, saved_offset, len_offset;
625 proto_item *item = NULL;
627 gchar *type_str = NULL;
632 orig_offset = asn1->offset;
633 saved_offset = asn1->offset;
634 asn1_id_decode1(asn1, &tag);
636 len_offset = asn1->offset;
637 asn1_length_decode(asn1, &def_len, &len);
640 proto_tree_add_text(tree, asn1->tvb, saved_offset, -1, "Problem Code");
642 subtree = proto_item_add_subtree(item, ett_problem);
646 len = find_eoc(asn1);
649 proto_item_set_len(item, (asn1->offset - saved_offset) + len +
650 (def_len ? 0 : TC_EOC_LEN));
654 proto_tree_add_text(subtree, asn1->tvb,
655 asn1->offset, len, "Unknown encoding of Problem Code");
661 asn1_eoc_decode(asn1, -1);
667 saved_offset = asn1->offset;
668 asn1_int32_value_decode(asn1, 1, &spec);
673 type_str = "General Problem";
676 case 0: str = "Unrecognized Component"; break;
677 case 1: str = "Mistyped Component"; break;
678 case 2: str = "Badly Structured Component"; break;
689 case 0: str = "Duplicate Invoke ID"; break;
690 case 1: str = "Unrecognized Operation"; break;
691 case 2: str = "Mistyped Parameter"; break;
692 case 3: str = "Resource Limitation"; break;
693 case 4: str = "Initiating Release"; break;
694 case 5: str = "Unrecognized Linked ID"; break;
695 case 6: str = "Linked Response Unexpected"; break;
696 case 7: str = "Unexpected Linked Operation"; break;
704 type_str = "Return Result";
707 case 0: str = "Unrecognized Invoke ID"; break;
708 case 1: str = "Return Result Unexpected"; break;
709 case 2: str = "Mistyped Parameter"; break;
717 type_str = "Return Error";
720 case 0: str = "Unrecognized Invoke ID"; break;
721 case 1: str = "Return Error Unexpected"; break;
722 case 2: str = "Unrecognized Error"; break;
723 case 3: str = "Unexpected Error"; break;
724 case 4: str = "Mistyped Parameter"; break;
732 type_str = "Undefined";
736 proto_tree_add_uint_format(subtree, hf_tcap_tag, asn1->tvb,
737 orig_offset, len_offset - orig_offset, tag, type_str);
741 proto_tree_add_uint(subtree, hf_tcap_length, asn1->tvb,
742 len_offset, saved_offset - len_offset, len);
746 proto_tree_add_text(subtree, asn1->tvb,
747 len_offset, saved_offset - len_offset, "Length: Indefinite");
750 proto_tree_add_text(subtree, asn1->tvb, saved_offset, 1,
751 "Problem Specifier %s", str);
756 dissect_ansi_opr_code(ASN1_SCK *asn1, proto_tree *tree)
760 gboolean got_it = FALSE;
763 #define TCAP_NAT_OPR_CODE_TAG 0xd0
764 if (check_tcap_tag(asn1, TCAP_NAT_OPR_CODE_TAG))
767 dissect_tcap_tag(asn1, tree, &tag, "National TCAP Operation Code Identifier");
770 #define TCAP_PRIV_OPR_CODE_TAG 0xd1
771 else if (check_tcap_tag(asn1, TCAP_PRIV_OPR_CODE_TAG))
774 dissect_tcap_tag(asn1, tree, &tag, "Private TCAP Operation Code Identifier");
780 dissect_tcap_len(asn1, tree, &def_len, &len);
782 proto_tree_add_text(tree, asn1->tvb, asn1->offset, len, "Operation Code");
789 dissect_ansi_problem(ASN1_SCK *asn1, proto_tree *tree)
791 guint saved_offset = 0;
795 proto_item *item = NULL;
797 gchar *type_str = NULL;
802 #define TCAP_PROB_CODE_TAG 0xd5
803 if (check_tcap_tag(asn1, TCAP_PROB_CODE_TAG))
805 str = "Problem Code Identifier";
813 saved_offset = asn1->offset;
814 asn1_id_decode1(asn1, &tag);
817 proto_tree_add_text(tree, asn1->tvb, saved_offset, -1, "Problem Code");
819 subtree = proto_item_add_subtree(item, ett_problem);
821 proto_tree_add_uint_format(subtree, hf_tcap_tag, asn1->tvb,
822 saved_offset, asn1->offset - saved_offset, tag, str);
824 dissect_tcap_len(asn1, subtree, &def_len, &len);
825 proto_item_set_len(item, (asn1->offset - saved_offset) + len);
829 proto_tree_add_text(subtree, asn1->tvb,
830 asn1->offset, len, "Unknown encoding of Problem Code");
836 saved_offset = asn1->offset;
837 asn1_int32_value_decode(asn1, 1, &type);
838 asn1_int32_value_decode(asn1, 1, &spec);
842 case 0: type_str = "Not used"; break;
845 type_str = "General";
848 case 1: str = "Unrecognized Component Type"; break;
849 case 2: str = "Incorrect Component Portion"; break;
850 case 3: str = "Badly Structured Component Portion"; break;
861 case 1: str = "Duplicate Invoke ID"; break;
862 case 2: str = "Unrecognized Operation Code"; break;
863 case 3: str = "Incorrect Parameter"; break;
864 case 4: str = "Unrecognized Correlation ID"; break;
872 type_str = "Return Result";
875 case 1: str = "Unrecognized Correlation ID"; break;
876 case 2: str = "Unexpected Return Result"; break;
877 case 3: str = "Incorrect Parameter"; break;
885 type_str = "Return Error";
888 case 1: str = "Unrecognized Correlation ID"; break;
889 case 2: str = "Unexpected Return Error"; break;
890 case 3: str = "Unrecognized Error"; break;
891 case 4: str = "Unexpected Error"; break;
892 case 5: str = "Incorrect Parameter"; break;
900 type_str = "Transaction Portion";
903 case 1: str = "Unrecognized Package Type"; break;
904 case 2: str = "Incorrect Transaction Portion"; break;
905 case 3: str = "Badly Structured Transaction Portion"; break;
906 case 4: str = "Unrecognized Transaction ID"; break;
907 case 5: str = "Permission to Release"; break;
908 case 6: str = "Resource Unavailable"; break;
916 type_str = "Undefined";
920 if (spec == 255) { str = "Reserved"; }
921 else if (spec == 0) { str = "Not used"; }
923 proto_tree_add_text(subtree, asn1->tvb,
924 saved_offset, 1, "Problem Type %s", type_str);
926 proto_tree_add_text(subtree, asn1->tvb,
927 saved_offset + 1, 1, "Problem Specifier %s", str);
932 dissect_ansi_error(ASN1_SCK *asn1, proto_tree *tree)
934 guint saved_offset = 0;
938 proto_item *item = NULL;
943 #define TCAP_NAT_ERR_CODE_TAG 0xd3
944 if (check_tcap_tag(asn1, TCAP_NAT_ERR_CODE_TAG))
946 str = "National TCAP Error Code Identifier";
948 #define TCAP_PRIV_ERR_CODE_TAG 0xd4
949 else if (check_tcap_tag(asn1, TCAP_PRIV_ERR_CODE_TAG))
951 str = "Private TCAP Error Code Identifier";
959 saved_offset = asn1->offset;
960 asn1_id_decode1(asn1, &tag);
963 proto_tree_add_text(tree, asn1->tvb,
964 saved_offset, -1, "TCAP Error Code");
966 subtree = proto_item_add_subtree(item, ett_error);
968 proto_tree_add_uint_format(subtree, hf_tcap_tag, asn1->tvb,
969 saved_offset, asn1->offset - saved_offset, tag, str);
971 dissect_tcap_len(asn1, subtree, &def_len, &len);
972 proto_item_set_len(item, (asn1->offset - saved_offset) + len);
974 proto_tree_add_text(subtree, asn1->tvb, asn1->offset, len, "Error Code");
981 dissect_ansi_param(ASN1_SCK *asn1, proto_tree *tree)
985 gboolean got_it = FALSE;
988 #define TCAP_PARAM_SET_TAG 0xf2
989 if (check_tcap_tag(asn1, TCAP_PARAM_SET_TAG))
992 dissect_tcap_tag(asn1, tree, &tag, "Parameter Set Identifier");
995 #define TCAP_PARAM_SEQ_TAG 0x30
996 else if (check_tcap_tag(asn1, TCAP_PARAM_SEQ_TAG))
999 dissect_tcap_tag(asn1, tree, &tag, "Parameter Sequence Identifier");
1005 dissect_tcap_len(asn1, tree, &def_len, &len);
1007 proto_tree_add_text(tree, asn1->tvb, asn1->offset, len, "Parameter Data");
1009 asn1->offset += len;
1014 dissect_ansi_tcap_reject(ASN1_SCK *asn1, proto_tree *tree)
1017 proto_tree *subtree;
1019 #define COMPONENT_ID_TAG 0xcf
1020 if (check_tcap_tag(asn1, COMPONENT_ID_TAG))
1022 subtree = dissect_tcap_component(asn1, tree, &len);
1027 dissect_tcap_octet(asn1, subtree, "Correlation ID:");
1032 dissect_ansi_problem(asn1, tree);
1034 dissect_ansi_param(asn1, tree);
1038 dissect_ansi_tcap_re(ASN1_SCK *asn1, proto_tree *tree)
1041 proto_tree *subtree;
1043 #define COMPONENT_ID_TAG 0xcf
1044 if (check_tcap_tag(asn1, COMPONENT_ID_TAG))
1046 subtree = dissect_tcap_component(asn1, tree, &len);
1051 dissect_tcap_octet(asn1, tree, "Correlation ID:");
1056 dissect_ansi_error(asn1, tree);
1058 dissect_ansi_param(asn1, tree);
1062 dissect_ansi_tcap_rr(ASN1_SCK *asn1, proto_tree *tree)
1065 proto_tree *subtree;
1067 #define COMPONENT_ID_TAG 0xcf
1068 if (check_tcap_tag(asn1, COMPONENT_ID_TAG))
1070 subtree = dissect_tcap_component(asn1, tree, &len);
1075 dissect_tcap_octet(asn1, tree, "Correlation ID:");
1080 dissect_ansi_param(asn1, tree);
1084 dissect_ansi_tcap_invoke(ASN1_SCK *asn1, proto_tree *tree)
1087 proto_tree *subtree;
1089 #define COMPONENT_ID_TAG 0xcf
1090 if (check_tcap_tag(asn1, COMPONENT_ID_TAG))
1092 subtree = dissect_tcap_component(asn1, tree, &len);
1097 dissect_tcap_octet(asn1, tree, "Invoke ID:");
1101 dissect_tcap_octet(asn1, tree, "Invoke ID:");
1102 dissect_tcap_octet(asn1, tree, "Correlation ID:");
1107 dissect_ansi_opr_code(asn1, tree);
1109 dissect_ansi_param(asn1, tree);
1113 dissect_tcap_invoke(ASN1_SCK *asn1, proto_tree *tree)
1115 proto_tree *subtree;
1116 guint orig_offset, saved_offset;
1123 orig_offset = asn1->offset;
1124 saved_offset = asn1->offset;
1125 ret = asn1_id_decode1(asn1, &tag);
1128 proto_tree_add_text(tree, asn1->tvb, saved_offset, -1, "Component");
1130 subtree = proto_item_add_subtree(item, ett_component);
1132 proto_tree_add_uint_format(subtree, hf_tcap_tag, asn1->tvb,
1133 saved_offset, asn1->offset - saved_offset, tag, "Invoke Type Tag");
1135 dissect_tcap_len(asn1, subtree, &def_len, &len);
1137 saved_offset = asn1->offset;
1139 dissect_tcap_invokeId(asn1, subtree);
1141 dissect_tcap_lnkId(asn1, subtree);
1143 dissect_tcap_opr_code(asn1, subtree);
1147 len -= asn1->offset - saved_offset;
1151 len = find_eoc(asn1);
1154 dissect_tcap_param(asn1, subtree, len);
1158 dissect_tcap_eoc(asn1, subtree);
1161 proto_item_set_len(item, asn1->offset - orig_offset);
1165 dissect_tcap_rr(ASN1_SCK *asn1, proto_tree *tree, gchar *str)
1167 guint tag, len, comp_len;
1168 guint orig_offset, saved_offset, len_offset;
1169 proto_item *seq_item, *item;
1170 proto_tree *seq_subtree, *subtree;
1172 gboolean comp_def_len;
1175 orig_offset = asn1->offset;
1176 saved_offset = asn1->offset;
1177 asn1_id_decode1(asn1, &tag);
1180 proto_tree_add_text(tree, asn1->tvb, saved_offset, -1, "Component");
1182 subtree = proto_item_add_subtree(item, ett_component);
1184 proto_tree_add_uint_format(subtree, hf_tcap_tag, asn1->tvb,
1185 saved_offset, asn1->offset - saved_offset, tag, str);
1187 dissect_tcap_len(asn1, subtree, &comp_def_len, &comp_len);
1189 saved_offset = asn1->offset;
1191 dissect_tcap_invokeId(asn1, subtree);
1193 if (tvb_length_remaining(asn1->tvb, asn1->offset) <= 0)
1195 proto_item_set_len(item, asn1->offset - orig_offset);
1200 saved_offset = asn1->offset;
1203 asn1_id_decode1(asn1, &tag);
1205 if (tag == TC_SEQ_TAG)
1207 len_offset = asn1->offset;
1208 asn1_length_decode(asn1, &def_len, &len);
1211 proto_tree_add_text(subtree, asn1->tvb, saved_offset, -1, "Sequence");
1213 seq_subtree = proto_item_add_subtree(seq_item, ett_params);
1215 proto_tree_add_uint_format(seq_subtree, hf_tcap_tag, asn1->tvb,
1216 saved_offset, len_offset - saved_offset, tag, "Sequence Tag");
1220 proto_tree_add_uint(seq_subtree, hf_tcap_length, asn1->tvb,
1221 len_offset, asn1->offset - len_offset, len);
1225 proto_tree_add_text(seq_subtree, asn1->tvb,
1226 len_offset, asn1->offset - len_offset, "Length: Indefinite");
1228 len = find_eoc(asn1);
1231 proto_item_set_len(seq_item,
1232 (asn1->offset - saved_offset) + len +
1233 (def_len ? 0 : TC_EOC_LEN));
1235 saved_offset = asn1->offset;
1237 dissect_tcap_opr_code(asn1, seq_subtree);
1239 len -= asn1->offset - saved_offset;
1241 dissect_tcap_param(asn1, seq_subtree, len);
1245 dissect_tcap_eoc(asn1, seq_subtree);
1251 dissect_tcap_eoc(asn1, subtree);
1254 proto_item_set_len(item, asn1->offset - orig_offset);
1258 dissect_tcap_re(ASN1_SCK *asn1, proto_tree *tree)
1260 guint tag, len, comp_len;
1261 guint orig_offset, saved_offset;
1263 proto_tree *subtree;
1264 gboolean comp_def_len, def_len;
1267 orig_offset = asn1->offset;
1268 saved_offset = asn1->offset;
1269 asn1_id_decode1(asn1, &tag);
1272 proto_tree_add_text(tree, asn1->tvb, saved_offset, -1, "Component");
1274 subtree = proto_item_add_subtree(item, ett_component);
1276 proto_tree_add_uint_format(subtree, hf_tcap_tag, asn1->tvb,
1277 saved_offset, asn1->offset - saved_offset,
1278 tag, "Return Error Type Tag");
1280 dissect_tcap_len(asn1, subtree, &comp_def_len, &comp_len);
1284 comp_len = find_eoc(asn1);
1287 saved_offset = asn1->offset;
1289 dissect_tcap_invokeId(asn1, subtree);
1291 #define TC_LOCAL_ERR_CODE_TAG 0x2
1292 #define TC_GBL_ERR_CODE_TAG 0x6
1293 if (check_tcap_tag(asn1, TC_LOCAL_ERR_CODE_TAG))
1296 dissect_tcap_tag(asn1, subtree, &tag, "Local Error Code Tag");
1298 else if (check_tcap_tag(asn1, TC_GBL_ERR_CODE_TAG))
1301 dissect_tcap_tag(asn1, subtree, &tag, "Global Error Code Tag");
1305 proto_tree_add_text(subtree, asn1->tvb, asn1->offset, comp_len,
1306 "Unknown Error Code");
1308 asn1->offset += comp_len;
1312 dissect_tcap_eoc(asn1, subtree);
1315 proto_item_set_len(item, asn1->offset - orig_offset);
1320 dissect_tcap_len(asn1, subtree, &def_len, &len);
1321 dissect_tcap_integer(asn1, subtree, len, "Error Code:");
1323 dissect_tcap_param(asn1, subtree, comp_len - (asn1->offset - saved_offset));
1327 dissect_tcap_eoc(asn1, subtree);
1330 proto_item_set_len(item, asn1->offset - orig_offset);
1336 dissect_tcap_reject(ASN1_SCK *asn1, proto_tree *tree)
1338 guint tag, comp_len;
1341 proto_tree *subtree;
1346 saved_offset = asn1->offset;
1347 asn1_id_decode1(asn1, &tag);
1349 item = proto_tree_add_text(tree, asn1->tvb, saved_offset, -1, "Component");
1351 subtree = proto_item_add_subtree(item, ett_component);
1353 proto_tree_add_uint_format(subtree, hf_tcap_tag, asn1->tvb,
1354 saved_offset, asn1->offset - saved_offset,
1355 tag, "Reject Type Tag");
1357 dissect_tcap_len(asn1, subtree, &def_len, &comp_len);
1359 dissect_tcap_invokeId(asn1, subtree);
1361 dissect_tcap_problem(asn1, subtree);
1365 dissect_tcap_eoc(asn1, subtree);
1368 proto_item_set_len(item, asn1->offset - saved_offset);
1372 dissect_ansi_tcap_next_tvb(ASN1_SCK *asn1, guint len, proto_tree *tree)
1377 gboolean flag = TRUE;
1379 proto_item *item, *tag_item;
1380 proto_tree *subtree, *tag_subtree;
1384 if (lock_info_col) col_set_fence(g_pinfo->cinfo, COL_INFO);
1386 next_tvb = tvb_new_subset(asn1->tvb, asn1->offset, len, len);
1388 /* process components data */
1389 if (!dissector_try_port(tcap_ansi_ssn_dissector_table, g_pinfo->match_port, next_tvb, g_pinfo, g_tcap_tree))
1393 saved_offset = asn1->offset;
1394 ret = asn1_id_decode1(asn1, &tag);
1397 * verify tag type is known
1401 case ANSI_TC_INVOKE_L :
1404 case ANSI_TC_REJECT :
1405 case ANSI_TC_INVOKE_N :
1417 item = proto_tree_add_text(tree, asn1->tvb, saved_offset, -1, "Components");
1418 subtree = proto_item_add_subtree(item, ett_component);
1422 case ANSI_TC_INVOKE_L :
1423 tag_item = proto_tree_add_uint_format(subtree, hf_tcap_tag, asn1->tvb, saved_offset,
1424 asn1->offset - saved_offset, tag, "Invoke(Last)");
1425 dissect_tcap_len(asn1, subtree, &def_len, &len);
1426 tag_subtree = proto_item_add_subtree(tag_item, ett_component);
1428 dissect_ansi_tcap_invoke(asn1, tag_subtree);
1431 tag_item = proto_tree_add_uint_format(subtree, hf_tcap_tag, asn1->tvb, saved_offset,
1432 asn1->offset - saved_offset, tag, "Return Result(Last)");
1433 dissect_tcap_len(asn1, subtree, &def_len, &len);
1434 tag_subtree = proto_item_add_subtree(tag_item, ett_component);
1436 dissect_ansi_tcap_rr(asn1, tag_subtree);
1439 tag_item = proto_tree_add_uint_format(subtree, hf_tcap_tag, asn1->tvb, saved_offset,
1440 asn1->offset - saved_offset, tag, "Return Error");
1441 dissect_tcap_len(asn1, subtree, &def_len, &len);
1442 tag_subtree = proto_item_add_subtree(tag_item, ett_component);
1444 dissect_ansi_tcap_re(asn1, tag_subtree);
1446 case ANSI_TC_REJECT :
1447 tag_item = proto_tree_add_uint_format(subtree, hf_tcap_tag, asn1->tvb, saved_offset,
1448 asn1->offset - saved_offset, tag, "Reject");
1449 dissect_tcap_len(asn1, subtree, &def_len, &len);
1450 tag_subtree = proto_item_add_subtree(tag_item, ett_component);
1452 dissect_ansi_tcap_reject(asn1, tag_subtree);
1454 case ANSI_TC_INVOKE_N :
1455 tag_item = proto_tree_add_uint_format(subtree, hf_tcap_tag, asn1->tvb, saved_offset,
1456 asn1->offset - saved_offset, tag, "Invoke(Not Last)");
1457 dissect_tcap_len(asn1, subtree, &def_len, &len);
1458 tag_subtree = proto_item_add_subtree(tag_item, ett_component);
1460 dissect_ansi_tcap_invoke(asn1, tag_subtree);
1463 tag_item = proto_tree_add_uint_format(subtree, hf_tcap_tag, asn1->tvb, saved_offset,
1464 asn1->offset - saved_offset, tag, "Return Result(Not Last)");
1465 dissect_tcap_len(asn1, subtree, &def_len, &len);
1466 tag_subtree = proto_item_add_subtree(tag_item, ett_component);
1468 dissect_ansi_tcap_rr(asn1, tag_subtree);
1472 proto_item_set_len(item, asn1->offset - saved_offset);
1478 /* No sub-dissection occured, treat it as raw data */
1479 call_dissector(data_handle, next_tvb, g_pinfo, g_tcap_tree);
1484 dissect_tcap_components(ASN1_SCK *asn1, proto_tree *tcap_tree)
1486 proto_tree *subtree;
1487 proto_item *comps_item;
1488 guint saved_offset, comps_start;
1489 guint len, comp_len;
1491 gboolean comps_def_len, def_len;
1496 if (tvb_length_remaining(asn1->tvb, asn1->offset) <= 0)
1501 comps_start = asn1->offset;
1502 saved_offset = asn1->offset;
1503 ret = asn1_id_decode1(asn1, &tag);
1505 if (ST_ITU_CMP_TAG != tag)
1507 asn1->offset = saved_offset;
1512 proto_tree_add_text(tcap_tree, asn1->tvb,
1513 saved_offset, -1, "Components Portion");
1515 subtree = proto_item_add_subtree(comps_item, ett_comps_portion);
1517 proto_tree_add_uint_format(subtree, hf_tcap_tag, asn1->tvb, saved_offset,
1518 asn1->offset - saved_offset, tag, "Component Portion Tag");
1520 dissect_tcap_len(asn1, subtree, &comps_def_len, &len);
1524 proto_item_set_len(comps_item, (asn1->offset - comps_start) + len);
1527 if (lock_info_col) col_set_fence(g_pinfo->cinfo, COL_INFO);
1529 /* call next dissector for EACH component */
1532 (comps_def_len ? 0 : TC_EOC_LEN) +
1533 (g_tcap_ends_def_len ? 0 : TC_EOC_LEN);
1535 while (tvb_length_remaining(asn1->tvb, asn1->offset) > keep_len)
1537 /* peek at tag and length */
1538 saved_offset = asn1->offset;
1539 ret = asn1_id_decode1(asn1, &tag);
1543 ret = asn1_length_decode(asn1, &def_len, &comp_len);
1547 comp_len += (asn1->offset - saved_offset);
1551 comp_len = (asn1->offset - saved_offset) + find_eoc(asn1) + TC_EOC_LEN;
1554 next_tvb = tvb_new_subset(asn1->tvb, saved_offset, comp_len, comp_len);
1555 asn1->offset = saved_offset;
1557 /* process component data */
1558 if (dissector_try_port(tcap_itu_ssn_dissector_table, g_pinfo->match_port, next_tvb, g_pinfo, g_tcap_tree))
1560 proto_tree_add_text(subtree, asn1->tvb, asn1->offset, comp_len, "Component");
1562 asn1->offset += comp_len;
1569 dissect_tcap_invoke(asn1, subtree);
1572 dissect_tcap_rr(asn1, subtree, "Return Result(Last) Type Tag");
1575 dissect_tcap_re(asn1, subtree);
1578 dissect_tcap_reject(asn1, subtree);
1581 /* same definition as RRL */
1582 dissect_tcap_rr(asn1, subtree, "Return Result(Not Last) Type Tag");
1585 /* treat it as raw data */
1586 call_dissector(data_handle, next_tvb, g_pinfo, g_tcap_tree);
1594 dissect_tcap_eoc(asn1, subtree);
1596 proto_item_set_len(comps_item, asn1->offset - comps_start);
1602 /* dissect dialog portion */
1604 dissect_tcap_dlg_protocol_version(ASN1_SCK *asn1, proto_tree *tcap_tree, proto_item *ti)
1606 guint saved_offset = 0;
1612 #define TC_DLG_PROTO_VER_TAG 0x80
1613 if (check_tcap_tag(asn1, TC_DLG_PROTO_VER_TAG))
1615 saved_offset = asn1->offset;
1616 ret = asn1_id_decode1(asn1, &tag);
1617 proto_tree_add_uint_format(tcap_tree, hf_tcap_tag, asn1->tvb,
1618 saved_offset, asn1->offset - saved_offset, tag,
1619 "Protocol Version Tag: 0x%x", tag);
1621 dissect_tcap_len(asn1, tcap_tree, &def_len, &len);
1622 saved_offset = asn1->offset;
1624 proto_tree_add_bytes(tcap_tree, hf_tcap_bytes, asn1->tvb, saved_offset, len,
1625 (guchar*)(tvb_get_ptr(asn1->tvb, saved_offset, len)));
1626 asn1->offset += len;
1633 dissect_tcap_dlg_application_context_name(ASN1_SCK *asn1, proto_tree *tcap_tree)
1635 guint saved_offset = 0;
1636 guint name_len, len, len2;
1642 saved_offset = asn1->offset;
1643 ret = asn1_id_decode1(asn1, &tag);
1644 proto_tree_add_uint_format(tcap_tree, hf_tcap_tag, asn1->tvb, saved_offset, asn1->offset - saved_offset, tag,
1645 "Application Context Name Tag: 0x%x", tag);
1647 dissect_tcap_len(asn1, tcap_tree, &def_len, &name_len);
1649 saved_offset = asn1->offset;
1650 ret = asn1_oid_decode (asn1, &oid, &len, &len2);
1651 proto_tree_add_bytes(tcap_tree, hf_tcap_app_con_name, asn1->tvb, saved_offset, len2, tvb_get_ptr(asn1->tvb, saved_offset, len2));
1652 if (ret == ASN1_ERR_NOERROR) g_free(oid);
1656 /* for Application Context Name Tag */
1657 dissect_tcap_eoc(asn1, tcap_tree);
1664 dissect_tcap_dlg_result(ASN1_SCK *asn1, proto_tree *tree)
1666 guint tag, rtag_len, itag_len;
1667 guint saved_offset = 0;
1671 gboolean rtag_def_len;
1674 dissect_tcap_tag(asn1, tree, &tag, "Result Tag");
1676 dissect_tcap_len(asn1, tree, &rtag_def_len, &rtag_len);
1679 dissect_tcap_tag(asn1, tree, &tag, "Integer Tag");
1681 dissect_tcap_len(asn1, tree, &def_len, &itag_len);
1683 saved_offset = asn1->offset;
1684 asn1_int32_value_decode(asn1, itag_len, &value);
1688 case 0x00: str = "Accepted"; break;
1689 case 0x01: str = "Reject-permanent"; break;
1690 default: str = "Unknown value"; break;
1693 proto_tree_add_int_format(tree, hf_tcap_int, asn1->tvb, saved_offset, asn1->offset - saved_offset,
1694 value, "%s %d", str, value);
1698 /* for Result Tag */
1699 dissect_tcap_eoc(asn1, tree);
1706 dissect_tcap_dlg_result_src_diag(ASN1_SCK *asn1, proto_tree *tree)
1708 guint saved_offset = 0;
1714 gboolean serv_def_len;
1715 gboolean diag_def_len;
1718 dissect_tcap_tag(asn1, tree, &tag, "Result Source Diagnostic Tag");
1720 dissect_tcap_len(asn1, tree, &diag_def_len, &len);
1722 #define TC_DIAG_SERV_USER_TAG 0xa1
1723 #define TC_DIAG_SERV_PROV_TAG 0xa2
1724 if (check_tcap_tag(asn1, TC_DIAG_SERV_USER_TAG))
1727 dissect_tcap_tag(asn1, tree, &tag, "Dialogue Service User Tag");
1730 else if (check_tcap_tag(asn1, TC_DIAG_SERV_PROV_TAG))
1733 dissect_tcap_tag(asn1, tree, &tag, "Dialogue Service Provider Tag");
1738 proto_tree_add_text(tree, asn1->tvb, asn1->offset, len,
1739 "Unknown Result Source Diagnostic");
1741 asn1->offset += len;
1745 dissect_tcap_len(asn1, tree, &serv_def_len, &len);
1748 dissect_tcap_tag(asn1, tree, &tag, "Integer Tag");
1750 dissect_tcap_len(asn1, tree, &def_len, &len);
1752 saved_offset = asn1->offset;
1753 asn1_int32_value_decode(asn1, len, &value);
1759 case 0x00: str = "Null"; break;
1760 case 0x01: str = "No reason given"; break;
1761 case 0x02: str = "Application Context Name not supplied"; break;
1762 default: str = "Unknown value"; break;
1769 case 0x00: str = "Null"; break;
1770 case 0x01: str = "No reason given"; break;
1771 case 0x02: str = "No common dialogue portion"; break;
1772 default: str = "Unknown value"; break;
1776 proto_tree_add_int_format(tree, hf_tcap_int, asn1->tvb, saved_offset, asn1->offset - saved_offset,
1777 value, "%s %d", str, value);
1781 /* for Dialogue Service User/Provider Tag */
1782 dissect_tcap_eoc(asn1, tree);
1787 /* for Result Source Diagnostic Tag */
1788 dissect_tcap_eoc(asn1, tree);
1795 dissect_tcap_dlg_user_info(ASN1_SCK *asn1, proto_tree *tree)
1798 guint saved_offset = 0;
1800 gboolean user_info_def_len;
1802 #define TC_USR_INFO_TAG 0xbe
1803 if (check_tcap_tag(asn1, TC_USR_INFO_TAG))
1806 dissect_tcap_tag(asn1, tree, &tag, "User Info Tag");
1807 dissect_tcap_len(asn1, tree, &user_info_def_len, &len);
1809 #define TC_EXT_TAG 0x28
1810 if (check_tcap_tag(asn1, TC_EXT_TAG))
1812 saved_offset = asn1->offset;
1813 asn1_id_decode1(asn1, &tag);
1814 proto_tree_add_uint_format(tree, hf_tcap_length, asn1->tvb, saved_offset, asn1->offset - saved_offset,
1815 tag, "External Tag: 0x%x", tag);
1817 dissect_tcap_len(asn1, tree, &def_len, &len);
1820 proto_tree_add_text(tree, asn1->tvb, asn1->offset, len, "Parameter Data");
1821 asn1->offset += len;
1823 if (!user_info_def_len)
1825 /* for User Information Tag */
1826 dissect_tcap_eoc(asn1, tree);
1834 dissect_tcap_dlg_req(ASN1_SCK *asn1, proto_tree *tcap_tree)
1836 proto_tree *subtree;
1837 guint saved_offset = 0;
1841 proto_item *req_item;
1842 guint req_start = asn1->offset;
1845 /* dissect dialog portion */
1846 saved_offset = asn1->offset;
1847 ret = asn1_id_decode1(asn1, &tag);
1848 req_item = proto_tree_add_text(tcap_tree, asn1->tvb, saved_offset, -1, "Dialogue Request");
1849 subtree = proto_item_add_subtree(req_item, ett_dlg_req);
1850 proto_tree_add_uint(subtree, hf_tcap_dlg_type, asn1->tvb, saved_offset, asn1->offset - saved_offset, tag);
1852 dissect_tcap_len(asn1, subtree, &def_len, &len);
1854 dissect_tcap_dlg_protocol_version(asn1, subtree, NULL);
1856 dissect_tcap_dlg_application_context_name(asn1, subtree);
1858 dissect_tcap_dlg_user_info(asn1, subtree);
1860 /* decode end of sequence */
1864 /* for Dialogue Request Tag */
1865 dissect_tcap_eoc(asn1, subtree);
1868 proto_item_set_len(req_item, asn1->offset - req_start);
1874 dissect_tcap_dlg_rsp(ASN1_SCK *asn1, proto_tree *tcap_tree)
1876 proto_tree *subtree;
1877 guint saved_offset = 0;
1881 proto_item *req_item;
1882 guint req_start = asn1->offset;
1885 /* dissect dialog portion */
1886 saved_offset = asn1->offset;
1887 ret = asn1_id_decode1(asn1, &tag);
1888 req_item = proto_tree_add_text(tcap_tree, asn1->tvb, saved_offset, -1, "Dialogue Response");
1889 subtree = proto_item_add_subtree(req_item, ett_dlg_rsp);
1890 proto_tree_add_uint(subtree, hf_tcap_dlg_type, asn1->tvb, saved_offset, asn1->offset - saved_offset, tag);
1892 dissect_tcap_len(asn1, subtree, &def_len, &len);
1894 dissect_tcap_dlg_protocol_version(asn1, subtree, NULL);
1896 dissect_tcap_dlg_application_context_name(asn1, subtree);
1899 dissect_tcap_dlg_result(asn1, subtree);
1901 /* result source diag */
1902 dissect_tcap_dlg_result_src_diag(asn1, subtree);
1904 dissect_tcap_dlg_user_info(asn1, subtree);
1908 /* for Dialogue Response Tag */
1909 dissect_tcap_eoc(asn1, subtree);
1912 proto_item_set_len(req_item, asn1->offset - req_start);
1918 dissect_tcap_dlg_abrt(ASN1_SCK *asn1, proto_tree *tree)
1920 proto_tree *subtree;
1921 guint saved_offset = 0;
1925 proto_item *req_item;
1928 gboolean def_len, abort_def_len;
1930 /* dissect dialog pabort portion */
1931 saved_offset = asn1->offset;
1932 ret = asn1_id_decode1(asn1, &tag);
1933 req_item = proto_tree_add_text(tree, asn1->tvb, saved_offset, -1, "Dialogue Abort");
1934 subtree = proto_item_add_subtree(req_item, ett_dlg_abort );
1935 proto_tree_add_uint(subtree, hf_tcap_dlg_type, asn1->tvb, saved_offset, asn1->offset - saved_offset, tag);
1937 dissect_tcap_len(asn1, subtree, &abort_def_len, &len);
1940 dissect_tcap_tag(asn1, subtree, &tag, "Abort Source Tag");
1941 dissect_tcap_len(asn1, subtree, &def_len, &len);
1943 saved_offset = asn1->offset;
1944 asn1_int32_value_decode(asn1, len, &value);
1948 case 0x00: str = "Dialogue Service User"; break;
1949 case 0x01: str = "Dialogue Service Provider"; break;
1950 default: str = "Unknown value"; break;
1953 proto_tree_add_int_format(subtree, hf_tcap_int, asn1->tvb, saved_offset, asn1->offset - saved_offset,
1954 value, "Abort Source: %s %d", str, value);
1956 dissect_tcap_dlg_user_info(asn1, subtree);
1960 /* for Dialogue Abort Tag */
1961 dissect_tcap_eoc(asn1, subtree);
1968 dissect_tcap_dialog_portion(ASN1_SCK *asn1, proto_tree *tcap_tree, proto_item *ti)
1970 proto_tree *subtree;
1971 guint saved_offset = 0;
1975 proto_item *dlg_item;
1976 guint dlg_start = asn1->offset;
1977 gboolean def_len, ext_tag_def_len, portion_def_len;
1979 if (tvb_length_remaining(asn1->tvb, asn1->offset) <= 0)
1984 /* dissect dialog portion */
1985 saved_offset = asn1->offset;
1986 ret = asn1_id_decode1(asn1, &tag);
1988 /* error handling */
1989 if (ST_ITU_DLG_TAG != tag)
1991 asn1->offset = saved_offset;
1996 proto_tree_add_text(tcap_tree, asn1->tvb, saved_offset, -1, "Dialogue Portion");
1998 subtree = proto_item_add_subtree(dlg_item, ett_dlg_portion);
2000 proto_tree_add_uint_format(subtree, hf_tcap_tag, asn1->tvb,
2001 saved_offset, asn1->offset - saved_offset, tag, "Dialogue Portion Tag");
2003 dissect_tcap_len(asn1, subtree, &portion_def_len, &len);
2005 if (portion_def_len)
2007 proto_item_set_len(dlg_item, len);
2010 ext_tag_def_len = FALSE;
2011 saved_offset = asn1->offset;
2012 ret = asn1_id_decode1(asn1, &tag);
2013 #define TC_EXT_TAG 0x28
2014 if (TC_EXT_TAG != tag)
2016 asn1->offset = saved_offset;
2020 proto_tree_add_uint_format(subtree, hf_tcap_length, asn1->tvb,
2021 saved_offset, asn1->offset - saved_offset, tag,
2022 "External Tag: 0x%x", tag);
2024 dissect_tcap_len(asn1, subtree, &ext_tag_def_len, &len);
2027 saved_offset = asn1->offset;
2028 ret = asn1_id_decode1(asn1, &tag);
2029 #define TC_OID_TAG 0x06
2030 if (TC_OID_TAG != tag)
2032 asn1->offset = saved_offset;
2036 proto_tree_add_uint_format(subtree, hf_tcap_tag, asn1->tvb,
2037 saved_offset, asn1->offset - saved_offset, tag,
2038 "Object Identifier Tag");
2040 dissect_tcap_len(asn1, subtree, &def_len, &len);
2042 saved_offset = asn1->offset;
2044 proto_tree_add_bytes(subtree, hf_tcap_bytes, asn1->tvb, saved_offset, len,
2045 (guchar*)(tvb_get_ptr(asn1->tvb, saved_offset, len)));
2047 asn1->offset += len;
2050 saved_offset = asn1->offset;
2051 ret = asn1_id_decode1(asn1, &tag);
2053 proto_tree_add_uint_format(subtree, hf_tcap_tag, asn1->tvb,
2054 saved_offset, asn1->offset - saved_offset, tag,
2055 "Single-ASN.1-type Tag");
2057 dissect_tcap_len(asn1, subtree, &def_len, &len);
2059 proto_item_set_len(dlg_item, asn1->offset - dlg_start);
2062 saved_offset = asn1->offset;
2063 ret = asn1_id_decode1(asn1, &tag);
2064 asn1->offset = saved_offset;
2069 dissect_tcap_dlg_req(asn1, subtree);
2072 dissect_tcap_dlg_rsp(asn1, subtree);
2075 dissect_tcap_dlg_abrt(asn1, subtree);
2081 /* decode end of sequence */
2085 dissect_tcap_eoc(asn1, subtree);
2088 if (!ext_tag_def_len)
2090 dissect_tcap_eoc(asn1, subtree);
2093 if (!portion_def_len)
2095 dissect_tcap_eoc(asn1, subtree);
2098 proto_item_set_len(dlg_item, asn1->offset - dlg_start);
2103 /* dissect reason */
2105 dissect_tcap_abort_reason(ASN1_SCK *asn1, proto_tree *tcap_tree)
2107 guint saved_offset = 0;
2109 proto_tree *subtree;
2115 #define TC_PABRT_REASON_TAG 0x4a
2116 tag = TC_PABRT_REASON_TAG;
2117 if (check_tcap_tag(asn1, tag))
2119 saved_offset = asn1->offset;
2121 proto_tree_add_text(tcap_tree, asn1->tvb, saved_offset, -1, "PAbort Cause");
2123 subtree = proto_item_add_subtree(item, ett_reason);
2126 dissect_tcap_tag(asn1, subtree, &tag, "PAbort Cause Tag");
2127 dissect_tcap_len(asn1, subtree, &def_len, &len);
2129 proto_item_set_len(item, (asn1->offset - saved_offset) + len);
2131 saved_offset = asn1->offset;
2132 asn1_int32_value_decode(asn1, len, &value);
2136 case 0x00: str = "Unrecognized Message Type"; break;
2137 case 0x01: str = "Unrecognized Transaction ID"; break;
2138 case 0x02: str = "Badly Formatted Transaction Portion"; break;
2139 case 0x03: str = "Incorrect Transaction Portion"; break;
2140 case 0x04: str = "Resource Limitation"; break;
2146 proto_tree_add_text(subtree, asn1->tvb,
2147 saved_offset, asn1->offset - saved_offset, "Cause Value %s (%d)",
2154 /* dissect each type of message */
2157 dissect_tcap_unidirectional(ASN1_SCK *asn1, proto_tree *tcap_tree)
2160 dissect_tcap_dialog_portion(asn1, tcap_tree, NULL);
2162 dissect_tcap_components(asn1, tcap_tree);
2166 dissect_tcap_begin(ASN1_SCK *asn1, proto_tree *tcap_tree, proto_item *ti)
2169 dissect_tcap_tid(asn1, tcap_tree, ti, ST_TID_SOURCE);
2171 dissect_tcap_dialog_portion(asn1, tcap_tree, NULL);
2173 dissect_tcap_components(asn1, tcap_tree);
2177 dissect_tcap_continue(ASN1_SCK *asn1, proto_tree *tcap_tree, proto_item *ti)
2180 dissect_tcap_tid(asn1, tcap_tree, ti, ST_TID_SOURCE);
2182 dissect_tcap_tid(asn1, tcap_tree, ti, ST_TID_DEST);
2184 dissect_tcap_dialog_portion(asn1, tcap_tree, NULL);
2186 dissect_tcap_components(asn1, tcap_tree);
2191 dissect_tcap_end(ASN1_SCK *asn1, proto_tree *tcap_tree, proto_item *ti)
2194 dissect_tcap_tid(asn1, tcap_tree, ti, ST_TID_DEST);
2196 dissect_tcap_dialog_portion(asn1, tcap_tree, NULL);
2198 dissect_tcap_components(asn1, tcap_tree);
2202 dissect_tcap_abort(ASN1_SCK *asn1, proto_tree *tree, proto_item *ti)
2205 dissect_tcap_tid(asn1, tree, ti, ST_TID_DEST);
2207 dissect_tcap_abort_reason(asn1, tree);
2209 dissect_tcap_dialog_portion(asn1, tree, NULL);
2214 dissect_tcap_message(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tcap_tree)
2220 guint saved_offset = 0;
2224 asn1_open(&asn1, tvb, offset);
2226 asn1_id_decode1(&asn1, &msg_type_tag);
2228 str = match_strval(msg_type_tag, msg_type_strings);
2232 proto_tree_add_text(tcap_tree, asn1.tvb, offset, -1, "Unknown message type, ignoring");
2236 if (check_col(pinfo->cinfo, COL_INFO))
2238 col_set_str(pinfo->cinfo, COL_INFO, str);
2239 col_append_str(pinfo->cinfo, COL_INFO, " ");
2242 proto_tree_add_uint_hidden(tcap_tree, hf_tcap_ssn, asn1.tvb, offset,
2243 0, pinfo->match_port); /* len -1 is unacceptable */
2245 ti = proto_tree_add_uint(tcap_tree, hf_tcap_message_type, asn1.tvb, offset, asn1.offset - saved_offset,
2248 dissect_tcap_len(&asn1, tcap_tree, &g_tcap_ends_def_len, &len);
2250 switch(msg_type_tag)
2252 case ST_MSG_TYP_UNI:
2253 dissect_tcap_unidirectional(&asn1, tcap_tree);
2255 case ST_MSG_TYP_BGN:
2256 dissect_tcap_begin(&asn1, tcap_tree, ti);
2258 case ST_MSG_TYP_CNT:
2259 dissect_tcap_continue(&asn1, tcap_tree, ti);
2261 case ST_MSG_TYP_END:
2262 dissect_tcap_end(&asn1, tcap_tree, ti);
2264 case ST_MSG_TYP_PABT:
2265 dissect_tcap_abort(&asn1, tcap_tree, ti);
2268 proto_tree_add_text(tcap_tree, asn1.tvb, offset, -1,
2269 "Message type not handled, ignoring");
2273 if (!g_tcap_ends_def_len)
2275 dissect_tcap_eoc(&asn1, tcap_tree);
2278 asn1_close(&asn1, &saved_offset);
2282 dissect_ansi_tcap_components(ASN1_SCK *asn1, proto_tree *tcap_tree)
2284 proto_tree *subtree;
2285 guint saved_offset = 0;
2289 proto_item *cmp_item;
2290 guint cmp_start = asn1->offset;
2293 saved_offset = asn1->offset;
2294 ret = asn1_id_decode1(asn1, &tag);
2296 if (ST_ANSI_CMP_TAG != tag)
2298 asn1->offset = saved_offset;
2302 cmp_item = proto_tree_add_text(tcap_tree, asn1->tvb, saved_offset, -1, "Components Portion");
2304 subtree = proto_item_add_subtree(cmp_item, ett_comps_portion);
2306 proto_tree_add_uint_format(subtree, hf_tcap_tag, asn1->tvb, saved_offset, asn1->offset - saved_offset, tag,
2307 "Component Sequence Identifier");
2309 dissect_tcap_len(asn1, tcap_tree, &def_len, &len);
2311 /* call next dissector */
2313 dissect_ansi_tcap_next_tvb(asn1, len, subtree);
2315 proto_item_set_len(cmp_item, asn1->offset - cmp_start);
2321 dissect_ansi_tcap_unidirectional(ASN1_SCK *asn1, proto_tree *tcap_tree)
2323 guint saved_offset = 0;
2327 proto_item *trans_item;
2328 guint trans_start = asn1->offset;
2331 saved_offset = asn1->offset;
2332 ret = asn1_id_decode1(asn1, &tag);
2334 if (ST_ANSI_TID_TAG != tag)
2336 asn1->offset = saved_offset;
2340 trans_item = proto_tree_add_text(tcap_tree, asn1->tvb, saved_offset, -1, "Transaction Portion");
2342 dissect_tcap_len(asn1, tcap_tree, &def_len, &len);
2349 proto_item_set_len(trans_item, asn1->offset - trans_start);
2351 dissect_ansi_tcap_components(asn1, tcap_tree);
2357 dissect_ansi_tcap_qwp_qwop(ASN1_SCK *asn1, proto_tree *tcap_tree, proto_item *ti)
2359 proto_tree *subtree;
2360 guint saved_offset = 0;
2364 proto_item *trans_item;
2365 guint trans_start = asn1->offset;
2370 saved_offset = asn1->offset;
2371 ret = asn1_id_decode1(asn1, &tag);
2373 if (ST_ANSI_TID_TAG != tag)
2375 asn1->offset = saved_offset;
2379 trans_item = proto_tree_add_text(tcap_tree, asn1->tvb, saved_offset, -1, "Transaction Portion");
2380 subtree = proto_item_add_subtree(trans_item, ett_dlg_portion);
2382 proto_tree_add_uint_format(subtree, hf_tcap_tag, asn1->tvb, saved_offset, asn1->offset - saved_offset, tag,
2383 "Originating Transaction ID Identifier");
2385 dissect_tcap_len(asn1, tcap_tree, &def_len, &len);
2392 saved_offset = asn1->offset;
2393 ret = asn1_string_value_decode(asn1, len, &poctets);
2395 memcpy(&val, poctets, len);
2396 ti = proto_tree_add_uint(subtree, hf_tcap_id, asn1->tvb, saved_offset, asn1->offset - saved_offset, val);
2399 if (check_col(g_pinfo->cinfo, COL_INFO))
2400 col_append_fstr(g_pinfo->cinfo, COL_INFO, "otid(%x) ", val);
2402 proto_item_set_len(trans_item, asn1->offset - trans_start);
2404 dissect_ansi_tcap_components(asn1, tcap_tree);
2410 dissect_ansi_tcap_abort(ASN1_SCK *asn1, proto_tree *tcap_tree, proto_item *ti)
2412 proto_tree *subtree;
2413 guint saved_offset = 0;
2417 proto_item *trans_item;
2418 guint trans_start = asn1->offset;
2425 saved_offset = asn1->offset;
2426 ret = asn1_id_decode1(asn1, &tag);
2428 if (ST_ANSI_TID_TAG != tag)
2430 asn1->offset = saved_offset;
2435 proto_tree_add_text(tcap_tree, asn1->tvb,
2436 saved_offset, -1, "Transaction Portion");
2438 subtree = proto_item_add_subtree(trans_item, ett_dlg_portion);
2440 proto_tree_add_uint_format(subtree, hf_tcap_tag, asn1->tvb,
2441 saved_offset, asn1->offset - saved_offset, tag,
2442 "Responding Transaction ID Identifier");
2444 dissect_tcap_len(asn1, subtree, &def_len, &len);
2451 saved_offset = asn1->offset;
2452 ret = asn1_string_value_decode(asn1, len, &poctets);
2455 memcpy(&val, poctets, len);
2456 ti = proto_tree_add_uint(subtree, hf_tcap_id, asn1->tvb, saved_offset, asn1->offset - saved_offset, val);
2459 if (check_col(g_pinfo->cinfo, COL_INFO))
2460 col_append_fstr(g_pinfo->cinfo, COL_INFO, "rtid(%x) ", val);
2462 proto_item_set_len(trans_item, asn1->offset - trans_start);
2464 if (tvb_length_remaining(asn1->tvb, asn1->offset) <= 0)
2466 proto_tree_add_text(tcap_tree, asn1->tvb, asn1->offset, -1,
2467 "!!! Missing Component Portion !!!");
2472 saved_offset = asn1->offset;
2473 ret = asn1_id_decode1(asn1, &tag);
2475 #define ANSI_TC_PABRT_CAUSE_TAG 0xd7
2476 if (tag == ANSI_TC_PABRT_CAUSE_TAG)
2479 proto_tree_add_text(tcap_tree, asn1->tvb, saved_offset, -1, "P-Abort Portion");
2481 subtree = proto_item_add_subtree(trans_item, ett_dlg_abort);
2483 dissect_tcap_len(asn1, subtree, &def_len, &len);
2485 proto_item_set_len(trans_item, (asn1->offset - saved_offset) + len);
2487 saved_offset = asn1->offset;
2488 asn1_int32_value_decode(asn1, len, &value);
2492 case 1: str = "Unrecognized Package Type"; break;
2493 case 2: str = "Incorrect Transaction Portion"; break;
2494 case 3: str = "Badly Structured Transaction Portion"; break;
2495 case 4: str = "Unrecognized Transaction ID"; break;
2496 case 5: str = "Permission to Release"; break;
2497 case 6: str = "Resource Unavailable"; break;
2503 proto_tree_add_text(subtree, asn1->tvb,
2504 saved_offset, asn1->offset - saved_offset, "P-Abort Cause Value %s (%d)",
2507 #define ANSI_TC_UABRT_INFO_TAG 0xd8
2508 else if (tag == ANSI_TC_UABRT_INFO_TAG)
2511 proto_tree_add_text(tcap_tree, asn1->tvb, saved_offset, -1, "U-Abort Portion");
2513 subtree = proto_item_add_subtree(trans_item, ett_dlg_abort);
2515 dissect_tcap_len(asn1, subtree, &def_len, &len);
2518 dissect_tcap_integer(asn1, subtree, len, "User Abort Information:");
2526 dissect_ansi_tcap_rsp(ASN1_SCK *asn1, proto_tree *tcap_tree, proto_item *ti)
2528 proto_tree *subtree;
2529 guint saved_offset = 0;
2533 proto_item *trans_item;
2534 guint trans_start = asn1->offset;
2539 saved_offset = asn1->offset;
2540 ret = asn1_id_decode1(asn1, &tag);
2542 if (ST_ANSI_TID_TAG != tag)
2544 asn1->offset = saved_offset;
2548 trans_item = proto_tree_add_text(tcap_tree, asn1->tvb, saved_offset, -1, "Transaction Portion");
2549 subtree = proto_item_add_subtree(trans_item, ett_dlg_portion);
2551 proto_tree_add_uint_format(subtree, hf_tcap_tag, asn1->tvb, saved_offset, asn1->offset - saved_offset, tag,
2552 "Responding Transaction ID Identifier");
2554 dissect_tcap_len(asn1, tcap_tree, &def_len, &len);
2561 saved_offset = asn1->offset;
2562 ret = asn1_string_value_decode(asn1, len, &poctets);
2564 memcpy(&val, poctets, len);
2565 ti = proto_tree_add_uint(subtree, hf_tcap_id, asn1->tvb, saved_offset, asn1->offset - saved_offset, val);
2568 if (check_col(g_pinfo->cinfo, COL_INFO))
2569 col_append_fstr(g_pinfo->cinfo, COL_INFO, "rtid(%x) ", val);
2571 proto_item_set_len(trans_item, asn1->offset - trans_start);
2573 dissect_ansi_tcap_components(asn1, tcap_tree);
2579 dissect_ansi_tcap_cwp_cwop(ASN1_SCK *asn1, proto_tree *tcap_tree, proto_item *ti)
2581 proto_tree *subtree;
2582 guint saved_offset = 0;
2586 proto_item *trans_item;
2587 guint trans_start = asn1->offset;
2592 saved_offset = asn1->offset;
2593 ret = asn1_id_decode1(asn1, &tag);
2595 if (ST_ANSI_TID_TAG != tag)
2597 asn1->offset = saved_offset;
2601 trans_item = proto_tree_add_text(tcap_tree, asn1->tvb, saved_offset, -1, "Transaction Portion");
2602 subtree = proto_item_add_subtree(trans_item, ett_dlg_portion);
2604 proto_tree_add_uint_format(subtree, hf_tcap_tag, asn1->tvb, saved_offset, asn1->offset - saved_offset, tag,
2605 "Transaction ID Identifier");
2607 dissect_tcap_len(asn1, tcap_tree, &def_len, &len);
2614 saved_offset = asn1->offset;
2615 ret = asn1_string_value_decode(asn1, 4, &poctets);
2617 memcpy(&val, poctets, 4);
2618 ti = proto_tree_add_uint(subtree, hf_tcap_id, asn1->tvb, saved_offset, asn1->offset - saved_offset, val);
2621 if (check_col(g_pinfo->cinfo, COL_INFO))
2622 col_append_fstr(g_pinfo->cinfo, COL_INFO, "otid(%x) ", val);
2624 saved_offset = asn1->offset;
2625 ret = asn1_string_value_decode(asn1, 4, &poctets);
2627 memcpy(&val, poctets, 4);
2628 ti = proto_tree_add_uint(subtree, hf_tcap_id, asn1->tvb, saved_offset, asn1->offset - saved_offset, val);
2631 if (check_col(g_pinfo->cinfo, COL_INFO))
2632 col_append_fstr(g_pinfo->cinfo, COL_INFO, "rtid(%x) ", val);
2634 proto_item_set_len(trans_item, asn1->offset - trans_start);
2636 dissect_ansi_tcap_components(asn1, tcap_tree);
2642 dissect_ansi_tcap_message(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tcap_tree)
2648 guint saved_offset = 0;
2653 asn1_open(&asn1, tvb, offset);
2655 asn1_id_decode1(&asn1, &msg_type_tag);
2657 str = match_strval(msg_type_tag, ansi_msg_type_strings);
2661 proto_tree_add_text(tcap_tree, asn1.tvb, offset, -1, "Unknown message type, ignoring");
2665 if (check_col(pinfo->cinfo, COL_INFO))
2667 col_set_str(pinfo->cinfo, COL_INFO, str);
2668 col_append_str(pinfo->cinfo, COL_INFO, " ");
2671 proto_tree_add_uint_hidden(tcap_tree, hf_tcap_ssn, asn1.tvb, offset,
2672 0, pinfo->match_port); /* len -1 is unacceptable */
2674 ti = proto_tree_add_uint(tcap_tree, hf_ansi_tcap_message_type, asn1.tvb, offset, asn1.offset - saved_offset,
2677 dissect_tcap_len(&asn1, tcap_tree, &def_len, &len);
2679 switch(msg_type_tag)
2681 case ANSI_ST_MSG_TYP_UNI:
2682 dissect_ansi_tcap_unidirectional(&asn1, tcap_tree);
2684 case ANSI_ST_MSG_TYP_QWP:
2685 dissect_ansi_tcap_qwp_qwop(&asn1, tcap_tree, ti);
2687 case ANSI_ST_MSG_TYP_QWOP:
2688 dissect_ansi_tcap_qwp_qwop(&asn1, tcap_tree, ti);
2690 case ANSI_ST_MSG_TYP_RSP:
2691 dissect_ansi_tcap_rsp(&asn1, tcap_tree, ti);
2693 case ANSI_ST_MSG_TYP_CWP:
2694 dissect_ansi_tcap_cwp_cwop(&asn1, tcap_tree, ti);
2696 case ANSI_ST_MSG_TYP_CWOP:
2697 dissect_ansi_tcap_cwp_cwop(&asn1, tcap_tree, ti);
2699 case ANSI_ST_MSG_TYP_ABT:
2700 dissect_ansi_tcap_abort(&asn1, tcap_tree, ti);
2703 proto_tree_add_text(tcap_tree, asn1.tvb, offset, -1,
2704 "Message type not handled, ignoring");
2708 asn1_close(&asn1, &saved_offset);
2711 /* Code to actually dissect the packets */
2713 dissect_tcap(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
2716 proto_tree *tcap_tree;
2720 if (check_col(pinfo->cinfo, COL_PROTOCOL))
2721 col_set_str(pinfo->cinfo, COL_PROTOCOL, "TCAP");
2723 /* In the interest of speed, if "tree" is NULL, don't do any
2724 * work not necessary to generate protocol tree items.
2728 ti = proto_tree_add_item(tree, proto_tcap, tvb, 0, -1, FALSE);
2729 tcap_tree = proto_item_add_subtree(ti, ett_tcap);
2732 if (tcap_standard == ITU_TCAP_STANDARD)
2734 dissect_tcap_message(tvb, pinfo, tcap_tree);
2738 dissect_ansi_tcap_message(tvb, pinfo, tcap_tree);
2744 /* Register the protocol with Ethereal */
2746 /* this format is require because a script is used to build the C function
2747 that calls all the protocol registration.
2750 proto_register_tcap(void)
2753 /* Setup list of header fields See Section 1.6.1 for details*/
2754 static hf_register_info hf[] = {
2755 /*{ &hf_tcap_FIELDABBREV,
2756 { "FIELDNAME", "PROTOABBREV.FIELDABBREV",
2757 FIELDTYPE, FIELDBASE, FIELDCONVERT, BITMASK,
2761 { "Tag", "tcap.msgtype",
2762 FT_UINT8, BASE_HEX, NULL, 0,
2766 { "Length", "tcap.len",
2767 FT_UINT8, BASE_HEX, NULL, 0,
2771 { "Value", "tcap.id",
2772 FT_UINT8, BASE_HEX, NULL, 0,
2775 { &hf_tcap_message_type,
2776 { "Message Type", "tcap.msgtype",
2777 FT_UINT8, BASE_HEX, VALS(msg_type_strings), 0,
2780 { &hf_ansi_tcap_message_type,
2781 { "Message Type", "tcap.msgtype",
2782 FT_UINT8, BASE_HEX, VALS(ansi_msg_type_strings), 0,
2786 { "Transaction Id", "tcap.tid",
2787 FT_UINT32, BASE_DEC, VALS(tid_strings), 0,
2791 { "Called or Calling SubSystem Number", "tcap.ssn",
2792 FT_UINT8, BASE_DEC, 0x0, 0x0,
2795 { &hf_tcap_dlg_type,
2796 { "Dialogue Type", "tcap.dlgtype",
2797 FT_UINT8, BASE_HEX, VALS(dlg_type_strings), 0,
2800 { &hf_tcap_app_con_name,
2801 { "Application Context Name", "tcap.dlg.appconname",
2802 FT_BYTES, BASE_HEX, 0, 0,
2806 { "Binary Data", "tcap.data",
2807 FT_BYTES, BASE_HEX, 0, 0,
2811 { "Integer Data", "tcap.data",
2812 FT_INT32, BASE_DEC, 0, 0,
2817 /* Setup protocol subtree array */
2818 static gint *ett[] = {
2835 static enum_val_t tcap_options[] = {
2836 { "ITU", ITU_TCAP_STANDARD },
2837 { "ANSI", ANSI_TCAP_STANDARD },
2841 module_t *tcap_module;
2843 /* Register the protocol name and description */
2844 proto_tcap = proto_register_protocol("Transaction Capabilities Application Part",
2847 /* Required function calls to register the header fields and subtrees used */
2848 proto_register_field_array(proto_tcap, hf, array_length(hf));
2849 proto_register_subtree_array(ett, array_length(ett));
2851 tcap_module = prefs_register_protocol(proto_tcap, NULL);
2853 prefs_register_enum_preference(tcap_module, "standard", "TCAP standard",
2854 "The SS7 standard used in TCAP packets",
2855 (gint *)&tcap_standard, tcap_options, FALSE);
2857 prefs_register_bool_preference(tcap_module, "lock_info_col", "Lock Info column",
2858 "Always show TCAP in Info column",
2861 /* we will fake a ssn subfield which has the same value obtained from sccp */
2862 tcap_itu_ssn_dissector_table = register_dissector_table("tcap.itu_ssn", "ITU TCAP SSN", FT_UINT8, BASE_DEC);
2863 tcap_ansi_ssn_dissector_table = register_dissector_table("tcap.ansi_ssn", "ANSI TCAP SSN", FT_UINT8, BASE_DEC);
2867 /* If this dissector uses sub-dissector registration add a registration routine.
2868 This format is required because a script is used to find these routines and
2869 create the code that calls these routines.
2872 proto_reg_handoff_tcap(void)
2874 dissector_handle_t tcap_handle;
2876 tcap_handle = create_dissector_handle(dissect_tcap,
2879 dissector_add("sccp.ssn", 5, tcap_handle); /* MAP*/
2880 dissector_add("sccp.ssn", 6, tcap_handle); /* HLR*/
2881 dissector_add("sccp.ssn", 7, tcap_handle); /* VLR */
2882 dissector_add("sccp.ssn", 8, tcap_handle); /* MSC */
2883 dissector_add("sccp.ssn", 9, tcap_handle); /* EIR */
2884 dissector_add("sccp.ssn", 10, tcap_handle); /* EIR */
2885 dissector_add("sccp.ssn", 11, tcap_handle); /* SMS/MC */
2886 dissector_add("sccp.ssn", 12, tcap_handle); /* IS41 OTAF */
2888 dissector_add("sua.ssn", 5, tcap_handle); /* MAP*/
2889 dissector_add("sua.ssn", 6, tcap_handle); /* HLR*/
2890 dissector_add("sua.ssn", 7, tcap_handle); /* VLR */
2891 dissector_add("sua.ssn", 8, tcap_handle); /* MSC */
2892 dissector_add("sua.ssn", 9, tcap_handle); /* EIR */
2893 dissector_add("sua.ssn", 10, tcap_handle); /* EIR */
2894 dissector_add("sua.ssn", 11, tcap_handle); /* SMS/MC */
2895 dissector_add("sua.ssn", 12, tcap_handle); /* IS41 OTAF */
2897 data_handle = find_dissector("data");