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.1 2003/10/02 06:13:28 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;
69 void proto_reg_handoff_tcap(void);
72 static packet_info *g_pinfo = NULL;
73 static proto_tree *g_tcap_tree = NULL;
74 static gboolean g_tcap_ends_def_len = FALSE;
76 /* Initialize the protocol and registered fields */
77 static int proto_tcap = -1;
78 static int hf_tcap_message_type = -1;
79 static int hf_ansi_tcap_message_type = -1;
80 static int hf_tcap_none = -1;
81 static int hf_tcap_tag = -1;
82 static int hf_tcap_length = -1;
83 static int hf_tcap_bytes = -1;
84 static int hf_tcap_app_con_name = -1;
85 static int hf_tcap_id = -1;
86 static int hf_tcap_tid = -1;
87 static int hf_tcap_ssn = -1; /* faked */
88 static int hf_tcap_dlg_type = -1;
89 static int hf_tcap_cmp_type = -1;
90 static int hf_ansi_tcap_cmp_type = -1;
91 static int hf_tcap_int = -1;
93 /* Initialize the subtree pointers */
94 static gint ett_tcap = -1;
96 static gint ett_otid = -1;
97 static gint ett_dtid = -1;
98 static gint ett_dlg_portion = -1;
99 static gint ett_dlg_req = -1;
100 static gint ett_dlg_rsp = -1;
101 static gint ett_dlg_abrt = -1;
102 static gint ett_cmp_portion = -1;
103 static gint ett_reason = -1;
104 static gint ett_component = -1;
105 static gint ett_problem = -1;
106 static gint ett_error = -1;
107 static gint ett_params = -1;
108 static gint ett_param = -1;
110 static dissector_handle_t data_handle;
111 static dissector_table_t tcap_itu_ssn_dissector_table; /* map use ssn in sccp */
112 static dissector_table_t tcap_ansi_ssn_dissector_table; /* map use ssn in sccp */
113 static gboolean lock_info_col = TRUE;
115 #define TC_SEQ_TAG 0x30
116 #define TC_SET_TAG 0x31
118 #define TC_EOC_LEN 2 /* 0x00 0x00 */
120 /* TCAP transaction message type definition - Samuel */
121 #define ST_MSG_TYP_UNI 0x61 /*0b01100001*/
122 #define ST_MSG_TYP_BGN 0x62 /*0b01100010*/
123 #define ST_MSG_TYP_CNT 0x65 /*0b01100101*/
124 #define ST_MSG_TYP_END 0x64 /*0b01100100*/
125 #define ST_MSG_TYP_PABT 0x67 /*0b01100111*/
126 static const value_string msg_type_strings[] = {
127 { ST_MSG_TYP_UNI, "TC-UNI" },
128 { ST_MSG_TYP_BGN, "TC-BEGIN" },
129 { ST_MSG_TYP_CNT, "TC-CONTINUE" },
130 { ST_MSG_TYP_END, "TC-END" },
131 { ST_MSG_TYP_PABT, "TC-PABORT" },
135 /* ANSI TCAP transaction message type definition */
136 #define ANSI_ST_MSG_TYP_UNI 0xe1
137 #define ANSI_ST_MSG_TYP_QWP 0xe2
138 #define ANSI_ST_MSG_TYP_QWOP 0xe3
139 #define ANSI_ST_MSG_TYP_RSP 0xe4
140 #define ANSI_ST_MSG_TYP_CWP 0xe5
141 #define ANSI_ST_MSG_TYP_CWOP 0xe6
142 #define ANSI_ST_MSG_TYP_PABT 0xf6
143 static const value_string ansi_msg_type_strings[] = {
144 { ANSI_ST_MSG_TYP_UNI, "TC-UNI" },
145 { ANSI_ST_MSG_TYP_QWP, "TC-QUERY W PERM" },
146 { ANSI_ST_MSG_TYP_QWOP, "TC-QUERY WO PERM" },
147 { ANSI_ST_MSG_TYP_RSP, "TC-RESPONSE" },
148 { ANSI_ST_MSG_TYP_CWP, "TC-CONV W PERM" },
149 { ANSI_ST_MSG_TYP_CWOP, "TC-CONV WO PERM" },
150 { ANSI_ST_MSG_TYP_PABT, "TC-PABORT" },
154 #define ST_ANSI_CMP_TAG 0xe8
155 #define ST_ANSI_TID_TAG 0xc7
157 /* TCAP TID tag value - Samuel */
158 #define ST_TID_SOURCE 0
159 #define ST_TID_DEST 1
160 #define ST_ITU_ORG_TID_TAG 0x48 /*0b01001000*/
161 #define ST_ITU_DST_TID_TAG 0x49 /*0b01001001*/
162 #define ST_ITU_PABT_TAG 0x4a /*0b01001010*/
163 #define ST_ITU_DLG_TAG 0x6b
164 #define ST_ITU_CMP_TAG 0x6c
166 static const value_string tid_strings[] = {
167 { ST_ITU_ORG_TID_TAG, "Source Transaction ID" },
168 { ST_ITU_DST_TID_TAG, "Destination Transaction ID" },
172 /* TCAP dialog type */
173 #define TC_DLG_REQ 0x60
174 #define TC_DLG_RSP 0x61
175 #define TC_DLG_ABRT 0x64
177 static const value_string dlg_type_strings[] = {
178 { TC_DLG_REQ , "Dialogue Request" },
179 { TC_DLG_RSP , "Dialogue Response" },
180 { TC_DLG_ABRT, "Dialogue Abort" },
184 /* TCAP component type */
185 #define TC_INVOKE 0xa1
188 #define TC_REJECT 0xa4
191 static const value_string cmp_type_strings[] = {
192 { TC_INVOKE, "Invoke" },
193 { TC_RRL, "Return Result(Last)" },
194 { TC_RE, "Return Error" },
195 { TC_REJECT, "Reject" },
196 { TC_RRN, "Return Result(Not Last)" },
200 /* ANSI TCAP component type */
201 #define ANSI_TC_INVOKE_L 0xe9
202 #define ANSI_TC_RRL 0xea
203 #define ANSI_TC_RE 0xeb
204 #define ANSI_TC_REJECT 0xec
205 #define ANSI_TC_INVOKE_N 0xed
206 #define ANSI_TC_RRN 0xee
208 static const value_string ansi_cmp_type_strings[] = {
209 { ANSI_TC_INVOKE_L, "Invoke(Last)" },
210 { ANSI_TC_RRL, "Return Result(Last)" },
211 { ANSI_TC_RE, "Return Error" },
212 { ANSI_TC_REJECT, "Reject" },
213 { ANSI_TC_INVOKE_N, "Invoke(Not Last)" },
214 { ANSI_TC_RRN, "Return Result(Not Last)" },
224 dissect_tcap_len(ASN1_SCK *asn1, proto_tree *tree, gboolean *def_len, guint *len)
229 saved_offset = asn1->offset;
232 ret = asn1_length_decode(asn1, def_len, len);
236 proto_tree_add_uint(tree, hf_tcap_length, asn1->tvb, saved_offset, asn1->offset - saved_offset, *len);
240 proto_tree_add_none_format(tree, hf_tcap_none, asn1->tvb,
241 saved_offset, asn1->offset - saved_offset, "Length: Indefinite");
248 dissect_tcap_eoc(ASN1_SCK *asn1, proto_tree *tree)
250 guint saved_offset, ret;
252 saved_offset = asn1->offset;
254 if (tvb_length_remaining(asn1->tvb, saved_offset) <= 0)
259 if (!asn1_eoc(asn1, -1))
264 ret = asn1_eoc_decode(asn1, -1);
266 proto_tree_add_none_format(tree, hf_tcap_none, asn1->tvb,
267 saved_offset, asn1->offset - saved_offset, "End of Contents");
273 dissect_tcap_tag(ASN1_SCK *asn1, proto_tree *tree, guint *tag, guchar * str)
275 guint saved_offset, real_tag;
277 saved_offset = asn1->offset;
278 asn1_id_decode1(asn1, &real_tag);
279 if ((*tag != (guint) -1) && (real_tag != *tag))
281 asn1->offset = saved_offset;
284 proto_tree_add_uint_format(tree, hf_tcap_tag, asn1->tvb, saved_offset, asn1->offset - saved_offset,
290 dissect_tcap_octet(ASN1_SCK *asn1, proto_tree *tree, guchar * str)
295 saved_offset = asn1->offset;
296 asn1_octet_decode(asn1, &my_oct);
297 proto_tree_add_uint_format(tree, hf_tcap_id, asn1->tvb, saved_offset, asn1->offset - saved_offset,
298 my_oct, "%s %d", str, my_oct);
303 dissect_tcap_integer(ASN1_SCK *asn1, proto_tree *tree, guint len, guchar * str)
308 saved_offset = asn1->offset;
309 asn1_int32_value_decode(asn1, len, &invokeId);
310 proto_tree_add_int_format(tree, hf_tcap_int, asn1->tvb, saved_offset, asn1->offset - saved_offset,
311 invokeId, "%s %d", str, invokeId);
316 check_tcap_tag(ASN1_SCK *asn1, guint tag)
318 guint saved_offset, real_tag;
320 if (tvb_length_remaining(asn1->tvb, asn1->offset) <= 0)
325 saved_offset = asn1->offset;
326 asn1_id_decode1(asn1, &real_tag);
327 asn1->offset = saved_offset;
328 return (tag == real_tag);
333 dissect_tcap_tid(ASN1_SCK *asn1, proto_tree *tcap_tree, proto_item *ti, int type)
335 guint saved_offset, org_offset = 0;
339 proto_item *tid_item;
345 org_offset = asn1->offset;
346 if ( ST_TID_SOURCE == type)
348 tid_item = proto_tree_add_none_format(tcap_tree, hf_tcap_none, asn1->tvb, asn1->offset, -1, "Source Transaction ID");
349 subtree = proto_item_add_subtree(tid_item, ett_otid);
353 tid_item = proto_tree_add_none_format(tcap_tree, hf_tcap_none, asn1->tvb, asn1->offset, -1, "Destination Transaction ID");
354 subtree = proto_item_add_subtree(tid_item, ett_dtid);
357 saved_offset = asn1->offset;
358 ret = asn1_id_decode1(asn1, &tag);
359 proto_tree_add_uint(subtree, hf_tcap_tid, asn1->tvb, saved_offset, asn1->offset - saved_offset, tag);
365 if (ST_ITU_ORG_TID_TAG != tag)
367 asn1->offset = saved_offset;
372 if (ST_ITU_DST_TID_TAG != tag)
374 asn1->offset = saved_offset;
383 dissect_tcap_len(asn1, subtree, &def_len, &len);
385 saved_offset = asn1->offset;
386 ret = asn1_string_value_decode(asn1, len, &poctets);
388 memcpy(&val, poctets, len);
390 ti = proto_tree_add_uint(subtree, hf_tcap_id, asn1->tvb, saved_offset, asn1->offset - saved_offset, val);
393 proto_item_set_len(tid_item, asn1->offset - org_offset);
395 if (type == ST_TID_DEST)
397 if (check_col(g_pinfo->cinfo, COL_INFO))
398 col_append_fstr(g_pinfo->cinfo, COL_INFO, "dtid(%x) ", val);
402 if (check_col(g_pinfo->cinfo, COL_INFO))
403 col_append_fstr(g_pinfo->cinfo, COL_INFO, "stid(%x) ", val);
410 /* dissect operation portion */
412 dissect_tcap_invokeId(ASN1_SCK *asn1, proto_tree *tree)
418 #define INVOKE_ID_TAG 0x2
419 if (check_tcap_tag(asn1, INVOKE_ID_TAG))
422 dissect_tcap_tag(asn1, tree, &tag, "Invoke ID Tag");
423 dissect_tcap_len(asn1, tree, &def_len, &len);
424 dissect_tcap_integer(asn1, tree, len, "Invoke ID:");
431 dissect_tcap_lnkId(ASN1_SCK *asn1, proto_tree *tree)
437 #define LINK_ID_TAG 0x80
438 if (check_tcap_tag(asn1, LINK_ID_TAG))
441 dissect_tcap_tag(asn1, tree, &tag, "Linked ID Tag");
442 dissect_tcap_len(asn1, tree, &def_len, &len);
443 dissect_tcap_integer(asn1, tree, len, "Linked ID:");
450 dissect_tcap_opr_code(ASN1_SCK *asn1, proto_tree *tree)
454 gboolean got_it = FALSE;
457 #define TCAP_LOC_OPR_CODE_TAG 0x02
458 if (check_tcap_tag(asn1, TCAP_LOC_OPR_CODE_TAG))
461 dissect_tcap_tag(asn1, tree, &tag, "Local Operation Code Tag");
464 #define TCAP_GLB_OPR_CODE_TAG 0x06
465 else if (check_tcap_tag(asn1, TCAP_GLB_OPR_CODE_TAG))
468 dissect_tcap_tag(asn1, tree, &tag, "Global Operation Code Tag");
474 dissect_tcap_len(asn1, tree, &def_len, &len);
476 proto_tree_add_none_format(tree, hf_tcap_none, asn1->tvb, asn1->offset, len, "Operation Code");
483 dissect_tcap_param(ASN1_SCK *asn1, proto_tree *tree)
485 guint off_tree[100], saved_offset, len_offset;
489 proto_item *item_tree[100], *item;
490 proto_tree *seq_tree[100], *use_tree, *subtree;
495 #define TC_INVALID_TAG 0
496 while ((tvb_length_remaining(asn1->tvb, asn1->offset) > 0) &&
497 (!check_tcap_tag(asn1, 0)))
499 saved_offset = asn1->offset;
500 asn1_id_decode1(asn1, &tag);
501 len_offset = asn1->offset;
502 asn1_length_decode(asn1, &def_len, &len);
504 if (tag == TC_SEQ_TAG)
507 proto_tree_add_none_format(use_tree, hf_tcap_none, asn1->tvb,
508 saved_offset, -1, "Sequence");
510 subtree = proto_item_add_subtree(item, ett_params);
512 proto_tree_add_uint_format(subtree, hf_tcap_tag, asn1->tvb,
513 saved_offset, len_offset - saved_offset, tag, "Sequence Tag");
517 proto_tree_add_none_format(subtree, hf_tcap_none, asn1->tvb,
518 len_offset, asn1->offset - len_offset, "Length: Indefinite");
520 seq_tree[num_seq] = subtree;
521 item_tree[num_seq] = item;
522 off_tree[num_seq] = saved_offset;
527 proto_tree_add_uint(subtree, hf_tcap_length, asn1->tvb,
528 len_offset, asn1->offset - len_offset, len);
530 proto_item_set_len(item, (asn1->offset - saved_offset) + len);
539 proto_tree_add_uint_format(use_tree, hf_tcap_tag, asn1->tvb,
540 saved_offset, len_offset - saved_offset, tag, "Parameter Tag");
541 proto_tree_add_none_format(use_tree, hf_tcap_none, asn1->tvb,
542 len_offset, asn1->offset - len_offset, "Length: Indefinite");
544 seq_tree[num_seq] = use_tree;
545 item_tree[num_seq] = NULL;
552 proto_tree_add_none_format(use_tree, hf_tcap_none, asn1->tvb,
553 saved_offset, -1, "Parameter");
555 subtree = proto_item_add_subtree(item, ett_param);
557 proto_tree_add_uint_format(subtree, hf_tcap_tag, asn1->tvb,
558 saved_offset, len_offset - saved_offset, tag, "Parameter Tag");
560 proto_tree_add_uint(subtree, hf_tcap_length, asn1->tvb,
561 len_offset, asn1->offset - len_offset, len);
563 proto_item_set_len(item, (asn1->offset - saved_offset) + len);
565 proto_tree_add_none_format(subtree, hf_tcap_none, asn1->tvb,
566 asn1->offset, len, "Parameter Data");
571 if (tvb_length_remaining(asn1->tvb, asn1->offset) <=0) break;
573 while ((num_seq > 0) &&
576 saved_offset = asn1->offset;
577 asn1_eoc_decode(asn1, -1);
579 proto_tree_add_none_format(seq_tree[num_seq-1], hf_tcap_none, asn1->tvb,
580 saved_offset, asn1->offset - saved_offset, "End of Contents");
582 if (item_tree[num_seq-1] != NULL)
584 proto_item_set_len(item_tree[num_seq-1], asn1->offset - off_tree[num_seq-1]);
595 dissect_tcap_component(ASN1_SCK *asn1, proto_tree *tree, guint *len_p)
604 saved_offset = asn1->offset;
605 asn1_id_decode1(asn1, &tag);
608 proto_tree_add_none_format(tree, hf_tcap_none, asn1->tvb,
609 saved_offset, -1, "Component ID");
611 subtree = proto_item_add_subtree(item, ett_component);
613 proto_tree_add_uint_format(subtree, hf_tcap_tag, asn1->tvb,
614 saved_offset, asn1->offset - saved_offset, tag,
615 "Component ID Identifier");
617 dissect_tcap_len(asn1, subtree, &def_len, len_p);
619 proto_item_set_len(item, (asn1->offset - saved_offset) + *len_p);
625 dissect_tcap_problem(ASN1_SCK *asn1, proto_tree *tree)
627 guint orig_offset, saved_offset = 0;
631 proto_item *item = NULL;
633 gchar *type_str = NULL;
638 orig_offset = asn1->offset;
639 saved_offset = asn1->offset;
640 asn1_id_decode1(asn1, &tag);
641 tag_len = asn1->offset - saved_offset;
644 proto_tree_add_none_format(tree, hf_tcap_none, asn1->tvb,
645 saved_offset, -1, "Problem Code");
647 subtree = proto_item_add_subtree(item, ett_problem);
649 dissect_tcap_len(asn1, subtree, &def_len, &len);
650 proto_item_set_len(item, (asn1->offset - saved_offset) + len);
654 proto_tree_add_none_format(subtree, hf_tcap_none, asn1->tvb,
655 asn1->offset, len, "Unknown encoding of Problem Code");
661 saved_offset = asn1->offset;
662 asn1_int32_value_decode(asn1, 1, &spec);
667 type_str = "General Problem";
670 case 0: str = "Unrecognized Component"; break;
671 case 1: str = "Mistyped Component"; break;
672 case 2: str = "Badly Structured Component"; break;
683 case 0: str = "Duplicate Invoke ID"; break;
684 case 1: str = "Unrecognized Operation"; break;
685 case 2: str = "Mistyped Parameter"; break;
686 case 3: str = "Resource Limitation"; break;
687 case 4: str = "Initiating Release"; break;
688 case 5: str = "Unrecognized Linked ID"; break;
689 case 6: str = "Linked Response Unexpected"; break;
690 case 7: str = "Unexpected Linked Operation"; break;
698 type_str = "Return Result";
701 case 0: str = "Unrecognized Invoke ID"; break;
702 case 1: str = "Return Result Unexpected"; break;
703 case 2: str = "Mistyped Parameter"; break;
711 type_str = "Return Error";
714 case 0: str = "Unrecognized Invoke ID"; break;
715 case 1: str = "Return Error Unexpected"; break;
716 case 2: str = "Unrecognized Error"; break;
717 case 3: str = "Unexpected Error"; break;
718 case 4: str = "Mistyped Parameter"; break;
726 type_str = "Undefined";
730 proto_tree_add_uint_format(subtree, hf_tcap_tag, asn1->tvb,
731 orig_offset, tag_len, tag, type_str);
733 proto_tree_add_none_format(subtree, hf_tcap_none, asn1->tvb,
734 saved_offset, 1, "Problem Specifier %s", str);
739 dissect_ansi_opr_code(ASN1_SCK *asn1, proto_tree *tree)
743 gboolean got_it = FALSE;
746 #define TCAP_NAT_OPR_CODE_TAG 0xd0
747 if (check_tcap_tag(asn1, TCAP_NAT_OPR_CODE_TAG))
750 dissect_tcap_tag(asn1, tree, &tag, "National TCAP Operation Code Identifier");
753 #define TCAP_PRIV_OPR_CODE_TAG 0xd1
754 else if (check_tcap_tag(asn1, TCAP_PRIV_OPR_CODE_TAG))
757 dissect_tcap_tag(asn1, tree, &tag, "Private TCAP Operation Code Identifier");
763 dissect_tcap_len(asn1, tree, &def_len, &len);
765 proto_tree_add_none_format(tree, hf_tcap_none, asn1->tvb, asn1->offset, len, "Operation Code");
772 dissect_ansi_problem(ASN1_SCK *asn1, proto_tree *tree)
774 guint saved_offset = 0;
778 proto_item *item = NULL;
780 gchar *type_str = NULL;
785 #define TCAP_PROB_CODE_TAG 0xd5
786 if (check_tcap_tag(asn1, TCAP_PROB_CODE_TAG))
788 str = "Problem Code Identifier";
796 saved_offset = asn1->offset;
797 asn1_id_decode1(asn1, &tag);
800 proto_tree_add_none_format(tree, hf_tcap_none, asn1->tvb,
801 saved_offset, -1, "Problem Code");
803 subtree = proto_item_add_subtree(item, ett_problem);
805 proto_tree_add_uint_format(subtree, hf_tcap_tag, asn1->tvb,
806 saved_offset, asn1->offset - saved_offset, tag, str);
808 dissect_tcap_len(asn1, subtree, &def_len, &len);
809 proto_item_set_len(item, (asn1->offset - saved_offset) + len);
813 proto_tree_add_none_format(subtree, hf_tcap_none, asn1->tvb,
814 asn1->offset, len, "Unknown encoding of Problem Code");
820 saved_offset = asn1->offset;
821 asn1_int32_value_decode(asn1, 1, &type);
822 asn1_int32_value_decode(asn1, 1, &spec);
826 case 0: type_str = "Not used"; break;
829 type_str = "General";
832 case 1: str = "Unrecognized Component Type"; break;
833 case 2: str = "Incorrect Component Portion"; break;
834 case 3: str = "Badly Structured Component Portion"; break;
845 case 1: str = "Duplicate Invoke ID"; break;
846 case 2: str = "Unrecognized Operation Code"; break;
847 case 3: str = "Incorrect Parameter"; break;
848 case 4: str = "Unrecognized Correlation ID"; break;
856 type_str = "Return Result";
859 case 1: str = "Unrecognized Correlation ID"; break;
860 case 2: str = "Unexpected Return Result"; break;
861 case 3: str = "Incorrect Parameter"; break;
869 type_str = "Return Error";
872 case 1: str = "Unrecognized Correlation ID"; break;
873 case 2: str = "Unexpected Return Error"; break;
874 case 3: str = "Unrecognized Error"; break;
875 case 4: str = "Unexpected Error"; break;
876 case 5: str = "Incorrect Parameter"; break;
884 type_str = "Transaction Portion";
887 case 1: str = "Unrecognized Package Type"; break;
888 case 2: str = "Incorrect Transaction Portion"; break;
889 case 3: str = "Badly Structured Transaction Portion"; break;
890 case 4: str = "Unrecognized Transaction ID"; break;
891 case 5: str = "Permission to Release"; break;
892 case 6: str = "Resource Unavailable"; break;
900 type_str = "Undefined";
904 if (spec == 255) { str = "Reserved"; }
905 else if (spec == 0) { str = "Not used"; }
907 proto_tree_add_none_format(subtree, hf_tcap_none, asn1->tvb,
908 saved_offset, 1, "Problem Type %s", type_str);
910 proto_tree_add_none_format(subtree, hf_tcap_none, asn1->tvb,
911 saved_offset + 1, 1, "Problem Specifier %s", str);
916 dissect_ansi_error(ASN1_SCK *asn1, proto_tree *tree)
918 guint saved_offset = 0;
922 proto_item *item = NULL;
927 #define TCAP_NAT_ERR_CODE_TAG 0xd3
928 if (check_tcap_tag(asn1, TCAP_NAT_ERR_CODE_TAG))
930 str = "National TCAP Error Code Identifier";
932 #define TCAP_PRIV_ERR_CODE_TAG 0xd4
933 else if (check_tcap_tag(asn1, TCAP_PRIV_ERR_CODE_TAG))
935 str = "Private TCAP Error Code Identifier";
943 saved_offset = asn1->offset;
944 asn1_id_decode1(asn1, &tag);
947 proto_tree_add_none_format(tree, hf_tcap_none, asn1->tvb,
948 saved_offset, -1, "TCAP Error Code");
950 subtree = proto_item_add_subtree(item, ett_error);
952 proto_tree_add_uint_format(subtree, hf_tcap_tag, asn1->tvb,
953 saved_offset, asn1->offset - saved_offset, tag, str);
955 dissect_tcap_len(asn1, subtree, &def_len, &len);
956 proto_item_set_len(item, (asn1->offset - saved_offset) + len);
958 proto_tree_add_none_format(subtree, hf_tcap_none, asn1->tvb,
959 asn1->offset, len, "Error Code");
966 dissect_ansi_param(ASN1_SCK *asn1, proto_tree *tree)
970 gboolean got_it = FALSE;
973 #define TCAP_PARAM_SET_TAG 0xf2
974 if (check_tcap_tag(asn1, TCAP_PARAM_SET_TAG))
977 dissect_tcap_tag(asn1, tree, &tag, "Parameter Set Identifier");
980 #define TCAP_PARAM_SEQ_TAG 0x30
981 else if (check_tcap_tag(asn1, TCAP_PARAM_SEQ_TAG))
984 dissect_tcap_tag(asn1, tree, &tag, "Parameter Sequence Identifier");
990 dissect_tcap_len(asn1, tree, &def_len, &len);
992 proto_tree_add_none_format(tree, hf_tcap_none, asn1->tvb, asn1->offset, len, "Parameter Data");
999 dissect_ansi_tcap_reject(ASN1_SCK *asn1, proto_tree *tree)
1002 proto_tree *subtree;
1004 #define COMPONENT_ID_TAG 0xcf
1005 if (check_tcap_tag(asn1, COMPONENT_ID_TAG))
1007 subtree = dissect_tcap_component(asn1, tree, &len);
1012 dissect_tcap_octet(asn1, subtree, "Correlation ID:");
1017 dissect_ansi_problem(asn1, tree);
1019 dissect_ansi_param(asn1, tree);
1023 dissect_ansi_tcap_re(ASN1_SCK *asn1, proto_tree *tree)
1026 proto_tree *subtree;
1028 #define COMPONENT_ID_TAG 0xcf
1029 if (check_tcap_tag(asn1, COMPONENT_ID_TAG))
1031 subtree = dissect_tcap_component(asn1, tree, &len);
1036 dissect_tcap_octet(asn1, tree, "Correlation ID:");
1041 dissect_ansi_error(asn1, tree);
1043 dissect_ansi_param(asn1, tree);
1047 dissect_ansi_tcap_rr(ASN1_SCK *asn1, proto_tree *tree)
1050 proto_tree *subtree;
1052 #define COMPONENT_ID_TAG 0xcf
1053 if (check_tcap_tag(asn1, COMPONENT_ID_TAG))
1055 subtree = dissect_tcap_component(asn1, tree, &len);
1060 dissect_tcap_octet(asn1, tree, "Correlation ID:");
1065 dissect_ansi_param(asn1, tree);
1069 dissect_ansi_tcap_invoke(ASN1_SCK *asn1, proto_tree *tree)
1072 proto_tree *subtree;
1074 #define COMPONENT_ID_TAG 0xcf
1075 if (check_tcap_tag(asn1, COMPONENT_ID_TAG))
1077 subtree = dissect_tcap_component(asn1, tree, &len);
1082 dissect_tcap_octet(asn1, tree, "Invoke ID:");
1086 dissect_tcap_octet(asn1, tree, "Invoke ID:");
1087 dissect_tcap_octet(asn1, tree, "Correlation ID:");
1092 dissect_ansi_opr_code(asn1, tree);
1094 dissect_ansi_param(asn1, tree);
1098 dissect_tcap_invoke(ASN1_SCK *asn1, proto_tree *tree)
1100 proto_tree *subtree;
1101 guint saved_offset = 0;
1106 guint start = asn1->offset;
1109 saved_offset = asn1->offset;
1110 ret = asn1_id_decode1(asn1, &tag);
1111 item = proto_tree_add_none_format(tree, hf_tcap_none, asn1->tvb, saved_offset, -1, "Components");
1112 subtree = proto_item_add_subtree(item, ett_component);
1113 proto_tree_add_uint_format(subtree, hf_tcap_tag, asn1->tvb, saved_offset, asn1->offset - saved_offset,
1114 tag, "Invoke Type Tag");
1116 dissect_tcap_len(asn1, subtree, &def_len, &len);
1120 proto_item_set_len(item, (asn1->offset - start) + len);
1123 dissect_tcap_invokeId(asn1, subtree);
1125 dissect_tcap_lnkId(asn1, subtree);
1127 dissect_tcap_opr_code(asn1, subtree);
1129 dissect_tcap_param(asn1, subtree);
1133 dissect_tcap_eoc(asn1, subtree);
1138 dissect_tcap_rr(ASN1_SCK *asn1, proto_tree *tree, gchar *str)
1140 guint tag, len, comp_len;
1143 proto_tree *subtree;
1145 gboolean comp_def_len;
1148 saved_offset = asn1->offset;
1149 asn1_id_decode1(asn1, &tag);
1150 item = proto_tree_add_none_format(tree, hf_tcap_none, asn1->tvb, saved_offset, -1, "Components");
1151 subtree = proto_item_add_subtree(item, ett_component);
1152 proto_tree_add_uint_format(subtree, hf_tcap_tag, asn1->tvb, saved_offset, asn1->offset - saved_offset,
1155 dissect_tcap_len(asn1, subtree, &comp_def_len, &comp_len);
1159 proto_item_set_len(item, (asn1->offset - saved_offset) + comp_len);
1162 dissect_tcap_invokeId(asn1, subtree);
1165 if (check_tcap_tag(asn1, TC_SEQ_TAG))
1168 dissect_tcap_tag(asn1, subtree, &tag, "Sequence Tag");
1169 dissect_tcap_len(asn1, subtree, &def_len, &len);
1172 dissect_tcap_opr_code(asn1, subtree);
1174 dissect_tcap_param(asn1, subtree);
1178 dissect_tcap_eoc(asn1, subtree);
1183 dissect_tcap_re(ASN1_SCK *asn1, proto_tree *tree)
1185 guint tag, len, comp_len;
1188 proto_tree *subtree;
1192 saved_offset = asn1->offset;
1193 asn1_id_decode1(asn1, &tag);
1194 item = proto_tree_add_none_format(tree, hf_tcap_none, asn1->tvb, saved_offset, -1, "Components");
1195 subtree = proto_item_add_subtree(item, ett_component);
1196 proto_tree_add_uint_format(subtree, hf_tcap_tag, asn1->tvb, saved_offset, asn1->offset - saved_offset,
1197 tag, "Return Error Type Tag");
1199 dissect_tcap_len(asn1, subtree, &def_len, &comp_len);
1203 proto_item_set_len(item, (asn1->offset - saved_offset) + comp_len);
1206 saved_offset = asn1->offset;
1207 dissect_tcap_invokeId(asn1, subtree);
1209 #define TC_LOCAL_ERR_CODE_TAG 0x2
1210 #define TC_GBL_ERR_CODE_TAG 0x6
1211 if (check_tcap_tag(asn1, TC_LOCAL_ERR_CODE_TAG))
1214 dissect_tcap_tag(asn1, subtree, &tag, "Local Error Code Tag");
1216 else if (check_tcap_tag(asn1, TC_GBL_ERR_CODE_TAG))
1219 dissect_tcap_tag(asn1, subtree, &tag, "Global Error Code Tag");
1223 proto_tree_add_none_format(subtree, hf_tcap_none, asn1->tvb, asn1->offset, comp_len,
1224 "Unknown Error Code");
1226 asn1->offset += (comp_len - (asn1->offset - saved_offset));
1230 dissect_tcap_len(asn1, subtree, &def_len, &len);
1231 dissect_tcap_integer(asn1, subtree, len, "Error Code:");
1233 dissect_tcap_param(asn1, subtree);
1237 dissect_tcap_eoc(asn1, subtree);
1244 dissect_tcap_reject(ASN1_SCK *asn1, proto_tree *tree)
1246 guint tag, comp_len;
1249 proto_tree *subtree;
1254 saved_offset = asn1->offset;
1255 asn1_id_decode1(asn1, &tag);
1257 item = proto_tree_add_none_format(tree, hf_tcap_none, asn1->tvb, saved_offset, -1, "Components");
1259 subtree = proto_item_add_subtree(item, ett_component);
1261 proto_tree_add_uint_format(subtree, hf_tcap_tag, asn1->tvb, saved_offset, asn1->offset - saved_offset,
1262 tag, "Reject Type Tag");
1264 dissect_tcap_len(asn1, subtree, &def_len, &comp_len);
1268 proto_item_set_len(item, (asn1->offset - saved_offset) + comp_len);
1271 dissect_tcap_invokeId(asn1, subtree);
1273 dissect_tcap_problem(asn1, tree);
1277 dissect_tcap_eoc(asn1, subtree);
1282 dissect_ansi_tcap_next_tvb(ASN1_SCK *asn1, guint len, proto_tree *tree)
1287 gboolean flag = TRUE;
1289 proto_item *item, *tag_item;
1290 proto_tree *subtree, *tag_subtree;
1294 if (lock_info_col) col_set_fence(g_pinfo->cinfo, COL_INFO);
1296 next_tvb = tvb_new_subset(asn1->tvb, asn1->offset, len, len);
1298 /* process components data */
1299 if (!dissector_try_port(tcap_ansi_ssn_dissector_table, g_pinfo->match_port, next_tvb, g_pinfo, g_tcap_tree))
1303 saved_offset = asn1->offset;
1304 ret = asn1_id_decode1(asn1, &tag);
1307 * verify tag type is known
1311 case ANSI_TC_INVOKE_L :
1314 case ANSI_TC_REJECT :
1315 case ANSI_TC_INVOKE_N :
1327 item = proto_tree_add_none_format(tree, hf_tcap_none, asn1->tvb, saved_offset, -1, "Components");
1328 subtree = proto_item_add_subtree(item, ett_component);
1332 case ANSI_TC_INVOKE_L :
1333 tag_item = proto_tree_add_uint_format(subtree, hf_tcap_tag, asn1->tvb, saved_offset,
1334 asn1->offset - saved_offset, tag, "Invoke(Last)");
1335 dissect_tcap_len(asn1, subtree, &def_len, &len);
1336 tag_subtree = proto_item_add_subtree(tag_item, ett_component);
1338 dissect_ansi_tcap_invoke(asn1, tag_subtree);
1341 tag_item = proto_tree_add_uint_format(subtree, hf_tcap_tag, asn1->tvb, saved_offset,
1342 asn1->offset - saved_offset, tag, "Return Result(Last)");
1343 dissect_tcap_len(asn1, subtree, &def_len, &len);
1344 tag_subtree = proto_item_add_subtree(tag_item, ett_component);
1346 dissect_ansi_tcap_rr(asn1, tag_subtree);
1349 tag_item = proto_tree_add_uint_format(subtree, hf_tcap_tag, asn1->tvb, saved_offset,
1350 asn1->offset - saved_offset, tag, "Return Error");
1351 dissect_tcap_len(asn1, subtree, &def_len, &len);
1352 tag_subtree = proto_item_add_subtree(tag_item, ett_component);
1354 dissect_ansi_tcap_re(asn1, tag_subtree);
1356 case ANSI_TC_REJECT :
1357 tag_item = proto_tree_add_uint_format(subtree, hf_tcap_tag, asn1->tvb, saved_offset,
1358 asn1->offset - saved_offset, tag, "Reject");
1359 dissect_tcap_len(asn1, subtree, &def_len, &len);
1360 tag_subtree = proto_item_add_subtree(tag_item, ett_component);
1362 dissect_ansi_tcap_reject(asn1, tag_subtree);
1364 case ANSI_TC_INVOKE_N :
1365 tag_item = proto_tree_add_uint_format(subtree, hf_tcap_tag, asn1->tvb, saved_offset,
1366 asn1->offset - saved_offset, tag, "Invoke(Not Last)");
1367 dissect_tcap_len(asn1, subtree, &def_len, &len);
1368 tag_subtree = proto_item_add_subtree(tag_item, ett_component);
1370 dissect_ansi_tcap_invoke(asn1, tag_subtree);
1373 tag_item = proto_tree_add_uint_format(subtree, hf_tcap_tag, asn1->tvb, saved_offset,
1374 asn1->offset - saved_offset, tag, "Return Result(Not Last)");
1375 dissect_tcap_len(asn1, subtree, &def_len, &len);
1376 tag_subtree = proto_item_add_subtree(tag_item, ett_component);
1378 dissect_ansi_tcap_rr(asn1, tag_subtree);
1382 proto_item_set_len(item, asn1->offset - saved_offset);
1388 /* No sub-dissection occured, treat it as raw data */
1389 call_dissector(data_handle, next_tvb, g_pinfo, g_tcap_tree);
1394 dissect_tcap_next_tvb(ASN1_SCK *asn1, guint len, proto_tree *tree)
1401 if (lock_info_col) col_set_fence(g_pinfo->cinfo, COL_INFO);
1403 next_tvb = tvb_new_subset(asn1->tvb, asn1->offset, len, len);
1405 /* process components data */
1406 if (dissector_try_port(tcap_itu_ssn_dissector_table, g_pinfo->match_port, next_tvb, g_pinfo, g_tcap_tree))
1408 asn1->offset += len;
1412 saved_offset = asn1->offset;
1413 ret = asn1_id_decode1(asn1, &tag);
1414 asn1->offset = saved_offset;
1419 dissect_tcap_invoke(asn1, tree);
1422 dissect_tcap_rr(asn1, tree, "Return Result(Last) Type Tag");
1425 dissect_tcap_re(asn1, tree);
1428 dissect_tcap_reject(asn1, tree);
1431 /* same definition as RRL */
1432 dissect_tcap_rr(asn1, tree, "Return Result(Not Last) Type Tag");
1435 /* treat it as raw data */
1436 call_dissector(data_handle, next_tvb, g_pinfo, g_tcap_tree);
1443 dissect_tcap_components(ASN1_SCK *asn1, proto_tree *tcap_tree)
1445 proto_tree *subtree;
1446 guint saved_offset = 0;
1447 guint len, next_tvb_len;
1450 proto_item *cmp_item;
1451 guint cmp_start = asn1->offset;
1454 if (tvb_length_remaining(asn1->tvb, asn1->offset) <= 0)
1459 saved_offset = asn1->offset;
1460 ret = asn1_id_decode1(asn1, &tag);
1462 if (ST_ITU_CMP_TAG != tag)
1464 asn1->offset = saved_offset;
1468 cmp_item = proto_tree_add_none_format(tcap_tree, hf_tcap_none, asn1->tvb, saved_offset, -1, "Components Portion");
1469 subtree = proto_item_add_subtree(cmp_item, ett_cmp_portion);
1471 proto_tree_add_uint_format(subtree, hf_tcap_tag, asn1->tvb, saved_offset, asn1->offset - saved_offset, tag,
1472 "Component Portion Tag");
1474 dissect_tcap_len(asn1, subtree, &def_len, &len);
1478 proto_item_set_len(cmp_item, (asn1->offset - cmp_start) + len);
1481 /* call next dissector */
1486 * take remaining length minus the EOC for the indefinite
1490 tvb_length_remaining(asn1->tvb, asn1->offset) - TC_EOC_LEN;
1498 * take length minus the EOC for the indefinite
1499 * transaction message length
1501 next_tvb_len -= g_tcap_ends_def_len ? 0 : TC_EOC_LEN;
1503 dissect_tcap_next_tvb(asn1, next_tvb_len, subtree);
1507 dissect_tcap_eoc(asn1, subtree);
1510 proto_item_set_len(cmp_item, asn1->offset - cmp_start);
1515 /* dissect dialog portion */
1517 dissect_tcap_dlg_protocol_version(ASN1_SCK *asn1, proto_tree *tcap_tree, proto_item *ti)
1519 guint saved_offset = 0;
1525 #define TC_DLG_PROTO_VER_TAG 0x80
1526 if (check_tcap_tag(asn1, TC_DLG_PROTO_VER_TAG))
1528 saved_offset = asn1->offset;
1529 ret = asn1_id_decode1(asn1, &tag);
1530 proto_tree_add_uint_format(tcap_tree, hf_tcap_tag, asn1->tvb,
1531 saved_offset, asn1->offset - saved_offset, tag,
1532 "Protocol Version Tag: 0x%x", tag);
1534 dissect_tcap_len(asn1, tcap_tree, &def_len, &len);
1535 saved_offset = asn1->offset;
1537 proto_tree_add_bytes(tcap_tree, hf_tcap_bytes, asn1->tvb, saved_offset, len,
1538 (guchar*)(tvb_get_ptr(asn1->tvb, saved_offset, len)));
1539 asn1->offset += len;
1546 dissect_tcap_dlg_application_context_name(ASN1_SCK *asn1, proto_tree *tcap_tree)
1548 guint saved_offset = 0;
1549 guint name_len, len, len2;
1555 saved_offset = asn1->offset;
1556 ret = asn1_id_decode1(asn1, &tag);
1557 proto_tree_add_uint_format(tcap_tree, hf_tcap_tag, asn1->tvb, saved_offset, asn1->offset - saved_offset, tag,
1558 "Application Context Name Tag: 0x%x", tag);
1560 dissect_tcap_len(asn1, tcap_tree, &def_len, &name_len);
1562 saved_offset = asn1->offset;
1563 ret = asn1_oid_decode (asn1, &oid, &len, &len2);
1564 proto_tree_add_bytes(tcap_tree, hf_tcap_app_con_name, asn1->tvb, saved_offset, len2, tvb_get_ptr(asn1->tvb, saved_offset, len2));
1565 if (ret == ASN1_ERR_NOERROR) g_free(oid);
1569 /* for Application Context Name Tag */
1570 dissect_tcap_eoc(asn1, tcap_tree);
1577 dissect_tcap_dlg_result(ASN1_SCK *asn1, proto_tree *tree)
1579 guint tag, rtag_len, itag_len;
1580 guint saved_offset = 0;
1584 gboolean rtag_def_len;
1587 dissect_tcap_tag(asn1, tree, &tag, "Result Tag");
1589 dissect_tcap_len(asn1, tree, &rtag_def_len, &rtag_len);
1592 dissect_tcap_tag(asn1, tree, &tag, "Integer Tag");
1594 dissect_tcap_len(asn1, tree, &def_len, &itag_len);
1596 saved_offset = asn1->offset;
1597 asn1_int32_value_decode(asn1, itag_len, &value);
1601 case 0x00: str = "Accepted"; break;
1602 case 0x01: str = "Reject-permanent"; break;
1603 default: str = "Unknown value"; break;
1606 proto_tree_add_int_format(tree, hf_tcap_int, asn1->tvb, saved_offset, asn1->offset - saved_offset,
1607 value, "%s %d", str, value);
1611 /* for Result Tag */
1612 dissect_tcap_eoc(asn1, tree);
1619 dissect_tcap_dlg_result_src_diag(ASN1_SCK *asn1, proto_tree *tree)
1621 guint saved_offset = 0;
1627 gboolean serv_def_len;
1628 gboolean diag_def_len;
1631 dissect_tcap_tag(asn1, tree, &tag, "Result Source Diagnostic Tag");
1633 dissect_tcap_len(asn1, tree, &diag_def_len, &len);
1635 #define TC_DIAG_SERV_USER_TAG 0xa1
1636 #define TC_DIAG_SERV_PROV_TAG 0xa2
1637 if (check_tcap_tag(asn1, TC_DIAG_SERV_USER_TAG))
1640 dissect_tcap_tag(asn1, tree, &tag, "Dialogue Service User Tag");
1643 else if (check_tcap_tag(asn1, TC_DIAG_SERV_PROV_TAG))
1646 dissect_tcap_tag(asn1, tree, &tag, "Dialogue Service Provider Tag");
1651 proto_tree_add_none_format(tree, hf_tcap_none, asn1->tvb, asn1->offset, len,
1652 "Unknown Result Source Diagnostic");
1654 asn1->offset += len;
1658 dissect_tcap_len(asn1, tree, &serv_def_len, &len);
1661 dissect_tcap_tag(asn1, tree, &tag, "Integer Tag");
1663 dissect_tcap_len(asn1, tree, &def_len, &len);
1665 saved_offset = asn1->offset;
1666 asn1_int32_value_decode(asn1, len, &value);
1672 case 0x00: str = "Null"; break;
1673 case 0x01: str = "No reason given"; break;
1674 case 0x02: str = "Application Context Name not supplied"; break;
1675 default: str = "Unknown value"; break;
1682 case 0x00: str = "Null"; break;
1683 case 0x01: str = "No reason given"; break;
1684 case 0x02: str = "No common dialogue portion"; break;
1685 default: str = "Unknown value"; break;
1689 proto_tree_add_int_format(tree, hf_tcap_int, asn1->tvb, saved_offset, asn1->offset - saved_offset,
1690 value, "%s %d", str, value);
1694 /* for Dialogue Service User/Provider Tag */
1695 dissect_tcap_eoc(asn1, tree);
1700 /* for Result Source Diagnostic Tag */
1701 dissect_tcap_eoc(asn1, tree);
1708 dissect_tcap_dlg_user_info(ASN1_SCK *asn1, proto_tree *tree)
1711 guint saved_offset = 0;
1713 gboolean user_info_def_len;
1715 #define TC_USR_INFO_TAG 0xbe
1716 if (check_tcap_tag(asn1, TC_USR_INFO_TAG))
1719 dissect_tcap_tag(asn1, tree, &tag, "User Info Tag");
1720 dissect_tcap_len(asn1, tree, &user_info_def_len, &len);
1722 #define TC_EXT_TAG 0x28
1723 if (check_tcap_tag(asn1, TC_EXT_TAG))
1725 saved_offset = asn1->offset;
1726 asn1_id_decode1(asn1, &tag);
1727 proto_tree_add_uint_format(tree, hf_tcap_length, asn1->tvb, saved_offset, asn1->offset - saved_offset,
1728 tag, "External Tag: 0x%x", tag);
1730 dissect_tcap_len(asn1, tree, &def_len, &len);
1733 proto_tree_add_none_format(tree, hf_tcap_none, asn1->tvb, asn1->offset, len, "Parameter Data");
1734 asn1->offset += len;
1736 if (!user_info_def_len)
1738 /* for User Information Tag */
1739 dissect_tcap_eoc(asn1, tree);
1747 dissect_tcap_dlg_req(ASN1_SCK *asn1, proto_tree *tcap_tree)
1749 proto_tree *subtree;
1750 guint saved_offset = 0;
1754 proto_item *req_item;
1755 guint req_start = asn1->offset;
1758 /* dissect dialog portion */
1759 saved_offset = asn1->offset;
1760 ret = asn1_id_decode1(asn1, &tag);
1761 req_item = proto_tree_add_none_format(tcap_tree, hf_tcap_none, asn1->tvb, saved_offset, -1, "Dialogue Request");
1762 subtree = proto_item_add_subtree(req_item, ett_dlg_req);
1763 proto_tree_add_uint(subtree, hf_tcap_dlg_type, asn1->tvb, saved_offset, asn1->offset - saved_offset, tag);
1765 dissect_tcap_len(asn1, subtree, &def_len, &len);
1767 dissect_tcap_dlg_protocol_version(asn1, subtree, NULL);
1769 dissect_tcap_dlg_application_context_name(asn1, subtree);
1771 dissect_tcap_dlg_user_info(asn1, subtree);
1773 /* decode end of sequence */
1777 /* for Dialogue Request Tag */
1778 dissect_tcap_eoc(asn1, subtree);
1781 proto_item_set_len(req_item, asn1->offset - req_start);
1787 dissect_tcap_dlg_rsp(ASN1_SCK *asn1, proto_tree *tcap_tree)
1789 proto_tree *subtree;
1790 guint saved_offset = 0;
1794 proto_item *req_item;
1795 guint req_start = asn1->offset;
1798 /* dissect dialog portion */
1799 saved_offset = asn1->offset;
1800 ret = asn1_id_decode1(asn1, &tag);
1801 req_item = proto_tree_add_none_format(tcap_tree, hf_tcap_none, asn1->tvb, saved_offset, -1, "Dialogue Response");
1802 subtree = proto_item_add_subtree(req_item, ett_dlg_rsp);
1803 proto_tree_add_uint(subtree, hf_tcap_dlg_type, asn1->tvb, saved_offset, asn1->offset - saved_offset, tag);
1805 dissect_tcap_len(asn1, subtree, &def_len, &len);
1807 dissect_tcap_dlg_protocol_version(asn1, subtree, NULL);
1809 dissect_tcap_dlg_application_context_name(asn1, subtree);
1812 dissect_tcap_dlg_result(asn1, subtree);
1814 /* result source diag */
1815 dissect_tcap_dlg_result_src_diag(asn1, subtree);
1817 dissect_tcap_dlg_user_info(asn1, subtree);
1821 /* for Dialogue Response Tag */
1822 dissect_tcap_eoc(asn1, subtree);
1825 proto_item_set_len(req_item, asn1->offset - req_start);
1831 dissect_tcap_dlg_abrt(ASN1_SCK *asn1, proto_tree *tree)
1833 proto_tree *subtree;
1834 guint saved_offset = 0;
1838 proto_item *req_item;
1841 gboolean def_len, abort_def_len;
1843 /* dissect dialog pabort portion */
1844 saved_offset = asn1->offset;
1845 ret = asn1_id_decode1(asn1, &tag);
1846 req_item = proto_tree_add_none_format(tree, hf_tcap_none, asn1->tvb, saved_offset, -1, "Dialogue Abort");
1847 subtree = proto_item_add_subtree(req_item, ett_dlg_abrt );
1848 proto_tree_add_uint(subtree, hf_tcap_dlg_type, asn1->tvb, saved_offset, asn1->offset - saved_offset, tag);
1850 dissect_tcap_len(asn1, subtree, &abort_def_len, &len);
1853 dissect_tcap_tag(asn1, subtree, &tag, "Abort Source Tag");
1854 dissect_tcap_len(asn1, subtree, &def_len, &len);
1856 saved_offset = asn1->offset;
1857 asn1_int32_value_decode(asn1, len, &value);
1861 case 0x00: str = "Dialogue Service User"; break;
1862 case 0x01: str = "Dialogue Service Provider"; break;
1863 default: str = "Unknown value"; break;
1866 proto_tree_add_int_format(subtree, hf_tcap_int, asn1->tvb, saved_offset, asn1->offset - saved_offset,
1867 value, "Abort Source: %s %d", str, value);
1869 dissect_tcap_dlg_user_info(asn1, subtree);
1873 /* for Dialogue Abort Tag */
1874 dissect_tcap_eoc(asn1, subtree);
1881 dissect_tcap_dialog_portion(ASN1_SCK *asn1, proto_tree *tcap_tree, proto_item *ti)
1883 proto_tree *subtree;
1884 guint saved_offset = 0;
1888 proto_item *dlg_item;
1889 guint dlg_start = asn1->offset;
1890 gboolean def_len, ext_tag_def_len, portion_def_len;
1892 if (tvb_length_remaining(asn1->tvb, asn1->offset) <= 0)
1897 /* dissect dialog portion */
1898 saved_offset = asn1->offset;
1899 ret = asn1_id_decode1(asn1, &tag);
1901 /* error handling */
1902 if (ST_ITU_DLG_TAG != tag)
1904 asn1->offset = saved_offset;
1909 proto_tree_add_none_format(tcap_tree, hf_tcap_none, asn1->tvb,
1910 saved_offset, -1, "Dialogue Portion");
1912 subtree = proto_item_add_subtree(dlg_item, ett_dlg_portion);
1914 proto_tree_add_uint_format(subtree, hf_tcap_tag, asn1->tvb,
1915 saved_offset, asn1->offset - saved_offset, tag, "Dialogue Portion Tag");
1917 dissect_tcap_len(asn1, subtree, &portion_def_len, &len);
1919 if (portion_def_len)
1921 proto_item_set_len(dlg_item, len);
1924 ext_tag_def_len = FALSE;
1925 saved_offset = asn1->offset;
1926 ret = asn1_id_decode1(asn1, &tag);
1927 #define TC_EXT_TAG 0x28
1928 if (TC_EXT_TAG != tag)
1930 asn1->offset = saved_offset;
1934 proto_tree_add_uint_format(subtree, hf_tcap_length, asn1->tvb,
1935 saved_offset, asn1->offset - saved_offset, tag,
1936 "External Tag: 0x%x", tag);
1938 dissect_tcap_len(asn1, subtree, &ext_tag_def_len, &len);
1941 saved_offset = asn1->offset;
1942 ret = asn1_id_decode1(asn1, &tag);
1943 #define TC_OID_TAG 0x06
1944 if (TC_OID_TAG != tag)
1946 asn1->offset = saved_offset;
1950 proto_tree_add_uint_format(subtree, hf_tcap_tag, asn1->tvb,
1951 saved_offset, asn1->offset - saved_offset, tag,
1952 "Object Identifier Tag");
1954 dissect_tcap_len(asn1, subtree, &def_len, &len);
1956 saved_offset = asn1->offset;
1958 proto_tree_add_bytes(subtree, hf_tcap_bytes, asn1->tvb, saved_offset, len,
1959 (guchar*)(tvb_get_ptr(asn1->tvb, saved_offset, len)));
1961 asn1->offset += len;
1964 saved_offset = asn1->offset;
1965 ret = asn1_id_decode1(asn1, &tag);
1967 proto_tree_add_uint_format(subtree, hf_tcap_tag, asn1->tvb,
1968 saved_offset, asn1->offset - saved_offset, tag,
1969 "Single-ASN.1-type Tag");
1971 dissect_tcap_len(asn1, subtree, &def_len, &len);
1973 proto_item_set_len(dlg_item, asn1->offset - dlg_start);
1976 saved_offset = asn1->offset;
1977 ret = asn1_id_decode1(asn1, &tag);
1978 asn1->offset = saved_offset;
1983 dissect_tcap_dlg_req(asn1, subtree);
1986 dissect_tcap_dlg_rsp(asn1, subtree);
1989 dissect_tcap_dlg_abrt(asn1, subtree);
1995 /* decode end of sequence */
1999 dissect_tcap_eoc(asn1, subtree);
2002 if (!ext_tag_def_len)
2004 dissect_tcap_eoc(asn1, subtree);
2007 if (!portion_def_len)
2009 dissect_tcap_eoc(asn1, subtree);
2012 proto_item_set_len(dlg_item, asn1->offset - dlg_start);
2017 /* dissect reason */
2019 dissect_tcap_abort_reason(ASN1_SCK *asn1, proto_tree *tcap_tree)
2021 guint saved_offset = 0;
2023 proto_tree *subtree;
2029 #define TC_PABRT_REASON_TAG 0x4a
2030 tag = TC_PABRT_REASON_TAG;
2031 if (check_tcap_tag(asn1, tag))
2033 saved_offset = asn1->offset;
2035 proto_tree_add_none_format(tcap_tree, hf_tcap_none, asn1->tvb,
2036 saved_offset, -1, "PAbort Cause");
2038 subtree = proto_item_add_subtree(item, ett_reason);
2041 dissect_tcap_tag(asn1, subtree, &tag, "PAbort Cause Tag");
2042 dissect_tcap_len(asn1, subtree, &def_len, &len);
2044 proto_item_set_len(item, (asn1->offset - saved_offset) + len);
2046 saved_offset = asn1->offset;
2047 asn1_int32_value_decode(asn1, len, &value);
2051 case 0x00: str = "Unrecognized Message Type"; break;
2052 case 0x01: str = "Unrecognized Transaction ID"; break;
2053 case 0x02: str = "Badly Formatted Transaction Portion"; break;
2054 case 0x03: str = "Incorrect Transaction Portion"; break;
2055 case 0x04: str = "Resource Limitation"; break;
2061 proto_tree_add_none_format(subtree, hf_tcap_none, asn1->tvb,
2062 saved_offset, asn1->offset - saved_offset, "Cause Value %s (%d)",
2069 /* dissect each type of message */
2072 dissect_tcap_unidirectional(ASN1_SCK *asn1, proto_tree *tcap_tree)
2075 dissect_tcap_dialog_portion(asn1, tcap_tree, NULL);
2077 dissect_tcap_components(asn1, tcap_tree);
2081 dissect_tcap_begin(ASN1_SCK *asn1, proto_tree *tcap_tree, proto_item *ti)
2084 dissect_tcap_tid(asn1, tcap_tree, ti, ST_TID_SOURCE);
2086 dissect_tcap_dialog_portion(asn1, tcap_tree, NULL);
2088 dissect_tcap_components(asn1, tcap_tree);
2092 dissect_tcap_continue(ASN1_SCK *asn1, proto_tree *tcap_tree, proto_item *ti)
2095 dissect_tcap_tid(asn1, tcap_tree, ti, ST_TID_SOURCE);
2097 dissect_tcap_tid(asn1, tcap_tree, ti, ST_TID_DEST);
2099 dissect_tcap_dialog_portion(asn1, tcap_tree, NULL);
2101 dissect_tcap_components(asn1, tcap_tree);
2106 dissect_tcap_end(ASN1_SCK *asn1, proto_tree *tcap_tree, proto_item *ti)
2109 dissect_tcap_tid(asn1, tcap_tree, ti, ST_TID_DEST);
2111 dissect_tcap_dialog_portion(asn1, tcap_tree, NULL);
2113 dissect_tcap_components(asn1, tcap_tree);
2117 dissect_tcap_abort(ASN1_SCK *asn1, proto_tree *tree, proto_item *ti)
2120 dissect_tcap_tid(asn1, tree, ti, ST_TID_DEST);
2122 dissect_tcap_abort_reason(asn1, tree);
2124 dissect_tcap_dialog_portion(asn1, tree, NULL);
2129 dissect_tcap_message(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tcap_tree)
2135 guint saved_offset = 0;
2139 asn1_open(&asn1, tvb, offset);
2141 asn1_id_decode1(&asn1, &msg_type_tag);
2143 str = match_strval(msg_type_tag, msg_type_strings);
2147 proto_tree_add_none_format(tcap_tree, hf_tcap_none, asn1.tvb, offset, -1, "Unknown message type, ignoring");
2151 if (check_col(pinfo->cinfo, COL_INFO))
2153 col_set_str(pinfo->cinfo, COL_INFO, str);
2154 col_append_str(pinfo->cinfo, COL_INFO, " ");
2157 proto_tree_add_uint_hidden(tcap_tree, hf_tcap_ssn, asn1.tvb, offset,
2158 0, pinfo->match_port); /* len -1 is unacceptable */
2160 ti = proto_tree_add_uint(tcap_tree, hf_tcap_message_type, asn1.tvb, offset, asn1.offset - saved_offset,
2163 dissect_tcap_len(&asn1, tcap_tree, &g_tcap_ends_def_len, &len);
2165 switch(msg_type_tag)
2167 case ST_MSG_TYP_UNI:
2168 dissect_tcap_unidirectional(&asn1, tcap_tree);
2170 case ST_MSG_TYP_BGN:
2171 dissect_tcap_begin(&asn1, tcap_tree, ti);
2173 case ST_MSG_TYP_CNT:
2174 dissect_tcap_continue(&asn1, tcap_tree, ti);
2176 case ST_MSG_TYP_END:
2177 dissect_tcap_end(&asn1, tcap_tree, ti);
2179 case ST_MSG_TYP_PABT:
2180 dissect_tcap_abort(&asn1, tcap_tree, ti);
2183 proto_tree_add_none_format(tcap_tree, hf_tcap_none, asn1.tvb, offset, -1,
2184 "Message type not handled, ignoring");
2188 if (!g_tcap_ends_def_len)
2190 dissect_tcap_eoc(&asn1, tcap_tree);
2193 asn1_close(&asn1, &saved_offset);
2197 dissect_ansi_tcap_components(ASN1_SCK *asn1, proto_tree *tcap_tree)
2199 proto_tree *subtree;
2200 guint saved_offset = 0;
2204 proto_item *cmp_item;
2205 guint cmp_start = asn1->offset;
2208 saved_offset = asn1->offset;
2209 ret = asn1_id_decode1(asn1, &tag);
2211 if (ST_ANSI_CMP_TAG != tag)
2213 asn1->offset = saved_offset;
2217 cmp_item = proto_tree_add_none_format(tcap_tree, hf_tcap_none, asn1->tvb, saved_offset, -1, "Components Portion");
2219 subtree = proto_item_add_subtree(cmp_item, ett_cmp_portion);
2221 proto_tree_add_uint_format(subtree, hf_tcap_tag, asn1->tvb, saved_offset, asn1->offset - saved_offset, tag,
2222 "Component Sequence Identifier");
2224 dissect_tcap_len(asn1, tcap_tree, &def_len, &len);
2226 /* call next dissector */
2228 dissect_ansi_tcap_next_tvb(asn1, len, subtree);
2230 proto_item_set_len(cmp_item, asn1->offset - cmp_start);
2236 dissect_ansi_tcap_unidirectional(ASN1_SCK *asn1, proto_tree *tcap_tree)
2238 guint saved_offset = 0;
2242 proto_item *trans_item;
2243 guint trans_start = asn1->offset;
2246 saved_offset = asn1->offset;
2247 ret = asn1_id_decode1(asn1, &tag);
2249 if (ST_ANSI_TID_TAG != tag)
2251 asn1->offset = saved_offset;
2255 trans_item = proto_tree_add_none_format(tcap_tree, hf_tcap_none, asn1->tvb, saved_offset, -1, "Transaction Portion");
2257 dissect_tcap_len(asn1, tcap_tree, &def_len, &len);
2264 proto_item_set_len(trans_item, asn1->offset - trans_start);
2266 dissect_ansi_tcap_components(asn1, tcap_tree);
2272 dissect_ansi_tcap_qwp_qwop(ASN1_SCK *asn1, proto_tree *tcap_tree, proto_item *ti)
2274 proto_tree *subtree;
2275 guint saved_offset = 0;
2279 proto_item *trans_item;
2280 guint trans_start = asn1->offset;
2285 saved_offset = asn1->offset;
2286 ret = asn1_id_decode1(asn1, &tag);
2288 if (ST_ANSI_TID_TAG != tag)
2290 asn1->offset = saved_offset;
2294 trans_item = proto_tree_add_none_format(tcap_tree, hf_tcap_none, asn1->tvb, saved_offset, -1, "Transaction Portion");
2295 subtree = proto_item_add_subtree(trans_item, ett_dlg_portion);
2297 dissect_tcap_len(asn1, tcap_tree, &def_len, &len);
2299 proto_tree_add_uint_format(subtree, hf_tcap_tag, asn1->tvb, saved_offset, asn1->offset - saved_offset, tag,
2300 "Originating Transaction ID Identifier");
2307 saved_offset = asn1->offset;
2308 ret = asn1_string_value_decode(asn1, len, &poctets);
2310 memcpy(&val, poctets, len);
2311 ti = proto_tree_add_uint(subtree, hf_tcap_id, asn1->tvb, saved_offset, asn1->offset - saved_offset, val);
2314 if (check_col(g_pinfo->cinfo, COL_INFO))
2315 col_append_fstr(g_pinfo->cinfo, COL_INFO, "otid(%x) ", val);
2317 proto_item_set_len(trans_item, asn1->offset - trans_start);
2319 dissect_ansi_tcap_components(asn1, tcap_tree);
2325 dissect_ansi_tcap_abort(ASN1_SCK *asn1, proto_tree *tcap_tree, proto_item *ti)
2327 proto_tree *subtree;
2328 guint saved_offset = 0;
2332 proto_item *trans_item;
2333 guint trans_start = asn1->offset;
2338 saved_offset = asn1->offset;
2339 ret = asn1_id_decode1(asn1, &tag);
2341 if (ST_ANSI_TID_TAG != tag)
2343 asn1->offset = saved_offset;
2347 trans_item = proto_tree_add_none_format(tcap_tree, hf_tcap_none, asn1->tvb, saved_offset, -1, "Transaction Portion");
2348 subtree = proto_item_add_subtree(trans_item, ett_dlg_portion);
2350 proto_tree_add_uint_format(subtree, hf_tcap_tag, asn1->tvb, saved_offset, asn1->offset - saved_offset, tag,
2351 "Responding Transaction ID Identifier");
2353 dissect_tcap_len(asn1, tcap_tree, &def_len, &len);
2360 saved_offset = asn1->offset;
2361 ret = asn1_string_value_decode(asn1, len, &poctets);
2363 memcpy(&val, poctets, len);
2364 ti = proto_tree_add_uint(subtree, hf_tcap_id, asn1->tvb, saved_offset, asn1->offset - saved_offset, val);
2367 if (check_col(g_pinfo->cinfo, COL_INFO))
2368 col_append_fstr(g_pinfo->cinfo, COL_INFO, "rtid(%x) ", val);
2370 proto_item_set_len(trans_item, asn1->offset - trans_start);
2372 saved_offset = asn1->offset;
2373 ret = asn1_id_decode1(asn1, &tag);
2375 #define ANSI_TC_PABRT_CAUSE_TAG 0xd7
2376 if (tag == ANSI_TC_PABRT_CAUSE_TAG)
2378 trans_item = proto_tree_add_none_format(tcap_tree, hf_tcap_none, asn1->tvb, saved_offset, -1, "P-Abort Portion");
2380 subtree = proto_item_add_subtree(trans_item, ett_dlg_abrt);
2382 proto_tree_add_uint_format(subtree, hf_tcap_tag, asn1->tvb, saved_offset, asn1->offset - saved_offset, tag,
2383 "Responding Transaction ID Identifier");
2386 dissect_tcap_len(asn1, tcap_tree, &def_len, &len);
2387 dissect_tcap_integer(asn1, tcap_tree, len, "P-Abort Cause:");
2389 #define ANSI_TC_UABRT_INFO_TAG 0xd8
2390 else if (tag == ANSI_TC_UABRT_INFO_TAG)
2392 trans_item = proto_tree_add_none_format(tcap_tree, hf_tcap_none, asn1->tvb, saved_offset, -1, "U-Abort Portion");
2394 dissect_tcap_len(asn1, tcap_tree, &def_len, &len);
2397 dissect_tcap_integer(asn1, tcap_tree, len, "User Abort Information:");
2405 dissect_ansi_tcap_rsp(ASN1_SCK *asn1, proto_tree *tcap_tree, proto_item *ti)
2407 proto_tree *subtree;
2408 guint saved_offset = 0;
2412 proto_item *trans_item;
2413 guint trans_start = asn1->offset;
2418 saved_offset = asn1->offset;
2419 ret = asn1_id_decode1(asn1, &tag);
2421 if (ST_ANSI_TID_TAG != tag)
2423 asn1->offset = saved_offset;
2427 trans_item = proto_tree_add_none_format(tcap_tree, hf_tcap_none, asn1->tvb, saved_offset, -1, "Transaction Portion");
2428 subtree = proto_item_add_subtree(trans_item, ett_dlg_portion);
2430 proto_tree_add_uint_format(subtree, hf_tcap_tag, asn1->tvb, saved_offset, asn1->offset - saved_offset, tag,
2431 "Responding Transaction ID Identifier");
2433 dissect_tcap_len(asn1, tcap_tree, &def_len, &len);
2440 saved_offset = asn1->offset;
2441 ret = asn1_string_value_decode(asn1, len, &poctets);
2443 memcpy(&val, poctets, len);
2444 ti = proto_tree_add_uint(subtree, hf_tcap_id, asn1->tvb, saved_offset, asn1->offset - saved_offset, val);
2447 if (check_col(g_pinfo->cinfo, COL_INFO))
2448 col_append_fstr(g_pinfo->cinfo, COL_INFO, "rtid(%x) ", val);
2450 proto_item_set_len(trans_item, asn1->offset - trans_start);
2452 dissect_ansi_tcap_components(asn1, tcap_tree);
2458 dissect_ansi_tcap_cwp_cwop(ASN1_SCK *asn1, proto_tree *tcap_tree, proto_item *ti)
2460 proto_tree *subtree;
2461 guint saved_offset = 0;
2465 proto_item *trans_item;
2466 guint trans_start = asn1->offset;
2471 saved_offset = asn1->offset;
2472 ret = asn1_id_decode1(asn1, &tag);
2474 if (ST_ANSI_TID_TAG != tag)
2476 asn1->offset = saved_offset;
2480 trans_item = proto_tree_add_none_format(tcap_tree, hf_tcap_none, asn1->tvb, saved_offset, -1, "Transaction Portion");
2481 subtree = proto_item_add_subtree(trans_item, ett_dlg_portion);
2483 proto_tree_add_uint_format(subtree, hf_tcap_tag, asn1->tvb, saved_offset, asn1->offset - saved_offset, tag,
2484 "Transaction ID Identifier");
2486 dissect_tcap_len(asn1, tcap_tree, &def_len, &len);
2493 saved_offset = asn1->offset;
2494 ret = asn1_string_value_decode(asn1, 4, &poctets);
2496 memcpy(&val, poctets, 4);
2497 ti = proto_tree_add_uint(subtree, hf_tcap_id, asn1->tvb, saved_offset, asn1->offset - saved_offset, val);
2500 if (check_col(g_pinfo->cinfo, COL_INFO))
2501 col_append_fstr(g_pinfo->cinfo, COL_INFO, "otid(%x) ", val);
2503 saved_offset = asn1->offset;
2504 ret = asn1_string_value_decode(asn1, 4, &poctets);
2506 memcpy(&val, poctets, 4);
2507 ti = proto_tree_add_uint(subtree, hf_tcap_id, asn1->tvb, saved_offset, asn1->offset - saved_offset, val);
2510 if (check_col(g_pinfo->cinfo, COL_INFO))
2511 col_append_fstr(g_pinfo->cinfo, COL_INFO, "rtid(%x) ", val);
2513 proto_item_set_len(trans_item, asn1->offset - trans_start);
2515 dissect_ansi_tcap_components(asn1, tcap_tree);
2521 dissect_ansi_tcap_message(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tcap_tree)
2527 guint saved_offset = 0;
2532 asn1_open(&asn1, tvb, offset);
2534 asn1_id_decode1(&asn1, &msg_type_tag);
2536 str = match_strval(msg_type_tag, ansi_msg_type_strings);
2540 proto_tree_add_none_format(tcap_tree, hf_tcap_none, asn1.tvb, offset, -1, "Unknown message type, ignoring");
2544 if (check_col(pinfo->cinfo, COL_INFO))
2546 col_set_str(pinfo->cinfo, COL_INFO, str);
2547 col_append_str(pinfo->cinfo, COL_INFO, " ");
2550 proto_tree_add_uint_hidden(tcap_tree, hf_tcap_ssn, asn1.tvb, offset,
2551 0, pinfo->match_port); /* len -1 is unacceptable */
2553 ti = proto_tree_add_uint(tcap_tree, hf_ansi_tcap_message_type, asn1.tvb, offset, asn1.offset - saved_offset,
2556 dissect_tcap_len(&asn1, tcap_tree, &def_len, &len);
2558 switch(msg_type_tag)
2560 case ANSI_ST_MSG_TYP_UNI:
2561 dissect_ansi_tcap_unidirectional(&asn1, tcap_tree);
2563 case ANSI_ST_MSG_TYP_QWP:
2564 dissect_ansi_tcap_qwp_qwop(&asn1, tcap_tree, ti);
2566 case ANSI_ST_MSG_TYP_QWOP:
2567 dissect_ansi_tcap_qwp_qwop(&asn1, tcap_tree, ti);
2569 case ANSI_ST_MSG_TYP_RSP:
2570 dissect_ansi_tcap_rsp(&asn1, tcap_tree, ti);
2572 case ANSI_ST_MSG_TYP_CWP:
2573 dissect_ansi_tcap_cwp_cwop(&asn1, tcap_tree, ti);
2575 case ANSI_ST_MSG_TYP_CWOP:
2576 dissect_ansi_tcap_cwp_cwop(&asn1, tcap_tree, ti);
2578 case ANSI_ST_MSG_TYP_PABT:
2579 dissect_ansi_tcap_abort(&asn1, tcap_tree, ti);
2582 proto_tree_add_none_format(tcap_tree, hf_tcap_none, asn1.tvb, offset, -1,
2583 "Message type not handled, ignoring");
2587 asn1_close(&asn1, &saved_offset);
2590 /* Code to actually dissect the packets */
2592 dissect_tcap(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
2595 proto_tree *tcap_tree;
2599 if (check_col(pinfo->cinfo, COL_PROTOCOL))
2600 col_set_str(pinfo->cinfo, COL_PROTOCOL, "TCAP");
2602 /* In the interest of speed, if "tree" is NULL, don't do any
2603 * work not necessary to generate protocol tree items.
2607 ti = proto_tree_add_item(tree, proto_tcap, tvb, 0, -1, FALSE);
2608 tcap_tree = proto_item_add_subtree(ti, ett_tcap);
2611 if (tcap_standard == ITU_TCAP_STANDARD)
2613 dissect_tcap_message(tvb, pinfo, tcap_tree);
2617 dissect_ansi_tcap_message(tvb, pinfo, tcap_tree);
2623 /* Register the protocol with Ethereal */
2625 /* this format is require because a script is used to build the C function
2626 that calls all the protocol registration.
2629 proto_register_tcap(void)
2632 /* Setup list of header fields See Section 1.6.1 for details*/
2633 static hf_register_info hf[] = {
2634 /*{ &hf_tcap_FIELDABBREV,
2635 { "FIELDNAME", "PROTOABBREV.FIELDABBREV",
2636 FIELDTYPE, FIELDBASE, FIELDCONVERT, BITMASK,
2640 { "Tag", "tcap.msgtype",
2641 FT_UINT8, BASE_HEX, NULL, 0,
2645 { "Length", "tcap.len",
2646 FT_UINT8, BASE_HEX, NULL, 0,
2650 { "Value", "tcap.id",
2651 FT_UINT8, BASE_HEX, NULL, 0,
2654 { &hf_tcap_message_type,
2655 { "Message Type", "tcap.msgtype",
2656 FT_UINT8, BASE_HEX, VALS(msg_type_strings), 0,
2659 { &hf_ansi_tcap_message_type,
2660 { "Message Type", "tcap.msgtype",
2661 FT_UINT8, BASE_HEX, VALS(ansi_msg_type_strings), 0,
2665 { "Sub tree", "tcap.none",
2670 { "Transaction Id", "tcap.tid",
2671 FT_UINT32, BASE_DEC, VALS(tid_strings), 0,
2675 { "Called or Calling SubSystem Number", "tcap.ssn",
2676 FT_UINT8, BASE_DEC, 0x0, 0x0,
2679 { &hf_tcap_cmp_type,
2680 { "Component Type", "tcap.cmptype",
2681 FT_UINT8, BASE_HEX, VALS(cmp_type_strings), 0,
2684 { &hf_ansi_tcap_cmp_type,
2685 { "Component Type", "tcap.cmptype",
2686 FT_UINT8, BASE_HEX, VALS(ansi_cmp_type_strings), 0,
2689 { &hf_tcap_dlg_type,
2690 { "Dialogue Type", "tcap.dlgtype",
2691 FT_UINT8, BASE_HEX, VALS(dlg_type_strings), 0,
2694 { &hf_tcap_app_con_name,
2695 { "Application Context Name", "tcap.dlg.appconname",
2696 FT_BYTES, BASE_HEX, 0, 0,
2700 { "Binary Data", "tcap.data",
2701 FT_BYTES, BASE_HEX, 0, 0,
2705 { "Integer Data", "tcap.data",
2706 FT_INT32, BASE_DEC, 0, 0,
2711 /* Setup protocol subtree array */
2712 static gint *ett[] = {
2729 static enum_val_t tcap_options[] = {
2730 { "ITU", ITU_TCAP_STANDARD },
2731 { "ANSI", ANSI_TCAP_STANDARD },
2735 module_t *tcap_module;
2737 /* Register the protocol name and description */
2738 proto_tcap = proto_register_protocol("Transaction Capabilities Application Part",
2741 /* Required function calls to register the header fields and subtrees used */
2742 proto_register_field_array(proto_tcap, hf, array_length(hf));
2743 proto_register_subtree_array(ett, array_length(ett));
2745 tcap_module = prefs_register_protocol(proto_tcap, proto_reg_handoff_tcap);
2747 prefs_register_enum_preference(tcap_module, "standard", "TCAP standard",
2748 "The SS7 standard used in TCAP packets",
2749 (gint *)&tcap_standard, tcap_options, FALSE);
2751 prefs_register_bool_preference(tcap_module, "lock_info_col", "Lock Info column",
2752 "Always show TCAP in Info column",
2755 /* we will fake a ssn subfield which has the same value obtained from sccp */
2756 tcap_itu_ssn_dissector_table = register_dissector_table("tcap.itu_ssn", "ITU TCAP SSN", FT_UINT8, BASE_DEC);
2757 tcap_ansi_ssn_dissector_table = register_dissector_table("tcap.ansi_ssn", "ANSI TCAP SSN", FT_UINT8, BASE_DEC);
2761 /* If this dissector uses sub-dissector registration add a registration routine.
2762 This format is required because a script is used to find these routines and
2763 create the code that calls these routines.
2766 proto_reg_handoff_tcap(void)
2768 static gboolean tcap_prefs_initialized = FALSE;
2769 dissector_handle_t tcap_handle;
2771 if (!tcap_prefs_initialized)
2773 tcap_handle = create_dissector_handle(dissect_tcap,
2776 dissector_add("sccp.ssn", 5, tcap_handle); /* MAP*/
2777 dissector_add("sccp.ssn", 6, tcap_handle); /* HLR*/
2778 dissector_add("sccp.ssn", 7, tcap_handle); /* VLR */
2779 dissector_add("sccp.ssn", 8, tcap_handle); /* MSC */
2780 dissector_add("sccp.ssn", 9, tcap_handle); /* EIR */
2781 dissector_add("sccp.ssn", 10, tcap_handle); /* EIR */
2782 dissector_add("sccp.ssn", 11, tcap_handle); /* SMS/MC */
2783 dissector_add("sccp.ssn", 12, tcap_handle); /* IS41 OTAF */
2785 tcap_prefs_initialized = TRUE;
2788 data_handle = find_dissector("data");