attr_dissector_fn_t
[wireshark-sm.git] / doc / README.stats_tree
blob9d303d38334d9bce9c68e43cc4b0799267cf654b
1 tapping with stats_tree
3 Let's suppose that you want to write a tap only to keep counters, and you
4 don't want to get involved with GUI programming or maybe you'd like to make
5 it a plugin. A stats_tree might be the way to go. The stats_tree module takes
6 care of the representation (GUI for Wireshark and text for TShark) of the
7 tap data. So there's very little code to write to make a tap listener usable
8 from both Wireshark and TShark.
10 First, you should add the TAP to the dissector in question as described in
11 README.tapping .
13 Once the dissector in question is "tapped" you have to write the stats tree
14 code which is made of three parts:
16 The init callback routine:
17    which will be executed before any packet is passed to the tap. Here you
18    should create the "static" nodes of your tree. As well as initialize your
19    data.
21 The (per)packet callback routine:
22    As the tap_packet callback is going to be called for every packet, it
23    should be used to increment the counters.
25 The cleanup callback:
26    It is called at the destruction of the stats_tree and might be used to
27    free ....
29 Other than that the stats_tree should be registered.
31 If you want to make it a plugin, stats_tree_register() should be called by
32 plugin_register_tap_listener() read README.plugins for other information
33 regarding Wireshark plugins.
35 If you want it as part of the dissector stats_tree_register() can be called
36 either by proto_register_xxx() or if you prefer by proto_reg_handoff_xxx().
39 A small example of a very basic stats_tree plugin follows.
41 ----- example stats_tree plugin ------
42 /* udpterm_stats_tree.c
43  * A small example of stats_tree plugin that counts udp packets by termination
44  * 2005, Luis E. G. Ontanon
45  *
46  * Wireshark - Network traffic analyzer
47  * By Gerald Combs <gerald@wireshark.org>
48  * Copyright 1998 Gerald Combs
49  *
50  * SPDX-License-Identifier: GPL-2.0-or-later
51  */
53 #include "config.h"
55 #include <gmodule.h>
57 #include <epan/stats_tree.h>
58 #include <epan/dissectors/udp.h>
60 static int st_udp_term;
61 static char* st_str_udp_term = "UDP terminations";
63 /* this one initializes the tree, creating the root nodes */
64 extern void udp_term_stats_tree_init(stats_tree* st) {
65         /* we create a node under which we'll add every termination */
66         st_udp_term = stats_tree_create_node(st, st_str_udp_term, 0, STAT_DT_INT, true);
69 /* this one will be called with every udp packet */
70 extern tap_packet_status
71 udp_term_stats_tree_packet(stats_tree *st, /* st as it was passed to us */
72                            packet_info *pinfo,  /* we'll fetch the addresses from here */
73                            epan_dissect_t *edt _U_, /* unused */
74                            const void *p) /* we'll use this to fetch the ports */
76         static uint8_t str[128];
77         e_udphdr* udphdr = (e_udphdr*) p;
79         /* we increment by one (tick) the root node */
80         tick_stat_node(st, st_str_udp_term, 0, false);
82         /* we then tick a node for this src_addr:src_port
83            if the node doesn't exists it will be created */
84         snprintf(str, sizeof(str),"%s:%u",address_to_str(&pinfo->net_src),udphdr->sport);
85         tick_stat_node(st, str, st_udp_term, false);
87         /* same thing for dst */
88         snprintf(str, sizeof(str),"%s:%u",address_to_str(&pinfo->net_dst),udphdr->dport);
89         tick_stat_node(st, str, st_udp_term, false);
91         return 1;
94 WS_DLL_PUBLIC_DEF const char version[] = "0.0";
96 WS_DLL_PUBLIC_DEF void plugin_register_tap_listener(void) {
98     stats_tree_register_plugin("udp", /* the proto we are going to "tap" */
99                                "udp_terms", /* the abbreviation for this tree (to be used as -z udp_terms,tree) */
100                                st_str_udp_term, /* the name of the menu and window (use "/" for sub menus)*/
101                                0, /* tap listener flags for per-packet callback */
102                                udp_term_stats_tree_packet, /* the per packet callback */
103                                udp_term_stats_tree_init, /* the init callback */
104                                NULL ); /* the cleanup callback (in this case there isn't) */
108 ----- END ------
110 the stats_tree API
111 ==================
112  every stats_tree callback has a stats_tree* parameter (st), stats_tree is an obscure
113  data structure which should be passed to the api functions.
115 stats_tree_register(tapname, abbr, name, flags, packet_cb, init_cb, cleanup_cb);
116  registers a new stats tree with default group REGISTER_STAT_GROUP_UNSORTED
118 stats_tree_register_plugin(tapname, abbr, name, flags, packet_cb, init_cb, cleanup_cb);
119  registers a new stats tree from a plugin with the default group REGISTER_STAT_GROUP_UNSORTED
121 stats_tree_set_group(st_config, stat_group);
122  changes the menu statistics group for a stats tree
124 stats_tree_parent_id_by_name( st, parent_name)
125   returns the id of a candidate parent node given its name
128 Node functions
129 ==============
131 All the functions that operate on nodes return a parent_id
133 stats_tree_create_node(st, name, parent_id, datatype, with_children)
134   Creates a node in the tree (to be used in the in init_cb)
135     name: the name of the new node
136     parent_id: the id of the parent_node (NULL for root)
137     datatype: datatype of the new node, STAT_DT_INT or STAT_DT_FLOAT. The only
138               methods implemented for floats are averages.
139     with_children: true if this node will have "dynamically created" children
140                    (i.e. it will be a candidate parent)
143 stats_tree_create_node_by_pname(st, name, parent_name, datatype, with_children);
144   As before but creates a node using its parent's name
147 stats_tree_create_range_node(st, name, parent_id, ...)
148 stats_tree_create_range_node_string(st, name, parent_id, num_str_ranges, str_ranges)
149 stats_tree_range_node_with_pname(st, name, parent_name, ...)
150   Creates a node in the tree, that will contain a ranges list.
151     example:
152        stats_tree_create_range_node(st,name,parent_id,
153                                 "-99","100-199","200-299","300-399","400-", NULL);
155 stats_tree_tick_range(st, name, parent_id, value_in_range);
156 stats_tree_tick_range_by_pname(st, name, parent_name, value_in_range)
157    Increases by one the ranged node and the sub node to whose range the value belongs
160 stats_tree_create_pivot(st, name, parent_id);
161 stats_tree_create_pivot_by_pname(st, name, parent_name);
162   Creates a "pivot node"
164 stats_tree_tick_pivot(st, pivot_id, pivoted_string);
165  Each time a pivot node will be ticked it will get increased, and, it will
166  increase (or create) the children named as pivoted_string
168 the following will either increase or create a node (with value 1) when called
170 tick_stat_node(st, name, parent_id, with_children)
171 increases by one a stat_node
173 increase_stat_node(st, name, parent_id, with_children, value)
174 increases by value a stat_node
176 set_stat_node(st, name, parent_id, with_children, value)
177 sets the value of a stat_node
179 zero_stat_node(st, name, parent_id, with_children)
180 resets to zero a stat_node
182 Averages work by tracking both the number of items added to node (the ticking
183 action) and the value of each item added to the node. This is done
184 automatically for ranged nodes; for other node types you need to call one of
185 the functions below to associate item values with each tick.
187 avg_stat_node_add_value_notick(st, name, parent_id, with_children, value)
188 avg_stat_node_add_value_int(st, name, parent_id, with_children, value)
189 avg_stat_node_add_value_float(st, name, parent_id, with_children, value)
191 The difference between the above functions is whether the item count is
192 increased or not. To properly compute the average you need to either call
193 avg_stat_node_add_value or avg_stat_node_add_value_notick combined
194 tick_stat_node. The later sequence allows for plug-ins which are compatible
195 with older Wireshark versions which ignores avg_stat_node_add_value because
196 it does not understand the command. This would result in 0 counts for all
197 nodes. It is preferred to use avg_stat_node_add_value if you are not writing
198 a plug-in.
200 avg_stat_node_add_value_int is used the same way as tick_stat_node with the
201 exception that you now specify an additional value associated with the tick.
203 avg_stat_node_add_value_float is used to compute averages of floats, for nodes
204 with the STAT_DT_FLOAT datatype.
206 Do not mix increase_stat_node, set_stat_node or zero_stat_node
207 with avg_stat_node_add_value_int as this will lead to incorrect results for the
208 average value.
210 stats_tree now also support setting flags per node to control the behaviour
211 of these nodes. This can be done using the stat_node_set_flags and
212 stat_node_clear_flags functions. Currently these flags are defined:
214         ST_FLG_DEF_NOEXPAND: By default the top-level nodes in a tree are
215                         automatically expanded in the GUI. Setting this flag on
216                         such a node prevents the node from automatically
217                         expanding.
218         ST_FLG_SORT_TOP: Nodes with this flag is sorted separately from nodes
219                         without this flag (in effect partitioning tree into a top
220                         and bottom half. Each half is sorted normally. Top always
221                         appear first :)
223 The same node manipulations can also be performed via generic functions:
225 stats_tree_manip_node_int(mode, st, name, parent_id, with_children, value);
226 stats_tree_manip_node_float(mode, st, name, parent_id, with_children, value);
228 mode is an enum with the following set of values:
229     MN_INCREASE
230     MN_SET
231     MN_AVERAGE
232     MN_AVERAGE_NOTICK
233     MN_SET_FLAGS
234     MN_CLEAR_FLAGS
236 You can find more examples of these in $srcdir/plugins/epan/stats_tree/pinfo_stats_tree.c
238 Luis E. G. Ontanon.