Add #ifndef __PRIVILEGES_H__ / #define / #endif logic to prevent multiple
[obnox/wireshark/wip.git] / doc / README.tapping
1 $Id$
2
3 The TAP system in Wireshark is a powerful and flexible mechanism to get event
4 driven notification on packets matching certain protocols and/or filters.
5 In order to use the tapping system, very little knowledge of Wireshark
6 internals are required.
7
8 As examples on how to use the tap system see the implementation of
9 tap-rpcstat.c           (tshark version)
10 gtk/rpc_stat.c          (gtk-wireshark version)
11
12 If all you need is to keep some counters, there's the stats_tree API,
13 which offers a simple way to make a GUI and tshark tap-listener; see
14 README.stats_tree.  However, keep reading, as you'll need much of what's
15 in this document.
16
17 The tap system consists of two parts:
18 1, code in the actual dissectors to allow tapping data from that particular
19 protocol dissector, and
20 2, event driven code in an extension such as tap-rpcstat.c that registers
21 a tap listener and processes received data.
22
23
24
25 So you want to hack together a tap application?
26
27
28 TAP
29 ===
30 First you must decide which protocol you are interested in writing a tap
31 application for and check if that protocol has already got a tap installed
32 in it.
33 If it already has a tap device installed then you don't have to do anything.
34 If not, then you have to add a tap but don't worry, this is extremely easy to
35 do and is done in four easy steps;
36 (see packet-rpc.c and search for tap for an example)
37
38 1, We need tap.h so just add '#include "tap.h"' (preceded by packet.h) to
39 the includes.
40
41 2, We need a tap handler so just add 'static int <protocol>_tap = -1;'
42
43 3, Down in proto_register_<protocol>() you need to add
44 '<protocol>_tap = register_tap("<protocol>");'
45
46 4, In the actual dissector for that protocol, after any child dissectors
47 have returned, just add 'tap_queue_packet(<protocol>_tap, pinfo, <pointer>);'
48
49 <pointer> is used if the tap has any special additional data to provide to the
50 tap listeners. What this points to is dependent on the protocol that is tapped,
51 or if there are no useful extra data to provide just specify NULL.  For
52 packet-rpc.c what we specify there is the persistent structure 'rpc_call' which
53 contains lots of useful information from the rpc layer that a listener might
54 need.
55
56
57
58 TAP LISTENER
59 ============
60 (see tap-rpcstat.c as an example)
61 Interfacing your application is not that much harder either.
62 Only 3 callbacks and two functions.
63
64
65 The two functions to start or stop tapping are
66
67 register_tap_listener(const char *tapname, void *tapdata, const char *fstring,
68         guint flags,
69         void (*reset)(void *tapdata),
70         gboolean (*packet)(void *tapdata, packet_info *pinfo, epan_dissect_t *edt, const void *<pointer>),
71         void (*draw)(void *tapdata));
72
73 remove_tap_listener(void *tapdata);
74
75
76 remove_tap_listener(void *tapdata)
77 This function is used to deregister and stop a tap listener.
78
79 register_tap_listener() is used to register an instance of a tap application
80 to the tap system.
81
82 *tapname
83 is the name of the tap we want to listen to. I.e. the name used in
84 step 3 above.
85
86 *tapdata
87 is the instance identifier. The tap system uses the value of this
88 pointer to distinguish between different instances of a tap.
89 Just make sure that it is unique by letting it be the pointer to a struct
90 holding all state variables. If you want to allow multiple concurrent
91 instances, just put ALL state variables inside a struct allocated by
92 g_malloc() and use that pointer.
93 (tap-rpcstat.c use this technique to allow multiple simultaneous instances)
94
95 *fstring
96 is a pointer to a filter string.
97 If this is NULL, then the tap system will provide ALL packets passing the
98 tapped protocol to your listener.
99 If you specify a filter string here the tap system will first try
100 to apply this string to the packet and then only pass those packets that
101 matched the filter to your listener.
102 The syntax for the filter string is identical to normal display filters.
103
104 NOTE: Specifying filter strings will have a significant performance impact
105 on your application and Wireshark. If possible it is MUCH better to take
106 unfiltered data and just filter it yourself in the packet-callback than
107 to specify a filter string.
108 ONLY use a filter string if no other option exist.
109
110 flags
111 is a set of flags for the tap listener.  The flags that can be set are:
112
113     TL_REQUIRES_PROTO_TREE
114
115         set if your tap listener "packet" routine requires a protocol
116         tree to be built.  It will require a protocol tree to be
117         built if either
118
119                 1) it looks at the protocol tree in edt->tree
120
121         or
122
123                 2) the tap-specific data passed to it is constructed only if
124                    the protocol tree is being built.
125
126     TL_REQUIRES_COLUMNS
127
128         set if your tap listener "packet" routine requires the column
129         strings to be constructed.
130
131 void (*reset)(void *tapdata)
132 This callback is called whenever Wireshark wants to inform your
133 listener that it is about to start [re]reading a capture file or a new capture
134 from an interface and that your application should reset any state it has
135 in the *tapdata instance.
136
137 gboolean (*packet)(void *tapdata, packet_info *pinfo, epan_dissect_t *edt, void *data)
138 This callback is used whenever a new packet has arrived at the tap and that
139 it has passed the filter (if there were a filter).
140 The *data structure type is specific to each tap.
141 This function returns an gboolean and it should return
142  TRUE, if the data in the packet caused state to be updated
143        (and thus a redraw of the window would later be required)
144  FALSE, if we don't need to redraw the window.
145 NOTE: that (*packet) should be as fast and efficient as possible. Use this
146 function ONLY to store data for later and do the CPU-intensive processing
147 or GUI updates down in (*draw) instead.
148
149
150 void (*draw)(void *tapdata)
151 This callback is used when Wireshark wants your application to redraw its
152 output. It will usually not be called unless your application has received
153 new data through the (*packet) callback.
154 On some ports of Wireshark (gtk2) (*draw) will be called asynchronously
155 from a separate thread up to once every 2-3 seconds.
156 On other ports it might only be called once when the capture is finished
157 or the file has been [re]read completely.
158
159
160
161 So, create three callbacks:
162 1, reset   to reset the state variables in the structure passed to it.
163 2, packet  to update these state variables.
164 3, draw    to take these state variables and draw them on the screen.
165
166 then just make Wireshark call register_tap_listener() when you want to tap
167 and call remove_tap_listener() when you are finished.
168
169
170 WHEN DO TAP LISTENERS GET CALLED?
171 ===================================
172 Tap listeners are only called when Wireshark reads a new capture for
173 the first time or whenever Wireshark needs to rescan/redissect
174 the capture.
175 Redissection occurs when you apply a new display filter or if you
176 change and Save/Apply a preference setting that might affect how
177 packets are dissected.
178 After each individual packet has been completely dissected and all
179 dissectors have returned, all the tap listeners that have been flagged
180 to receive tap data during the dissection of the frame will be called in
181 sequence.
182 The order in which the tap listeners will be called is not defined.
183 Not until all tap listeners for the frame has been called and returned
184 will Wireshark continue to dissect the next packet.
185 This is why it is important to make the *_packet() callbacks execute as
186 quickly as possible, else we create an extra delay until the next packet
187 is dissected.
188
189 Keep in mind though: for some protocols, such as IP, the protocol can
190 appear multiple times in different layers inside the same packet.
191 For example, IP encapsulated over IP which will call the ip dissector
192 twice for the same packet.
193 IF the tap is going to return private data using the last parameter to
194 tap_queue_packet() and IF the protocol can appear multiple times inside the
195 same packet, you will have to make sure that each instance of
196 tap_queue_packet() is using its own instance of private struct variable
197 so they don't overwrite each other.
198
199 See packet-ip.c which has a simple solution to the problem. It creates
200 a unique instance of the IP header using ep_alloc().
201 Previous versions used a static struct of 4 instances of the IP header
202 struct and cycled through them each time the dissector was called. (4
203 was just a number taken out of the blue but it should be enough for most
204 cases.) This would fail if there were more than 4 IP headers in the same
205 packet, but that was unlikely.
206
207
208 TIPS
209 ====
210 Of course, there is nothing that forces you to make (*draw) draw stuff
211 on the screen.
212 You can hand register_tap_listener() NULL for both (*draw) and (*reset)
213 (well also for (*packet) but that would be a very boring extension).
214
215 Perhaps you want an extension that will execute a certain command
216 every time it sees a certain packet?
217 Well, try this :
218         int packet(void *tapdata,...) {
219                 ...
220                 system("mail ...");
221                 return0;
222         }
223
224         register_tap_listener("tcp", struct, "tcp.port==57", NULL, packet, NULL);
225
226         Let struct contain an email address?
227         Then you have something simple that will make Wireshark send an email
228         out automagically for each and every time it dissects
229         a packet containing TCP traffic to port 57.
230         Please put in some rate limitation if you do this.
231
232         Let struct contain a command line and make (*packet) execute it?
233         The possibilities are rather large.
234
235
236
237 See tap-rpcstat.c for an example
238 See tap.c as well. It contains lots of comments and descriptions on the tap
239 system.
240
241
242
243