Ethereal-dev: [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: Alejandro Vaquero <alejandrovaquero@xxxxxxxxx>
Date: Fri, 18 Feb 2005 13:00:00 -0700
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); }
- Follow-Ups:
- 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
- Prev by Date: RE: [Ethereal-dev] attached packet trace causes ethereal to seg faultin JXTA dissector
- Next by Date: Re: [Ethereal-dev] Voip Calls analysis and Graph analysis
- Previous by thread: Re: [Ethereal-dev] Voip Calls analysis and Graph analysis
- Next by thread: Re: [Ethereal-dev] Voip Calls analysis and Graph analysis
- Index(es):