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.5 2003/12/29 00:41:07 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_none = -1;
79 static int hf_tcap_tag = -1;
80 static int hf_tcap_length = -1;
81 static int hf_tcap_bytes = -1;
82 static int hf_tcap_app_con_name = -1;
83 static int hf_tcap_id = -1;
84 static int hf_tcap_tid = -1;
85 static int hf_tcap_ssn = -1; /* faked */
86 static int hf_tcap_dlg_type = -1;
87 static int hf_tcap_int = -1;
89 /* Initialize the subtree pointers */
90 static gint ett_tcap = -1;
92 static gint ett_otid = -1;
93 static gint ett_dtid = -1;
94 static gint ett_dlg_portion = -1;
95 static gint ett_dlg_req = -1;
96 static gint ett_dlg_rsp = -1;
97 static gint ett_dlg_abort = -1;
98 static gint ett_cmp_portion = -1;
99 static gint ett_reason = -1;
100 static gint ett_component = -1;
101 static gint ett_problem = -1;
102 static gint ett_error = -1;
103 static gint ett_params = -1;
104 static gint ett_param = -1;
106 static dissector_handle_t data_handle;
107 static dissector_table_t tcap_itu_ssn_dissector_table; /* map use ssn in sccp */
108 static dissector_table_t tcap_ansi_ssn_dissector_table; /* map use ssn in sccp */
109 static gboolean lock_info_col = TRUE;
111 #define TC_SEQ_TAG 0x30
112 #define TC_SET_TAG 0x31
114 #define TC_EOC_LEN 2 /* 0x00 0x00 */
116 /* TCAP transaction message type definition - Samuel */
117 #define ST_MSG_TYP_UNI 0x61 /*0b01100001*/
118 #define ST_MSG_TYP_BGN 0x62 /*0b01100010*/
119 #define ST_MSG_TYP_CNT 0x65 /*0b01100101*/
120 #define ST_MSG_TYP_END 0x64 /*0b01100100*/
121 #define ST_MSG_TYP_PABT 0x67 /*0b01100111*/
122 static const value_string msg_type_strings[] = {
123 { ST_MSG_TYP_UNI, "TC-UNI" },
124 { ST_MSG_TYP_BGN, "TC-BEGIN" },
125 { ST_MSG_TYP_CNT, "TC-CONTINUE" },
126 { ST_MSG_TYP_END, "TC-END" },
127 { ST_MSG_TYP_PABT, "TC-PABORT" },
131 /* ANSI TCAP transaction message type definition */
132 #define ANSI_ST_MSG_TYP_UNI 0xe1
133 #define ANSI_ST_MSG_TYP_QWP 0xe2
134 #define ANSI_ST_MSG_TYP_QWOP 0xe3
135 #define ANSI_ST_MSG_TYP_RSP 0xe4
136 #define ANSI_ST_MSG_TYP_CWP 0xe5
137 #define ANSI_ST_MSG_TYP_CWOP 0xe6
138 #define ANSI_ST_MSG_TYP_ABT 0xf6
139 static const value_string ansi_msg_type_strings[] = {
140 { ANSI_ST_MSG_TYP_UNI, "TC-UNI" },
141 { ANSI_ST_MSG_TYP_QWP, "TC-QUERY W PERM" },
142 { ANSI_ST_MSG_TYP_QWOP, "TC-QUERY WO PERM" },
143 { ANSI_ST_MSG_TYP_RSP, "TC-RESPONSE" },
144 { ANSI_ST_MSG_TYP_CWP, "TC-CONV W PERM" },
145 { ANSI_ST_MSG_TYP_CWOP, "TC-CONV WO PERM" },
146 { ANSI_ST_MSG_TYP_ABT, "TC-ABORT" },
150 #define ST_ANSI_CMP_TAG 0xe8
151 #define ST_ANSI_TID_TAG 0xc7
153 /* TCAP TID tag value - Samuel */
154 #define ST_TID_SOURCE 0
155 #define ST_TID_DEST 1
156 #define ST_ITU_ORG_TID_TAG 0x48 /*0b01001000*/
157 #define ST_ITU_DST_TID_TAG 0x49 /*0b01001001*/
158 #define ST_ITU_PABT_TAG 0x4a /*0b01001010*/
159 #define ST_ITU_DLG_TAG 0x6b
160 #define ST_ITU_CMP_TAG 0x6c
162 static const value_string tid_strings[] = {
163 { ST_ITU_ORG_TID_TAG, "Source Transaction ID" },
164 { ST_ITU_DST_TID_TAG, "Destination Transaction ID" },
168 /* TCAP dialog type */
169 #define TC_DLG_REQ 0x60
170 #define TC_DLG_RSP 0x61
171 #define TC_DLG_ABRT 0x64
173 static const value_string dlg_type_strings[] = {
174 { TC_DLG_REQ , "Dialogue Request" },
175 { TC_DLG_RSP , "Dialogue Response" },
176 { TC_DLG_ABRT, "Dialogue Abort" },
180 /* TCAP component type */
181 #define TC_INVOKE 0xa1
184 #define TC_REJECT 0xa4
187 /* ANSI TCAP component type */
188 #define ANSI_TC_INVOKE_L 0xe9
189 #define ANSI_TC_RRL 0xea
190 #define ANSI_TC_RE 0xeb
191 #define ANSI_TC_REJECT 0xec
192 #define ANSI_TC_INVOKE_N 0xed
193 #define ANSI_TC_RRN 0xee
201 dissect_tcap_len(ASN1_SCK *asn1, proto_tree *tree, gboolean *def_len, guint *len)
206 saved_offset = asn1->offset;
209 ret = asn1_length_decode(asn1, def_len, len);
213 proto_tree_add_uint(tree, hf_tcap_length, asn1->tvb, saved_offset, asn1->offset - saved_offset, *len);
217 proto_tree_add_none_format(tree, hf_tcap_none, asn1->tvb,
218 saved_offset, asn1->offset - saved_offset, "Length: Indefinite");
225 dissect_tcap_eoc(ASN1_SCK *asn1, proto_tree *tree)
227 guint saved_offset, ret;
229 saved_offset = asn1->offset;
231 if (tvb_length_remaining(asn1->tvb, saved_offset) <= 0)
236 if (!asn1_eoc(asn1, -1))
241 ret = asn1_eoc_decode(asn1, -1);
243 proto_tree_add_none_format(tree, hf_tcap_none, asn1->tvb,
244 saved_offset, asn1->offset - saved_offset, "End of Contents");
250 dissect_tcap_tag(ASN1_SCK *asn1, proto_tree *tree, guint *tag, guchar * str)
252 guint saved_offset, real_tag;
254 saved_offset = asn1->offset;
255 asn1_id_decode1(asn1, &real_tag);
256 if ((*tag != (guint) -1) && (real_tag != *tag))
258 asn1->offset = saved_offset;
261 proto_tree_add_uint_format(tree, hf_tcap_tag, asn1->tvb, saved_offset, asn1->offset - saved_offset,
267 dissect_tcap_octet(ASN1_SCK *asn1, proto_tree *tree, guchar * str)
272 saved_offset = asn1->offset;
273 asn1_octet_decode(asn1, &my_oct);
274 proto_tree_add_uint_format(tree, hf_tcap_id, asn1->tvb, saved_offset, asn1->offset - saved_offset,
275 my_oct, "%s %d", str, my_oct);
280 dissect_tcap_integer(ASN1_SCK *asn1, proto_tree *tree, guint len, guchar * str)
285 saved_offset = asn1->offset;
286 asn1_int32_value_decode(asn1, len, &invokeId);
287 proto_tree_add_int_format(tree, hf_tcap_int, asn1->tvb, saved_offset, asn1->offset - saved_offset,
288 invokeId, "%s %d", str, invokeId);
293 check_tcap_tag(ASN1_SCK *asn1, guint tag)
295 guint saved_offset, real_tag;
297 if (tvb_length_remaining(asn1->tvb, asn1->offset) <= 0)
302 saved_offset = asn1->offset;
303 asn1_id_decode1(asn1, &real_tag);
304 asn1->offset = saved_offset;
305 return (tag == real_tag);
310 dissect_tcap_tid(ASN1_SCK *asn1, proto_tree *tcap_tree, proto_item *ti, int type)
312 guint saved_offset, org_offset = 0;
316 proto_item *tid_item;
322 org_offset = asn1->offset;
323 if ( ST_TID_SOURCE == type)
325 tid_item = proto_tree_add_none_format(tcap_tree, hf_tcap_none, asn1->tvb, asn1->offset, -1, "Source Transaction ID");
326 subtree = proto_item_add_subtree(tid_item, ett_otid);
330 tid_item = proto_tree_add_none_format(tcap_tree, hf_tcap_none, asn1->tvb, asn1->offset, -1, "Destination Transaction ID");
331 subtree = proto_item_add_subtree(tid_item, ett_dtid);
334 saved_offset = asn1->offset;
335 ret = asn1_id_decode1(asn1, &tag);
336 proto_tree_add_uint(subtree, hf_tcap_tid, asn1->tvb, saved_offset, asn1->offset - saved_offset, tag);
342 if (ST_ITU_ORG_TID_TAG != tag)
344 asn1->offset = saved_offset;
349 if (ST_ITU_DST_TID_TAG != tag)
351 asn1->offset = saved_offset;
360 dissect_tcap_len(asn1, subtree, &def_len, &len);
362 saved_offset = asn1->offset;
363 ret = asn1_string_value_decode(asn1, len, &poctets);
365 memcpy(&val, poctets, len);
367 ti = proto_tree_add_uint(subtree, hf_tcap_id, asn1->tvb, saved_offset, asn1->offset - saved_offset, val);
370 proto_item_set_len(tid_item, asn1->offset - org_offset);
372 if (type == ST_TID_DEST)
374 if (check_col(g_pinfo->cinfo, COL_INFO))
375 col_append_fstr(g_pinfo->cinfo, COL_INFO, "dtid(%x) ", val);
379 if (check_col(g_pinfo->cinfo, COL_INFO))
380 col_append_fstr(g_pinfo->cinfo, COL_INFO, "stid(%x) ", val);
387 /* dissect operation portion */
389 dissect_tcap_invokeId(ASN1_SCK *asn1, proto_tree *tree)
395 #define INVOKE_ID_TAG 0x2
396 if (check_tcap_tag(asn1, INVOKE_ID_TAG))
399 dissect_tcap_tag(asn1, tree, &tag, "Invoke ID Tag");
400 dissect_tcap_len(asn1, tree, &def_len, &len);
401 dissect_tcap_integer(asn1, tree, len, "Invoke ID:");
408 dissect_tcap_lnkId(ASN1_SCK *asn1, proto_tree *tree)
414 #define LINK_ID_TAG 0x80
415 if (check_tcap_tag(asn1, LINK_ID_TAG))
418 dissect_tcap_tag(asn1, tree, &tag, "Linked ID Tag");
419 dissect_tcap_len(asn1, tree, &def_len, &len);
420 dissect_tcap_integer(asn1, tree, len, "Linked ID:");
427 dissect_tcap_opr_code(ASN1_SCK *asn1, proto_tree *tree)
431 gboolean got_it = FALSE;
434 #define TCAP_LOC_OPR_CODE_TAG 0x02
435 if (check_tcap_tag(asn1, TCAP_LOC_OPR_CODE_TAG))
438 dissect_tcap_tag(asn1, tree, &tag, "Local Operation Code Tag");
441 #define TCAP_GLB_OPR_CODE_TAG 0x06
442 else if (check_tcap_tag(asn1, TCAP_GLB_OPR_CODE_TAG))
445 dissect_tcap_tag(asn1, tree, &tag, "Global Operation Code Tag");
451 dissect_tcap_len(asn1, tree, &def_len, &len);
453 proto_tree_add_none_format(tree, hf_tcap_none, asn1->tvb, asn1->offset, len, "Operation Code");
460 dissect_tcap_param(ASN1_SCK *asn1, proto_tree *tree)
462 guint off_tree[100], saved_offset, len_offset;
466 proto_item *item_tree[100], *item;
467 proto_tree *seq_tree[100], *use_tree, *subtree;
472 #define TC_INVALID_TAG 0
473 while ((tvb_length_remaining(asn1->tvb, asn1->offset) > 0) &&
474 (!check_tcap_tag(asn1, 0)))
476 saved_offset = asn1->offset;
477 asn1_id_decode1(asn1, &tag);
478 len_offset = asn1->offset;
479 asn1_length_decode(asn1, &def_len, &len);
481 if (tag == TC_SEQ_TAG)
484 proto_tree_add_none_format(use_tree, hf_tcap_none, asn1->tvb,
485 saved_offset, -1, "Sequence");
487 subtree = proto_item_add_subtree(item, ett_params);
489 proto_tree_add_uint_format(subtree, hf_tcap_tag, asn1->tvb,
490 saved_offset, len_offset - saved_offset, tag, "Sequence Tag");
494 proto_tree_add_none_format(subtree, hf_tcap_none, asn1->tvb,
495 len_offset, asn1->offset - len_offset, "Length: Indefinite");
497 seq_tree[num_seq] = subtree;
498 item_tree[num_seq] = item;
499 off_tree[num_seq] = saved_offset;
504 proto_tree_add_uint(subtree, hf_tcap_length, asn1->tvb,
505 len_offset, asn1->offset - len_offset, len);
507 proto_item_set_len(item, (asn1->offset - saved_offset) + len);
516 proto_tree_add_uint_format(use_tree, hf_tcap_tag, asn1->tvb,
517 saved_offset, len_offset - saved_offset, tag, "Parameter Tag");
518 proto_tree_add_none_format(use_tree, hf_tcap_none, asn1->tvb,
519 len_offset, asn1->offset - len_offset, "Length: Indefinite");
521 seq_tree[num_seq] = use_tree;
522 item_tree[num_seq] = NULL;
529 proto_tree_add_none_format(use_tree, hf_tcap_none, asn1->tvb,
530 saved_offset, -1, "Parameter");
532 subtree = proto_item_add_subtree(item, ett_param);
534 proto_tree_add_uint_format(subtree, hf_tcap_tag, asn1->tvb,
535 saved_offset, len_offset - saved_offset, tag, "Parameter Tag");
537 proto_tree_add_uint(subtree, hf_tcap_length, asn1->tvb,
538 len_offset, asn1->offset - len_offset, len);
540 proto_item_set_len(item, (asn1->offset - saved_offset) + len);
542 proto_tree_add_none_format(subtree, hf_tcap_none, asn1->tvb,
543 asn1->offset, len, "Parameter Data");
548 if (tvb_length_remaining(asn1->tvb, asn1->offset) <=0) break;
550 while ((num_seq > 0) &&
553 saved_offset = asn1->offset;
554 asn1_eoc_decode(asn1, -1);
556 proto_tree_add_none_format(seq_tree[num_seq-1], hf_tcap_none, asn1->tvb,
557 saved_offset, asn1->offset - saved_offset, "End of Contents");
559 if (item_tree[num_seq-1] != NULL)
561 proto_item_set_len(item_tree[num_seq-1], asn1->offset - off_tree[num_seq-1]);
572 dissect_tcap_component(ASN1_SCK *asn1, proto_tree *tree, guint *len_p)
581 saved_offset = asn1->offset;
582 asn1_id_decode1(asn1, &tag);
585 proto_tree_add_none_format(tree, hf_tcap_none, asn1->tvb,
586 saved_offset, -1, "Component ID");
588 subtree = proto_item_add_subtree(item, ett_component);
590 proto_tree_add_uint_format(subtree, hf_tcap_tag, asn1->tvb,
591 saved_offset, asn1->offset - saved_offset, tag,
592 "Component ID Identifier");
594 dissect_tcap_len(asn1, subtree, &def_len, len_p);
596 proto_item_set_len(item, (asn1->offset - saved_offset) + *len_p);
602 dissect_tcap_problem(ASN1_SCK *asn1, proto_tree *tree)
604 guint orig_offset, saved_offset = 0;
608 proto_item *item = NULL;
610 gchar *type_str = NULL;
615 orig_offset = asn1->offset;
616 saved_offset = asn1->offset;
617 asn1_id_decode1(asn1, &tag);
618 tag_len = asn1->offset - saved_offset;
621 proto_tree_add_none_format(tree, hf_tcap_none, asn1->tvb,
622 saved_offset, -1, "Problem Code");
624 subtree = proto_item_add_subtree(item, ett_problem);
626 dissect_tcap_len(asn1, subtree, &def_len, &len);
627 proto_item_set_len(item, (asn1->offset - saved_offset) + len);
631 proto_tree_add_none_format(subtree, hf_tcap_none, asn1->tvb,
632 asn1->offset, len, "Unknown encoding of Problem Code");
638 saved_offset = asn1->offset;
639 asn1_int32_value_decode(asn1, 1, &spec);
644 type_str = "General Problem";
647 case 0: str = "Unrecognized Component"; break;
648 case 1: str = "Mistyped Component"; break;
649 case 2: str = "Badly Structured Component"; break;
660 case 0: str = "Duplicate Invoke ID"; break;
661 case 1: str = "Unrecognized Operation"; break;
662 case 2: str = "Mistyped Parameter"; break;
663 case 3: str = "Resource Limitation"; break;
664 case 4: str = "Initiating Release"; break;
665 case 5: str = "Unrecognized Linked ID"; break;
666 case 6: str = "Linked Response Unexpected"; break;
667 case 7: str = "Unexpected Linked Operation"; break;
675 type_str = "Return Result";
678 case 0: str = "Unrecognized Invoke ID"; break;
679 case 1: str = "Return Result Unexpected"; break;
680 case 2: str = "Mistyped Parameter"; break;
688 type_str = "Return Error";
691 case 0: str = "Unrecognized Invoke ID"; break;
692 case 1: str = "Return Error Unexpected"; break;
693 case 2: str = "Unrecognized Error"; break;
694 case 3: str = "Unexpected Error"; break;
695 case 4: str = "Mistyped Parameter"; break;
703 type_str = "Undefined";
707 proto_tree_add_uint_format(subtree, hf_tcap_tag, asn1->tvb,
708 orig_offset, tag_len, tag, type_str);
710 proto_tree_add_none_format(subtree, hf_tcap_none, asn1->tvb,
711 saved_offset, 1, "Problem Specifier %s", str);
716 dissect_ansi_opr_code(ASN1_SCK *asn1, proto_tree *tree)
720 gboolean got_it = FALSE;
723 #define TCAP_NAT_OPR_CODE_TAG 0xd0
724 if (check_tcap_tag(asn1, TCAP_NAT_OPR_CODE_TAG))
727 dissect_tcap_tag(asn1, tree, &tag, "National TCAP Operation Code Identifier");
730 #define TCAP_PRIV_OPR_CODE_TAG 0xd1
731 else if (check_tcap_tag(asn1, TCAP_PRIV_OPR_CODE_TAG))
734 dissect_tcap_tag(asn1, tree, &tag, "Private TCAP Operation Code Identifier");
740 dissect_tcap_len(asn1, tree, &def_len, &len);
742 proto_tree_add_none_format(tree, hf_tcap_none, asn1->tvb, asn1->offset, len, "Operation Code");
749 dissect_ansi_problem(ASN1_SCK *asn1, proto_tree *tree)
751 guint saved_offset = 0;
755 proto_item *item = NULL;
757 gchar *type_str = NULL;
762 #define TCAP_PROB_CODE_TAG 0xd5
763 if (check_tcap_tag(asn1, TCAP_PROB_CODE_TAG))
765 str = "Problem Code Identifier";
773 saved_offset = asn1->offset;
774 asn1_id_decode1(asn1, &tag);
777 proto_tree_add_none_format(tree, hf_tcap_none, asn1->tvb,
778 saved_offset, -1, "Problem Code");
780 subtree = proto_item_add_subtree(item, ett_problem);
782 proto_tree_add_uint_format(subtree, hf_tcap_tag, asn1->tvb,
783 saved_offset, asn1->offset - saved_offset, tag, str);
785 dissect_tcap_len(asn1, subtree, &def_len, &len);
786 proto_item_set_len(item, (asn1->offset - saved_offset) + len);
790 proto_tree_add_none_format(subtree, hf_tcap_none, asn1->tvb,
791 asn1->offset, len, "Unknown encoding of Problem Code");
797 saved_offset = asn1->offset;
798 asn1_int32_value_decode(asn1, 1, &type);
799 asn1_int32_value_decode(asn1, 1, &spec);
803 case 0: type_str = "Not used"; break;
806 type_str = "General";
809 case 1: str = "Unrecognized Component Type"; break;
810 case 2: str = "Incorrect Component Portion"; break;
811 case 3: str = "Badly Structured Component Portion"; break;
822 case 1: str = "Duplicate Invoke ID"; break;
823 case 2: str = "Unrecognized Operation Code"; break;
824 case 3: str = "Incorrect Parameter"; break;
825 case 4: str = "Unrecognized Correlation ID"; break;
833 type_str = "Return Result";
836 case 1: str = "Unrecognized Correlation ID"; break;
837 case 2: str = "Unexpected Return Result"; break;
838 case 3: str = "Incorrect Parameter"; break;
846 type_str = "Return Error";
849 case 1: str = "Unrecognized Correlation ID"; break;
850 case 2: str = "Unexpected Return Error"; break;
851 case 3: str = "Unrecognized Error"; break;
852 case 4: str = "Unexpected Error"; break;
853 case 5: str = "Incorrect Parameter"; break;
861 type_str = "Transaction Portion";
864 case 1: str = "Unrecognized Package Type"; break;
865 case 2: str = "Incorrect Transaction Portion"; break;
866 case 3: str = "Badly Structured Transaction Portion"; break;
867 case 4: str = "Unrecognized Transaction ID"; break;
868 case 5: str = "Permission to Release"; break;
869 case 6: str = "Resource Unavailable"; break;
877 type_str = "Undefined";
881 if (spec == 255) { str = "Reserved"; }
882 else if (spec == 0) { str = "Not used"; }
884 proto_tree_add_none_format(subtree, hf_tcap_none, asn1->tvb,
885 saved_offset, 1, "Problem Type %s", type_str);
887 proto_tree_add_none_format(subtree, hf_tcap_none, asn1->tvb,
888 saved_offset + 1, 1, "Problem Specifier %s", str);
893 dissect_ansi_error(ASN1_SCK *asn1, proto_tree *tree)
895 guint saved_offset = 0;
899 proto_item *item = NULL;
904 #define TCAP_NAT_ERR_CODE_TAG 0xd3
905 if (check_tcap_tag(asn1, TCAP_NAT_ERR_CODE_TAG))
907 str = "National TCAP Error Code Identifier";
909 #define TCAP_PRIV_ERR_CODE_TAG 0xd4
910 else if (check_tcap_tag(asn1, TCAP_PRIV_ERR_CODE_TAG))
912 str = "Private TCAP Error Code Identifier";
920 saved_offset = asn1->offset;
921 asn1_id_decode1(asn1, &tag);
924 proto_tree_add_none_format(tree, hf_tcap_none, asn1->tvb,
925 saved_offset, -1, "TCAP Error Code");
927 subtree = proto_item_add_subtree(item, ett_error);
929 proto_tree_add_uint_format(subtree, hf_tcap_tag, asn1->tvb,
930 saved_offset, asn1->offset - saved_offset, tag, str);
932 dissect_tcap_len(asn1, subtree, &def_len, &len);
933 proto_item_set_len(item, (asn1->offset - saved_offset) + len);
935 proto_tree_add_none_format(subtree, hf_tcap_none, asn1->tvb,
936 asn1->offset, len, "Error Code");
943 dissect_ansi_param(ASN1_SCK *asn1, proto_tree *tree)
947 gboolean got_it = FALSE;
950 #define TCAP_PARAM_SET_TAG 0xf2
951 if (check_tcap_tag(asn1, TCAP_PARAM_SET_TAG))
954 dissect_tcap_tag(asn1, tree, &tag, "Parameter Set Identifier");
957 #define TCAP_PARAM_SEQ_TAG 0x30
958 else if (check_tcap_tag(asn1, TCAP_PARAM_SEQ_TAG))
961 dissect_tcap_tag(asn1, tree, &tag, "Parameter Sequence Identifier");
967 dissect_tcap_len(asn1, tree, &def_len, &len);
969 proto_tree_add_none_format(tree, hf_tcap_none, asn1->tvb, asn1->offset, len, "Parameter Data");
976 dissect_ansi_tcap_reject(ASN1_SCK *asn1, proto_tree *tree)
981 #define COMPONENT_ID_TAG 0xcf
982 if (check_tcap_tag(asn1, COMPONENT_ID_TAG))
984 subtree = dissect_tcap_component(asn1, tree, &len);
989 dissect_tcap_octet(asn1, subtree, "Correlation ID:");
994 dissect_ansi_problem(asn1, tree);
996 dissect_ansi_param(asn1, tree);
1000 dissect_ansi_tcap_re(ASN1_SCK *asn1, proto_tree *tree)
1003 proto_tree *subtree;
1005 #define COMPONENT_ID_TAG 0xcf
1006 if (check_tcap_tag(asn1, COMPONENT_ID_TAG))
1008 subtree = dissect_tcap_component(asn1, tree, &len);
1013 dissect_tcap_octet(asn1, tree, "Correlation ID:");
1018 dissect_ansi_error(asn1, tree);
1020 dissect_ansi_param(asn1, tree);
1024 dissect_ansi_tcap_rr(ASN1_SCK *asn1, proto_tree *tree)
1027 proto_tree *subtree;
1029 #define COMPONENT_ID_TAG 0xcf
1030 if (check_tcap_tag(asn1, COMPONENT_ID_TAG))
1032 subtree = dissect_tcap_component(asn1, tree, &len);
1037 dissect_tcap_octet(asn1, tree, "Correlation ID:");
1042 dissect_ansi_param(asn1, tree);
1046 dissect_ansi_tcap_invoke(ASN1_SCK *asn1, proto_tree *tree)
1049 proto_tree *subtree;
1051 #define COMPONENT_ID_TAG 0xcf
1052 if (check_tcap_tag(asn1, COMPONENT_ID_TAG))
1054 subtree = dissect_tcap_component(asn1, tree, &len);
1059 dissect_tcap_octet(asn1, tree, "Invoke ID:");
1063 dissect_tcap_octet(asn1, tree, "Invoke ID:");
1064 dissect_tcap_octet(asn1, tree, "Correlation ID:");
1069 dissect_ansi_opr_code(asn1, tree);
1071 dissect_ansi_param(asn1, tree);
1075 dissect_tcap_invoke(ASN1_SCK *asn1, proto_tree *tree)
1077 proto_tree *subtree;
1078 guint saved_offset = 0;
1083 guint start = asn1->offset;
1086 saved_offset = asn1->offset;
1087 ret = asn1_id_decode1(asn1, &tag);
1088 item = proto_tree_add_none_format(tree, hf_tcap_none, asn1->tvb, saved_offset, -1, "Components");
1089 subtree = proto_item_add_subtree(item, ett_component);
1090 proto_tree_add_uint_format(subtree, hf_tcap_tag, asn1->tvb, saved_offset, asn1->offset - saved_offset,
1091 tag, "Invoke Type Tag");
1093 dissect_tcap_len(asn1, subtree, &def_len, &len);
1097 proto_item_set_len(item, (asn1->offset - start) + len);
1100 dissect_tcap_invokeId(asn1, subtree);
1102 dissect_tcap_lnkId(asn1, subtree);
1104 dissect_tcap_opr_code(asn1, subtree);
1106 dissect_tcap_param(asn1, subtree);
1110 dissect_tcap_eoc(asn1, subtree);
1115 dissect_tcap_rr(ASN1_SCK *asn1, proto_tree *tree, gchar *str)
1117 guint tag, len, comp_len;
1120 proto_tree *subtree;
1122 gboolean comp_def_len;
1125 saved_offset = asn1->offset;
1126 asn1_id_decode1(asn1, &tag);
1127 item = proto_tree_add_none_format(tree, hf_tcap_none, asn1->tvb, saved_offset, -1, "Components");
1128 subtree = proto_item_add_subtree(item, ett_component);
1129 proto_tree_add_uint_format(subtree, hf_tcap_tag, asn1->tvb, saved_offset, asn1->offset - saved_offset,
1132 dissect_tcap_len(asn1, subtree, &comp_def_len, &comp_len);
1136 proto_item_set_len(item, (asn1->offset - saved_offset) + comp_len);
1139 dissect_tcap_invokeId(asn1, subtree);
1142 if (check_tcap_tag(asn1, TC_SEQ_TAG))
1145 dissect_tcap_tag(asn1, subtree, &tag, "Sequence Tag");
1146 dissect_tcap_len(asn1, subtree, &def_len, &len);
1149 dissect_tcap_opr_code(asn1, subtree);
1151 dissect_tcap_param(asn1, subtree);
1155 dissect_tcap_eoc(asn1, subtree);
1160 dissect_tcap_re(ASN1_SCK *asn1, proto_tree *tree)
1162 guint tag, len, comp_len;
1165 proto_tree *subtree;
1169 saved_offset = asn1->offset;
1170 asn1_id_decode1(asn1, &tag);
1171 item = proto_tree_add_none_format(tree, hf_tcap_none, asn1->tvb, saved_offset, -1, "Components");
1172 subtree = proto_item_add_subtree(item, ett_component);
1173 proto_tree_add_uint_format(subtree, hf_tcap_tag, asn1->tvb, saved_offset, asn1->offset - saved_offset,
1174 tag, "Return Error Type Tag");
1176 dissect_tcap_len(asn1, subtree, &def_len, &comp_len);
1180 proto_item_set_len(item, (asn1->offset - saved_offset) + comp_len);
1183 saved_offset = asn1->offset;
1184 dissect_tcap_invokeId(asn1, subtree);
1186 #define TC_LOCAL_ERR_CODE_TAG 0x2
1187 #define TC_GBL_ERR_CODE_TAG 0x6
1188 if (check_tcap_tag(asn1, TC_LOCAL_ERR_CODE_TAG))
1191 dissect_tcap_tag(asn1, subtree, &tag, "Local Error Code Tag");
1193 else if (check_tcap_tag(asn1, TC_GBL_ERR_CODE_TAG))
1196 dissect_tcap_tag(asn1, subtree, &tag, "Global Error Code Tag");
1200 proto_tree_add_none_format(subtree, hf_tcap_none, asn1->tvb, asn1->offset, comp_len,
1201 "Unknown Error Code");
1203 asn1->offset += (comp_len - (asn1->offset - saved_offset));
1207 dissect_tcap_len(asn1, subtree, &def_len, &len);
1208 dissect_tcap_integer(asn1, subtree, len, "Error Code:");
1210 dissect_tcap_param(asn1, subtree);
1214 dissect_tcap_eoc(asn1, subtree);
1221 dissect_tcap_reject(ASN1_SCK *asn1, proto_tree *tree)
1223 guint tag, comp_len;
1226 proto_tree *subtree;
1231 saved_offset = asn1->offset;
1232 asn1_id_decode1(asn1, &tag);
1234 item = proto_tree_add_none_format(tree, hf_tcap_none, asn1->tvb, saved_offset, -1, "Components");
1236 subtree = proto_item_add_subtree(item, ett_component);
1238 proto_tree_add_uint_format(subtree, hf_tcap_tag, asn1->tvb, saved_offset, asn1->offset - saved_offset,
1239 tag, "Reject Type Tag");
1241 dissect_tcap_len(asn1, subtree, &def_len, &comp_len);
1245 proto_item_set_len(item, (asn1->offset - saved_offset) + comp_len);
1248 dissect_tcap_invokeId(asn1, subtree);
1250 dissect_tcap_problem(asn1, tree);
1254 dissect_tcap_eoc(asn1, subtree);
1259 dissect_ansi_tcap_next_tvb(ASN1_SCK *asn1, guint len, proto_tree *tree)
1264 gboolean flag = TRUE;
1266 proto_item *item, *tag_item;
1267 proto_tree *subtree, *tag_subtree;
1271 if (lock_info_col) col_set_fence(g_pinfo->cinfo, COL_INFO);
1273 next_tvb = tvb_new_subset(asn1->tvb, asn1->offset, len, len);
1275 /* process components data */
1276 if (!dissector_try_port(tcap_ansi_ssn_dissector_table, g_pinfo->match_port, next_tvb, g_pinfo, g_tcap_tree))
1280 saved_offset = asn1->offset;
1281 ret = asn1_id_decode1(asn1, &tag);
1284 * verify tag type is known
1288 case ANSI_TC_INVOKE_L :
1291 case ANSI_TC_REJECT :
1292 case ANSI_TC_INVOKE_N :
1304 item = proto_tree_add_none_format(tree, hf_tcap_none, asn1->tvb, saved_offset, -1, "Components");
1305 subtree = proto_item_add_subtree(item, ett_component);
1309 case ANSI_TC_INVOKE_L :
1310 tag_item = proto_tree_add_uint_format(subtree, hf_tcap_tag, asn1->tvb, saved_offset,
1311 asn1->offset - saved_offset, tag, "Invoke(Last)");
1312 dissect_tcap_len(asn1, subtree, &def_len, &len);
1313 tag_subtree = proto_item_add_subtree(tag_item, ett_component);
1315 dissect_ansi_tcap_invoke(asn1, tag_subtree);
1318 tag_item = proto_tree_add_uint_format(subtree, hf_tcap_tag, asn1->tvb, saved_offset,
1319 asn1->offset - saved_offset, tag, "Return Result(Last)");
1320 dissect_tcap_len(asn1, subtree, &def_len, &len);
1321 tag_subtree = proto_item_add_subtree(tag_item, ett_component);
1323 dissect_ansi_tcap_rr(asn1, tag_subtree);
1326 tag_item = proto_tree_add_uint_format(subtree, hf_tcap_tag, asn1->tvb, saved_offset,
1327 asn1->offset - saved_offset, tag, "Return Error");
1328 dissect_tcap_len(asn1, subtree, &def_len, &len);
1329 tag_subtree = proto_item_add_subtree(tag_item, ett_component);
1331 dissect_ansi_tcap_re(asn1, tag_subtree);
1333 case ANSI_TC_REJECT :
1334 tag_item = proto_tree_add_uint_format(subtree, hf_tcap_tag, asn1->tvb, saved_offset,
1335 asn1->offset - saved_offset, tag, "Reject");
1336 dissect_tcap_len(asn1, subtree, &def_len, &len);
1337 tag_subtree = proto_item_add_subtree(tag_item, ett_component);
1339 dissect_ansi_tcap_reject(asn1, tag_subtree);
1341 case ANSI_TC_INVOKE_N :
1342 tag_item = proto_tree_add_uint_format(subtree, hf_tcap_tag, asn1->tvb, saved_offset,
1343 asn1->offset - saved_offset, tag, "Invoke(Not Last)");
1344 dissect_tcap_len(asn1, subtree, &def_len, &len);
1345 tag_subtree = proto_item_add_subtree(tag_item, ett_component);
1347 dissect_ansi_tcap_invoke(asn1, tag_subtree);
1350 tag_item = proto_tree_add_uint_format(subtree, hf_tcap_tag, asn1->tvb, saved_offset,
1351 asn1->offset - saved_offset, tag, "Return Result(Not Last)");
1352 dissect_tcap_len(asn1, subtree, &def_len, &len);
1353 tag_subtree = proto_item_add_subtree(tag_item, ett_component);
1355 dissect_ansi_tcap_rr(asn1, tag_subtree);
1359 proto_item_set_len(item, asn1->offset - saved_offset);
1365 /* No sub-dissection occured, treat it as raw data */
1366 call_dissector(data_handle, next_tvb, g_pinfo, g_tcap_tree);
1371 dissect_tcap_next_tvb(ASN1_SCK *asn1, guint len, proto_tree *tree)
1378 if (lock_info_col) col_set_fence(g_pinfo->cinfo, COL_INFO);
1380 next_tvb = tvb_new_subset(asn1->tvb, asn1->offset, len, len);
1382 /* process components data */
1383 if (dissector_try_port(tcap_itu_ssn_dissector_table, g_pinfo->match_port, next_tvb, g_pinfo, g_tcap_tree))
1385 asn1->offset += len;
1389 saved_offset = asn1->offset;
1390 ret = asn1_id_decode1(asn1, &tag);
1391 asn1->offset = saved_offset;
1396 dissect_tcap_invoke(asn1, tree);
1399 dissect_tcap_rr(asn1, tree, "Return Result(Last) Type Tag");
1402 dissect_tcap_re(asn1, tree);
1405 dissect_tcap_reject(asn1, tree);
1408 /* same definition as RRL */
1409 dissect_tcap_rr(asn1, tree, "Return Result(Not Last) Type Tag");
1412 /* treat it as raw data */
1413 call_dissector(data_handle, next_tvb, g_pinfo, g_tcap_tree);
1420 dissect_tcap_components(ASN1_SCK *asn1, proto_tree *tcap_tree)
1422 proto_tree *subtree;
1423 guint saved_offset = 0;
1424 guint len, next_tvb_len;
1427 proto_item *cmp_item;
1428 guint cmp_start = asn1->offset;
1431 if (tvb_length_remaining(asn1->tvb, asn1->offset) <= 0)
1436 saved_offset = asn1->offset;
1437 ret = asn1_id_decode1(asn1, &tag);
1439 if (ST_ITU_CMP_TAG != tag)
1441 asn1->offset = saved_offset;
1445 cmp_item = proto_tree_add_none_format(tcap_tree, hf_tcap_none, asn1->tvb, saved_offset, -1, "Components Portion");
1446 subtree = proto_item_add_subtree(cmp_item, ett_cmp_portion);
1448 proto_tree_add_uint_format(subtree, hf_tcap_tag, asn1->tvb, saved_offset, asn1->offset - saved_offset, tag,
1449 "Component Portion Tag");
1451 dissect_tcap_len(asn1, subtree, &def_len, &len);
1455 proto_item_set_len(cmp_item, (asn1->offset - cmp_start) + len);
1458 /* call next dissector */
1463 * take remaining length minus the EOC for the indefinite
1467 tvb_length_remaining(asn1->tvb, asn1->offset) - TC_EOC_LEN;
1475 * take length minus the EOC for the indefinite
1476 * transaction message length
1478 next_tvb_len -= g_tcap_ends_def_len ? 0 : TC_EOC_LEN;
1480 dissect_tcap_next_tvb(asn1, next_tvb_len, subtree);
1484 dissect_tcap_eoc(asn1, subtree);
1487 proto_item_set_len(cmp_item, asn1->offset - cmp_start);
1492 /* dissect dialog portion */
1494 dissect_tcap_dlg_protocol_version(ASN1_SCK *asn1, proto_tree *tcap_tree, proto_item *ti)
1496 guint saved_offset = 0;
1502 #define TC_DLG_PROTO_VER_TAG 0x80
1503 if (check_tcap_tag(asn1, TC_DLG_PROTO_VER_TAG))
1505 saved_offset = asn1->offset;
1506 ret = asn1_id_decode1(asn1, &tag);
1507 proto_tree_add_uint_format(tcap_tree, hf_tcap_tag, asn1->tvb,
1508 saved_offset, asn1->offset - saved_offset, tag,
1509 "Protocol Version Tag: 0x%x", tag);
1511 dissect_tcap_len(asn1, tcap_tree, &def_len, &len);
1512 saved_offset = asn1->offset;
1514 proto_tree_add_bytes(tcap_tree, hf_tcap_bytes, asn1->tvb, saved_offset, len,
1515 (guchar*)(tvb_get_ptr(asn1->tvb, saved_offset, len)));
1516 asn1->offset += len;
1523 dissect_tcap_dlg_application_context_name(ASN1_SCK *asn1, proto_tree *tcap_tree)
1525 guint saved_offset = 0;
1526 guint name_len, len, len2;
1532 saved_offset = asn1->offset;
1533 ret = asn1_id_decode1(asn1, &tag);
1534 proto_tree_add_uint_format(tcap_tree, hf_tcap_tag, asn1->tvb, saved_offset, asn1->offset - saved_offset, tag,
1535 "Application Context Name Tag: 0x%x", tag);
1537 dissect_tcap_len(asn1, tcap_tree, &def_len, &name_len);
1539 saved_offset = asn1->offset;
1540 ret = asn1_oid_decode (asn1, &oid, &len, &len2);
1541 proto_tree_add_bytes(tcap_tree, hf_tcap_app_con_name, asn1->tvb, saved_offset, len2, tvb_get_ptr(asn1->tvb, saved_offset, len2));
1542 if (ret == ASN1_ERR_NOERROR) g_free(oid);
1546 /* for Application Context Name Tag */
1547 dissect_tcap_eoc(asn1, tcap_tree);
1554 dissect_tcap_dlg_result(ASN1_SCK *asn1, proto_tree *tree)
1556 guint tag, rtag_len, itag_len;
1557 guint saved_offset = 0;
1561 gboolean rtag_def_len;
1564 dissect_tcap_tag(asn1, tree, &tag, "Result Tag");
1566 dissect_tcap_len(asn1, tree, &rtag_def_len, &rtag_len);
1569 dissect_tcap_tag(asn1, tree, &tag, "Integer Tag");
1571 dissect_tcap_len(asn1, tree, &def_len, &itag_len);
1573 saved_offset = asn1->offset;
1574 asn1_int32_value_decode(asn1, itag_len, &value);
1578 case 0x00: str = "Accepted"; break;
1579 case 0x01: str = "Reject-permanent"; break;
1580 default: str = "Unknown value"; break;
1583 proto_tree_add_int_format(tree, hf_tcap_int, asn1->tvb, saved_offset, asn1->offset - saved_offset,
1584 value, "%s %d", str, value);
1588 /* for Result Tag */
1589 dissect_tcap_eoc(asn1, tree);
1596 dissect_tcap_dlg_result_src_diag(ASN1_SCK *asn1, proto_tree *tree)
1598 guint saved_offset = 0;
1604 gboolean serv_def_len;
1605 gboolean diag_def_len;
1608 dissect_tcap_tag(asn1, tree, &tag, "Result Source Diagnostic Tag");
1610 dissect_tcap_len(asn1, tree, &diag_def_len, &len);
1612 #define TC_DIAG_SERV_USER_TAG 0xa1
1613 #define TC_DIAG_SERV_PROV_TAG 0xa2
1614 if (check_tcap_tag(asn1, TC_DIAG_SERV_USER_TAG))
1617 dissect_tcap_tag(asn1, tree, &tag, "Dialogue Service User Tag");
1620 else if (check_tcap_tag(asn1, TC_DIAG_SERV_PROV_TAG))
1623 dissect_tcap_tag(asn1, tree, &tag, "Dialogue Service Provider Tag");
1628 proto_tree_add_none_format(tree, hf_tcap_none, asn1->tvb, asn1->offset, len,
1629 "Unknown Result Source Diagnostic");
1631 asn1->offset += len;
1635 dissect_tcap_len(asn1, tree, &serv_def_len, &len);
1638 dissect_tcap_tag(asn1, tree, &tag, "Integer Tag");
1640 dissect_tcap_len(asn1, tree, &def_len, &len);
1642 saved_offset = asn1->offset;
1643 asn1_int32_value_decode(asn1, len, &value);
1649 case 0x00: str = "Null"; break;
1650 case 0x01: str = "No reason given"; break;
1651 case 0x02: str = "Application Context Name not supplied"; break;
1652 default: str = "Unknown value"; break;
1659 case 0x00: str = "Null"; break;
1660 case 0x01: str = "No reason given"; break;
1661 case 0x02: str = "No common dialogue portion"; break;
1662 default: str = "Unknown value"; break;
1666 proto_tree_add_int_format(tree, hf_tcap_int, asn1->tvb, saved_offset, asn1->offset - saved_offset,
1667 value, "%s %d", str, value);
1671 /* for Dialogue Service User/Provider Tag */
1672 dissect_tcap_eoc(asn1, tree);
1677 /* for Result Source Diagnostic Tag */
1678 dissect_tcap_eoc(asn1, tree);
1685 dissect_tcap_dlg_user_info(ASN1_SCK *asn1, proto_tree *tree)
1688 guint saved_offset = 0;
1690 gboolean user_info_def_len;
1692 #define TC_USR_INFO_TAG 0xbe
1693 if (check_tcap_tag(asn1, TC_USR_INFO_TAG))
1696 dissect_tcap_tag(asn1, tree, &tag, "User Info Tag");
1697 dissect_tcap_len(asn1, tree, &user_info_def_len, &len);
1699 #define TC_EXT_TAG 0x28
1700 if (check_tcap_tag(asn1, TC_EXT_TAG))
1702 saved_offset = asn1->offset;
1703 asn1_id_decode1(asn1, &tag);
1704 proto_tree_add_uint_format(tree, hf_tcap_length, asn1->tvb, saved_offset, asn1->offset - saved_offset,
1705 tag, "External Tag: 0x%x", tag);
1707 dissect_tcap_len(asn1, tree, &def_len, &len);
1710 proto_tree_add_none_format(tree, hf_tcap_none, asn1->tvb, asn1->offset, len, "Parameter Data");
1711 asn1->offset += len;
1713 if (!user_info_def_len)
1715 /* for User Information Tag */
1716 dissect_tcap_eoc(asn1, tree);
1724 dissect_tcap_dlg_req(ASN1_SCK *asn1, proto_tree *tcap_tree)
1726 proto_tree *subtree;
1727 guint saved_offset = 0;
1731 proto_item *req_item;
1732 guint req_start = asn1->offset;
1735 /* dissect dialog portion */
1736 saved_offset = asn1->offset;
1737 ret = asn1_id_decode1(asn1, &tag);
1738 req_item = proto_tree_add_none_format(tcap_tree, hf_tcap_none, asn1->tvb, saved_offset, -1, "Dialogue Request");
1739 subtree = proto_item_add_subtree(req_item, ett_dlg_req);
1740 proto_tree_add_uint(subtree, hf_tcap_dlg_type, asn1->tvb, saved_offset, asn1->offset - saved_offset, tag);
1742 dissect_tcap_len(asn1, subtree, &def_len, &len);
1744 dissect_tcap_dlg_protocol_version(asn1, subtree, NULL);
1746 dissect_tcap_dlg_application_context_name(asn1, subtree);
1748 dissect_tcap_dlg_user_info(asn1, subtree);
1750 /* decode end of sequence */
1754 /* for Dialogue Request Tag */
1755 dissect_tcap_eoc(asn1, subtree);
1758 proto_item_set_len(req_item, asn1->offset - req_start);
1764 dissect_tcap_dlg_rsp(ASN1_SCK *asn1, proto_tree *tcap_tree)
1766 proto_tree *subtree;
1767 guint saved_offset = 0;
1771 proto_item *req_item;
1772 guint req_start = asn1->offset;
1775 /* dissect dialog portion */
1776 saved_offset = asn1->offset;
1777 ret = asn1_id_decode1(asn1, &tag);
1778 req_item = proto_tree_add_none_format(tcap_tree, hf_tcap_none, asn1->tvb, saved_offset, -1, "Dialogue Response");
1779 subtree = proto_item_add_subtree(req_item, ett_dlg_rsp);
1780 proto_tree_add_uint(subtree, hf_tcap_dlg_type, asn1->tvb, saved_offset, asn1->offset - saved_offset, tag);
1782 dissect_tcap_len(asn1, subtree, &def_len, &len);
1784 dissect_tcap_dlg_protocol_version(asn1, subtree, NULL);
1786 dissect_tcap_dlg_application_context_name(asn1, subtree);
1789 dissect_tcap_dlg_result(asn1, subtree);
1791 /* result source diag */
1792 dissect_tcap_dlg_result_src_diag(asn1, subtree);
1794 dissect_tcap_dlg_user_info(asn1, subtree);
1798 /* for Dialogue Response Tag */
1799 dissect_tcap_eoc(asn1, subtree);
1802 proto_item_set_len(req_item, asn1->offset - req_start);
1808 dissect_tcap_dlg_abrt(ASN1_SCK *asn1, proto_tree *tree)
1810 proto_tree *subtree;
1811 guint saved_offset = 0;
1815 proto_item *req_item;
1818 gboolean def_len, abort_def_len;
1820 /* dissect dialog pabort portion */
1821 saved_offset = asn1->offset;
1822 ret = asn1_id_decode1(asn1, &tag);
1823 req_item = proto_tree_add_none_format(tree, hf_tcap_none, asn1->tvb, saved_offset, -1, "Dialogue Abort");
1824 subtree = proto_item_add_subtree(req_item, ett_dlg_abort );
1825 proto_tree_add_uint(subtree, hf_tcap_dlg_type, asn1->tvb, saved_offset, asn1->offset - saved_offset, tag);
1827 dissect_tcap_len(asn1, subtree, &abort_def_len, &len);
1830 dissect_tcap_tag(asn1, subtree, &tag, "Abort Source Tag");
1831 dissect_tcap_len(asn1, subtree, &def_len, &len);
1833 saved_offset = asn1->offset;
1834 asn1_int32_value_decode(asn1, len, &value);
1838 case 0x00: str = "Dialogue Service User"; break;
1839 case 0x01: str = "Dialogue Service Provider"; break;
1840 default: str = "Unknown value"; break;
1843 proto_tree_add_int_format(subtree, hf_tcap_int, asn1->tvb, saved_offset, asn1->offset - saved_offset,
1844 value, "Abort Source: %s %d", str, value);
1846 dissect_tcap_dlg_user_info(asn1, subtree);
1850 /* for Dialogue Abort Tag */
1851 dissect_tcap_eoc(asn1, subtree);
1858 dissect_tcap_dialog_portion(ASN1_SCK *asn1, proto_tree *tcap_tree, proto_item *ti)
1860 proto_tree *subtree;
1861 guint saved_offset = 0;
1865 proto_item *dlg_item;
1866 guint dlg_start = asn1->offset;
1867 gboolean def_len, ext_tag_def_len, portion_def_len;
1869 if (tvb_length_remaining(asn1->tvb, asn1->offset) <= 0)
1874 /* dissect dialog portion */
1875 saved_offset = asn1->offset;
1876 ret = asn1_id_decode1(asn1, &tag);
1878 /* error handling */
1879 if (ST_ITU_DLG_TAG != tag)
1881 asn1->offset = saved_offset;
1886 proto_tree_add_none_format(tcap_tree, hf_tcap_none, asn1->tvb,
1887 saved_offset, -1, "Dialogue Portion");
1889 subtree = proto_item_add_subtree(dlg_item, ett_dlg_portion);
1891 proto_tree_add_uint_format(subtree, hf_tcap_tag, asn1->tvb,
1892 saved_offset, asn1->offset - saved_offset, tag, "Dialogue Portion Tag");
1894 dissect_tcap_len(asn1, subtree, &portion_def_len, &len);
1896 if (portion_def_len)
1898 proto_item_set_len(dlg_item, len);
1901 ext_tag_def_len = FALSE;
1902 saved_offset = asn1->offset;
1903 ret = asn1_id_decode1(asn1, &tag);
1904 #define TC_EXT_TAG 0x28
1905 if (TC_EXT_TAG != tag)
1907 asn1->offset = saved_offset;
1911 proto_tree_add_uint_format(subtree, hf_tcap_length, asn1->tvb,
1912 saved_offset, asn1->offset - saved_offset, tag,
1913 "External Tag: 0x%x", tag);
1915 dissect_tcap_len(asn1, subtree, &ext_tag_def_len, &len);
1918 saved_offset = asn1->offset;
1919 ret = asn1_id_decode1(asn1, &tag);
1920 #define TC_OID_TAG 0x06
1921 if (TC_OID_TAG != tag)
1923 asn1->offset = saved_offset;
1927 proto_tree_add_uint_format(subtree, hf_tcap_tag, asn1->tvb,
1928 saved_offset, asn1->offset - saved_offset, tag,
1929 "Object Identifier Tag");
1931 dissect_tcap_len(asn1, subtree, &def_len, &len);
1933 saved_offset = asn1->offset;
1935 proto_tree_add_bytes(subtree, hf_tcap_bytes, asn1->tvb, saved_offset, len,
1936 (guchar*)(tvb_get_ptr(asn1->tvb, saved_offset, len)));
1938 asn1->offset += len;
1941 saved_offset = asn1->offset;
1942 ret = asn1_id_decode1(asn1, &tag);
1944 proto_tree_add_uint_format(subtree, hf_tcap_tag, asn1->tvb,
1945 saved_offset, asn1->offset - saved_offset, tag,
1946 "Single-ASN.1-type Tag");
1948 dissect_tcap_len(asn1, subtree, &def_len, &len);
1950 proto_item_set_len(dlg_item, asn1->offset - dlg_start);
1953 saved_offset = asn1->offset;
1954 ret = asn1_id_decode1(asn1, &tag);
1955 asn1->offset = saved_offset;
1960 dissect_tcap_dlg_req(asn1, subtree);
1963 dissect_tcap_dlg_rsp(asn1, subtree);
1966 dissect_tcap_dlg_abrt(asn1, subtree);
1972 /* decode end of sequence */
1976 dissect_tcap_eoc(asn1, subtree);
1979 if (!ext_tag_def_len)
1981 dissect_tcap_eoc(asn1, subtree);
1984 if (!portion_def_len)
1986 dissect_tcap_eoc(asn1, subtree);
1989 proto_item_set_len(dlg_item, asn1->offset - dlg_start);
1994 /* dissect reason */
1996 dissect_tcap_abort_reason(ASN1_SCK *asn1, proto_tree *tcap_tree)
1998 guint saved_offset = 0;
2000 proto_tree *subtree;
2006 #define TC_PABRT_REASON_TAG 0x4a
2007 tag = TC_PABRT_REASON_TAG;
2008 if (check_tcap_tag(asn1, tag))
2010 saved_offset = asn1->offset;
2012 proto_tree_add_none_format(tcap_tree, hf_tcap_none, asn1->tvb,
2013 saved_offset, -1, "PAbort Cause");
2015 subtree = proto_item_add_subtree(item, ett_reason);
2018 dissect_tcap_tag(asn1, subtree, &tag, "PAbort Cause Tag");
2019 dissect_tcap_len(asn1, subtree, &def_len, &len);
2021 proto_item_set_len(item, (asn1->offset - saved_offset) + len);
2023 saved_offset = asn1->offset;
2024 asn1_int32_value_decode(asn1, len, &value);
2028 case 0x00: str = "Unrecognized Message Type"; break;
2029 case 0x01: str = "Unrecognized Transaction ID"; break;
2030 case 0x02: str = "Badly Formatted Transaction Portion"; break;
2031 case 0x03: str = "Incorrect Transaction Portion"; break;
2032 case 0x04: str = "Resource Limitation"; break;
2038 proto_tree_add_none_format(subtree, hf_tcap_none, asn1->tvb,
2039 saved_offset, asn1->offset - saved_offset, "Cause Value %s (%d)",
2046 /* dissect each type of message */
2049 dissect_tcap_unidirectional(ASN1_SCK *asn1, proto_tree *tcap_tree)
2052 dissect_tcap_dialog_portion(asn1, tcap_tree, NULL);
2054 dissect_tcap_components(asn1, tcap_tree);
2058 dissect_tcap_begin(ASN1_SCK *asn1, proto_tree *tcap_tree, proto_item *ti)
2061 dissect_tcap_tid(asn1, tcap_tree, ti, ST_TID_SOURCE);
2063 dissect_tcap_dialog_portion(asn1, tcap_tree, NULL);
2065 dissect_tcap_components(asn1, tcap_tree);
2069 dissect_tcap_continue(ASN1_SCK *asn1, proto_tree *tcap_tree, proto_item *ti)
2072 dissect_tcap_tid(asn1, tcap_tree, ti, ST_TID_SOURCE);
2074 dissect_tcap_tid(asn1, tcap_tree, ti, ST_TID_DEST);
2076 dissect_tcap_dialog_portion(asn1, tcap_tree, NULL);
2078 dissect_tcap_components(asn1, tcap_tree);
2083 dissect_tcap_end(ASN1_SCK *asn1, proto_tree *tcap_tree, proto_item *ti)
2086 dissect_tcap_tid(asn1, tcap_tree, ti, ST_TID_DEST);
2088 dissect_tcap_dialog_portion(asn1, tcap_tree, NULL);
2090 dissect_tcap_components(asn1, tcap_tree);
2094 dissect_tcap_abort(ASN1_SCK *asn1, proto_tree *tree, proto_item *ti)
2097 dissect_tcap_tid(asn1, tree, ti, ST_TID_DEST);
2099 dissect_tcap_abort_reason(asn1, tree);
2101 dissect_tcap_dialog_portion(asn1, tree, NULL);
2106 dissect_tcap_message(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tcap_tree)
2112 guint saved_offset = 0;
2116 asn1_open(&asn1, tvb, offset);
2118 asn1_id_decode1(&asn1, &msg_type_tag);
2120 str = match_strval(msg_type_tag, msg_type_strings);
2124 proto_tree_add_none_format(tcap_tree, hf_tcap_none, asn1.tvb, offset, -1, "Unknown message type, ignoring");
2128 if (check_col(pinfo->cinfo, COL_INFO))
2130 col_set_str(pinfo->cinfo, COL_INFO, str);
2131 col_append_str(pinfo->cinfo, COL_INFO, " ");
2134 proto_tree_add_uint_hidden(tcap_tree, hf_tcap_ssn, asn1.tvb, offset,
2135 0, pinfo->match_port); /* len -1 is unacceptable */
2137 ti = proto_tree_add_uint(tcap_tree, hf_tcap_message_type, asn1.tvb, offset, asn1.offset - saved_offset,
2140 dissect_tcap_len(&asn1, tcap_tree, &g_tcap_ends_def_len, &len);
2142 switch(msg_type_tag)
2144 case ST_MSG_TYP_UNI:
2145 dissect_tcap_unidirectional(&asn1, tcap_tree);
2147 case ST_MSG_TYP_BGN:
2148 dissect_tcap_begin(&asn1, tcap_tree, ti);
2150 case ST_MSG_TYP_CNT:
2151 dissect_tcap_continue(&asn1, tcap_tree, ti);
2153 case ST_MSG_TYP_END:
2154 dissect_tcap_end(&asn1, tcap_tree, ti);
2156 case ST_MSG_TYP_PABT:
2157 dissect_tcap_abort(&asn1, tcap_tree, ti);
2160 proto_tree_add_none_format(tcap_tree, hf_tcap_none, asn1.tvb, offset, -1,
2161 "Message type not handled, ignoring");
2165 if (!g_tcap_ends_def_len)
2167 dissect_tcap_eoc(&asn1, tcap_tree);
2170 asn1_close(&asn1, &saved_offset);
2174 dissect_ansi_tcap_components(ASN1_SCK *asn1, proto_tree *tcap_tree)
2176 proto_tree *subtree;
2177 guint saved_offset = 0;
2181 proto_item *cmp_item;
2182 guint cmp_start = asn1->offset;
2185 saved_offset = asn1->offset;
2186 ret = asn1_id_decode1(asn1, &tag);
2188 if (ST_ANSI_CMP_TAG != tag)
2190 asn1->offset = saved_offset;
2194 cmp_item = proto_tree_add_none_format(tcap_tree, hf_tcap_none, asn1->tvb, saved_offset, -1, "Components Portion");
2196 subtree = proto_item_add_subtree(cmp_item, ett_cmp_portion);
2198 proto_tree_add_uint_format(subtree, hf_tcap_tag, asn1->tvb, saved_offset, asn1->offset - saved_offset, tag,
2199 "Component Sequence Identifier");
2201 dissect_tcap_len(asn1, tcap_tree, &def_len, &len);
2203 /* call next dissector */
2205 dissect_ansi_tcap_next_tvb(asn1, len, subtree);
2207 proto_item_set_len(cmp_item, asn1->offset - cmp_start);
2213 dissect_ansi_tcap_unidirectional(ASN1_SCK *asn1, proto_tree *tcap_tree)
2215 guint saved_offset = 0;
2219 proto_item *trans_item;
2220 guint trans_start = asn1->offset;
2223 saved_offset = asn1->offset;
2224 ret = asn1_id_decode1(asn1, &tag);
2226 if (ST_ANSI_TID_TAG != tag)
2228 asn1->offset = saved_offset;
2232 trans_item = proto_tree_add_none_format(tcap_tree, hf_tcap_none, asn1->tvb, saved_offset, -1, "Transaction Portion");
2234 dissect_tcap_len(asn1, tcap_tree, &def_len, &len);
2241 proto_item_set_len(trans_item, asn1->offset - trans_start);
2243 dissect_ansi_tcap_components(asn1, tcap_tree);
2249 dissect_ansi_tcap_qwp_qwop(ASN1_SCK *asn1, proto_tree *tcap_tree, proto_item *ti)
2251 proto_tree *subtree;
2252 guint saved_offset = 0;
2256 proto_item *trans_item;
2257 guint trans_start = asn1->offset;
2262 saved_offset = asn1->offset;
2263 ret = asn1_id_decode1(asn1, &tag);
2265 if (ST_ANSI_TID_TAG != tag)
2267 asn1->offset = saved_offset;
2271 trans_item = proto_tree_add_none_format(tcap_tree, hf_tcap_none, asn1->tvb, saved_offset, -1, "Transaction Portion");
2272 subtree = proto_item_add_subtree(trans_item, ett_dlg_portion);
2274 proto_tree_add_uint_format(subtree, hf_tcap_tag, asn1->tvb, saved_offset, asn1->offset - saved_offset, tag,
2275 "Originating Transaction ID Identifier");
2277 dissect_tcap_len(asn1, tcap_tree, &def_len, &len);
2284 saved_offset = asn1->offset;
2285 ret = asn1_string_value_decode(asn1, len, &poctets);
2287 memcpy(&val, poctets, len);
2288 ti = proto_tree_add_uint(subtree, hf_tcap_id, asn1->tvb, saved_offset, asn1->offset - saved_offset, val);
2291 if (check_col(g_pinfo->cinfo, COL_INFO))
2292 col_append_fstr(g_pinfo->cinfo, COL_INFO, "otid(%x) ", val);
2294 proto_item_set_len(trans_item, asn1->offset - trans_start);
2296 dissect_ansi_tcap_components(asn1, tcap_tree);
2302 dissect_ansi_tcap_abort(ASN1_SCK *asn1, proto_tree *tcap_tree, proto_item *ti)
2304 proto_tree *subtree;
2305 guint saved_offset = 0;
2309 proto_item *trans_item;
2310 guint trans_start = asn1->offset;
2317 saved_offset = asn1->offset;
2318 ret = asn1_id_decode1(asn1, &tag);
2320 if (ST_ANSI_TID_TAG != tag)
2322 asn1->offset = saved_offset;
2327 proto_tree_add_none_format(tcap_tree, hf_tcap_none, asn1->tvb,
2328 saved_offset, -1, "Transaction Portion");
2330 subtree = proto_item_add_subtree(trans_item, ett_dlg_portion);
2332 proto_tree_add_uint_format(subtree, hf_tcap_tag, asn1->tvb,
2333 saved_offset, asn1->offset - saved_offset, tag,
2334 "Responding Transaction ID Identifier");
2336 dissect_tcap_len(asn1, subtree, &def_len, &len);
2343 saved_offset = asn1->offset;
2344 ret = asn1_string_value_decode(asn1, len, &poctets);
2347 memcpy(&val, poctets, len);
2348 ti = proto_tree_add_uint(subtree, hf_tcap_id, asn1->tvb, saved_offset, asn1->offset - saved_offset, val);
2351 if (check_col(g_pinfo->cinfo, COL_INFO))
2352 col_append_fstr(g_pinfo->cinfo, COL_INFO, "rtid(%x) ", val);
2354 proto_item_set_len(trans_item, asn1->offset - trans_start);
2356 if (tvb_length_remaining(asn1->tvb, asn1->offset) <= 0)
2358 proto_tree_add_text(tcap_tree, asn1->tvb, asn1->offset, -1,
2359 "!!! Missing Component Portion !!!");
2364 saved_offset = asn1->offset;
2365 ret = asn1_id_decode1(asn1, &tag);
2367 #define ANSI_TC_PABRT_CAUSE_TAG 0xd7
2368 if (tag == ANSI_TC_PABRT_CAUSE_TAG)
2371 proto_tree_add_none_format(tcap_tree, hf_tcap_none, asn1->tvb,
2372 saved_offset, -1, "P-Abort Portion");
2374 subtree = proto_item_add_subtree(trans_item, ett_dlg_abort);
2376 dissect_tcap_len(asn1, subtree, &def_len, &len);
2378 proto_item_set_len(trans_item, (asn1->offset - saved_offset) + len);
2380 saved_offset = asn1->offset;
2381 asn1_int32_value_decode(asn1, len, &value);
2385 case 1: str = "Unrecognized Package Type"; break;
2386 case 2: str = "Incorrect Transaction Portion"; break;
2387 case 3: str = "Badly Structured Transaction Portion"; break;
2388 case 4: str = "Unrecognized Transaction ID"; break;
2389 case 5: str = "Permission to Release"; break;
2390 case 6: str = "Resource Unavailable"; break;
2396 proto_tree_add_text(subtree, asn1->tvb,
2397 saved_offset, asn1->offset - saved_offset, "P-Abort Cause Value %s (%d)",
2400 #define ANSI_TC_UABRT_INFO_TAG 0xd8
2401 else if (tag == ANSI_TC_UABRT_INFO_TAG)
2404 proto_tree_add_none_format(tcap_tree, hf_tcap_none, asn1->tvb,
2405 saved_offset, -1, "U-Abort Portion");
2407 subtree = proto_item_add_subtree(trans_item, ett_dlg_abort);
2409 dissect_tcap_len(asn1, subtree, &def_len, &len);
2412 dissect_tcap_integer(asn1, subtree, len, "User Abort Information:");
2420 dissect_ansi_tcap_rsp(ASN1_SCK *asn1, proto_tree *tcap_tree, proto_item *ti)
2422 proto_tree *subtree;
2423 guint saved_offset = 0;
2427 proto_item *trans_item;
2428 guint trans_start = asn1->offset;
2433 saved_offset = asn1->offset;
2434 ret = asn1_id_decode1(asn1, &tag);
2436 if (ST_ANSI_TID_TAG != tag)
2438 asn1->offset = saved_offset;
2442 trans_item = proto_tree_add_none_format(tcap_tree, hf_tcap_none, asn1->tvb, saved_offset, -1, "Transaction Portion");
2443 subtree = proto_item_add_subtree(trans_item, ett_dlg_portion);
2445 proto_tree_add_uint_format(subtree, hf_tcap_tag, asn1->tvb, saved_offset, asn1->offset - saved_offset, tag,
2446 "Responding Transaction ID Identifier");
2448 dissect_tcap_len(asn1, tcap_tree, &def_len, &len);
2455 saved_offset = asn1->offset;
2456 ret = asn1_string_value_decode(asn1, len, &poctets);
2458 memcpy(&val, poctets, len);
2459 ti = proto_tree_add_uint(subtree, hf_tcap_id, asn1->tvb, saved_offset, asn1->offset - saved_offset, val);
2462 if (check_col(g_pinfo->cinfo, COL_INFO))
2463 col_append_fstr(g_pinfo->cinfo, COL_INFO, "rtid(%x) ", val);
2465 proto_item_set_len(trans_item, asn1->offset - trans_start);
2467 dissect_ansi_tcap_components(asn1, tcap_tree);
2473 dissect_ansi_tcap_cwp_cwop(ASN1_SCK *asn1, proto_tree *tcap_tree, proto_item *ti)
2475 proto_tree *subtree;
2476 guint saved_offset = 0;
2480 proto_item *trans_item;
2481 guint trans_start = asn1->offset;
2486 saved_offset = asn1->offset;
2487 ret = asn1_id_decode1(asn1, &tag);
2489 if (ST_ANSI_TID_TAG != tag)
2491 asn1->offset = saved_offset;
2495 trans_item = proto_tree_add_none_format(tcap_tree, hf_tcap_none, asn1->tvb, saved_offset, -1, "Transaction Portion");
2496 subtree = proto_item_add_subtree(trans_item, ett_dlg_portion);
2498 proto_tree_add_uint_format(subtree, hf_tcap_tag, asn1->tvb, saved_offset, asn1->offset - saved_offset, tag,
2499 "Transaction ID Identifier");
2501 dissect_tcap_len(asn1, tcap_tree, &def_len, &len);
2508 saved_offset = asn1->offset;
2509 ret = asn1_string_value_decode(asn1, 4, &poctets);
2511 memcpy(&val, poctets, 4);
2512 ti = proto_tree_add_uint(subtree, hf_tcap_id, asn1->tvb, saved_offset, asn1->offset - saved_offset, val);
2515 if (check_col(g_pinfo->cinfo, COL_INFO))
2516 col_append_fstr(g_pinfo->cinfo, COL_INFO, "otid(%x) ", val);
2518 saved_offset = asn1->offset;
2519 ret = asn1_string_value_decode(asn1, 4, &poctets);
2521 memcpy(&val, poctets, 4);
2522 ti = proto_tree_add_uint(subtree, hf_tcap_id, asn1->tvb, saved_offset, asn1->offset - saved_offset, val);
2525 if (check_col(g_pinfo->cinfo, COL_INFO))
2526 col_append_fstr(g_pinfo->cinfo, COL_INFO, "rtid(%x) ", val);
2528 proto_item_set_len(trans_item, asn1->offset - trans_start);
2530 dissect_ansi_tcap_components(asn1, tcap_tree);
2536 dissect_ansi_tcap_message(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tcap_tree)
2542 guint saved_offset = 0;
2547 asn1_open(&asn1, tvb, offset);
2549 asn1_id_decode1(&asn1, &msg_type_tag);
2551 str = match_strval(msg_type_tag, ansi_msg_type_strings);
2555 proto_tree_add_none_format(tcap_tree, hf_tcap_none, asn1.tvb, offset, -1, "Unknown message type, ignoring");
2559 if (check_col(pinfo->cinfo, COL_INFO))
2561 col_set_str(pinfo->cinfo, COL_INFO, str);
2562 col_append_str(pinfo->cinfo, COL_INFO, " ");
2565 proto_tree_add_uint_hidden(tcap_tree, hf_tcap_ssn, asn1.tvb, offset,
2566 0, pinfo->match_port); /* len -1 is unacceptable */
2568 ti = proto_tree_add_uint(tcap_tree, hf_ansi_tcap_message_type, asn1.tvb, offset, asn1.offset - saved_offset,
2571 dissect_tcap_len(&asn1, tcap_tree, &def_len, &len);
2573 switch(msg_type_tag)
2575 case ANSI_ST_MSG_TYP_UNI:
2576 dissect_ansi_tcap_unidirectional(&asn1, tcap_tree);
2578 case ANSI_ST_MSG_TYP_QWP:
2579 dissect_ansi_tcap_qwp_qwop(&asn1, tcap_tree, ti);
2581 case ANSI_ST_MSG_TYP_QWOP:
2582 dissect_ansi_tcap_qwp_qwop(&asn1, tcap_tree, ti);
2584 case ANSI_ST_MSG_TYP_RSP:
2585 dissect_ansi_tcap_rsp(&asn1, tcap_tree, ti);
2587 case ANSI_ST_MSG_TYP_CWP:
2588 dissect_ansi_tcap_cwp_cwop(&asn1, tcap_tree, ti);
2590 case ANSI_ST_MSG_TYP_CWOP:
2591 dissect_ansi_tcap_cwp_cwop(&asn1, tcap_tree, ti);
2593 case ANSI_ST_MSG_TYP_ABT:
2594 dissect_ansi_tcap_abort(&asn1, tcap_tree, ti);
2597 proto_tree_add_none_format(tcap_tree, hf_tcap_none, asn1.tvb, offset, -1,
2598 "Message type not handled, ignoring");
2602 asn1_close(&asn1, &saved_offset);
2605 /* Code to actually dissect the packets */
2607 dissect_tcap(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
2610 proto_tree *tcap_tree;
2614 if (check_col(pinfo->cinfo, COL_PROTOCOL))
2615 col_set_str(pinfo->cinfo, COL_PROTOCOL, "TCAP");
2617 /* In the interest of speed, if "tree" is NULL, don't do any
2618 * work not necessary to generate protocol tree items.
2622 ti = proto_tree_add_item(tree, proto_tcap, tvb, 0, -1, FALSE);
2623 tcap_tree = proto_item_add_subtree(ti, ett_tcap);
2626 if (tcap_standard == ITU_TCAP_STANDARD)
2628 dissect_tcap_message(tvb, pinfo, tcap_tree);
2632 dissect_ansi_tcap_message(tvb, pinfo, tcap_tree);
2638 /* Register the protocol with Ethereal */
2640 /* this format is require because a script is used to build the C function
2641 that calls all the protocol registration.
2644 proto_register_tcap(void)
2647 /* Setup list of header fields See Section 1.6.1 for details*/
2648 static hf_register_info hf[] = {
2649 /*{ &hf_tcap_FIELDABBREV,
2650 { "FIELDNAME", "PROTOABBREV.FIELDABBREV",
2651 FIELDTYPE, FIELDBASE, FIELDCONVERT, BITMASK,
2655 { "Tag", "tcap.msgtype",
2656 FT_UINT8, BASE_HEX, NULL, 0,
2660 { "Length", "tcap.len",
2661 FT_UINT8, BASE_HEX, NULL, 0,
2665 { "Value", "tcap.id",
2666 FT_UINT8, BASE_HEX, NULL, 0,
2669 { &hf_tcap_message_type,
2670 { "Message Type", "tcap.msgtype",
2671 FT_UINT8, BASE_HEX, VALS(msg_type_strings), 0,
2674 { &hf_ansi_tcap_message_type,
2675 { "Message Type", "tcap.msgtype",
2676 FT_UINT8, BASE_HEX, VALS(ansi_msg_type_strings), 0,
2680 { "Sub tree", "tcap.none",
2685 { "Transaction Id", "tcap.tid",
2686 FT_UINT32, BASE_DEC, VALS(tid_strings), 0,
2690 { "Called or Calling SubSystem Number", "tcap.ssn",
2691 FT_UINT8, BASE_DEC, 0x0, 0x0,
2694 { &hf_tcap_dlg_type,
2695 { "Dialogue Type", "tcap.dlgtype",
2696 FT_UINT8, BASE_HEX, VALS(dlg_type_strings), 0,
2699 { &hf_tcap_app_con_name,
2700 { "Application Context Name", "tcap.dlg.appconname",
2701 FT_BYTES, BASE_HEX, 0, 0,
2705 { "Binary Data", "tcap.data",
2706 FT_BYTES, BASE_HEX, 0, 0,
2710 { "Integer Data", "tcap.data",
2711 FT_INT32, BASE_DEC, 0, 0,
2716 /* Setup protocol subtree array */
2717 static gint *ett[] = {
2734 static enum_val_t tcap_options[] = {
2735 { "ITU", ITU_TCAP_STANDARD },
2736 { "ANSI", ANSI_TCAP_STANDARD },
2740 module_t *tcap_module;
2742 /* Register the protocol name and description */
2743 proto_tcap = proto_register_protocol("Transaction Capabilities Application Part",
2746 /* Required function calls to register the header fields and subtrees used */
2747 proto_register_field_array(proto_tcap, hf, array_length(hf));
2748 proto_register_subtree_array(ett, array_length(ett));
2750 tcap_module = prefs_register_protocol(proto_tcap, NULL);
2752 prefs_register_enum_preference(tcap_module, "standard", "TCAP standard",
2753 "The SS7 standard used in TCAP packets",
2754 (gint *)&tcap_standard, tcap_options, FALSE);
2756 prefs_register_bool_preference(tcap_module, "lock_info_col", "Lock Info column",
2757 "Always show TCAP in Info column",
2760 /* we will fake a ssn subfield which has the same value obtained from sccp */
2761 tcap_itu_ssn_dissector_table = register_dissector_table("tcap.itu_ssn", "ITU TCAP SSN", FT_UINT8, BASE_DEC);
2762 tcap_ansi_ssn_dissector_table = register_dissector_table("tcap.ansi_ssn", "ANSI TCAP SSN", FT_UINT8, BASE_DEC);
2766 /* If this dissector uses sub-dissector registration add a registration routine.
2767 This format is required because a script is used to find these routines and
2768 create the code that calls these routines.
2771 proto_reg_handoff_tcap(void)
2773 dissector_handle_t tcap_handle;
2775 tcap_handle = create_dissector_handle(dissect_tcap,
2778 dissector_add("sccp.ssn", 5, tcap_handle); /* MAP*/
2779 dissector_add("sccp.ssn", 6, tcap_handle); /* HLR*/
2780 dissector_add("sccp.ssn", 7, tcap_handle); /* VLR */
2781 dissector_add("sccp.ssn", 8, tcap_handle); /* MSC */
2782 dissector_add("sccp.ssn", 9, tcap_handle); /* EIR */
2783 dissector_add("sccp.ssn", 10, tcap_handle); /* EIR */
2784 dissector_add("sccp.ssn", 11, tcap_handle); /* SMS/MC */
2785 dissector_add("sccp.ssn", 12, tcap_handle); /* IS41 OTAF */
2787 dissector_add("sua.ssn", 5, tcap_handle); /* MAP*/
2788 dissector_add("sua.ssn", 6, tcap_handle); /* HLR*/
2789 dissector_add("sua.ssn", 7, tcap_handle); /* VLR */
2790 dissector_add("sua.ssn", 8, tcap_handle); /* MSC */
2791 dissector_add("sua.ssn", 9, tcap_handle); /* EIR */
2792 dissector_add("sua.ssn", 10, tcap_handle); /* EIR */
2793 dissector_add("sua.ssn", 11, tcap_handle); /* SMS/MC */
2794 dissector_add("sua.ssn", 12, tcap_handle); /* IS41 OTAF */
2796 data_handle = find_dissector("data");