aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLuis Ontanon <luis.ontanon@gmail.com>2005-03-21 21:48:10 +0000
committerLuis Ontanon <luis.ontanon@gmail.com>2005-03-21 21:48:10 +0000
commit7c87fca629fcaf48feb094217930bcbb4a218d99 (patch)
treeb38fc2a95dc41dddf9f7eac9b489d14e3feb4ba3
parent0108e3ada921f621c8249e3ad9e488009486770f (diff)
Something is better than nothing, Sooner is better than later.
svn path=/trunk/; revision=13856
-rw-r--r--doc/README.stats_tree199
1 files changed, 199 insertions, 0 deletions
diff --git a/doc/README.stats_tree b/doc/README.stats_tree
new file mode 100644
index 0000000000..612ae47d32
--- /dev/null
+++ b/doc/README.stats_tree
@@ -0,0 +1,199 @@
+$Id$
+tapping with stats_tree
+
+Let's suppose that you want to write a tap only to keep counters, and you
+don't want to get involved with GUI programming or maybe you'd like to make
+it a plugin. A stats_tree might be the way to go. The stats_tree module takes
+care of the representation (GUI for ethereal and text for tethereal) of the
+tap data. So there's very little code to write to make a tap listener usable
+from both ethereal and tethereal.
+
+First, you should add the TAP to the dissector in question as described in
+README.tapping .
+
+Once the dissector in question is "tapped" you have to write the stats tree
+code which is made of three parts:
+
+The init callback routine:
+ which will be executed before any packet is passed to the tap. Here you
+ should create the "static" nodes of your tree. As well as initialize your
+ data.
+
+The (per)packet callback routine:
+ As the tap_packet callback is going to be called for every packet, it
+ should be used to increment the counters.
+
+The cleanup callback:
+ It is called at the destruction of the stats_tree and might be used to
+ free ....
+
+Other than that the stats_tree should be registered.
+
+If you want to make it a plugin, stats_tree_register() should be called by
+plugin_register_tap_listener() read README.plugin for other information
+regarding ethereal plugins.
+
+If you want it as part of the dissector stats_tree_register() can be called
+either by proto_register_xxx() or if you prefer by proto_reg_handoff_xxx().
+
+
+A small example of a very basic stats_tree plugin follows.
+
+----- example stats_tree plugin ------
+/* udpterm_stats_tree.c
+ * A small example of stats_tree plugin that counts udp packets by termination
+ * 2005, Luis E. G. Ontanon
+ *
+ * $ ~Id: $
+ *
+ * Ethereal - Network traffic analyzer
+ * By Gerald Combs <gerald@ethereal.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
+
+#ifndef ENABLE_STATIC
+#include <gmodule.h>
+#else
+#include <glib.h>
+#endif
+
+#include <epan/stats_tree.h>
+#include <epan/dissectors/udp.h>
+
+static int st_udp_term;
+static gchar* st_str_udp_term = "UDP terminations";
+
+/* this one initializes the tree, creating the root nodes */
+extern void udp_term_stats_tree_init(stats_tree* st) {
+ /* we create a node under which we'll add every termination */
+ st_udp_term = stats_tree_create_node(st, st_str_udp_term, 0, TRUE);
+}
+
+/* this one will be called with every udp packet */
+extern int udp_term_stats_tree_packet(stats_tree *st, /* st as it was passed to us */
+ packet_info *pinfo, /* we'll fetch the addreses from here */
+ epan_dissect_t *edt _U_, /* unused */
+ const void *p) /* we'll use this to fetch the ports */
+{
+ static guint8 str[128];
+ e_udphdr* udphdr = (e_udphdr*) p;
+
+ /* we increment by one (tick) the root node */
+ stats_tree_tick_node(st, st_udp_term, 0, FALSE);
+
+ /* we then tick a node for this src_addr:src_port
+ if the node doesn't exists it will be created */
+ g_snprintf(str, sizeof(str),"%s:%u",address_to_str(&pinfo->net_src),udphdr->sport);
+ tick_stat_node(st, str, st_udp_term, FALSE);
+
+ /* same thing for dst */
+ g_snprintf(str, sizeof(str),"%s:%u",address_to_str(&pinfo->net_dst),udphdr->dport);
+ tick_stat_node(st, str, st_udp_term, FALSE);
+
+ return 1;
+}
+
+#ifndef ENABLE_STATIC
+G_MODULE_EXPORT const gchar version[] = "0.0";
+
+G_MODULE_EXPORT void plugin_register_tap_listener(void) {
+
+ stats_tree_register("udp", /* the proto we are going to "tap" */
+ "udp_terms", /* the abbreviation for this tree (to be used as -z udp_terms,tree) */
+ st_str_udp_term, /* the name of the menu and window (use "/" for sub menus)*/
+ udp_term_stats_tree_init, /* the init callback */
+ ip_hosts_stats_tree_init, /* the per packet callback */
+ NULL ); /* the cleanup callback (in this case there isn't) */
+
+}
+#endif
+
+----- END ------
+
+the stats_tree API
+==================
+ every stats_tree callback has a stats_tree* parameter (st), stats_tree is an obscure
+ data structure which should be passed to the api functions.
+
+stats_tree_register( tapname, abbr, name, packet_cb, init_cb, cleanup_cb);
+ registers a new stats tree
+
+stats_tree_parent_id_by_name( st, parent_name)
+ returns the id of a candidate parent node given its name
+
+
+Node functions
+==============
+
+All the functions that opearate on nodes return a parent_id
+
+stats_tree_create_node(st, name, parent_id, with_children)
+ Creates a node in the tree (to be used in the in init_cb)
+ name: the name of the new node
+ parent_id: the id of the parent_node (NULL for root)
+ with_children: TRUE if this node will have "dynamically created" children
+ (i.e. it will be a candidate parrent)
+
+
+stats_tree_create_node_by_pname(st, name, parent_name, with_children);
+ As before but creates a node using it's parent's name
+
+
+stats_tree_create_range_node(st, name, parent_id, ...)
+stats_tree_range_node_with_pname(st, name, parent_name, ...)
+ Creates a node in the tree, that will contain a ranges list.
+ example:
+ stats_tree_create_range_node(st,name,parent_id,
+ "-99","100-199","200-299","300-399","400-", NULL);
+
+stats_tree_tick_range( st, name, parent_id, value_in_range);
+stats_tree_tick_range_by_pname(st,name,parent_name,value_in_range)
+ Increases by one the ranged node and the sub node to whose range the value belongs
+
+
+stats_tree_create_pivot(st, name, parent_id);
+stats_tree_create_pivot_by_pname(st, name, parent_name);
+ Creates a "pivot node"
+
+stats_tree_tick_pivot(st, pivot_id, pivoted_string);
+ Each time a pivot node will be ticked it will get increased, and, it will
+ increase (or create) the children named as pivoted_string
+
+
+the following will either increase or create a node (with value 1) when called
+
+tick_stat_node(st,name,parent_id,with_children)
+increases by one a stat_node
+
+increase_stat_node(st,name,parent_id,with_children,value)
+increases by value a stat_node
+
+set_stat_node(st,name,parent_id,with_children,value)
+sets the value of a stat_node
+
+zero_stat_node(st,name,parent_id,with_children)
+resets to zero a stat_node
+
+
+You can find more examples of these in $srcdir/plugins/stats_tree/pinfo_stats_tree.c
+
+Luis E. G. Ontanon.