aboutsummaryrefslogtreecommitdiffstats
path: root/tap-protohierstat.c
diff options
context:
space:
mode:
authorRonnie Sahlberg <ronnie_sahlberg@ozemail.com.au>2002-11-01 05:29:36 +0000
committerRonnie Sahlberg <ronnie_sahlberg@ozemail.com.au>2002-11-01 05:29:36 +0000
commitcdb4e6929c75ed4e2595b41c8e7caaf683201c69 (patch)
treeb4677051752a7ab1defc3aa5bf321eb33413dce4 /tap-protohierstat.c
parentdcc95e010ffc94cd94bb8ab808151d1869bfc341 (diff)
New tap extension for tethereal : ProtocolHierarchyStatistics.
Similar to what is available on ethereal:/Tools/ProtocolHierarchyStatistics but this one can handle ALL protocols that tethereal has dissectors for. Maybe a gtk/gtk2 version of this should replace the existing one in ethereal? Try -z io,phs or -z io,phs,<filter> to test it. svn path=/trunk/; revision=6532
Diffstat (limited to 'tap-protohierstat.c')
-rw-r--r--tap-protohierstat.c217
1 files changed, 217 insertions, 0 deletions
diff --git a/tap-protohierstat.c b/tap-protohierstat.c
new file mode 100644
index 0000000000..a919d5110f
--- /dev/null
+++ b/tap-protohierstat.c
@@ -0,0 +1,217 @@
+/* tap-protohierstat.c
+ * protohierstat 2002 Ronnie Sahlberg
+ *
+ * $Id: tap-protohierstat.c,v 1.1 2002/11/01 05:29:34 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.
+ */
+
+/* This module provides ProtocolHierarchyStatistics for tethereal */
+
+#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 "epan/epan_dissect.h"
+#include "epan/proto.h"
+#include "tap.h"
+#include "register.h"
+
+typedef struct _phs_t {
+ struct _phs_t *sibling;
+ struct _phs_t *child;
+ struct _phs_t *parent;
+ char *filter;
+ int protocol;
+ char *proto_name;
+ guint32 frames;
+ guint32 bytes;
+} phs_t;
+
+
+static phs_t *
+new_phs_t(phs_t *parent)
+{
+ phs_t *rs;
+ rs=g_malloc(sizeof(phs_t));
+ rs->sibling=NULL;
+ rs->child=NULL;
+ rs->parent=parent;
+ rs->filter=NULL;
+ rs->protocol=-1;
+ rs->proto_name=NULL;
+ rs->frames=0;
+ rs->bytes=0;
+ return rs;
+}
+
+
+static int
+protohierstat_packet(void *prs, packet_info *pinfo, epan_dissect_t *edt, void *dummy _U_)
+{
+ phs_t *rs=prs;
+ phs_t *tmprs;
+ proto_tree *tree;
+ field_info *fi;
+
+ if(!edt){
+ return 0;
+ }
+ if(!edt->tree){
+ return 0;
+ }
+ if(!edt->tree->children){
+ return 0;
+ }
+
+ for(tree=edt->tree->children;tree;tree=tree->next){
+ fi=PITEM_FINFO(tree);
+
+ /* first time we saw a protocol at this leaf */
+ if(rs->protocol==-1){
+ rs->protocol=fi->hfinfo->id;
+ rs->proto_name=fi->hfinfo->abbrev;
+ rs->frames=1;
+ rs->bytes=pinfo->fd->pkt_len;
+ rs->child=new_phs_t(rs);
+ rs=rs->child;
+ continue;
+ }
+
+ /* find this protocol in the list of siblings */
+ for(tmprs=rs;tmprs;tmprs=tmprs->sibling){
+ if(tmprs->protocol==fi->hfinfo->id){
+ break;
+ }
+ }
+
+ /* not found, then we must add it to the end of the list */
+ if(!tmprs){
+ for(tmprs=rs;tmprs->sibling;tmprs=tmprs->sibling)
+ ;
+ tmprs->sibling=new_phs_t(rs->parent);
+ rs=tmprs->sibling;
+ rs->protocol=fi->hfinfo->id;
+ rs->proto_name=fi->hfinfo->abbrev;
+ } else {
+ rs=tmprs;
+ }
+
+ rs->frames++;
+ rs->bytes+=pinfo->fd->pkt_len;
+
+ if(!rs->child){
+ rs->child=new_phs_t(rs);
+ }
+ rs=rs->child;
+ }
+ return 1;
+}
+
+static void
+phs_draw(phs_t *rs, int indentation)
+{
+ int i;
+ char str[80];
+ for(;rs;rs=rs->sibling){
+ if(rs->protocol==-1){
+ return;
+ }
+ str[0]=0;
+ for(i=0;i<indentation;i++){
+ strcat(str," ");
+ }
+ strcat(str, rs->proto_name);
+ printf("%-40s frames:%d bytes:%d\n",str, rs->frames, rs->bytes);
+ phs_draw(rs->child, indentation+1);
+ }
+}
+
+static void
+protohierstat_draw(void *prs)
+{
+ phs_t *rs=prs;
+
+ printf("\n");
+ printf("===================================================================\n");
+ printf("Protocol Hierarchy Statistics\n");
+ printf("Filter: %s\n\n",rs->filter?rs->filter:"");
+ phs_draw(rs,0);
+ printf("===================================================================\n");
+}
+
+
+static void
+protohierstat_init(char *optarg)
+{
+ phs_t *rs;
+ int pos=0;
+ char *filter=NULL;
+
+ if(!strcmp("io,phs",optarg)){
+ filter="frame";
+ } else if(sscanf(optarg,"io,phs,%n",&pos)==0){
+ if(pos){
+ filter=optarg+pos;
+ } else {
+ /* We must use a filter to guarantee that edt->tree
+ will be populated. "frame" matches everything so
+ that one is used instead of no filter.
+ */
+ filter="frame";
+ }
+ } else {
+ fprintf(stderr, "tethereal: invalid \"-z io,phs[,<filter>]\" argument\n");
+ exit(1);
+ }
+
+ rs=new_phs_t(NULL);
+
+ if(filter){
+ rs->filter=g_malloc(strlen(filter)+1);
+ strcpy(rs->filter, filter);
+ } else {
+ rs->filter=NULL;
+ }
+
+ if(register_tap_listener("frame", rs, filter, NULL, protohierstat_packet, protohierstat_draw)){
+ /* error, we failed to attach to the tap. clean up */
+ g_free(rs->filter);
+ g_free(rs);
+
+ fprintf(stderr,"tethereal: protohierstat_init() failed to attach to tap.\n");
+ exit(1);
+ }
+}
+
+
+void
+register_tap_listener_protohierstat(void)
+{
+ register_ethereal_tap("io,phs", protohierstat_init, NULL, NULL);
+}
+