summaryrefslogtreecommitdiffstats
path: root/doc/README.stats_tree
diff options
context:
space:
mode:
Diffstat (limited to 'doc/README.stats_tree')
-rw-r--r--doc/README.stats_tree238
1 files changed, 238 insertions, 0 deletions
diff --git a/doc/README.stats_tree b/doc/README.stats_tree
new file mode 100644
index 0000000..1b7e69e
--- /dev/null
+++ b/doc/README.stats_tree
@@ -0,0 +1,238 @@
+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 Wireshark and text for TShark) of the
+tap data. So there's very little code to write to make a tap listener usable
+from both Wireshark and TShark.
+
+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.plugins for other information
+regarding Wireshark 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
+ *
+ * Wireshark - Network traffic analyzer
+ * By Gerald Combs <gerald@wireshark.org>
+ * Copyright 1998 Gerald Combs
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include "config.h"
+
+#include <gmodule.h>
+
+#include <epan/stats_tree.h>
+#include <epan/dissectors/udp.h>
+
+static int st_udp_term;
+static char* 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, STAT_DT_INT, true);
+}
+
+/* this one will be called with every udp packet */
+extern tap_packet_status
+udp_term_stats_tree_packet(stats_tree *st, /* st as it was passed to us */
+ packet_info *pinfo, /* we'll fetch the addresses from here */
+ epan_dissect_t *edt _U_, /* unused */
+ const void *p) /* we'll use this to fetch the ports */
+{
+ static uint8_t str[128];
+ e_udphdr* udphdr = (e_udphdr*) p;
+
+ /* we increment by one (tick) the root node */
+ tick_stat_node(st, st_str_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 */
+ 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 */
+ 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;
+}
+
+WS_DLL_PUBLIC_DEF const char version[] = "0.0";
+
+WS_DLL_PUBLIC_DEF void plugin_register_tap_listener(void) {
+
+ stats_tree_register_plugin("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)*/
+ 0, /* tap listener flags for per-packet callback */
+ udp_term_stats_tree_packet, /* the per packet callback */
+ udp_term_stats_tree_init, /* the init callback */
+ NULL ); /* the cleanup callback (in this case there isn't) */
+
+}
+
+----- 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, flags, packet_cb, init_cb, cleanup_cb);
+ registers a new stats tree with default group REGISTER_STAT_GROUP_UNSORTED
+
+stats_tree_register_plugin(tapname, abbr, name, flags, packet_cb, init_cb, cleanup_cb);
+ registers a new stats tree from a plugin with the default group
+
+stats_tree_register_with_group(tapname, abbr, name, flags, packet_cb, init_cb, cleanup_cb, stat_group);
+ registers a new stats tree under a particular stat group
+
+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 operate on nodes return a parent_id
+
+stats_tree_create_node(st, name, parent_id, datatype, 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)
+ datatype: datatype of the new node, STAT_DT_INT or STAT_DT_FLOAT. The only
+ methods implemented for floats are averages.
+ with_children: true if this node will have "dynamically created" children
+ (i.e. it will be a candidate parent)
+
+
+stats_tree_create_node_by_pname(st, name, parent_name, datatype, with_children);
+ As before but creates a node using its parent's name
+
+
+stats_tree_create_range_node(st, name, parent_id, ...)
+stats_tree_create_range_node_string(st, name, parent_id, num_str_ranges, str_ranges)
+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
+
+Averages work by tracking both the number of items added to node (the ticking
+action) and the value of each item added to the node. This is done
+automatically for ranged nodes; for other node types you need to call one of
+the functions below to associate item values with each tick.
+
+avg_stat_node_add_value_notick(st, name, parent_id, with_children, value)
+avg_stat_node_add_value_int(st, name, parent_id, with_children, value)
+avg_stat_node_add_value_float(st, name, parent_id, with_children, value)
+
+The difference between the above functions is whether the item count is
+increased or not. To properly compute the average you need to either call
+avg_stat_node_add_value or avg_stat_node_add_value_notick combined
+tick_stat_node. The later sequence allows for plug-ins which are compatible
+with older Wireshark versions which ignores avg_stat_node_add_value because
+it does not understand the command. This would result in 0 counts for all
+nodes. It is preferred to use avg_stat_node_add_value if you are not writing
+a plug-in.
+
+avg_stat_node_add_value_int is used the same way as tick_stat_node with the
+exception that you now specify an additional value associated with the tick.
+
+avg_stat_node_add_value_float is used to compute averages of floats, for nodes
+with the STAT_DT_FLOAT datatype.
+
+Do not mix increase_stat_node, set_stat_node or zero_stat_node
+with avg_stat_node_add_value_int as this will lead to incorrect results for the
+average value.
+
+stats_tree now also support setting flags per node to control the behaviour
+of these nodes. This can be done using the stat_node_set_flags and
+stat_node_clear_flags functions. Currently these flags are defined:
+
+ ST_FLG_DEF_NOEXPAND: By default the top-level nodes in a tree are
+ automatically expanded in the GUI. Setting this flag on
+ such a node prevents the node from automatically
+ expanding.
+ ST_FLG_SORT_TOP: Nodes with this flag is sorted separately from nodes
+ without this flag (in effect partitioning tree into a top
+ and bottom half. Each half is sorted normally. Top always
+ appear first :)
+
+The same node manipulations can also be performed via generic functions:
+
+stats_tree_manip_node_int(mode, st, name, parent_id, with_children, value);
+stats_tree_manip_node_float(mode, st, name, parent_id, with_children, value);
+
+mode is an enum with the following set of values:
+ MN_INCREASE
+ MN_SET
+ MN_AVERAGE
+ MN_AVERAGE_NOTICK
+ MN_SET_FLAGS
+ MN_CLEAR_FLAGS
+
+You can find more examples of these in $srcdir/plugins/epan/stats_tree/pinfo_stats_tree.c
+
+Luis E. G. Ontanon.