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.
From: LEGO <luis.ontanon@xxxxxxxxx>
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 > > >
- Follow-Ups:
- Re: [Ethereal-dev] Voip Calls analysis and Graph analysis
- From: Alejandro Vaquero
- Re: [Ethereal-dev] Voip Calls analysis and Graph analysis
- From: Lars Roland
- Re: [Ethereal-dev] Voip Calls analysis and Graph analysis
- References:
- [Ethereal-dev] Voip Calls analysis and Graph analysis
- From: Anders Broman
- Re: [Ethereal-dev] Voip Calls analysis and Graph analysis
- From: Lars Roland
- [Ethereal-dev] Voip Calls analysis and Graph analysis
- From: Alejandro Vaquero
- [Ethereal-dev] Voip Calls analysis and Graph analysis
- Prev by Date: [Ethereal-dev] Voip Calls analysis and Graph analysis
- Next by Date: Re: [Ethereal-dev] Voip Calls analysis and Graph analysis
- Previous by thread: [Ethereal-dev] Voip Calls analysis and Graph analysis
- Next by thread: Re: [Ethereal-dev] Voip Calls analysis and Graph analysis
- Index(es):