diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-10 20:34:10 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-10 20:34:10 +0000 |
commit | e4ba6dbc3f1e76890b22773807ea37fe8fa2b1bc (patch) | |
tree | 68cb5ef9081156392f1dd62a00c6ccc1451b93df /doc/README.stats_tree | |
parent | Initial commit. (diff) | |
download | wireshark-e4ba6dbc3f1e76890b22773807ea37fe8fa2b1bc.tar.xz wireshark-e4ba6dbc3f1e76890b22773807ea37fe8fa2b1bc.zip |
Adding upstream version 4.2.2.upstream/4.2.2
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'doc/README.stats_tree')
-rw-r--r-- | doc/README.stats_tree | 238 |
1 files changed, 238 insertions, 0 deletions
diff --git a/doc/README.stats_tree b/doc/README.stats_tree new file mode 100644 index 00000000..1b7e69e4 --- /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. |