From Lars Roland:
authorguy <guy@f5534014-38df-0310-8fa8-9805f1628bb7>
Wed, 16 Apr 2003 07:25:12 +0000 (07:25 +0000)
committerguy <guy@f5534014-38df-0310-8fa8-9805f1628bb7>
Wed, 16 Apr 2003 07:25:12 +0000 (07:25 +0000)
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.

git-svn-id: http://anonsvn.wireshark.org/wireshark/trunk@7469 f5534014-38df-0310-8fa8-9805f1628bb7

15 files changed:
AUTHORS
Makefile.am
Makefile.nmake
gtk/Makefile.am
gtk/Makefile.nmake
gtk/menu.c
gtk/mgcp_stat.c [new file with mode: 0644]
gtk/mgcp_stat.h [new file with mode: 0644]
plugins/mgcp/AUTHORS
plugins/mgcp/ChangeLog
plugins/mgcp/moduleinfo.h
plugins/mgcp/packet-mgcp.c
tap-mgcpstat.c
timestats.c [new file with mode: 0644]
timestats.h [new file with mode: 0644]

diff --git a/AUTHORS b/AUTHORS
index 7ed0fc5ce626adca2427176522231e5c69444fae..4636028bec09580ea571994853b8948e6f7390e6 100644 (file)
--- 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> {
index 00dacd82718b5510953542f6c27f4ea969d2c693..e3ab400cfcb78e6903c1611dd76c16bd19191674 100644 (file)
@@ -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 \
index 422d3f1aaa5e6f983131ebfb362e5ff284269fd5..a8cc2fb9731ed8d7ea7b5ee973f4caa51617cda6 100644 (file)
@@ -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      \
index 99bd8d357c7690976f45f39824bf9d6d927ec26e..3fde739797f5ad0bec2076d5a30725dcf675fa3e 100644 (file)
@@ -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     \
index 1e43c56fe8240beafc922021b32b4d3ce8334b27..c53c791b676cb937a8456ce358088c634c369f8f 100644 (file)
@@ -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      \
index 57dd668c89fb6d96270120a1c93aabbc28255426..e0a65e5ce48bd61f63ce6d00d81113d0b6d7f87c 100644 (file)
@@ -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>
 #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 (file)
index 0000000..1fa087f
--- /dev/null
@@ -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 (file)
index 0000000..0cd6508
--- /dev/null
@@ -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
index 867d6688eb01d07eb82d4edff71acb42bbd036fd..36228a508cd5d3ddf8047652a9a189a412a89657 100644 (file)
@@ -1,3 +1,4 @@
 Author :
 Ed Warnicke <hagbard@physics.rutgers.edu>
+Lars Roland <lars.roland@gmx.net>
 
index 163d606266661303eefcd1a29768fb71a6d9af33..b9188486529df93a7cb376215da27f675d3f958c 100644 (file)
@@ -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.  
index f69fd1bbf3854a9a1b672c6da7f0c3bd3b0ffe57..472059d00b7639b7b5c0704f049b12fa29f7b27e 100644 (file)
@@ -13,5 +13,5 @@
 #endif
 
 /* Version number of package */
-#define VERSION "0.0.8"
+#define VERSION "0.0.9"
 
index a7695ced7588bde3d6687054a46697d3c46f72a0..16b94103d54df2a5f6aab6a436be257ff9f04091 100644 (file)
@@ -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);
        }
index 0f80b89f2d280244b3351740e158e50f70b29908..6ec9f5ea5eaa28fca0c723648df52f9b0b13fbaf 100644 (file)
@@ -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.
 #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 (file)
index 0000000..0a09f3a
--- /dev/null
@@ -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 (file)
index 0000000..8f584ef
--- /dev/null
@@ -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