diff options
-rw-r--r-- | AUTHORS | 3 | ||||
-rw-r--r-- | Makefile.am | 4 | ||||
-rw-r--r-- | Makefile.nmake | 3 | ||||
-rw-r--r-- | gtk/Makefile.am | 4 | ||||
-rw-r--r-- | gtk/Makefile.nmake | 3 | ||||
-rw-r--r-- | gtk/menu.c | 12 | ||||
-rw-r--r-- | gtk/mgcp_stat.c | 353 | ||||
-rw-r--r-- | gtk/mgcp_stat.h | 30 | ||||
-rw-r--r-- | plugins/mgcp/AUTHORS | 1 | ||||
-rw-r--r-- | plugins/mgcp/ChangeLog | 5 | ||||
-rw-r--r-- | plugins/mgcp/moduleinfo.h | 2 | ||||
-rw-r--r-- | plugins/mgcp/packet-mgcp.c | 31 | ||||
-rw-r--r-- | tap-mgcpstat.c | 202 | ||||
-rw-r--r-- | timestats.c | 132 | ||||
-rw-r--r-- | timestats.h | 53 |
15 files changed, 709 insertions, 129 deletions
@@ -1639,7 +1639,8 @@ Laurent Meyer <laurent.meyer [AT] thales-avionics.com> { } Lars Roland <Lars.Roland [AT] gmx.net> { - MGCP request/response matching and MGCPSTAT calculation + MGCP request/response matching and MGCP statistics tap + Routines for handling time statistics } Miha Jemec <m.jemec [AT] iskratel.si> { diff --git a/Makefile.am b/Makefile.am index 00dacd8271..e3ab400cfc 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,7 +1,7 @@ # Makefile.am # Automake file for Ethereal # -# $Id: Makefile.am,v 1.573 2003/04/06 02:32:34 guy Exp $ +# $Id: Makefile.am,v 1.574 2003/04/16 07:24:03 guy Exp $ # # Ethereal - Network traffic analyzer # By Gerald Combs <gerald@ethereal.com> @@ -717,6 +717,8 @@ ETHEREAL_COMMON_SRC = \ smb.h \ tap.c \ tap.h \ + timestats.c \ + timestats.h \ util.c \ util.h \ x11-declarations.h \ diff --git a/Makefile.nmake b/Makefile.nmake index 422d3f1aaa..a8cc2fb973 100644 --- a/Makefile.nmake +++ b/Makefile.nmake @@ -1,7 +1,7 @@ ## Makefile for building ethereal.exe with Microsoft C and nmake ## Use: $(MAKE) /$(MAKEFLAGS) -f makefile.nmake # -# $Id: Makefile.nmake,v 1.292 2003/04/06 02:32:34 guy Exp $ +# $Id: Makefile.nmake,v 1.293 2003/04/16 07:24:03 guy Exp $ include config.nmake include <win32.mak> @@ -400,6 +400,7 @@ ETHEREAL_COMMON_OBJECTS = \ register.obj \ ringbuffer.obj \ tap.obj \ + timestats.obj \ util.obj \ xdlc.obj \ xmlstub.obj \ diff --git a/gtk/Makefile.am b/gtk/Makefile.am index 99bd8d357c..3fde739797 100644 --- a/gtk/Makefile.am +++ b/gtk/Makefile.am @@ -1,7 +1,7 @@ # Makefile.am # Automake file for the GTK interface routines for Ethereal # -# $Id: Makefile.am,v 1.54 2003/03/06 20:35:12 sahlberg Exp $ +# $Id: Makefile.am,v 1.55 2003/04/16 07:24:06 guy Exp $ # # Ethereal - Network traffic analyzer # By Gerald Combs <gerald@ethereal.com> @@ -32,6 +32,8 @@ ETHEREAL_TAP_SRC = \ dcerpc_stat.h \ io_stat.c \ io_stat.h \ + mgcp_stat.c \ + mgcp_stat.h \ rpc_stat.c \ rpc_stat.h \ rpc_progs.c \ diff --git a/gtk/Makefile.nmake b/gtk/Makefile.nmake index 1e43c56fe8..c53c791b67 100644 --- a/gtk/Makefile.nmake +++ b/gtk/Makefile.nmake @@ -1,7 +1,7 @@ ## Makefile for building ethereal.exe with Microsoft C and nmake ## Use: $(MAKE) /$(MAKEFLAGS) -f makefile.nmake # -# $Id: Makefile.nmake,v 1.41 2003/03/06 20:35:12 sahlberg Exp $ +# $Id: Makefile.nmake,v 1.42 2003/04/16 07:24:06 guy Exp $ include ..\config.nmake @@ -24,6 +24,7 @@ CVARSDLL=-DWIN32 -DNULL=0 -D_MT -D_DLL ETHEREAL_TAP_SRC = \ dcerpc_stat.c \ io_stat.c \ + mgcp_stat.c \ rpc_stat.c \ rpc_progs.c \ smb_stat.c \ diff --git a/gtk/menu.c b/gtk/menu.c index 57dd668c89..e0a65e5ce4 100644 --- a/gtk/menu.c +++ b/gtk/menu.c @@ -1,7 +1,7 @@ /* menu.c * Menu routines * - * $Id: menu.c,v 1.85 2003/03/06 21:21:43 deniel Exp $ + * $Id: menu.c,v 1.86 2003/04/16 07:24:06 guy Exp $ * * Ethereal - Network traffic analyzer * By Gerald Combs <gerald@ethereal.com> @@ -62,9 +62,11 @@ #include "rpc_progs.h" #include "dcerpc_stat.h" #include "smb_stat.h" +#include "mgcp_stat.h" #include "compat_macros.h" #include "gtkglobals.h" #include "tap_rtp.h" +#include "../tap.h" GtkWidget *popup_menu_object; @@ -254,6 +256,10 @@ static GtkItemFactoryEntry menu_items[] = NULL), ITEM_FACTORY_ENTRY("/Tools/Statistics/SMB/RTT", NULL, gtk_smbstat_cb, 0, NULL, NULL), + ITEM_FACTORY_ENTRY("/Tools/Statistics/MGCP", NULL, NULL, 0, "<Branch>", + NULL), + ITEM_FACTORY_ENTRY("/Tools/Statistics/MGCP/RTD", NULL, gtk_mgcpstat_cb, + 0, NULL, NULL), ITEM_FACTORY_ENTRY("/Tools/Statistics/RTP Analysis...", NULL, rtp_analyse_cb, 0, NULL, NULL), ITEM_FACTORY_ENTRY("/_Help", NULL, NULL, 0, "<LastBranch>", NULL), @@ -429,6 +435,10 @@ menus_init(void) { set_menu_sensitivity("/Edit/Copy", FALSE); set_menu_sensitivity("/Edit/Paste", FALSE); #endif + + if(!find_tap_id("mgcp")) { + set_menu_sensitivity("/Tools/Statistics/MGCP/RTD", FALSE); + } set_menus_for_captured_packets(FALSE); set_menus_for_selected_packet(FALSE); set_menus_for_selected_tree_row(FALSE); diff --git a/gtk/mgcp_stat.c b/gtk/mgcp_stat.c new file mode 100644 index 0000000000..1fa087f6db --- /dev/null +++ b/gtk/mgcp_stat.c @@ -0,0 +1,353 @@ +/* mgcp_stat.c + * mgcp-statistics for ethereal + * Copyright 2003 Lars Roland + * + * $Id: mgcp_stat.c,v 1.1 2003/04/16 07:24:06 guy Exp $ + * + * Ethereal - Network traffic analyzer + * By Gerald Combs <gerald@ethereal.com> + * Copyright 1998 Gerald Combs + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include <stdio.h> + +#ifdef HAVE_SYS_TYPES_H +# include <sys/types.h> +#endif + +#include <gtk/gtk.h> +#include <string.h> +#include "../epan/packet_info.h" +#include "../tap.h" +#include "../epan/value_string.h" +#include "../register.h" +#include "../plugins/mgcp/packet-mgcp.h" +#include "../timestats.h" +#include "mgcp_stat.h" +#include "compat_macros.h" +#include "../simple_dialog.h" +#include "../file.h" +#include "../globals.h" + +#define NUM_TIMESTATS 11 + +/* used to keep track of the statistics for an entire program interface */ +typedef struct _mgcpstat_t { + GtkWidget *win; + GtkWidget *vbox; + char *filter; + GtkWidget *table; + int table_height; + timestat_t rtd[NUM_TIMESTATS]; + guint32 open_req_num; + guint32 disc_rsp_num; + guint32 req_dup_num; + guint32 rsp_dup_num; +} mgcpstat_t; + +static const value_string mgcp_mesage_type[] = { + { 0, "Overall"}, + { 1, "EPCF"}, + { 2, "CRCX"}, + { 3, "MDCX"}, + { 4, "DLCX"}, + { 5, "RQNT"}, + { 6, "NTFY"}, + { 7, "AUEP"}, + { 8, "AUCX"}, + { 9, "RSIP"}, +}; + +static void +add_table_entry(mgcpstat_t *ss, char *str, int x, int y) +{ + GtkWidget *tmp; + + if(y>=ss->table_height){ + ss->table_height=y+1; + gtk_table_resize(GTK_TABLE(ss->table), ss->table_height, 7); + } + tmp=gtk_label_new(str); + gtk_table_attach_defaults(GTK_TABLE(ss->table), tmp, x, x+1, y, y+1); + gtk_label_set_justify(GTK_LABEL(tmp), GTK_JUSTIFY_LEFT); + gtk_widget_show(tmp); +} + + +static void +mgcpstat_reset(void *pms) +{ + mgcpstat_t *ms=(mgcpstat_t *)pms; + int i; + + for(i=0;i<NUM_TIMESTATS;i++) { + ms->rtd[i].num=0; + ms->rtd[i].min_num=0; + ms->rtd[i].max_num=0; + ms->rtd[i].min.secs=0; + ms->rtd[i].min.nsecs=0; + ms->rtd[i].max.secs=0; + ms->rtd[i].max.nsecs=0; + ms->rtd[i].tot.secs=0; + ms->rtd[i].tot.nsecs=0; + } + + ms->open_req_num=0; + ms->disc_rsp_num=0; + ms->req_dup_num=0; + ms->rsp_dup_num=0; + +} + + +static int +mgcpstat_packet(void *pms, packet_info *pinfo, epan_dissect_t *edt _U_, void *pmi) +{ + mgcpstat_t *ms=(mgcpstat_t *)pms; + mgcp_info_t *mi=pmi; + nstime_t delta; + + switch (mi->mgcp_type) { + + case MGCP_REQUEST: + if(mi->is_duplicate){ + /* Duplicate is ignored */ + ms->req_dup_num++; + return 0; + } + else { + ms->open_req_num++; + return 0; + } + break; + + case MGCP_RESPONSE: + if(mi->is_duplicate){ + /* Duplicate is ignored */ + ms->rsp_dup_num++; + return 0; + } + else if (!mi->request_available) { + /* no request was seen */ + ms->disc_rsp_num++; + return 0; + } + else { + ms->open_req_num--; + /* calculate time delta between request and response */ + delta.secs=pinfo->fd->abs_secs-mi->req_time.secs; + delta.nsecs=pinfo->fd->abs_usecs*1000-mi->req_time.nsecs; + if(delta.nsecs<0){ + delta.nsecs+=1000000000; + delta.secs--; + } + + time_stat_update(&(ms->rtd[0]),&delta, pinfo); + + if (strncasecmp(mi->code, "EPCF", 4) == 0 ) { + time_stat_update(&(ms->rtd[1]),&delta, pinfo); + } + else if (strncasecmp(mi->code, "CRCX", 4) == 0 ) { + time_stat_update(&(ms->rtd[2]),&delta, pinfo); + } + else if (strncasecmp(mi->code, "MDCX", 4) == 0 ) { + time_stat_update(&(ms->rtd[3]),&delta, pinfo); + } + else if (strncasecmp(mi->code, "DLCX", 4) == 0 ) { + time_stat_update(&(ms->rtd[4]),&delta, pinfo); + } + else if (strncasecmp(mi->code, "RQNT", 4) == 0 ) { + time_stat_update(&(ms->rtd[5]),&delta, pinfo); + } + else if (strncasecmp(mi->code, "NTFY", 4) == 0 ) { + time_stat_update(&(ms->rtd[6]),&delta, pinfo); + } + else if (strncasecmp(mi->code, "AUEP", 4) == 0 ) { + time_stat_update(&(ms->rtd[7]),&delta, pinfo); + } + else if (strncasecmp(mi->code, "AUCX", 4) == 0 ) { + time_stat_update(&(ms->rtd[8]),&delta, pinfo); + } + else if (strncasecmp(mi->code, "RSIP", 4) == 0 ) { + time_stat_update(&(ms->rtd[9]),&delta, pinfo); + } + else { + time_stat_update(&(ms->rtd[10]),&delta, pinfo); + } + + return 1; + } + break; + + default: + return 0; + break; + } +} + +static void +mgcpstat_draw(void *pms) +{ + mgcpstat_t *ms=(mgcpstat_t *)pms; + int i; + int pos; + char str[256]; + + gtk_widget_destroy(ms->table); + ms->table_height=5; + ms->table=gtk_table_new(ms->table_height, 7, TRUE); + gtk_container_add(GTK_CONTAINER(ms->vbox), ms->table); + + pos=0; + + add_table_entry(ms, "Type", 0, pos); + add_table_entry(ms, "Messages", 1, pos); + add_table_entry(ms, "Min RTD", 2, pos); + add_table_entry(ms, "Max RTD", 3, pos); + add_table_entry(ms, "Avg RTD", 4, pos); + add_table_entry(ms, "Min in Frame", 5, pos); + add_table_entry(ms, "Max in Frame", 6, pos); + pos++; + + for(i=0;i<NUM_TIMESTATS;i++) { + /* nothing seen, nothing to do */ + if(ms->rtd[i].num==0){ + continue; + } + + sprintf(str, "%s", val_to_str(i,mgcp_mesage_type,"Other")); + add_table_entry(ms, str, 0, pos); + sprintf(str, "%d", ms->rtd[i].num); + add_table_entry(ms, str, 1, pos); + sprintf(str, "%8.2f msec", nstime_to_msec(&(ms->rtd[i].min))); + add_table_entry(ms, str, 2, pos); + sprintf(str, "%8.2f msec", nstime_to_msec(&(ms->rtd[i].max))); + add_table_entry(ms, str, 3, pos); + sprintf(str, "%8.2f msec", get_average(&(ms->rtd[i].tot), ms->rtd[i].num)); + add_table_entry(ms, str, 4, pos); + sprintf(str, "%6u", ms->rtd[i].min_num); + add_table_entry(ms, str, 5, pos); + sprintf(str, "%6u", ms->rtd[i].max_num); + add_table_entry(ms, str, 6, pos); + pos++; + } + + gtk_widget_show(ms->table); +} + +void protect_thread_critical_region(void); +void unprotect_thread_critical_region(void); +static void +win_destroy_cb(GtkWindow *win _U_, gpointer data) +{ + mgcpstat_t *ms=(mgcpstat_t *)data; + + protect_thread_critical_region(); + remove_tap_listener(ms); + unprotect_thread_critical_region(); + + if(ms->filter){ + g_free(ms->filter); + ms->filter=NULL; + } + g_free(ms); +} + +void +gtk_mgcpstat_init(char *optarg) +{ + mgcpstat_t *ms; + char *filter=NULL; + GtkWidget *stat_label; + GtkWidget *filter_label; + char filter_string[256]; + + if(!strncmp(optarg,"mgcp,rtd,",9)){ + filter=optarg+9; + } else { + filter=g_malloc(1); + *filter='\0'; + } + + ms=g_malloc(sizeof(mgcpstat_t)); + ms->filter=g_malloc(strlen(filter)+1); + strcpy(ms->filter, filter); + + mgcpstat_reset(ms); + + ms->win=gtk_window_new(GTK_WINDOW_TOPLEVEL); + gtk_window_set_title(GTK_WINDOW(ms->win), "MGCP Response Time Delay (RTD) Statistics"); + SIGNAL_CONNECT(ms->win, "destroy", win_destroy_cb, ms); + + ms->vbox=gtk_vbox_new(FALSE, 0); + gtk_container_add(GTK_CONTAINER(ms->win), ms->vbox); + gtk_container_set_border_width(GTK_CONTAINER(ms->vbox), 10); + gtk_widget_show(ms->vbox); + + stat_label=gtk_label_new("MGCP Response Time Delay (RTD) Statistics"); + gtk_box_pack_start(GTK_BOX(ms->vbox), stat_label, FALSE, FALSE, 0); + gtk_widget_show(stat_label); + + snprintf(filter_string,255,"Filter:%s",filter?filter:""); + filter_label=gtk_label_new(filter_string); + gtk_box_pack_start(GTK_BOX(ms->vbox), filter_label, FALSE, FALSE, 0); + gtk_widget_show(filter_label); + + ms->table_height=5; + ms->table=gtk_table_new(ms->table_height, 7, TRUE); + gtk_container_add(GTK_CONTAINER(ms->vbox), ms->table); + + add_table_entry(ms, "Type", 0, 0); + add_table_entry(ms, "Messages", 1, 0); + add_table_entry(ms, "Min RTD", 2, 0); + add_table_entry(ms, "Max RTD", 3, 0); + add_table_entry(ms, "Avg RTD", 4, 0); + add_table_entry(ms, "Min in Frame", 5, 0); + add_table_entry(ms, "Max in Frame", 6, 0); + + gtk_widget_show(ms->table); + + if(register_tap_listener("mgcp", ms, filter, mgcpstat_reset, mgcpstat_packet, mgcpstat_draw)){ + char str[256]; + /* error, we failed to attach to the tap. clean up */ + snprintf(str,255,"Could not attach to tap using filter:%s",filter?filter:""); + simple_dialog(ESD_TYPE_WARN, NULL, str); + g_free(ms->filter); + g_free(ms); + return; + } + + gtk_widget_show_all(ms->win); + redissect_packets(&cfile); +} + +void +register_tap_listener_gtkmgcpstat(void) +{ + register_ethereal_tap("mgcp,rtd", gtk_mgcpstat_init, NULL, NULL); +} + + +void +gtk_mgcpstat_cb(GtkWidget *w _U_, gpointer d _U_) +{ + gtk_mgcpstat_init("mgcp,rtd"); +} diff --git a/gtk/mgcp_stat.h b/gtk/mgcp_stat.h new file mode 100644 index 0000000000..0cd650808b --- /dev/null +++ b/gtk/mgcp_stat.h @@ -0,0 +1,30 @@ +/* mgcp_stat.h + * mgcp_stat 2003 Lars Roland + * + * $Id: mgcp_stat.h,v 1.1 2003/04/16 07:24:06 guy Exp $ + * + * Ethereal - Network traffic analyzer + * By Gerald Combs <gerald@ethereal.com> + * Copyright 1998 Gerald Combs + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef __MGCPSTAT_H__ +#define __MGCPSTAT_H__ + +void gtk_mgcpstat_cb(GtkWidget *w, gpointer d); + +#endif diff --git a/plugins/mgcp/AUTHORS b/plugins/mgcp/AUTHORS index 867d6688eb..36228a508c 100644 --- a/plugins/mgcp/AUTHORS +++ b/plugins/mgcp/AUTHORS @@ -1,3 +1,4 @@ Author : Ed Warnicke <hagbard@physics.rutgers.edu> +Lars Roland <lars.roland@gmx.net> diff --git a/plugins/mgcp/ChangeLog b/plugins/mgcp/ChangeLog index 163d606266..b918848652 100644 --- a/plugins/mgcp/ChangeLog +++ b/plugins/mgcp/ChangeLog @@ -1,3 +1,8 @@ +Overview of changes in Ethereal MGCP plugin 0.0.9: +* Added calculation of request-to-response time delay +* support for building detailed delay statistics by the tapping + subsystem of ethereal + Overview of changes in Ethereal MGCP plugin 0.0.2: * Fixed misc problems with improperly dissecting some xgcp packets as short or malformed. diff --git a/plugins/mgcp/moduleinfo.h b/plugins/mgcp/moduleinfo.h index f69fd1bbf3..472059d00b 100644 --- a/plugins/mgcp/moduleinfo.h +++ b/plugins/mgcp/moduleinfo.h @@ -13,5 +13,5 @@ #endif /* Version number of package */ -#define VERSION "0.0.8" +#define VERSION "0.0.9" diff --git a/plugins/mgcp/packet-mgcp.c b/plugins/mgcp/packet-mgcp.c index a7695ced75..16b94103d5 100644 --- a/plugins/mgcp/packet-mgcp.c +++ b/plugins/mgcp/packet-mgcp.c @@ -2,7 +2,7 @@ * Routines for mgcp packet disassembly * RFC 2705 * - * $Id: packet-mgcp.c,v 1.37 2003/03/06 19:15:09 guy Exp $ + * $Id: packet-mgcp.c,v 1.38 2003/04/16 07:24:08 guy Exp $ * * Copyright (c) 2000 by Ed Warnicke <hagbard@physics.rutgers.edu> * @@ -189,7 +189,7 @@ static dissector_handle_t sdp_handle; /* * Init Hash table stuff */ - + typedef struct _mgcp_call_info_key { guint32 transid; conversation_t *conversation; @@ -329,7 +329,7 @@ dissect_mgcp_message(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gint tvb_sectionend,tvb_sectionbegin, tvb_len, tvb_current_len; tvbuff_t *next_tvb; static mgcp_info_t mi; - + /* Initialize variables */ tvb_sectionend = 0; tvb_sectionbegin = tvb_sectionend; @@ -441,7 +441,7 @@ mgcp_init_protocol(void) mgcp_call_info_value_chunk = g_mem_chunk_new("call_info_value_chunk", sizeof(mgcp_call_t), 200 * sizeof(mgcp_call_t), - G_ALLOC_ONLY); + G_ALLOC_ONLY); } /* Register all the bits needed with the filtering engine */ @@ -456,10 +456,10 @@ proto_register_mgcp(void) { &hf_mgcp_rsp, { "Response", "mgcp.rsp", FT_BOOLEAN, BASE_NONE, NULL, 0x0, "TRUE if MGCP response", HFILL }}, - { &hf_mgcp_req_frame, + { &hf_mgcp_req_frame, { "Request Frame", "mgcp.reqframe", FT_FRAMENUM, BASE_NONE, NULL, 0, "Request Frame", HFILL }}, - { &hf_mgcp_rsp_frame, + { &hf_mgcp_rsp_frame, { "Response Frame", "mgcp.rspframe", FT_FRAMENUM, BASE_NONE, NULL, 0, "Response Frame", HFILL }}, { &hf_mgcp_time, @@ -638,7 +638,7 @@ proto_register_mgcp(void) "Display the number of MGCP messages " "found in a packet in the protocol column.", &global_mgcp_message_count); - + mgcp_tap = register_tap("mgcp"); } @@ -968,7 +968,7 @@ static void dissect_mgcp_firstline(tvbuff_t *tvb, packet_info *pinfo, mgcp_call_info_key *new_mgcp_call_key = NULL; mgcp_call_t *mgcp_call = NULL; nstime_t delta; - + static address null_address = { AT_NONE, 0, NULL }; proto_item* (*my_proto_tree_add_string)(proto_tree*, int, tvbuff_t*, gint, gint, const char*); @@ -1073,6 +1073,7 @@ static void dissect_mgcp_firstline(tvbuff_t *tvb, packet_info *pinfo, tokennum++; } while( tvb_current_offset < tvb_len && tvb_previous_offset < tvb_len && tokennum <= 3); + switch (mgcp_type){ case MGCP_RESPONSE: proto_tree_add_boolean_hidden(tree, hf_mgcp_rsp, tvb, 0, 0, TRUE); @@ -1119,6 +1120,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; + strcpy(mi->code,mgcp_call->code); proto_tree_add_uint_format(tree, hf_mgcp_req_frame, tvb, 0, 0, mgcp_call->req_num, "This is a response to a request in frame %u", @@ -1144,7 +1146,7 @@ static void dissect_mgcp_firstline(tvbuff_t *tvb, packet_info *pinfo, if (mgcp_call->rsp_num != pinfo->fd->num) { /* No, so it's a duplicate response. Mark it as such. */ - mi->is_duplicate = TRUE; + mi->is_duplicate = TRUE; if (check_col(pinfo->cinfo, COL_INFO)) { col_append_fstr(pinfo->cinfo, COL_INFO, ", Duplicate Response %u",mi->transid); @@ -1206,11 +1208,11 @@ static void dissect_mgcp_firstline(tvbuff_t *tvb, packet_info *pinfo, pinfo->destport, 0); } } - + /* prepare the key data */ mgcp_call_key.transid = mi->transid; mgcp_call_key.conversation = conversation; - + /* look up the request */ mgcp_call = g_hash_table_lookup(mgcp_calls, &mgcp_call_key); if (mgcp_call != NULL) { @@ -1223,11 +1225,11 @@ static void dissect_mgcp_firstline(tvbuff_t *tvb, packet_info *pinfo, mi->is_duplicate = TRUE; if (check_col(pinfo->cinfo, COL_INFO)) { col_append_fstr(pinfo->cinfo, COL_INFO, - ", Duplicate Request %u",mi->transid); + ", Duplicate Request %u",mi->transid); if (tree) { - proto_tree_add_uint_hidden(tree, + proto_tree_add_uint_hidden(tree, hf_mgcp_dup, tvb, 0,0, mi->transid); - proto_tree_add_uint_hidden(tree, + proto_tree_add_uint_hidden(tree, hf_mgcp_req_dup, tvb, 0,0, mi->transid); } } @@ -1249,6 +1251,7 @@ 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/tap-mgcpstat.c b/tap-mgcpstat.c index 0f80b89f2d..6ec9f5ea5e 100644 --- a/tap-mgcpstat.c +++ b/tap-mgcpstat.c @@ -1,22 +1,22 @@ /* tap-mgcpstat.c * mgcpstat 2003 Lars Roland * - * $Id: tap-mgcpstat.c,v 1.3 2003/03/12 00:36:22 guy Exp $ + * $Id: tap-mgcpstat.c,v 1.4 2003/04/16 07:24:04 guy Exp $ * * Ethereal - Network traffic analyzer * By Gerald Combs <gerald@ethereal.com> * Copyright 1998 Gerald Combs - * + * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. @@ -38,67 +38,32 @@ #include "epan/value_string.h" #include "register.h" #include "plugins/mgcp/packet-mgcp.h" +#include "timestats.h" - -/* Summary of response-time calculations*/ -typedef struct _rtd_t { - long int num; - nstime_t min; - nstime_t max; - nstime_t tot; -} rtd_t; +#define NUM_TIMESTATS 11 /* used to keep track of the statistics for an entire program interface */ typedef struct _mgcpstat_t { char *filter; - rtd_t rtd; - long int open_req_num; - long int disc_rsp_num; - long int req_dup_num; - long int rsp_dup_num; + timestat_t rtd[NUM_TIMESTATS]; + guint32 open_req_num; + guint32 disc_rsp_num; + guint32 req_dup_num; + guint32 rsp_dup_num; } mgcpstat_t; -/* A Function to update a mgcp_rtd_t struct */ - -void -rtd_stat_update(rtd_t *rtd,nstime_t delta) -{ - rtd->num++; - if((rtd->max.secs==0) - && (rtd->max.nsecs==0) ){ - rtd->max.secs=delta.secs; - rtd->max.nsecs=delta.nsecs; - } - - if((rtd->min.secs==0) - && (rtd->min.nsecs==0) ){ - rtd->min.secs=delta.secs; - rtd->min.nsecs=delta.nsecs; - } - - if( (delta.secs<rtd->min.secs) - ||( (delta.secs==rtd->min.secs) - &&(delta.nsecs<rtd->min.nsecs) ) ){ - rtd->min.secs=delta.secs; - rtd->min.nsecs=delta.nsecs; - } - - if( (delta.secs>rtd->max.secs) - ||( (delta.secs==rtd->max.secs) - &&(delta.nsecs>rtd->max.nsecs) ) ){ - rtd->max.secs=delta.secs; - rtd->max.nsecs=delta.nsecs; - } - - rtd->tot.secs += delta.secs; - rtd->tot.nsecs += delta.nsecs; - if(rtd->tot.nsecs>1000000000){ - rtd->tot.nsecs-=1000000000; - rtd->tot.secs++; - } - - -} +static const value_string mgcp_mesage_type[] = { + { 0, "Overall"}, + { 1, "EPCF "}, + { 2, "CRCX "}, + { 3, "MDCX "}, + { 4, "DLCX "}, + { 5, "RQNT "}, + { 6, "NTFY "}, + { 7, "AUEP "}, + { 8, "AUCX "}, + { 9, "RSIP "}, +}; static int mgcpstat_packet(void *pms, packet_info *pinfo, epan_dissect_t *edt _U_, void *pmi) @@ -108,7 +73,7 @@ mgcpstat_packet(void *pms, packet_info *pinfo, epan_dissect_t *edt _U_, void *pm nstime_t delta; switch (mi->mgcp_type) { - + case MGCP_REQUEST: if(mi->is_duplicate){ /* Duplicate is ignored */ @@ -120,7 +85,7 @@ mgcpstat_packet(void *pms, packet_info *pinfo, epan_dissect_t *edt _U_, void *pm return 0; } break; - + case MGCP_RESPONSE: if(mi->is_duplicate){ /* Duplicate is ignored */ @@ -141,8 +106,40 @@ mgcpstat_packet(void *pms, packet_info *pinfo, epan_dissect_t *edt _U_, void *pm delta.nsecs+=1000000000; delta.secs--; } - - rtd_stat_update(&(ms->rtd),delta); + + time_stat_update(&(ms->rtd[0]),&delta, pinfo); + + if (strncasecmp(mi->code, "EPCF", 4) == 0 ) { + time_stat_update(&(ms->rtd[1]),&delta, pinfo); + } + else if (strncasecmp(mi->code, "CRCX", 4) == 0 ) { + time_stat_update(&(ms->rtd[2]),&delta, pinfo); + } + else if (strncasecmp(mi->code, "MDCX", 4) == 0 ) { + time_stat_update(&(ms->rtd[3]),&delta, pinfo); + } + else if (strncasecmp(mi->code, "DLCX", 4) == 0 ) { + time_stat_update(&(ms->rtd[4]),&delta, pinfo); + } + else if (strncasecmp(mi->code, "RQNT", 4) == 0 ) { + time_stat_update(&(ms->rtd[5]),&delta, pinfo); + } + else if (strncasecmp(mi->code, "NTFY", 4) == 0 ) { + time_stat_update(&(ms->rtd[6]),&delta, pinfo); + } + else if (strncasecmp(mi->code, "AUEP", 4) == 0 ) { + time_stat_update(&(ms->rtd[7]),&delta, pinfo); + } + else if (strncasecmp(mi->code, "AUCX", 4) == 0 ) { + time_stat_update(&(ms->rtd[8]),&delta, pinfo); + } + else if (strncasecmp(mi->code, "RSIP", 4) == 0 ) { + time_stat_update(&(ms->rtd[9]),&delta, pinfo); + } + else { + time_stat_update(&(ms->rtd[10]),&delta, pinfo); + } + return 1; } break; @@ -157,42 +154,29 @@ static void mgcpstat_draw(void *pms) { mgcpstat_t *ms=(mgcpstat_t *)pms; - -#ifdef G_HAVE_UINT64 - guint64 avg; -#else - guint32 avg; -#endif - - - /* calculating average rtd */ - /* scale it to units of 10us.*/ - /* for long captures with a large tot time, this can overflow on 32bit */ - avg=(int)ms->rtd.tot.secs; - avg=avg*100000+(int)ms->rtd.tot.nsecs/10000; - if(ms->rtd.num){ - avg/=ms->rtd.num; - } else { - avg=0; - } + int i; /* printing results */ printf("\n"); - printf("===================================================================\n"); + printf("=====================================================================================================\n"); printf("MGCP Response Time Delay (RTD) Statistics:\n"); - printf("Filter: %s\n",ms->filter?ms->filter:""); - printf("Duplicate requests: %ld\n",ms->req_dup_num); - printf("Duplicate responses: %ld\n",ms->rsp_dup_num); - printf("Open requests: %ld\n",ms->open_req_num); - printf("Discarded responses: %ld\n",ms->disc_rsp_num); - printf("Messages | Min RTD | Max RTD | Avg RTD \n"); - printf("%7ld | %5d.%03d msec | %5d.%03d msec | %5d.%02d0 msec\n", - ms->rtd.num, - (int)((ms->rtd.min.secs*1000)+(ms->rtd.min.nsecs/1000000)),(ms->rtd.min.nsecs%1000000)/1000, - (int)((ms->rtd.max.secs*1000)+(ms->rtd.max.nsecs/1000000)),(ms->rtd.max.nsecs%1000000)/1000, - avg/100, avg%100 - ); - printf("===================================================================\n"); + printf("Filter for statistics: %s\n",ms->filter?ms->filter:""); + printf("Duplicate requests: %u\n",ms->req_dup_num); + printf("Duplicate responses: %u\n",ms->rsp_dup_num); + printf("Open requests: %u\n",ms->open_req_num); + printf("Discarded responses: %u\n",ms->disc_rsp_num); + printf("Type | Messages | Min RTD | Max RTD | Avg RTD | Min in Frame | Max in Frame |\n"); + for(i=0;i<NUM_TIMESTATS;i++) { + if(ms->rtd[i].num) { + printf("%s | %7u | %8.2f msec | %8.2f msec | %8.2f msec | %10u | %10u |\n", + val_to_str(i,mgcp_mesage_type,"Other "),ms->rtd[i].num, + nstime_to_msec(&(ms->rtd[i].min)), nstime_to_msec(&(ms->rtd[i].max)), + get_average(&(ms->rtd[i].tot), ms->rtd[i].num), + ms->rtd[i].min_num, ms->rtd[i].max_num + ); + } + } + printf("=====================================================================================================\n"); } @@ -200,31 +184,33 @@ static void mgcpstat_init(char *optarg) { mgcpstat_t *ms; + int i; char *filter=NULL; if(!strncmp(optarg,"mgcp,rtd,",9)){ filter=optarg+9; } else { - filter=NULL; + filter=g_malloc(1); + *filter='\0'; } ms=g_malloc(sizeof(mgcpstat_t)); - if(filter){ - ms->filter=g_malloc(strlen(filter)+1); - strcpy(ms->filter, filter); - } else { - ms->filter=NULL; + ms->filter=g_malloc(strlen(filter)+1); + strcpy(ms->filter, filter); + + for(i=0;i<NUM_TIMESTATS;i++) { + ms->rtd[i].num=0; + ms->rtd[i].min_num=0; + ms->rtd[i].max_num=0; + ms->rtd[i].min.secs=0; + ms->rtd[i].min.nsecs=0; + ms->rtd[i].max.secs=0; + ms->rtd[i].max.nsecs=0; + ms->rtd[i].tot.secs=0; + ms->rtd[i].tot.nsecs=0; } - ms->rtd.num=0; - ms->rtd.min.secs=0; - ms->rtd.min.nsecs=0; - ms->rtd.max.secs=0; - ms->rtd.max.nsecs=0; - ms->rtd.tot.secs=0; - ms->rtd.tot.nsecs=0; - ms->open_req_num=0; ms->disc_rsp_num=0; ms->req_dup_num=0; diff --git a/timestats.c b/timestats.c new file mode 100644 index 0000000000..0a09f3a38e --- /dev/null +++ b/timestats.c @@ -0,0 +1,132 @@ +/* timestats.c + * routines for time statistics + * Copyrigth 2003 Lars Roland + * + * $Id: timestats.c,v 1.1 2003/04/16 07:24:04 guy Exp $ + * + * Ethereal - Network traffic analyzer + * By Gerald Combs <gerald@ethereal.com> + * Copyright 1998 Gerald Combs + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include "timestats.h" + +/* + * function: get_timedelta + * delta = b - a + */ + +void get_timedelta(nstime_t *delta, nstime_t *b, nstime_t *a ) +{ + delta->secs = b->secs - a->secs; + delta->nsecs= b->nsecs - a->nsecs; + if(delta->nsecs<0){ + delta->nsecs+=1000000000; + delta->secs--; + } +} + +/* + * function: addtime + * sum += a + */ + +void addtime(nstime_t *sum, nstime_t *a) +{ + sum->secs += a->secs; + sum->nsecs += a->nsecs; + if(sum->nsecs>1000000000){ + sum->nsecs-=1000000000; + sum->secs++; + } +} + +/* + * function: nstime_to_msec + * converts nstime to gdouble, time base is milli seconds + */ + +gdouble nstime_to_msec(nstime_t *time) +{ + return ((double)time->secs*1000 + (double)time->nsecs/1000000); +} + +/* A Function to update a timestat_t struct with a new sample*/ + +void +time_stat_update(timestat_t *stats, nstime_t *delta, packet_info *pinfo) +{ + if((stats->max.secs==0) + && (stats->max.nsecs==0) ){ + stats->max.secs=delta->secs; + stats->max.nsecs=delta->nsecs; + stats->max_num=pinfo->fd->num; + } + + if((stats->min.secs==0) + && (stats->min.nsecs==0) ){ + stats->min.secs=delta->secs; + stats->min.nsecs=delta->nsecs; + stats->min_num=pinfo->fd->num; + } + + if( (delta->secs<stats->min.secs) + ||( (delta->secs==stats->min.secs) + &&(delta->nsecs<stats->min.nsecs) ) ){ + stats->min.secs=delta->secs; + stats->min.nsecs=delta->nsecs; + stats->min_num=pinfo->fd->num; + } + + if( (delta->secs>stats->max.secs) + ||( (delta->secs==stats->max.secs) + &&(delta->nsecs>stats->max.nsecs) ) ){ + stats->max.secs=delta->secs; + stats->max.nsecs=delta->nsecs; + stats->max_num=pinfo->fd->num; + } + + stats->tot.secs += delta->secs; + stats->tot.nsecs += delta->nsecs; + if(stats->tot.nsecs>1000000000){ + stats->tot.nsecs-=1000000000; + stats->tot.secs++; + } + + stats->num++; +} + +/* + * get_average - function + * + * function to calculate the average + * returns the average as a gdouble , time base is milli seconds + */ + +gdouble get_average(nstime_t *sum, guint32 num) +{ + gdouble average; + + if(num > 0) { + average = (double)sum->secs*1000 + (double)sum->nsecs/1000000; + average /= num; + } + else { + average = 0; + } + return average; +} diff --git a/timestats.h b/timestats.h new file mode 100644 index 0000000000..8f584ef173 --- /dev/null +++ b/timestats.h @@ -0,0 +1,53 @@ +/* timestats.h + * Routines and definitions for time statistics + * Copyrigth 2003 Lars Roland + * + * $Id: timestats.h,v 1.1 2003/04/16 07:24:04 guy Exp $ + * + * Ethereal - Network traffic analyzer + * By Gerald Combs <gerald@ethereal.com> + * Copyright 1998 Gerald Combs + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef _time_stat +#define _time_stat + +#include <glib.h> +#include "epan/packet_info.h" +#include "epan/nstime.h" + + /* Summary of time statistics*/ +typedef struct _timestat_t { + guint32 num; /* number of samples */ + guint32 min_num; /* frame number of minimum */ + guint32 max_num; /* frame number of maximum */ + nstime_t min; + nstime_t max; + nstime_t tot; + gdouble variance; +} timestat_t; + +/* functions */ +extern void get_timedelta(nstime_t *delta, nstime_t *b, nstime_t *a ); /* delta = b - a */ +extern void addtime(nstime_t *sum, nstime_t *a); /* sum += a */ + +extern gdouble nstime_to_msec(nstime_t *time); /* converts nstime to gdouble, time base is milli seconds*/ + +extern void time_stat_update(timestat_t *stats, nstime_t *delta, packet_info *pinfo); +extern gdouble get_average(nstime_t *sum, guint32 num); + +#endif |