Make Mac OS X buildbot happy (Missing _U_)
[metze/wireshark/wip.git] / doc / README.stats_tree
1 $Id$
2 tapping with stats_tree
3
4 Let's suppose that you want to write a tap only to keep counters, and you
5 don't want to get involved with GUI programming or maybe you'd like to make
6 it a plugin. A stats_tree might be the way to go. The stats_tree module takes
7 care of the representation (GUI for wireshark and text for tshark) of the
8 tap data. So there's very little code to write to make a tap listener usable
9 from both wireshark and tshark.
10
11 First, you should add the TAP to the dissector in question as described in
12 README.tapping .
13
14 Once the dissector in question is "tapped" you have to write the stats tree
15 code which is made of three parts:
16
17 The init callback routine:
18    which will be executed before any packet is passed to the tap. Here you
19    should create the "static" nodes of your tree. As well as initialize your
20    data.
21    
22 The (per)packet callback routine:
23    As the tap_packet callback is going to be called for every packet, it
24    should be used to increment the counters.
25    
26 The cleanup callback:
27    It is called at the destruction of the stats_tree and might be used to
28    free ....
29
30 Other than that the stats_tree should be registered.
31
32 If you want to make it a plugin, stats_tree_register() should be called by
33 plugin_register_tap_listener() read README.plugin for other information
34 regarding wireshark plugins.
35
36 If you want it as part of the dissector stats_tree_register() can be called
37 either by proto_register_xxx() or if you prefer by proto_reg_handoff_xxx().
38
39
40 A small example of a very basic stats_tree plugin follows.
41
42 ----- example stats_tree plugin ------
43 /* udpterm_stats_tree.c
44  * A small example of stats_tree plugin that counts udp packets by termination
45  * 2005, Luis E. G. Ontanon
46  *
47  * $ ~Id:  $
48  *
49  * Wireshark - Network traffic analyzer
50  * By Gerald Combs <gerald@wireshark.org>
51  * Copyright 1998 Gerald Combs
52  *
53  * This program is free software; you can redistribute it and/or
54  * modify it under the terms of the GNU General Public License
55  * as published by the Free Software Foundation; either version 2
56  * of the License, or (at your option) any later version.
57  *
58  * This program is distributed in the hope that it will be useful,
59  * but WITHOUT ANY WARRANTY; without even the implied warranty of
60  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
61  * GNU General Public License for more details.
62  *
63  * You should have received a copy of the GNU General Public License
64  * along with this program; if not, write to the Free Software
65  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
66  */
67
68 #include "config.h"
69
70 #ifndef ENABLE_STATIC
71 #include <gmodule.h>
72 #else
73 #include <glib.h>
74 #endif
75
76 #include <epan/stats_tree.h>
77 #include <epan/dissectors/udp.h>
78
79 static int st_udp_term;
80 static gchar* st_str_udp_term = "UDP terminations";
81
82 /* this one initializes the tree, creating the root nodes */
83 extern void udp_term_stats_tree_init(stats_tree* st) {
84         /* we create a node under which we'll add every termination */
85         st_udp_term = stats_tree_create_node(st, st_str_udp_term, 0, TRUE);     
86 }
87
88 /* this one will be called with every udp packet */
89 extern int udp_term_stats_tree_packet(stats_tree *st, /* st as it was passed to us */ 
90                                       packet_info *pinfo,  /* we'll fetch the addresses from here */
91                                       epan_dissect_t *edt _U_, /* unused */ 
92                                       const void *p) /* we'll use this to fetch the ports */
93 {
94         static guint8 str[128];
95         e_udphdr* udphdr = (e_udphdr*) p;
96         
97         /* we increment by one (tick) the root node */
98         stats_tree_tick_node(st, st_udp_term, 0, FALSE);
99         
100         /* we then tick a node for this src_addr:src_port
101            if the node doesn't exists it will be created */
102         g_snprintf(str, sizeof(str),"%s:%u",address_to_str(&pinfo->net_src),udphdr->sport);
103         tick_stat_node(st, str, st_udp_term, FALSE);
104
105         /* same thing for dst */
106         g_snprintf(str, sizeof(str),"%s:%u",address_to_str(&pinfo->net_dst),udphdr->dport);
107         tick_stat_node(st, str, st_udp_term, FALSE);
108         
109         return 1;
110 }
111
112 #ifndef ENABLE_STATIC
113 WS_DLL_PUBLIC_DEF const gchar version[] = "0.0";
114
115 WS_DLL_PUBLIC_DEF void plugin_register_tap_listener(void) {
116
117     stats_tree_register("udp", /* the proto we are going to "tap" */
118                         "udp_terms", /* the abbreviation for this tree (to be used as -z udp_terms,tree) */
119                         st_str_udp_term, /* the name of the menu and window (use "/" for sub menus)*/
120                         0, /* tap listener flags for per-packet callback */
121                         udp_term_stats_tree_packet, /* the per packet callback */
122                         udp_term_stats_tree_init, /* the init callback */
123                         NULL ); /* the cleanup callback (in this case there isn't) */
124
125 }
126 #endif
127
128 ----- END ------
129
130 the stats_tree API
131 ==================
132  every stats_tree callback has a stats_tree* parameter (st), stats_tree is an obscure
133  data structure which should be passed to the api functions.
134
135 stats_tree_register( tapname, abbr, name, flags, packet_cb, init_cb, cleanup_cb);
136  registers a new stats tree
137
138 stats_tree_parent_id_by_name( st, parent_name)
139   returns the id of a candidate parent node given its name 
140
141
142 Node functions
143 ==============
144
145 All the functions that operate on nodes return a parent_id
146
147 stats_tree_create_node(st, name, parent_id, with_children)
148   Creates a node in the tree (to be used in the in init_cb)
149     name: the name of the new node
150     parent_id: the id of the parent_node (NULL for root)
151     with_children: TRUE if this node will have "dynamically created" children
152                    (i.e. it will be a candidate parent)
153
154
155 stats_tree_create_node_by_pname(st, name, parent_name, with_children);
156   As before but creates a node using its parent's name
157
158
159 stats_tree_create_range_node(st, name, parent_id, ...)
160 stats_tree_create_range_node_string(st, name, parent_id, num_str_ranges, str_ranges)
161 stats_tree_range_node_with_pname(st, name, parent_name, ...)
162   Creates a node in the tree, that will contain a ranges list.
163     example:
164        stats_tree_create_range_node(st,name,parent_id,
165                                 "-99","100-199","200-299","300-399","400-", NULL);
166
167 stats_tree_tick_range( st, name,  parent_id, value_in_range);
168 stats_tree_tick_range_by_pname(st,name,parent_name,value_in_range)
169    Increases by one the ranged node and the sub node to whose range the value belongs
170
171
172 stats_tree_create_pivot(st, name, parent_id);
173 stats_tree_create_pivot_by_pname(st, name, parent_name);
174   Creates a "pivot node"
175
176 stats_tree_tick_pivot(st, pivot_id, pivoted_string);
177  Each time a pivot node will be ticked it will get increased, and, it will
178  increase (or create) the children named as pivoted_string
179
180
181 the following will either increase or create a node (with value 1) when called
182
183 tick_stat_node(st,name,parent_id,with_children)
184 increases by one a stat_node
185
186 increase_stat_node(st,name,parent_id,with_children,value)
187 increases by value a stat_node
188
189 set_stat_node(st,name,parent_id,with_children,value)
190 sets the value of a stat_node
191
192 zero_stat_node(st,name,parent_id,with_children)
193 resets to zero a stat_node
194
195
196 You can find more examples of these in $srcdir/plugins/stats_tree/pinfo_stats_tree.c
197
198 Luis E. G. Ontanon.