forked from osmocom/wireshark
Move tcap and camel "persistent data" functionality to the dissectors themselves instead of being part of epan directory.
svn path=/trunk/; revision=54499
This commit is contained in:
parent
94387fdcbd
commit
58346b6327
|
@ -38,7 +38,6 @@
|
|||
#include "packet-ber.h"
|
||||
#include "packet-tcap.h"
|
||||
#include "packet-ansi_tcap.h"
|
||||
#include <epan/tcap-persistentdata.h>
|
||||
|
||||
#define PNAME "ANSI Transaction Capabilities Application Part"
|
||||
#define PSNAME "ANSI_TCAP"
|
||||
|
@ -89,6 +88,13 @@ extern gboolean gtcap_PersistentSRT;
|
|||
extern guint gtcap_RepetitionTimeout;
|
||||
extern guint gtcap_LostTimeout;
|
||||
|
||||
/* When several Tcap components are received in a single TCAP message,
|
||||
we have to use several buffers for the stored parameters
|
||||
because else this data are erased during TAP dissector call */
|
||||
#define MAX_TCAP_INSTANCE 10
|
||||
int tcapsrt_global_current=0;
|
||||
struct tcapsrt_info_t tcapsrt_global_info[MAX_TCAP_INSTANCE];
|
||||
|
||||
static dissector_table_t ber_oid_dissector_table=NULL;
|
||||
static const char * cur_oid;
|
||||
static const char * tcapext_oid;
|
||||
|
|
|
@ -55,8 +55,6 @@
|
|||
#include "packet-gsm_a_common.h"
|
||||
#include "packet-inap.h"
|
||||
#include "packet-tcap.h"
|
||||
#include <epan/camel-persistentdata.h>
|
||||
#include <epan/tcap-persistentdata.h>
|
||||
|
||||
#define PNAME "Camel"
|
||||
#define PSNAME "CAMEL"
|
||||
|
@ -70,6 +68,14 @@ int camel_tap = -1;
|
|||
static guint32 opcode=0;
|
||||
static guint32 errorCode=0;
|
||||
static guint32 camel_ver = 0;
|
||||
|
||||
/* When several Camel components are received in a single TCAP message,
|
||||
we have to use several buffers for the stored parameters
|
||||
because else this data are erased during TAP dissector call */
|
||||
#define MAX_CAMEL_INSTANCE 10
|
||||
static int camelsrt_global_current=0;
|
||||
static struct camelsrt_info_t camelsrt_global_info[MAX_CAMEL_INSTANCE];
|
||||
|
||||
/* ROSE context */
|
||||
static rose_ctx_t camel_rose_ctx;
|
||||
|
||||
|
@ -91,20 +97,20 @@ static int hf_camel_CAMEL_SCIBillingChargingCharacteristics = -1;
|
|||
static int hf_camel_CAMEL_SCIGPRSBillingChargingCharacteristics = -1;
|
||||
static int hf_camel_CAMEL_CallResult = -1;
|
||||
|
||||
/* Used by camel-persistentdata.c */
|
||||
int hf_camelsrt_SessionId=-1;
|
||||
int hf_camelsrt_RequestNumber=-1;
|
||||
int hf_camelsrt_Duplicate=-1;
|
||||
int hf_camelsrt_RequestFrame=-1;
|
||||
int hf_camelsrt_ResponseFrame=-1;
|
||||
int hf_camelsrt_DeltaTime=-1;
|
||||
int hf_camelsrt_SessionTime=-1;
|
||||
int hf_camelsrt_DeltaTime31=-1;
|
||||
int hf_camelsrt_DeltaTime75=-1;
|
||||
int hf_camelsrt_DeltaTime65=-1;
|
||||
int hf_camelsrt_DeltaTime22=-1;
|
||||
int hf_camelsrt_DeltaTime35=-1;
|
||||
int hf_camelsrt_DeltaTime80=-1;
|
||||
/* Used by persistent data */
|
||||
static int hf_camelsrt_SessionId=-1;
|
||||
static int hf_camelsrt_RequestNumber=-1;
|
||||
static int hf_camelsrt_Duplicate=-1;
|
||||
static int hf_camelsrt_RequestFrame=-1;
|
||||
static int hf_camelsrt_ResponseFrame=-1;
|
||||
static int hf_camelsrt_DeltaTime=-1;
|
||||
static int hf_camelsrt_SessionTime=-1;
|
||||
static int hf_camelsrt_DeltaTime31=-1;
|
||||
static int hf_camelsrt_DeltaTime75=-1;
|
||||
static int hf_camelsrt_DeltaTime65=-1;
|
||||
static int hf_camelsrt_DeltaTime22=-1;
|
||||
static int hf_camelsrt_DeltaTime35=-1;
|
||||
static int hf_camelsrt_DeltaTime80=-1;
|
||||
|
||||
#include "packet-camel-hf.c"
|
||||
|
||||
|
@ -118,9 +124,10 @@ static int dissect_camel_CAMEL_AChBillingChargingCharacteristics(gboolean implic
|
|||
static int dissect_camel_CAMEL_AChBillingChargingCharacteristicsV2(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_);
|
||||
static int dissect_camel_CAMEL_CallResult(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_);
|
||||
|
||||
gboolean gcamel_HandleSRT=FALSE;
|
||||
extern gboolean gcamel_PersistentSRT;
|
||||
extern gboolean gcamel_DisplaySRT;
|
||||
static gboolean gcamel_HandleSRT=FALSE;
|
||||
static gboolean gcamel_PersistentSRT=FALSE;
|
||||
static gboolean gcamel_DisplaySRT=FALSE;
|
||||
static gboolean gcamel_StatSRT=FALSE;
|
||||
|
||||
/* Initialize the subtree pointers */
|
||||
static gint ett_camel = -1;
|
||||
|
@ -155,6 +162,10 @@ static guint8 PDPTypeNumber;
|
|||
const char *camel_obj_id = NULL;
|
||||
gboolean is_ExtensionField =FALSE;
|
||||
|
||||
/* Global hash tables*/
|
||||
static GHashTable *srt_calls = NULL;
|
||||
static guint32 camelsrt_global_SessionId=1;
|
||||
|
||||
static int camel_opcode_type;
|
||||
#define CAMEL_OPCODE_INVOKE 1
|
||||
#define CAMEL_OPCODE_RETURN_RESULT 2
|
||||
|
@ -169,6 +180,19 @@ static const value_string camel_Component_vals[] = {
|
|||
{ 0, NULL }
|
||||
};
|
||||
|
||||
const value_string camelSRTtype_naming[]= {
|
||||
{ CAMELSRT_SESSION, "TCAP_Session" },
|
||||
{ CAMELSRT_VOICE_INITIALDP, "InialDP/Continue" },
|
||||
{ CAMELSRT_VOICE_ACR1, "Slice1_ACR/ACH" },
|
||||
{ CAMELSRT_VOICE_ACR2, "Slice2_ACR/ACH" },
|
||||
{ CAMELSRT_VOICE_ACR3, "Slice3_ACR/ACH" },
|
||||
{ CAMELSRT_VOICE_DISC, "EvtRepBSCM/Release" },
|
||||
{ CAMELSRT_SMS_INITIALDP, "InitialDP/ContinueSMS" },
|
||||
{ CAMELSRT_GPRS_INITIALDP, "InitialDP/ContinueGPRS" },
|
||||
{ CAMELSRT_GPRS_REPORT, "EvtRepGPRS/ContinueGPRS" },
|
||||
{ 0,NULL}
|
||||
};
|
||||
|
||||
#if 0
|
||||
static const true_false_string camel_extension_value = {
|
||||
"No Extension",
|
||||
|
@ -281,6 +305,28 @@ static const value_string camel_ectTreatmentIndicator_values[] = {
|
|||
|
||||
#include "packet-camel-table.c"
|
||||
|
||||
/*
|
||||
* DEBUG fonctions
|
||||
*/
|
||||
|
||||
#undef DEBUG_CAMELSRT
|
||||
/* #define DEBUG_CAMELSRT */
|
||||
|
||||
#ifdef DEBUG_CAMELSRT
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
static guint debug_level = 99;
|
||||
|
||||
static void dbg(guint level, char *fmt, ...) {
|
||||
va_list ap;
|
||||
|
||||
if (level > debug_level) return;
|
||||
va_start(ap,fmt);
|
||||
vfprintf(stderr, fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
#endif
|
||||
|
||||
static char camel_number_to_char(int number)
|
||||
{
|
||||
if (number < 10)
|
||||
|
@ -330,6 +376,662 @@ static int dissect_camel_InitialDPArgExtensionV2(gboolean implicit_tag _U_, tvbu
|
|||
|
||||
#include "packet-camel-table2.c"
|
||||
|
||||
/*
|
||||
* Functions needed for Hash-Table
|
||||
*/
|
||||
|
||||
/* compare 2 keys */
|
||||
static gint
|
||||
camelsrt_call_equal(gconstpointer k1, gconstpointer k2)
|
||||
{
|
||||
const struct camelsrt_call_info_key_t *key1 = (const struct camelsrt_call_info_key_t *) k1;
|
||||
const struct camelsrt_call_info_key_t *key2 = (const struct camelsrt_call_info_key_t *) k2;
|
||||
|
||||
return (key1->SessionIdKey == key2->SessionIdKey) ;
|
||||
}
|
||||
|
||||
/* calculate a hash key */
|
||||
static guint
|
||||
camelsrt_call_hash(gconstpointer k)
|
||||
{
|
||||
const struct camelsrt_call_info_key_t *key = (const struct camelsrt_call_info_key_t *) k;
|
||||
return key->SessionIdKey;
|
||||
}
|
||||
|
||||
/*
|
||||
* Find the dialog by Key and Time
|
||||
*/
|
||||
static struct camelsrt_call_t *
|
||||
find_camelsrt_call(struct camelsrt_call_info_key_t *p_camelsrt_call_key)
|
||||
{
|
||||
struct camelsrt_call_t *p_camelsrt_call = NULL;
|
||||
p_camelsrt_call = (struct camelsrt_call_t *)g_hash_table_lookup(srt_calls, p_camelsrt_call_key);
|
||||
|
||||
#ifdef DEBUG_CAMELSRT
|
||||
if(p_camelsrt_call) {
|
||||
dbg(10,"D%d ", p_camelsrt_call->session_id);
|
||||
} else {
|
||||
dbg(23,"Not in hash ");
|
||||
}
|
||||
#endif
|
||||
|
||||
return p_camelsrt_call;
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialize the data per call for the Service Response Time Statistics
|
||||
* Data are linked to a Camel operation in a TCAP transaction
|
||||
*/
|
||||
static void
|
||||
raz_camelsrt_call (struct camelsrt_call_t *p_camelsrt_call)
|
||||
{
|
||||
memset(p_camelsrt_call,0,sizeof(struct camelsrt_call_t));
|
||||
}
|
||||
|
||||
/*
|
||||
* New record to create, to identify a new transaction
|
||||
*/
|
||||
static struct camelsrt_call_t *
|
||||
new_camelsrt_call(struct camelsrt_call_info_key_t *p_camelsrt_call_key)
|
||||
{
|
||||
struct camelsrt_call_info_key_t *p_new_camelsrt_call_key;
|
||||
struct camelsrt_call_t *p_new_camelsrt_call = NULL;
|
||||
|
||||
/* Register the transaction in the hash table
|
||||
with the tcap transaction Id as main Key
|
||||
Once created, this entry will be updated later */
|
||||
|
||||
p_new_camelsrt_call_key = se_new(struct camelsrt_call_info_key_t);
|
||||
p_new_camelsrt_call_key->SessionIdKey = p_camelsrt_call_key->SessionIdKey;
|
||||
p_new_camelsrt_call = se_new(struct camelsrt_call_t);
|
||||
raz_camelsrt_call(p_new_camelsrt_call);
|
||||
p_new_camelsrt_call->session_id = camelsrt_global_SessionId++;
|
||||
#ifdef DEBUG_CAMELSRT
|
||||
dbg(10,"D%d ", p_new_camelsrt_call->session_id);
|
||||
#endif
|
||||
/* store it */
|
||||
g_hash_table_insert(srt_calls, p_new_camelsrt_call_key, p_new_camelsrt_call);
|
||||
return p_new_camelsrt_call;
|
||||
}
|
||||
|
||||
/*
|
||||
* Routine called when the TAP is initialized.
|
||||
* so hash table are (re)created
|
||||
*/
|
||||
void
|
||||
camelsrt_init_routine(void)
|
||||
{
|
||||
|
||||
/* free hash-table for SRT */
|
||||
if (srt_calls != NULL) {
|
||||
#ifdef DEBUG_CAMELSRT
|
||||
dbg(16,"Destroy hash ");
|
||||
#endif
|
||||
g_hash_table_destroy(srt_calls);
|
||||
}
|
||||
|
||||
/* create new hash-table for SRT */
|
||||
srt_calls = g_hash_table_new(camelsrt_call_hash, camelsrt_call_equal);
|
||||
#ifdef DEBUG_CAMELSRT
|
||||
dbg(16,"Create hash ");
|
||||
#endif
|
||||
/* Reset the session counter */
|
||||
camelsrt_global_SessionId=1;
|
||||
|
||||
/* The Display of SRT is enable
|
||||
* 1) For wireshark only if Persistent Stat is enable
|
||||
* 2) For Tshark, if the SRT handling is enable
|
||||
*/
|
||||
gcamel_DisplaySRT=gcamel_PersistentSRT || gcamel_HandleSRT&gcamel_StatSRT;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Update a record with the data of the Request
|
||||
*/
|
||||
static void
|
||||
update_camelsrt_call(struct camelsrt_call_t *p_camelsrt_call, packet_info *pinfo,
|
||||
guint msg_category)
|
||||
{
|
||||
p_camelsrt_call->category[msg_category].req_num = pinfo->fd->num;
|
||||
p_camelsrt_call->category[msg_category].rsp_num = 0;
|
||||
p_camelsrt_call->category[msg_category].responded = FALSE;
|
||||
p_camelsrt_call->category[msg_category].req_time = pinfo->fd->abs_ts;
|
||||
}
|
||||
|
||||
/*
|
||||
* Update the Camel session info, and close the session.
|
||||
* Then remove the associated context, if we do not have persistentSRT enable
|
||||
*/
|
||||
static void
|
||||
camelsrt_close_call_matching(packet_info *pinfo,
|
||||
struct camelsrt_info_t *p_camelsrt_info)
|
||||
{
|
||||
struct camelsrt_call_t *p_camelsrt_call;
|
||||
struct camelsrt_call_info_key_t camelsrt_call_key;
|
||||
nstime_t delta;
|
||||
|
||||
p_camelsrt_info->bool_msginfo[CAMELSRT_SESSION]=TRUE;
|
||||
#ifdef DEBUG_CAMELSRT
|
||||
dbg(10,"\n Session end #%u\n", pinfo->fd->num);
|
||||
#endif
|
||||
/* look only for matching request, if matching conversation is available. */
|
||||
camelsrt_call_key.SessionIdKey = p_camelsrt_info->tcap_session_id;
|
||||
|
||||
#ifdef DEBUG_CAMELSRT
|
||||
dbg(11,"Search key %lu ",camelsrt_call_key.SessionIdKey);
|
||||
#endif
|
||||
p_camelsrt_call = find_camelsrt_call(&camelsrt_call_key);
|
||||
if(p_camelsrt_call) {
|
||||
#ifdef DEBUG_CAMELSRT
|
||||
dbg(12,"Found ");
|
||||
#endif
|
||||
/* Calculate Service Response Time */
|
||||
nstime_delta(&delta, &pinfo->fd->abs_ts, &p_camelsrt_call->category[CAMELSRT_SESSION].req_time);
|
||||
p_camelsrt_call->category[CAMELSRT_SESSION].responded = TRUE;
|
||||
p_camelsrt_info->msginfo[CAMELSRT_SESSION].request_available = TRUE;
|
||||
p_camelsrt_info->msginfo[CAMELSRT_SESSION].is_delta_time = TRUE;
|
||||
p_camelsrt_info->msginfo[CAMELSRT_SESSION].delta_time = delta; /* give it to tap */
|
||||
p_camelsrt_info->msginfo[CAMELSRT_SESSION].req_time = p_camelsrt_call->category[CAMELSRT_SESSION].req_time;
|
||||
|
||||
if ( !gcamel_PersistentSRT ) {
|
||||
g_hash_table_remove(srt_calls, &camelsrt_call_key);
|
||||
#ifdef DEBUG_CAMELSRT
|
||||
dbg(20,"remove hash ");
|
||||
#endif
|
||||
} else {
|
||||
#ifdef DEBUG_CAMELSRT
|
||||
dbg(20,"keep hash ");
|
||||
#endif
|
||||
}
|
||||
} /* call reference found */
|
||||
}
|
||||
|
||||
/*
|
||||
* Callback function for the TCAP dissector
|
||||
* This callback function is used to inform the camel layer, that the session
|
||||
* has been Closed or Aborted by a TCAP message without Camel component
|
||||
* So, we can close the context for camel session, and update the stats.
|
||||
*/
|
||||
static void
|
||||
camelsrt_tcap_matching(tvbuff_t *tvb _U_, packet_info *pinfo,
|
||||
proto_tree *tree _U_,
|
||||
struct tcaphash_context_t *p_tcap_context)
|
||||
{
|
||||
struct camelsrt_info_t *p_camelsrt_info;
|
||||
|
||||
#ifdef DEBUG_CAMELSRT
|
||||
dbg(11,"Camel_CallBack ");
|
||||
#endif
|
||||
p_camelsrt_info=camelsrt_razinfo();
|
||||
|
||||
p_camelsrt_info->tcap_context=p_tcap_context;
|
||||
if (p_tcap_context) {
|
||||
#ifdef DEBUG_CAMELSRT
|
||||
dbg(11,"Close TCAP ");
|
||||
#endif
|
||||
p_camelsrt_info->tcap_session_id = p_tcap_context->session_id;
|
||||
camelsrt_close_call_matching(pinfo, p_camelsrt_info);
|
||||
tap_queue_packet(camel_tap, pinfo, p_camelsrt_info);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Create the record identifiying the Camel session
|
||||
* As the Tcap session id given by the TCAP dissector is uniq, it will be
|
||||
* used as main key.
|
||||
*/
|
||||
static void
|
||||
camelsrt_begin_call_matching(packet_info *pinfo,
|
||||
struct camelsrt_info_t *p_camelsrt_info)
|
||||
{
|
||||
struct camelsrt_call_t *p_camelsrt_call;
|
||||
struct camelsrt_call_info_key_t camelsrt_call_key;
|
||||
|
||||
p_camelsrt_info->bool_msginfo[CAMELSRT_SESSION]=TRUE;
|
||||
|
||||
/* prepare the key data */
|
||||
camelsrt_call_key.SessionIdKey = p_camelsrt_info->tcap_session_id;
|
||||
|
||||
/* look up the request */
|
||||
#ifdef DEBUG_CAMELSRT
|
||||
dbg(10,"\n Session begin #%u\n", pinfo->fd->num);
|
||||
dbg(11,"Search key %lu ",camelsrt_call_key.SessionIdKey);
|
||||
#endif
|
||||
p_camelsrt_call = (struct camelsrt_call_t *)g_hash_table_lookup(srt_calls, &camelsrt_call_key);
|
||||
if (p_camelsrt_call) {
|
||||
/* We have seen this request before -> do nothing */
|
||||
#ifdef DEBUG_CAMELSRT
|
||||
dbg(22,"Already seen ");
|
||||
#endif
|
||||
} else { /* p_camelsrt_call has not been found */
|
||||
#ifdef DEBUG_CAMELSRT
|
||||
dbg(10,"New key %lu ",camelsrt_call_key.SessionIdKey);
|
||||
#endif
|
||||
p_camelsrt_call = new_camelsrt_call(&camelsrt_call_key);
|
||||
p_camelsrt_call->tcap_context=(struct tcaphash_context_t *)p_camelsrt_info->tcap_context;
|
||||
update_camelsrt_call(p_camelsrt_call, pinfo,CAMELSRT_SESSION);
|
||||
|
||||
#ifdef DEBUG_CAMELSRT
|
||||
dbg(11,"Update Callback ");
|
||||
#endif
|
||||
p_camelsrt_call->tcap_context->callback=camelsrt_tcap_matching;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Register the request, and try to find the response
|
||||
*
|
||||
*/
|
||||
static void
|
||||
camelsrt_request_call_matching(tvbuff_t *tvb, packet_info *pinfo,
|
||||
proto_tree *tree,
|
||||
struct camelsrt_info_t *p_camelsrt_info,
|
||||
guint srt_type )
|
||||
{
|
||||
struct camelsrt_call_t *p_camelsrt_call;
|
||||
struct camelsrt_call_info_key_t camelsrt_call_key;
|
||||
proto_item *ti, *hidden_item;
|
||||
|
||||
#ifdef DEBUG_CAMELSRT
|
||||
dbg(10,"\n %s #%u\n", val_to_str_const(srt_type, camelSRTtype_naming, "Unk"),pinfo->fd->num);
|
||||
#endif
|
||||
|
||||
/* look only for matching request, if matching conversation is available. */
|
||||
camelsrt_call_key.SessionIdKey = p_camelsrt_info->tcap_session_id;
|
||||
|
||||
#ifdef DEBUG_CAMELSRT
|
||||
dbg(11,"Search key %lu ", camelsrt_call_key.SessionIdKey);
|
||||
#endif
|
||||
p_camelsrt_call = find_camelsrt_call(&camelsrt_call_key);
|
||||
if(p_camelsrt_call) {
|
||||
#ifdef DEBUG_CAMELSRT
|
||||
dbg(12,"Found ");
|
||||
#endif
|
||||
if (gcamel_DisplaySRT)
|
||||
proto_tree_add_uint(tree, hf_camelsrt_SessionId, tvb, 0,0, p_camelsrt_call->session_id);
|
||||
|
||||
|
||||
/* Hmm.. As there are several slices ApplyChargingReport/ApplyCharging
|
||||
* we will prepare the measurement for 3 slices with 3 categories */
|
||||
if (srt_type==CAMELSRT_VOICE_ACR1) {
|
||||
if (p_camelsrt_call->category[CAMELSRT_VOICE_ACR1].req_num == 0) {
|
||||
srt_type=CAMELSRT_VOICE_ACR1;
|
||||
} else if ( (p_camelsrt_call->category[CAMELSRT_VOICE_ACR2].req_num == 0)
|
||||
&& (p_camelsrt_call->category[CAMELSRT_VOICE_ACR1].rsp_num != 0)
|
||||
&& (p_camelsrt_call->category[CAMELSRT_VOICE_ACR1].rsp_num < pinfo->fd->num) ) {
|
||||
srt_type=CAMELSRT_VOICE_ACR2;
|
||||
} else if ( (p_camelsrt_call->category[CAMELSRT_VOICE_ACR3].req_num == 0)
|
||||
&& (p_camelsrt_call->category[CAMELSRT_VOICE_ACR2].rsp_num != 0)
|
||||
&& (p_camelsrt_call->category[CAMELSRT_VOICE_ACR2].rsp_num < pinfo->fd->num) ) {
|
||||
srt_type=CAMELSRT_VOICE_ACR3;
|
||||
} else if (p_camelsrt_call->category[CAMELSRT_VOICE_ACR1].rsp_num != 0
|
||||
&& p_camelsrt_call->category[CAMELSRT_VOICE_ACR1].rsp_num > pinfo->fd->num) {
|
||||
srt_type=CAMELSRT_VOICE_ACR1;
|
||||
} else if ( p_camelsrt_call->category[CAMELSRT_VOICE_ACR2].rsp_num != 0
|
||||
&& p_camelsrt_call->category[CAMELSRT_VOICE_ACR2].rsp_num > pinfo->fd->num) {
|
||||
srt_type=CAMELSRT_VOICE_ACR2;
|
||||
} else if (p_camelsrt_call->category[CAMELSRT_VOICE_ACR1].rsp_num != 0
|
||||
&& p_camelsrt_call->category[CAMELSRT_VOICE_ACR3].rsp_num > pinfo->fd->num) {
|
||||
srt_type=CAMELSRT_VOICE_ACR3;
|
||||
}
|
||||
#ifdef DEBUG_CAMELSRT
|
||||
dbg(70,"Request ACR %u ",srt_type);
|
||||
dbg(70,"ACR1 %u %u",p_camelsrt_call->category[CAMELSRT_VOICE_ACR1].req_num, p_camelsrt_call->category[CAMELSRT_VOICE_ACR1].rsp_num);
|
||||
dbg(70,"ACR2 %u %u",p_camelsrt_call->category[CAMELSRT_VOICE_ACR2].req_num, p_camelsrt_call->category[CAMELSRT_VOICE_ACR2].rsp_num);
|
||||
dbg(70,"ACR3 %u %u",p_camelsrt_call->category[CAMELSRT_VOICE_ACR3].req_num, p_camelsrt_call->category[CAMELSRT_VOICE_ACR3].rsp_num);
|
||||
#endif
|
||||
} /* not ACR */
|
||||
p_camelsrt_info->bool_msginfo[srt_type]=TRUE;
|
||||
|
||||
|
||||
if (p_camelsrt_call->category[srt_type].req_num == 0) {
|
||||
/* We have not yet seen a request to that call, so this must be the first request
|
||||
remember its frame number. */
|
||||
#ifdef DEBUG_CAMELSRT
|
||||
dbg(5,"Set reqlink #%u ", pinfo->fd->num);
|
||||
#endif
|
||||
update_camelsrt_call(p_camelsrt_call, pinfo, srt_type);
|
||||
} else {
|
||||
/* We have seen a request to this call - but was it *this* request? */
|
||||
if (p_camelsrt_call->category[srt_type].req_num != pinfo->fd->num) {
|
||||
|
||||
if (srt_type!=CAMELSRT_VOICE_DISC) {
|
||||
/* No, so it's a duplicate resquest. Mark it as such. */
|
||||
#ifdef DEBUG_CAMELSRT
|
||||
dbg(21,"Display_duplicate with req %d ", p_camelsrt_call->category[srt_type].req_num);
|
||||
#endif
|
||||
p_camelsrt_info->msginfo[srt_type].is_duplicate = TRUE;
|
||||
if (gcamel_DisplaySRT){
|
||||
hidden_item = proto_tree_add_uint(tree, hf_camelsrt_Duplicate, tvb, 0,0, 77);
|
||||
PROTO_ITEM_SET_HIDDEN(hidden_item);
|
||||
}
|
||||
|
||||
} else {
|
||||
/* Ignore duplicate frame */
|
||||
if (pinfo->fd->num > p_camelsrt_call->category[srt_type].req_num) {
|
||||
p_camelsrt_call->category[srt_type].req_num = pinfo->fd->num;
|
||||
#ifdef DEBUG_CAMELSRT
|
||||
dbg(5,"DISC Set reqlink #%u ", pinfo->fd->num);
|
||||
#endif
|
||||
update_camelsrt_call(p_camelsrt_call, pinfo, srt_type);
|
||||
} /* greater frame */
|
||||
} /* DISC */
|
||||
} /* req_num already seen */
|
||||
} /* req_num != 0 */
|
||||
|
||||
/* add link to response frame, if available */
|
||||
if ( gcamel_DisplaySRT &&
|
||||
(p_camelsrt_call->category[srt_type].rsp_num != 0) &&
|
||||
(p_camelsrt_call->category[srt_type].req_num != 0) &&
|
||||
(p_camelsrt_call->category[srt_type].req_num == pinfo->fd->num) ) {
|
||||
#ifdef DEBUG_CAMELSRT
|
||||
dbg(20,"Display_framersplink %d ",p_camelsrt_call->category[srt_type].rsp_num);
|
||||
#endif
|
||||
ti = proto_tree_add_uint_format(tree, hf_camelsrt_RequestFrame, tvb, 0, 0,
|
||||
p_camelsrt_call->category[srt_type].rsp_num,
|
||||
"Linked response %s in frame %u",
|
||||
val_to_str_const(srt_type, camelSRTtype_naming, "Unk"),
|
||||
p_camelsrt_call->category[srt_type].rsp_num);
|
||||
PROTO_ITEM_SET_GENERATED(ti);
|
||||
} /* frame valid */
|
||||
} /* call reference */
|
||||
}
|
||||
|
||||
/*
|
||||
* Display the delta time between two messages in a field corresponding
|
||||
* to the category (hf_camelsrt_DeltaTimexx).
|
||||
*/
|
||||
static void
|
||||
camelsrt_display_DeltaTime(proto_tree *tree, tvbuff_t *tvb, nstime_t *value_ptr,
|
||||
guint category)
|
||||
{
|
||||
proto_item *ti;
|
||||
|
||||
if ( gcamel_DisplaySRT ) {
|
||||
switch(category) {
|
||||
case CAMELSRT_VOICE_INITIALDP:
|
||||
ti = proto_tree_add_time(tree, hf_camelsrt_DeltaTime31, tvb, 0, 0, value_ptr);
|
||||
PROTO_ITEM_SET_GENERATED(ti);
|
||||
break;
|
||||
|
||||
case CAMELSRT_VOICE_ACR1:
|
||||
case CAMELSRT_VOICE_ACR2:
|
||||
case CAMELSRT_VOICE_ACR3:
|
||||
ti = proto_tree_add_time(tree, hf_camelsrt_DeltaTime22, tvb, 0, 0, value_ptr);
|
||||
PROTO_ITEM_SET_GENERATED(ti);
|
||||
break;
|
||||
|
||||
case CAMELSRT_VOICE_DISC:
|
||||
ti = proto_tree_add_time(tree, hf_camelsrt_DeltaTime35, tvb, 0, 0, value_ptr);
|
||||
PROTO_ITEM_SET_GENERATED(ti);
|
||||
break;
|
||||
|
||||
case CAMELSRT_GPRS_INITIALDP:
|
||||
ti = proto_tree_add_time(tree, hf_camelsrt_DeltaTime75, tvb, 0, 0, value_ptr);
|
||||
PROTO_ITEM_SET_GENERATED(ti);
|
||||
break;
|
||||
|
||||
case CAMELSRT_GPRS_REPORT:
|
||||
ti = proto_tree_add_time(tree, hf_camelsrt_DeltaTime80, tvb, 0, 0, value_ptr);
|
||||
PROTO_ITEM_SET_GENERATED(ti);
|
||||
break;
|
||||
|
||||
case CAMELSRT_SMS_INITIALDP:
|
||||
ti = proto_tree_add_time(tree, hf_camelsrt_DeltaTime65, tvb, 0, 0, value_ptr);
|
||||
PROTO_ITEM_SET_GENERATED(ti);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Check if the received message is a response to a previous request
|
||||
* registered is the camel session context.
|
||||
*/
|
||||
static void
|
||||
camelsrt_report_call_matching(tvbuff_t *tvb, packet_info *pinfo,
|
||||
proto_tree *tree,
|
||||
struct camelsrt_info_t *p_camelsrt_info,
|
||||
guint srt_type)
|
||||
{
|
||||
struct camelsrt_call_t *p_camelsrt_call;
|
||||
struct camelsrt_call_info_key_t camelsrt_call_key;
|
||||
nstime_t delta;
|
||||
proto_item *ti, *hidden_item;
|
||||
|
||||
#ifdef DEBUG_CAMELSRT
|
||||
dbg(10,"\n %s #%u\n", val_to_str_const(srt_type, camelSRTtype_naming, "Unk"),pinfo->fd->num);
|
||||
#endif
|
||||
camelsrt_call_key.SessionIdKey = p_camelsrt_info->tcap_session_id;
|
||||
/* look only for matching request, if matching conversation is available. */
|
||||
|
||||
#ifdef DEBUG_CAMELSRT
|
||||
dbg(11,"Search key %lu ",camelsrt_call_key.SessionIdKey);
|
||||
#endif
|
||||
p_camelsrt_call = find_camelsrt_call(&camelsrt_call_key);
|
||||
if(p_camelsrt_call) {
|
||||
#ifdef DEBUG_CAMELSRT
|
||||
dbg(12,"Found, req=%d ",p_camelsrt_call->category[srt_type].req_num);
|
||||
#endif
|
||||
if ( gcamel_DisplaySRT )
|
||||
proto_tree_add_uint(tree, hf_camelsrt_SessionId, tvb, 0,0, p_camelsrt_call->session_id);
|
||||
|
||||
if (srt_type==CAMELSRT_VOICE_ACR1) {
|
||||
if (p_camelsrt_call->category[CAMELSRT_VOICE_ACR3].req_num != 0
|
||||
&& p_camelsrt_call->category[CAMELSRT_VOICE_ACR3].req_num < pinfo->fd->num) {
|
||||
srt_type=CAMELSRT_VOICE_ACR1;
|
||||
} else if ( p_camelsrt_call->category[CAMELSRT_VOICE_ACR2].req_num != 0
|
||||
&& p_camelsrt_call->category[CAMELSRT_VOICE_ACR2].req_num < pinfo->fd->num) {
|
||||
srt_type=CAMELSRT_VOICE_ACR2;
|
||||
} else if (p_camelsrt_call->category[CAMELSRT_VOICE_ACR1].req_num != 0
|
||||
&& p_camelsrt_call->category[CAMELSRT_VOICE_ACR1].req_num < pinfo->fd->num) {
|
||||
srt_type=CAMELSRT_VOICE_ACR1;
|
||||
}
|
||||
#ifdef DEBUG_CAMELSRT
|
||||
dbg(70,"Report ACR %u ",srt_type);
|
||||
#endif
|
||||
} /* not ACR */
|
||||
p_camelsrt_info->bool_msginfo[srt_type]=TRUE;
|
||||
|
||||
if (p_camelsrt_call->category[srt_type].rsp_num == 0) {
|
||||
if ( (p_camelsrt_call->category[srt_type].req_num != 0)
|
||||
&& (pinfo->fd->num > p_camelsrt_call->category[srt_type].req_num) ){
|
||||
/* We have not yet seen a response to that call, so this must be the first response;
|
||||
remember its frame number only if response comes after request */
|
||||
#ifdef DEBUG_CAMELSRT
|
||||
dbg(14,"Set reslink #%d req %u ",pinfo->fd->num, p_camelsrt_call->category[srt_type].req_num);
|
||||
#endif
|
||||
p_camelsrt_call->category[srt_type].rsp_num = pinfo->fd->num;
|
||||
|
||||
} else {
|
||||
#ifdef DEBUG_CAMELSRT
|
||||
dbg(2,"badreslink #%u req %u ",pinfo->fd->num, p_camelsrt_call->category[srt_type].req_num);
|
||||
#endif
|
||||
} /* req_num != 0 */
|
||||
} else { /* rsp_num != 0 */
|
||||
/* We have seen a response to this call - but was it *this* response? */
|
||||
if (p_camelsrt_call->category[srt_type].rsp_num != pinfo->fd->num) {
|
||||
/* No, so it's a duplicate response. Mark it as such. */
|
||||
#ifdef DEBUG_CAMELSRT
|
||||
dbg(21,"Display_duplicate rsp=%d ", p_camelsrt_call->category[srt_type].rsp_num);
|
||||
#endif
|
||||
p_camelsrt_info->msginfo[srt_type].is_duplicate = TRUE;
|
||||
if ( gcamel_DisplaySRT ){
|
||||
hidden_item = proto_tree_add_uint(tree, hf_camelsrt_Duplicate, tvb, 0,0, 77);
|
||||
PROTO_ITEM_SET_HIDDEN(hidden_item);
|
||||
}
|
||||
}
|
||||
} /* rsp_num != 0 */
|
||||
|
||||
if ( (p_camelsrt_call->category[srt_type].req_num != 0) &&
|
||||
(p_camelsrt_call->category[srt_type].rsp_num != 0) &&
|
||||
(p_camelsrt_call->category[srt_type].rsp_num == pinfo->fd->num) ) {
|
||||
|
||||
p_camelsrt_call->category[srt_type].responded = TRUE;
|
||||
p_camelsrt_info->msginfo[srt_type].request_available = TRUE;
|
||||
#ifdef DEBUG_CAMELSRT
|
||||
dbg(20,"Display_frameReqlink %d ",p_camelsrt_call->category[srt_type].req_num);
|
||||
#endif
|
||||
/* Indicate the frame to which this is a reply. */
|
||||
if ( gcamel_DisplaySRT ) {
|
||||
ti = proto_tree_add_uint_format(tree, hf_camelsrt_ResponseFrame, tvb, 0, 0,
|
||||
p_camelsrt_call->category[srt_type].req_num,
|
||||
"Linked request %s in frame %u",
|
||||
val_to_str_const(srt_type, camelSRTtype_naming, "Unk"),
|
||||
p_camelsrt_call->category[srt_type].req_num);
|
||||
PROTO_ITEM_SET_GENERATED(ti);
|
||||
}
|
||||
/* Calculate Service Response Time */
|
||||
nstime_delta(&delta, &pinfo->fd->abs_ts, &p_camelsrt_call->category[srt_type].req_time);
|
||||
|
||||
p_camelsrt_info->msginfo[srt_type].is_delta_time = TRUE;
|
||||
p_camelsrt_info->msginfo[srt_type].delta_time = delta; /* give it to tap */
|
||||
p_camelsrt_info->msginfo[srt_type].req_time = p_camelsrt_call->category[srt_type].req_time;
|
||||
|
||||
/* display Service Response Time and make it filterable */
|
||||
camelsrt_display_DeltaTime(tree, tvb, &delta, srt_type);
|
||||
|
||||
} /*req_num != 0 && not duplicate */
|
||||
} /* call reference found */
|
||||
}
|
||||
|
||||
/*
|
||||
* Service Response Time analyze, called just after the camel dissector
|
||||
* According to the camel operation, we
|
||||
* - open/close a context for the camel session
|
||||
* - look for a request, or look for the corresponding response
|
||||
*/
|
||||
void
|
||||
camelsrt_call_matching(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
|
||||
struct camelsrt_info_t *p_camelsrt_info)
|
||||
{
|
||||
|
||||
#ifdef DEBUG_CAMELSRT
|
||||
dbg(10,"tcap_session #%d ", p_camelsrt_info->tcap_session_id);
|
||||
#endif
|
||||
|
||||
switch (p_camelsrt_info->opcode) {
|
||||
|
||||
case 0: /*InitialDP*/
|
||||
camelsrt_begin_call_matching(pinfo, p_camelsrt_info);
|
||||
camelsrt_request_call_matching(tvb, pinfo, tree, p_camelsrt_info,
|
||||
CAMELSRT_VOICE_INITIALDP);
|
||||
break;
|
||||
case 60: /*InitialDPSMS*/
|
||||
camelsrt_begin_call_matching(pinfo, p_camelsrt_info);
|
||||
camelsrt_request_call_matching(tvb, pinfo, tree, p_camelsrt_info,
|
||||
CAMELSRT_SMS_INITIALDP);
|
||||
break;
|
||||
case 78: /*InitialDPGPRS*/
|
||||
camelsrt_begin_call_matching(pinfo, p_camelsrt_info);
|
||||
camelsrt_request_call_matching(tvb, pinfo, tree, p_camelsrt_info,
|
||||
CAMELSRT_GPRS_INITIALDP);
|
||||
break;
|
||||
|
||||
case 23: /*RequestReportBCSMEvent*/
|
||||
break;
|
||||
|
||||
case 63: /*RequestReportSMSEvent*/
|
||||
break;
|
||||
|
||||
case 81: /*RequestReportGPRSEvent*/
|
||||
break;
|
||||
|
||||
case 24: /*EventReportBCSMEvent*/
|
||||
camelsrt_request_call_matching(tvb, pinfo, tree, p_camelsrt_info,
|
||||
CAMELSRT_VOICE_DISC );
|
||||
break;
|
||||
|
||||
case 64: /*EventReportSMS*/
|
||||
/* Session has been explicity closed without TC_END */
|
||||
camelsrt_close_call_matching(pinfo, p_camelsrt_info);
|
||||
tcapsrt_close((struct tcaphash_context_t *)p_camelsrt_info->tcap_context, pinfo);
|
||||
break;
|
||||
|
||||
case 80: /*EventReportGPRS*/
|
||||
camelsrt_begin_call_matching(pinfo, p_camelsrt_info);
|
||||
camelsrt_request_call_matching(tvb, pinfo, tree, p_camelsrt_info,
|
||||
CAMELSRT_GPRS_REPORT);
|
||||
break;
|
||||
|
||||
case 35: /*ApplyCharging*/
|
||||
camelsrt_report_call_matching(tvb, pinfo, tree, p_camelsrt_info,
|
||||
CAMELSRT_VOICE_ACR1 );
|
||||
break;
|
||||
|
||||
case 71: /*ApplyChargingGPRS*/
|
||||
break;
|
||||
|
||||
case 36: /*ApplyChargingReport*/
|
||||
camelsrt_request_call_matching(tvb, pinfo, tree, p_camelsrt_info,
|
||||
CAMELSRT_VOICE_ACR1 );
|
||||
break;
|
||||
|
||||
case 72: /*ApplyChargingReportGPRS*/
|
||||
break;
|
||||
|
||||
case 31: /*Continue*/
|
||||
camelsrt_report_call_matching(tvb, pinfo, tree, p_camelsrt_info,
|
||||
CAMELSRT_VOICE_INITIALDP);
|
||||
break;
|
||||
case 65: /*ContinueSMS*/
|
||||
camelsrt_report_call_matching(tvb, pinfo, tree, p_camelsrt_info,
|
||||
CAMELSRT_SMS_INITIALDP);
|
||||
break;
|
||||
case 75: /*ContinueGPRS*/
|
||||
camelsrt_report_call_matching(tvb, pinfo, tree, p_camelsrt_info,
|
||||
CAMELSRT_GPRS_INITIALDP);
|
||||
camelsrt_report_call_matching(tvb, pinfo, tree, p_camelsrt_info,
|
||||
CAMELSRT_GPRS_REPORT);
|
||||
break;
|
||||
|
||||
case 22: /*ReleaseCall*/
|
||||
camelsrt_report_call_matching(tvb, pinfo, tree, p_camelsrt_info,
|
||||
CAMELSRT_VOICE_DISC);
|
||||
/* Session has been closed by Network */
|
||||
camelsrt_close_call_matching(pinfo, p_camelsrt_info);
|
||||
break;
|
||||
|
||||
case 66: /*ReleaseSMS*/
|
||||
/* Session has been closed by Network */
|
||||
camelsrt_close_call_matching(pinfo, p_camelsrt_info);
|
||||
tcapsrt_close((struct tcaphash_context_t *)p_camelsrt_info->tcap_context,pinfo);
|
||||
break;
|
||||
|
||||
case 79: /*ReleaseGPRS*/
|
||||
/* Session has been closed by Network */
|
||||
camelsrt_close_call_matching(pinfo, p_camelsrt_info);
|
||||
break;
|
||||
} /* switch opcode */
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialize the Message Info used by the main dissector
|
||||
* Data are linked to a TCAP transaction
|
||||
*/
|
||||
struct camelsrt_info_t *
|
||||
camelsrt_razinfo(void)
|
||||
{
|
||||
struct camelsrt_info_t *p_camelsrt_info ;
|
||||
|
||||
/* Global buffer for packet extraction */
|
||||
camelsrt_global_current++;
|
||||
if(camelsrt_global_current==MAX_CAMEL_INSTANCE){
|
||||
camelsrt_global_current=0;
|
||||
}
|
||||
|
||||
p_camelsrt_info=&camelsrt_global_info[camelsrt_global_current];
|
||||
memset(p_camelsrt_info,0,sizeof(struct camelsrt_info_t));
|
||||
|
||||
p_camelsrt_info->opcode=255;
|
||||
|
||||
return p_camelsrt_info;
|
||||
}
|
||||
|
||||
|
||||
static guint8 camel_pdu_type = 0;
|
||||
static guint8 camel_pdu_size = 0;
|
||||
|
|
|
@ -46,4 +46,103 @@ void proto_register_camel(void);
|
|||
WS_DLL_PUBLIC const value_string camel_opr_code_strings[];
|
||||
/* #include "packet-camel-exp.h"*/
|
||||
|
||||
/** @file
|
||||
*/
|
||||
#define NB_CAMELSRT_CATEGORY 9+1 /**< Number of type of message */
|
||||
/* for example TC_BEGIN with InitalDP, and TC_CONT with RequestReportBCSMEvent
|
||||
is a category, we want to measure the delay between the two messages */
|
||||
|
||||
#define CAMELSRT_SESSION 1
|
||||
|
||||
#define CAMELSRT_VOICE_INITIALDP 2
|
||||
#define CAMELSRT_VOICE_ACR1 3
|
||||
#define CAMELSRT_VOICE_ACR2 4
|
||||
#define CAMELSRT_VOICE_ACR3 5
|
||||
#define CAMELSRT_VOICE_DISC 6
|
||||
|
||||
#define CAMELSRT_GPRS_INITIALDP 7
|
||||
#define CAMELSRT_GPRS_REPORT 8
|
||||
|
||||
#define CAMELSRT_SMS_INITIALDP 9
|
||||
|
||||
WS_DLL_PUBLIC const value_string camelSRTtype_naming[];
|
||||
|
||||
/** If we have a request message and its response,
|
||||
(eg: ApplyCharging, ApplyChargingReport)
|
||||
the frames numbers are stored in this structure */
|
||||
|
||||
struct camelsrt_category_t {
|
||||
guint32 req_num; /**< frame number request seen */
|
||||
guint32 rsp_num; /**< frame number response seen */
|
||||
nstime_t req_time; /**< arrival time of request */
|
||||
gboolean responded; /**< true, if request has been responded */
|
||||
};
|
||||
|
||||
/** List of stored parameters for a Camel dialogue
|
||||
All this parameters are linked to the hash table key below (use of Tid)
|
||||
In case of same Tid reused, the Camel parameters are chained.
|
||||
The right dialogue will be identified with the arrival time of the InitialDP */
|
||||
|
||||
struct camelsrt_call_t {
|
||||
guint32 session_id; /**< Identify the session, with an internal number */
|
||||
struct tcaphash_context_t * tcap_context;
|
||||
struct camelsrt_category_t category[NB_CAMELSRT_CATEGORY];
|
||||
};
|
||||
|
||||
|
||||
/** The Key for the hash table is the TCAP origine transaction identifier
|
||||
of the TC_BEGIN containing the InitialDP */
|
||||
|
||||
struct camelsrt_call_info_key_t {
|
||||
guint32 SessionIdKey;
|
||||
};
|
||||
|
||||
/** Info for a couple of messages (or category)
|
||||
The request must be available, not duplicated,
|
||||
and once the corresponding response received,
|
||||
we can deduce the Delta Time between Request/response */
|
||||
|
||||
struct camelsrt_msginfo_t {
|
||||
gboolean request_available;
|
||||
gboolean is_duplicate;
|
||||
gboolean is_delta_time;
|
||||
nstime_t req_time;
|
||||
nstime_t delta_time;
|
||||
};
|
||||
|
||||
/** List of infos to store for the analyse */
|
||||
|
||||
struct camelsrt_info_t {
|
||||
guint32 tcap_session_id;
|
||||
void * tcap_context;
|
||||
guint8 opcode; /**< operation code of message received */
|
||||
guint8 bool_msginfo[NB_CAMELSRT_CATEGORY]; /**< category for the received message */
|
||||
struct camelsrt_msginfo_t msginfo[NB_CAMELSRT_CATEGORY];
|
||||
};
|
||||
|
||||
/**
|
||||
* Routine called when the TAP is initialized.
|
||||
* so hash table are (re)created
|
||||
*/
|
||||
void camelsrt_init_routine(void);
|
||||
|
||||
/**
|
||||
* Initialize the Message Info used by the main dissector
|
||||
* Data are linked to a TCAP transaction
|
||||
*/
|
||||
struct camelsrt_info_t * camelsrt_razinfo(void);
|
||||
|
||||
/**
|
||||
* Service Response Time analyze, called just after the camel dissector
|
||||
* According to the camel operation, we
|
||||
* - open/close a context for the camel session
|
||||
* - look for a request, or look for the corresponding response
|
||||
*/
|
||||
void camelsrt_call_matching(tvbuff_t *tvb,
|
||||
packet_info * pinfo _U_,
|
||||
proto_tree *tree,
|
||||
struct camelsrt_info_t * p_camel_info);
|
||||
|
||||
WS_DLL_PUBLIC gboolean gcamel_StatSRT;
|
||||
|
||||
#endif /* PACKET_camel_H */
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -70,6 +70,147 @@ struct tcap_private_t {
|
|||
gchar *TransactionID_str;
|
||||
};
|
||||
|
||||
/** @file
|
||||
* lists and hash tables used in wireshark's tcap dissector
|
||||
* for calculation of delays in tcap-calls
|
||||
*/
|
||||
|
||||
#define LENGTH_OID 23
|
||||
struct tcaphash_context_t {
|
||||
struct tcaphash_context_key_t * key;
|
||||
guint32 session_id;
|
||||
guint32 first_frame;
|
||||
guint32 last_frame;
|
||||
nstime_t begin_time; /**< time of arrival of TC_BEGIN */
|
||||
nstime_t end_time; /**< time of closing message */
|
||||
gboolean responded; /**< true, if request has been responded */
|
||||
gboolean closed;
|
||||
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_ansicall_t * ansicall;
|
||||
};
|
||||
|
||||
struct tcaphash_begincall_t {
|
||||
struct tcaphash_begin_info_key_t * beginkey;
|
||||
struct tcaphash_context_t * context;
|
||||
gboolean father;
|
||||
struct tcaphash_begincall_t * next_begincall;
|
||||
struct tcaphash_begincall_t * previous_begincall;
|
||||
};
|
||||
|
||||
struct tcaphash_contcall_t {
|
||||
struct tcaphash_cont_info_key_t * contkey;
|
||||
struct tcaphash_context_t * context;
|
||||
gboolean father;
|
||||
struct tcaphash_contcall_t * next_contcall;
|
||||
struct tcaphash_contcall_t * previous_contcall;
|
||||
};
|
||||
|
||||
struct tcaphash_endcall_t {
|
||||
struct tcaphash_end_info_key_t * endkey;
|
||||
struct tcaphash_context_t * context;
|
||||
gboolean father;
|
||||
struct tcaphash_endcall_t * next_endcall;
|
||||
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 */
|
||||
|
||||
struct tcaphash_context_key_t {
|
||||
guint32 session_id;
|
||||
};
|
||||
|
||||
struct tcaphash_begin_info_key_t {
|
||||
guint32 hashKey;
|
||||
guint32 tid;
|
||||
guint32 opc_hash;
|
||||
guint32 dpc_hash;
|
||||
};
|
||||
|
||||
struct tcaphash_cont_info_key_t {
|
||||
guint32 hashKey;
|
||||
guint32 src_tid;
|
||||
guint32 dst_tid;
|
||||
guint32 opc_hash;
|
||||
guint32 dpc_hash;
|
||||
};
|
||||
|
||||
struct tcaphash_end_info_key_t {
|
||||
guint32 hashKey;
|
||||
guint32 tid;
|
||||
guint32 opc_hash;
|
||||
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 {
|
||||
guint32 tcap_session_id;
|
||||
guint32 src_tid;
|
||||
guint32 dst_tid;
|
||||
guint8 ope;
|
||||
};
|
||||
|
||||
/**
|
||||
* Routine called when the TAP is initialized.
|
||||
* so hash table are (re)created
|
||||
*/
|
||||
void tcapsrt_init_routine(void);
|
||||
|
||||
/**
|
||||
* Initialize the Message Info used by the main dissector
|
||||
* Data are linked to a TCAP transaction
|
||||
*/
|
||||
struct tcapsrt_info_t * tcapsrt_razinfo(void);
|
||||
|
||||
void tcapsrt_close(struct tcaphash_context_t * p_tcaphash_context,
|
||||
packet_info * pinfo _U_);
|
||||
|
||||
/**
|
||||
* 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 _U_,
|
||||
proto_tree *tree,
|
||||
struct tcapsrt_info_t * p_tcap_info);
|
||||
|
||||
WS_DLL_PUBLIC gboolean gtcap_StatSRT;
|
||||
|
||||
extern gint tcap_standard;
|
||||
|
||||
extern const value_string tcap_component_type_str[];
|
||||
|
|
|
@ -1476,7 +1476,6 @@ set(LIBWIRESHARK_FILES
|
|||
app_mem_usage.c
|
||||
asn1.c
|
||||
atalk-utils.c
|
||||
camel-persistentdata.c
|
||||
charsets.c
|
||||
circuit.c
|
||||
column.c
|
||||
|
@ -1534,7 +1533,6 @@ set(LIBWIRESHARK_FILES
|
|||
stream.c
|
||||
t35.c
|
||||
tap.c
|
||||
tcap-persistentdata.c
|
||||
timestamp.c
|
||||
timestats.c
|
||||
tfs.c
|
||||
|
|
|
@ -32,7 +32,6 @@ LIBWIRESHARK_SRC = \
|
|||
app_mem_usage.c \
|
||||
asn1.c \
|
||||
atalk-utils.c \
|
||||
camel-persistentdata.c \
|
||||
charsets.c \
|
||||
circuit.c \
|
||||
column.c \
|
||||
|
@ -89,7 +88,6 @@ LIBWIRESHARK_SRC = \
|
|||
stream.c \
|
||||
t35.c \
|
||||
tap.c \
|
||||
tcap-persistentdata.c \
|
||||
timestamp.c \
|
||||
timestats.c \
|
||||
tfs.c \
|
||||
|
@ -158,7 +156,6 @@ LIBWIRESHARK_INCLUDES = \
|
|||
atalk-utils.h \
|
||||
ax25_pids.h \
|
||||
bridged_pids.h \
|
||||
camel-persistentdata.h \
|
||||
charsets.h \
|
||||
chdlctypes.h \
|
||||
circuit.h \
|
||||
|
@ -246,7 +243,6 @@ LIBWIRESHARK_INCLUDES = \
|
|||
t35.h \
|
||||
tap.h \
|
||||
tap-voip.h \
|
||||
tcap-persistentdata.h \
|
||||
timestamp.h \
|
||||
timestats.h \
|
||||
tfs.h \
|
||||
|
|
|
@ -1,798 +0,0 @@
|
|||
/*
|
||||
* camel-persistentdata.c
|
||||
* Source for lists and hash tables used in wireshark's camel dissector
|
||||
* for calculation of delays in camel calls
|
||||
* Copyright 2006 Florent Drouin
|
||||
*
|
||||
* $Id$
|
||||
*
|
||||
* Wireshark - Network traffic analyzer
|
||||
* By Gerald Combs <gerald@wireshark.org>
|
||||
* Copyright 1998 Gerald Combs
|
||||
*
|
||||
* 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
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <glib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <epan/emem.h>
|
||||
#include <epan/packet.h>
|
||||
#include <epan/tap.h>
|
||||
#include <epan/asn1.h>
|
||||
#include <epan/camel-persistentdata.h>
|
||||
#include <epan/dissectors/packet-tcap.h>
|
||||
#include <epan/dissectors/packet-mtp3.h>
|
||||
|
||||
const value_string camelSRTtype_naming[]= {
|
||||
{ CAMELSRT_SESSION, "TCAP_Session" },
|
||||
{ CAMELSRT_VOICE_INITIALDP, "InialDP/Continue" },
|
||||
{ CAMELSRT_VOICE_ACR1, "Slice1_ACR/ACH" },
|
||||
{ CAMELSRT_VOICE_ACR2, "Slice2_ACR/ACH" },
|
||||
{ CAMELSRT_VOICE_ACR3, "Slice3_ACR/ACH" },
|
||||
{ CAMELSRT_VOICE_DISC, "EvtRepBSCM/Release" },
|
||||
{ CAMELSRT_SMS_INITIALDP, "InitialDP/ContinueSMS" },
|
||||
{ CAMELSRT_GPRS_INITIALDP, "InitialDP/ContinueGPRS" },
|
||||
{ CAMELSRT_GPRS_REPORT, "EvtRepGPRS/ContinueGPRS" },
|
||||
{ 0,NULL}
|
||||
};
|
||||
|
||||
static gint camelsrt_call_equal(gconstpointer k1, gconstpointer k2);
|
||||
static guint camelsrt_call_hash(gconstpointer k);
|
||||
static struct camelsrt_call_t *find_camelsrt_call(struct camelsrt_call_info_key_t *p_camelsrt_call_key);
|
||||
static struct camelsrt_call_t *new_camelsrt_call(struct camelsrt_call_info_key_t *p_camelsrt_call_key);
|
||||
|
||||
static void update_camelsrt_call(struct camelsrt_call_t *p_camelsrt_call,
|
||||
packet_info *pinfo, guint msg_category);
|
||||
|
||||
static void camelsrt_begin_call_matching(packet_info *pinfo,
|
||||
struct camelsrt_info_t *p_camelsrt_info);
|
||||
|
||||
static void camelsrt_request_call_matching(tvbuff_t *tvb, packet_info *pinfo,
|
||||
proto_tree *tree,
|
||||
struct camelsrt_info_t *p_camelsrt_info,
|
||||
guint srt_type);
|
||||
|
||||
static void camelsrt_report_call_matching(tvbuff_t *tvb, packet_info *pinfo,
|
||||
proto_tree *tree,
|
||||
struct camelsrt_info_t *p_camelsrt_info,
|
||||
guint srt_type);
|
||||
|
||||
static void camelsrt_close_call_matching(packet_info *pinfo,
|
||||
struct camelsrt_info_t *p_camelsrt_info);
|
||||
|
||||
static void camelsrt_display_DeltaTime(proto_tree *tree, tvbuff_t *tvb,
|
||||
nstime_t *value_ptr, guint category);
|
||||
|
||||
static void raz_camelsrt_call (struct camelsrt_call_t *p_camelsrt_call);
|
||||
|
||||
void camelsrt_tcap_matching(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
|
||||
struct tcaphash_context_t *tcap_context);
|
||||
|
||||
/* When several Camel components are received in a single TCAP message,
|
||||
we have to use several buffers for the stored parameters
|
||||
because else this data are erased during TAP dissector call */
|
||||
#define MAX_CAMEL_INSTANCE 10
|
||||
int camelsrt_global_current=0;
|
||||
struct camelsrt_info_t camelsrt_global_info[MAX_CAMEL_INSTANCE];
|
||||
|
||||
/* Configuration parameters to enable or disable the Service Response Time */
|
||||
extern gboolean gcamel_HandleSRT;
|
||||
gboolean gcamel_PersistentSRT=FALSE;
|
||||
gboolean gcamel_DisplaySRT=FALSE;
|
||||
gboolean gcamel_StatSRT=FALSE;
|
||||
|
||||
extern int camel_tap;
|
||||
|
||||
extern int hf_camelsrt_SessionId;
|
||||
extern int hf_camelsrt_RequestNumber;
|
||||
extern int hf_camelsrt_Duplicate;
|
||||
extern int hf_camelsrt_RequestFrame;
|
||||
extern int hf_camelsrt_ResponseFrame;
|
||||
extern int hf_camelsrt_DeltaTime;
|
||||
extern int hf_camelsrt_SessionTime;
|
||||
extern int hf_camelsrt_DeltaTime31;
|
||||
extern int hf_camelsrt_DeltaTime75;
|
||||
extern int hf_camelsrt_DeltaTime65;
|
||||
extern int hf_camelsrt_DeltaTime22;
|
||||
extern int hf_camelsrt_DeltaTime35;
|
||||
extern int hf_camelsrt_DeltaTime80;
|
||||
|
||||
/* Global hash tables*/
|
||||
static GHashTable *srt_calls = NULL;
|
||||
guint32 camelsrt_global_SessionId=1;
|
||||
|
||||
/*
|
||||
* DEBUG fonctions
|
||||
*/
|
||||
|
||||
#undef DEBUG_CAMELSRT
|
||||
/* #define DEBUG_CAMELSRT */
|
||||
|
||||
#ifdef DEBUG_CAMELSRT
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
static guint debug_level = 99;
|
||||
|
||||
static void dbg(guint level, char *fmt, ...) {
|
||||
va_list ap;
|
||||
|
||||
if (level > debug_level) return;
|
||||
va_start(ap,fmt);
|
||||
vfprintf(stderr, fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Functions needed for Hash-Table
|
||||
*/
|
||||
|
||||
/* compare 2 keys */
|
||||
static gint
|
||||
camelsrt_call_equal(gconstpointer k1, gconstpointer k2)
|
||||
{
|
||||
const struct camelsrt_call_info_key_t *key1 = (const struct camelsrt_call_info_key_t *) k1;
|
||||
const struct camelsrt_call_info_key_t *key2 = (const struct camelsrt_call_info_key_t *) k2;
|
||||
|
||||
return (key1->SessionIdKey == key2->SessionIdKey) ;
|
||||
}
|
||||
|
||||
/* calculate a hash key */
|
||||
static guint
|
||||
camelsrt_call_hash(gconstpointer k)
|
||||
{
|
||||
const struct camelsrt_call_info_key_t *key = (const struct camelsrt_call_info_key_t *) k;
|
||||
return key->SessionIdKey;
|
||||
}
|
||||
|
||||
/*
|
||||
* Find the dialog by Key and Time
|
||||
*/
|
||||
static struct camelsrt_call_t *
|
||||
find_camelsrt_call(struct camelsrt_call_info_key_t *p_camelsrt_call_key)
|
||||
{
|
||||
struct camelsrt_call_t *p_camelsrt_call = NULL;
|
||||
p_camelsrt_call = (struct camelsrt_call_t *)g_hash_table_lookup(srt_calls, p_camelsrt_call_key);
|
||||
|
||||
#ifdef DEBUG_CAMELSRT
|
||||
if(p_camelsrt_call) {
|
||||
dbg(10,"D%d ", p_camelsrt_call->session_id);
|
||||
} else {
|
||||
dbg(23,"Not in hash ");
|
||||
}
|
||||
#endif
|
||||
|
||||
return p_camelsrt_call;
|
||||
}
|
||||
|
||||
/*
|
||||
* New record to create, to identify a new transaction
|
||||
*/
|
||||
static struct camelsrt_call_t *
|
||||
new_camelsrt_call(struct camelsrt_call_info_key_t *p_camelsrt_call_key)
|
||||
{
|
||||
struct camelsrt_call_info_key_t *p_new_camelsrt_call_key;
|
||||
struct camelsrt_call_t *p_new_camelsrt_call = NULL;
|
||||
|
||||
/* Register the transaction in the hash table
|
||||
with the tcap transaction Id as main Key
|
||||
Once created, this entry will be updated later */
|
||||
|
||||
p_new_camelsrt_call_key = se_new(struct camelsrt_call_info_key_t);
|
||||
p_new_camelsrt_call_key->SessionIdKey = p_camelsrt_call_key->SessionIdKey;
|
||||
p_new_camelsrt_call = se_new(struct camelsrt_call_t);
|
||||
raz_camelsrt_call(p_new_camelsrt_call);
|
||||
p_new_camelsrt_call->session_id = camelsrt_global_SessionId++;
|
||||
#ifdef DEBUG_CAMELSRT
|
||||
dbg(10,"D%d ", p_new_camelsrt_call->session_id);
|
||||
#endif
|
||||
/* store it */
|
||||
g_hash_table_insert(srt_calls, p_new_camelsrt_call_key, p_new_camelsrt_call);
|
||||
return p_new_camelsrt_call;
|
||||
}
|
||||
|
||||
/*
|
||||
* Update a record with the data of the Request
|
||||
*/
|
||||
static void
|
||||
update_camelsrt_call(struct camelsrt_call_t *p_camelsrt_call, packet_info *pinfo,
|
||||
guint msg_category)
|
||||
{
|
||||
p_camelsrt_call->category[msg_category].req_num = pinfo->fd->num;
|
||||
p_camelsrt_call->category[msg_category].rsp_num = 0;
|
||||
p_camelsrt_call->category[msg_category].responded = FALSE;
|
||||
p_camelsrt_call->category[msg_category].req_time = pinfo->fd->abs_ts;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Routine called when the TAP is initialized.
|
||||
* so hash table are (re)created
|
||||
*/
|
||||
void
|
||||
camelsrt_init_routine(void)
|
||||
{
|
||||
|
||||
/* free hash-table for SRT */
|
||||
if (srt_calls != NULL) {
|
||||
#ifdef DEBUG_CAMELSRT
|
||||
dbg(16,"Destroy hash ");
|
||||
#endif
|
||||
g_hash_table_destroy(srt_calls);
|
||||
}
|
||||
|
||||
/* create new hash-table for SRT */
|
||||
srt_calls = g_hash_table_new(camelsrt_call_hash, camelsrt_call_equal);
|
||||
#ifdef DEBUG_CAMELSRT
|
||||
dbg(16,"Create hash ");
|
||||
#endif
|
||||
/* Reset the session counter */
|
||||
camelsrt_global_SessionId=1;
|
||||
|
||||
/* The Display of SRT is enable
|
||||
* 1) For wireshark only if Persistent Stat is enable
|
||||
* 2) For Tshark, if the SRT handling is enable
|
||||
*/
|
||||
gcamel_DisplaySRT=gcamel_PersistentSRT || gcamel_HandleSRT&gcamel_StatSRT;
|
||||
}
|
||||
|
||||
/*
|
||||
* Service Response Time analyze, called just after the camel dissector
|
||||
* According to the camel operation, we
|
||||
* - open/close a context for the camel session
|
||||
* - look for a request, or look for the corresponding response
|
||||
*/
|
||||
void
|
||||
camelsrt_call_matching(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
|
||||
struct camelsrt_info_t *p_camelsrt_info)
|
||||
{
|
||||
|
||||
#ifdef DEBUG_CAMELSRT
|
||||
dbg(10,"tcap_session #%d ", p_camelsrt_info->tcap_session_id);
|
||||
#endif
|
||||
|
||||
switch (p_camelsrt_info->opcode) {
|
||||
|
||||
case 0: /*InitialDP*/
|
||||
camelsrt_begin_call_matching(pinfo, p_camelsrt_info);
|
||||
camelsrt_request_call_matching(tvb, pinfo, tree, p_camelsrt_info,
|
||||
CAMELSRT_VOICE_INITIALDP);
|
||||
break;
|
||||
case 60: /*InitialDPSMS*/
|
||||
camelsrt_begin_call_matching(pinfo, p_camelsrt_info);
|
||||
camelsrt_request_call_matching(tvb, pinfo, tree, p_camelsrt_info,
|
||||
CAMELSRT_SMS_INITIALDP);
|
||||
break;
|
||||
case 78: /*InitialDPGPRS*/
|
||||
camelsrt_begin_call_matching(pinfo, p_camelsrt_info);
|
||||
camelsrt_request_call_matching(tvb, pinfo, tree, p_camelsrt_info,
|
||||
CAMELSRT_GPRS_INITIALDP);
|
||||
break;
|
||||
|
||||
case 23: /*RequestReportBCSMEvent*/
|
||||
break;
|
||||
|
||||
case 63: /*RequestReportSMSEvent*/
|
||||
break;
|
||||
|
||||
case 81: /*RequestReportGPRSEvent*/
|
||||
break;
|
||||
|
||||
case 24: /*EventReportBCSMEvent*/
|
||||
camelsrt_request_call_matching(tvb, pinfo, tree, p_camelsrt_info,
|
||||
CAMELSRT_VOICE_DISC );
|
||||
break;
|
||||
|
||||
case 64: /*EventReportSMS*/
|
||||
/* Session has been explicity closed without TC_END */
|
||||
camelsrt_close_call_matching(pinfo, p_camelsrt_info);
|
||||
tcapsrt_close((struct tcaphash_context_t *)p_camelsrt_info->tcap_context, pinfo);
|
||||
break;
|
||||
|
||||
case 80: /*EventReportGPRS*/
|
||||
camelsrt_begin_call_matching(pinfo, p_camelsrt_info);
|
||||
camelsrt_request_call_matching(tvb, pinfo, tree, p_camelsrt_info,
|
||||
CAMELSRT_GPRS_REPORT);
|
||||
break;
|
||||
|
||||
case 35: /*ApplyCharging*/
|
||||
camelsrt_report_call_matching(tvb, pinfo, tree, p_camelsrt_info,
|
||||
CAMELSRT_VOICE_ACR1 );
|
||||
break;
|
||||
|
||||
case 71: /*ApplyChargingGPRS*/
|
||||
break;
|
||||
|
||||
case 36: /*ApplyChargingReport*/
|
||||
camelsrt_request_call_matching(tvb, pinfo, tree, p_camelsrt_info,
|
||||
CAMELSRT_VOICE_ACR1 );
|
||||
break;
|
||||
|
||||
case 72: /*ApplyChargingReportGPRS*/
|
||||
break;
|
||||
|
||||
case 31: /*Continue*/
|
||||
camelsrt_report_call_matching(tvb, pinfo, tree, p_camelsrt_info,
|
||||
CAMELSRT_VOICE_INITIALDP);
|
||||
break;
|
||||
case 65: /*ContinueSMS*/
|
||||
camelsrt_report_call_matching(tvb, pinfo, tree, p_camelsrt_info,
|
||||
CAMELSRT_SMS_INITIALDP);
|
||||
break;
|
||||
case 75: /*ContinueGPRS*/
|
||||
camelsrt_report_call_matching(tvb, pinfo, tree, p_camelsrt_info,
|
||||
CAMELSRT_GPRS_INITIALDP);
|
||||
camelsrt_report_call_matching(tvb, pinfo, tree, p_camelsrt_info,
|
||||
CAMELSRT_GPRS_REPORT);
|
||||
break;
|
||||
|
||||
case 22: /*ReleaseCall*/
|
||||
camelsrt_report_call_matching(tvb, pinfo, tree, p_camelsrt_info,
|
||||
CAMELSRT_VOICE_DISC);
|
||||
/* Session has been closed by Network */
|
||||
camelsrt_close_call_matching(pinfo, p_camelsrt_info);
|
||||
break;
|
||||
|
||||
case 66: /*ReleaseSMS*/
|
||||
/* Session has been closed by Network */
|
||||
camelsrt_close_call_matching(pinfo, p_camelsrt_info);
|
||||
tcapsrt_close((struct tcaphash_context_t *)p_camelsrt_info->tcap_context,pinfo);
|
||||
break;
|
||||
|
||||
case 79: /*ReleaseGPRS*/
|
||||
/* Session has been closed by Network */
|
||||
camelsrt_close_call_matching(pinfo, p_camelsrt_info);
|
||||
break;
|
||||
} /* switch opcode */
|
||||
}
|
||||
|
||||
/*
|
||||
* Callback function for the TCAP dissector
|
||||
* This callback function is used to inform the camel layer, that the session
|
||||
* has been Closed or Aborted by a TCAP message without Camel component
|
||||
* So, we can close the context for camel session, and update the stats.
|
||||
*/
|
||||
void
|
||||
camelsrt_tcap_matching(tvbuff_t *tvb _U_, packet_info *pinfo,
|
||||
proto_tree *tree _U_,
|
||||
struct tcaphash_context_t *p_tcap_context)
|
||||
{
|
||||
struct camelsrt_info_t *p_camelsrt_info;
|
||||
|
||||
#ifdef DEBUG_CAMELSRT
|
||||
dbg(11,"Camel_CallBack ");
|
||||
#endif
|
||||
p_camelsrt_info=camelsrt_razinfo();
|
||||
|
||||
p_camelsrt_info->tcap_context=p_tcap_context;
|
||||
if (p_tcap_context) {
|
||||
#ifdef DEBUG_CAMELSRT
|
||||
dbg(11,"Close TCAP ");
|
||||
#endif
|
||||
p_camelsrt_info->tcap_session_id = p_tcap_context->session_id;
|
||||
camelsrt_close_call_matching(pinfo, p_camelsrt_info);
|
||||
tap_queue_packet(camel_tap, pinfo, p_camelsrt_info);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Create the record identifiying the Camel session
|
||||
* As the Tcap session id given by the TCAP dissector is uniq, it will be
|
||||
* used as main key.
|
||||
*/
|
||||
static void
|
||||
camelsrt_begin_call_matching(packet_info *pinfo,
|
||||
struct camelsrt_info_t *p_camelsrt_info)
|
||||
{
|
||||
struct camelsrt_call_t *p_camelsrt_call;
|
||||
struct camelsrt_call_info_key_t camelsrt_call_key;
|
||||
|
||||
p_camelsrt_info->bool_msginfo[CAMELSRT_SESSION]=TRUE;
|
||||
|
||||
/* prepare the key data */
|
||||
camelsrt_call_key.SessionIdKey = p_camelsrt_info->tcap_session_id;
|
||||
|
||||
/* look up the request */
|
||||
#ifdef DEBUG_CAMELSRT
|
||||
dbg(10,"\n Session begin #%u\n", pinfo->fd->num);
|
||||
dbg(11,"Search key %lu ",camelsrt_call_key.SessionIdKey);
|
||||
#endif
|
||||
p_camelsrt_call = (struct camelsrt_call_t *)g_hash_table_lookup(srt_calls, &camelsrt_call_key);
|
||||
if (p_camelsrt_call) {
|
||||
/* We have seen this request before -> do nothing */
|
||||
#ifdef DEBUG_CAMELSRT
|
||||
dbg(22,"Already seen ");
|
||||
#endif
|
||||
} else { /* p_camelsrt_call has not been found */
|
||||
#ifdef DEBUG_CAMELSRT
|
||||
dbg(10,"New key %lu ",camelsrt_call_key.SessionIdKey);
|
||||
#endif
|
||||
p_camelsrt_call = new_camelsrt_call(&camelsrt_call_key);
|
||||
p_camelsrt_call->tcap_context=(struct tcaphash_context_t *)p_camelsrt_info->tcap_context;
|
||||
update_camelsrt_call(p_camelsrt_call, pinfo,CAMELSRT_SESSION);
|
||||
|
||||
#ifdef DEBUG_CAMELSRT
|
||||
dbg(11,"Update Callback ");
|
||||
#endif
|
||||
p_camelsrt_call->tcap_context->callback=camelsrt_tcap_matching;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Register the request, and try to find the response
|
||||
*
|
||||
*/
|
||||
static void
|
||||
camelsrt_request_call_matching(tvbuff_t *tvb, packet_info *pinfo,
|
||||
proto_tree *tree,
|
||||
struct camelsrt_info_t *p_camelsrt_info,
|
||||
guint srt_type )
|
||||
{
|
||||
struct camelsrt_call_t *p_camelsrt_call;
|
||||
struct camelsrt_call_info_key_t camelsrt_call_key;
|
||||
proto_item *ti, *hidden_item;
|
||||
|
||||
#ifdef DEBUG_CAMELSRT
|
||||
dbg(10,"\n %s #%u\n", val_to_str_const(srt_type, camelSRTtype_naming, "Unk"),pinfo->fd->num);
|
||||
#endif
|
||||
|
||||
/* look only for matching request, if matching conversation is available. */
|
||||
camelsrt_call_key.SessionIdKey = p_camelsrt_info->tcap_session_id;
|
||||
|
||||
#ifdef DEBUG_CAMELSRT
|
||||
dbg(11,"Search key %lu ", camelsrt_call_key.SessionIdKey);
|
||||
#endif
|
||||
p_camelsrt_call = find_camelsrt_call(&camelsrt_call_key);
|
||||
if(p_camelsrt_call) {
|
||||
#ifdef DEBUG_CAMELSRT
|
||||
dbg(12,"Found ");
|
||||
#endif
|
||||
if (gcamel_DisplaySRT)
|
||||
proto_tree_add_uint(tree, hf_camelsrt_SessionId, tvb, 0,0, p_camelsrt_call->session_id);
|
||||
|
||||
|
||||
/* Hmm.. As there are several slices ApplyChargingReport/ApplyCharging
|
||||
* we will prepare the measurement for 3 slices with 3 categories */
|
||||
if (srt_type==CAMELSRT_VOICE_ACR1) {
|
||||
if (p_camelsrt_call->category[CAMELSRT_VOICE_ACR1].req_num == 0) {
|
||||
srt_type=CAMELSRT_VOICE_ACR1;
|
||||
} else if ( (p_camelsrt_call->category[CAMELSRT_VOICE_ACR2].req_num == 0)
|
||||
&& (p_camelsrt_call->category[CAMELSRT_VOICE_ACR1].rsp_num != 0)
|
||||
&& (p_camelsrt_call->category[CAMELSRT_VOICE_ACR1].rsp_num < pinfo->fd->num) ) {
|
||||
srt_type=CAMELSRT_VOICE_ACR2;
|
||||
} else if ( (p_camelsrt_call->category[CAMELSRT_VOICE_ACR3].req_num == 0)
|
||||
&& (p_camelsrt_call->category[CAMELSRT_VOICE_ACR2].rsp_num != 0)
|
||||
&& (p_camelsrt_call->category[CAMELSRT_VOICE_ACR2].rsp_num < pinfo->fd->num) ) {
|
||||
srt_type=CAMELSRT_VOICE_ACR3;
|
||||
} else if (p_camelsrt_call->category[CAMELSRT_VOICE_ACR1].rsp_num != 0
|
||||
&& p_camelsrt_call->category[CAMELSRT_VOICE_ACR1].rsp_num > pinfo->fd->num) {
|
||||
srt_type=CAMELSRT_VOICE_ACR1;
|
||||
} else if ( p_camelsrt_call->category[CAMELSRT_VOICE_ACR2].rsp_num != 0
|
||||
&& p_camelsrt_call->category[CAMELSRT_VOICE_ACR2].rsp_num > pinfo->fd->num) {
|
||||
srt_type=CAMELSRT_VOICE_ACR2;
|
||||
} else if (p_camelsrt_call->category[CAMELSRT_VOICE_ACR1].rsp_num != 0
|
||||
&& p_camelsrt_call->category[CAMELSRT_VOICE_ACR3].rsp_num > pinfo->fd->num) {
|
||||
srt_type=CAMELSRT_VOICE_ACR3;
|
||||
}
|
||||
#ifdef DEBUG_CAMELSRT
|
||||
dbg(70,"Request ACR %u ",srt_type);
|
||||
dbg(70,"ACR1 %u %u",p_camelsrt_call->category[CAMELSRT_VOICE_ACR1].req_num, p_camelsrt_call->category[CAMELSRT_VOICE_ACR1].rsp_num);
|
||||
dbg(70,"ACR2 %u %u",p_camelsrt_call->category[CAMELSRT_VOICE_ACR2].req_num, p_camelsrt_call->category[CAMELSRT_VOICE_ACR2].rsp_num);
|
||||
dbg(70,"ACR3 %u %u",p_camelsrt_call->category[CAMELSRT_VOICE_ACR3].req_num, p_camelsrt_call->category[CAMELSRT_VOICE_ACR3].rsp_num);
|
||||
#endif
|
||||
} /* not ACR */
|
||||
p_camelsrt_info->bool_msginfo[srt_type]=TRUE;
|
||||
|
||||
|
||||
if (p_camelsrt_call->category[srt_type].req_num == 0) {
|
||||
/* We have not yet seen a request to that call, so this must be the first request
|
||||
remember its frame number. */
|
||||
#ifdef DEBUG_CAMELSRT
|
||||
dbg(5,"Set reqlink #%u ", pinfo->fd->num);
|
||||
#endif
|
||||
update_camelsrt_call(p_camelsrt_call, pinfo, srt_type);
|
||||
} else {
|
||||
/* We have seen a request to this call - but was it *this* request? */
|
||||
if (p_camelsrt_call->category[srt_type].req_num != pinfo->fd->num) {
|
||||
|
||||
if (srt_type!=CAMELSRT_VOICE_DISC) {
|
||||
/* No, so it's a duplicate resquest. Mark it as such. */
|
||||
#ifdef DEBUG_CAMELSRT
|
||||
dbg(21,"Display_duplicate with req %d ", p_camelsrt_call->category[srt_type].req_num);
|
||||
#endif
|
||||
p_camelsrt_info->msginfo[srt_type].is_duplicate = TRUE;
|
||||
if (gcamel_DisplaySRT){
|
||||
hidden_item = proto_tree_add_uint(tree, hf_camelsrt_Duplicate, tvb, 0,0, 77);
|
||||
PROTO_ITEM_SET_HIDDEN(hidden_item);
|
||||
}
|
||||
|
||||
} else {
|
||||
/* Ignore duplicate frame */
|
||||
if (pinfo->fd->num > p_camelsrt_call->category[srt_type].req_num) {
|
||||
p_camelsrt_call->category[srt_type].req_num = pinfo->fd->num;
|
||||
#ifdef DEBUG_CAMELSRT
|
||||
dbg(5,"DISC Set reqlink #%u ", pinfo->fd->num);
|
||||
#endif
|
||||
update_camelsrt_call(p_camelsrt_call, pinfo, srt_type);
|
||||
} /* greater frame */
|
||||
} /* DISC */
|
||||
} /* req_num already seen */
|
||||
} /* req_num != 0 */
|
||||
|
||||
/* add link to response frame, if available */
|
||||
if ( gcamel_DisplaySRT &&
|
||||
(p_camelsrt_call->category[srt_type].rsp_num != 0) &&
|
||||
(p_camelsrt_call->category[srt_type].req_num != 0) &&
|
||||
(p_camelsrt_call->category[srt_type].req_num == pinfo->fd->num) ) {
|
||||
#ifdef DEBUG_CAMELSRT
|
||||
dbg(20,"Display_framersplink %d ",p_camelsrt_call->category[srt_type].rsp_num);
|
||||
#endif
|
||||
ti = proto_tree_add_uint_format(tree, hf_camelsrt_RequestFrame, tvb, 0, 0,
|
||||
p_camelsrt_call->category[srt_type].rsp_num,
|
||||
"Linked response %s in frame %u",
|
||||
val_to_str_const(srt_type, camelSRTtype_naming, "Unk"),
|
||||
p_camelsrt_call->category[srt_type].rsp_num);
|
||||
PROTO_ITEM_SET_GENERATED(ti);
|
||||
} /* frame valid */
|
||||
} /* call reference */
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Check if the received message is a response to a previous request
|
||||
* registered is the camel session context.
|
||||
*/
|
||||
static void
|
||||
camelsrt_report_call_matching(tvbuff_t *tvb, packet_info *pinfo,
|
||||
proto_tree *tree,
|
||||
struct camelsrt_info_t *p_camelsrt_info,
|
||||
guint srt_type)
|
||||
{
|
||||
struct camelsrt_call_t *p_camelsrt_call;
|
||||
struct camelsrt_call_info_key_t camelsrt_call_key;
|
||||
nstime_t delta;
|
||||
proto_item *ti, *hidden_item;
|
||||
|
||||
#ifdef DEBUG_CAMELSRT
|
||||
dbg(10,"\n %s #%u\n", val_to_str_const(srt_type, camelSRTtype_naming, "Unk"),pinfo->fd->num);
|
||||
#endif
|
||||
camelsrt_call_key.SessionIdKey = p_camelsrt_info->tcap_session_id;
|
||||
/* look only for matching request, if matching conversation is available. */
|
||||
|
||||
#ifdef DEBUG_CAMELSRT
|
||||
dbg(11,"Search key %lu ",camelsrt_call_key.SessionIdKey);
|
||||
#endif
|
||||
p_camelsrt_call = find_camelsrt_call(&camelsrt_call_key);
|
||||
if(p_camelsrt_call) {
|
||||
#ifdef DEBUG_CAMELSRT
|
||||
dbg(12,"Found, req=%d ",p_camelsrt_call->category[srt_type].req_num);
|
||||
#endif
|
||||
if ( gcamel_DisplaySRT )
|
||||
proto_tree_add_uint(tree, hf_camelsrt_SessionId, tvb, 0,0, p_camelsrt_call->session_id);
|
||||
|
||||
if (srt_type==CAMELSRT_VOICE_ACR1) {
|
||||
if (p_camelsrt_call->category[CAMELSRT_VOICE_ACR3].req_num != 0
|
||||
&& p_camelsrt_call->category[CAMELSRT_VOICE_ACR3].req_num < pinfo->fd->num) {
|
||||
srt_type=CAMELSRT_VOICE_ACR1;
|
||||
} else if ( p_camelsrt_call->category[CAMELSRT_VOICE_ACR2].req_num != 0
|
||||
&& p_camelsrt_call->category[CAMELSRT_VOICE_ACR2].req_num < pinfo->fd->num) {
|
||||
srt_type=CAMELSRT_VOICE_ACR2;
|
||||
} else if (p_camelsrt_call->category[CAMELSRT_VOICE_ACR1].req_num != 0
|
||||
&& p_camelsrt_call->category[CAMELSRT_VOICE_ACR1].req_num < pinfo->fd->num) {
|
||||
srt_type=CAMELSRT_VOICE_ACR1;
|
||||
}
|
||||
#ifdef DEBUG_CAMELSRT
|
||||
dbg(70,"Report ACR %u ",srt_type);
|
||||
#endif
|
||||
} /* not ACR */
|
||||
p_camelsrt_info->bool_msginfo[srt_type]=TRUE;
|
||||
|
||||
if (p_camelsrt_call->category[srt_type].rsp_num == 0) {
|
||||
if ( (p_camelsrt_call->category[srt_type].req_num != 0)
|
||||
&& (pinfo->fd->num > p_camelsrt_call->category[srt_type].req_num) ){
|
||||
/* We have not yet seen a response to that call, so this must be the first response;
|
||||
remember its frame number only if response comes after request */
|
||||
#ifdef DEBUG_CAMELSRT
|
||||
dbg(14,"Set reslink #%d req %u ",pinfo->fd->num, p_camelsrt_call->category[srt_type].req_num);
|
||||
#endif
|
||||
p_camelsrt_call->category[srt_type].rsp_num = pinfo->fd->num;
|
||||
|
||||
} else {
|
||||
#ifdef DEBUG_CAMELSRT
|
||||
dbg(2,"badreslink #%u req %u ",pinfo->fd->num, p_camelsrt_call->category[srt_type].req_num);
|
||||
#endif
|
||||
} /* req_num != 0 */
|
||||
} else { /* rsp_num != 0 */
|
||||
/* We have seen a response to this call - but was it *this* response? */
|
||||
if (p_camelsrt_call->category[srt_type].rsp_num != pinfo->fd->num) {
|
||||
/* No, so it's a duplicate response. Mark it as such. */
|
||||
#ifdef DEBUG_CAMELSRT
|
||||
dbg(21,"Display_duplicate rsp=%d ", p_camelsrt_call->category[srt_type].rsp_num);
|
||||
#endif
|
||||
p_camelsrt_info->msginfo[srt_type].is_duplicate = TRUE;
|
||||
if ( gcamel_DisplaySRT ){
|
||||
hidden_item = proto_tree_add_uint(tree, hf_camelsrt_Duplicate, tvb, 0,0, 77);
|
||||
PROTO_ITEM_SET_HIDDEN(hidden_item);
|
||||
}
|
||||
}
|
||||
} /* rsp_num != 0 */
|
||||
|
||||
if ( (p_camelsrt_call->category[srt_type].req_num != 0) &&
|
||||
(p_camelsrt_call->category[srt_type].rsp_num != 0) &&
|
||||
(p_camelsrt_call->category[srt_type].rsp_num == pinfo->fd->num) ) {
|
||||
|
||||
p_camelsrt_call->category[srt_type].responded = TRUE;
|
||||
p_camelsrt_info->msginfo[srt_type].request_available = TRUE;
|
||||
#ifdef DEBUG_CAMELSRT
|
||||
dbg(20,"Display_frameReqlink %d ",p_camelsrt_call->category[srt_type].req_num);
|
||||
#endif
|
||||
/* Indicate the frame to which this is a reply. */
|
||||
if ( gcamel_DisplaySRT ) {
|
||||
ti = proto_tree_add_uint_format(tree, hf_camelsrt_ResponseFrame, tvb, 0, 0,
|
||||
p_camelsrt_call->category[srt_type].req_num,
|
||||
"Linked request %s in frame %u",
|
||||
val_to_str_const(srt_type, camelSRTtype_naming, "Unk"),
|
||||
p_camelsrt_call->category[srt_type].req_num);
|
||||
PROTO_ITEM_SET_GENERATED(ti);
|
||||
}
|
||||
/* Calculate Service Response Time */
|
||||
nstime_delta(&delta, &pinfo->fd->abs_ts, &p_camelsrt_call->category[srt_type].req_time);
|
||||
|
||||
p_camelsrt_info->msginfo[srt_type].is_delta_time = TRUE;
|
||||
p_camelsrt_info->msginfo[srt_type].delta_time = delta; /* give it to tap */
|
||||
p_camelsrt_info->msginfo[srt_type].req_time = p_camelsrt_call->category[srt_type].req_time;
|
||||
|
||||
/* display Service Response Time and make it filterable */
|
||||
camelsrt_display_DeltaTime(tree, tvb, &delta, srt_type);
|
||||
|
||||
} /*req_num != 0 && not duplicate */
|
||||
} /* call reference found */
|
||||
}
|
||||
|
||||
/*
|
||||
* Update the Camel session info, and close the session.
|
||||
* Then remove the associated context, if we do not have persistentSRT enable
|
||||
*/
|
||||
static void
|
||||
camelsrt_close_call_matching(packet_info *pinfo,
|
||||
struct camelsrt_info_t *p_camelsrt_info)
|
||||
{
|
||||
struct camelsrt_call_t *p_camelsrt_call;
|
||||
struct camelsrt_call_info_key_t camelsrt_call_key;
|
||||
nstime_t delta;
|
||||
|
||||
p_camelsrt_info->bool_msginfo[CAMELSRT_SESSION]=TRUE;
|
||||
#ifdef DEBUG_CAMELSRT
|
||||
dbg(10,"\n Session end #%u\n", pinfo->fd->num);
|
||||
#endif
|
||||
/* look only for matching request, if matching conversation is available. */
|
||||
camelsrt_call_key.SessionIdKey = p_camelsrt_info->tcap_session_id;
|
||||
|
||||
#ifdef DEBUG_CAMELSRT
|
||||
dbg(11,"Search key %lu ",camelsrt_call_key.SessionIdKey);
|
||||
#endif
|
||||
p_camelsrt_call = find_camelsrt_call(&camelsrt_call_key);
|
||||
if(p_camelsrt_call) {
|
||||
#ifdef DEBUG_CAMELSRT
|
||||
dbg(12,"Found ");
|
||||
#endif
|
||||
/* Calculate Service Response Time */
|
||||
nstime_delta(&delta, &pinfo->fd->abs_ts, &p_camelsrt_call->category[CAMELSRT_SESSION].req_time);
|
||||
p_camelsrt_call->category[CAMELSRT_SESSION].responded = TRUE;
|
||||
p_camelsrt_info->msginfo[CAMELSRT_SESSION].request_available = TRUE;
|
||||
p_camelsrt_info->msginfo[CAMELSRT_SESSION].is_delta_time = TRUE;
|
||||
p_camelsrt_info->msginfo[CAMELSRT_SESSION].delta_time = delta; /* give it to tap */
|
||||
p_camelsrt_info->msginfo[CAMELSRT_SESSION].req_time = p_camelsrt_call->category[CAMELSRT_SESSION].req_time;
|
||||
|
||||
if ( !gcamel_PersistentSRT ) {
|
||||
g_hash_table_remove(srt_calls, &camelsrt_call_key);
|
||||
#ifdef DEBUG_CAMELSRT
|
||||
dbg(20,"remove hash ");
|
||||
#endif
|
||||
} else {
|
||||
#ifdef DEBUG_CAMELSRT
|
||||
dbg(20,"keep hash ");
|
||||
#endif
|
||||
}
|
||||
} /* call reference found */
|
||||
}
|
||||
|
||||
/*
|
||||
* Display the delta time between two messages in a field corresponding
|
||||
* to the category (hf_camelsrt_DeltaTimexx).
|
||||
*/
|
||||
static void
|
||||
camelsrt_display_DeltaTime(proto_tree *tree, tvbuff_t *tvb, nstime_t *value_ptr,
|
||||
guint category)
|
||||
{
|
||||
proto_item *ti;
|
||||
|
||||
if ( gcamel_DisplaySRT ) {
|
||||
switch(category) {
|
||||
case CAMELSRT_VOICE_INITIALDP:
|
||||
ti = proto_tree_add_time(tree, hf_camelsrt_DeltaTime31, tvb, 0, 0, value_ptr);
|
||||
PROTO_ITEM_SET_GENERATED(ti);
|
||||
break;
|
||||
|
||||
case CAMELSRT_VOICE_ACR1:
|
||||
case CAMELSRT_VOICE_ACR2:
|
||||
case CAMELSRT_VOICE_ACR3:
|
||||
ti = proto_tree_add_time(tree, hf_camelsrt_DeltaTime22, tvb, 0, 0, value_ptr);
|
||||
PROTO_ITEM_SET_GENERATED(ti);
|
||||
break;
|
||||
|
||||
case CAMELSRT_VOICE_DISC:
|
||||
ti = proto_tree_add_time(tree, hf_camelsrt_DeltaTime35, tvb, 0, 0, value_ptr);
|
||||
PROTO_ITEM_SET_GENERATED(ti);
|
||||
break;
|
||||
|
||||
case CAMELSRT_GPRS_INITIALDP:
|
||||
ti = proto_tree_add_time(tree, hf_camelsrt_DeltaTime75, tvb, 0, 0, value_ptr);
|
||||
PROTO_ITEM_SET_GENERATED(ti);
|
||||
break;
|
||||
|
||||
case CAMELSRT_GPRS_REPORT:
|
||||
ti = proto_tree_add_time(tree, hf_camelsrt_DeltaTime80, tvb, 0, 0, value_ptr);
|
||||
PROTO_ITEM_SET_GENERATED(ti);
|
||||
break;
|
||||
|
||||
case CAMELSRT_SMS_INITIALDP:
|
||||
ti = proto_tree_add_time(tree, hf_camelsrt_DeltaTime65, tvb, 0, 0, value_ptr);
|
||||
PROTO_ITEM_SET_GENERATED(ti);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialize the Message Info used by the main dissector
|
||||
* Data are linked to a TCAP transaction
|
||||
*/
|
||||
struct camelsrt_info_t *
|
||||
camelsrt_razinfo(void)
|
||||
{
|
||||
struct camelsrt_info_t *p_camelsrt_info ;
|
||||
|
||||
/* Global buffer for packet extraction */
|
||||
camelsrt_global_current++;
|
||||
if(camelsrt_global_current==MAX_CAMEL_INSTANCE){
|
||||
camelsrt_global_current=0;
|
||||
}
|
||||
|
||||
p_camelsrt_info=&camelsrt_global_info[camelsrt_global_current];
|
||||
memset(p_camelsrt_info,0,sizeof(struct camelsrt_info_t));
|
||||
|
||||
p_camelsrt_info->opcode=255;
|
||||
|
||||
return p_camelsrt_info;
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialize the data per call for the Service Response Time Statistics
|
||||
* Data are linked to a Camel operation in a TCAP transaction
|
||||
*/
|
||||
static void
|
||||
raz_camelsrt_call (struct camelsrt_call_t *p_camelsrt_call)
|
||||
{
|
||||
memset(p_camelsrt_call,0,sizeof(struct camelsrt_call_t));
|
||||
}
|
|
@ -1,144 +0,0 @@
|
|||
/*
|
||||
* camel-persistentdata.h
|
||||
* Definitions for lists and hash tables used in wireshark's camel dissector
|
||||
* for calculation of delays in camel-transactions
|
||||
* Copyright 2006 Florent Drouin
|
||||
*
|
||||
* $Id$
|
||||
*
|
||||
* Wireshark - Network traffic analyzer
|
||||
* By Gerald Combs <gerald@wireshark.org>
|
||||
* Copyright 1998 Gerald Combs
|
||||
*
|
||||
* 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
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#ifndef __CAMEL_PERSISTENTDATA_H__
|
||||
#define __CAMEL_PERSISTENTDATA_H__
|
||||
|
||||
#include <epan/packet.h>
|
||||
#include <epan/conversation.h>
|
||||
#include <epan/dissectors/packet-camel.h>
|
||||
#include <epan/tcap-persistentdata.h>
|
||||
#include "ws_symbol_export.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
|
||||
/** @file
|
||||
*/
|
||||
#define NB_CAMELSRT_CATEGORY 9+1 /**< Number of type of message */
|
||||
/* for example TC_BEGIN with InitalDP, and TC_CONT with RequestReportBCSMEvent
|
||||
is a category, we want to measure the delay between the two messages */
|
||||
|
||||
#define CAMELSRT_SESSION 1
|
||||
|
||||
#define CAMELSRT_VOICE_INITIALDP 2
|
||||
#define CAMELSRT_VOICE_ACR1 3
|
||||
#define CAMELSRT_VOICE_ACR2 4
|
||||
#define CAMELSRT_VOICE_ACR3 5
|
||||
#define CAMELSRT_VOICE_DISC 6
|
||||
|
||||
#define CAMELSRT_GPRS_INITIALDP 7
|
||||
#define CAMELSRT_GPRS_REPORT 8
|
||||
|
||||
#define CAMELSRT_SMS_INITIALDP 9
|
||||
|
||||
WS_DLL_PUBLIC const value_string camelSRTtype_naming[];
|
||||
|
||||
/** If we have a request message and its response,
|
||||
(eg: ApplyCharging, ApplyChargingReport)
|
||||
the frames numbers are stored in this structure */
|
||||
|
||||
struct camelsrt_category_t {
|
||||
guint32 req_num; /**< frame number request seen */
|
||||
guint32 rsp_num; /**< frame number response seen */
|
||||
nstime_t req_time; /**< arrival time of request */
|
||||
gboolean responded; /**< true, if request has been responded */
|
||||
};
|
||||
|
||||
/** List of stored parameters for a Camel dialogue
|
||||
All this parameters are linked to the hash table key below (use of Tid)
|
||||
In case of same Tid reused, the Camel parameters are chained.
|
||||
The right dialogue will be identified with the arrival time of the InitialDP */
|
||||
|
||||
struct camelsrt_call_t {
|
||||
guint32 session_id; /**< Identify the session, with an internal number */
|
||||
struct tcaphash_context_t * tcap_context;
|
||||
struct camelsrt_category_t category[NB_CAMELSRT_CATEGORY];
|
||||
};
|
||||
|
||||
|
||||
/** The Key for the hash table is the TCAP origine transaction identifier
|
||||
of the TC_BEGIN containing the InitialDP */
|
||||
|
||||
struct camelsrt_call_info_key_t {
|
||||
guint32 SessionIdKey;
|
||||
};
|
||||
|
||||
/** Info for a couple of messages (or category)
|
||||
The request must be available, not duplicated,
|
||||
and once the corresponding response received,
|
||||
we can deduce the Delta Time between Request/response */
|
||||
|
||||
struct camelsrt_msginfo_t {
|
||||
gboolean request_available;
|
||||
gboolean is_duplicate;
|
||||
gboolean is_delta_time;
|
||||
nstime_t req_time;
|
||||
nstime_t delta_time;
|
||||
};
|
||||
|
||||
/** List of infos to store for the analyse */
|
||||
|
||||
struct camelsrt_info_t {
|
||||
guint32 tcap_session_id;
|
||||
void * tcap_context;
|
||||
guint8 opcode; /**< operation code of message received */
|
||||
guint8 bool_msginfo[NB_CAMELSRT_CATEGORY]; /**< category for the received message */
|
||||
struct camelsrt_msginfo_t msginfo[NB_CAMELSRT_CATEGORY];
|
||||
};
|
||||
|
||||
/**
|
||||
* Routine called when the TAP is initialized.
|
||||
* so hash table are (re)created
|
||||
*/
|
||||
void camelsrt_init_routine(void);
|
||||
|
||||
/**
|
||||
* Initialize the Message Info used by the main dissector
|
||||
* Data are linked to a TCAP transaction
|
||||
*/
|
||||
struct camelsrt_info_t * camelsrt_razinfo(void);
|
||||
|
||||
/**
|
||||
* Service Response Time analyze, called just after the camel dissector
|
||||
* According to the camel operation, we
|
||||
* - open/close a context for the camel session
|
||||
* - look for a request, or look for the corresponding response
|
||||
*/
|
||||
void camelsrt_call_matching(tvbuff_t *tvb,
|
||||
packet_info * pinfo _U_,
|
||||
proto_tree *tree,
|
||||
struct camelsrt_info_t * p_camel_info);
|
||||
|
||||
WS_DLL_PUBLIC gboolean gcamel_StatSRT;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif /* camel-persistentdata.h */
|
|
@ -46,7 +46,6 @@
|
|||
#include "packet-ber.h"
|
||||
#include "packet-tcap.h"
|
||||
#include "packet-ansi_tcap.h"
|
||||
#include <epan/tcap-persistentdata.h>
|
||||
|
||||
#define PNAME "ANSI Transaction Capabilities Application Part"
|
||||
#define PSNAME "ANSI_TCAP"
|
||||
|
@ -126,7 +125,7 @@ static int hf_ansi_tcap_paramSequence = -1; /* T_paramSequence */
|
|||
static int hf_ansi_tcap_paramSet = -1; /* T_paramSet */
|
||||
|
||||
/*--- End of included file: packet-ansi_tcap-hf.c ---*/
|
||||
#line 66 "../../asn1/ansi_tcap/packet-ansi_tcap-template.c"
|
||||
#line 65 "../../asn1/ansi_tcap/packet-ansi_tcap-template.c"
|
||||
|
||||
/* Initialize the subtree pointers */
|
||||
static gint ett_tcap = -1;
|
||||
|
@ -172,7 +171,7 @@ static gint ett_ansi_tcap_T_paramSequence = -1;
|
|||
static gint ett_ansi_tcap_T_paramSet = -1;
|
||||
|
||||
/*--- End of included file: packet-ansi_tcap-ett.c ---*/
|
||||
#line 85 "../../asn1/ansi_tcap/packet-ansi_tcap-template.c"
|
||||
#line 84 "../../asn1/ansi_tcap/packet-ansi_tcap-template.c"
|
||||
|
||||
#define MAX_SSN 254
|
||||
|
||||
|
@ -1395,7 +1394,7 @@ dissect_ansi_tcap_PackageType(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int
|
|||
|
||||
|
||||
/*--- End of included file: packet-ansi_tcap-fn.c ---*/
|
||||
#line 353 "../../asn1/ansi_tcap/packet-ansi_tcap-template.c"
|
||||
#line 352 "../../asn1/ansi_tcap/packet-ansi_tcap-template.c"
|
||||
|
||||
|
||||
|
||||
|
@ -1740,7 +1739,7 @@ proto_register_ansi_tcap(void)
|
|||
NULL, HFILL }},
|
||||
|
||||
/*--- End of included file: packet-ansi_tcap-hfarr.c ---*/
|
||||
#line 489 "../../asn1/ansi_tcap/packet-ansi_tcap-template.c"
|
||||
#line 488 "../../asn1/ansi_tcap/packet-ansi_tcap-template.c"
|
||||
};
|
||||
|
||||
/* Setup protocol subtree array */
|
||||
|
@ -1778,7 +1777,7 @@ proto_register_ansi_tcap(void)
|
|||
&ett_ansi_tcap_T_paramSet,
|
||||
|
||||
/*--- End of included file: packet-ansi_tcap-ettarr.c ---*/
|
||||
#line 500 "../../asn1/ansi_tcap/packet-ansi_tcap-template.c"
|
||||
#line 499 "../../asn1/ansi_tcap/packet-ansi_tcap-template.c"
|
||||
};
|
||||
|
||||
static const enum_val_t ansi_tcap_response_matching_type_values[] = {
|
||||
|
|
|
@ -63,8 +63,6 @@
|
|||
#include "packet-gsm_a_common.h"
|
||||
#include "packet-inap.h"
|
||||
#include "packet-tcap.h"
|
||||
#include <epan/camel-persistentdata.h>
|
||||
#include <epan/tcap-persistentdata.h>
|
||||
|
||||
#define PNAME "Camel"
|
||||
#define PSNAME "CAMEL"
|
||||
|
@ -78,6 +76,14 @@ int camel_tap = -1;
|
|||
static guint32 opcode=0;
|
||||
static guint32 errorCode=0;
|
||||
static guint32 camel_ver = 0;
|
||||
|
||||
/* When several Camel components are received in a single TCAP message,
|
||||
we have to use several buffers for the stored parameters
|
||||
because else this data are erased during TAP dissector call */
|
||||
#define MAX_CAMEL_INSTANCE 10
|
||||
static int camelsrt_global_current=0;
|
||||
static struct camelsrt_info_t camelsrt_global_info[MAX_CAMEL_INSTANCE];
|
||||
|
||||
/* ROSE context */
|
||||
static rose_ctx_t camel_rose_ctx;
|
||||
|
||||
|
@ -99,20 +105,20 @@ static int hf_camel_CAMEL_SCIBillingChargingCharacteristics = -1;
|
|||
static int hf_camel_CAMEL_SCIGPRSBillingChargingCharacteristics = -1;
|
||||
static int hf_camel_CAMEL_CallResult = -1;
|
||||
|
||||
/* Used by camel-persistentdata.c */
|
||||
int hf_camelsrt_SessionId=-1;
|
||||
int hf_camelsrt_RequestNumber=-1;
|
||||
int hf_camelsrt_Duplicate=-1;
|
||||
int hf_camelsrt_RequestFrame=-1;
|
||||
int hf_camelsrt_ResponseFrame=-1;
|
||||
int hf_camelsrt_DeltaTime=-1;
|
||||
int hf_camelsrt_SessionTime=-1;
|
||||
int hf_camelsrt_DeltaTime31=-1;
|
||||
int hf_camelsrt_DeltaTime75=-1;
|
||||
int hf_camelsrt_DeltaTime65=-1;
|
||||
int hf_camelsrt_DeltaTime22=-1;
|
||||
int hf_camelsrt_DeltaTime35=-1;
|
||||
int hf_camelsrt_DeltaTime80=-1;
|
||||
/* Used by persistent data */
|
||||
static int hf_camelsrt_SessionId=-1;
|
||||
static int hf_camelsrt_RequestNumber=-1;
|
||||
static int hf_camelsrt_Duplicate=-1;
|
||||
static int hf_camelsrt_RequestFrame=-1;
|
||||
static int hf_camelsrt_ResponseFrame=-1;
|
||||
static int hf_camelsrt_DeltaTime=-1;
|
||||
static int hf_camelsrt_SessionTime=-1;
|
||||
static int hf_camelsrt_DeltaTime31=-1;
|
||||
static int hf_camelsrt_DeltaTime75=-1;
|
||||
static int hf_camelsrt_DeltaTime65=-1;
|
||||
static int hf_camelsrt_DeltaTime22=-1;
|
||||
static int hf_camelsrt_DeltaTime35=-1;
|
||||
static int hf_camelsrt_DeltaTime80=-1;
|
||||
|
||||
|
||||
/*--- Included file: packet-camel-hf.c ---*/
|
||||
|
@ -603,7 +609,7 @@ static int hf_camel_present = -1; /* INTEGER */
|
|||
static int hf_camel_InvokeId_present = -1; /* InvokeId_present */
|
||||
|
||||
/*--- End of included file: packet-camel-hf.c ---*/
|
||||
#line 110 "../../asn1/camel/packet-camel-template.c"
|
||||
#line 116 "../../asn1/camel/packet-camel-template.c"
|
||||
|
||||
static struct camelsrt_info_t * gp_camelsrt_info;
|
||||
|
||||
|
@ -615,9 +621,10 @@ static int dissect_camel_CAMEL_AChBillingChargingCharacteristics(gboolean implic
|
|||
static int dissect_camel_CAMEL_AChBillingChargingCharacteristicsV2(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_);
|
||||
static int dissect_camel_CAMEL_CallResult(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_);
|
||||
|
||||
gboolean gcamel_HandleSRT=FALSE;
|
||||
extern gboolean gcamel_PersistentSRT;
|
||||
extern gboolean gcamel_DisplaySRT;
|
||||
static gboolean gcamel_HandleSRT=FALSE;
|
||||
static gboolean gcamel_PersistentSRT=FALSE;
|
||||
static gboolean gcamel_DisplaySRT=FALSE;
|
||||
static gboolean gcamel_StatSRT=FALSE;
|
||||
|
||||
/* Initialize the subtree pointers */
|
||||
static gint ett_camel = -1;
|
||||
|
@ -830,7 +837,7 @@ static gint ett_camel_T_problem = -1;
|
|||
static gint ett_camel_InvokeId = -1;
|
||||
|
||||
/*--- End of included file: packet-camel-ett.c ---*/
|
||||
#line 138 "../../asn1/camel/packet-camel-template.c"
|
||||
#line 145 "../../asn1/camel/packet-camel-template.c"
|
||||
|
||||
static expert_field ei_camel_unknown_invokeData = EI_INIT;
|
||||
static expert_field ei_camel_unknown_returnResultData = EI_INIT;
|
||||
|
@ -851,6 +858,10 @@ static guint8 PDPTypeNumber;
|
|||
const char *camel_obj_id = NULL;
|
||||
gboolean is_ExtensionField =FALSE;
|
||||
|
||||
/* Global hash tables*/
|
||||
static GHashTable *srt_calls = NULL;
|
||||
static guint32 camelsrt_global_SessionId=1;
|
||||
|
||||
static int camel_opcode_type;
|
||||
#define CAMEL_OPCODE_INVOKE 1
|
||||
#define CAMEL_OPCODE_RETURN_RESULT 2
|
||||
|
@ -865,6 +876,19 @@ static const value_string camel_Component_vals[] = {
|
|||
{ 0, NULL }
|
||||
};
|
||||
|
||||
const value_string camelSRTtype_naming[]= {
|
||||
{ CAMELSRT_SESSION, "TCAP_Session" },
|
||||
{ CAMELSRT_VOICE_INITIALDP, "InialDP/Continue" },
|
||||
{ CAMELSRT_VOICE_ACR1, "Slice1_ACR/ACH" },
|
||||
{ CAMELSRT_VOICE_ACR2, "Slice2_ACR/ACH" },
|
||||
{ CAMELSRT_VOICE_ACR3, "Slice3_ACR/ACH" },
|
||||
{ CAMELSRT_VOICE_DISC, "EvtRepBSCM/Release" },
|
||||
{ CAMELSRT_SMS_INITIALDP, "InitialDP/ContinueSMS" },
|
||||
{ CAMELSRT_GPRS_INITIALDP, "InitialDP/ContinueGPRS" },
|
||||
{ CAMELSRT_GPRS_REPORT, "EvtRepGPRS/ContinueGPRS" },
|
||||
{ 0,NULL}
|
||||
};
|
||||
|
||||
#if 0
|
||||
static const true_false_string camel_extension_value = {
|
||||
"No Extension",
|
||||
|
@ -1158,7 +1182,7 @@ static const value_string camel_ectTreatmentIndicator_values[] = {
|
|||
#define noInvokeId NULL
|
||||
|
||||
/*--- End of included file: packet-camel-val.h ---*/
|
||||
#line 281 "../../asn1/camel/packet-camel-template.c"
|
||||
#line 305 "../../asn1/camel/packet-camel-template.c"
|
||||
|
||||
|
||||
/*--- Included file: packet-camel-table.c ---*/
|
||||
|
@ -1248,7 +1272,29 @@ static const value_string camel_err_code_string_vals[] = {
|
|||
|
||||
|
||||
/*--- End of included file: packet-camel-table.c ---*/
|
||||
#line 283 "../../asn1/camel/packet-camel-template.c"
|
||||
#line 307 "../../asn1/camel/packet-camel-template.c"
|
||||
|
||||
/*
|
||||
* DEBUG fonctions
|
||||
*/
|
||||
|
||||
#undef DEBUG_CAMELSRT
|
||||
/* #define DEBUG_CAMELSRT */
|
||||
|
||||
#ifdef DEBUG_CAMELSRT
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
static guint debug_level = 99;
|
||||
|
||||
static void dbg(guint level, char *fmt, ...) {
|
||||
va_list ap;
|
||||
|
||||
if (level > debug_level) return;
|
||||
va_start(ap,fmt);
|
||||
vfprintf(stderr, fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
#endif
|
||||
|
||||
static char camel_number_to_char(int number)
|
||||
{
|
||||
|
@ -7011,7 +7057,7 @@ static void dissect_CAP_U_ABORT_REASON_PDU(tvbuff_t *tvb _U_, packet_info *pinfo
|
|||
|
||||
|
||||
/*--- End of included file: packet-camel-fn.c ---*/
|
||||
#line 330 "../../asn1/camel/packet-camel-template.c"
|
||||
#line 376 "../../asn1/camel/packet-camel-template.c"
|
||||
|
||||
|
||||
/*--- Included file: packet-camel-table2.c ---*/
|
||||
|
@ -7218,7 +7264,663 @@ static int dissect_returnErrorData(proto_tree *tree, tvbuff_t *tvb, int offset,a
|
|||
|
||||
|
||||
/*--- End of included file: packet-camel-table2.c ---*/
|
||||
#line 332 "../../asn1/camel/packet-camel-template.c"
|
||||
#line 378 "../../asn1/camel/packet-camel-template.c"
|
||||
|
||||
/*
|
||||
* Functions needed for Hash-Table
|
||||
*/
|
||||
|
||||
/* compare 2 keys */
|
||||
static gint
|
||||
camelsrt_call_equal(gconstpointer k1, gconstpointer k2)
|
||||
{
|
||||
const struct camelsrt_call_info_key_t *key1 = (const struct camelsrt_call_info_key_t *) k1;
|
||||
const struct camelsrt_call_info_key_t *key2 = (const struct camelsrt_call_info_key_t *) k2;
|
||||
|
||||
return (key1->SessionIdKey == key2->SessionIdKey) ;
|
||||
}
|
||||
|
||||
/* calculate a hash key */
|
||||
static guint
|
||||
camelsrt_call_hash(gconstpointer k)
|
||||
{
|
||||
const struct camelsrt_call_info_key_t *key = (const struct camelsrt_call_info_key_t *) k;
|
||||
return key->SessionIdKey;
|
||||
}
|
||||
|
||||
/*
|
||||
* Find the dialog by Key and Time
|
||||
*/
|
||||
static struct camelsrt_call_t *
|
||||
find_camelsrt_call(struct camelsrt_call_info_key_t *p_camelsrt_call_key)
|
||||
{
|
||||
struct camelsrt_call_t *p_camelsrt_call = NULL;
|
||||
p_camelsrt_call = (struct camelsrt_call_t *)g_hash_table_lookup(srt_calls, p_camelsrt_call_key);
|
||||
|
||||
#ifdef DEBUG_CAMELSRT
|
||||
if(p_camelsrt_call) {
|
||||
dbg(10,"D%d ", p_camelsrt_call->session_id);
|
||||
} else {
|
||||
dbg(23,"Not in hash ");
|
||||
}
|
||||
#endif
|
||||
|
||||
return p_camelsrt_call;
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialize the data per call for the Service Response Time Statistics
|
||||
* Data are linked to a Camel operation in a TCAP transaction
|
||||
*/
|
||||
static void
|
||||
raz_camelsrt_call (struct camelsrt_call_t *p_camelsrt_call)
|
||||
{
|
||||
memset(p_camelsrt_call,0,sizeof(struct camelsrt_call_t));
|
||||
}
|
||||
|
||||
/*
|
||||
* New record to create, to identify a new transaction
|
||||
*/
|
||||
static struct camelsrt_call_t *
|
||||
new_camelsrt_call(struct camelsrt_call_info_key_t *p_camelsrt_call_key)
|
||||
{
|
||||
struct camelsrt_call_info_key_t *p_new_camelsrt_call_key;
|
||||
struct camelsrt_call_t *p_new_camelsrt_call = NULL;
|
||||
|
||||
/* Register the transaction in the hash table
|
||||
with the tcap transaction Id as main Key
|
||||
Once created, this entry will be updated later */
|
||||
|
||||
p_new_camelsrt_call_key = se_new(struct camelsrt_call_info_key_t);
|
||||
p_new_camelsrt_call_key->SessionIdKey = p_camelsrt_call_key->SessionIdKey;
|
||||
p_new_camelsrt_call = se_new(struct camelsrt_call_t);
|
||||
raz_camelsrt_call(p_new_camelsrt_call);
|
||||
p_new_camelsrt_call->session_id = camelsrt_global_SessionId++;
|
||||
#ifdef DEBUG_CAMELSRT
|
||||
dbg(10,"D%d ", p_new_camelsrt_call->session_id);
|
||||
#endif
|
||||
/* store it */
|
||||
g_hash_table_insert(srt_calls, p_new_camelsrt_call_key, p_new_camelsrt_call);
|
||||
return p_new_camelsrt_call;
|
||||
}
|
||||
|
||||
/*
|
||||
* Routine called when the TAP is initialized.
|
||||
* so hash table are (re)created
|
||||
*/
|
||||
void
|
||||
camelsrt_init_routine(void)
|
||||
{
|
||||
|
||||
/* free hash-table for SRT */
|
||||
if (srt_calls != NULL) {
|
||||
#ifdef DEBUG_CAMELSRT
|
||||
dbg(16,"Destroy hash ");
|
||||
#endif
|
||||
g_hash_table_destroy(srt_calls);
|
||||
}
|
||||
|
||||
/* create new hash-table for SRT */
|
||||
srt_calls = g_hash_table_new(camelsrt_call_hash, camelsrt_call_equal);
|
||||
#ifdef DEBUG_CAMELSRT
|
||||
dbg(16,"Create hash ");
|
||||
#endif
|
||||
/* Reset the session counter */
|
||||
camelsrt_global_SessionId=1;
|
||||
|
||||
/* The Display of SRT is enable
|
||||
* 1) For wireshark only if Persistent Stat is enable
|
||||
* 2) For Tshark, if the SRT handling is enable
|
||||
*/
|
||||
gcamel_DisplaySRT=gcamel_PersistentSRT || gcamel_HandleSRT&gcamel_StatSRT;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Update a record with the data of the Request
|
||||
*/
|
||||
static void
|
||||
update_camelsrt_call(struct camelsrt_call_t *p_camelsrt_call, packet_info *pinfo,
|
||||
guint msg_category)
|
||||
{
|
||||
p_camelsrt_call->category[msg_category].req_num = pinfo->fd->num;
|
||||
p_camelsrt_call->category[msg_category].rsp_num = 0;
|
||||
p_camelsrt_call->category[msg_category].responded = FALSE;
|
||||
p_camelsrt_call->category[msg_category].req_time = pinfo->fd->abs_ts;
|
||||
}
|
||||
|
||||
/*
|
||||
* Update the Camel session info, and close the session.
|
||||
* Then remove the associated context, if we do not have persistentSRT enable
|
||||
*/
|
||||
static void
|
||||
camelsrt_close_call_matching(packet_info *pinfo,
|
||||
struct camelsrt_info_t *p_camelsrt_info)
|
||||
{
|
||||
struct camelsrt_call_t *p_camelsrt_call;
|
||||
struct camelsrt_call_info_key_t camelsrt_call_key;
|
||||
nstime_t delta;
|
||||
|
||||
p_camelsrt_info->bool_msginfo[CAMELSRT_SESSION]=TRUE;
|
||||
#ifdef DEBUG_CAMELSRT
|
||||
dbg(10,"\n Session end #%u\n", pinfo->fd->num);
|
||||
#endif
|
||||
/* look only for matching request, if matching conversation is available. */
|
||||
camelsrt_call_key.SessionIdKey = p_camelsrt_info->tcap_session_id;
|
||||
|
||||
#ifdef DEBUG_CAMELSRT
|
||||
dbg(11,"Search key %lu ",camelsrt_call_key.SessionIdKey);
|
||||
#endif
|
||||
p_camelsrt_call = find_camelsrt_call(&camelsrt_call_key);
|
||||
if(p_camelsrt_call) {
|
||||
#ifdef DEBUG_CAMELSRT
|
||||
dbg(12,"Found ");
|
||||
#endif
|
||||
/* Calculate Service Response Time */
|
||||
nstime_delta(&delta, &pinfo->fd->abs_ts, &p_camelsrt_call->category[CAMELSRT_SESSION].req_time);
|
||||
p_camelsrt_call->category[CAMELSRT_SESSION].responded = TRUE;
|
||||
p_camelsrt_info->msginfo[CAMELSRT_SESSION].request_available = TRUE;
|
||||
p_camelsrt_info->msginfo[CAMELSRT_SESSION].is_delta_time = TRUE;
|
||||
p_camelsrt_info->msginfo[CAMELSRT_SESSION].delta_time = delta; /* give it to tap */
|
||||
p_camelsrt_info->msginfo[CAMELSRT_SESSION].req_time = p_camelsrt_call->category[CAMELSRT_SESSION].req_time;
|
||||
|
||||
if ( !gcamel_PersistentSRT ) {
|
||||
g_hash_table_remove(srt_calls, &camelsrt_call_key);
|
||||
#ifdef DEBUG_CAMELSRT
|
||||
dbg(20,"remove hash ");
|
||||
#endif
|
||||
} else {
|
||||
#ifdef DEBUG_CAMELSRT
|
||||
dbg(20,"keep hash ");
|
||||
#endif
|
||||
}
|
||||
} /* call reference found */
|
||||
}
|
||||
|
||||
/*
|
||||
* Callback function for the TCAP dissector
|
||||
* This callback function is used to inform the camel layer, that the session
|
||||
* has been Closed or Aborted by a TCAP message without Camel component
|
||||
* So, we can close the context for camel session, and update the stats.
|
||||
*/
|
||||
static void
|
||||
camelsrt_tcap_matching(tvbuff_t *tvb _U_, packet_info *pinfo,
|
||||
proto_tree *tree _U_,
|
||||
struct tcaphash_context_t *p_tcap_context)
|
||||
{
|
||||
struct camelsrt_info_t *p_camelsrt_info;
|
||||
|
||||
#ifdef DEBUG_CAMELSRT
|
||||
dbg(11,"Camel_CallBack ");
|
||||
#endif
|
||||
p_camelsrt_info=camelsrt_razinfo();
|
||||
|
||||
p_camelsrt_info->tcap_context=p_tcap_context;
|
||||
if (p_tcap_context) {
|
||||
#ifdef DEBUG_CAMELSRT
|
||||
dbg(11,"Close TCAP ");
|
||||
#endif
|
||||
p_camelsrt_info->tcap_session_id = p_tcap_context->session_id;
|
||||
camelsrt_close_call_matching(pinfo, p_camelsrt_info);
|
||||
tap_queue_packet(camel_tap, pinfo, p_camelsrt_info);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Create the record identifiying the Camel session
|
||||
* As the Tcap session id given by the TCAP dissector is uniq, it will be
|
||||
* used as main key.
|
||||
*/
|
||||
static void
|
||||
camelsrt_begin_call_matching(packet_info *pinfo,
|
||||
struct camelsrt_info_t *p_camelsrt_info)
|
||||
{
|
||||
struct camelsrt_call_t *p_camelsrt_call;
|
||||
struct camelsrt_call_info_key_t camelsrt_call_key;
|
||||
|
||||
p_camelsrt_info->bool_msginfo[CAMELSRT_SESSION]=TRUE;
|
||||
|
||||
/* prepare the key data */
|
||||
camelsrt_call_key.SessionIdKey = p_camelsrt_info->tcap_session_id;
|
||||
|
||||
/* look up the request */
|
||||
#ifdef DEBUG_CAMELSRT
|
||||
dbg(10,"\n Session begin #%u\n", pinfo->fd->num);
|
||||
dbg(11,"Search key %lu ",camelsrt_call_key.SessionIdKey);
|
||||
#endif
|
||||
p_camelsrt_call = (struct camelsrt_call_t *)g_hash_table_lookup(srt_calls, &camelsrt_call_key);
|
||||
if (p_camelsrt_call) {
|
||||
/* We have seen this request before -> do nothing */
|
||||
#ifdef DEBUG_CAMELSRT
|
||||
dbg(22,"Already seen ");
|
||||
#endif
|
||||
} else { /* p_camelsrt_call has not been found */
|
||||
#ifdef DEBUG_CAMELSRT
|
||||
dbg(10,"New key %lu ",camelsrt_call_key.SessionIdKey);
|
||||
#endif
|
||||
p_camelsrt_call = new_camelsrt_call(&camelsrt_call_key);
|
||||
p_camelsrt_call->tcap_context=(struct tcaphash_context_t *)p_camelsrt_info->tcap_context;
|
||||
update_camelsrt_call(p_camelsrt_call, pinfo,CAMELSRT_SESSION);
|
||||
|
||||
#ifdef DEBUG_CAMELSRT
|
||||
dbg(11,"Update Callback ");
|
||||
#endif
|
||||
p_camelsrt_call->tcap_context->callback=camelsrt_tcap_matching;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Register the request, and try to find the response
|
||||
*
|
||||
*/
|
||||
static void
|
||||
camelsrt_request_call_matching(tvbuff_t *tvb, packet_info *pinfo,
|
||||
proto_tree *tree,
|
||||
struct camelsrt_info_t *p_camelsrt_info,
|
||||
guint srt_type )
|
||||
{
|
||||
struct camelsrt_call_t *p_camelsrt_call;
|
||||
struct camelsrt_call_info_key_t camelsrt_call_key;
|
||||
proto_item *ti, *hidden_item;
|
||||
|
||||
#ifdef DEBUG_CAMELSRT
|
||||
dbg(10,"\n %s #%u\n", val_to_str_const(srt_type, camelSRTtype_naming, "Unk"),pinfo->fd->num);
|
||||
#endif
|
||||
|
||||
/* look only for matching request, if matching conversation is available. */
|
||||
camelsrt_call_key.SessionIdKey = p_camelsrt_info->tcap_session_id;
|
||||
|
||||
#ifdef DEBUG_CAMELSRT
|
||||
dbg(11,"Search key %lu ", camelsrt_call_key.SessionIdKey);
|
||||
#endif
|
||||
p_camelsrt_call = find_camelsrt_call(&camelsrt_call_key);
|
||||
if(p_camelsrt_call) {
|
||||
#ifdef DEBUG_CAMELSRT
|
||||
dbg(12,"Found ");
|
||||
#endif
|
||||
if (gcamel_DisplaySRT)
|
||||
proto_tree_add_uint(tree, hf_camelsrt_SessionId, tvb, 0,0, p_camelsrt_call->session_id);
|
||||
|
||||
|
||||
/* Hmm.. As there are several slices ApplyChargingReport/ApplyCharging
|
||||
* we will prepare the measurement for 3 slices with 3 categories */
|
||||
if (srt_type==CAMELSRT_VOICE_ACR1) {
|
||||
if (p_camelsrt_call->category[CAMELSRT_VOICE_ACR1].req_num == 0) {
|
||||
srt_type=CAMELSRT_VOICE_ACR1;
|
||||
} else if ( (p_camelsrt_call->category[CAMELSRT_VOICE_ACR2].req_num == 0)
|
||||
&& (p_camelsrt_call->category[CAMELSRT_VOICE_ACR1].rsp_num != 0)
|
||||
&& (p_camelsrt_call->category[CAMELSRT_VOICE_ACR1].rsp_num < pinfo->fd->num) ) {
|
||||
srt_type=CAMELSRT_VOICE_ACR2;
|
||||
} else if ( (p_camelsrt_call->category[CAMELSRT_VOICE_ACR3].req_num == 0)
|
||||
&& (p_camelsrt_call->category[CAMELSRT_VOICE_ACR2].rsp_num != 0)
|
||||
&& (p_camelsrt_call->category[CAMELSRT_VOICE_ACR2].rsp_num < pinfo->fd->num) ) {
|
||||
srt_type=CAMELSRT_VOICE_ACR3;
|
||||
} else if (p_camelsrt_call->category[CAMELSRT_VOICE_ACR1].rsp_num != 0
|
||||
&& p_camelsrt_call->category[CAMELSRT_VOICE_ACR1].rsp_num > pinfo->fd->num) {
|
||||
srt_type=CAMELSRT_VOICE_ACR1;
|
||||
} else if ( p_camelsrt_call->category[CAMELSRT_VOICE_ACR2].rsp_num != 0
|
||||
&& p_camelsrt_call->category[CAMELSRT_VOICE_ACR2].rsp_num > pinfo->fd->num) {
|
||||
srt_type=CAMELSRT_VOICE_ACR2;
|
||||
} else if (p_camelsrt_call->category[CAMELSRT_VOICE_ACR1].rsp_num != 0
|
||||
&& p_camelsrt_call->category[CAMELSRT_VOICE_ACR3].rsp_num > pinfo->fd->num) {
|
||||
srt_type=CAMELSRT_VOICE_ACR3;
|
||||
}
|
||||
#ifdef DEBUG_CAMELSRT
|
||||
dbg(70,"Request ACR %u ",srt_type);
|
||||
dbg(70,"ACR1 %u %u",p_camelsrt_call->category[CAMELSRT_VOICE_ACR1].req_num, p_camelsrt_call->category[CAMELSRT_VOICE_ACR1].rsp_num);
|
||||
dbg(70,"ACR2 %u %u",p_camelsrt_call->category[CAMELSRT_VOICE_ACR2].req_num, p_camelsrt_call->category[CAMELSRT_VOICE_ACR2].rsp_num);
|
||||
dbg(70,"ACR3 %u %u",p_camelsrt_call->category[CAMELSRT_VOICE_ACR3].req_num, p_camelsrt_call->category[CAMELSRT_VOICE_ACR3].rsp_num);
|
||||
#endif
|
||||
} /* not ACR */
|
||||
p_camelsrt_info->bool_msginfo[srt_type]=TRUE;
|
||||
|
||||
|
||||
if (p_camelsrt_call->category[srt_type].req_num == 0) {
|
||||
/* We have not yet seen a request to that call, so this must be the first request
|
||||
remember its frame number. */
|
||||
#ifdef DEBUG_CAMELSRT
|
||||
dbg(5,"Set reqlink #%u ", pinfo->fd->num);
|
||||
#endif
|
||||
update_camelsrt_call(p_camelsrt_call, pinfo, srt_type);
|
||||
} else {
|
||||
/* We have seen a request to this call - but was it *this* request? */
|
||||
if (p_camelsrt_call->category[srt_type].req_num != pinfo->fd->num) {
|
||||
|
||||
if (srt_type!=CAMELSRT_VOICE_DISC) {
|
||||
/* No, so it's a duplicate resquest. Mark it as such. */
|
||||
#ifdef DEBUG_CAMELSRT
|
||||
dbg(21,"Display_duplicate with req %d ", p_camelsrt_call->category[srt_type].req_num);
|
||||
#endif
|
||||
p_camelsrt_info->msginfo[srt_type].is_duplicate = TRUE;
|
||||
if (gcamel_DisplaySRT){
|
||||
hidden_item = proto_tree_add_uint(tree, hf_camelsrt_Duplicate, tvb, 0,0, 77);
|
||||
PROTO_ITEM_SET_HIDDEN(hidden_item);
|
||||
}
|
||||
|
||||
} else {
|
||||
/* Ignore duplicate frame */
|
||||
if (pinfo->fd->num > p_camelsrt_call->category[srt_type].req_num) {
|
||||
p_camelsrt_call->category[srt_type].req_num = pinfo->fd->num;
|
||||
#ifdef DEBUG_CAMELSRT
|
||||
dbg(5,"DISC Set reqlink #%u ", pinfo->fd->num);
|
||||
#endif
|
||||
update_camelsrt_call(p_camelsrt_call, pinfo, srt_type);
|
||||
} /* greater frame */
|
||||
} /* DISC */
|
||||
} /* req_num already seen */
|
||||
} /* req_num != 0 */
|
||||
|
||||
/* add link to response frame, if available */
|
||||
if ( gcamel_DisplaySRT &&
|
||||
(p_camelsrt_call->category[srt_type].rsp_num != 0) &&
|
||||
(p_camelsrt_call->category[srt_type].req_num != 0) &&
|
||||
(p_camelsrt_call->category[srt_type].req_num == pinfo->fd->num) ) {
|
||||
#ifdef DEBUG_CAMELSRT
|
||||
dbg(20,"Display_framersplink %d ",p_camelsrt_call->category[srt_type].rsp_num);
|
||||
#endif
|
||||
ti = proto_tree_add_uint_format(tree, hf_camelsrt_RequestFrame, tvb, 0, 0,
|
||||
p_camelsrt_call->category[srt_type].rsp_num,
|
||||
"Linked response %s in frame %u",
|
||||
val_to_str_const(srt_type, camelSRTtype_naming, "Unk"),
|
||||
p_camelsrt_call->category[srt_type].rsp_num);
|
||||
PROTO_ITEM_SET_GENERATED(ti);
|
||||
} /* frame valid */
|
||||
} /* call reference */
|
||||
}
|
||||
|
||||
/*
|
||||
* Display the delta time between two messages in a field corresponding
|
||||
* to the category (hf_camelsrt_DeltaTimexx).
|
||||
*/
|
||||
static void
|
||||
camelsrt_display_DeltaTime(proto_tree *tree, tvbuff_t *tvb, nstime_t *value_ptr,
|
||||
guint category)
|
||||
{
|
||||
proto_item *ti;
|
||||
|
||||
if ( gcamel_DisplaySRT ) {
|
||||
switch(category) {
|
||||
case CAMELSRT_VOICE_INITIALDP:
|
||||
ti = proto_tree_add_time(tree, hf_camelsrt_DeltaTime31, tvb, 0, 0, value_ptr);
|
||||
PROTO_ITEM_SET_GENERATED(ti);
|
||||
break;
|
||||
|
||||
case CAMELSRT_VOICE_ACR1:
|
||||
case CAMELSRT_VOICE_ACR2:
|
||||
case CAMELSRT_VOICE_ACR3:
|
||||
ti = proto_tree_add_time(tree, hf_camelsrt_DeltaTime22, tvb, 0, 0, value_ptr);
|
||||
PROTO_ITEM_SET_GENERATED(ti);
|
||||
break;
|
||||
|
||||
case CAMELSRT_VOICE_DISC:
|
||||
ti = proto_tree_add_time(tree, hf_camelsrt_DeltaTime35, tvb, 0, 0, value_ptr);
|
||||
PROTO_ITEM_SET_GENERATED(ti);
|
||||
break;
|
||||
|
||||
case CAMELSRT_GPRS_INITIALDP:
|
||||
ti = proto_tree_add_time(tree, hf_camelsrt_DeltaTime75, tvb, 0, 0, value_ptr);
|
||||
PROTO_ITEM_SET_GENERATED(ti);
|
||||
break;
|
||||
|
||||
case CAMELSRT_GPRS_REPORT:
|
||||
ti = proto_tree_add_time(tree, hf_camelsrt_DeltaTime80, tvb, 0, 0, value_ptr);
|
||||
PROTO_ITEM_SET_GENERATED(ti);
|
||||
break;
|
||||
|
||||
case CAMELSRT_SMS_INITIALDP:
|
||||
ti = proto_tree_add_time(tree, hf_camelsrt_DeltaTime65, tvb, 0, 0, value_ptr);
|
||||
PROTO_ITEM_SET_GENERATED(ti);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Check if the received message is a response to a previous request
|
||||
* registered is the camel session context.
|
||||
*/
|
||||
static void
|
||||
camelsrt_report_call_matching(tvbuff_t *tvb, packet_info *pinfo,
|
||||
proto_tree *tree,
|
||||
struct camelsrt_info_t *p_camelsrt_info,
|
||||
guint srt_type)
|
||||
{
|
||||
struct camelsrt_call_t *p_camelsrt_call;
|
||||
struct camelsrt_call_info_key_t camelsrt_call_key;
|
||||
nstime_t delta;
|
||||
proto_item *ti, *hidden_item;
|
||||
|
||||
#ifdef DEBUG_CAMELSRT
|
||||
dbg(10,"\n %s #%u\n", val_to_str_const(srt_type, camelSRTtype_naming, "Unk"),pinfo->fd->num);
|
||||
#endif
|
||||
camelsrt_call_key.SessionIdKey = p_camelsrt_info->tcap_session_id;
|
||||
/* look only for matching request, if matching conversation is available. */
|
||||
|
||||
#ifdef DEBUG_CAMELSRT
|
||||
dbg(11,"Search key %lu ",camelsrt_call_key.SessionIdKey);
|
||||
#endif
|
||||
p_camelsrt_call = find_camelsrt_call(&camelsrt_call_key);
|
||||
if(p_camelsrt_call) {
|
||||
#ifdef DEBUG_CAMELSRT
|
||||
dbg(12,"Found, req=%d ",p_camelsrt_call->category[srt_type].req_num);
|
||||
#endif
|
||||
if ( gcamel_DisplaySRT )
|
||||
proto_tree_add_uint(tree, hf_camelsrt_SessionId, tvb, 0,0, p_camelsrt_call->session_id);
|
||||
|
||||
if (srt_type==CAMELSRT_VOICE_ACR1) {
|
||||
if (p_camelsrt_call->category[CAMELSRT_VOICE_ACR3].req_num != 0
|
||||
&& p_camelsrt_call->category[CAMELSRT_VOICE_ACR3].req_num < pinfo->fd->num) {
|
||||
srt_type=CAMELSRT_VOICE_ACR1;
|
||||
} else if ( p_camelsrt_call->category[CAMELSRT_VOICE_ACR2].req_num != 0
|
||||
&& p_camelsrt_call->category[CAMELSRT_VOICE_ACR2].req_num < pinfo->fd->num) {
|
||||
srt_type=CAMELSRT_VOICE_ACR2;
|
||||
} else if (p_camelsrt_call->category[CAMELSRT_VOICE_ACR1].req_num != 0
|
||||
&& p_camelsrt_call->category[CAMELSRT_VOICE_ACR1].req_num < pinfo->fd->num) {
|
||||
srt_type=CAMELSRT_VOICE_ACR1;
|
||||
}
|
||||
#ifdef DEBUG_CAMELSRT
|
||||
dbg(70,"Report ACR %u ",srt_type);
|
||||
#endif
|
||||
} /* not ACR */
|
||||
p_camelsrt_info->bool_msginfo[srt_type]=TRUE;
|
||||
|
||||
if (p_camelsrt_call->category[srt_type].rsp_num == 0) {
|
||||
if ( (p_camelsrt_call->category[srt_type].req_num != 0)
|
||||
&& (pinfo->fd->num > p_camelsrt_call->category[srt_type].req_num) ){
|
||||
/* We have not yet seen a response to that call, so this must be the first response;
|
||||
remember its frame number only if response comes after request */
|
||||
#ifdef DEBUG_CAMELSRT
|
||||
dbg(14,"Set reslink #%d req %u ",pinfo->fd->num, p_camelsrt_call->category[srt_type].req_num);
|
||||
#endif
|
||||
p_camelsrt_call->category[srt_type].rsp_num = pinfo->fd->num;
|
||||
|
||||
} else {
|
||||
#ifdef DEBUG_CAMELSRT
|
||||
dbg(2,"badreslink #%u req %u ",pinfo->fd->num, p_camelsrt_call->category[srt_type].req_num);
|
||||
#endif
|
||||
} /* req_num != 0 */
|
||||
} else { /* rsp_num != 0 */
|
||||
/* We have seen a response to this call - but was it *this* response? */
|
||||
if (p_camelsrt_call->category[srt_type].rsp_num != pinfo->fd->num) {
|
||||
/* No, so it's a duplicate response. Mark it as such. */
|
||||
#ifdef DEBUG_CAMELSRT
|
||||
dbg(21,"Display_duplicate rsp=%d ", p_camelsrt_call->category[srt_type].rsp_num);
|
||||
#endif
|
||||
p_camelsrt_info->msginfo[srt_type].is_duplicate = TRUE;
|
||||
if ( gcamel_DisplaySRT ){
|
||||
hidden_item = proto_tree_add_uint(tree, hf_camelsrt_Duplicate, tvb, 0,0, 77);
|
||||
PROTO_ITEM_SET_HIDDEN(hidden_item);
|
||||
}
|
||||
}
|
||||
} /* rsp_num != 0 */
|
||||
|
||||
if ( (p_camelsrt_call->category[srt_type].req_num != 0) &&
|
||||
(p_camelsrt_call->category[srt_type].rsp_num != 0) &&
|
||||
(p_camelsrt_call->category[srt_type].rsp_num == pinfo->fd->num) ) {
|
||||
|
||||
p_camelsrt_call->category[srt_type].responded = TRUE;
|
||||
p_camelsrt_info->msginfo[srt_type].request_available = TRUE;
|
||||
#ifdef DEBUG_CAMELSRT
|
||||
dbg(20,"Display_frameReqlink %d ",p_camelsrt_call->category[srt_type].req_num);
|
||||
#endif
|
||||
/* Indicate the frame to which this is a reply. */
|
||||
if ( gcamel_DisplaySRT ) {
|
||||
ti = proto_tree_add_uint_format(tree, hf_camelsrt_ResponseFrame, tvb, 0, 0,
|
||||
p_camelsrt_call->category[srt_type].req_num,
|
||||
"Linked request %s in frame %u",
|
||||
val_to_str_const(srt_type, camelSRTtype_naming, "Unk"),
|
||||
p_camelsrt_call->category[srt_type].req_num);
|
||||
PROTO_ITEM_SET_GENERATED(ti);
|
||||
}
|
||||
/* Calculate Service Response Time */
|
||||
nstime_delta(&delta, &pinfo->fd->abs_ts, &p_camelsrt_call->category[srt_type].req_time);
|
||||
|
||||
p_camelsrt_info->msginfo[srt_type].is_delta_time = TRUE;
|
||||
p_camelsrt_info->msginfo[srt_type].delta_time = delta; /* give it to tap */
|
||||
p_camelsrt_info->msginfo[srt_type].req_time = p_camelsrt_call->category[srt_type].req_time;
|
||||
|
||||
/* display Service Response Time and make it filterable */
|
||||
camelsrt_display_DeltaTime(tree, tvb, &delta, srt_type);
|
||||
|
||||
} /*req_num != 0 && not duplicate */
|
||||
} /* call reference found */
|
||||
}
|
||||
|
||||
/*
|
||||
* Service Response Time analyze, called just after the camel dissector
|
||||
* According to the camel operation, we
|
||||
* - open/close a context for the camel session
|
||||
* - look for a request, or look for the corresponding response
|
||||
*/
|
||||
void
|
||||
camelsrt_call_matching(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
|
||||
struct camelsrt_info_t *p_camelsrt_info)
|
||||
{
|
||||
|
||||
#ifdef DEBUG_CAMELSRT
|
||||
dbg(10,"tcap_session #%d ", p_camelsrt_info->tcap_session_id);
|
||||
#endif
|
||||
|
||||
switch (p_camelsrt_info->opcode) {
|
||||
|
||||
case 0: /*InitialDP*/
|
||||
camelsrt_begin_call_matching(pinfo, p_camelsrt_info);
|
||||
camelsrt_request_call_matching(tvb, pinfo, tree, p_camelsrt_info,
|
||||
CAMELSRT_VOICE_INITIALDP);
|
||||
break;
|
||||
case 60: /*InitialDPSMS*/
|
||||
camelsrt_begin_call_matching(pinfo, p_camelsrt_info);
|
||||
camelsrt_request_call_matching(tvb, pinfo, tree, p_camelsrt_info,
|
||||
CAMELSRT_SMS_INITIALDP);
|
||||
break;
|
||||
case 78: /*InitialDPGPRS*/
|
||||
camelsrt_begin_call_matching(pinfo, p_camelsrt_info);
|
||||
camelsrt_request_call_matching(tvb, pinfo, tree, p_camelsrt_info,
|
||||
CAMELSRT_GPRS_INITIALDP);
|
||||
break;
|
||||
|
||||
case 23: /*RequestReportBCSMEvent*/
|
||||
break;
|
||||
|
||||
case 63: /*RequestReportSMSEvent*/
|
||||
break;
|
||||
|
||||
case 81: /*RequestReportGPRSEvent*/
|
||||
break;
|
||||
|
||||
case 24: /*EventReportBCSMEvent*/
|
||||
camelsrt_request_call_matching(tvb, pinfo, tree, p_camelsrt_info,
|
||||
CAMELSRT_VOICE_DISC );
|
||||
break;
|
||||
|
||||
case 64: /*EventReportSMS*/
|
||||
/* Session has been explicity closed without TC_END */
|
||||
camelsrt_close_call_matching(pinfo, p_camelsrt_info);
|
||||
tcapsrt_close((struct tcaphash_context_t *)p_camelsrt_info->tcap_context, pinfo);
|
||||
break;
|
||||
|
||||
case 80: /*EventReportGPRS*/
|
||||
camelsrt_begin_call_matching(pinfo, p_camelsrt_info);
|
||||
camelsrt_request_call_matching(tvb, pinfo, tree, p_camelsrt_info,
|
||||
CAMELSRT_GPRS_REPORT);
|
||||
break;
|
||||
|
||||
case 35: /*ApplyCharging*/
|
||||
camelsrt_report_call_matching(tvb, pinfo, tree, p_camelsrt_info,
|
||||
CAMELSRT_VOICE_ACR1 );
|
||||
break;
|
||||
|
||||
case 71: /*ApplyChargingGPRS*/
|
||||
break;
|
||||
|
||||
case 36: /*ApplyChargingReport*/
|
||||
camelsrt_request_call_matching(tvb, pinfo, tree, p_camelsrt_info,
|
||||
CAMELSRT_VOICE_ACR1 );
|
||||
break;
|
||||
|
||||
case 72: /*ApplyChargingReportGPRS*/
|
||||
break;
|
||||
|
||||
case 31: /*Continue*/
|
||||
camelsrt_report_call_matching(tvb, pinfo, tree, p_camelsrt_info,
|
||||
CAMELSRT_VOICE_INITIALDP);
|
||||
break;
|
||||
case 65: /*ContinueSMS*/
|
||||
camelsrt_report_call_matching(tvb, pinfo, tree, p_camelsrt_info,
|
||||
CAMELSRT_SMS_INITIALDP);
|
||||
break;
|
||||
case 75: /*ContinueGPRS*/
|
||||
camelsrt_report_call_matching(tvb, pinfo, tree, p_camelsrt_info,
|
||||
CAMELSRT_GPRS_INITIALDP);
|
||||
camelsrt_report_call_matching(tvb, pinfo, tree, p_camelsrt_info,
|
||||
CAMELSRT_GPRS_REPORT);
|
||||
break;
|
||||
|
||||
case 22: /*ReleaseCall*/
|
||||
camelsrt_report_call_matching(tvb, pinfo, tree, p_camelsrt_info,
|
||||
CAMELSRT_VOICE_DISC);
|
||||
/* Session has been closed by Network */
|
||||
camelsrt_close_call_matching(pinfo, p_camelsrt_info);
|
||||
break;
|
||||
|
||||
case 66: /*ReleaseSMS*/
|
||||
/* Session has been closed by Network */
|
||||
camelsrt_close_call_matching(pinfo, p_camelsrt_info);
|
||||
tcapsrt_close((struct tcaphash_context_t *)p_camelsrt_info->tcap_context,pinfo);
|
||||
break;
|
||||
|
||||
case 79: /*ReleaseGPRS*/
|
||||
/* Session has been closed by Network */
|
||||
camelsrt_close_call_matching(pinfo, p_camelsrt_info);
|
||||
break;
|
||||
} /* switch opcode */
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialize the Message Info used by the main dissector
|
||||
* Data are linked to a TCAP transaction
|
||||
*/
|
||||
struct camelsrt_info_t *
|
||||
camelsrt_razinfo(void)
|
||||
{
|
||||
struct camelsrt_info_t *p_camelsrt_info ;
|
||||
|
||||
/* Global buffer for packet extraction */
|
||||
camelsrt_global_current++;
|
||||
if(camelsrt_global_current==MAX_CAMEL_INSTANCE){
|
||||
camelsrt_global_current=0;
|
||||
}
|
||||
|
||||
p_camelsrt_info=&camelsrt_global_info[camelsrt_global_current];
|
||||
memset(p_camelsrt_info,0,sizeof(struct camelsrt_info_t));
|
||||
|
||||
p_camelsrt_info->opcode=255;
|
||||
|
||||
return p_camelsrt_info;
|
||||
}
|
||||
|
||||
|
||||
static guint8 camel_pdu_type = 0;
|
||||
|
@ -7417,7 +8119,7 @@ void proto_reg_handoff_camel(void) {
|
|||
|
||||
|
||||
/*--- End of included file: packet-camel-dis-tab.c ---*/
|
||||
#line 523 "../../asn1/camel/packet-camel-template.c"
|
||||
#line 1225 "../../asn1/camel/packet-camel-template.c"
|
||||
} else {
|
||||
range_foreach(ssn_range, range_delete_callback);
|
||||
g_free(ssn_range);
|
||||
|
@ -9531,7 +10233,7 @@ void proto_register_camel(void) {
|
|||
"InvokeId_present", HFILL }},
|
||||
|
||||
/*--- End of included file: packet-camel-hfarr.c ---*/
|
||||
#line 696 "../../asn1/camel/packet-camel-template.c"
|
||||
#line 1398 "../../asn1/camel/packet-camel-template.c"
|
||||
};
|
||||
|
||||
/* List of subtrees */
|
||||
|
@ -9746,7 +10448,7 @@ void proto_register_camel(void) {
|
|||
&ett_camel_InvokeId,
|
||||
|
||||
/*--- End of included file: packet-camel-ettarr.c ---*/
|
||||
#line 712 "../../asn1/camel/packet-camel-template.c"
|
||||
#line 1414 "../../asn1/camel/packet-camel-template.c"
|
||||
};
|
||||
|
||||
static ei_register_info ei[] = {
|
||||
|
|
|
@ -54,4 +54,103 @@ void proto_register_camel(void);
|
|||
WS_DLL_PUBLIC const value_string camel_opr_code_strings[];
|
||||
/* #include "packet-camel-exp.h"*/
|
||||
|
||||
/** @file
|
||||
*/
|
||||
#define NB_CAMELSRT_CATEGORY 9+1 /**< Number of type of message */
|
||||
/* for example TC_BEGIN with InitalDP, and TC_CONT with RequestReportBCSMEvent
|
||||
is a category, we want to measure the delay between the two messages */
|
||||
|
||||
#define CAMELSRT_SESSION 1
|
||||
|
||||
#define CAMELSRT_VOICE_INITIALDP 2
|
||||
#define CAMELSRT_VOICE_ACR1 3
|
||||
#define CAMELSRT_VOICE_ACR2 4
|
||||
#define CAMELSRT_VOICE_ACR3 5
|
||||
#define CAMELSRT_VOICE_DISC 6
|
||||
|
||||
#define CAMELSRT_GPRS_INITIALDP 7
|
||||
#define CAMELSRT_GPRS_REPORT 8
|
||||
|
||||
#define CAMELSRT_SMS_INITIALDP 9
|
||||
|
||||
WS_DLL_PUBLIC const value_string camelSRTtype_naming[];
|
||||
|
||||
/** If we have a request message and its response,
|
||||
(eg: ApplyCharging, ApplyChargingReport)
|
||||
the frames numbers are stored in this structure */
|
||||
|
||||
struct camelsrt_category_t {
|
||||
guint32 req_num; /**< frame number request seen */
|
||||
guint32 rsp_num; /**< frame number response seen */
|
||||
nstime_t req_time; /**< arrival time of request */
|
||||
gboolean responded; /**< true, if request has been responded */
|
||||
};
|
||||
|
||||
/** List of stored parameters for a Camel dialogue
|
||||
All this parameters are linked to the hash table key below (use of Tid)
|
||||
In case of same Tid reused, the Camel parameters are chained.
|
||||
The right dialogue will be identified with the arrival time of the InitialDP */
|
||||
|
||||
struct camelsrt_call_t {
|
||||
guint32 session_id; /**< Identify the session, with an internal number */
|
||||
struct tcaphash_context_t * tcap_context;
|
||||
struct camelsrt_category_t category[NB_CAMELSRT_CATEGORY];
|
||||
};
|
||||
|
||||
|
||||
/** The Key for the hash table is the TCAP origine transaction identifier
|
||||
of the TC_BEGIN containing the InitialDP */
|
||||
|
||||
struct camelsrt_call_info_key_t {
|
||||
guint32 SessionIdKey;
|
||||
};
|
||||
|
||||
/** Info for a couple of messages (or category)
|
||||
The request must be available, not duplicated,
|
||||
and once the corresponding response received,
|
||||
we can deduce the Delta Time between Request/response */
|
||||
|
||||
struct camelsrt_msginfo_t {
|
||||
gboolean request_available;
|
||||
gboolean is_duplicate;
|
||||
gboolean is_delta_time;
|
||||
nstime_t req_time;
|
||||
nstime_t delta_time;
|
||||
};
|
||||
|
||||
/** List of infos to store for the analyse */
|
||||
|
||||
struct camelsrt_info_t {
|
||||
guint32 tcap_session_id;
|
||||
void * tcap_context;
|
||||
guint8 opcode; /**< operation code of message received */
|
||||
guint8 bool_msginfo[NB_CAMELSRT_CATEGORY]; /**< category for the received message */
|
||||
struct camelsrt_msginfo_t msginfo[NB_CAMELSRT_CATEGORY];
|
||||
};
|
||||
|
||||
/**
|
||||
* Routine called when the TAP is initialized.
|
||||
* so hash table are (re)created
|
||||
*/
|
||||
void camelsrt_init_routine(void);
|
||||
|
||||
/**
|
||||
* Initialize the Message Info used by the main dissector
|
||||
* Data are linked to a TCAP transaction
|
||||
*/
|
||||
struct camelsrt_info_t * camelsrt_razinfo(void);
|
||||
|
||||
/**
|
||||
* Service Response Time analyze, called just after the camel dissector
|
||||
* According to the camel operation, we
|
||||
* - open/close a context for the camel session
|
||||
* - look for a request, or look for the corresponding response
|
||||
*/
|
||||
void camelsrt_call_matching(tvbuff_t *tvb,
|
||||
packet_info * pinfo _U_,
|
||||
proto_tree *tree,
|
||||
struct camelsrt_info_t * p_camel_info);
|
||||
|
||||
WS_DLL_PUBLIC gboolean gcamel_StatSRT;
|
||||
|
||||
#endif /* PACKET_camel_H */
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -78,6 +78,147 @@ struct tcap_private_t {
|
|||
gchar *TransactionID_str;
|
||||
};
|
||||
|
||||
/** @file
|
||||
* lists and hash tables used in wireshark's tcap dissector
|
||||
* for calculation of delays in tcap-calls
|
||||
*/
|
||||
|
||||
#define LENGTH_OID 23
|
||||
struct tcaphash_context_t {
|
||||
struct tcaphash_context_key_t * key;
|
||||
guint32 session_id;
|
||||
guint32 first_frame;
|
||||
guint32 last_frame;
|
||||
nstime_t begin_time; /**< time of arrival of TC_BEGIN */
|
||||
nstime_t end_time; /**< time of closing message */
|
||||
gboolean responded; /**< true, if request has been responded */
|
||||
gboolean closed;
|
||||
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_ansicall_t * ansicall;
|
||||
};
|
||||
|
||||
struct tcaphash_begincall_t {
|
||||
struct tcaphash_begin_info_key_t * beginkey;
|
||||
struct tcaphash_context_t * context;
|
||||
gboolean father;
|
||||
struct tcaphash_begincall_t * next_begincall;
|
||||
struct tcaphash_begincall_t * previous_begincall;
|
||||
};
|
||||
|
||||
struct tcaphash_contcall_t {
|
||||
struct tcaphash_cont_info_key_t * contkey;
|
||||
struct tcaphash_context_t * context;
|
||||
gboolean father;
|
||||
struct tcaphash_contcall_t * next_contcall;
|
||||
struct tcaphash_contcall_t * previous_contcall;
|
||||
};
|
||||
|
||||
struct tcaphash_endcall_t {
|
||||
struct tcaphash_end_info_key_t * endkey;
|
||||
struct tcaphash_context_t * context;
|
||||
gboolean father;
|
||||
struct tcaphash_endcall_t * next_endcall;
|
||||
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 */
|
||||
|
||||
struct tcaphash_context_key_t {
|
||||
guint32 session_id;
|
||||
};
|
||||
|
||||
struct tcaphash_begin_info_key_t {
|
||||
guint32 hashKey;
|
||||
guint32 tid;
|
||||
guint32 opc_hash;
|
||||
guint32 dpc_hash;
|
||||
};
|
||||
|
||||
struct tcaphash_cont_info_key_t {
|
||||
guint32 hashKey;
|
||||
guint32 src_tid;
|
||||
guint32 dst_tid;
|
||||
guint32 opc_hash;
|
||||
guint32 dpc_hash;
|
||||
};
|
||||
|
||||
struct tcaphash_end_info_key_t {
|
||||
guint32 hashKey;
|
||||
guint32 tid;
|
||||
guint32 opc_hash;
|
||||
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 {
|
||||
guint32 tcap_session_id;
|
||||
guint32 src_tid;
|
||||
guint32 dst_tid;
|
||||
guint8 ope;
|
||||
};
|
||||
|
||||
/**
|
||||
* Routine called when the TAP is initialized.
|
||||
* so hash table are (re)created
|
||||
*/
|
||||
void tcapsrt_init_routine(void);
|
||||
|
||||
/**
|
||||
* Initialize the Message Info used by the main dissector
|
||||
* Data are linked to a TCAP transaction
|
||||
*/
|
||||
struct tcapsrt_info_t * tcapsrt_razinfo(void);
|
||||
|
||||
void tcapsrt_close(struct tcaphash_context_t * p_tcaphash_context,
|
||||
packet_info * pinfo _U_);
|
||||
|
||||
/**
|
||||
* 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 _U_,
|
||||
proto_tree *tree,
|
||||
struct tcapsrt_info_t * p_tcap_info);
|
||||
|
||||
WS_DLL_PUBLIC gboolean gtcap_StatSRT;
|
||||
|
||||
extern gint tcap_standard;
|
||||
|
||||
extern const value_string tcap_component_type_str[];
|
||||
|
@ -104,6 +245,6 @@ int dissect_tcap_UniDialoguePDU(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, in
|
|||
int dissect_tcap_DialoguePDU(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 91 "../../asn1/tcap/packet-tcap-template.h"
|
||||
#line 232 "../../asn1/tcap/packet-tcap-template.h"
|
||||
|
||||
#endif /* PACKET_tcap_H */
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,177 +0,0 @@
|
|||
/*
|
||||
* tcap-persistentdata.h
|
||||
* Definitions for lists and hash tables used in wireshark's tcap dissector
|
||||
* for calculation of delays in tcap-transactions
|
||||
* Copyright 2006 Florent Drouin (based on h225-persistentdata from Lars Roland)
|
||||
*
|
||||
* Wireshark - Network traffic analyzer
|
||||
* 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
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#ifndef __tcapsrt_HASH__
|
||||
#define __tcapsrt_HASH__
|
||||
|
||||
#include <epan/packet.h>
|
||||
#include <epan/conversation.h>
|
||||
#include <epan/dissectors/packet-tcap.h>
|
||||
#include "ws_symbol_export.h"
|
||||
|
||||
/** @file
|
||||
* lists and hash tables used in wireshark's tcap dissector
|
||||
* for calculation of delays in tcap-calls
|
||||
*/
|
||||
|
||||
#define LENGTH_OID 23
|
||||
struct tcaphash_context_t {
|
||||
struct tcaphash_context_key_t * key;
|
||||
guint32 session_id;
|
||||
guint32 first_frame;
|
||||
guint32 last_frame;
|
||||
nstime_t begin_time; /**< time of arrival of TC_BEGIN */
|
||||
nstime_t end_time; /**< time of closing message */
|
||||
gboolean responded; /**< true, if request has been responded */
|
||||
gboolean closed;
|
||||
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_ansicall_t * ansicall;
|
||||
};
|
||||
|
||||
struct tcaphash_begincall_t {
|
||||
struct tcaphash_begin_info_key_t * beginkey;
|
||||
struct tcaphash_context_t * context;
|
||||
gboolean father;
|
||||
struct tcaphash_begincall_t * next_begincall;
|
||||
struct tcaphash_begincall_t * previous_begincall;
|
||||
};
|
||||
|
||||
struct tcaphash_contcall_t {
|
||||
struct tcaphash_cont_info_key_t * contkey;
|
||||
struct tcaphash_context_t * context;
|
||||
gboolean father;
|
||||
struct tcaphash_contcall_t * next_contcall;
|
||||
struct tcaphash_contcall_t * previous_contcall;
|
||||
};
|
||||
|
||||
struct tcaphash_endcall_t {
|
||||
struct tcaphash_end_info_key_t * endkey;
|
||||
struct tcaphash_context_t * context;
|
||||
gboolean father;
|
||||
struct tcaphash_endcall_t * next_endcall;
|
||||
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 */
|
||||
|
||||
struct tcaphash_context_key_t {
|
||||
guint32 session_id;
|
||||
};
|
||||
|
||||
struct tcaphash_begin_info_key_t {
|
||||
guint32 hashKey;
|
||||
guint32 tid;
|
||||
guint32 opc_hash;
|
||||
guint32 dpc_hash;
|
||||
};
|
||||
|
||||
struct tcaphash_cont_info_key_t {
|
||||
guint32 hashKey;
|
||||
guint32 src_tid;
|
||||
guint32 dst_tid;
|
||||
guint32 opc_hash;
|
||||
guint32 dpc_hash;
|
||||
};
|
||||
|
||||
struct tcaphash_end_info_key_t {
|
||||
guint32 hashKey;
|
||||
guint32 tid;
|
||||
guint32 opc_hash;
|
||||
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 {
|
||||
guint32 tcap_session_id;
|
||||
guint32 src_tid;
|
||||
guint32 dst_tid;
|
||||
guint8 ope;
|
||||
};
|
||||
|
||||
/**
|
||||
* Routine called when the TAP is initialized.
|
||||
* so hash table are (re)created
|
||||
*/
|
||||
void tcapsrt_init_routine(void);
|
||||
|
||||
/**
|
||||
* Initialize the Message Info used by the main dissector
|
||||
* Data are linked to a TCAP transaction
|
||||
*/
|
||||
struct tcapsrt_info_t * tcapsrt_razinfo(void);
|
||||
|
||||
void tcapsrt_close(struct tcaphash_context_t * p_tcaphash_context,
|
||||
packet_info * pinfo _U_);
|
||||
|
||||
/**
|
||||
* 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 _U_,
|
||||
proto_tree *tree,
|
||||
struct tcapsrt_info_t * p_tcap_info);
|
||||
|
||||
WS_DLL_PUBLIC gboolean gtcap_StatSRT;
|
||||
|
||||
#endif /* __tcapsrt_HASH__*/
|
|
@ -37,7 +37,7 @@
|
|||
#include "epan/value_string.h"
|
||||
#include "epan/stat_cmd_args.h"
|
||||
#include "epan/asn1.h"
|
||||
#include "epan/camel-persistentdata.h"
|
||||
#include "epan/dissectors/packet-camel.h"
|
||||
|
||||
void register_tap_listener_camelcounter(void);
|
||||
|
||||
|
|
|
@ -35,7 +35,7 @@
|
|||
#include "epan/value_string.h"
|
||||
#include "epan/asn1.h"
|
||||
#include "epan/dissectors/packet-camel.h"
|
||||
#include "epan/camel-persistentdata.h"
|
||||
#include "epan/dissectors/packet-tcap.h"
|
||||
#include "epan/timestats.h"
|
||||
#include "epan/stat_cmd_args.h"
|
||||
|
||||
|
|
|
@ -35,7 +35,7 @@
|
|||
#include <epan/tap.h>
|
||||
#include <epan/packet.h>
|
||||
#include <epan/asn1.h>
|
||||
#include <epan/camel-persistentdata.h>
|
||||
#include <epan/dissectors/packet-camel.h>
|
||||
|
||||
#include "../stat_menu.h"
|
||||
|
||||
|
|
|
@ -34,7 +34,7 @@
|
|||
#include <epan/tap.h>
|
||||
#include <epan/packet.h>
|
||||
#include <epan/asn1.h>
|
||||
#include <epan/camel-persistentdata.h>
|
||||
#include <epan/dissectors/packet-camel.h>
|
||||
|
||||
#include "../file.h"
|
||||
#include "../stat_menu.h"
|
||||
|
|
Loading…
Reference in New Issue