aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLars Roland <Lars.Roland@gmx.net>2005-02-20 15:53:11 +0000
committerLars Roland <Lars.Roland@gmx.net>2005-02-20 15:53:11 +0000
commitb65e9739d29e6ccaba833986088f10d32405475d (patch)
tree586b38b0e155434aef2d602a4cb8072d5e858cb6
parenta177b7a4cc593a7655c8a9bc23ced7ac68cf2b6d (diff)
Don't register mgcp taps,
when we haven't loaded the mgcp plugin. and From Alejandro Vaquero: mgcp support for the voip call analysis tap svn path=/trunk/; revision=13447
-rw-r--r--gtk/mgcp_stat.c6
-rw-r--r--gtk/voip_calls.c391
-rw-r--r--gtk/voip_calls.h20
-rw-r--r--gtk/voip_calls_dlg.c8
-rw-r--r--plugins/mgcp/packet-mgcp.c53
-rw-r--r--plugins/mgcp/packet-mgcp.h6
-rw-r--r--tap-mgcpstat.c5
7 files changed, 466 insertions, 23 deletions
diff --git a/gtk/mgcp_stat.c b/gtk/mgcp_stat.c
index 5e1b9215ae..1f4d8b67a4 100644
--- a/gtk/mgcp_stat.c
+++ b/gtk/mgcp_stat.c
@@ -324,9 +324,11 @@ static tap_dfilter_dlg mgcp_srt_dlg = {
void
register_tap_listener_gtkmgcpstat(void)
{
- register_ethereal_tap("mgcp,srt", gtk_mgcpstat_init);
+ /* We don't register this tap, if we don't have the mgcp plugin loaded.*/
+ if (find_tap_id("mgcp")) {
+ register_ethereal_tap("mgcp,srt", gtk_mgcpstat_init);
- if (find_tap_id("mgcp"))
register_tap_menu_item("MGCP...", REGISTER_TAP_GROUP_RESPONSE_TIME,
gtk_tap_dfilter_dlg_cb, NULL, NULL, &(mgcp_srt_dlg));
+ }
}
diff --git a/gtk/voip_calls.c b/gtk/voip_calls.c
index 98a2e9317f..5d0dfe7725 100644
--- a/gtk/voip_calls.c
+++ b/gtk/voip_calls.c
@@ -53,14 +53,16 @@
#include <epan/dissectors/packet-h245.h>
#include <epan/dissectors/packet-q931.h>
#include <epan/dissectors/packet-sdp.h>
+#include <plugins/mgcp/packet-mgcp.h>
#include <epan/dissectors/packet-rtp.h>
#include "rtp_pt.h"
#include "alert_box.h"
#include "simple_dialog.h"
-char *voip_call_state_name[6]={
+char *voip_call_state_name[7]={
"CALL SETUP",
+ "RINGING",
"IN CALL",
"CANCELLED",
"COMPLETED",
@@ -69,10 +71,11 @@ char *voip_call_state_name[6]={
};
/* defines whether we can consider the call active */
-char *voip_protocol_name[3]={
+char *voip_protocol_name[4]={
"SIP",
"ISUP",
- "H323"
+ "H323",
+ "MGCP"
};
@@ -80,7 +83,7 @@ char *voip_protocol_name[3]={
/****************************************************************************/
/* the one and only global voip_calls_tapinfo_t structure */
static voip_calls_tapinfo_t the_tapinfo_struct =
- {0, NULL, 0, NULL, 0, 0, 0, 0, NULL, 0, 0, 0, 0, 0, 0, 0};
+ {0, NULL, 0, NULL, 0, 0, 0, 0, NULL, 0, 0, 0, 0, 0, 0, 0, 0};
/* the one and only global voip_rtp_tapinfo_t structure */
static voip_rtp_tapinfo_t the_tapinfo_rtp_struct =
@@ -1436,6 +1439,8 @@ remove_tap_listener_h245dg_calls(void)
have_H245dg_tap_listener=FALSE;
}
+static gchar *sdp_summary = NULL;
+static guint32 sdp_frame_num = 0;
/****************************************************************************/
/****************************TAP for SDP PROTOCOL ***************************/
@@ -1446,11 +1451,16 @@ SDPcalls_packet(void *ptr _U_, packet_info *pinfo, epan_dissect_t *edt _U_, cons
{
voip_calls_tapinfo_t *tapinfo = &the_tapinfo_struct;
const sdp_packet_info *pi = SDPinfo;
- char summary_str[50];
-
+
+ /* There are protocols like MGCP where the SDP is called before the tap for the
+ MGCP packet, in those cases we assign the SPD summary to global lastSDPsummary
+ to use it later
+ */
+ g_free(sdp_summary);
+ sdp_frame_num = pinfo->fd->num;
/* Append to graph the SDP summary if the packet exists */
- g_snprintf(summary_str, 50, "SDP (%s)", pi->summary_str);
- append_to_frame_graph(tapinfo, pinfo->fd->num, summary_str, NULL);
+ sdp_summary = g_strdup_printf("SDP (%s)", pi->summary_str);
+ append_to_frame_graph(tapinfo, pinfo->fd->num, sdp_summary, NULL);
return 1; /* refresh output */
}
@@ -1503,6 +1513,371 @@ remove_tap_listener_sdp_calls(void)
+/****************************************************************************/
+/* ***************************TAP for MGCP **********************************/
+/****************************************************************************/
+
+/*
+ This function will look for a signal/event in the SignalReq/ObsEvent string
+ and return true if it is found
+*/
+boolean isSignal(gchar *signal, gchar *signalStr)
+{
+ gint i;
+ gchar **resultArray;
+
+ /* if there is no signalStr, just return false */
+ if (signalStr == NULL) return FALSE;
+
+ /* if are both "blank" return true */
+ if ( (*signal == '\0') && (*signalStr == '\0') ) return TRUE;
+
+ /* look for signal in signalSre */
+ resultArray = g_strsplit(signalStr, ",", 10);
+
+ for (i = 0; resultArray[i]; i++) {
+ g_strstrip(resultArray[i]);
+ if (strcmp(resultArray[i], signal) == 0) return TRUE;
+ }
+
+ g_strfreev(resultArray);
+
+ return FALSE;
+}
+
+/*
+ This function will get the Caller ID info and replace the current string
+ This is how it looks the caller Id: rg, ci(02/16/08/29, "3035550002","Ale Sipura 2")
+*/
+void mgcpCallerID(gchar *signalStr, gchar **callerId)
+{
+ gint i;
+ gchar **resultArray;
+ gchar **arrayStr;
+
+ /* if there is no signalStr, just return false */
+ if (signalStr == NULL) return;
+
+ arrayStr = g_strsplit(signalStr, "\"", 10);
+
+ if (arrayStr[0] == NULL) return;
+
+ /* look for the ci signal */
+ resultArray = g_strsplit_set(arrayStr[0], ",(", 10);
+
+ for (i = 0; resultArray[i]; i++) {
+ g_strstrip(resultArray[i]);
+ if (strcmp(resultArray[i], "ci") == 0){
+ if (arrayStr[1] != NULL){
+ /* free the previous "From" field of the call, and assign the new */
+ g_free(*callerId);
+ *callerId = g_strdup(arrayStr[1]);
+ }
+ g_strfreev(arrayStr);
+ g_strfreev(resultArray);
+ return;
+ }
+ }
+
+ g_strfreev(arrayStr);
+ g_strfreev(resultArray);
+
+ return;
+}
+
+
+/*
+ This function will get the Dialed Digits and replace the current string
+ This is how it looks the dialed digits 5,5,5,0,0,0,2,#,*
+*/
+void mgcpDialedDigits(gchar *signalStr, gchar **dialedDigits)
+{
+ gchar *tmpStr;
+ gchar resultStr[50];
+ gint i,j;
+
+ /* if there is no signalStr, just return false */
+ if (signalStr == NULL) return;
+
+ tmpStr = g_strdup(signalStr);
+
+ tmpStr = g_strcanon(tmpStr, "123456790#*", '?');
+
+ for (i = 0, j = 0; tmpStr[i] && i<50; i++) {
+ if (tmpStr[i] != '?')
+ resultStr[j++] = tmpStr[i];
+ }
+ resultStr[j] = '\0';
+
+ if (*resultStr == '\0') return;
+
+ g_free(*dialedDigits);
+ *dialedDigits = g_strdup(resultStr);
+ g_free(tmpStr);
+
+ return;
+}
+
+
+
+/****************************************************************************/
+/* whenever a MGCP packet is seen by the tap listener */
+static int
+MGCPcalls_packet( void *ptr _U_, packet_info *pinfo, epan_dissect_t *edt _U_, const void *MGCPinfo)
+{
+ voip_calls_tapinfo_t *tapinfo = &the_tapinfo_struct;
+
+ voip_calls_info_t *tmp_listinfo;
+ voip_calls_info_t *strinfo = NULL;
+ mgcp_calls_info_t *tmp_mgcpinfo;
+ GList* list;
+ GList* listGraph;
+ gchar *frame_label = NULL;
+ gchar *comment = NULL;
+ graph_analysis_item_t *gai;
+ boolean new = FALSE;
+ boolean fromEndpoint = FALSE; /* true for calls originated in Endpoints, false for calls from MGC */
+ gdouble diff_time;
+
+ const mgcp_info_t *pi = MGCPinfo;
+
+
+ if ((pi->mgcp_type == MGCP_REQUEST) && !pi->is_duplicate ){
+ /* check wether we already have a call with this Endpoint and it is active*/
+ list = g_list_first(tapinfo->strinfo_list);
+ while (list)
+ {
+ tmp_listinfo=list->data;
+ if ((tmp_listinfo->protocol == VOIP_MGCP) && (tmp_listinfo->call_active_state == VOIP_ACTIVE)){
+ tmp_mgcpinfo = tmp_listinfo->prot_info;
+ if (pi->endpointId != NULL){
+ if (g_ascii_strcasecmp(tmp_mgcpinfo->endpointId,pi->endpointId)==0){
+ /*
+ check first if it is an ended call. We consider an ended call after 1sec we don't
+ get a packet in this Endpoint and the call has been released
+ */
+ diff_time = (pinfo->fd->rel_secs + (double)pinfo->fd->rel_secs/1000000) - (tmp_listinfo->stop_sec + (double)tmp_listinfo->stop_usec/1000000);
+ if ( ((tmp_listinfo->call_state == VOIP_CANCELLED) || (tmp_listinfo->call_state == VOIP_COMPLETED) || (tmp_listinfo->call_state == VOIP_REJECTED)) && (diff_time > 1) ){
+ tmp_listinfo->call_active_state = VOIP_INACTIVE;
+ } else {
+ strinfo = (voip_calls_info_t*)(list->data);
+ break;
+ }
+ }
+ }
+ }
+ list = g_list_next (list);
+ }
+
+ /* there is no call with this Endpoint, lets see if this a new call or not */
+ if (strinfo == NULL){
+ if ( (strcmp(pi->code, "NTFY") == 0) && isSignal("hd", pi->observedEvents) ){ /* off hook transition */
+ /* this is a new call from the Endpoint */
+ fromEndpoint = TRUE;
+ new = TRUE;
+ } else if (strcmp(pi->code, "CRCX") == 0){
+ /* this is a new call from the MGC */
+ fromEndpoint = FALSE;
+ new = TRUE;
+ }
+ if (!new) return 0;
+ }
+ } else if ( ((pi->mgcp_type == MGCP_RESPONSE) && pi->request_available) ||
+ ((pi->mgcp_type == MGCP_REQUEST) && pi->is_duplicate) ) {
+ /* if it is a response OR if it is a duplicated Request, lets look in the Graph if thre is a request that match */
+ listGraph = g_list_first(tapinfo->graph_analysis->list);
+ while (listGraph)
+ {
+ gai = listGraph->data;
+ if (gai->frame_num == pi->req_num){
+ /* there is a request that match, so look the associated call with this call_num */
+ list = g_list_first(tapinfo->strinfo_list);
+ while (list)
+ {
+ tmp_listinfo=list->data;
+ if (tmp_listinfo->protocol == VOIP_MGCP){
+ if (tmp_listinfo->call_num == gai->conv_num){
+ tmp_mgcpinfo = tmp_listinfo->prot_info;
+ strinfo = (voip_calls_info_t*)(list->data);
+ break;
+ }
+ }
+ list = g_list_next (list);
+ }
+ if (strinfo != NULL) break;
+ }
+ listGraph = g_list_next(listGraph);
+ }
+ /* if there is not a matching request, just return */
+ if (strinfo == NULL) return 0;
+ } else return 0;
+
+ /* not in the list? then create a new entry */
+ if (strinfo==NULL){
+ strinfo = g_malloc(sizeof(voip_calls_info_t));
+ strinfo->call_active_state = VOIP_ACTIVE;
+ strinfo->call_state = VOIP_CALL_SETUP;
+ if (fromEndpoint) {
+ strinfo->from_identity=g_strdup(pi->endpointId);
+ strinfo->to_identity=g_strdup("");
+ } else {
+ strinfo->from_identity=g_strdup("");
+ strinfo->to_identity=g_strdup(pi->endpointId);
+ }
+ g_memmove(&(strinfo->initial_speaker), pinfo->src.data, 4);
+ strinfo->first_frame_num=pinfo->fd->num;
+ strinfo->selected=FALSE;
+ strinfo->start_sec=pinfo->fd->rel_secs;
+ strinfo->start_usec=pinfo->fd->rel_usecs;
+ strinfo->protocol=VOIP_MGCP;
+ strinfo->prot_info=g_malloc(sizeof(mgcp_calls_info_t));
+ tmp_mgcpinfo=strinfo->prot_info;
+ tmp_mgcpinfo->endpointId = g_strdup(pi->endpointId);
+ tmp_mgcpinfo->fromEndpoint = fromEndpoint;
+ strinfo->npackets = 0;
+ strinfo->call_num = tapinfo->ncalls++;
+ tapinfo->strinfo_list = g_list_append(tapinfo->strinfo_list, strinfo);
+ }
+
+ /* change call state and add to graph */
+ switch (pi->mgcp_type)
+ {
+ case MGCP_REQUEST:
+ if ( (strcmp(pi->code, "NTFY") == 0) && (pi->observedEvents != NULL) ){
+ frame_label = g_strdup_printf("%s ObsEvt:%s",pi->code, pi->observedEvents);
+
+ if (tmp_mgcpinfo->fromEndpoint){
+ /* use the Dialed digits to fill the "To" for the call */
+ mgcpDialedDigits(pi->observedEvents, &(strinfo->to_identity));
+
+ /* from MGC and the user picked up, the call is connected */
+ } else if (isSignal("hd", pi->observedEvents))
+ strinfo->call_state=VOIP_IN_CALL;
+
+ /* hung up signal */
+ if (isSignal("hu", pi->observedEvents)) {
+ if ((strinfo->call_state == VOIP_CALL_SETUP) || (strinfo->call_state == VOIP_RINGING)){
+ strinfo->call_state = VOIP_CANCELLED;
+ } else {
+ strinfo->call_state = VOIP_COMPLETED;
+ }
+ }
+
+ } else if (strcmp(pi->code, "RQNT") == 0) {
+ /* for calls from Endpoint: if there is a "no signal" RQNT and the call was RINGING, we assume this is the CONNECT */
+ if ( tmp_mgcpinfo->fromEndpoint && isSignal("", pi->signalReq) && (strinfo->call_state == VOIP_RINGING) ) {
+ strinfo->call_state = VOIP_IN_CALL;
+ }
+
+ /* if there is ringback or ring tone, change state to ringing */
+ if ( isSignal("rg", pi->signalReq) || isSignal("rt", pi->signalReq) ) {
+ strinfo->call_state = VOIP_RINGING;
+ }
+
+ /* if there is a Busy or ReorderTone, and the call was Ringing or Setup the call is Rejected */
+ if ( (isSignal("ro", pi->signalReq) || isSignal("bz", pi->signalReq)) && ((strinfo->call_state == VOIP_CALL_SETUP) || (strinfo->call_state = VOIP_RINGING)) ) {
+ strinfo->call_state = VOIP_REJECTED;
+ }
+
+ if (pi->signalReq != NULL)
+ frame_label = g_strdup_printf("%s%sSigReq:%s",pi->code, (pi->hasDigitMap == TRUE)?" DigitMap ":"", pi->signalReq);
+ else
+ frame_label = g_strdup_printf("%s%s",pi->code, (pi->hasDigitMap == TRUE)?" DigitMap ":"");
+
+ /* use the CallerID info to fill the "From" for the call */
+ if (!tmp_mgcpinfo->fromEndpoint) mgcpCallerID(pi->signalReq, &(strinfo->from_identity));
+
+ } else if (strcmp(pi->code, "DLCX") == 0) {
+ /*
+ if there is a DLCX in a call To an Endpoint and the call was not connected, we use
+ the DLCX as the end of the call
+ */
+ if (!tmp_mgcpinfo->fromEndpoint){
+ if ((strinfo->call_state == VOIP_CALL_SETUP) || (strinfo->call_state == VOIP_RINGING)){
+ strinfo->call_state = VOIP_CANCELLED;
+ }
+ }
+ }
+
+ if (frame_label == NULL) frame_label = g_strdup_printf("%s",pi->code);
+ break;
+ case MGCP_RESPONSE:
+ frame_label = g_strdup_printf("%d (%s)",pi->rspcode, pi->code);
+ break;
+ }
+
+
+ comment = g_strdup_printf("MGCP %s %s%s", tmp_mgcpinfo->endpointId, (pi->mgcp_type == MGCP_REQUEST)?"Request":"Response", pi->is_duplicate?" Duplicate":"");
+
+ strinfo->stop_sec=pinfo->fd->rel_secs;
+ strinfo->stop_usec=pinfo->fd->rel_usecs;
+ strinfo->last_frame_num=pinfo->fd->num;
+ ++(strinfo->npackets);
+ /* increment the packets counter of all calls */
+ ++(tapinfo->npackets);
+
+ /* add to the graph */
+ add_to_graph(tapinfo, pinfo, frame_label, comment, strinfo->call_num);
+ g_free(comment);
+ g_free(frame_label);
+
+ /* add SDP info if apply */
+ if ( (sdp_summary != NULL) && (sdp_frame_num == pinfo->fd->num) ){
+ append_to_frame_graph(tapinfo, pinfo->fd->num, sdp_summary, NULL);
+ g_free(sdp_summary);
+ sdp_summary = NULL;
+ }
+
+ return 1; /* refresh output */
+}
+
+
+/****************************************************************************/
+/* TAP INTERFACE */
+/****************************************************************************/
+static gboolean have_MGCP_tap_listener=FALSE;
+/****************************************************************************/
+void
+mgcp_calls_init_tap(void)
+{
+ GString *error_string;
+
+ if(have_MGCP_tap_listener==FALSE)
+ {
+ /* don't register tap listener, if we have it already */
+ /* we send an empty filter, to force a non null "tree" in the mgcp dissector */
+ error_string = register_tap_listener("mgcp", &(the_tapinfo_struct.mgcp_dummy), strdup(""),
+ voip_calls_dlg_reset,
+ MGCPcalls_packet,
+ voip_calls_dlg_draw
+ );
+ if (error_string != NULL) {
+ simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
+ error_string->str);
+ g_string_free(error_string, TRUE);
+ exit(1);
+ }
+ have_MGCP_tap_listener=TRUE;
+ }
+}
+
+
+
+/* XXX just copied from gtk/rpc_stat.c */
+void protect_thread_critical_region(void);
+void unprotect_thread_critical_region(void);
+
+/****************************************************************************/
+void
+remove_tap_listener_mgcp_calls(void)
+{
+ protect_thread_critical_region();
+ remove_tap_listener(&(the_tapinfo_struct.mgcp_dummy));
+ unprotect_thread_critical_region();
+
+ have_MGCP_tap_listener=FALSE;
+}
+
/****************************************************************************/
diff --git a/gtk/voip_calls.h b/gtk/voip_calls.h
index ec8fdc3f14..fd3a2c80f7 100644
--- a/gtk/voip_calls.h
+++ b/gtk/voip_calls.h
@@ -44,6 +44,7 @@
/* defines voip call state */
typedef enum _voip_call_state {
VOIP_CALL_SETUP,
+ VOIP_RINGING,
VOIP_IN_CALL,
VOIP_CANCELLED,
VOIP_COMPLETED,
@@ -51,7 +52,7 @@ typedef enum _voip_call_state {
VOIP_UNKNOWN
} voip_call_state;
-extern char *voip_call_state_name[6];
+extern char *voip_call_state_name[7];
typedef enum _voip_call_active_state {
VOIP_ACTIVE,
@@ -61,10 +62,11 @@ typedef enum _voip_call_active_state {
typedef enum _voip_protocol {
VOIP_SIP,
VOIP_ISUP,
- VOIP_H323
+ VOIP_H323,
+ VOIP_MGCP
} voip_protocol;
-extern char *voip_protocol_name[3];
+extern char *voip_protocol_name[4];
/* defines specific SIP data */
@@ -81,13 +83,13 @@ typedef struct _sip_calls_info {
} sip_calls_info_t;
/* defines specific ISUP data */
-
typedef struct _isup_calls_info {
guint16 cic;
guint32 opc, dpc;
guint8 ni;
} isup_calls_info_t;
+/* defines specific H245 data */
typedef struct _h245_address {
guint32 h245_address;
guint16 h245_port;
@@ -107,6 +109,13 @@ typedef struct _h323_calls_info {
guint requestSeqNum;
} h323_calls_info_t;
+/* defines specific MGCP data */
+typedef struct _mgcp_calls_info {
+ gchar *endpointId;
+ gboolean fromEndpoint; /* true if the call was originated from the Endpoint, false for calls from MGC */
+} mgcp_calls_info_t;
+
+
/* defines a voip call */
typedef struct _voip_calls_info {
voip_call_state call_state;
@@ -149,6 +158,7 @@ typedef struct _voip_calls_tapinfo {
int mtp3_dummy;
int isup_dummy;
int q931_dummy;
+ int mgcp_dummy;
} voip_calls_tapinfo_t;
@@ -197,6 +207,7 @@ void h245dg_calls_init_tap(void);
void q931_calls_init_tap(void);
void sdp_calls_init_tap(void);
void rtp_init_tap(void);
+void mgcp_calls_init_tap(void);
/*
@@ -211,6 +222,7 @@ void remove_tap_listener_h245dg_calls(void);
void remove_tap_listener_q931_calls(void);
void remove_tap_listener_sdp_calls(void);
void remove_tap_listener_rtp(void);
+void remove_tap_listener_mgcp_calls(void);
/*
* Retrieves a constant reference to the unique info structure of the voip_calls tap listener.
diff --git a/gtk/voip_calls_dlg.c b/gtk/voip_calls_dlg.c
index c2fe98aeeb..c7c140fc61 100644
--- a/gtk/voip_calls_dlg.c
+++ b/gtk/voip_calls_dlg.c
@@ -49,6 +49,7 @@
#include "globals.h"
#include "epan/filesystem.h"
+#include <epan/tap.h>
#include "tap_menu.h"
#include "dlg_utils.h"
#include "ui_util.h"
@@ -173,6 +174,9 @@ void voip_calls_remove_tap_listener()
remove_tap_listener_q931_calls();
remove_tap_listener_sdp_calls();
remove_tap_listener_rtp();
+ if (find_tap_id("mgcp")) {
+ remove_tap_listener_mgcp_calls();
+ }
}
/****************************************************************************/
@@ -672,6 +676,10 @@ voip_calls_init_tap(char *dummy _U_)
q931_calls_init_tap();
sdp_calls_init_tap();
rtp_init_tap();
+ /* We don't register this tap, if we don't have the mgcp plugin loaded.*/
+ if (find_tap_id("mgcp")) {
+ mgcp_calls_init_tap();
+ }
/* init the Graph Analysys */
graph_analysis_data = graph_analysis_init();
diff --git a/plugins/mgcp/packet-mgcp.c b/plugins/mgcp/packet-mgcp.c
index 68dd50190e..3ff7bd6158 100644
--- a/plugins/mgcp/packet-mgcp.c
+++ b/plugins/mgcp/packet-mgcp.c
@@ -226,7 +226,7 @@ static gint tvb_parse_param(tvbuff_t *tvb, gint offset, gint maxlength,
static void dissect_mgcp_message(tvbuff_t *tvb, packet_info *pinfo,
proto_tree *tree,proto_tree *mgcp_tree, proto_tree *ti);
static void dissect_mgcp_firstline(tvbuff_t *tvb, packet_info *pinfo,
- proto_tree *tree, mgcp_info_t *mi);
+ proto_tree *tree);
static void dissect_mgcp_params(tvbuff_t *tvb,
proto_tree *tree);
static void dissect_mgcp_connectionparams(proto_tree *parent_tree, tvbuff_t *tvb, gint offset, gint param_type_len, gint param_val_len);
@@ -378,6 +378,10 @@ dissect_mgcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
}
}
+static mgcp_info_t pi_arr[5]; /* We assuming a maximum of 5 mgcp messaages per packet */
+static int pi_current=0;
+static mgcp_info_t *mi;
+
static void
dissect_mgcp_message(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
proto_tree *mgcp_tree, proto_tree *ti){
@@ -386,7 +390,28 @@ dissect_mgcp_message(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
gint sectionlen;
gint tvb_sectionend,tvb_sectionbegin, tvb_len, tvb_current_len;
tvbuff_t *next_tvb;
- static mgcp_info_t mi;
+
+ /* Initialise stat info for passing to tap */
+ pi_current++;
+ if(pi_current==5){
+ pi_current=0;
+ }
+ mi=&pi_arr[pi_current];
+
+
+ mi->mgcp_type = MGCP_OTHERS;
+ mi->code[0] = '\0';
+ mi->transid = 0;
+ mi->req_time.secs=0;
+ mi->req_time.nsecs=0;
+ mi->is_duplicate = FALSE;
+ mi->request_available = FALSE;
+ mi->req_num = 0;
+ mi->endpointId = NULL;
+ mi->observedEvents = NULL;
+ mi->rspcode = 0;
+ mi->signalReq = NULL;
+ mi->hasDigitMap = FALSE;
/* Initialize variables */
tvb_sectionend = 0;
@@ -409,7 +434,7 @@ dissect_mgcp_message(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
if( sectionlen > 0){
dissect_mgcp_firstline(tvb_new_subset(tvb, tvb_sectionbegin,
sectionlen,-1), pinfo,
- mgcp_tree, &mi);
+ mgcp_tree);
}
tvb_sectionbegin = tvb_sectionend;
@@ -882,8 +907,10 @@ static gboolean is_rfc2234_alpha(guint8 c){
static gint tvb_parse_param(tvbuff_t* tvb, gint offset, gint len, int** hf){
gint returnvalue, tvb_current_offset,counter;
guint8 tempchar;
+ gchar **buf;
tvb_current_offset = offset;
- returnvalue = -1;
+ returnvalue = -1;
+ buf = NULL;
*hf = NULL;
if(len > 0){
tempchar = tvb_get_guint8(tvb,tvb_current_offset);
@@ -956,12 +983,15 @@ static gint tvb_parse_param(tvbuff_t* tvb, gint offset, gint len, int** hf){
break;
case 'S':
*hf = &hf_mgcp_param_signalreq;
+ buf = &(mi->signalReq);
break;
case 'D':
*hf = &hf_mgcp_param_digitmap;
+ mi->hasDigitMap = TRUE;
break;
case 'O':
*hf = &hf_mgcp_param_observedevent;
+ buf = &(mi->observedEvents);
break;
case 'P':
*hf = &hf_mgcp_param_connectionparam;
@@ -1015,6 +1045,9 @@ static gint tvb_parse_param(tvbuff_t* tvb, gint offset, gint len, int** hf){
tvb_current_offset = tvb_skip_wsp(tvb,tvb_current_offset,
(len - tvb_current_offset + offset));
returnvalue = tvb_current_offset;
+ if (buf != NULL) {
+ *buf = tvb_get_string(tvb, tvb_current_offset, (len - tvb_current_offset + offset));
+ }
}
else {
*hf = &hf_mgcp_param_invalid;
@@ -1050,11 +1083,12 @@ static gint tvb_parse_param(tvbuff_t* tvb, gint offset, gint len, int** hf){
static void dissect_mgcp_firstline(tvbuff_t *tvb, packet_info *pinfo,
- proto_tree *tree, mgcp_info_t *mi){
+ proto_tree *tree){
gint tvb_current_offset,tvb_previous_offset,tvb_len,tvb_current_len;
gint tokennum, tokenlen;
char *transid = NULL;
char *code = NULL;
+ char *endpointId = NULL;
mgcp_type_t mgcp_type = MGCP_OTHERS;
conversation_t* conversation;
mgcp_call_info_key mgcp_call_key;
@@ -1107,6 +1141,7 @@ static void dissect_mgcp_firstline(tvbuff_t *tvb, packet_info *pinfo,
else if (is_mgcp_rspcode(tvb,tvb_previous_offset,tvb_current_len)){
mgcp_type = MGCP_RESPONSE;
rspcode = atoi(code);
+ mi->rspcode = rspcode;
proto_tree_add_uint(tree,hf_mgcp_rsp_rspcode, tvb,
tvb_previous_offset, tokenlen,
rspcode);
@@ -1126,10 +1161,11 @@ static void dissect_mgcp_firstline(tvbuff_t *tvb, packet_info *pinfo,
}
if(tokennum == 2){
if(mgcp_type == MGCP_REQUEST){
+ endpointId = tvb_format_text(tvb, tvb_previous_offset,tokenlen);
+ mi->endpointId = g_strdup(endpointId);
my_proto_tree_add_string(tree,hf_mgcp_req_endpoint, tvb,
tvb_previous_offset, tokenlen,
- tvb_format_text(tvb, tvb_previous_offset,
- tokenlen));
+ endpointId);
}
else if(mgcp_type == MGCP_RESPONSE){
if(tvb_current_offset < tvb_len){
@@ -1214,6 +1250,7 @@ static void dissect_mgcp_firstline(tvbuff_t *tvb, packet_info *pinfo,
if(mgcp_call->req_num){
mi->request_available = TRUE;
mgcp_call->responded = TRUE;
+ mi->req_num = mgcp_call->req_num;
strcpy(mi->code,mgcp_call->code);
proto_tree_add_uint_format(tree, hf_mgcp_req_frame,
tvb, 0, 0, mgcp_call->req_num,
@@ -1317,6 +1354,7 @@ static void dissect_mgcp_firstline(tvbuff_t *tvb, packet_info *pinfo,
/* No, so it's a duplicate request.
Mark it as such. */
mi->is_duplicate = TRUE;
+ mi->req_num = mgcp_call->req_num;
if (check_col(pinfo->cinfo, COL_INFO)) {
col_append_fstr(pinfo->cinfo, COL_INFO,
", Duplicate Request %u",mi->transid);
@@ -1345,7 +1383,6 @@ static void dissect_mgcp_firstline(tvbuff_t *tvb, packet_info *pinfo,
mgcp_call->req_time.secs=pinfo->fd->abs_secs;
mgcp_call->req_time.nsecs=pinfo->fd->abs_usecs*1000;
strcpy(mgcp_call->code,mi->code);
-
/* store it */
g_hash_table_insert(mgcp_calls, new_mgcp_call_key, mgcp_call);
}
diff --git a/plugins/mgcp/packet-mgcp.h b/plugins/mgcp/packet-mgcp.h
index 50f08685e5..22a98839f2 100644
--- a/plugins/mgcp/packet-mgcp.h
+++ b/plugins/mgcp/packet-mgcp.h
@@ -40,6 +40,12 @@ typedef struct _mgcp_info_t {
nstime_t req_time;
gboolean is_duplicate;
gboolean request_available;
+ guint32 req_num; /* frame number request seen */
+ gchar *endpointId;
+ gchar *observedEvents;
+ guint32 rspcode;
+ gchar *signalReq;
+ gboolean *hasDigitMap;
} mgcp_info_t;
/* Item of request list */
diff --git a/tap-mgcpstat.c b/tap-mgcpstat.c
index 0426a3e264..f8b92b6192 100644
--- a/tap-mgcpstat.c
+++ b/tap-mgcpstat.c
@@ -233,6 +233,9 @@ mgcpstat_init(char *optarg)
void
register_tap_listener_mgcpstat(void)
{
- register_ethereal_tap("mgcp,rtd", mgcpstat_init);
+ /* We don't register this tap, if we don't have the mgcp plugin loaded.*/
+ if (find_tap_id("mgcp")) {
+ register_ethereal_tap("mgcp,rtd", mgcpstat_init);
+ }
}