summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeff Morriss <jeff.morriss@ulticom.com>2007-07-27 19:24:40 +0000
committerJeff Morriss <jeff.morriss@ulticom.com>2007-07-27 19:24:40 +0000
commit29facf8ff9be835fc97df4a96a3d649967dc00b3 (patch)
tree6f44aac0fb94a35b64a39b0819dab799f24a44f2
parentf104bfa2adba5535ff818a0afd0b9acecf0764bb (diff)
downloadwireshark-29facf8ff9be835fc97df4a96a3d649967dc00b3.tar.gz
From Florent Drouin:
- add support of session management for tcap ANSI. (In fact, this support already exist for ANSI MAP subdissector, but as our simulators can reuse the tcap transaction Id, the decoding of the response may be wrong) - move the code related to asn1 in tcap.cnf, and update tcap.cnf - move the code related to the session management in tcap-persistentdata - add a compilation option to free the entry in the hashtable for a closed transaction. This is used only for tshark statistics generation, with huge file. - cleanup and add some comments Add Id tags to epan/tcap-persistentdata.{c,h} svn path=/trunk/; revision=22415
-rw-r--r--AUTHORS6
-rw-r--r--asn1/tcap/packet-tcap-template.c166
-rw-r--r--asn1/tcap/packet-tcap-template.h7
-rw-r--r--asn1/tcap/tcap.cnf133
-rw-r--r--epan/dissectors/packet-tcap.c351
-rw-r--r--epan/dissectors/packet-tcap.h11
-rw-r--r--epan/tcap-persistentdata.c866
-rw-r--r--epan/tcap-persistentdata.h21
8 files changed, 1199 insertions, 362 deletions
diff --git a/AUTHORS b/AUTHORS
index 1c2654baab..530014f70f 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -2651,10 +2651,14 @@ Ted Percival <ted[AT]midg3t.net> {
Support for PA-S4U2Self Kerberos packet type
}
-Marc Petit-Huguenin <marc [AT] petit-huguenin.org> {
+Marc Petit-Huguenin <marc [AT] petit-huguenin.org> {
Update STUN2 to draft-ietf-behave-rfc3489bis-07
}
+Florent Drouin <florent.drouin [AT] alcatel-lucent.fr> {
+ TCAP statistics
+}
+
and by:
Pavel Roskin <proski [AT] gnu.org>
diff --git a/asn1/tcap/packet-tcap-template.c b/asn1/tcap/packet-tcap-template.c
index 14d82df9e0..6dd48db063 100644
--- a/asn1/tcap/packet-tcap-template.c
+++ b/asn1/tcap/packet-tcap-template.c
@@ -4,6 +4,7 @@
* Built from the gsm-map dissector Copyright 2004 - 2005, Anders Broman <anders.broman@ericsson.com>
*
* $Id$
+ *
* Wireshark - Network traffic analyzer
* By Gerald Combs <gerald@wireshark.org>
* Copyright 1998 Gerald Combs
@@ -94,7 +95,6 @@ static const char * cur_oid;
static const char * tcapext_oid;
static proto_tree * tcap_top_tree=NULL;
static proto_tree * tcap_stat_tree=NULL;
-static proto_item * tcap_stat_item=NULL;
static dissector_handle_t data_handle;
@@ -104,6 +104,7 @@ static void raz_tcap_private(struct tcap_private_t * p_tcap_private);
static int dissect_tcap_param(asn1_ctx_t *actx, proto_tree *tree, tvbuff_t *tvb, int offset);
static int dissect_tcap_UserInformation(gboolean implicit_tag _U_, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_, proto_tree *tree, int hf_index _U_);
static int dissect_tcap_TheComponent(gboolean implicit_tag _U_, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_, proto_tree *tree, int hf_index _U_);
+static int dissect_tcap_TheComponentPDU(gboolean implicit_tag _U_, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_, proto_tree *tree, int hf_index _U_);
static int dissect_tcap_TheExternUserInfo(gboolean implicit_tag _U_, tvbuff_t *tvb, int offset,asn1_ctx_t *actx _U_, proto_tree *tree, int hf_index _U_);
static GHashTable* ansi_sub_dissectors = NULL;
@@ -158,15 +159,15 @@ dissect_tcap(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree)
{
proto_item *item=NULL;
proto_tree *tree=NULL;
- proto_item *stat_item=NULL;
- proto_tree *stat_tree=NULL;
- gint offset = 0;
+
struct tcaphash_context_t * p_tcap_context;
dissector_handle_t subdissector_handle;
asn1_ctx_t asn1_ctx;
asn1_ctx_init(&asn1_ctx, ASN1_ENC_BER, TRUE, pinfo);
tcap_top_tree = parent_tree;
+ tcap_stat_tree = NULL;
+
if (check_col(pinfo->cinfo, COL_PROTOCOL))
{
col_set_str(pinfo->cinfo, COL_PROTOCOL, "TCAP");
@@ -176,7 +177,6 @@ dissect_tcap(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree)
if(parent_tree){
item = proto_tree_add_item(parent_tree, proto_tcap, tvb, 0, -1, FALSE);
tree = proto_item_add_subtree(item, ett_tcap);
- tcap_stat_item=item;
tcap_stat_tree=tree;
}
cur_oid = NULL;
@@ -190,29 +190,25 @@ dissect_tcap(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree)
dissect_tcap_TCMessage(FALSE, tvb, 0, &asn1_ctx, tree, -1);
if (gtcap_HandleSRT && !tcap_subdissector_used ) {
- if (gtcap_DisplaySRT && tree) {
- stat_item = proto_tree_add_text(tree, tvb, 0, 0, "Stat");
- PROTO_ITEM_SET_GENERATED(stat_item);
- stat_tree = proto_item_add_subtree(stat_item, ett_tcap_stat);
- }
- p_tcap_context=tcapsrt_call_matching(tvb, pinfo, stat_tree, gp_tcapsrt_info);
- tcap_private.context=p_tcap_context;
+ p_tcap_context=tcapsrt_call_matching(tvb, pinfo, tcap_stat_tree, gp_tcapsrt_info);
+ tcap_private.context=p_tcap_context;
/* If the current message is TCAP only,
- * save the Application contexte name for the next messages
+ * save the Application Context Name for the next messages
*/
if ( p_tcap_context && cur_oid && !p_tcap_context->oid_present ) {
/* Save the application context and the sub dissector */
ber_oid_dissector_table = find_dissector_table("ber.oid");
strncpy(p_tcap_context->oid,cur_oid, LENGTH_OID);
+ p_tcap_context->oid_present=TRUE;
if ( (subdissector_handle = dissector_get_string_handle(ber_oid_dissector_table, cur_oid)) ) {
p_tcap_context->subdissector_handle=subdissector_handle;
- p_tcap_context->oid_present=TRUE;
+ p_tcap_context->subdissector_present=TRUE;
}
}
if (gtcap_HandleSRT && p_tcap_context && p_tcap_context->callback) {
/* Callback fonction for the upper layer */
- (p_tcap_context->callback)(tvb, pinfo, stat_tree, p_tcap_context);
+ (p_tcap_context->callback)(tvb, pinfo, tcap_stat_tree, p_tcap_context);
}
}
}
@@ -286,10 +282,10 @@ proto_register_tcap(void)
"Duration of the TCAP session", HFILL }
},
{ &hf_tcapsrt_Duplicate,
- { "Request Duplicate",
+ { "Session Duplicate",
"tcap.srt.duplicate",
- FT_UINT32, BASE_DEC, NULL, 0x0,
- "", HFILL }
+ FT_FRAMENUM, BASE_NONE, NULL, 0x0,
+ "SRT Duplicated with Session", HFILL }
},
#include "packet-tcap-hfarr.c"
};
@@ -475,53 +471,30 @@ static void raz_tcap_private(struct tcap_private_t * p_tcap_private)
memset(p_tcap_private,0,sizeof(struct tcap_private_t) );
}
-
+/*
+ * Call ITU Subdissector to decode the Tcap Component
+ */
static int
dissect_tcap_TheComponent(gboolean implicit_tag _U_, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_, proto_tree *tree, int hf_index _U_)
{
- tvbuff_t * next_tvb;
- dissector_handle_t subdissector_handle;
+ dissector_handle_t subdissector_handle=NULL;
gboolean is_subdissector=FALSE;
struct tcaphash_context_t * p_tcap_context=NULL;
- gint8 class;
- gboolean pc;
- gint tag;
- guint32 len, s_offset;
- gint ind_field;
- proto_tree * stat_tree=NULL;
- proto_item * stat_item=NULL;
/*
* ok lets look at the oid and ssn and try and find a dissector, otherwise lets decode it.
*/
ber_oid_dissector_table = find_dissector_table("ber.oid");
- s_offset = offset;
- offset = get_ber_identifier(tvb, offset, &class, &pc, &tag);
- offset = get_ber_length(tree, tvb, offset, &len, &ind_field);
- /* we can believe the length now */
- next_tvb = tvb_new_subset(tvb, s_offset, len+(offset-s_offset), len+(offset-s_offset));
- if (!next_tvb)
- return offset+len;
-
- dissect_ber_old_choice(actx, tree, next_tvb, 0,
- Component_choice, hf_index, ett_tcap_Component,NULL);
-
/*
* Handle The TCAP Service Response Time
*/
if ( gtcap_HandleSRT ) {
if (!tcap_subdissector_used) {
- /* Create TCAP context and tree for display */
- if (gtcap_DisplaySRT && tree) {
- stat_item = proto_tree_add_text(tcap_stat_tree, tvb, offset, -1, "Stat");
- PROTO_ITEM_SET_GENERATED(stat_item);
- stat_tree = proto_item_add_subtree(stat_item, ett_tcap_stat);
- }
- p_tcap_context=tcapsrt_call_matching(tvb, actx->pinfo, stat_tree, gp_tcapsrt_info);
- tcap_subdissector_used=TRUE;
- gp_tcap_context=p_tcap_context;
- tcap_private.context=p_tcap_context;
+ p_tcap_context=tcapsrt_call_matching(tvb, actx->pinfo, tcap_stat_tree, gp_tcapsrt_info);
+ tcap_subdissector_used=TRUE;
+ gp_tcap_context=p_tcap_context;
+ tcap_private.context=p_tcap_context;
}else{
/* Take the last TCAP context */
p_tcap_context = gp_tcap_context;
@@ -534,21 +507,31 @@ dissect_tcap_TheComponent(gboolean implicit_tag _U_, tvbuff_t *tvb, int offset,
/* We have already an Application Context, check if we have
to fallback to a lower version */
if ( strncmp(p_tcap_context->oid,cur_oid, LENGTH_OID)!=0) {
- /* ACN, changed, Fallback to lower version
- * and update the subdissector (purely formal)
+ /* ACN, changed, Fallback to lower version
+ * and update the subdissector (purely formal)
*/
strncpy(p_tcap_context->oid,cur_oid, LENGTH_OID);
if ( (subdissector_handle = dissector_get_string_handle(ber_oid_dissector_table, cur_oid)) ) {
p_tcap_context->subdissector_handle=subdissector_handle;
+ p_tcap_context->subdissector_present=TRUE;
}
}
} else {
/* We do not have the OID in the TCAP context, so store it */
strncpy(p_tcap_context->oid,cur_oid, LENGTH_OID);
+ p_tcap_context->oid_present=TRUE;
+ /* Try to find a subdissector according to OID */
if ( (subdissector_handle
= dissector_get_string_handle(ber_oid_dissector_table, cur_oid)) ) {
p_tcap_context->subdissector_handle=subdissector_handle;
- p_tcap_context->oid_present=TRUE;
+ p_tcap_context->subdissector_present=TRUE;
+ } else {
+ /* Not found, so try to find a subdissector according to SSN */
+ if ( (subdissector_handle = get_itu_tcap_subdissector(actx->pinfo->match_port))) {
+ /* Found according to SSN */
+ p_tcap_context->subdissector_handle=subdissector_handle;
+ p_tcap_context->subdissector_present=TRUE;
+ }
}
} /* context OID */
} else {
@@ -562,7 +545,7 @@ dissect_tcap_TheComponent(gboolean implicit_tag _U_, tvbuff_t *tvb, int offset,
if ( p_tcap_context
- && p_tcap_context->oid_present) {
+ && p_tcap_context->subdissector_present) {
/* Take the subdissector from the context */
subdissector_handle=p_tcap_context->subdissector_handle;
is_subdissector=TRUE;
@@ -615,43 +598,78 @@ dissect_tcap_TheComponent(gboolean implicit_tag _U_, tvbuff_t *tvb, int offset,
/* Call the sub dissector if present, and not already called */
if (is_subdissector)
- call_dissector(subdissector_handle, next_tvb, actx->pinfo, tcap_top_tree);
+ call_dissector(subdissector_handle, tvb, actx->pinfo, tree);
- return offset+len;
+ return offset;
}
+/*
+ * Call ANSI Subdissector to decode the Tcap Component
+ */
+static int
+dissect_tcap_TheComponentPDU(gboolean implicit_tag _U_, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_, proto_tree *tree, int hf_index _U_)
+{
+ dissector_handle_t subdissector_handle;
+ gboolean is_subdissector=FALSE;
+ struct tcaphash_context_t * p_tcap_context=NULL;
+
+ gchar str[20];
+
+
+ /*
+ * Handle The TCAP Service Response Time
+ */
+ if ( gtcap_HandleSRT ) {
+ if (!tcap_subdissector_used) {
+ p_tcap_context=tcapsrt_call_matching(tvb, actx->pinfo, tcap_stat_tree, gp_tcapsrt_info);
+ tcap_subdissector_used=TRUE;
+ gp_tcap_context=p_tcap_context;
+ tcap_private.context=p_tcap_context;
+ } else {
+ /* Take the last TCAP context */
+ p_tcap_context = gp_tcap_context;
+ tcap_private.context=p_tcap_context;
+ }
+ }
+
+ if (p_tcap_context) {
+ /* tcap_private.TransactionID_str = bytes_to_str(&(p_tcap_context->session_id),4); */
+ g_snprintf(str, sizeof(str), "(%d)",p_tcap_context->session_id);
+ tcap_private.TransactionID_str = str;
+ }
+
+ if ( (subdissector_handle
+ = get_ansi_tcap_subdissector(actx->pinfo->match_port))) {
+ /* Found according to SSN */
+ is_subdissector=TRUE;
+ } else {
+ /* Nothing found, take the Data handler */
+ subdissector_handle = data_handle;
+ is_subdissector=TRUE;
+ } /* SSN */
+
+ /* Call the sub dissector if present, and not already called */
+ if (is_subdissector)
+ call_dissector(subdissector_handle, tvb, actx->pinfo, tree);
+
+ return offset;
+}
static int
dissect_tcap_TheExternUserInfo(gboolean implicit_tag _U_, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_, proto_tree *tree, int hf_index _U_)
{
- tvbuff_t *next_tvb;
- gint8 class;
- gboolean pc;
- gint tag;
- guint32 len, start_offset;
- gint ind_field;
-
/*
* ok lets look at the oid and ssn and try and find a dissector, otherwise lets decode it.
*/
ber_oid_dissector_table = find_dissector_table("ber.oid");
- start_offset = offset;
- offset = get_ber_identifier(tvb, offset, &class, &pc, &tag);
- offset = get_ber_length(tree, tvb, offset, &len, &ind_field);
-
- next_tvb = tvb_new_subset(tvb, start_offset, len +(offset - start_offset), len+(offset - start_offset));
- if (!next_tvb)
- return offset+len;
if (ber_oid_dissector_table && tcapext_oid){
- if(!dissector_try_string(ber_oid_dissector_table, tcapext_oid, next_tvb, actx->pinfo, tcap_top_tree))
+ if(!dissector_try_string(ber_oid_dissector_table, tcapext_oid, tvb, actx->pinfo, tree))
{
- dissect_tcap_param(actx,tree,next_tvb,0);
- offset+=len;
- return offset;
+ return dissect_tcap_param(actx,tree,tvb,0);
}
}
- return offset+len;
+ return offset;
}
diff --git a/asn1/tcap/packet-tcap-template.h b/asn1/tcap/packet-tcap-template.h
index 814e2c1a4e..cd362a607d 100644
--- a/asn1/tcap/packet-tcap-template.h
+++ b/asn1/tcap/packet-tcap-template.h
@@ -48,7 +48,7 @@
#define TCAP_INVOKE_ID_TAG 0x02
#define TCAP_LINKED_ID_TAG 0x80
-#define TCAP_EOC_LEN 2
+#define TCAP_EOC_LEN 2
#define TCAP_CONSTRUCTOR(TCtag) (TCtag & 0x20)
@@ -56,6 +56,8 @@
#define TC_CONT 2
#define TC_END 3
#define TC_ABORT 4
+#define TC_ANSI_ABORT 5
+#define TC_ANSI_ALL 6
struct tcap_private_t {
gboolean acv; /* Is the Application Context Version present */
@@ -68,8 +70,11 @@ struct tcap_private_t {
extern gint tcap_standard;
extern const value_string tcap_component_type_str[];
+void proto_reg_handoff_tcap(void);
+void proto_register_tcap(void);
extern dissector_handle_t get_itu_tcap_subdissector(guint32 ssn);
+dissector_handle_t get_ansi_tcap_subdissector(guint32 ssn);
extern void add_ansi_tcap_subdissector(guint32 ssn, dissector_handle_t dissector);
extern void add_itu_tcap_subdissector(guint32 ssn, dissector_handle_t dissector);
diff --git a/asn1/tcap/tcap.cnf b/asn1/tcap/tcap.cnf
index b43c3a5777..9a1663945a 100644
--- a/asn1/tcap/tcap.cnf
+++ b/asn1/tcap/tcap.cnf
@@ -23,6 +23,7 @@ UniDialoguePDU B "0.0.17.773.1.2.1" "uniDialogue-as-id"
#.FIELD_RENAME
+#----------------------------------------------------------------------------------------
#.FN_BODY DialogueOC
tvbuff_t *next_tvb;
gint8 class;
@@ -45,6 +46,7 @@ offset = dissect_ber_length(actx->pinfo, tree, tvb, offset, &len, &ind_field);
return offset+len;
+#----------------------------------------------------------------------------------------
#.FN_BODY ExternalPDU
gint8 class;
gboolean pc;
@@ -56,21 +58,20 @@ offset = dissect_ber_identifier(actx->pinfo, tree, tvb, offset, &class, &pc, &ta
offset = dissect_ber_length(actx->pinfo, tree, tvb, offset, &len, &ind_field);
%(DEFAULT_BODY)s
-#.FN_BODY Dialog1
-gint8 class;
- gboolean pc;
- gint tag;
- guint32 len;
- gint ind_field;
+#----------------------------------------------------------------------------------------
+#.FN_BODY Dialog1 VAL_PTR = &parameter_tvb
+ tvbuff_t *parameter_tvb;
+
+%(DEFAULT_BODY)s
-/* Calculate the correct length, Tags will be shown in DialoguePDU */
-offset = get_ber_identifier(tvb, offset, &class, &pc, &tag);
-offset = get_ber_length(tree, tvb, offset, &len, &ind_field);
+ if (!parameter_tvb)
+ return offset;
dissect_tcap_DialoguePDU(TRUE, tvb, 0, actx, tree, -1);
-return offset+len;
+#.END
+#----------------------------------------------------------------------------------------
#.FN_BODY Parameter
tvbuff_t *next_tvb;
gint8 class;
@@ -88,9 +89,10 @@ gint8 class;
if (!next_tvb)
return offset;
dissect_tcap_param(actx,tree,tvb,0);
- offset += len;
- return offset;
+ return offset+len;
+
+#----------------------------------------------------------------------------------------
#.FN_BODY User-information
tvbuff_t *next_tvb;
gint8 class;
@@ -107,11 +109,32 @@ if (!next_tvb)
return offset+len;
dissect_tcap_UserInformation(TRUE, next_tvb, 0, actx, tree, -1);
-
return offset+len;
+
+#----------------------------------------------------------------------------------------
#.FN_BODY Component
-dissect_tcap_TheComponent(implicit_tag, tvb, offset, actx, tree, hf_index);
+tvbuff_t *next_tvb;
+gint8 class;
+gboolean pc;
+gint tag;
+guint32 len, comp_offset;
+gint ind_field;
+
+comp_offset = dissect_ber_identifier(actx->pinfo, tree, tvb, offset, &class, &pc, &tag);
+comp_offset = dissect_ber_length(actx->pinfo, tree, tvb, comp_offset, &len, &ind_field);
+/* we can believe the length now */
+next_tvb = tvb_new_subset(tvb, offset, len+comp_offset-offset, len+comp_offset-offset);
+
+if (!next_tvb)
+ return comp_offset;
+
+%(DEFAULT_BODY)s
+ dissect_tcap_TheComponent(implicit_tag, next_tvb, 0, actx, tcap_top_tree, hf_index);
+
+/* return comp_offset+len; or return offset (will be automatically added */
+
+#----------------------------------------------------------------------------------------
#.FN_BODY Applicationcontext FN_VARIANT = _str VAL_PTR = &cur_oid
%(DEFAULT_BODY)s
tcap_private.oid= (void*) cur_oid;
@@ -119,14 +142,34 @@ dissect_tcap_TheComponent(implicit_tag, tvb, offset, actx, tree, hf_index);
# Do not overwrite the ApplicationContext with the UserInfoOID !
#
+#----------------------------------------------------------------------------------------
#.FN_BODY UserInfoOID FN_VARIANT = _str VAL_PTR = &tcapext_oid
%(DEFAULT_BODY)s
-# tcap_private.oid= (void*)tcapext_oid;
-# tcap_private.acv=TRUE;
+#----------------------------------------------------------------------------------------
#.FN_BODY ExternUserInfo
-dissect_tcap_TheExternUserInfo(implicit_tag, tvb, offset, actx, tree, hf_index);
+tvbuff_t *next_tvb;
+gint8 class;
+gboolean pc;
+gint tag;
+guint32 len, comp_offset;
+gint ind_field;
+
+comp_offset = dissect_ber_identifier(actx->pinfo, tree, tvb, offset, &class, &pc, &tag);
+comp_offset = dissect_ber_length(actx->pinfo, tree, tvb, comp_offset, &len, &ind_field);
+/* we can believe the length now */
+next_tvb = tvb_new_subset(tvb, offset, len+comp_offset-offset, len+comp_offset-offset);
+
+if (!next_tvb)
+ return comp_offset;
+
+%(DEFAULT_BODY)s
+
+dissect_tcap_TheExternUserInfo(implicit_tag, next_tvb, 0, actx, tcap_top_tree, hf_index);
+return comp_offset+len;
+
+#----------------------------------------------------------------------------------------
#.FN_BODY ANSIParameters
/* we are doing the ParamSet here so need to look at the tags*/
guint32 len;
@@ -137,24 +180,28 @@ else
offset = dissect_ber_octet_string(TRUE, actx, tree, tvb, 0, hf_index,
NULL);
-
+#----------------------------------------------------------------------------------------
#.FN_BODY ComponentPDU
-tvbuff_t *next_tvb;
-dissector_handle_t subdissector_handle;
-
-next_tvb = tvb_new_subset(tvb, offset, tvb_length_remaining(tvb, offset), tvb_length_remaining(tvb, offset));
+tvbuff_t *next_tvb;
+gint8 class;
+gboolean pc;
+gint tag;
+guint32 len, comp_offset;
+gint ind_field;
-if (! (subdissector_handle = get_ansi_tcap_subdissector(actx->pinfo->match_port))) {
- subdissector_handle = data_handle;
-}
+comp_offset = dissect_ber_identifier(actx->pinfo, tree, tvb, offset, &class, &pc, &tag);
+comp_offset = dissect_ber_length(actx->pinfo, tree, tvb, comp_offset, &len, &ind_field);
+/* we can believe the length now */
+next_tvb = tvb_new_subset(tvb, offset, len+comp_offset-offset, len+comp_offset-offset);
- tcap_subdissector_used=TRUE;
+if (!next_tvb)
+ return offset;
-call_dissector(subdissector_handle, next_tvb, actx->pinfo, tcap_top_tree);
+%(DEFAULT_BODY)s
-offset = dissect_ber_old_choice(actx, tree, tvb, offset,
- ComponentPDU_choice, hf_index, ett_tcap_ComponentPDU,NULL);
+dissect_tcap_TheComponentPDU(implicit_tag, next_tvb, 0, actx, tcap_top_tree, hf_index);
+#----------------------------------------------------------------------------------------
#.FN_BODY OrigTransactionID
tvbuff_t *parameter_tvb;
guint8 len, i;
@@ -193,6 +240,7 @@ if (parameter_tvb){
}
+#----------------------------------------------------------------------------------------
#.FN_BODY DestTransactionID
tvbuff_t *parameter_tvb;
guint8 len , i;
@@ -268,36 +316,61 @@ if (check_col(actx->pinfo->cinfo, COL_INFO))
#.FN_HDR AbortPDU
+gp_tcapsrt_info->ope=TC_ANSI_ABORT;
+
if (check_col(actx->pinfo->cinfo, COL_INFO))
col_add_str(actx->pinfo->cinfo, COL_INFO, "Abort ");
#.END
#.FN_HDR TCMessage/ansiqueryWithPerm
+gp_tcapsrt_info->ope=TC_ANSI_ALL;
if (check_col(actx->pinfo->cinfo, COL_INFO))
col_add_str(actx->pinfo->cinfo, COL_INFO, "QueryWithPerm ");
#.FN_HDR TCMessage/ansiqueryWithoutPerm
+gp_tcapsrt_info->ope=TC_ANSI_ALL;
if (check_col(actx->pinfo->cinfo, COL_INFO))
col_add_str(actx->pinfo->cinfo, COL_INFO, "QueryWithOutPerm ");
#.FN_HDR TCMessage/ansiresponse
+gp_tcapsrt_info->ope=TC_ANSI_ALL;
if (check_col(actx->pinfo->cinfo, COL_INFO))
col_add_str(actx->pinfo->cinfo, COL_INFO, "Response ");
#.FN_HDR TCMessage/ansiconversationWithPerm
+gp_tcapsrt_info->ope=TC_ANSI_ALL;
if (check_col(actx->pinfo->cinfo, COL_INFO))
col_add_str(actx->pinfo->cinfo, COL_INFO, "ConversationWithPerm ");
#.FN_HDR TCMessage/ansiconversationWithoutPerm
+gp_tcapsrt_info->ope=TC_ANSI_ALL;
if (check_col(actx->pinfo->cinfo, COL_INFO))
col_add_str(actx->pinfo->cinfo, COL_INFO, "ConversationWithoutPerm ");
#.END
+#----------------------------------------------------------------------------------------
#.FN_BODY TransactionID VAL_PTR = &next_tvb
tvbuff_t *next_tvb;
+guint8 len;
%(DEFAULT_BODY)s
-if(next_tvb)
+if(next_tvb) {
tcap_private.TransactionID_str = tvb_bytes_to_str(next_tvb, 0,tvb_length(next_tvb));
+ len = tvb_length_remaining(next_tvb, 0);
+ switch(len) {
+ case 1:
+ gp_tcapsrt_info->src_tid=tvb_get_guint8(next_tvb, 0);
+ break;
+ case 2:
+ gp_tcapsrt_info->src_tid=tvb_get_ntohs(next_tvb, 0);
+ break;
+ case 4:
+ gp_tcapsrt_info->src_tid=tvb_get_ntohl(next_tvb, 0);
+ break;
+ default:
+ gp_tcapsrt_info->src_tid=0;
+ break;
+ }
+}
#.END
diff --git a/epan/dissectors/packet-tcap.c b/epan/dissectors/packet-tcap.c
index f52570fafe..3ebb530ef0 100644
--- a/epan/dissectors/packet-tcap.c
+++ b/epan/dissectors/packet-tcap.c
@@ -1,6 +1,6 @@
/* Do not modify this file. */
/* It is created automatically by the ASN.1 to Wireshark dissector compiler */
-/* .\packet-tcap.c */
+/* ./packet-tcap.c */
/* ../../tools/asn2wrs.py -b -e -p tcap -c tcap.cnf -s packet-tcap-template tcap.asn */
/* Input file: packet-tcap-template.c */
@@ -12,6 +12,7 @@
* Built from the gsm-map dissector Copyright 2004 - 2005, Anders Broman <anders.broman@ericsson.com>
*
* $Id$
+ *
* Wireshark - Network traffic analyzer
* By Gerald Combs <gerald@wireshark.org>
* Copyright 1998 Gerald Combs
@@ -197,7 +198,7 @@ static int hf_tcap_T_protocol_versionre_version1 = -1;
static int hf_tcap_T_protocol_version3_version1 = -1;
/*--- End of included file: packet-tcap-hf.c ---*/
-#line 63 "packet-tcap-template.c"
+#line 64 "packet-tcap-template.c"
/* Initialize the subtree pointers */
static gint ett_tcap = -1;
@@ -268,7 +269,7 @@ static gint ett_tcap_OperationCode = -1;
static gint ett_tcap_ErrorCode = -1;
/*--- End of included file: packet-tcap-ett.c ---*/
-#line 79 "packet-tcap-template.c"
+#line 80 "packet-tcap-template.c"
#define MAX_SSN 254
static range_t *global_ssn_range;
@@ -287,7 +288,6 @@ static const char * cur_oid;
static const char * tcapext_oid;
static proto_tree * tcap_top_tree=NULL;
static proto_tree * tcap_stat_tree=NULL;
-static proto_item * tcap_stat_item=NULL;
static dissector_handle_t data_handle;
@@ -297,6 +297,7 @@ static void raz_tcap_private(struct tcap_private_t * p_tcap_private);
static int dissect_tcap_param(asn1_ctx_t *actx, proto_tree *tree, tvbuff_t *tvb, int offset);
static int dissect_tcap_UserInformation(gboolean implicit_tag _U_, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_, proto_tree *tree, int hf_index _U_);
static int dissect_tcap_TheComponent(gboolean implicit_tag _U_, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_, proto_tree *tree, int hf_index _U_);
+static int dissect_tcap_TheComponentPDU(gboolean implicit_tag _U_, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_, proto_tree *tree, int hf_index _U_);
static int dissect_tcap_TheExternUserInfo(gboolean implicit_tag _U_, tvbuff_t *tvb, int offset,asn1_ctx_t *actx _U_, proto_tree *tree, int hf_index _U_);
static GHashTable* ansi_sub_dissectors = NULL;
@@ -361,7 +362,7 @@ static int dissect_protocol_versionrq_impl(proto_tree *tree _U_, tvbuff_t *tvb _
static int
dissect_tcap_Applicationcontext(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
-#line 116 "tcap.cnf"
+#line 139 "tcap.cnf"
offset = dissect_ber_object_identifier_str(implicit_tag, actx, tree, tvb, offset, hf_index, &cur_oid);
tcap_private.oid= (void*) cur_oid;
@@ -379,7 +380,7 @@ static int dissect_application_context_name(proto_tree *tree _U_, tvbuff_t *tvb
static int
dissect_tcap_User_information(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
-#line 95 "tcap.cnf"
+#line 97 "tcap.cnf"
tvbuff_t *next_tvb;
gint8 class;
gboolean pc;
@@ -395,10 +396,10 @@ if (!next_tvb)
return offset+len;
dissect_tcap_UserInformation(TRUE, next_tvb, 0, actx, tree, -1);
-
return offset+len;
+
return offset;
}
static int dissect_user_information_impl(proto_tree *tree _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_) {
@@ -633,20 +634,17 @@ static int dissect_objectConfidentialityId_impl(proto_tree *tree _U_, tvbuff_t *
static int
dissect_tcap_Dialog1(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
-#line 60 "tcap.cnf"
-gint8 class;
- gboolean pc;
- gint tag;
- guint32 len;
- gint ind_field;
+#line 63 "tcap.cnf"
+ tvbuff_t *parameter_tvb;
-/* Calculate the correct length, Tags will be shown in DialoguePDU */
-offset = get_ber_identifier(tvb, offset, &class, &pc, &tag);
-offset = get_ber_length(tree, tvb, offset, &len, &ind_field);
+ offset = dissect_ber_octet_string(implicit_tag, actx, tree, tvb, offset, hf_index,
+ &parameter_tvb);
- dissect_tcap_DialoguePDU(TRUE, tvb, 0, actx, tree, -1);
-return offset+len;
+ if (!parameter_tvb)
+ return offset;
+
+ dissect_tcap_DialoguePDU(TRUE, tvb, 0, actx, tree, -1);
@@ -665,7 +663,7 @@ static const ber_old_sequence_t ExternalPDU_sequence[] = {
static int
dissect_tcap_ExternalPDU(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
-#line 49 "tcap.cnf"
+#line 51 "tcap.cnf"
gint8 class;
gboolean pc;
gint tag;
@@ -687,7 +685,7 @@ offset = dissect_ber_length(actx->pinfo, tree, tvb, offset, &len, &ind_field);
static int
dissect_tcap_UserInfoOID(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
-#line 123 "tcap.cnf"
+#line 147 "tcap.cnf"
offset = dissect_ber_object_identifier_str(implicit_tag, actx, tree, tvb, offset, hf_index, &tcapext_oid);
@@ -703,8 +701,29 @@ static int dissect_useroid(proto_tree *tree _U_, tvbuff_t *tvb _U_, int offset _
static int
dissect_tcap_ExternUserInfo(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
-#line 128 "tcap.cnf"
-dissect_tcap_TheExternUserInfo(implicit_tag, tvb, offset, actx, tree, hf_index);
+#line 151 "tcap.cnf"
+tvbuff_t *next_tvb;
+gint8 class;
+gboolean pc;
+gint tag;
+guint32 len, comp_offset;
+gint ind_field;
+
+comp_offset = dissect_ber_identifier(actx->pinfo, tree, tvb, offset, &class, &pc, &tag);
+comp_offset = dissect_ber_length(actx->pinfo, tree, tvb, comp_offset, &len, &ind_field);
+/* we can believe the length now */
+next_tvb = tvb_new_subset(tvb, offset, len+comp_offset-offset, len+comp_offset-offset);
+
+if (!next_tvb)
+ return comp_offset;
+
+ offset = dissect_ber_octet_string(implicit_tag, actx, tree, tvb, offset, hf_index,
+ NULL);
+
+
+dissect_tcap_TheExternUserInfo(implicit_tag, next_tvb, 0, actx, tcap_top_tree, hf_index);
+
+return comp_offset+len;
@@ -863,7 +882,7 @@ dissect_tcap_UniDialoguePDU(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int of
static int
dissect_tcap_DialogueOC(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
-#line 27 "tcap.cnf"
+#line 28 "tcap.cnf"
tvbuff_t *next_tvb;
gint8 class;
gboolean pc;
@@ -978,7 +997,7 @@ static int dissect_opCode(proto_tree *tree _U_, tvbuff_t *tvb _U_, int offset _U
static int
dissect_tcap_Parameter(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
-#line 75 "tcap.cnf"
+#line 76 "tcap.cnf"
tvbuff_t *next_tvb;
gint8 class;
gboolean pc;
@@ -995,8 +1014,8 @@ gint8 class;
if (!next_tvb)
return offset;
dissect_tcap_param(actx,tree,tvb,0);
- offset += len;
- return offset;
+
+ return offset+len;
@@ -1317,8 +1336,30 @@ static const ber_old_choice_t Component_choice[] = {
static int
dissect_tcap_Component(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
-#line 113 "tcap.cnf"
-dissect_tcap_TheComponent(implicit_tag, tvb, offset, actx, tree, hf_index);
+#line 116 "tcap.cnf"
+tvbuff_t *next_tvb;
+gint8 class;
+gboolean pc;
+gint tag;
+guint32 len, comp_offset;
+gint ind_field;
+
+comp_offset = dissect_ber_identifier(actx->pinfo, tree, tvb, offset, &class, &pc, &tag);
+comp_offset = dissect_ber_length(actx->pinfo, tree, tvb, comp_offset, &len, &ind_field);
+/* we can believe the length now */
+next_tvb = tvb_new_subset(tvb, offset, len+comp_offset-offset, len+comp_offset-offset);
+
+if (!next_tvb)
+ return comp_offset;
+
+ offset = dissect_ber_old_choice(actx, tree, tvb, offset,
+ Component_choice, hf_index, ett_tcap_Component,
+ NULL);
+
+
+ dissect_tcap_TheComponent(implicit_tag, next_tvb, 0, actx, tcap_top_tree, hf_index);
+
+/* return comp_offset+len; or return offset (will be automatically added */
@@ -1366,7 +1407,7 @@ static int dissect_unidirectional_impl(proto_tree *tree _U_, tvbuff_t *tvb _U_,
static int
dissect_tcap_OrigTransactionID(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
-#line 159 "tcap.cnf"
+#line 206 "tcap.cnf"
tvbuff_t *parameter_tvb;
guint8 len, i;
proto_item *tid_item;
@@ -1422,7 +1463,7 @@ static const ber_old_sequence_t Begin_sequence[] = {
static int
dissect_tcap_Begin(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
-#line 232 "tcap.cnf"
+#line 280 "tcap.cnf"
gp_tcapsrt_info->ope=TC_BEGIN;
/* Do not change col_add_str() to col_append_str() here: we _want_ this call
@@ -1448,7 +1489,7 @@ static int dissect_begin_impl(proto_tree *tree _U_, tvbuff_t *tvb _U_, int offse
static int
dissect_tcap_DestTransactionID(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
-#line 197 "tcap.cnf"
+#line 245 "tcap.cnf"
tvbuff_t *parameter_tvb;
guint8 len , i;
proto_item *tid_item;
@@ -1501,7 +1542,7 @@ static const ber_old_sequence_t End_sequence[] = {
static int
dissect_tcap_End(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
-#line 247 "tcap.cnf"
+#line 295 "tcap.cnf"
gp_tcapsrt_info->ope=TC_END;
if (check_col(actx->pinfo->cinfo, COL_INFO))
@@ -1527,7 +1568,7 @@ static const ber_old_sequence_t Continue_sequence[] = {
static int
dissect_tcap_Continue(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
-#line 255 "tcap.cnf"
+#line 303 "tcap.cnf"
gp_tcapsrt_info->ope=TC_CONT;
if (check_col(actx->pinfo->cinfo, COL_INFO))
@@ -1598,7 +1639,7 @@ static const ber_old_sequence_t Abort_sequence[] = {
static int
dissect_tcap_Abort(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
-#line 263 "tcap.cnf"
+#line 311 "tcap.cnf"
gp_tcapsrt_info->ope=TC_ABORT;
if (check_col(actx->pinfo->cinfo, COL_INFO))
@@ -1617,16 +1658,33 @@ static int dissect_abort_impl(proto_tree *tree _U_, tvbuff_t *tvb _U_, int offse
static int
dissect_tcap_TransactionID(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
-#line 295 "tcap.cnf"
+#line 351 "tcap.cnf"
tvbuff_t *next_tvb;
+guint8 len;
offset = dissect_ber_octet_string(implicit_tag, actx, tree, tvb, offset, hf_index,
&next_tvb);
-if(next_tvb)
+if(next_tvb) {
tcap_private.TransactionID_str = tvb_bytes_to_str(next_tvb, 0,tvb_length(next_tvb));
+ len = tvb_length_remaining(next_tvb, 0);
+ switch(len) {
+ case 1:
+ gp_tcapsrt_info->src_tid=tvb_get_guint8(next_tvb, 0);
+ break;
+ case 2:
+ gp_tcapsrt_info->src_tid=tvb_get_ntohs(next_tvb, 0);
+ break;
+ case 4:
+ gp_tcapsrt_info->src_tid=tvb_get_ntohl(next_tvb, 0);
+ break;
+ default:
+ gp_tcapsrt_info->src_tid=0;
+ break;
+ }
+}
@@ -1829,7 +1887,7 @@ static int dissect_operationCode(proto_tree *tree _U_, tvbuff_t *tvb _U_, int of
static int
dissect_tcap_ANSIParameters(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
-#line 131 "tcap.cnf"
+#line 174 "tcap.cnf"
/* we are doing the ParamSet here so need to look at the tags*/
guint32 len;
len = tvb_length_remaining(tvb, offset);
@@ -1841,7 +1899,6 @@ offset = dissect_ber_octet_string(TRUE, actx, tree, tvb, 0, hf_index,
-
return offset;
}
static int dissect_ansiparams(proto_tree *tree _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_) {
@@ -2095,22 +2152,28 @@ static const ber_old_choice_t ComponentPDU_choice[] = {
static int
dissect_tcap_ComponentPDU(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
-#line 142 "tcap.cnf"
-tvbuff_t *next_tvb;
-dissector_handle_t subdissector_handle;
+#line 185 "tcap.cnf"
+tvbuff_t *next_tvb;
+gint8 class;
+gboolean pc;
+gint tag;
+guint32 len, comp_offset;
+gint ind_field;
-next_tvb = tvb_new_subset(tvb, offset, tvb_length_remaining(tvb, offset), tvb_length_remaining(tvb, offset));
+comp_offset = dissect_ber_identifier(actx->pinfo, tree, tvb, offset, &class, &pc, &tag);
+comp_offset = dissect_ber_length(actx->pinfo, tree, tvb, comp_offset, &len, &ind_field);
+/* we can believe the length now */
+next_tvb = tvb_new_subset(tvb, offset, len+comp_offset-offset, len+comp_offset-offset);
-if (! (subdissector_handle = get_ansi_tcap_subdissector(actx->pinfo->match_port))) {
- subdissector_handle = data_handle;
-}
+if (!next_tvb)
+ return offset;
- tcap_subdissector_used=TRUE;
+ offset = dissect_ber_old_choice(actx, tree, tvb, offset,
+ ComponentPDU_choice, hf_index, ett_tcap_ComponentPDU,
+ NULL);
-call_dissector(subdissector_handle, next_tvb, actx->pinfo, tcap_top_tree);
-offset = dissect_ber_old_choice(actx, tree, tvb, offset,
- ComponentPDU_choice, hf_index, ett_tcap_ComponentPDU,NULL);
+dissect_tcap_TheComponentPDU(implicit_tag, next_tvb, 0, actx, tcap_top_tree, hf_index);
@@ -2175,7 +2238,8 @@ dissect_tcap_TransactionPDU(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int of
static int
dissect_tcap_T_ansiqueryWithPerm(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
-#line 277 "tcap.cnf"
+#line 327 "tcap.cnf"
+gp_tcapsrt_info->ope=TC_ANSI_ALL;
if (check_col(actx->pinfo->cinfo, COL_INFO))
col_add_str(actx->pinfo->cinfo, COL_INFO, "QueryWithPerm ");
@@ -2191,7 +2255,8 @@ static int dissect_ansiqueryWithPerm_impl(proto_tree *tree _U_, tvbuff_t *tvb _U
static int
dissect_tcap_T_ansiqueryWithoutPerm(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
-#line 280 "tcap.cnf"
+#line 331 "tcap.cnf"
+gp_tcapsrt_info->ope=TC_ANSI_ALL;
if (check_col(actx->pinfo->cinfo, COL_INFO))
col_add_str(actx->pinfo->cinfo, COL_INFO, "QueryWithOutPerm ");
@@ -2207,7 +2272,8 @@ static int dissect_ansiqueryWithoutPerm_impl(proto_tree *tree _U_, tvbuff_t *tvb
static int
dissect_tcap_T_ansiresponse(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
-#line 283 "tcap.cnf"
+#line 335 "tcap.cnf"
+gp_tcapsrt_info->ope=TC_ANSI_ALL;
if (check_col(actx->pinfo->cinfo, COL_INFO))
col_add_str(actx->pinfo->cinfo, COL_INFO, "Response ");
@@ -2223,7 +2289,8 @@ static int dissect_ansiresponse_impl(proto_tree *tree _U_, tvbuff_t *tvb _U_, in
static int
dissect_tcap_T_ansiconversationWithPerm(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
-#line 286 "tcap.cnf"
+#line 339 "tcap.cnf"
+gp_tcapsrt_info->ope=TC_ANSI_ALL;
if (check_col(actx->pinfo->cinfo, COL_INFO))
col_add_str(actx->pinfo->cinfo, COL_INFO, "ConversationWithPerm ");
@@ -2239,7 +2306,8 @@ static int dissect_ansiconversationWithPerm_impl(proto_tree *tree _U_, tvbuff_t
static int
dissect_tcap_T_ansiconversationWithoutPerm(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
-#line 289 "tcap.cnf"
+#line 343 "tcap.cnf"
+gp_tcapsrt_info->ope=TC_ANSI_ALL;
if (check_col(actx->pinfo->cinfo, COL_INFO))
col_add_str(actx->pinfo->cinfo, COL_INFO, "ConversationWithoutPerm ");
@@ -2314,7 +2382,9 @@ static const ber_old_sequence_t AbortPDU_sequence[] = {
static int
dissect_tcap_AbortPDU(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
-#line 271 "tcap.cnf"
+#line 319 "tcap.cnf"
+gp_tcapsrt_info->ope=TC_ANSI_ABORT;
+
if (check_col(actx->pinfo->cinfo, COL_INFO))
col_add_str(actx->pinfo->cinfo, COL_INFO, "Abort ");
@@ -2406,7 +2476,7 @@ static void dissect_UniDialoguePDU_PDU(tvbuff_t *tvb _U_, packet_info *pinfo _U_
/*--- End of included file: packet-tcap-fn.c ---*/
-#line 144 "packet-tcap-template.c"
+#line 145 "packet-tcap-template.c"
@@ -2424,15 +2494,15 @@ dissect_tcap(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree)
{
proto_item *item=NULL;
proto_tree *tree=NULL;
- proto_item *stat_item=NULL;
- proto_tree *stat_tree=NULL;
- gint offset = 0;
+
struct tcaphash_context_t * p_tcap_context;
dissector_handle_t subdissector_handle;
asn1_ctx_t asn1_ctx;
asn1_ctx_init(&asn1_ctx, ASN1_ENC_BER, TRUE, pinfo);
tcap_top_tree = parent_tree;
+ tcap_stat_tree = NULL;
+
if (check_col(pinfo->cinfo, COL_PROTOCOL))
{
col_set_str(pinfo->cinfo, COL_PROTOCOL, "TCAP");
@@ -2442,7 +2512,6 @@ dissect_tcap(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree)
if(parent_tree){
item = proto_tree_add_item(parent_tree, proto_tcap, tvb, 0, -1, FALSE);
tree = proto_item_add_subtree(item, ett_tcap);
- tcap_stat_item=item;
tcap_stat_tree=tree;
}
cur_oid = NULL;
@@ -2456,29 +2525,25 @@ dissect_tcap(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree)
dissect_tcap_TCMessage(FALSE, tvb, 0, &asn1_ctx, tree, -1);
if (gtcap_HandleSRT && !tcap_subdissector_used ) {
- if (gtcap_DisplaySRT && tree) {
- stat_item = proto_tree_add_text(tree, tvb, 0, 0, "Stat");
- PROTO_ITEM_SET_GENERATED(stat_item);
- stat_tree = proto_item_add_subtree(stat_item, ett_tcap_stat);
- }
- p_tcap_context=tcapsrt_call_matching(tvb, pinfo, stat_tree, gp_tcapsrt_info);
- tcap_private.context=p_tcap_context;
+ p_tcap_context=tcapsrt_call_matching(tvb, pinfo, tcap_stat_tree, gp_tcapsrt_info);
+ tcap_private.context=p_tcap_context;
/* If the current message is TCAP only,
- * save the Application contexte name for the next messages
+ * save the Application Context Name for the next messages
*/
if ( p_tcap_context && cur_oid && !p_tcap_context->oid_present ) {
/* Save the application context and the sub dissector */
ber_oid_dissector_table = find_dissector_table("ber.oid");
strncpy(p_tcap_context->oid,cur_oid, LENGTH_OID);
+ p_tcap_context->oid_present=TRUE;
if ( (subdissector_handle = dissector_get_string_handle(ber_oid_dissector_table, cur_oid)) ) {
p_tcap_context->subdissector_handle=subdissector_handle;
- p_tcap_context->oid_present=TRUE;
+ p_tcap_context->subdissector_present=TRUE;
}
}
if (gtcap_HandleSRT && p_tcap_context && p_tcap_context->callback) {
/* Callback fonction for the upper layer */
- (p_tcap_context->callback)(tvb, pinfo, stat_tree, p_tcap_context);
+ (p_tcap_context->callback)(tvb, pinfo, tcap_stat_tree, p_tcap_context);
}
}
}
@@ -2503,7 +2568,7 @@ proto_reg_handoff_tcap(void)
/*--- End of included file: packet-tcap-dis-tab.c ---*/
-#line 233 "packet-tcap-template.c"
+#line 229 "packet-tcap-template.c"
}
static void init_tcap(void);
@@ -2560,10 +2625,10 @@ proto_register_tcap(void)
"Duration of the TCAP session", HFILL }
},
{ &hf_tcapsrt_Duplicate,
- { "Request Duplicate",
+ { "Session Duplicate",
"tcap.srt.duplicate",
- FT_UINT32, BASE_DEC, NULL, 0x0,
- "", HFILL }
+ FT_FRAMENUM, BASE_NONE, NULL, 0x0,
+ "SRT Duplicated with Session", HFILL }
},
/*--- Included file: packet-tcap-hfarr.c ---*/
@@ -3066,7 +3131,7 @@ proto_register_tcap(void)
"", HFILL }},
/*--- End of included file: packet-tcap-hfarr.c ---*/
-#line 295 "packet-tcap-template.c"
+#line 291 "packet-tcap-template.c"
};
/* Setup protocol subtree array */
@@ -3131,7 +3196,7 @@ proto_register_tcap(void)
&ett_tcap_ErrorCode,
/*--- End of included file: packet-tcap-ettarr.c ---*/
-#line 305 "packet-tcap-template.c"
+#line 301 "packet-tcap-template.c"
};
/*static enum_val_t tcap_options[] = {
@@ -3305,53 +3370,30 @@ static void raz_tcap_private(struct tcap_private_t * p_tcap_private)
memset(p_tcap_private,0,sizeof(struct tcap_private_t) );
}
-
+/*
+ * Call ITU Subdissector to decode the Tcap Component
+ */
static int
dissect_tcap_TheComponent(gboolean implicit_tag _U_, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_, proto_tree *tree, int hf_index _U_)
{
- tvbuff_t * next_tvb;
- dissector_handle_t subdissector_handle;
+ dissector_handle_t subdissector_handle=NULL;
gboolean is_subdissector=FALSE;
struct tcaphash_context_t * p_tcap_context=NULL;
- gint8 class;
- gboolean pc;
- gint tag;
- guint32 len, s_offset;
- gint ind_field;
- proto_tree * stat_tree=NULL;
- proto_item * stat_item=NULL;
/*
* ok lets look at the oid and ssn and try and find a dissector, otherwise lets decode it.
*/
ber_oid_dissector_table = find_dissector_table("ber.oid");
- s_offset = offset;
- offset = get_ber_identifier(tvb, offset, &class, &pc, &tag);
- offset = get_ber_length(tree, tvb, offset, &len, &ind_field);
- /* we can believe the length now */
- next_tvb = tvb_new_subset(tvb, s_offset, len+(offset-s_offset), len+(offset-s_offset));
- if (!next_tvb)
- return offset+len;
-
- dissect_ber_old_choice(actx, tree, next_tvb, 0,
- Component_choice, hf_index, ett_tcap_Component,NULL);
-
/*
* Handle The TCAP Service Response Time
*/
if ( gtcap_HandleSRT ) {
if (!tcap_subdissector_used) {
- /* Create TCAP context and tree for display */
- if (gtcap_DisplaySRT && tree) {
- stat_item = proto_tree_add_text(tcap_stat_tree, tvb, offset, -1, "Stat");
- PROTO_ITEM_SET_GENERATED(stat_item);
- stat_tree = proto_item_add_subtree(stat_item, ett_tcap_stat);
- }
- p_tcap_context=tcapsrt_call_matching(tvb, actx->pinfo, stat_tree, gp_tcapsrt_info);
- tcap_subdissector_used=TRUE;
- gp_tcap_context=p_tcap_context;
- tcap_private.context=p_tcap_context;
+ p_tcap_context=tcapsrt_call_matching(tvb, actx->pinfo, tcap_stat_tree, gp_tcapsrt_info);
+ tcap_subdissector_used=TRUE;
+ gp_tcap_context=p_tcap_context;
+ tcap_private.context=p_tcap_context;
}else{
/* Take the last TCAP context */
p_tcap_context = gp_tcap_context;
@@ -3364,21 +3406,31 @@ dissect_tcap_TheComponent(gboolean implicit_tag _U_, tvbuff_t *tvb, int offset,
/* We have already an Application Context, check if we have
to fallback to a lower version */
if ( strncmp(p_tcap_context->oid,cur_oid, LENGTH_OID)!=0) {
- /* ACN, changed, Fallback to lower version
- * and update the subdissector (purely formal)
+ /* ACN, changed, Fallback to lower version
+ * and update the subdissector (purely formal)
*/
strncpy(p_tcap_context->oid,cur_oid, LENGTH_OID);
if ( (subdissector_handle = dissector_get_string_handle(ber_oid_dissector_table, cur_oid)) ) {
p_tcap_context->subdissector_handle=subdissector_handle;
+ p_tcap_context->subdissector_present=TRUE;
}
}
} else {
/* We do not have the OID in the TCAP context, so store it */
strncpy(p_tcap_context->oid,cur_oid, LENGTH_OID);
+ p_tcap_context->oid_present=TRUE;
+ /* Try to find a subdissector according to OID */
if ( (subdissector_handle
= dissector_get_string_handle(ber_oid_dissector_table, cur_oid)) ) {
p_tcap_context->subdissector_handle=subdissector_handle;
- p_tcap_context->oid_present=TRUE;
+ p_tcap_context->subdissector_present=TRUE;
+ } else {
+ /* Not found, so try to find a subdissector according to SSN */
+ if ( (subdissector_handle = get_itu_tcap_subdissector(actx->pinfo->match_port))) {
+ /* Found according to SSN */
+ p_tcap_context->subdissector_handle=subdissector_handle;
+ p_tcap_context->subdissector_present=TRUE;
+ }
}
} /* context OID */
} else {
@@ -3392,7 +3444,7 @@ dissect_tcap_TheComponent(gboolean implicit_tag _U_, tvbuff_t *tvb, int offset,
if ( p_tcap_context
- && p_tcap_context->oid_present) {
+ && p_tcap_context->subdissector_present) {
/* Take the subdissector from the context */
subdissector_handle=p_tcap_context->subdissector_handle;
is_subdissector=TRUE;
@@ -3445,43 +3497,78 @@ dissect_tcap_TheComponent(gboolean implicit_tag _U_, tvbuff_t *tvb, int offset,
/* Call the sub dissector if present, and not already called */
if (is_subdissector)
- call_dissector(subdissector_handle, next_tvb, actx->pinfo, tcap_top_tree);
+ call_dissector(subdissector_handle, tvb, actx->pinfo, tree);
- return offset+len;
+ return offset;
}
+/*
+ * Call ANSI Subdissector to decode the Tcap Component
+ */
+static int
+dissect_tcap_TheComponentPDU(gboolean implicit_tag _U_, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_, proto_tree *tree, int hf_index _U_)
+{
+ dissector_handle_t subdissector_handle;
+ gboolean is_subdissector=FALSE;
+ struct tcaphash_context_t * p_tcap_context=NULL;
+
+ gchar str[20];
+
+
+ /*
+ * Handle The TCAP Service Response Time
+ */
+ if ( gtcap_HandleSRT ) {
+ if (!tcap_subdissector_used) {
+ p_tcap_context=tcapsrt_call_matching(tvb, actx->pinfo, tcap_stat_tree, gp_tcapsrt_info);
+ tcap_subdissector_used=TRUE;
+ gp_tcap_context=p_tcap_context;
+ tcap_private.context=p_tcap_context;
+ } else {
+ /* Take the last TCAP context */
+ p_tcap_context = gp_tcap_context;
+ tcap_private.context=p_tcap_context;
+ }
+ }
+
+ if (p_tcap_context) {
+ /* tcap_private.TransactionID_str = bytes_to_str(&(p_tcap_context->session_id),4); */
+ g_snprintf(str, sizeof(str), "(%d)",p_tcap_context->session_id);
+ tcap_private.TransactionID_str = str;
+ }
+
+ if ( (subdissector_handle
+ = get_ansi_tcap_subdissector(actx->pinfo->match_port))) {
+ /* Found according to SSN */
+ is_subdissector=TRUE;
+ } else {
+ /* Nothing found, take the Data handler */
+ subdissector_handle = data_handle;
+ is_subdissector=TRUE;
+ } /* SSN */
+
+ /* Call the sub dissector if present, and not already called */
+ if (is_subdissector)
+ call_dissector(subdissector_handle, tvb, actx->pinfo, tree);
+
+ return offset;
+}
static int
dissect_tcap_TheExternUserInfo(gboolean implicit_tag _U_, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_, proto_tree *tree, int hf_index _U_)
{
- tvbuff_t *next_tvb;
- gint8 class;
- gboolean pc;
- gint tag;
- guint32 len, start_offset;
- gint ind_field;
-
/*
* ok lets look at the oid and ssn and try and find a dissector, otherwise lets decode it.
*/
ber_oid_dissector_table = find_dissector_table("ber.oid");
- start_offset = offset;
- offset = get_ber_identifier(tvb, offset, &class, &pc, &tag);
- offset = get_ber_length(tree, tvb, offset, &len, &ind_field);
-
- next_tvb = tvb_new_subset(tvb, start_offset, len +(offset - start_offset), len+(offset - start_offset));
- if (!next_tvb)
- return offset+len;
if (ber_oid_dissector_table && tcapext_oid){
- if(!dissector_try_string(ber_oid_dissector_table, tcapext_oid, next_tvb, actx->pinfo, tcap_top_tree))
+ if(!dissector_try_string(ber_oid_dissector_table, tcapext_oid, tvb, actx->pinfo, tree))
{
- dissect_tcap_param(actx,tree,next_tvb,0);
- offset+=len;
- return offset;
+ return dissect_tcap_param(actx,tree,tvb,0);
}
}
- return offset+len;
+ return offset;
}
diff --git a/epan/dissectors/packet-tcap.h b/epan/dissectors/packet-tcap.h
index a5eca10b6c..a4dda65705 100644
--- a/epan/dissectors/packet-tcap.h
+++ b/epan/dissectors/packet-tcap.h
@@ -1,6 +1,6 @@
/* Do not modify this file. */
/* It is created automatically by the ASN.1 to Wireshark dissector compiler */
-/* .\packet-tcap.h */
+/* ./packet-tcap.h */
/* ../../tools/asn2wrs.py -b -e -p tcap -c tcap.cnf -s packet-tcap-template tcap.asn */
/* Input file: packet-tcap-template.h */
@@ -56,7 +56,7 @@
#define TCAP_INVOKE_ID_TAG 0x02
#define TCAP_LINKED_ID_TAG 0x80
-#define TCAP_EOC_LEN 2
+#define TCAP_EOC_LEN 2
#define TCAP_CONSTRUCTOR(TCtag) (TCtag & 0x20)
@@ -64,6 +64,8 @@
#define TC_CONT 2
#define TC_END 3
#define TC_ABORT 4
+#define TC_ANSI_ABORT 5
+#define TC_ANSI_ALL 6
struct tcap_private_t {
gboolean acv; /* Is the Application Context Version present */
@@ -76,8 +78,11 @@ struct tcap_private_t {
extern gint tcap_standard;
extern const value_string tcap_component_type_str[];
+void proto_reg_handoff_tcap(void);
+void proto_register_tcap(void);
extern dissector_handle_t get_itu_tcap_subdissector(guint32 ssn);
+dissector_handle_t get_ansi_tcap_subdissector(guint32 ssn);
extern void add_ansi_tcap_subdissector(guint32 ssn, dissector_handle_t dissector);
extern void add_itu_tcap_subdissector(guint32 ssn, dissector_handle_t dissector);
@@ -96,6 +101,6 @@ int dissect_tcap_DialoguePDU(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int o
int dissect_tcap_UniDialoguePDU(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_);
/*--- End of included file: packet-tcap-exp.h ---*/
-#line 83 "packet-tcap-template.h"
+#line 88 "packet-tcap-template.h"
#endif /* PACKET_tcap_H */
diff --git a/epan/tcap-persistentdata.c b/epan/tcap-persistentdata.c
index 76edc929a7..9e7deebaf3 100644
--- a/epan/tcap-persistentdata.c
+++ b/epan/tcap-persistentdata.c
@@ -8,6 +8,8 @@
* By Gerald Combs <gerald@wireshark.org>
* Copyright 1998 Gerald Combs
*
+ * $Id$
+ *
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
@@ -47,6 +49,8 @@ static gint tcaphash_cont_equal(gconstpointer k1, gconstpointer k2);
static guint tcaphash_cont_calchash(gconstpointer k);
static gint tcaphash_end_equal(gconstpointer k1, gconstpointer k2);
static guint tcaphash_end_calchash(gconstpointer k);
+static gint tcaphash_ansi_equal(gconstpointer k1, gconstpointer k2);
+static guint tcaphash_ansi_calchash(gconstpointer k);
static void update_tcaphash_begincall(struct tcaphash_begincall_t *p_tcaphash_begincall,
packet_info *pinfo );
@@ -89,6 +93,9 @@ static struct tcaphash_context_t *tcaphash_cont_matching(tvbuff_t *tvb, packet_i
static struct tcaphash_context_t *tcaphash_end_matching(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
struct tcapsrt_info_t *p_tcapsrt_info);
+static struct tcaphash_context_t *tcaphash_ansi_matching(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
+ struct tcapsrt_info_t *p_tcapsrt_info);
+
struct tcapsrt_info_t *tcapsrt_razinfo(void);
/* When several Tcap components are received in a single TCAP message,
@@ -107,6 +114,8 @@ gboolean gtcap_PersistentSRT=FALSE;
gboolean gtcap_DisplaySRT=FALSE;
gboolean gtcap_StatSRT=FALSE;
+extern gint ett_tcap_stat;
+
extern int hf_tcapsrt_SessionId;
extern int hf_tcapsrt_Duplicate;
extern int hf_tcapsrt_BeginSession;
@@ -118,12 +127,15 @@ static GHashTable *tcaphash_context = NULL;
static GHashTable *tcaphash_begin = NULL;
static GHashTable *tcaphash_cont = NULL;
static GHashTable *tcaphash_end = NULL;
+static GHashTable *tcaphash_ansi = NULL;
guint32 tcapsrt_global_SessionId=1;
/*
* DEBUG fonctions
*/
+#undef MEM_TCAPSRT
+/* #define MEM_TCAPSRT */
#undef DEBUG_TCAPSRT
/* #define DEBUG_TCAPSRT */
@@ -259,6 +271,38 @@ tcaphash_end_calchash(gconstpointer k)
return hashkey;
}
+static gint
+tcaphash_ansi_equal(gconstpointer k1, gconstpointer k2)
+{
+ const struct tcaphash_ansi_info_key_t *key1 = (const struct tcaphash_ansi_info_key_t *) k1;
+ const struct tcaphash_ansi_info_key_t *key2 = (const struct tcaphash_ansi_info_key_t *) k2;
+
+ if (key1->hashKey == key2->hashKey) {
+
+ if ( ( (key1->opc_hash == key2->opc_hash) &&
+ (key1->dpc_hash == key2->dpc_hash) &&
+ (key1->tid == key2->tid) )
+ ||
+ ( (key1->opc_hash == key2->dpc_hash) &&
+ (key1->dpc_hash == key2->opc_hash) &&
+ (key1->tid == key2->tid) )
+ )
+ return TRUE;
+ }
+ return FALSE;
+}
+
+/* calculate a hash key */
+static guint
+tcaphash_ansi_calchash(gconstpointer k)
+{
+ const struct tcaphash_ansi_info_key_t *key = (const struct tcaphash_ansi_info_key_t *) k;
+ guint hashkey;
+ /* hashkey = key->opc_hash<<16 + key->dpc_hash<<8 + key->src_tid; */
+ hashkey = key->tid;
+ return hashkey;
+}
+
/*
* Update a record with the data of the Request
*/
@@ -286,7 +330,11 @@ append_tcaphash_begincall(struct tcaphash_begincall_t *prev_begincall,
/* Append the transaction to the list, when the same key is found
This should append when the tcap-transaction Id is reused */
+#ifdef MEM_TCAPSRT
+ p_new_tcaphash_begincall = g_malloc0(sizeof(struct tcaphash_begincall_t));
+#else
p_new_tcaphash_begincall = se_alloc0(sizeof(struct tcaphash_begincall_t));
+#endif
p_new_tcaphash_begincall->context=p_tcaphash_context;
p_tcaphash_context->begincall=p_new_tcaphash_begincall;
p_new_tcaphash_begincall->beginkey=prev_begincall->beginkey;
@@ -309,6 +357,61 @@ append_tcaphash_begincall(struct tcaphash_begincall_t *prev_begincall,
return p_new_tcaphash_begincall;
}
+/*
+ * Update a record with the data of the Request
+ */
+static void
+update_tcaphash_ansicall(struct tcaphash_ansicall_t *p_tcaphash_ansicall,
+ packet_info *pinfo)
+{
+ p_tcaphash_ansicall->context->first_frame = pinfo->fd->num;
+ p_tcaphash_ansicall->context->last_frame = 0;
+ p_tcaphash_ansicall->context->responded = FALSE;
+ p_tcaphash_ansicall->context->begin_time = pinfo->fd->abs_ts;
+}
+
+/*
+ * Append a new dialogue, using the same Key, to the chained list
+ * The time is stored too
+ */
+static struct tcaphash_ansicall_t *
+append_tcaphash_ansicall(struct tcaphash_ansicall_t *prev_ansicall,
+ struct tcaphash_context_t *p_tcaphash_context,
+ packet_info *pinfo)
+{
+ struct tcaphash_ansicall_t *p_new_tcaphash_ansicall = NULL;
+
+ /* Append the transaction to the list, when the same key is found
+ This should append when the tcap-transaction Id is reused */
+
+#ifdef MEM_TCAPSRT
+ p_new_tcaphash_ansicall = g_malloc0(sizeof(struct tcaphash_ansicall_t));
+#else
+ p_new_tcaphash_ansicall = se_alloc0(sizeof(struct tcaphash_ansicall_t));
+#endif
+ p_new_tcaphash_ansicall->context=p_tcaphash_context;
+ p_tcaphash_context->ansicall=p_new_tcaphash_ansicall;
+ p_new_tcaphash_ansicall->ansikey=prev_ansicall->ansikey;
+ p_new_tcaphash_ansicall->context->first_frame = pinfo->fd->num;
+ p_new_tcaphash_ansicall->next_ansicall=NULL;
+ p_new_tcaphash_ansicall->previous_ansicall=prev_ansicall;
+ p_new_tcaphash_ansicall->father=FALSE;
+
+#ifdef DEBUG_TCAPSRT
+ dbg(10,"+A%d ", p_new_tcaphash_ansicall->context->session_id);
+#endif
+ /* Insert in the chained list */
+ prev_ansicall->next_ansicall = p_new_tcaphash_ansicall;
+ if (prev_ansicall->context->last_frame == 0) {
+#ifdef DEBUG_TCAPSRT
+ dbg(10,"last ");
+#endif
+ prev_ansicall->context->last_frame = pinfo->fd->num-1;
+ }
+ return p_new_tcaphash_ansicall;
+}
+
+
static struct tcaphash_contcall_t *
append_tcaphash_contcall(struct tcaphash_contcall_t *prev_contcall,
struct tcaphash_context_t *p_tcaphash_context)
@@ -318,7 +421,11 @@ append_tcaphash_contcall(struct tcaphash_contcall_t *prev_contcall,
/* Append the transaction to the list, when the same key is found
This should append when the tcap-transaction Id is reused */
+#ifdef MEM_TCAPSRT
+ p_new_tcaphash_contcall = g_malloc0(sizeof(struct tcaphash_contcall_t));
+#else
p_new_tcaphash_contcall = se_alloc0(sizeof(struct tcaphash_contcall_t));
+#endif
p_new_tcaphash_contcall->context=p_tcaphash_context;
p_tcaphash_context->contcall=p_new_tcaphash_contcall;
p_new_tcaphash_contcall->contkey=prev_contcall->contkey;
@@ -344,7 +451,11 @@ append_tcaphash_endcall(struct tcaphash_endcall_t *prev_endcall,
/* Append the transaction to the list, when the same key is found
This should append when the tcap-transaction Id is reused */
- p_new_tcaphash_endcall = se_alloc0(sizeof(struct tcaphash_endcall_t));
+#ifdef MEM_TCAPSRT
+ p_new_tcaphash_endcall = g_malloc0(sizeof(struct tcaphash_endcall_t));
+#else
+ p_new_tcaphash_endcall = se_alloc0(sizeof(struct tcaphash_endcall_t));
+#endif
p_new_tcaphash_endcall->context=p_tcaphash_context;
p_tcaphash_context->endcall=p_new_tcaphash_endcall;
p_new_tcaphash_endcall->endkey=prev_endcall->endkey;
@@ -389,6 +500,9 @@ find_tcaphash_begin(struct tcaphash_begin_info_key_t *p_tcaphash_begin_key,
return p_tcaphash_begincall;
break;
}
+#ifdef DEBUG_TCAPSRT
+ dbg(60,"[B%d] ", p_tcaphash_begincall->context->session_id);
+#endif
}
/* Break when list end is reached */
if(p_tcaphash_begincall->next_begincall == NULL) {
@@ -418,18 +532,18 @@ find_tcaphash_cont(struct tcaphash_cont_info_key_t *p_tcaphash_cont_key,
if(p_tcaphash_contcall) {
do {
- if ( p_tcaphash_contcall->context &&
- pinfo->fd->num >= p_tcaphash_contcall->context->first_frame &&
- (p_tcaphash_contcall->context->last_frame?pinfo->fd->num <= p_tcaphash_contcall->context->last_frame:1) ) {
- /* We have a dialogue, with this key, opened before this request */
+ if ( p_tcaphash_contcall->context ) {
+ if (pinfo->fd->num >= p_tcaphash_contcall->context->first_frame &&
+ (p_tcaphash_contcall->context->last_frame?pinfo->fd->num <= p_tcaphash_contcall->context->last_frame:1) ) {
+ /* We have a dialogue, with this key, opened before this request */
#ifdef DEBUG_TCAPSRT
- dbg(10,"C%d ", p_tcaphash_contcall->context->session_id);
+ dbg(10,"C%d ", p_tcaphash_contcall->context->session_id);
#endif
- return p_tcaphash_contcall;
- break;
- } else {
+ return p_tcaphash_contcall;
+ break;
+ }
#ifdef DEBUG_TCAPSRT
- dbg(23,"Bug in Clist ");
+ dbg(60,"[C%d] ", p_tcaphash_contcall->context->session_id);
#endif
}
/* Break when list end is reached */
@@ -474,11 +588,10 @@ find_tcaphash_end(struct tcaphash_end_info_key_t *p_tcaphash_end_key,
#endif
return p_tcaphash_endcall;
break;
- } else {
+ }
#ifdef DEBUG_TCAPSRT
- dbg(23,"Bug in Elist ");
+ dbg(60,"[E%d] ", p_tcaphash_endcall->context->session_id);
#endif
- }
}
/* Break when list end is reached */
if(p_tcaphash_endcall->next_endcall == NULL) {
@@ -511,10 +624,18 @@ new_tcaphash_context(struct tcaphash_context_key_t *p_tcaphash_context_key,
with the tcap transaction Id as Main Key
Once created, this entry will be updated later */
+#ifdef MEM_TCAPSRT
+ p_new_tcaphash_context_key = g_malloc(sizeof(struct tcaphash_context_key_t));
+#else
p_new_tcaphash_context_key = se_alloc(sizeof(struct tcaphash_context_key_t));
+#endif
p_new_tcaphash_context_key->session_id = p_tcaphash_context_key->session_id;
- p_new_tcaphash_context = se_alloc0(sizeof(struct tcaphash_context_t));
+#ifdef MEM_TCAPSRT
+ p_new_tcaphash_context = g_malloc0(sizeof(struct tcaphash_context_t));
+#else
+ p_new_tcaphash_context = se_alloc0(sizeof(struct tcaphash_context_t));
+#endif
p_new_tcaphash_context->key = p_new_tcaphash_context_key;
p_new_tcaphash_context->session_id = p_tcaphash_context_key->session_id;
p_new_tcaphash_context->first_frame = pinfo->fd->num;
@@ -540,13 +661,21 @@ new_tcaphash_begin(struct tcaphash_begin_info_key_t *p_tcaphash_begin_key,
with the tcap transaction Id as Main Key
Once created, this entry will be updated later */
- p_new_tcaphash_begin_key = se_alloc(sizeof(struct tcaphash_begin_info_key_t));
+#ifdef MEM_TCAPSRT
+ p_new_tcaphash_begin_key = g_malloc(sizeof(struct tcaphash_begin_info_key_t));
+#else
+ p_new_tcaphash_begin_key = se_alloc(sizeof(struct tcaphash_begin_info_key_t));
+#endif
p_new_tcaphash_begin_key->hashKey = p_tcaphash_begin_key->hashKey;
p_new_tcaphash_begin_key->tid = p_tcaphash_begin_key->tid;
p_new_tcaphash_begin_key->opc_hash = p_tcaphash_begin_key->opc_hash;
p_new_tcaphash_begin_key->dpc_hash = p_tcaphash_begin_key->dpc_hash;
- p_new_tcaphash_begincall = se_alloc0(sizeof(struct tcaphash_begincall_t));
+#ifdef MEM_TCAPSRT
+ p_new_tcaphash_begincall = g_malloc0(sizeof(struct tcaphash_begincall_t));
+#else
+ p_new_tcaphash_begincall = se_alloc0(sizeof(struct tcaphash_begincall_t));
+#endif
p_new_tcaphash_begincall->beginkey=p_new_tcaphash_begin_key;
p_new_tcaphash_begincall->context=p_tcaphash_context;
p_tcaphash_context->begincall=p_new_tcaphash_begincall;
@@ -578,14 +707,22 @@ new_tcaphash_cont(struct tcaphash_cont_info_key_t *p_tcaphash_cont_key,
with the tcap transaction Id as Main Key
Once created, this entry will be updated later */
- p_new_tcaphash_cont_key = se_alloc(sizeof(struct tcaphash_cont_info_key_t));
+#ifdef MEM_TCAPSRT
+ p_new_tcaphash_cont_key = g_malloc(sizeof(struct tcaphash_cont_info_key_t));
+#else
+ p_new_tcaphash_cont_key = se_alloc(sizeof(struct tcaphash_cont_info_key_t));
+#endif
p_new_tcaphash_cont_key->hashKey = p_tcaphash_cont_key->hashKey;
p_new_tcaphash_cont_key->src_tid = p_tcaphash_cont_key->src_tid;
p_new_tcaphash_cont_key->dst_tid = p_tcaphash_cont_key->dst_tid;
p_new_tcaphash_cont_key->opc_hash = p_tcaphash_cont_key->opc_hash;
p_new_tcaphash_cont_key->dpc_hash = p_tcaphash_cont_key->dpc_hash;
+#ifdef MEM_TCAPSRT
+ p_new_tcaphash_contcall = g_malloc0(sizeof(struct tcaphash_contcall_t));
+#else
p_new_tcaphash_contcall = se_alloc0(sizeof(struct tcaphash_contcall_t));
+#endif
p_new_tcaphash_contcall->contkey=p_new_tcaphash_cont_key;
p_new_tcaphash_contcall->context=p_tcaphash_context;
p_tcaphash_context->contcall=p_new_tcaphash_contcall;
@@ -616,13 +753,21 @@ new_tcaphash_end(struct tcaphash_end_info_key_t *p_tcaphash_end_key,
with the tcap transaction Id as Main Key
Once created, this entry will be updated later */
- p_new_tcaphash_end_key = se_alloc(sizeof(struct tcaphash_end_info_key_t));
+#ifdef MEM_TCAPSRT
+ p_new_tcaphash_end_key = g_malloc(sizeof(struct tcaphash_end_info_key_t));
+#else
+ p_new_tcaphash_end_key = se_alloc(sizeof(struct tcaphash_end_info_key_t));
+#endif
p_new_tcaphash_end_key->hashKey = p_tcaphash_end_key->hashKey;
p_new_tcaphash_end_key->tid = p_tcaphash_end_key->tid;
p_new_tcaphash_end_key->opc_hash = p_tcaphash_end_key->opc_hash;
p_new_tcaphash_end_key->dpc_hash = p_tcaphash_end_key->dpc_hash;
- p_new_tcaphash_endcall = se_alloc0(sizeof(struct tcaphash_endcall_t));
+#ifdef MEM_TCAPSRT
+ p_new_tcaphash_endcall = g_malloc0(sizeof(struct tcaphash_endcall_t));
+#else
+ p_new_tcaphash_endcall = se_alloc0(sizeof(struct tcaphash_endcall_t));
+#endif
p_new_tcaphash_endcall->endkey=p_new_tcaphash_end_key;
p_new_tcaphash_endcall->context=p_tcaphash_context;
p_tcaphash_context->endcall=p_new_tcaphash_endcall;
@@ -637,8 +782,49 @@ new_tcaphash_end(struct tcaphash_end_info_key_t *p_tcaphash_end_key,
g_hash_table_insert(tcaphash_end, p_new_tcaphash_end_key, p_new_tcaphash_endcall);
return p_new_tcaphash_endcall;
}
+/*
+ * New record to create, to identify a new transaction
+ */
+static struct tcaphash_ansicall_t *
+new_tcaphash_ansi(struct tcaphash_ansi_info_key_t *p_tcaphash_ansi_key,
+ struct tcaphash_context_t *p_tcaphash_context)
+{
+ struct tcaphash_ansi_info_key_t *p_new_tcaphash_ansi_key;
+ struct tcaphash_ansicall_t *p_new_tcaphash_ansicall = NULL;
+ /* Register the transaction in the hash table
+ with the tcap transaction Id as Main Key
+ Once created, this entry will be updated later */
+#ifdef MEM_TCAPSRT
+ p_new_tcaphash_ansi_key = g_malloc(sizeof(struct tcaphash_ansi_info_key_t));
+#else
+ p_new_tcaphash_ansi_key = se_alloc(sizeof(struct tcaphash_ansi_info_key_t));
+#endif
+ p_new_tcaphash_ansi_key->hashKey = p_tcaphash_ansi_key->hashKey;
+ p_new_tcaphash_ansi_key->tid = p_tcaphash_ansi_key->tid;
+ p_new_tcaphash_ansi_key->opc_hash = p_tcaphash_ansi_key->opc_hash;
+ p_new_tcaphash_ansi_key->dpc_hash = p_tcaphash_ansi_key->dpc_hash;
+
+#ifdef MEM_TCAPSRT
+ p_new_tcaphash_ansicall = g_malloc0(sizeof(struct tcaphash_ansicall_t));
+#else
+ p_new_tcaphash_ansicall = se_alloc0(sizeof(struct tcaphash_ansicall_t));
+#endif
+ p_new_tcaphash_ansicall->ansikey=p_new_tcaphash_ansi_key;
+ p_new_tcaphash_ansicall->context=p_tcaphash_context;
+ p_tcaphash_context->ansicall=p_new_tcaphash_ansicall;
+ p_new_tcaphash_ansicall->father=TRUE;
+ p_new_tcaphash_ansicall->next_ansicall=NULL;
+ p_new_tcaphash_ansicall->previous_ansicall=NULL;
+
+#ifdef DEBUG_TCAPSRT
+ dbg(10,"A%d ", p_new_tcaphash_ansicall->context->session_id);
+#endif
+ /* store it */
+ g_hash_table_insert(tcaphash_ansi, p_new_tcaphash_ansi_key, p_new_tcaphash_ansicall);
+ return p_new_tcaphash_ansicall;
+}
static struct tcaphash_contcall_t *
create_tcaphash_cont(struct tcaphash_cont_info_key_t *p_tcaphash_cont_key,
@@ -735,6 +921,13 @@ tcapsrt_init_routine(void)
g_hash_table_destroy(tcaphash_end);
}
+ if (tcaphash_ansi != NULL) {
+#ifdef DEBUG_TCAPSRT
+ dbg(16,"Destroy hash_ansi ");
+#endif
+ g_hash_table_destroy(tcaphash_ansi);
+ }
+
#ifdef DEBUG_TCAPSRT
dbg(16,"Create hash ");
#endif
@@ -743,6 +936,7 @@ tcapsrt_init_routine(void)
tcaphash_begin = g_hash_table_new(tcaphash_begin_calchash, tcaphash_begin_equal);
tcaphash_cont = g_hash_table_new(tcaphash_cont_calchash, tcaphash_cont_equal);
tcaphash_end = g_hash_table_new(tcaphash_end_calchash, tcaphash_end_equal);
+ tcaphash_ansi = g_hash_table_new(tcaphash_ansi_calchash, tcaphash_ansi_equal);
/* Reset the session counter */
tcapsrt_global_SessionId=1;
@@ -752,9 +946,20 @@ tcapsrt_init_routine(void)
}
/*
- * Service Responsee Time analyze
+ * Service Response Time analyze
* Called just after dissector call
- */
+ * Associate a TCAP context to a tcap session and display session related infomations
+ * like the first frame, the last, the session duration,
+ * and a uniq session identifier for the filtering
+ *
+ * For ETSI tcap, the TCAP context can be reached through three keys
+ * - a key (BEGIN) identifying the session according to the tcap source identifier
+ * - a key (CONT) identifying the established session (src_id and dst_id)
+ * - a key (END) identifying the session according to the tcap destination identifier
+ *
+ * For ANSI tcap, the TCAP context is reached through a uniq key
+ * - a key (ANSI) identifying the session according to the tcap identifier
+*/
struct tcaphash_context_t *
tcapsrt_call_matching(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
struct tcapsrt_info_t *p_tcapsrt_info)
@@ -762,8 +967,8 @@ tcapsrt_call_matching(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
struct tcaphash_context_t *tcap_context=NULL;
switch (p_tcapsrt_info->ope) {
-
- case TC_BEGIN: /*InitialDP*/
+
+ case TC_BEGIN:
#ifdef DEBUG_TCAPSRT
dbg(1,"TC_BEGIN ");
#endif
@@ -791,6 +996,14 @@ tcapsrt_call_matching(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
tcap_context=tcaphash_end_matching(tvb, pinfo, tree, p_tcapsrt_info);
break;
+ case TC_ANSI_ALL:
+ case TC_ANSI_ABORT:
+#ifdef DEBUG_TCAPSRT
+ dbg(1,"TC_ANSI ");
+#endif
+ tcap_context=tcaphash_ansi_matching(tvb, pinfo, tree, p_tcapsrt_info);
+ break;
+
default:
#ifdef DEBUG_TCAPSRT
dbg(1,"Unknow %d ", p_tcapsrt_info->ope);
@@ -819,9 +1032,11 @@ tcaphash_begin_matching(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
{
struct tcaphash_context_t *p_tcaphash_context=NULL;
struct tcaphash_context_key_t tcaphash_context_key;
- struct tcaphash_begincall_t *p_tcaphash_begincall, *p_new_tcaphash_begincall;
+ struct tcaphash_begincall_t *p_tcaphash_begincall, *p_new_tcaphash_begincall=NULL;
struct tcaphash_begin_info_key_t tcaphash_begin_key;
proto_item *pi;
+ proto_item *stat_item=NULL;
+ proto_tree *stat_tree=NULL;
/* prepare the key data */
tcaphash_begin_key.tid = p_tcapsrt_info->src_tid;
@@ -836,9 +1051,10 @@ tcaphash_begin_matching(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
dbg(51,"PC %s %s ",address_to_str(&pinfo->src), address_to_str(&pinfo->dst));
dbg(51,"Tid %lx ",tcaphash_begin_key.tid);
#endif
+
p_tcaphash_begincall = (struct tcaphash_begincall_t *)
- g_hash_table_lookup(tcaphash_begin, &tcaphash_begin_key);
-
+ g_hash_table_lookup(tcaphash_begin, &tcaphash_begin_key);
+
if (p_tcaphash_begincall) {
/* Walk through list of transaction with identical keys */
do {
@@ -851,10 +1067,10 @@ tcaphash_begin_matching(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
p_tcaphash_context=p_tcaphash_begincall->context;
break;
}
- /* If the last record for Tcap transaction with identifier has been reached */
+ /* If the last record for Tcap transaction with identifier has not been reached */
if (!p_tcaphash_begincall->next_begincall) {
/* check if we have to create a new record or not */
- /* if last request has been responded (response number in known)
+ /* if last request has been responded (response number is known)
and this request appears after last response (has bigger frame number)
and last request occured after the timeout for repetition,
or
@@ -879,19 +1095,21 @@ tcaphash_begin_matching(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
#endif
tcaphash_context_key.session_id = tcapsrt_global_SessionId++;
p_tcaphash_context = new_tcaphash_context(&tcaphash_context_key, pinfo);
+
p_new_tcaphash_begincall = append_tcaphash_begincall(p_tcaphash_begincall,
p_tcaphash_context,
pinfo);
-
#ifdef DEBUG_TCAPSRT
dbg(12,"Update key %lx ",tcaphash_begin_key.hashKey);
#endif
update_tcaphash_begincall(p_new_tcaphash_begincall, pinfo);
p_tcaphash_begincall=p_new_tcaphash_begincall;
- } else {
+ } else { /* timeout or message lost */
/* If the Tid is reused for a closed Transaction */
- /* Or if we received an InitialDP for a non closed Transaction */
+ /* Or if we received an TC_BEGIN for a Transaction marked as "closed" */
+ /* (this is the case, for pre-arranged END, the transaction is marked as closed */
+ /* by the upper layer, thank to a callback method close) */
if ( p_tcaphash_begincall->context->closed) {
#ifdef DEBUG_TCAPSRT
dbg(12,"(closed) Append key %lu ",tcaphash_begin_key.hashKey);
@@ -910,29 +1128,41 @@ tcaphash_begin_matching(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
p_tcaphash_begincall=p_new_tcaphash_begincall;
} else {
- /* No, so it's a duplicate request.Mark it as such. */
-#ifdef DEBUG_TCAPSRT
- dbg(21,"Display_duplicate ");
-#endif
- if (gtcap_DisplaySRT) {
- pi = proto_tree_add_uint_hidden(tree, hf_tcapsrt_Duplicate, tvb, 0,0, p_tcapsrt_info->src_tid);
+ /* the TCAP session is not closed, so, either messages have been lost */
+ /* or it's a duplicate request. Mark it as such. */
+#ifdef DEBUG_TCAPSRT
+ dbg(21,"Display_duplicate %d ",p_tcaphash_begincall->context->first_frame);
+#endif
+ p_tcaphash_context=p_tcaphash_begincall->context;
+ if (gtcap_DisplaySRT && tree) {
+ stat_item = proto_tree_add_text(tree, tvb, 0, -1, "Stat");
+ PROTO_ITEM_SET_GENERATED(stat_item);
+ stat_tree = proto_item_add_subtree(stat_item, ett_tcap_stat);
+ pi = proto_tree_add_uint_format(stat_tree, hf_tcapsrt_Duplicate, tvb, 0, 0,
+ p_tcaphash_context->first_frame,
+ "Duplicate with session %u in frame %u",
+ p_tcaphash_context->session_id,p_tcaphash_context->first_frame);
PROTO_ITEM_SET_GENERATED(pi);
}
- p_tcaphash_context=p_tcaphash_begincall->context;
- } /* test with Timeout */
- } /* closed */
+ return p_tcaphash_context;
+ } /* Previous session closed */
+ } /* test with Timeout or message Lost */
break;
} /* Next call is NULL */
+ /* Repeat the tests for the next record with the same transaction identifier */
p_tcaphash_begincall = p_tcaphash_begincall->next_begincall;
} while (p_tcaphash_begincall != NULL );
/*
- * New TCAP context
+ * End of analyze for the list be TC_BEGIN with same transaction ID
*/
} else { /* p_tcaphash_begincall has not been found */
+ /*
+ * Create a new TCAP context
+ */
#ifdef DEBUG_TCAPSRT
dbg(10,"New key %lx ",tcaphash_begin_key.hashKey);
#endif
-
+
tcaphash_context_key.session_id = tcapsrt_global_SessionId++;
p_tcaphash_context = new_tcaphash_context(&tcaphash_context_key, pinfo);
p_tcaphash_begincall = new_tcaphash_begin(&tcaphash_begin_key, p_tcaphash_context);
@@ -945,34 +1175,40 @@ tcaphash_begin_matching(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
}
/* display tcap session, if available */
- if ( gtcap_DisplaySRT &&
+ if ( gtcap_DisplaySRT && tree &&
p_tcaphash_context &&
p_tcaphash_context->session_id) {
- pi = proto_tree_add_uint(tree, hf_tcapsrt_SessionId, tvb, 0,0, p_tcaphash_context->session_id);
+ stat_item = proto_tree_add_text(tree, tvb, 0, 0, "Stat");
+ PROTO_ITEM_SET_GENERATED(stat_item);
+ stat_tree = proto_item_add_subtree(stat_item, ett_tcap_stat);
+ pi = proto_tree_add_uint(stat_tree, hf_tcapsrt_SessionId, tvb, 0,0, p_tcaphash_context->session_id);
PROTO_ITEM_SET_GENERATED(pi);
- }
-
- /* add link to response frame, if available */
- if( gtcap_DisplaySRT &&
- p_tcaphash_begincall->context->last_frame != 0){
+ /* add link to response frame, if available */
+ /* p_tcaphash_begincall->context->last_frame) */
+ if( p_tcaphash_context->last_frame != 0 ){
#ifdef DEBUG_TCAPSRT
- dbg(20,"Display_frameRsplink %d ",p_tcaphash_begincall->context->last_frame);
+ dbg(20,"Display_frameRsplink %d ",p_tcaphash_context->last_frame);
#endif
- pi = proto_tree_add_uint_format(tree, hf_tcapsrt_BeginSession, tvb, 0, 0,
- p_tcaphash_begincall->context->last_frame,
- "End of session in frame %u",
- p_tcaphash_begincall->context->last_frame);
- PROTO_ITEM_SET_GENERATED(pi);
+ pi = proto_tree_add_uint_format(stat_tree, hf_tcapsrt_BeginSession, tvb, 0, 0,
+ p_tcaphash_context->last_frame,
+ "End of session in frame %u",
+ p_tcaphash_context->last_frame);
+ PROTO_ITEM_SET_GENERATED(pi);
+ }
}
return p_tcaphash_context;
}
-/*
- * Register the request, and try to find the response
- *
- */
+/*
+* Try to find a TCAP session according to the source and destination
+* Identifier given in the TC_CONT
+* If nothing is found, it is probably a session in opening state, so try to find
+* a tcap session registered with a TC_BEGIN "key", matching the destination Id of the TC_CONT
+* Then associate the TC_CONT "key" to the TCAP context, and create a TC_END "key"
+* and display the available info for the TCAP context
+*/
static struct tcaphash_context_t *
tcaphash_cont_matching(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
struct tcapsrt_info_t *p_tcapsrt_info)
@@ -980,7 +1216,13 @@ tcaphash_cont_matching(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
struct tcaphash_context_t *p_tcaphash_context=NULL;
struct tcaphash_contcall_t *p_tcaphash_contcall;
struct tcaphash_cont_info_key_t tcaphash_cont_key;
+ struct tcaphash_begin_info_key_t tcaphash_begin_key;
+ struct tcaphash_begincall_t *p_tcaphash_begincall;
+ struct tcaphash_end_info_key_t tcaphash_end_key;
+ struct tcaphash_endcall_t *p_tcaphash_endcall;
proto_item *pi;
+ proto_item *stat_item=NULL;
+ proto_tree *stat_tree=NULL;
#ifdef DEBUG_TCAPSRT
dbg(10,"\n Hcont #%u ", pinfo->fd->num);
@@ -1004,16 +1246,11 @@ tcaphash_cont_matching(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
dbg(12,"CFound ");
#endif
p_tcaphash_context=p_tcaphash_contcall->context;
- } else { /* Not found */
+ } else { /* cont not found */
#ifdef DEBUG_TCAPSRT
dbg(12,"CnotFound ");
#endif
- struct tcaphash_begin_info_key_t tcaphash_begin_key;
- struct tcaphash_begincall_t *p_tcaphash_begincall;
-
- struct tcaphash_end_info_key_t tcaphash_end_key;
- struct tcaphash_endcall_t *p_tcaphash_endcall;
-
+ /* Find the TCAP transaction according to the TC_BEGIN */
tcaphash_begin_key.tid = p_tcapsrt_info->dst_tid;
tcaphash_begin_key.opc_hash=mtp3_pc_hash((const mtp3_addr_pc_t *)pinfo->src.data);
tcaphash_begin_key.dpc_hash=mtp3_pc_hash((const mtp3_addr_pc_t *)pinfo->dst.data);
@@ -1035,14 +1272,11 @@ tcaphash_cont_matching(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
#ifdef DEBUG_TCAPSRT
dbg(10,"New Ckey %lx ",tcaphash_cont_key.hashKey);
+ dbg(11,"Frame reqlink #%u ", pinfo->fd->num);
#endif
p_tcaphash_contcall = create_tcaphash_cont(&tcaphash_cont_key,
p_tcaphash_begincall->context);
-#ifdef DEBUG_TCAPSRT
- dbg(11,"Update Ckey %lx ",tcaphash_begin_key.hashKey);
- dbg(11,"Frame reqlink #%u ", pinfo->fd->num);
-#endif
tcaphash_end_key.tid = p_tcapsrt_info->src_tid;
tcaphash_end_key.opc_hash=mtp3_pc_hash((const mtp3_addr_pc_t *)pinfo->src.data);
tcaphash_end_key.dpc_hash=mtp3_pc_hash((const mtp3_addr_pc_t *)pinfo->dst.data);
@@ -1050,14 +1284,11 @@ tcaphash_cont_matching(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
#ifdef DEBUG_TCAPSRT
dbg(10,"New Ekey %lx ",tcaphash_end_key.hashKey);
+ dbg(11,"Frame reqlink #%u ", pinfo->fd->num);
#endif
p_tcaphash_endcall = create_tcaphash_end(&tcaphash_end_key,
p_tcaphash_begincall->context);
-#ifdef DEBUG_TCAPSRT
- dbg(11,"Update Ekey %lx ",tcaphash_end_key.hashKey);
- dbg(11,"Frame reqlink #%u ", pinfo->fd->num);
-#endif
} else { /* Begin not found */
#ifdef DEBUG_TCAPSRT
dbg(12,"BnotFound ");
@@ -1065,22 +1296,30 @@ tcaphash_cont_matching(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
} /* begin found */
} /* cont found */
/* display tcap session, if available */
- if (gtcap_DisplaySRT &&
+ if (gtcap_DisplaySRT && tree &&
p_tcaphash_context &&
- p_tcaphash_context->session_id) {
- pi = proto_tree_add_uint(tree, hf_tcapsrt_SessionId, tvb, 0,0, p_tcaphash_context->session_id);
+ p_tcaphash_context->session_id) {
+ stat_item = proto_tree_add_text(tree, tvb, 0, -1, "Stat");
+ PROTO_ITEM_SET_GENERATED(stat_item);
+ stat_tree = proto_item_add_subtree(stat_item, ett_tcap_stat);
+ pi = proto_tree_add_uint(stat_tree, hf_tcapsrt_SessionId, tvb, 0,0, p_tcaphash_context->session_id);
PROTO_ITEM_SET_GENERATED(pi);
}
-
+
return p_tcaphash_context;
}
+/*
+* Try to find a TCAP session according to the destination Identifier given in the TC_END/TC_ABORT
+* If nothing is found,
+* - either it is a session in opening state,
+* - or the session is closed/aborted by the remote, ( so we switch the src and dst tid )
+* so try to find a tcap session registered with a TC_BEGIN "key",
+* matching the destination Id of the TC_END
+* Then associate the TC_CONT "key" to the TCAP context
+* and display the available info for the TCAP context
+*/
-
-/*
- *
- *
- */
static struct tcaphash_context_t *
tcaphash_end_matching(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
struct tcapsrt_info_t *p_tcapsrt_info)
@@ -1094,7 +1333,8 @@ tcaphash_end_matching(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
struct tcaphash_begincall_t *p_tcaphash_begincall=NULL;
proto_item *pi;
nstime_t delta;
-
+ proto_item *stat_item=NULL;
+ proto_tree *stat_tree=NULL;
#ifdef DEBUG_TCAPSRT
dbg(10,"\n Hend #%u ", pinfo->fd->num);
@@ -1127,8 +1367,12 @@ tcaphash_end_matching(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
dbg(51,"Tid %lx ",tcaphash_begin_key.tid);
#endif
p_tcaphash_begincall = find_tcaphash_begin(&tcaphash_begin_key, pinfo,FALSE);
+ if(!p_tcaphash_begincall) {
+#ifdef DEBUG_TCAPSRT
+ dbg(12,"BnotFound ");
+#endif
+ }
}
-
if (p_tcaphash_endcall) {
/* Use the TC_BEGIN Destination reference */
p_tcaphash_context=p_tcaphash_endcall->context;
@@ -1136,14 +1380,18 @@ tcaphash_end_matching(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
/* Use the TC_BEGIN Source reference */
p_tcaphash_context=p_tcaphash_begincall->context;
}
-
+
if (p_tcaphash_context) {
-
+
#ifdef DEBUG_TCAPSRT
dbg(12,"Found, req=%d ",p_tcaphash_context->first_frame);
#endif
- if (gtcap_DisplaySRT) {
- pi = proto_tree_add_uint(tree, hf_tcapsrt_SessionId, tvb, 0,0, p_tcaphash_context->session_id);
+ if (gtcap_DisplaySRT && tree) {
+ stat_item = proto_tree_add_text(tree, tvb, 0, -1, "Stat");
+ PROTO_ITEM_SET_GENERATED(stat_item);
+ stat_tree = proto_item_add_subtree(stat_item, ett_tcap_stat);
+
+ pi = proto_tree_add_uint(stat_tree, hf_tcapsrt_SessionId, tvb, 0,0, p_tcaphash_context->session_id);
PROTO_ITEM_SET_GENERATED(pi);
}
@@ -1151,8 +1399,8 @@ tcaphash_end_matching(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
dbg(20,"Display framereqlink %d ",p_tcaphash_context->first_frame);
#endif
/* Indicate the frame to which this is a reply. */
- if (gtcap_DisplaySRT) {
- pi = proto_tree_add_uint_format(tree, hf_tcapsrt_EndSession, tvb, 0, 0,
+ if (gtcap_DisplaySRT && stat_tree) {
+ pi = proto_tree_add_uint_format(stat_tree, hf_tcapsrt_EndSession, tvb, 0, 0,
p_tcaphash_context->first_frame,
"Begin of session in frame %u",
p_tcaphash_context->first_frame);
@@ -1161,17 +1409,291 @@ tcaphash_end_matching(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
nstime_delta(&delta, &pinfo->fd->abs_ts, &p_tcaphash_context->begin_time);
/* display Service Response Time and make it filterable */
- pi = proto_tree_add_time(tree, hf_tcapsrt_SessionTime, tvb, 0, 0, &delta);
+ pi = proto_tree_add_time(stat_tree, hf_tcapsrt_SessionTime, tvb, 0, 0, &delta);
PROTO_ITEM_SET_GENERATED(pi);
}
- /* Close the context and remove it */
+ /* Close the context and remove it (if needed) */
tcapsrt_close(p_tcaphash_context,pinfo);
- } /* context present */
+ } else {/* context present */
+#ifdef DEBUG_TCAPSRT
+ dbg(12,"Context notFound ");
+#endif
+ }
return p_tcaphash_context;
}
/*
+ * ANSI PART
+ * Create the record identifiying the TCAP transaction
+ * When the identifier for the transaction is reused, check
+ * the following criteria before to append a new record:
+ * - a timeout corresponding to a message retransmission is detected,
+ * - a message hast been lost
+ * - or the previous transaction has been be closed
+ */
+static struct tcaphash_context_t *
+tcaphash_ansi_matching(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
+ struct tcapsrt_info_t *p_tcapsrt_info)
+{
+ struct tcaphash_context_t *p_tcaphash_context=NULL;
+ struct tcaphash_context_key_t tcaphash_context_key;
+ struct tcaphash_ansicall_t *p_tcaphash_ansicall, *p_new_tcaphash_ansicall;
+ struct tcaphash_ansi_info_key_t tcaphash_ansi_key;
+ proto_item *pi;
+ nstime_t delta;
+ gboolean isResponse=FALSE;
+ proto_tree * stat_tree=NULL;
+ proto_item * stat_item=NULL;
+
+ /* prepare the key data */
+ tcaphash_ansi_key.tid = p_tcapsrt_info->src_tid;
+ tcaphash_ansi_key.opc_hash = mtp3_pc_hash((const mtp3_addr_pc_t *)pinfo->src.data);
+ tcaphash_ansi_key.dpc_hash = mtp3_pc_hash((const mtp3_addr_pc_t *)pinfo->dst.data);
+ tcaphash_ansi_key.hashKey=tcaphash_ansi_calchash(&tcaphash_ansi_key);
+
+ /* look up the request */
+#ifdef DEBUG_TCAPSRT
+ dbg(10,"\n Hansi #%u ", pinfo->fd->num);
+ dbg(11,"key %lx ",tcaphash_ansi_key.hashKey);
+ dbg(51,"PC %s %s ",address_to_str(&pinfo->src), address_to_str(&pinfo->dst));
+ dbg(51,"Tid %lx ",tcaphash_ansi_key.tid);
+#endif
+ p_tcaphash_ansicall = (struct tcaphash_ansicall_t *)
+ g_hash_table_lookup(tcaphash_ansi, &tcaphash_ansi_key);
+
+ if (p_tcaphash_ansicall) {
+ /* Walk through list of transaction with identical keys */
+ do {
+ /* Check if the request with this reqSeqNum has been seen */
+ if (pinfo->fd->num == p_tcaphash_ansicall->context->first_frame) {
+ /* We have seen this request before -> do nothing */
+#ifdef DEBUG_TCAPSRT
+ dbg(22,"Request already seen ");
+#endif
+ isResponse=FALSE;
+ p_tcaphash_context=p_tcaphash_ansicall->context;
+ break;
+ }
+
+ /* Check if the reponse with this reqSeqNum has been seen */
+ if (pinfo->fd->num == p_tcaphash_ansicall->context->last_frame) {
+ /* We have seen this response before -> do nothing */
+#ifdef DEBUG_TCAPSRT
+ dbg(22,"Response already seen ");
+#endif
+ isResponse=TRUE;
+ p_tcaphash_context=p_tcaphash_ansicall->context;
+ break;
+ }
+
+ /* Check for the first Request without Response
+ received before this frame */
+ if ( pinfo->fd->num > p_tcaphash_ansicall->context->first_frame &&
+ p_tcaphash_ansicall->context->last_frame==0 ) {
+ /* Take it, and update the context */
+
+#ifdef DEBUG_TCAPSRT
+ dbg(12,"Update key %lx ",tcaphash_ansi_key.hashKey);
+#endif
+ p_tcaphash_ansicall->context->last_frame = pinfo->fd->num;
+ p_tcaphash_ansicall->context->responded = TRUE;
+ p_tcaphash_ansicall->context->closed = TRUE;
+ p_tcaphash_context=p_tcaphash_ansicall->context;
+ isResponse=TRUE;
+
+ if (gtcap_DisplaySRT && tree) {
+ stat_item = proto_tree_add_text(tree, tvb, 0, -1, "Stat");
+ PROTO_ITEM_SET_GENERATED(stat_item);
+ stat_tree = proto_item_add_subtree(stat_item, ett_tcap_stat);
+
+ pi = proto_tree_add_uint(stat_tree, hf_tcapsrt_SessionId, tvb, 0,0, p_tcaphash_context->session_id);
+ PROTO_ITEM_SET_GENERATED(pi);
+
+#ifdef DEBUG_TCAPSRT
+ dbg(20,"Display framereqlink %d ",p_tcaphash_context->first_frame);
+#endif
+ /* Indicate the frame to which this is a reply. */
+ pi = proto_tree_add_uint_format(stat_tree, hf_tcapsrt_EndSession, tvb, 0, 0,
+ p_tcaphash_context->first_frame,
+ "Begin of session in frame %u",
+ p_tcaphash_context->first_frame);
+ PROTO_ITEM_SET_GENERATED(pi);
+ /* Calculate Service Response Time */
+ nstime_delta(&delta, &pinfo->fd->abs_ts, &p_tcaphash_context->begin_time);
+
+ /* display Service Response Time and make it filterable */
+ pi = proto_tree_add_time(stat_tree, hf_tcapsrt_SessionTime, tvb, 0, 0, &delta);
+ PROTO_ITEM_SET_GENERATED(pi);
+ }
+ break;
+ } /* Lastframe=0, so take it */
+
+
+ /* If the last record for Tcap transaction with identifier has been reached */
+ if (!p_tcaphash_ansicall->next_ansicall) {
+ /* check if we have to create a new record or not */
+ /* if last request has been responded (response number in known)
+ and this request appears after last response (has bigger frame number)
+ and last request occured after the timeout for repetition,
+ or
+ if last request hasn't been responded (so number unknown)
+ and this request appears after last request (has bigger frame number)
+ and this request occured after the timeout for message lost */
+ if ( ( p_tcaphash_ansicall->context->last_frame != 0
+ && pinfo->fd->num > p_tcaphash_ansicall->context->first_frame
+ && (guint) pinfo->fd->abs_ts.secs > (guint)(p_tcaphash_ansicall->context->begin_time.secs + gtcap_RepetitionTimeout)
+ ) ||
+ ( p_tcaphash_ansicall->context->last_frame == 0
+ && pinfo->fd->num > p_tcaphash_ansicall->context->first_frame
+ && (guint)pinfo->fd->abs_ts.secs > (guint)(p_tcaphash_ansicall->context->begin_time.secs + gtcap_LostTimeout)
+ )
+ )
+ {
+ /* we decide that we have a new request */
+ /* Append new record to the list */
+#ifdef DEBUG_TCAPSRT
+ dbg(12,"(timeout) Append key %lx ",tcaphash_ansi_key.hashKey);
+ dbg(12,"Frame %u rsp %u ",pinfo->fd->num,p_tcaphash_ansicall->context->last_frame );
+#endif
+ tcaphash_context_key.session_id = tcapsrt_global_SessionId++;
+ p_tcaphash_context = new_tcaphash_context(&tcaphash_context_key, pinfo);
+ p_new_tcaphash_ansicall = append_tcaphash_ansicall(p_tcaphash_ansicall,
+ p_tcaphash_context,
+ pinfo);
+
+#ifdef DEBUG_TCAPSRT
+ dbg(12,"Update key %lx ",tcaphash_ansi_key.hashKey);
+#endif
+ update_tcaphash_ansicall(p_new_tcaphash_ansicall, pinfo);
+ p_tcaphash_ansicall=p_new_tcaphash_ansicall;
+ } else {
+
+ /* If the Tid is reused for a closed Transaction */
+ if ( p_tcaphash_ansicall->context->closed) {
+#ifdef DEBUG_TCAPSRT
+ dbg(12,"(closed) Append key %lu ",tcaphash_ansi_key.hashKey);
+ dbg(12,"Frame %u rsp %u ",pinfo->fd->num,p_tcaphash_ansicall->context->last_frame );
+#endif
+ tcaphash_context_key.session_id = tcapsrt_global_SessionId++;
+ p_tcaphash_context = new_tcaphash_context(&tcaphash_context_key, pinfo);
+ p_new_tcaphash_ansicall = append_tcaphash_ansicall(p_tcaphash_ansicall,
+ p_tcaphash_context,
+ pinfo);
+
+#ifdef DEBUG_TCAPSRT
+ dbg(12,"Update key %lu ",tcaphash_ansi_key.hashKey);
+#endif
+ update_tcaphash_ansicall(p_new_tcaphash_ansicall, pinfo);
+ p_tcaphash_ansicall=p_new_tcaphash_ansicall;
+
+ } else {
+ /* the Tid is reused for an opened Transaction */
+ /* so, this is the reply to the request of our context */
+ p_tcaphash_context=p_tcaphash_ansicall->context;
+#ifdef DEBUG_TCAPSRT
+ dbg(12,"Found, req=%d ",p_tcaphash_context->first_frame);
+#endif
+
+ if (gtcap_DisplaySRT && tree) {
+ stat_item = proto_tree_add_text(tree, tvb, 0, -1, "Stat");
+ PROTO_ITEM_SET_GENERATED(stat_item);
+ stat_tree = proto_item_add_subtree(stat_item, ett_tcap_stat);
+
+ pi = proto_tree_add_uint(stat_tree, hf_tcapsrt_SessionId, tvb, 0,0, p_tcaphash_context->session_id);
+ PROTO_ITEM_SET_GENERATED(pi);
+
+#ifdef DEBUG_TCAPSRT
+ dbg(20,"Display framereqlink %d ",p_tcaphash_context->first_frame);
+#endif
+ /* Indicate the frame to which this is a reply. */
+ pi = proto_tree_add_uint_format(stat_tree, hf_tcapsrt_EndSession, tvb, 0, 0,
+ p_tcaphash_context->first_frame,
+ "Begin of session in frame %u",
+ p_tcaphash_context->first_frame);
+ PROTO_ITEM_SET_GENERATED(pi);
+ /* Calculate Service Response Time */
+ nstime_delta(&delta, &pinfo->fd->abs_ts, &p_tcaphash_context->begin_time);
+
+ /* display Service Response Time and make it filterable */
+ pi = proto_tree_add_time(stat_tree, hf_tcapsrt_SessionTime, tvb, 0, 0, &delta);
+ PROTO_ITEM_SET_GENERATED(pi);
+ }
+ p_tcaphash_context=p_tcaphash_ansicall->context;
+ } /* test with Timeout */
+ } /* closed */
+ break;
+ } /* Next call is NULL */
+ p_tcaphash_ansicall = p_tcaphash_ansicall->next_ansicall;
+ } while (p_tcaphash_ansicall != NULL );
+ /*
+ * New TCAP context
+ */
+ } else { /* p_tcaphash_ansicall has not been found */
+#ifdef DEBUG_TCAPSRT
+ dbg(10,"New key %lx ",tcaphash_ansi_key.hashKey);
+#endif
+
+ tcaphash_context_key.session_id = tcapsrt_global_SessionId++;
+ p_tcaphash_context = new_tcaphash_context(&tcaphash_context_key, pinfo);
+ p_tcaphash_ansicall = new_tcaphash_ansi(&tcaphash_ansi_key, p_tcaphash_context);
+
+#ifdef DEBUG_TCAPSRT
+ dbg(11,"Update key %lx ",tcaphash_ansi_key.hashKey);
+ dbg(11,"Frame reqlink #%u ", pinfo->fd->num);
+#endif
+ update_tcaphash_ansicall(p_tcaphash_ansicall, pinfo);
+ }
+
+ /* display tcap session, if available */
+ if ( gtcap_DisplaySRT && tree &&
+ p_tcaphash_context &&
+ p_tcaphash_context->session_id) {
+ stat_item = proto_tree_add_text(tree, tvb, 0, -1, "Stat");
+ PROTO_ITEM_SET_GENERATED(stat_item);
+ stat_tree = proto_item_add_subtree(stat_item, ett_tcap_stat);
+ pi = proto_tree_add_uint(stat_tree, hf_tcapsrt_SessionId, tvb, 0,0, p_tcaphash_context->session_id);
+ PROTO_ITEM_SET_GENERATED(pi);
+ }
+
+
+ /* add link to response frame, if available */
+ if( gtcap_DisplaySRT && stat_tree &&
+ p_tcaphash_ansicall->context->last_frame != 0){
+ if (!isResponse) { /* Request */
+#ifdef DEBUG_TCAPSRT
+ dbg(20,"Display_frameRsplink %d ",p_tcaphash_ansicall->context->last_frame);
+#endif
+ pi = proto_tree_add_uint_format(stat_tree, hf_tcapsrt_BeginSession, tvb, 0, 0,
+ p_tcaphash_ansicall->context->last_frame,
+ "End of session in frame %u",
+ p_tcaphash_ansicall->context->last_frame);
+ PROTO_ITEM_SET_GENERATED(pi);
+ } else { /* Response */
+#ifdef DEBUG_TCAPSRT
+ dbg(20,"Display framereqlink %d ",p_tcaphash_context->first_frame);
+#endif
+ /* Indicate the frame to which this is a reply. */
+ if (gtcap_DisplaySRT) {
+ pi = proto_tree_add_uint_format(stat_tree, hf_tcapsrt_EndSession, tvb, 0, 0,
+ p_tcaphash_context->first_frame,
+ "Begin of session in frame %u",
+ p_tcaphash_context->first_frame);
+ PROTO_ITEM_SET_GENERATED(pi);
+ /* Calculate Service Response Time */
+ nstime_delta(&delta, &pinfo->fd->abs_ts, &p_tcaphash_context->begin_time);
+
+ /* display Service Response Time and make it filterable */
+ pi = proto_tree_add_time(stat_tree, hf_tcapsrt_SessionTime, tvb, 0, 0, &delta);
+ PROTO_ITEM_SET_GENERATED(pi);
+ }
+ } /* Request or Response */
+ }
+ return p_tcaphash_context;
+}
+
+
+/*
* Initialize the Message Info used by the main dissector
* Data are linked to a TCAP transaction
*/
@@ -1206,50 +1728,154 @@ tcapsrt_close(struct tcaphash_context_t *p_tcaphash_context,
p_tcaphash_context->closed=TRUE;
/* If the endkey is present */
- if ( p_tcaphash_context->endcall
- && !gtcap_PersistentSRT ) {
+ if (p_tcaphash_context->endcall
+ && !gtcap_PersistentSRT) {
+ if (p_tcaphash_context->endcall->next_endcall) {
+ if (p_tcaphash_context->endcall->previous_endcall ) {
+#ifdef DEBUG_TCAPSRT
+ dbg(20,"deplace Ehash ");
+#endif
+ p_tcaphash_context->endcall->previous_endcall->next_endcall
+ = p_tcaphash_context->endcall->next_endcall;
+ p_tcaphash_context->endcall->next_endcall->previous_endcall
+ = p_tcaphash_context->endcall->previous_endcall;
+ g_hash_table_remove(tcaphash_end, p_tcaphash_context->endcall->endkey);
+#ifdef MEM_TCAPSRT
+ g_free(p_tcaphash_context->endcall);
+#endif
+ } else {
+ /* cannot remove the father */
#ifdef DEBUG_TCAPSRT
- dbg(20,"remove Ehash ");
+ dbg(20,"father Ehash ");
#endif
- g_hash_table_remove(tcaphash_end, p_tcaphash_context->endcall->endkey);
- }
+ } /* no previous link, so father */
+ } else if (!gtcap_PersistentSRT) {
+#ifdef DEBUG_TCAPSRT
+ dbg(20,"remove Ehash ");
+#endif
+ g_hash_table_remove(tcaphash_end, p_tcaphash_context->endcall->endkey);
+#ifdef MEM_TCAPSRT
+ g_free(p_tcaphash_context->endcall->endkey);
+ g_free(p_tcaphash_context->endcall);
+#endif
+
+ } /* endcall without chained string */
+ } /* no endcall */
+
/* If the contkey is present */
- if ( p_tcaphash_context->contcall
- && !gtcap_PersistentSRT) {
+ if (p_tcaphash_context->contcall
+ && !gtcap_PersistentSRT) {
+ if (p_tcaphash_context->contcall->next_contcall) {
+ if (p_tcaphash_context->contcall->previous_contcall ) {
#ifdef DEBUG_TCAPSRT
- dbg(20,"remove Chash ");
+ dbg(20,"deplace Chash ");
#endif
- g_hash_table_remove(tcaphash_cont, p_tcaphash_context->contcall->contkey);
- }
+ p_tcaphash_context->contcall->previous_contcall->next_contcall
+ = p_tcaphash_context->contcall->next_contcall;
+ p_tcaphash_context->contcall->next_contcall->previous_contcall
+ = p_tcaphash_context->contcall->previous_contcall;
+ g_hash_table_remove(tcaphash_cont, p_tcaphash_context->contcall->contkey);
+#ifdef MEM_TCAPSRT
+ g_free(p_tcaphash_context->contcall);
+#endif
+ } else {
+ /* cannot remove the father */
+#ifdef DEBUG_TCAPSRT
+ dbg(20,"father Chash ");
+#endif
+ } /* no previous link, so father */
+ } else if (!gtcap_PersistentSRT) {
+#ifdef DEBUG_TCAPSRT
+ dbg(20,"remove Chash ");
+#endif
+ g_hash_table_remove(tcaphash_cont, p_tcaphash_context->contcall->contkey);
+#ifdef MEM_TCAPSRT
+ g_free(p_tcaphash_context->contcall->contkey);
+ g_free(p_tcaphash_context->contcall);
+#endif
+ } /* contcall without chained string */
+ } /* no contcall */
+
/* If the beginkey is present */
- if (p_tcaphash_context->begincall->next_begincall) {
- if (p_tcaphash_context->begincall->previous_begincall ) {
+ if (p_tcaphash_context->begincall
+ && !gtcap_PersistentSRT) {
+ if (p_tcaphash_context->begincall->next_begincall) {
+ if (p_tcaphash_context->begincall->previous_begincall ) {
#ifdef DEBUG_TCAPSRT
- dbg(20,"deplace Bhash ");
+ dbg(20,"deplace Bhash ");
#endif
- p_tcaphash_context->begincall->previous_begincall->next_begincall
- = p_tcaphash_context->begincall->next_begincall;
- p_tcaphash_context->begincall->next_begincall->previous_begincall
- = p_tcaphash_context->begincall->previous_begincall;
- } else {
- /* cannot remove the father */
+ p_tcaphash_context->begincall->previous_begincall->next_begincall
+ = p_tcaphash_context->begincall->next_begincall;
+ p_tcaphash_context->begincall->next_begincall->previous_begincall
+ = p_tcaphash_context->begincall->previous_begincall;
+ g_hash_table_remove(tcaphash_begin, p_tcaphash_context->begincall->beginkey);
+#ifdef MEM_TCAPSRT
+ g_free(p_tcaphash_context->begincall);
+#endif
+ } else {
+ /* cannot remove the father */
#ifdef DEBUG_TCAPSRT
- dbg(20,"father Bhash ");
+ dbg(20,"father Bhash ");
#endif
- }
- } else if (!gtcap_PersistentSRT) {
+ }
+ } else if (!gtcap_PersistentSRT) {
+#ifdef DEBUG_TCAPSRT
+ dbg(20,"remove Bhash ");
+#endif
+ g_hash_table_remove(tcaphash_begin, p_tcaphash_context->begincall->beginkey);
+#ifdef MEM_TCAPSRT
+ g_free(p_tcaphash_context->begincall->beginkey);
+ g_free(p_tcaphash_context->begincall);
+#endif
+ } /* begincall without chained string */
+ } /* no begincall */
+
+ /* If the ansikey is present */
+ if (p_tcaphash_context->ansicall
+ && !gtcap_PersistentSRT) {
+ if (p_tcaphash_context->ansicall->next_ansicall) {
+ if (p_tcaphash_context->ansicall->previous_ansicall ) {
+#ifdef DEBUG_TCAPSRT
+ dbg(20,"deplace Ahash ");
+#endif
+ p_tcaphash_context->ansicall->previous_ansicall->next_ansicall
+ = p_tcaphash_context->ansicall->next_ansicall;
+ p_tcaphash_context->ansicall->next_ansicall->previous_ansicall
+ = p_tcaphash_context->ansicall->previous_ansicall;
+ g_hash_table_remove(tcaphash_ansi, p_tcaphash_context->ansicall->ansikey);
+#ifdef MEM_TCAPSRT
+ g_free(p_tcaphash_context->ansicall);
+#endif
+ } else {
+ /* cannot remove the father */
#ifdef DEBUG_TCAPSRT
- dbg(20,"remove Bhash ");
+ dbg(20,"father Ahash ");
#endif
- g_hash_table_remove(tcaphash_begin, p_tcaphash_context->begincall->beginkey);
+ }
+ } else if (!gtcap_PersistentSRT) {
+#ifdef DEBUG_TCAPSRT
+ dbg(20,"remove Ahash ");
+#endif
+ g_hash_table_remove(tcaphash_ansi, p_tcaphash_context->ansicall->ansikey);
+#ifdef MEM_TCAPSRT
+ g_free(p_tcaphash_context->ansicall->ansikey);
+ g_free(p_tcaphash_context->ansicall);
+#endif
+ } /* ansicall without chained string */
+ } /* no ansicall */
+
+ if (!gtcap_PersistentSRT) {
#ifdef DEBUG_TCAPSRT
dbg(20,"remove context ");
#endif
g_hash_table_remove(tcaphash_context, p_tcaphash_context->key);
-
- } /* begincall without chained string */
+#ifdef MEM_TCAPSRT
+ g_free(p_tcaphash_context->key);
+ g_free(p_tcaphash_context);
+#endif
+ }
} else { /* no context */
#ifdef DEBUG_TCAPSRT
dbg(20,"No context to remove ");
diff --git a/epan/tcap-persistentdata.h b/epan/tcap-persistentdata.h
index 2b00df6d6e..9136bf8f74 100644
--- a/epan/tcap-persistentdata.h
+++ b/epan/tcap-persistentdata.h
@@ -8,6 +8,8 @@
* By Gerald Combs <gerald@wireshark.org>
* Copyright 1998 Gerald Combs
*
+ * $Id$
+ *
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
@@ -43,11 +45,13 @@ struct tcaphash_context_t {
gboolean upper_dissector;
gboolean oid_present;
gchar oid[LENGTH_OID+1];
+ gboolean subdissector_present;
dissector_handle_t subdissector_handle;
void (* callback) (tvbuff_t *,packet_info *, proto_tree *, struct tcaphash_context_t *);
struct tcaphash_begincall_t * begincall;
struct tcaphash_contcall_t * contcall;
- struct tcaphash_endcall_t * endcall;
+ struct tcaphash_endcall_t * endcall;
+ struct tcaphash_ansicall_t * ansicall;
};
struct tcaphash_begincall_t {
@@ -74,6 +78,14 @@ struct tcaphash_endcall_t {
struct tcaphash_endcall_t * previous_endcall;
};
+struct tcaphash_ansicall_t {
+ struct tcaphash_ansi_info_key_t * ansikey;
+ struct tcaphash_context_t * context;
+ gboolean father;
+ struct tcaphash_ansicall_t * next_ansicall;
+ struct tcaphash_ansicall_t * previous_ansicall;
+};
+
/* The Key for the hash table is the TCAP origine transaction identifier
of the TC_BEGIN containing the InitialDP */
@@ -103,6 +115,13 @@ struct tcaphash_end_info_key_t {
guint32 dpc_hash;
};
+struct tcaphash_ansi_info_key_t {
+ guint32 hashKey;
+ guint32 tid;
+ guint32 opc_hash;
+ guint32 dpc_hash;
+};
+
/* List of infos to store for the analyse */
struct tcapsrt_info_t {