aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGuy Harris <guy@alum.mit.edu>2003-04-16 07:25:12 +0000
committerGuy Harris <guy@alum.mit.edu>2003-04-16 07:25:12 +0000
commit7ddca7ecafcc8b383251e0b001b5e01a090a4fea (patch)
tree2978bb4fedf469dc86ddc1852d2295a744c20bc1
parentf17519118cbb588e3f945c8ab9847fbe87b3a8de (diff)
From Lars Roland:
Add Response-Time statistics for each known mgcp message-type. Fix a few bugs and remove trailing whitespace. Use "gdouble" for printing time-values and calculating the average. It is easier to use and shouldn't overflow on big trace files like "guint32". Move some functions for time statistics into the new file timestats.c in the main directory. This code may be useful in the rpc and smb rtt-taps as well. svn path=/trunk/; revision=7469
-rw-r--r--AUTHORS3
-rw-r--r--Makefile.am4
-rw-r--r--Makefile.nmake3
-rw-r--r--gtk/Makefile.am4
-rw-r--r--gtk/Makefile.nmake3
-rw-r--r--gtk/menu.c12
-rw-r--r--gtk/mgcp_stat.c353
-rw-r--r--gtk/mgcp_stat.h30
-rw-r--r--plugins/mgcp/AUTHORS1
-rw-r--r--plugins/mgcp/ChangeLog5
-rw-r--r--plugins/mgcp/moduleinfo.h2
-rw-r--r--plugins/mgcp/packet-mgcp.c31
-rw-r--r--tap-mgcpstat.c202
-rw-r--r--timestats.c132
-rw-r--r--timestats.h53
15 files changed, 709 insertions, 129 deletions
diff --git a/AUTHORS b/AUTHORS
index 7ed0fc5ce6..4636028bec 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -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