aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Makefile.am4
-rw-r--r--Makefile.nmake3
-rw-r--r--doc/ethereal.pod.template12
-rw-r--r--gtk/Makefile.am4
-rw-r--r--gtk/Makefile.nmake1
-rw-r--r--gtk/menu.c5
-rw-r--r--gtk/proto_hier_stats_dlg.c213
-rw-r--r--gtk/proto_hier_stats_dlg.h27
-rw-r--r--proto_hier_stats.c203
-rw-r--r--proto_hier_stats.h27
10 files changed, 495 insertions, 4 deletions
diff --git a/Makefile.am b/Makefile.am
index 92151a4bfe..cfbe9ebbdc 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -1,7 +1,7 @@
# Makefile.am
# Automake file for Ethereal
#
-# $Id: Makefile.am,v 1.293 2001/03/18 03:34:22 guy Exp $
+# $Id: Makefile.am,v 1.294 2001/03/22 23:54:44 gram Exp $
#
# Ethereal - Network traffic analyzer
# By Gerald Combs <gerald@zing.org>
@@ -371,6 +371,8 @@ ethereal_SOURCES = \
filters.h \
globals.h \
menu.h \
+ proto_hier_stats.h \
+ proto_hier_stats.c \
simple_dialog.h \
summary.c \
summary.h \
diff --git a/Makefile.nmake b/Makefile.nmake
index 9f2307fcd8..d80e50ccc8 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.87 2001/03/18 02:13:32 guy Exp $
+# $Id: Makefile.nmake,v 1.88 2001/03/22 23:54:44 gram Exp $
include config.nmake
@@ -207,6 +207,7 @@ ethereal_OBJECTS = \
capture.obj \
file.obj \
filters.obj \
+ proto_hier_stats.obj \
summary.obj \
tethereal_OBJECTS = \
diff --git a/doc/ethereal.pod.template b/doc/ethereal.pod.template
index 803ce43496..e8b0ef08c5 100644
--- a/doc/ethereal.pod.template
+++ b/doc/ethereal.pod.template
@@ -401,6 +401,18 @@ packet is a TCP packet to port 12345, using this dialog you can
instruct Ethereal to decode all packets to or from that TCP port as
HTTP packets.
+=item Tools:Protocol Hierarchy Statistics
+
+This shows the number of packets, and the number of bytes
+in those packets, for each protocol in the trace. It
+organizes the protocols in the same hierarchy in which
+they were found in the trace. Besides counting the packets
+in which the protocol exists, a count is also made
+for packets in which the protocol is the last protocol in
+the stack. These "Last Protocol" counts show you how many packets
+(and the byte count associated with those packets) B<ended> in a particular
+protocol.
+
=head2 WINDOWS
=over 4
diff --git a/gtk/Makefile.am b/gtk/Makefile.am
index acf76f2947..68c3c5d768 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.33 2001/02/01 07:34:33 guy Exp $
+# $Id: Makefile.am,v 1.34 2001/03/22 23:54:47 gram Exp $
#
# Ethereal - Network traffic analyzer
# By Gerald Combs <gerald@zing.org>
@@ -82,6 +82,8 @@ libui_a_SOURCES = \
proto_dlg.h \
proto_draw.c \
proto_draw.h \
+ proto_hier_stats_dlg.h \
+ proto_hier_stats_dlg.c \
simple_dialog.c \
stream_prefs.c \
stream_prefs.h \
diff --git a/gtk/Makefile.nmake b/gtk/Makefile.nmake
index c69428bc5a..dfbbb83527 100644
--- a/gtk/Makefile.nmake
+++ b/gtk/Makefile.nmake
@@ -40,6 +40,7 @@ OBJECTS=capture_dlg.obj \
progress_dlg.obj \
proto_dlg.obj \
proto_draw.obj \
+ proto_hier_stats_dlg.obj \
simple_dialog.obj \
stream_prefs.obj \
summary_dlg.obj \
diff --git a/gtk/menu.c b/gtk/menu.c
index 443cd06cee..2083b29845 100644
--- a/gtk/menu.c
+++ b/gtk/menu.c
@@ -1,7 +1,7 @@
/* menu.c
* Menu routines
*
- * $Id: menu.c,v 1.49 2001/02/11 23:02:05 guy Exp $
+ * $Id: menu.c,v 1.50 2001/03/22 23:54:47 gram Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@zing.org>
@@ -58,6 +58,7 @@
#include "decode_as_dlg.h"
#include "help_dlg.h"
#include "proto_dlg.h"
+#include "proto_hier_stats_dlg.h"
#include "keys.h"
#include "plugins.h"
@@ -150,6 +151,7 @@ static GtkItemFactoryEntry menu_items[] =
{"/Tools/_Decode As...", NULL, GTK_MENU_FUNC(decode_as_cb), 0, NULL},
/* {"/Tools/Graph", NULL, NULL, 0, NULL}, future use */
{"/Tools/_Summary", NULL, GTK_MENU_FUNC(summary_open_cb), 0, NULL},
+ {"/Tools/Protocol Hierarchy Statistics", NULL, GTK_MENU_FUNC(proto_hier_stats_cb), 0, NULL},
{"/_Help", NULL, NULL, 0, "<LastBranch>" },
{"/Help/_Help", NULL, GTK_MENU_FUNC(help_cb), 0, NULL},
{"/Help/<separator>", NULL, NULL, 0, "<Separator>"},
@@ -379,6 +381,7 @@ set_menus_for_captured_packets(gboolean have_captured_packets)
set_menu_sensitivity("/Display/Match Selected", have_captured_packets);
set_menu_sensitivity("/Display/Colorize Display...", have_captured_packets);
set_menu_sensitivity("/Tools/Summary", have_captured_packets);
+ set_menu_sensitivity("/Tools/Protocol Hierarchy Statistics", have_captured_packets);
}
/* Enable or disable menu items based on whether a packet is selected. */
diff --git a/gtk/proto_hier_stats_dlg.c b/gtk/proto_hier_stats_dlg.c
new file mode 100644
index 0000000000..aceec24b78
--- /dev/null
+++ b/gtk/proto_hier_stats_dlg.c
@@ -0,0 +1,213 @@
+/* proto_hier_stats_dlg.c
+ *
+ * $Id: proto_hier_stats_dlg.c,v 1.1 2001/03/22 23:54:47 gram Exp $
+ *
+ * Ethereal - Network traffic analyzer
+ * By Gerald Combs <gerald@zing.org>
+ * 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 <gtk/gtk.h>
+
+#include "proto_hier_stats.h"
+#include "dlg_utils.h"
+#include "main.h"
+
+#define NUM_STAT_COLUMNS 6
+
+typedef struct {
+
+ GtkCTree *tree;
+ GtkCTreeNode *parent;
+ ph_stats_t *ps;
+
+} draw_info_t;
+
+
+#define PCT(x,y) (100.0 * (float)(x) / (float)(y))
+
+static void
+fill_in_ctree_node(GNode *node, gpointer data)
+{
+ ph_stats_node_t *stats = node->data;
+ draw_info_t *di = data;
+
+ GtkCTree *tree = di->tree;
+ GtkCTreeNode *parent = di->parent;
+ ph_stats_t *ps = di->ps;
+
+ gchar *text[NUM_STAT_COLUMNS];
+ gboolean is_leaf;
+ GtkCTreeNode *new_node;
+
+ draw_info_t child_di;
+
+ if (g_node_n_children(node) > 0) {
+ is_leaf = FALSE;
+ }
+ else {
+ is_leaf = TRUE;
+ }
+
+ text[0] = stats->hfinfo->name;
+ text[1] = g_strdup_printf("%6.2f%%",
+ PCT(stats->num_pkts_total, ps->tot_packets));
+ text[2] = g_strdup_printf("%u", stats->num_pkts_total);
+ text[3] = g_strdup_printf("%u", stats->num_bytes_total);
+ text[4] = g_strdup_printf("%u", stats->num_pkts_last);
+ text[5] = g_strdup_printf("%u", stats->num_bytes_last);
+
+ new_node = gtk_ctree_insert_node(tree, parent, NULL, text,
+ 5, NULL, NULL, NULL, NULL,
+ is_leaf, TRUE);
+
+
+ g_free(text[1]);
+ g_free(text[2]);
+ g_free(text[3]);
+ g_free(text[4]);
+ g_free(text[5]);
+
+ child_di.tree = tree;
+ child_di.parent = new_node;
+ child_di.ps = ps;
+
+ g_node_children_foreach(node, G_TRAVERSE_ALL,
+ fill_in_ctree_node, &child_di);
+
+}
+
+
+
+static void
+fill_in_ctree(GtkWidget *tree, ph_stats_t *ps)
+{
+ draw_info_t di;
+
+ di.tree = GTK_CTREE(tree);
+ di.parent = NULL;
+ di.ps = ps;
+
+ g_node_children_foreach(ps->stats_tree, G_TRAVERSE_ALL,
+ fill_in_ctree_node, &di);
+}
+
+static void
+create_tree(GtkWidget *container)
+{
+ GtkWidget *sw, *tree;
+ ph_stats_t *ps;
+ int i, height;
+ gchar *column_titles[NUM_STAT_COLUMNS] = {
+ "Protocol",
+ "Percentage Packets",
+ "Packets",
+ "Bytes",
+ "Last-Protocol Packets",
+ "Last-Protocol Bytes",
+ };
+
+ ps = ph_stats_new();
+
+ /* Scrolled Window */
+ sw = gtk_scrolled_window_new(NULL, NULL);
+ gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(sw),
+ GTK_POLICY_AUTOMATIC,
+ GTK_POLICY_AUTOMATIC);
+ gtk_container_add(GTK_CONTAINER(container), sw);
+
+ tree = gtk_ctree_new_with_titles(NUM_STAT_COLUMNS, 0, column_titles);
+
+ /* XXX - get 'pos' to set vertical scroll-bar placement. */
+ /* XXX - set line style from preferences ???. */
+
+ /* The titel bars do nothing. */
+ gtk_clist_column_titles_passive(GTK_CLIST(tree));
+
+ /* Auto Resize all columns */
+ for (i = 0; i < NUM_STAT_COLUMNS; i++) {
+ gtk_clist_set_column_auto_resize(GTK_CLIST(tree), i, TRUE);
+ }
+
+
+ /* Right justify numeric columns */
+ for (i = 1; i <= 5; i++) {
+ gtk_clist_set_column_justification(GTK_CLIST(tree), i,
+ GTK_JUSTIFY_RIGHT);
+ }
+
+ /* Fill in the data. */
+ fill_in_ctree(tree, ps);
+
+ /* Try to size the CTree to a good initial size.
+ * 5 is a magic number that I pulled out off my hat.
+ * Using DEF_WIDTH is pretty bogus, too. */
+ height = GTK_CLIST(tree)->rows * (GTK_CLIST(tree)->row_height + 5);
+ gtk_widget_set_usize(tree, DEF_WIDTH, height);
+
+
+ gtk_container_add(GTK_CONTAINER(sw), tree);
+ ph_stats_free(ps);
+}
+
+void
+proto_hier_stats_cb(GtkWidget *w, gpointer d)
+{
+ GtkWidget *dlg, *bt, *vbox, *frame, *bbox;
+ const gchar *wname = "Protocol Hierarchy Statistics";
+
+ dlg = dlg_window_new(wname);
+
+ vbox = gtk_vbox_new(FALSE, 5);
+ gtk_container_border_width(GTK_CONTAINER(vbox), 5);
+ gtk_container_add(GTK_CONTAINER(dlg), vbox);
+
+ frame = gtk_frame_new(wname);
+ /*gtk_container_add(GTK_CONTAINER(vbox), frame);*/
+ gtk_box_pack_start(GTK_BOX(vbox), frame, TRUE, TRUE, 0);
+
+
+ /* Data section */
+ create_tree(frame);
+
+ /* Button row. We put it in an HButtonBox to
+ * keep it from expanding to the width of the window. */
+ bbox = gtk_hbutton_box_new();
+ gtk_button_box_set_spacing(GTK_BUTTON_BOX(bbox), 5);
+ /*gtk_container_add(GTK_CONTAINER(vbox), bbox);*/
+ gtk_box_pack_start(GTK_BOX(vbox), bbox, FALSE, FALSE, 0);
+
+ /* Close button */
+ bt = gtk_button_new_with_label("Close");
+ gtk_signal_connect_object(GTK_OBJECT(bt), "clicked",
+ GTK_SIGNAL_FUNC(gtk_widget_destroy),
+ GTK_OBJECT(dlg));
+ gtk_container_add(GTK_CONTAINER(bbox), bt);
+ GTK_WIDGET_SET_FLAGS(bt, GTK_CAN_DEFAULT);
+ gtk_widget_grab_default(bt);
+ dlg_set_cancel(dlg, bt);
+
+ gtk_widget_show_all(dlg);
+
+}
+
diff --git a/gtk/proto_hier_stats_dlg.h b/gtk/proto_hier_stats_dlg.h
new file mode 100644
index 0000000000..dc124ffec1
--- /dev/null
+++ b/gtk/proto_hier_stats_dlg.h
@@ -0,0 +1,27 @@
+/* proto_hier_stats_dlg.h
+ *
+ * $Id: proto_hier_stats_dlg.h,v 1.1 2001/03/22 23:54:47 gram Exp $
+ *
+ * Ethereal - Network traffic analyzer
+ * By Gerald Combs <gerald@zing.org>
+ * 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.
+ */
+
+
+void
+proto_hier_stats_cb(GtkWidget *w, gpointer d);
diff --git a/proto_hier_stats.c b/proto_hier_stats.c
new file mode 100644
index 0000000000..303d14ee6f
--- /dev/null
+++ b/proto_hier_stats.c
@@ -0,0 +1,203 @@
+/* proto_hier_stats.c
+ * Routines for calculating statistics based on protocol.
+ *
+ * $Id: proto_hier_stats.c,v 1.1 2001/03/22 23:54:44 gram Exp $
+ *
+ * Ethereal - Network traffic analyzer
+ * By Gerald Combs <gerald@zing.org>
+ * 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 "globals.h"
+#include "proto_hier_stats.h"
+#include <wtap.h>
+
+#include <stdio.h>
+#include <glib.h>
+
+static GNode*
+find_stat_node(GNode *parent_node, header_field_info *needle_hfinfo)
+{
+ GNode *needle_node;
+ field_info *finfo;
+ ph_stats_node_t *stats;
+
+ needle_node = g_node_first_child(parent_node);
+
+ while (needle_node) {
+ finfo = needle_node->data;
+ if (finfo && finfo->hfinfo && finfo->hfinfo->id == needle_hfinfo->id) {
+ return needle_node;
+ }
+ needle_node = g_node_next_sibling(needle_node);
+ }
+
+ /* None found. Create one. */
+ stats = g_new(ph_stats_node_t, 1);
+
+ /* Intialize counters */
+ stats->hfinfo = needle_hfinfo;
+ stats->num_pkts_total = 0;
+ stats->num_pkts_last = 0;
+ stats->num_bytes_total = 0;
+ stats->num_bytes_last = 0;
+
+ needle_node = g_node_new(stats);
+ g_node_append(parent_node, needle_node);
+ return needle_node;
+}
+
+
+static void
+process_node(proto_item *proto_node, GNode *parent_stat_node, ph_stats_t *ps, guint pkt_len)
+{
+ field_info *finfo;
+ ph_stats_node_t *stats;
+ proto_item *proto_sibling_node;
+ GNode *stat_node;
+
+ finfo = proto_node->data;
+ g_assert(finfo);
+
+ stat_node = find_stat_node(parent_stat_node, finfo->hfinfo);
+
+ /* Assert that the finfo is related to a protocol, not a field. */
+ g_assert(finfo->hfinfo->parent == -1);
+
+ stats = stat_node->data;
+ stats->num_pkts_total++;
+ stats->num_bytes_total += pkt_len;
+
+ proto_sibling_node = g_node_next_sibling(proto_node);
+
+ if (proto_sibling_node) {
+ process_node(proto_sibling_node, stat_node, ps, pkt_len);
+ }
+ else {
+ stats->num_pkts_last++;
+ stats->num_bytes_last += pkt_len;
+ }
+}
+
+
+
+static void
+process_tree(proto_tree *protocol_tree, ph_stats_t* ps, guint pkt_len)
+{
+ proto_item *proto_node;
+
+ proto_node = g_node_first_child(protocol_tree);
+ if (!proto_node) {
+ return;
+ }
+
+ process_node(proto_node, ps->stats_tree, ps, pkt_len);
+}
+
+static void
+process_frame(frame_data *frame, ph_stats_t* ps)
+{
+ epan_dissect_t *edt;
+ union wtap_pseudo_header phdr;
+ proto_tree *protocol_tree;
+ guint8 pd[WTAP_MAX_PACKET_SIZE];
+
+ protocol_tree = proto_tree_create_root();
+
+ /* Load the frame from the capture file */
+ wtap_seek_read(cfile.wth, frame->file_off, &phdr,
+ pd, frame->cap_len);
+
+ /* Dissect the frame */
+ edt = epan_dissect_new(&phdr, pd, frame, protocol_tree);
+
+ /* Get stats from this protocol tree */
+ process_tree(protocol_tree, ps, frame->pkt_len);
+
+ /* Free our memory. */
+ epan_dissect_free(edt);
+ proto_tree_free(protocol_tree);
+}
+
+
+
+ph_stats_t*
+ph_stats_new(void)
+{
+ ph_stats_t *ps;
+ frame_data *frame;
+ guint tot_packets, tot_bytes;
+
+ /* Initialize the data */
+ ps = g_new(ph_stats_t, 1);
+ ps->tot_packets = 0;
+ ps->tot_bytes = 0;
+ ps->stats_tree = g_node_new(NULL);
+
+ frame = cfile.plist;
+ tot_packets = 0;
+ tot_bytes = 0;
+
+ while (frame) {
+ /* Skip frames that are hidden due to the display filter */
+ if (!frame->flags.passed_dfilter) {
+ continue;
+ }
+
+ process_frame(frame, ps);
+
+ tot_packets++;
+ tot_bytes += frame->pkt_len;
+
+ frame = frame->next;
+ }
+
+ ps->tot_packets = tot_packets;
+ ps->tot_bytes = tot_bytes;
+
+ return ps;
+}
+
+static gboolean
+stat_node_free(GNode *node, gpointer data)
+{
+ ph_stats_node_t *stats = node->data;
+
+ if (stats) {
+ g_free(stats);
+ }
+}
+
+void
+ph_stats_free(ph_stats_t *ps)
+{
+
+ if (ps->stats_tree) {
+ g_node_traverse(ps->stats_tree, G_IN_ORDER,
+ G_TRAVERSE_ALL, -1,
+ stat_node_free, NULL);
+ g_node_destroy(ps->stats_tree);
+ }
+
+ g_free(ps);
+}
diff --git a/proto_hier_stats.h b/proto_hier_stats.h
new file mode 100644
index 0000000000..257c9e19eb
--- /dev/null
+++ b/proto_hier_stats.h
@@ -0,0 +1,27 @@
+
+#ifndef PROTO_HIER_STATS_H
+#define PROTO_HIER_STATS_H
+
+#include "proto.h"
+
+typedef struct {
+ header_field_info *hfinfo;
+ guint num_pkts_total;
+ guint num_pkts_last;
+ guint num_bytes_total;
+ guint num_bytes_last;
+} ph_stats_node_t;
+
+
+typedef struct {
+ guint tot_packets;
+ guint tot_bytes;
+ GNode *stats_tree;
+} ph_stats_t;
+
+
+ph_stats_t* ph_stats_new(void);
+
+void ph_stats_free(ph_stats_t *ps);
+
+#endif