-$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
+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 ethereal and tethereal.
+from both wireshark and tshark.
First, you should add the TAP to the dissector in question as described in
README.tapping .
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 ....
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.
+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 stats_tree plugin that counts udp packets by termination
* 2005, Luis E. G. Ontanon
*
- * $ ~Id: $
- *
* Wireshark - Network traffic analyzer
* By Gerald Combs <gerald@wireshark.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.
+ * SPDX-License-Identifier: GPL-2.0-or-later
*/
-#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>
/* 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);
+ 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 */
+extern int 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 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);
-
+ 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 */
g_snprintf(str, sizeof(str),"%s:%u",address_to_str(&pinfo->net_src),udphdr->sport);
/* 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";
+WS_DLL_PUBLIC_DEF const gchar version[] = "0.0";
-G_MODULE_EXPORT void plugin_register_tap_listener(void) {
+WS_DLL_PUBLIC_DEF 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) */
+ 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) */
}
-#endif
----- END ------
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);
+stats_tree_register(tapname, abbr, name, flags, packet_cb, init_cb, cleanup_cb);
registers a new stats tree
+stats_tree_register_plugin(tapname, abbr, name, flags, packet_cb, init_cb, cleanup_cb);
+ registers a new stats tree from a plugin
+
stats_tree_parent_id_by_name( st, parent_name)
- returns the id of a candidate parent node given its 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
+All the functions that operate 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)
+ (i.e. it will be a candidate parent)
stats_tree_create_node_by_pname(st, name, parent_name, with_children);
- As before but creates a node using it's parent's name
+ 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:
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
+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(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 is used the same way as tick_stat_node with the
+exception that you now specify an additional value associated with the tick.
+
+Do not mix increase_stat_node, set_stat_node or zero_stat_node
+with avg_stat_node_add_value 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 :)
+
+You can find more examples of these in $srcdir/plugins/epan/stats_tree/pinfo_stats_tree.c
Luis E. G. Ontanon.