Ethereal-dev: Re: [Ethereal-dev] Voip Calls analysis and Graph analysis

Note: This archive is from the project's previous web site, ethereal.com. This list is no longer active.

Date: Fri, 18 Feb 2005 21:13:48 +0100
Do you have any capture on which to test it?

Luis

On Fri, 18 Feb 2005 13:00:00 -0700, Alejandro Vaquero
<alejandrovaquero@xxxxxxxxx> wrote:
> 
> Hi All,
>     find attached a patch to add MGCP calls to the "Voip Analysis". The
> implementation is oriented to MGCP Residential Gateways.
> 
> Regards
> Alejandro
> 
> 
> Index: gtk/voip_calls_dlg.c
> ===================================================================
> --- gtk/voip_calls_dlg.c        (revision 13359)
> +++ gtk/voip_calls_dlg.c        (working copy)
> @@ -173,6 +173,7 @@
>         remove_tap_listener_q931_calls();
>         remove_tap_listener_sdp_calls();
>         remove_tap_listener_rtp();
> +       remove_tap_listener_mgcp_calls();
>  }
> 
>  /****************************************************************************/
> @@ -672,6 +673,7 @@
>         q931_calls_init_tap();
>         sdp_calls_init_tap();
>         rtp_init_tap();
> +       mgcp_calls_init_tap();
> 
>         /* init the Graph Analysys */
>         graph_analysis_data = graph_analysis_init();
> Index: gtk/voip_calls.c
> ===================================================================
> --- gtk/voip_calls.c    (revision 13359)
> +++ gtk/voip_calls.c    (working copy)
> @@ -52,6 +52,7 @@
>  #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"
> 
> @@ -69,8 +70,9 @@
>  #include <string.h>
> 
> -char *voip_call_state_name[6]={
> +char *voip_call_state_name[7]={
>         "CALL SETUP",
> +       "RINGING",
>         "IN CALL",
>         "CANCELLED",
>         "COMPLETED",
> @@ -79,10 +81,11 @@
>         };
> 
>  /* defines whether we can consider the call active */
> -char *voip_protocol_name[3]={
> +char *voip_protocol_name[4]={
>         "SIP",
>         "ISUP",
> -       "H323"
> +       "H323",
> +       "MGCP"
>         };
> 
> @@ -90,7 +93,7 @@
>  /****************************************************************************/
>  /* 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 =
> @@ -1446,6 +1449,8 @@
>         have_H245dg_tap_listener=FALSE;
>  }
> 
> +static gchar *sdp_summary = NULL;
> +static guint32 sdp_frame_num = 0;
> 
>  /****************************************************************************/
>  /****************************TAP for SDP PROTOCOL ***************************/
> @@ -1456,11 +1461,16 @@
>  {
>         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 */
>  }
> @@ -1513,9 +1523,374 @@
> 
> +/****************************************************************************/
> +/* ***************************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;
> +}
> +
> +
> +
> +/****************************************************************************/
>  /* ***************************TAP for OTHER PROTOCOL **********************************/
>  /****************************************************************************/
> 
> Index: gtk/voip_calls.h
> ===================================================================
> --- gtk/voip_calls.h    (revision 13359)
> +++ gtk/voip_calls.h    (working copy)
> @@ -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 @@
>                 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_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 @@
>  } 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 @@
>         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 @@
>         int mtp3_dummy;
>         int isup_dummy;
>         int q931_dummy;
> +       int mgcp_dummy;
>  } voip_calls_tapinfo_t;
> 
> @@ -197,6 +207,7 @@
>  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_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.
> Index: plugins/mgcp/packet-mgcp.h
> ===================================================================
> --- plugins/mgcp/packet-mgcp.h  (revision 13359)
> +++ plugins/mgcp/packet-mgcp.h  (working copy)
> @@ -40,6 +40,12 @@
>    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 */
> Index: plugins/mgcp/packet-mgcp.c
> ===================================================================
> --- plugins/mgcp/packet-mgcp.c  (revision 13359)
> +++ plugins/mgcp/packet-mgcp.c  (working copy)
> @@ -226,7 +226,7 @@
>  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);
> @@ -377,6 +377,7 @@
>      }
>    }
>  }
> +static mgcp_info_t *mi;
> 
>  static void
>  dissect_mgcp_message(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
> @@ -386,8 +387,23 @@
>    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 */
> +  mi = g_malloc(sizeof(mgcp_info_t));
> +  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;
>    tvb_sectionbegin = tvb_sectionend;
> @@ -409,7 +425,7 @@
>      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 +898,10 @@
>  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 +974,15 @@
>        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 +1036,9 @@
>        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 +1074,12 @@
> 
>  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 +1132,7 @@
>         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 +1152,11 @@
>        }
>        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 +1241,7 @@
>                         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 +1345,7 @@
>                         /* 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 +1374,6 @@
>                 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);
>         }
> 
> 
> _______________________________________________
> Ethereal-dev mailing list
> Ethereal-dev@xxxxxxxxxxxx
> http://www.ethereal.com/mailman/listinfo/ethereal-dev
> 
> 
>