aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--AUTHORS2
-rw-r--r--Makefile.am5
-rw-r--r--Makefile.nmake4
-rw-r--r--doc/ethereal.pod35
-rw-r--r--doc/tethereal.pod16
-rw-r--r--gtk/Makefile.am3
-rw-r--r--gtk/Makefile.nmake3
-rw-r--r--gtk/h225_ras_srt.c441
-rwxr-xr-xh225-persistentdata.c174
-rwxr-xr-xh225-persistentdata.h62
-rw-r--r--packet-h225.c218
-rw-r--r--packet-h225.h5
-rwxr-xr-xtap-h225rassrt.c251
13 files changed, 1209 insertions, 10 deletions
diff --git a/AUTHORS b/AUTHORS
index b3754e2a26..183649aa29 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -1682,7 +1682,7 @@ Laurent Meyer <laurent.meyer6 [AT] wanadoo.fr> {
Lars Roland <Lars.Roland [AT] gmx.net> {
MGCP request/response matching and MGCP statistics tap
Common routines for use by statistics taps
- H.225 message and reason tag counter taps
+ H.225 message and reason tag counter taps and Service Response Times
}
Miha Jemec <m.jemec [AT] iskratel.si> {
diff --git a/Makefile.am b/Makefile.am
index 0c2dc7504c..aef364b222 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -1,7 +1,7 @@
# Makefile.am
# Automake file for Ethereal
#
-# $Id: Makefile.am,v 1.651 2003/11/11 08:29:33 guy Exp $
+# $Id: Makefile.am,v 1.652 2003/11/16 23:11:17 sahlberg Exp $
#
# Ethereal - Network traffic analyzer
# By Gerald Combs <gerald@ethereal.com>
@@ -780,6 +780,8 @@ ETHEREAL_COMMON_SRC = \
g711.c \
g711.h \
greproto.h \
+ h225-persistentdata.c \
+ h225-persistentdata.h \
in_cksum.c \
in_cksum.h \
ip_opts.h \
@@ -916,6 +918,7 @@ TETHEREAL_TAP_SRC = \
tap-bootpstat.c \
tap-dcerpcstat.c \
tap-h225counter.c \
+ tap-h225rassrt.c \
tap-httpstat.c \
tap-iostat.c \
tap-iousers.c \
diff --git a/Makefile.nmake b/Makefile.nmake
index 11ca686664..a9f246f035 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.358 2003/11/11 08:29:33 guy Exp $
+# $Id: Makefile.nmake,v 1.359 2003/11/16 23:11:17 sahlberg Exp $
include config.nmake
include <win32.mak>
@@ -413,6 +413,7 @@ TETHEREAL_TAP_SRC = \
tap-bootpstat.c \
tap-dcerpcstat.c \
tap-h225counter.c \
+ tap-h225rassrt.c \
tap-httpstat.c \
tap-iostat.c \
tap-iousers.c \
@@ -445,6 +446,7 @@ ETHEREAL_COMMON_OBJECTS = \
follow.obj \
g711.obj \
getopt.obj \
+ h225-persistentdata.obj \
in_cksum.obj \
ipproto.obj \
packet-dcerpc-nt.obj \
diff --git a/doc/ethereal.pod b/doc/ethereal.pod
index a05d37879b..72eecfe660 100644
--- a/doc/ethereal.pod
+++ b/doc/ethereal.pod
@@ -466,6 +466,25 @@ on those calls that match that filter.
Example: use B<-z "h225,counter,ip.addr==1.2.3.4"> to only collect stats for
H.225 packets exchanged by the host at IP address 1.2.3.4 .
+
+B<-z> h225,srt[I<,filter>]
+
+Collect requests/response SRT (Service Response Time) data for ITU-T H.225 RAS.
+Data collected is number of calls of each ITU-T H.225 RAS Message Type,
+Minimum SRT, Maximum SRT, Average SRT, Minimum in Frame, and Maximum in Frame.
+You will also get the number of Open Requests (Unresponded Requests),
+Discarded Responses (Responses without matching request) and Duplicate Messages.
+Example: use B<-z h225,srt>.
+
+This option can be used multiple times on the command line.
+
+If the optional filterstring is provided, the stats will only be calculated
+on those calls that match that filter.
+Example: use B<-z "h225,srt,ip.addr==1.2.3.4"> to only collect stats for
+ITU-T H.225 RAS packets exchanged by the host at IP address 1.2.3.4 .
+
+
+
=back
=head1 INTERFACE
@@ -1079,7 +1098,7 @@ Below the graph are the LOAD values for each interval that would be calculated.
Collect requests/response SRT (Service Response Time) data for MGCP.
Data collected is B<number of calls> for each known MGCP Type,
-B<Minimum SRT>, B<Maximum SRT> and B<Average SRT>.
+B<Minimum SRT>, B<Maximum SRT>, B<Average SRT>, B<Minimum in Frame>, and B<Maximum in Frame>.
These windows opened will update in semi-real time to reflect changes when
doing live captures or when reading new capture files into B<Ethereal>.
@@ -1100,6 +1119,20 @@ You can apply an optional filter string in a dialog box, before starting
the counter. The statistics will only be calculated
on those calls matching that filter.
+=item Tools:Statistics:Service Response Time:ITU-T H.225 RAS
+
+Collect requests/response SRT (Service Response Time) data for ITU-T H.225 RAS.
+Data collected is B<number of calls> for each known ITU-T H.225 RAS Message Type,
+B<Minimum SRT>, B<Maximum SRT>, B<Average SRT>, B<Minimum in Frame>, and B<Maximum in Frame>.
+You will also get the number of B<Open Requests> (Unresponded Requests),
+B<Discarded Responses> (Responses without matching request) and Duplicate Messages.
+These windows opened will update in semi-real time to reflect changes when
+doing live captures or when reading new capture files into B<Ethereal>.
+
+You can apply an optional filter string in a dialog box, before starting
+the calculation. The statistics will only be calculated
+on those calls matching that filter.
+
=back
=head2 WINDOWS
diff --git a/doc/tethereal.pod b/doc/tethereal.pod
index 0bd3988717..a590601501 100644
--- a/doc/tethereal.pod
+++ b/doc/tethereal.pod
@@ -615,6 +615,22 @@ on those calls that match that filter.
Example: use B<-z "h225,counter,ip.addr==1.2.3.4"> to only collect stats for
H.225 packets exchanged by the host at IP address 1.2.3.4 .
+B<-z> h225,srt[I<,filter>]
+
+Collect requests/response SRT (Service Response Time) data for ITU-T H.225 RAS.
+Data collected is number of calls of each ITU-T H.225 RAS Message Type,
+Minimum SRT, Maximum SRT, Average SRT, Minimum in Frame, and Maximum in Frame.
+You will also get the number of Open Requests (Unresponded Requests),
+Discarded Responses (Responses without matching request) and Duplicate Messages.
+Example: use B<-z h225,srt>.
+
+This option can be used multiple times on the command line.
+
+If the optional filterstring is provided, the stats will only be calculated
+on those calls that match that filter.
+Example: use B<-z "h225,srt,ip.addr==1.2.3.4"> to only collect stats for
+ITU-T H.225 RAS packets exchanged by the host at IP address 1.2.3.4 .
+
=back
=head1 CAPTURE FILTER SYNTAX
diff --git a/gtk/Makefile.am b/gtk/Makefile.am
index ab57244fc1..aa5c59563a 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.74 2003/11/15 08:47:29 ulfl Exp $
+# $Id: Makefile.am,v 1.75 2003/11/16 23:11:20 sahlberg Exp $
#
# Ethereal - Network traffic analyzer
# By Gerald Combs <gerald@ethereal.com>
@@ -40,6 +40,7 @@ ETHEREAL_TAP_SRC = \
endpoint_talkers_udpip.c \
fc_stat.c \
h225_counter.c \
+ h225_ras_srt.c \
http_stat.c \
io_stat.c \
ldap_stat.c \
diff --git a/gtk/Makefile.nmake b/gtk/Makefile.nmake
index eb7f08546c..a776acdecd 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.59 2003/11/15 08:48:14 ulfl Exp $
+# $Id: Makefile.nmake,v 1.60 2003/11/16 23:11:20 sahlberg Exp $
include ..\config.nmake
@@ -31,6 +31,7 @@ ETHEREAL_TAP_SRC = \
endpoint_talkers_udpip.c \
fc_stat.c \
h225_counter.c \
+ h225_ras_srt.c \
http_stat.c \
io_stat.c \
ldap_stat.c \
diff --git a/gtk/h225_ras_srt.c b/gtk/h225_ras_srt.c
new file mode 100644
index 0000000000..80ef5034de
--- /dev/null
+++ b/gtk/h225_ras_srt.c
@@ -0,0 +1,441 @@
+/* h225_ras_srt.c
+ * h225 RAS Service Response Time statistics for ethereal
+ * Copyright 2003 Lars Roland
+ *
+ * $Id: h225_ras_srt.c,v 1.1 2003/11/16 23:11:20 sahlberg 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 "../epan/epan.h"
+#include "menu.h"
+#include "../tap.h"
+#include "../epan/value_string.h"
+#include "../register.h"
+#include "../packet-h225.h"
+#include "../timestats.h"
+#include "gtk_stat_util.h"
+#include "compat_macros.h"
+#include "../simple_dialog.h"
+#include "dlg_utils.h"
+#include "../file.h"
+#include "../globals.h"
+
+extern GtkWidget *main_display_filter_widget;
+
+static GtkWidget *dlg=NULL;
+static GtkWidget *filter_entry;
+
+/* following values represent the size of their valuestring arrays */
+#define NUM_RAS_STATS 7
+
+static const value_string ras_message_category[] = {
+ { 0, "Gatekeeper "},
+ { 1, "Registration "},
+ { 2, "UnRegistration"},
+ { 3, "Admission "},
+ { 4, "Bandwidth "},
+ { 5, "Disengage "},
+ { 6, "Location "},
+ { 0, NULL }
+};
+
+typedef enum _ras_type {
+ RAS_REQUEST,
+ RAS_CONFIRM,
+ RAS_REJECT,
+ RAS_OTHER
+}ras_type;
+
+typedef enum _ras_category {
+ RAS_GATEKEEPER,
+ RAS_REGISTRATION,
+ RAS_UNREGISTRATION,
+ RAS_ADMISSION,
+ RAS_BANDWIDTH,
+ RAS_DISENGAGE,
+ RAS_LOCATION,
+ RAS_OTHERS
+}ras_category;
+
+/* Summary of response-time calculations*/
+typedef struct _h225_rtd_t {
+ guint32 open_req_num;
+ guint32 disc_rsp_num;
+ guint32 req_dup_num;
+ guint32 rsp_dup_num;
+ timestat_t stats;
+} h225_rtd_t;
+
+/* used to keep track of the statistics for an entire program interface */
+typedef struct _h225rassrt_t {
+ GtkWidget *win;
+ GtkWidget *vbox;
+ char *filter;
+ GtkWidget *scrolled_window;
+ GtkCList *table;
+ h225_rtd_t ras_rtd[NUM_RAS_STATS];
+} h225rassrt_t;
+
+
+static void
+h225rassrt_reset(void *phs)
+{
+ h225rassrt_t *hs=(h225rassrt_t *)phs;
+ int i;
+
+ for(i=0;i<NUM_RAS_STATS;i++) {
+ hs->ras_rtd[i].stats.num = 0;
+ hs->ras_rtd[i].stats.min_num = 0;
+ hs->ras_rtd[i].stats.max_num = 0;
+ hs->ras_rtd[i].stats.min.secs = 0;
+ hs->ras_rtd[i].stats.min.nsecs = 0;
+ hs->ras_rtd[i].stats.max.secs = 0;
+ hs->ras_rtd[i].stats.max.nsecs = 0;
+ hs->ras_rtd[i].stats.tot.secs = 0;
+ hs->ras_rtd[i].stats.tot.nsecs = 0;
+ hs->ras_rtd[i].open_req_num = 0;
+ hs->ras_rtd[i].disc_rsp_num = 0;
+ hs->ras_rtd[i].req_dup_num = 0;
+ hs->ras_rtd[i].rsp_dup_num = 0;
+ }
+
+}
+
+
+static int
+h225rassrt_packet(void *phs, packet_info *pinfo _U_, epan_dissect_t *edt _U_, void *phi)
+{
+ h225rassrt_t *hs=(h225rassrt_t *)phs;
+ h225_packet_info *pi=phi;
+
+ ras_type rasmsg_type = RAS_OTHER;
+ ras_category rascategory = RAS_OTHERS;
+
+ if (pi->msg_type != H225_RAS || pi->msg_tag == -1) {
+ /* No RAS Message or uninitialized msg_tag -> return */
+ return 0;
+ }
+
+ if (pi->msg_tag < 21) {
+ /* */
+ rascategory = pi->msg_tag / 3;
+ rasmsg_type = pi->msg_tag % 3;
+ }
+ else {
+ /* No SRT yet (ToDo) */
+ return 0;
+ }
+
+ switch(rasmsg_type) {
+
+ case RAS_REQUEST:
+ if(pi->is_duplicate){
+ hs->ras_rtd[rascategory].req_dup_num++;
+ }
+ else {
+ hs->ras_rtd[rascategory].open_req_num++;
+ }
+ break;
+
+ case RAS_CONFIRM:
+ /* no break - delay stats are identical for Confirm and Reject */
+ case RAS_REJECT:
+ if(pi->is_duplicate){
+ /* Duplicate is ignored */
+ hs->ras_rtd[rascategory].rsp_dup_num++;
+ }
+ else if (!pi->request_available) {
+ /* no request was seen, ignore response */
+ hs->ras_rtd[rascategory].disc_rsp_num++;
+ }
+ else {
+ hs->ras_rtd[rascategory].open_req_num--;
+ time_stat_update(&(hs->ras_rtd[rascategory].stats),&(pi->delta_time), pinfo);
+ }
+ break;
+
+ default:
+ return 0;
+ break;
+ }
+ return 1;
+}
+
+static void
+h225rassrt_draw(void *phs)
+{
+ h225rassrt_t *hs=(h225rassrt_t *)phs;
+ int i;
+ char *str[11];
+
+ for(i=0;i<11;i++) {
+ str[i]=g_malloc(sizeof(char[256]));
+ }
+ /* Now print Message and Reason Counter Table */
+ /* clear list before printing */
+ gtk_clist_clear(hs->table);
+
+ for(i=0;i<NUM_RAS_STATS;i++) {
+ /* nothing seen, nothing to do */
+ if(hs->ras_rtd[i].stats.num==0){
+ continue;
+ }
+
+ sprintf(str[0], "%s", val_to_str(i,ras_message_category,"Other"));
+ sprintf(str[1], "%7d", hs->ras_rtd[i].stats.num);
+ sprintf(str[2], "%8.2f msec", nstime_to_msec(&(hs->ras_rtd[i].stats.min)));
+ sprintf(str[3], "%8.2f msec", nstime_to_msec(&(hs->ras_rtd[i].stats.max)));;
+ sprintf(str[4], "%8.2f msec", get_average(&(hs->ras_rtd[i].stats.tot), hs->ras_rtd[i].stats.num));
+ sprintf(str[5], "%6u", hs->ras_rtd[i].stats.min_num);
+ sprintf(str[6], "%6u", hs->ras_rtd[i].stats.max_num);
+ sprintf(str[7], "%4u", hs->ras_rtd[i].open_req_num);
+ sprintf(str[8], "%4u", hs->ras_rtd[i].disc_rsp_num);
+ sprintf(str[9], "%4u", hs->ras_rtd[i].req_dup_num);
+ sprintf(str[10], "%4u", hs->ras_rtd[i].rsp_dup_num);
+ gtk_clist_append(GTK_CLIST(hs->table), str);
+ }
+
+ gtk_widget_show(GTK_WIDGET(hs->table));
+
+}
+
+void protect_thread_critical_region(void);
+void unprotect_thread_critical_region(void);
+static void
+win_destroy_cb(GtkWindow *win _U_, gpointer data)
+{
+ h225rassrt_t *hs=(h225rassrt_t *)data;
+
+ protect_thread_critical_region();
+ remove_tap_listener(hs);
+ unprotect_thread_critical_region();
+
+ if(hs->filter){
+ g_free(hs->filter);
+ hs->filter=NULL;
+ }
+ g_free(hs);
+}
+
+
+static gchar *titles[]={"RAS-Type",
+ "Measurements",
+ "Min RTT",
+ "Max RTT",
+ "Avg RTT",
+ "Min in Frame",
+ "Max in Frame",
+ "Open Requests",
+ "Discarded Responses",
+ "Repeated Requests",
+ "Repeated Responses" };
+
+void
+gtk_h225rassrt_init(char *optarg)
+{
+ h225rassrt_t *hs;
+ char *filter=NULL;
+ GString *error_string;
+
+ if(strncmp(optarg,"h225,srt,",9) == 0){
+ filter=optarg+9;
+ } else {
+ filter=g_malloc(1);
+ *filter='\0';
+ }
+
+ hs=g_malloc(sizeof(h225rassrt_t));
+ hs->filter=g_malloc(strlen(filter)+1);
+ strcpy(hs->filter, filter);
+
+ h225rassrt_reset(hs);
+
+ hs->win=gtk_window_new(GTK_WINDOW_TOPLEVEL);
+ SIGNAL_CONNECT(hs->win, "destroy", win_destroy_cb, hs);
+
+ hs->vbox=gtk_vbox_new(FALSE, 0);
+
+ init_main_stat_window(hs->win, hs->vbox, "ITU-T H.225 RAS Service Response Time", filter);
+
+ /* init a scrolled window*/
+ hs->scrolled_window = gtk_scrolled_window_new(NULL, NULL);
+ WIDGET_SET_SIZE(hs->scrolled_window, 600, 160);
+
+ hs->table = create_stat_table(hs->scrolled_window, hs->vbox, 11, titles);
+
+ error_string=register_tap_listener("h225", hs, filter, h225rassrt_reset, h225rassrt_packet, h225rassrt_draw);
+ if(error_string){
+ simple_dialog(ESD_TYPE_WARN, NULL, error_string->str);
+ g_string_free(error_string, TRUE);
+ g_free(hs->filter);
+ g_free(hs);
+ return;
+ }
+
+ gtk_widget_show_all(hs->win);
+ redissect_packets(&cfile);
+}
+
+
+
+static void
+dlg_destroy_cb(void)
+{
+ dlg=NULL;
+}
+
+static void
+dlg_cancel_cb(GtkWidget *cancel_bt _U_, gpointer parent_w)
+{
+ gtk_widget_destroy(GTK_WIDGET(parent_w));
+}
+
+static void
+h225rassrt_start_button_clicked(GtkWidget *item _U_, gpointer data _U_)
+{
+ char *filter;
+ char str[256];
+
+ filter=(char *)gtk_entry_get_text(GTK_ENTRY(filter_entry));
+ if(filter[0]==0){
+ gtk_h225rassrt_init("h225,srt");
+ } else {
+ sprintf(str,"h225,srt,%s", filter);
+ gtk_h225rassrt_init(str);
+ }
+}
+
+
+static void
+gtk_h225rassrt_cb(GtkWidget *w _U_, gpointer d _U_)
+{
+ char *filter;
+ char *title;
+ GtkWidget *dlg_box;
+ GtkWidget *filter_box, *filter_label;
+ GtkWidget *bbox, *start_button, *cancel_button;
+
+ /* if the window is already open, bring it to front */
+ if(dlg){
+ gdk_window_raise(dlg->window);
+ return;
+ }
+
+ title = g_strdup_printf("Ethereal: H.225 RAS Service Response Time: %s", cf_get_display_name(&cfile));
+
+ dlg=dlg_window_new(title);
+ g_free(title);
+ SIGNAL_CONNECT(dlg, "destroy", dlg_destroy_cb, NULL);
+
+ dlg_box=gtk_vbox_new(FALSE, 10);
+ gtk_container_border_width(GTK_CONTAINER(dlg_box), 10);
+ gtk_container_add(GTK_CONTAINER(dlg), dlg_box);
+ gtk_widget_show(dlg_box);
+
+ /* Filter box */
+ filter_box=gtk_hbox_new(FALSE, 3);
+
+ /* Filter label */
+ filter_label=gtk_label_new("Filter:");
+ gtk_box_pack_start(GTK_BOX(filter_box), filter_label, FALSE, FALSE, 0);
+ gtk_widget_show(filter_label);
+
+ /* Filter entry */
+ filter_entry=gtk_entry_new();
+ gtk_widget_set_usize(filter_entry, 300, -2);
+ gtk_box_pack_start(GTK_BOX(filter_box), filter_entry, TRUE, TRUE, 0);
+ filter=gtk_entry_get_text(GTK_ENTRY(main_display_filter_widget));
+ if(filter){
+ gtk_entry_set_text(GTK_ENTRY(filter_entry), filter);
+ }
+ gtk_widget_show(filter_entry);
+
+ gtk_box_pack_start(GTK_BOX(dlg_box), filter_box, TRUE, TRUE, 0);
+ gtk_widget_show(filter_box);
+
+ /* button box */
+ bbox = gtk_hbutton_box_new();
+ gtk_button_box_set_layout(GTK_BUTTON_BOX(bbox), GTK_BUTTONBOX_DEFAULT_STYLE);
+ gtk_button_box_set_spacing(GTK_BUTTON_BOX(bbox), 5);
+ gtk_box_pack_start(GTK_BOX(dlg_box), bbox, FALSE, FALSE, 0);
+ gtk_widget_show(bbox);
+
+ /* the start button */
+ start_button=gtk_button_new_with_label("Create Stat");
+ SIGNAL_CONNECT_OBJECT(start_button, "clicked",
+ h225rassrt_start_button_clicked, NULL);
+ gtk_box_pack_start(GTK_BOX(bbox), start_button, TRUE, TRUE, 0);
+ GTK_WIDGET_SET_FLAGS(start_button, GTK_CAN_DEFAULT);
+ gtk_widget_grab_default(start_button);
+ gtk_widget_show(start_button);
+
+#if GTK_MAJOR_VERSION < 2
+ cancel_button=gtk_button_new_with_label("Cancel");
+#else
+ cancel_button=gtk_button_new_from_stock(GTK_STOCK_CANCEL);
+#endif
+ SIGNAL_CONNECT(cancel_button, "clicked", dlg_cancel_cb, dlg);
+ GTK_WIDGET_SET_FLAGS(cancel_button, GTK_CAN_DEFAULT);
+ gtk_box_pack_start(GTK_BOX(bbox), cancel_button, TRUE, TRUE, 0);
+ gtk_widget_show(cancel_button);
+
+ /* Catch the "activate" signal on the filter text entry, so that
+ if the user types Return there, we act as if the "Create Stat"
+ button had been selected, as happens if Return is typed if
+ some widget that *doesn't* handle the Return key has the input
+ focus. */
+ dlg_set_activate(filter_entry, start_button);
+
+ /* Catch the "key_press_event" signal in the window, so that we can
+ catch the ESC key being pressed and act as if the "Cancel" button
+ had been selected. */
+ dlg_set_cancel(dlg, cancel_button);
+
+ /* Give the initial focus to the "Filter" entry box. */
+ gtk_widget_grab_focus(filter_entry);
+
+ gtk_widget_show_all(dlg);
+}
+
+void
+register_tap_listener_gtk_h225rassrt(void)
+{
+ register_ethereal_tap("h225,srt", gtk_h225rassrt_init);
+}
+
+void
+register_tap_menu_gtk_h225rassrt(void)
+{
+ register_tap_menu_item("Statistics/Service Response Time/ITU-T H.225 RAS ...",
+ gtk_h225rassrt_cb, NULL, NULL);
+}
diff --git a/h225-persistentdata.c b/h225-persistentdata.c
new file mode 100755
index 0000000000..40b5607a5b
--- /dev/null
+++ b/h225-persistentdata.c
@@ -0,0 +1,174 @@
+/*
+ * h225-persistentdata.c
+ * Source for lists and hash tables used in ethereal's h225 dissector
+ * for calculation of delays in h225-calls
+ *
+ * Copyright 2003 Lars Roland
+ *
+ * $Id: h225-persistentdata.c,v 1.1 2003/11/16 23:11:18 sahlberg 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 <glib.h>
+#include <epan/packet.h>
+#include <epan/conversation.h>
+
+#include <stdio.h>
+#include <string.h>
+
+#include "h225-persistentdata.h"
+
+/* Global Memory Chunks for lists and Global hash tables*/
+
+static GMemChunk *h225ras_call_info_key_chunk = NULL;
+static GMemChunk *h225ras_call_info_value_chunk = NULL;
+
+static GHashTable *ras_calls[7] = {NULL, NULL, NULL, NULL, NULL, NULL, NULL};
+
+/*
+ * Functions needed for Ras-Hash-Table
+ */
+
+/* compare 2 keys */
+static gint h225ras_call_equal(gconstpointer k1, gconstpointer k2)
+{
+ const h225ras_call_info_key* key1 = (const h225ras_call_info_key*) k1;
+ const h225ras_call_info_key* key2 = (const h225ras_call_info_key*) k2;
+
+ return (key1->reqSeqNum == key2->reqSeqNum &&
+ key1->conversation == key2->conversation);
+}
+
+/* calculate a hash key */
+static guint h225ras_call_hash(gconstpointer k)
+{
+ const h225ras_call_info_key* key = (const h225ras_call_info_key*) k;
+
+ return key->reqSeqNum + (guint32)(key->conversation);
+}
+
+
+h225ras_call_t * find_h225ras_call(h225ras_call_info_key *h225ras_call_key ,int category)
+{
+ h225ras_call_t *h225ras_call = NULL;
+ h225ras_call = (h225ras_call_t *)g_hash_table_lookup(ras_calls[category], h225ras_call_key);
+
+ return h225ras_call;
+}
+
+h225ras_call_t * new_h225ras_call(h225ras_call_info_key *h225ras_call_key, packet_info *pinfo, guint8 *guid, int category)
+{
+ h225ras_call_info_key *new_h225ras_call_key;
+ h225ras_call_t *h225ras_call = NULL;
+
+
+ /* Prepare the value data.
+ "req_num" and "rsp_num" are frame numbers;
+ frame numbers are 1-origin, so we use 0
+ to mean "we don't yet know in which frame
+ the reply for this call appears". */
+ new_h225ras_call_key = (h225ras_call_info_key *)g_mem_chunk_alloc(h225ras_call_info_key_chunk);
+ new_h225ras_call_key->reqSeqNum = h225ras_call_key->reqSeqNum;
+ new_h225ras_call_key->conversation = h225ras_call_key->conversation;
+ h225ras_call = (h225ras_call_t *)g_mem_chunk_alloc(h225ras_call_info_value_chunk);
+ h225ras_call->req_num = pinfo->fd->num;
+ h225ras_call->rsp_num = 0;
+ h225ras_call->requestSeqNum = h225ras_call_key->reqSeqNum;
+ h225ras_call->responded = FALSE;
+ h225ras_call->next_call = NULL;
+ h225ras_call->req_time.secs=pinfo->fd->abs_secs;
+ h225ras_call->req_time.nsecs=pinfo->fd->abs_usecs*1000;
+ memcpy(h225ras_call->guid, guid,16);
+ /* store it */
+ g_hash_table_insert(ras_calls[category], new_h225ras_call_key, h225ras_call);
+
+ return h225ras_call;
+}
+
+h225ras_call_t * append_h225ras_call(h225ras_call_t *prev_call, packet_info *pinfo, guint8 *guid, int category _U_)
+{
+ h225ras_call_t *h225ras_call = NULL;
+
+ /* Prepare the value data.
+ "req_num" and "rsp_num" are frame numbers;
+ frame numbers are 1-origin, so we use 0
+ to mean "we don't yet know in which frame
+ the reply for this call appears". */
+ h225ras_call = (h225ras_call_t *)g_mem_chunk_alloc(h225ras_call_info_value_chunk);
+ h225ras_call->req_num = pinfo->fd->num;
+ h225ras_call->rsp_num = 0;
+ h225ras_call->requestSeqNum = prev_call->requestSeqNum;
+ h225ras_call->responded = FALSE;
+ h225ras_call->next_call = NULL;
+ h225ras_call->req_time.secs=pinfo->fd->abs_secs;
+ h225ras_call->req_time.nsecs=pinfo->fd->abs_usecs*1000;
+ memcpy(h225ras_call->guid, guid,16);
+
+ prev_call->next_call = h225ras_call;
+ return h225ras_call;
+}
+
+
+/* Init routine for hash tables and delay calculation
+ This routine will be called by Ethereal, before it
+ is (re-)dissecting a trace file from beginning.
+ We need to discard and init any state we've saved */
+
+void
+h225_init_routine(void)
+{
+ int i;
+
+ /* free hash-tables and mem_chunks for RAS SRT */
+ for(i=0;i<7;i++) {
+ if (ras_calls[i] != NULL) {
+ g_hash_table_destroy(ras_calls[i]);
+ ras_calls[i] = NULL;
+ }
+ }
+
+ if (h225ras_call_info_key_chunk != NULL) {
+ g_mem_chunk_destroy(h225ras_call_info_key_chunk);
+ h225ras_call_info_key_chunk = NULL;
+ }
+ if (h225ras_call_info_value_chunk != NULL) {
+ g_mem_chunk_destroy(h225ras_call_info_value_chunk);
+ h225ras_call_info_value_chunk = NULL;
+ }
+
+ /* create new hash-tables and mem_chunks for RAS SRT */
+
+ for(i=0;i<7;i++) {
+ ras_calls[i] = g_hash_table_new(h225ras_call_hash, h225ras_call_equal);
+ }
+
+ h225ras_call_info_key_chunk = g_mem_chunk_new("call_info_key_chunk",
+ sizeof(h225ras_call_info_key),
+ 400 * sizeof(h225ras_call_info_key),
+ G_ALLOC_ONLY);
+ h225ras_call_info_value_chunk = g_mem_chunk_new("call_info_value_chunk",
+ sizeof(h225ras_call_t),
+ 400 * sizeof(h225ras_call_t),
+ G_ALLOC_ONLY);
+}
diff --git a/h225-persistentdata.h b/h225-persistentdata.h
new file mode 100755
index 0000000000..061978a51d
--- /dev/null
+++ b/h225-persistentdata.h
@@ -0,0 +1,62 @@
+/*
+ * h225-persistentdata.h
+ * Definitions for lists and hash tables used in ethereal's h225 dissector
+ * for calculation of delays in h225-calls
+ *
+ * Copyright 2003 Lars Roland
+ *
+ * $Id: h225-persistentdata.h,v 1.1 2003/11/16 23:11:18 sahlberg 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 __h225_HASH__
+#define __h225_HASH__
+
+#include <glib.h>
+#include <epan/packet.h>
+#include <epan/conversation.h>
+
+
+/* Item of ras request list*/
+typedef struct _h225ras_call_t {
+ guint32 requestSeqNum;
+ guint8 guid[16];
+ guint32 req_num; /* frame number request seen */
+ guint32 rsp_num; /* frame number response seen */
+ nstime_t req_time; /* arrival time of request */
+ gboolean responded; /* true, if request has been responded */
+ struct _h225ras_call_t *next_call; /* pointer to next ras request with same SequenceNumber and conversation handle */
+} h225ras_call_t;
+
+
+/* Item of ras-request key list*/
+typedef struct _h225ras_call_info_key {
+ guint reqSeqNum;
+ conversation_t *conversation;
+} h225ras_call_info_key;
+
+/* functions, needed using ras-request and halfcall matching*/
+h225ras_call_t * find_h225ras_call(h225ras_call_info_key *h225ras_call_key ,int category);
+h225ras_call_t * new_h225ras_call(h225ras_call_info_key *h225ras_call_key, packet_info *pinfo, guint8 *guid, int category);
+h225ras_call_t * append_h225ras_call(h225ras_call_t *prev_call, packet_info *pinfo, guint8 *guid, int category);
+
+void h225_init_routine(void); /* init routine, used by ethereal */
+
+#endif /* __h225_HASH__*/
diff --git a/packet-h225.c b/packet-h225.c
index 4d04e6a800..9775e145ea 100644
--- a/packet-h225.c
+++ b/packet-h225.c
@@ -4,7 +4,7 @@
*
* Maintained by Andreas Sikkema (andreas.sikkema@philips.com)
*
- * $Id: packet-h225.c,v 1.24 2003/11/10 21:42:38 guy Exp $
+ * $Id: packet-h225.c,v 1.25 2003/11/16 23:11:18 sahlberg Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@ethereal.com>
@@ -43,12 +43,14 @@
#include "packet-h225.h"
#include "packet-h245.h"
#include "t35.h"
+#include "h225-persistentdata.h"
#define UDP_PORT_RAS1 1718
#define UDP_PORT_RAS2 1719
#define TCP_PORT_CS 1720
static void reset_h225_packet_info(h225_packet_info *pi);
+static void ras_call_matching(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, h225_packet_info *pi);
static h225_packet_info h225_pi;
@@ -524,6 +526,10 @@ static int hf_h225_nonStandard = -1;
static int hf_h225_nonStandardReason = -1;
static int hf_h225_nonStandardAddress = -1;
static int hf_h225_aliasAddress_sequence = -1;
+static int hf_h225_ras_req_frame = -1;
+static int hf_h225_ras_rsp_frame = -1;
+static int hf_h225_ras_dup = -1;
+static int hf_h225_ras_deltatime = -1;
/*aaa*/
static gint ett_h225 = -1;
@@ -7150,7 +7156,10 @@ dissect_h225_h323_message_body(tvbuff_t *tvb, int offset, packet_info *pinfo, pr
val_to_str(value, h323_message_body_vals, "<unknown>"));
}
- h225_pi.msg_tag = value;
+ if (h225_pi.msg_type == H225_CS) {
+ /* Don't override msg_tag value from IRR */
+ h225_pi.msg_tag = value;
+ }
if (contains_faststart == TRUE )
{
@@ -8449,6 +8458,8 @@ dissect_h225_RasMessage(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
}
h225_pi.msg_tag = value;
+ ras_call_matching(tvb, pinfo, tr, &(h225_pi));
+
tap_queue_packet(h225_tap, pinfo, &h225_pi);
}
@@ -9900,6 +9911,18 @@ proto_register_h225(void)
{ &hf_h225_nonStandardAddress,
{ "nonStandardAddress", "h225.nonStandardAddress", FT_NONE, BASE_NONE,
NULL, 0, "NonStandardParameter SEQUENCE", HFILL }},
+ { &hf_h225_ras_req_frame,
+ { "RAS Request Frame", "h225.ras.reqframe", FT_FRAMENUM, BASE_NONE,
+ NULL, 0, "RAS Request Frame", HFILL }},
+ { &hf_h225_ras_rsp_frame,
+ { "RAS Response Frame", "h225.ras.rspframe", FT_FRAMENUM, BASE_NONE,
+ NULL, 0, "RAS Response Frame", HFILL }},
+ { &hf_h225_ras_dup,
+ { "Duplicate RAS Message", "h225.ras.dup", FT_UINT32, BASE_DEC,
+ NULL, 0, "Duplicate RAS Message", HFILL }},
+ { &hf_h225_ras_deltatime,
+ { "RAS Service Response Time", "h225.ras.timedelta", FT_RELATIVE_TIME, BASE_NONE,
+ NULL, 0, "Timedelta between RAS-Request and RAS-Response", HFILL }},
/*ddd*/
};
@@ -10169,7 +10192,7 @@ proto_register_h225(void)
&ett_h225_H221NonStandard,
&ett_h225_NonStandardIdentifier,
&ett_h225_NonStandardParameter,
- &ett_h225_aliasAddress_sequence,
+ &ett_h225_aliasAddress_sequence,
/*eee*/
};
module_t *h225_module;
@@ -10187,6 +10210,7 @@ proto_register_h225(void)
nsp_object_dissector_table = register_dissector_table("h225.nsp.object", "H.245 NonStandardParameter (object)", FT_STRING, BASE_NONE);
nsp_h221_dissector_table = register_dissector_table("h225.nsp.h221", "H.245 NonStandardParameter (h221)", FT_UINT32, BASE_HEX);
+ register_init_routine(&h225_init_routine);
h225_tap = register_tap("h225");
}
@@ -10205,6 +10229,7 @@ proto_reg_handoff_h225(void)
dissector_add("udp.port", UDP_PORT_RAS2, h225ras_handle);
}
+
static void reset_h225_packet_info(h225_packet_info *pi)
{
if(pi == NULL) {
@@ -10216,4 +10241,191 @@ static void reset_h225_packet_info(h225_packet_info *pi)
pi->reason = -1;
pi->requestSeqNum = 0;
memset(pi->guid,0,16);
+ pi->is_duplicate = FALSE;
+ pi->request_available = FALSE;
+}
+
+/*
+ The following function contains the routines for RAS request/response matching.
+ A RAS response matches with a request, if both messages have the same
+ RequestSequenceNumber, belong to the same IP conversation and belong to the same
+ RAS "category" (e.g. Admission, Registration).
+
+ We use hashtables to access the lists of RAS calls (request/response pairs).
+ We have one hashtable for each RAS category. The hashkeys consist of the
+ non-unique 16-bit RequestSequenceNumber and values representing the conversation.
+
+ In big capture files, we might get different requests with identical keys.
+ These requests aren't necessarily duplicates. They might be valid new requests.
+ At the moment we just use the timedelta between the last valid and the new request
+ to decide if the new request is a duplicate or not. There might be better ways.
+ Two thresholds are defined below.
+
+ However the decision is made, another problem arises. We can't just add those
+ requests to our hashtables. Instead we create lists of RAS calls with identical keys.
+ The hashtables for RAS calls contain now pointers to the first RAS call in a list of
+ RAS calls with identical keys.
+ These lists aren't expected to contain more than 3 items and are usually single item
+ lists. So we don't need an expensive but intelligent way to access these lists
+ (e.g. hashtables). Just walk through such a list.
+*/
+
+#define THRESHOLD_REPEATED_RESPONDED_CALL 300
+#define THRESHOLD_REPEATED_NOT_RESPONDED_CALL 1800
+
+static void ras_call_matching(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, h225_packet_info *pi)
+{
+ conversation_t* conversation = NULL;
+ h225ras_call_info_key h225ras_call_key;
+ h225ras_call_t *h225ras_call = NULL;
+ nstime_t delta;
+ guint msg_category;
+
+ if(pi->msg_type == H225_RAS && pi->msg_tag < 21) {
+ /* make RAS request/response matching only for tags from 0 to 20 for now */
+
+ msg_category = pi->msg_tag / 3;
+ if(pi->msg_tag % 3 == 0) { /* Request Message */
+ conversation = find_conversation(&pinfo->src,
+ &pinfo->dst, pinfo->ptype, pinfo->srcport,
+ pinfo->destport, 0);
+
+ if (conversation == NULL) {
+ /* It's not part of any conversation - create a new one. */
+ conversation = conversation_new(&pinfo->src,
+ &pinfo->dst, pinfo->ptype, pinfo->srcport,
+ pinfo->destport, 0);
+
+ }
+
+ /* prepare the key data */
+ h225ras_call_key.reqSeqNum = pi->requestSeqNum;
+ h225ras_call_key.conversation = conversation;
+
+ /* look up the request */
+ h225ras_call = find_h225ras_call(&h225ras_call_key ,msg_category);
+
+ if (h225ras_call != NULL) {
+ /* We've seen requests with this reqSeqNum, with the same
+ source and destination, before - do we have
+ *this* request already? */
+ /* Walk through list of ras requests with identical keys */
+ do {
+ if (pinfo->fd->num == h225ras_call->req_num) {
+ /* We have seen this request before -> do nothing */
+ break;
+ }
+
+ /* if end of list is reached, exit loop and decide if request is duplicate or not. */
+ if (h225ras_call->next_call == NULL) {
+ if ( (pinfo->fd->num > h225ras_call->rsp_num && h225ras_call->rsp_num != 0
+ && pinfo->fd->abs_secs > h225ras_call->req_time.secs + THRESHOLD_REPEATED_RESPONDED_CALL )
+ ||(pinfo->fd->num > h225ras_call->req_num && h225ras_call->rsp_num == 0
+ && pinfo->fd->abs_secs > h225ras_call->req_time.secs + THRESHOLD_REPEATED_NOT_RESPONDED_CALL ) )
+ {
+ /* if last request has been responded
+ and this request appears after last response (has bigger frame number)
+ and last request occured more than 300 seconds ago,
+ or if last request hasn't been responded
+ and this request appears after last request (has bigger frame number)
+ and last request occured more than 1800 seconds ago,
+ we decide that we have a new request */
+ /* Append new ras call to list */
+ h225ras_call = append_h225ras_call(h225ras_call, pinfo, pi->guid, msg_category);
+ } else {
+ /* No, so it's a duplicate request.
+ Mark it as such. */
+ pi->is_duplicate = TRUE;
+ proto_tree_add_uint_hidden(tree, hf_h225_ras_dup, tvb, 0,0, pi->requestSeqNum);
+ }
+ break;
+ }
+ h225ras_call = h225ras_call->next_call;
+ } while (h225ras_call != NULL );
+ }
+ else {
+ h225ras_call = new_h225ras_call(&h225ras_call_key, pinfo, pi->guid, msg_category);
+ }
+
+ /* add link to response frame, if available */
+ if(h225ras_call->rsp_num != 0){
+ proto_tree_add_uint_format(tree, hf_h225_ras_rsp_frame, tvb, 0, 0, h225ras_call->rsp_num,
+ "The response to this request is in frame %u", h225ras_call->rsp_num);
+ }
+
+ /* end of request message handling*/
+ }
+ else { /* Confirm or Reject Message */
+ conversation = find_conversation(&pinfo->src,
+ &pinfo->dst, pinfo->ptype, pinfo->srcport,
+ pinfo->destport, 0);
+ if (conversation != NULL) {
+ /* look only for matching request, if
+ matching conversation is available. */
+ h225ras_call_key.reqSeqNum = pi->requestSeqNum;
+ h225ras_call_key.conversation = conversation;
+ h225ras_call = find_h225ras_call(&h225ras_call_key ,msg_category);
+ if(h225ras_call) {
+ /* find matching ras_call in list of ras calls with identical keys */
+ do {
+ if (pinfo->fd->num == h225ras_call->rsp_num) {
+ /* We have seen this response before -> stop now with matching ras call */
+ break;
+ }
+
+ /* Break when list end is reached */
+ if(h225ras_call->next_call == NULL) {
+ break;
+ }
+ h225ras_call = h225ras_call->next_call;
+ } while (h225ras_call != NULL) ;
+
+ /* if this is an ACF, ARJ or DCF, DRJ, give guid to tap and make it filterable */
+ if (msg_category == 3 || msg_category == 5) {
+ memcpy(pi->guid, h225ras_call->guid,16);
+ proto_tree_add_bytes_hidden(tree, hf_h225_guid, tvb, 0, 16, pi->guid);
+ }
+
+ if (h225ras_call->rsp_num == 0) {
+ /* We have not yet seen a response to that call, so
+ this must be the first response; remember its
+ frame number. */
+ h225ras_call->rsp_num = pinfo->fd->num;
+ }
+ else {
+ /* We have seen a response to this call - but was it
+ *this* response? */
+ if (h225ras_call->rsp_num != pinfo->fd->num) {
+ /* No, so it's a duplicate response.
+ Mark it as such. */
+ pi->is_duplicate = TRUE;
+ proto_tree_add_uint_hidden(tree, hf_h225_ras_dup, tvb, 0,0, pi->requestSeqNum);
+ }
+ }
+
+ if(h225ras_call->req_num != 0){
+ h225ras_call->responded = TRUE;
+ pi->request_available = TRUE;
+
+ /* Indicate the frame to which this is a reply. */
+ proto_tree_add_uint_format(tree, hf_h225_ras_req_frame, tvb, 0, 0, h225ras_call->req_num,
+ "This is a response to a request in frame %u", h225ras_call->req_num);
+
+ /* Calculate RAS Service Response Time */
+ delta.secs= pinfo->fd->abs_secs-h225ras_call->req_time.secs;
+ delta.nsecs=pinfo->fd->abs_usecs*1000-h225ras_call->req_time.nsecs;
+ if(delta.nsecs<0){
+ delta.nsecs+=1000000000;
+ delta.secs--;
+ }
+ pi->delta_time.secs = delta.secs; /* give it to tap */
+ pi->delta_time.nsecs = delta.nsecs;
+
+ /* display Ras Service Response Time and make it filterable */
+ proto_tree_add_time(tree, hf_h225_ras_deltatime, tvb, 0, 0, &(pi->delta_time));
+ }
+ }
+ }
+ }
+ }
}
diff --git a/packet-h225.h b/packet-h225.h
index b0e57d611b..1af4f2221f 100644
--- a/packet-h225.h
+++ b/packet-h225.h
@@ -2,7 +2,7 @@
* Routines for H.225 packet dissection
* 2003 Tomas Kukosa
*
- * $Id: packet-h225.h,v 1.4 2003/10/28 00:31:16 guy Exp $
+ * $Id: packet-h225.h,v 1.5 2003/11/16 23:11:18 sahlberg Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@ethereal.com>
@@ -42,6 +42,9 @@ typedef struct _h225_packet_info {
gint reason; /* reason tag, if available */
guint requestSeqNum; /* request sequence number of ras-message, if available */
guint8 guid[16]; /* globally unique call id */
+ gboolean is_duplicate; /* true, if this is a repeated message */
+ gboolean request_available; /* true, if response matches to a request */
+ nstime_t delta_time; /* this is the RAS response time delay */
} h225_packet_info;
#endif /* __H225_H__ */
diff --git a/tap-h225rassrt.c b/tap-h225rassrt.c
new file mode 100755
index 0000000000..a33fd8ba60
--- /dev/null
+++ b/tap-h225rassrt.c
@@ -0,0 +1,251 @@
+/* tap_h225rassrt.c
+ * h225 RAS Service Response Time statistics for ethereal
+ * Copyright 2003 Lars Roland
+ *
+ * $Id: tap-h225rassrt.c,v 1.1 2003/11/16 23:11:18 sahlberg 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 <string.h>
+#include "epan/packet_info.h"
+#include "tap.h"
+#include "epan/value_string.h"
+#include "register.h"
+#include "packet-h225.h"
+#include "timestats.h"
+
+/* following values represent the size of their valuestring arrays */
+#define NUM_RAS_STATS 7
+
+static const value_string ras_message_category[] = {
+ { 0, "Gatekeeper "},
+ { 1, "Registration "},
+ { 2, "UnRegistration"},
+ { 3, "Admission "},
+ { 4, "Bandwidth "},
+ { 5, "Disengage "},
+ { 6, "Location "},
+ { 0, NULL }
+};
+
+typedef enum _ras_type {
+ RAS_REQUEST,
+ RAS_CONFIRM,
+ RAS_REJECT,
+ RAS_OTHER
+}ras_type;
+
+typedef enum _ras_category {
+ RAS_GATEKEEPER,
+ RAS_REGISTRATION,
+ RAS_UNREGISTRATION,
+ RAS_ADMISSION,
+ RAS_BANDWIDTH,
+ RAS_DISENGAGE,
+ RAS_LOCATION,
+ RAS_OTHERS
+}ras_category;
+
+/* Summary of response-time calculations*/
+typedef struct _h225_rtd_t {
+ guint32 open_req_num;
+ guint32 disc_rsp_num;
+ guint32 req_dup_num;
+ guint32 rsp_dup_num;
+ timestat_t stats;
+} h225_rtd_t;
+
+/* used to keep track of the statistics for an entire program interface */
+typedef struct _h225rassrt_t {
+ char *filter;
+ h225_rtd_t ras_rtd[NUM_RAS_STATS];
+} h225rassrt_t;
+
+
+static void
+h225rassrt_reset(void *phs)
+{
+ h225rassrt_t *hs=(h225rassrt_t *)phs;
+ int i;
+
+ for(i=0;i<NUM_RAS_STATS;i++) {
+ hs->ras_rtd[i].stats.num = 0;
+ hs->ras_rtd[i].stats.min_num = 0;
+ hs->ras_rtd[i].stats.max_num = 0;
+ hs->ras_rtd[i].stats.min.secs = 0;
+ hs->ras_rtd[i].stats.min.nsecs = 0;
+ hs->ras_rtd[i].stats.max.secs = 0;
+ hs->ras_rtd[i].stats.max.nsecs = 0;
+ hs->ras_rtd[i].stats.tot.secs = 0;
+ hs->ras_rtd[i].stats.tot.nsecs = 0;
+ hs->ras_rtd[i].open_req_num = 0;
+ hs->ras_rtd[i].disc_rsp_num = 0;
+ hs->ras_rtd[i].req_dup_num = 0;
+ hs->ras_rtd[i].rsp_dup_num = 0;
+ }
+
+}
+
+static int
+h225rassrt_packet(void *phs, packet_info *pinfo _U_, epan_dissect_t *edt _U_, void *phi)
+{
+ h225rassrt_t *hs=(h225rassrt_t *)phs;
+ h225_packet_info *pi=phi;
+
+ ras_type rasmsg_type = RAS_OTHER;
+ ras_category rascategory = RAS_OTHERS;
+
+ if (pi->msg_type != H225_RAS || pi->msg_tag == -1) {
+ /* No RAS Message or uninitialized msg_tag -> return */
+ return 0;
+ }
+
+ if (pi->msg_tag < 21) {
+ /* */
+ rascategory = pi->msg_tag / 3;
+ rasmsg_type = pi->msg_tag % 3;
+ }
+ else {
+ /* No SRT yet (ToDo) */
+ return 0;
+ }
+
+ switch(rasmsg_type) {
+
+ case RAS_REQUEST:
+ if(pi->is_duplicate){
+ hs->ras_rtd[rascategory].req_dup_num++;
+ }
+ else {
+ hs->ras_rtd[rascategory].open_req_num++;
+ }
+ break;
+
+ case RAS_CONFIRM:
+ /* no break - delay calculation is identical for Confirm and Reject */
+ case RAS_REJECT:
+ if(pi->is_duplicate){
+ /* Duplicate is ignored */
+ hs->ras_rtd[rascategory].rsp_dup_num++;
+ }
+ else if (!pi->request_available) {
+ /* no request was seen, ignore response */
+ hs->ras_rtd[rascategory].disc_rsp_num++;
+ }
+ else {
+ hs->ras_rtd[rascategory].open_req_num--;
+ time_stat_update(&(hs->ras_rtd[rascategory].stats),&(pi->delta_time), pinfo);
+ }
+ break;
+
+ default:
+ return 0;
+ break;
+ }
+ return 1;
+}
+
+static void
+h225rassrt_draw(void *phs)
+{
+ h225rassrt_t *hs=(h225rassrt_t *)phs;
+ int i;
+ timestat_t *rtd_temp;
+
+ printf("======================================== H225 RAS Service Response Time ========================================\n");
+ printf("H225 RAS Service Response Time (SRT) Statistics:\n");
+ printf("RAS-Messages | Measurements | Min SRT | Max SRT | Avg SRT | Min in Frame | Max in Frame |\n");
+ for(i=0;i<NUM_RAS_STATS;i++) {
+ rtd_temp = &(hs->ras_rtd[i].stats);
+ if(rtd_temp->num){
+ printf("%s | %10u | %9.2f msec | %9.2f msec | %9.2f msec | %10u | %10u |\n",
+ val_to_str(i,ras_message_category,"Unknown "),rtd_temp->num,
+ nstime_to_msec(&(rtd_temp->min)), nstime_to_msec(&(rtd_temp->max)),
+ get_average(&(rtd_temp->tot), rtd_temp->num),
+ rtd_temp->min_num, rtd_temp->max_num
+ );
+ }
+ }
+ printf("================================================================================================================\n");
+ printf("RAS-Messages | Open REQ | Discarded RSP | Repeated REQ | Repeated RSP |\n");
+ for(i=0;i<NUM_RAS_STATS;i++) {
+ rtd_temp = &(hs->ras_rtd[i].stats);
+ if(rtd_temp->num){
+ printf("%s | %10u | %10u | %10u | %10u |\n",
+ val_to_str(i,ras_message_category,"Unknown "),
+ hs->ras_rtd[i].open_req_num, hs->ras_rtd[i].disc_rsp_num,
+ hs->ras_rtd[i].req_dup_num, hs->ras_rtd[i].rsp_dup_num
+ );
+ }
+ }
+ printf("================================================================================================================\n");
+
+}
+
+
+static void
+h225rassrt_init(char *optarg)
+{
+ h225rassrt_t *hs;
+ char *filter=NULL;
+ GString *error_string;
+
+ if(!strncmp(optarg,"h225,srt,",9)){
+ filter=optarg+9;
+ } else {
+ filter=g_malloc(1);
+ *filter='\0';
+ }
+
+ hs = g_malloc(sizeof(h225rassrt_t));
+ hs->filter=g_malloc(strlen(filter)+1);
+ strcpy(hs->filter, filter);
+
+ h225rassrt_reset(hs);
+
+ error_string=register_tap_listener("h225", hs, filter, NULL, h225rassrt_packet, h225rassrt_draw);
+ if(error_string){
+ /* error, we failed to attach to the tap. clean up */
+ g_free(hs->filter);
+ g_free(hs);
+
+ fprintf(stderr, "tethereal: Couldn't register h225,srt tap: %s\n",
+ error_string->str);
+ g_string_free(error_string, TRUE);
+ exit(1);
+ }
+}
+
+
+void
+register_tap_listener_h225rassrt(void)
+{
+ register_ethereal_tap("h225,srt", h225rassrt_init);
+}