fix log msg typo
[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"' to the includes.
39
40 2, We need a tap handler so just add 'static int <protocol>_tap = -1;'
41
42 3, Down in proto_register_<protocol>() you need to add
43 '<protocol>_tap = register_tap("<protocol>");'
44
45 4, In the actual dissector for that protocol, after any child dissectors
46 have returned, just add 'tap_queue_packet(<protocol>_tap, pinfo, <pointer>);'
47
48 <pointer> is used if the tap has any special additional data to provide to
49 the tap listeners. What this points to is dependent on the protocol that
50 is tapped, or if there are no useful extra data to provide just specify NULL.
51 For packet-rpc.c what we specify there is the persistent structure 'rpc_call'
52 which contains lots of useful information the rpc layer that a listener might
53 need.
54
55
56
57 TAP LISTENER
58 ============
59 (see tap-rpcstat.c as an example)
60 sInterfacing your application is not that much harder either.
61 Only 3 callbacks and two functions.
62
63
64 The two functions to start or stop tapping are
65
66 register_tap_listener(char *tapname, void *tapdata, char *fstring,
67         void (*reset)(void *tapdata), int  (*packet)(void *tapdata,
68         packet_info *pinfo, epan_dissect_t *edt, const void *<pointer>),
69         void (*draw)(void *tapdata));
70
71 remove_tap_listener(void *tapdata);
72
73
74 remove_tap_listener(void *tapdata)
75 This function is used to deregister and stop a tap listener.
76
77 register_tap_listener() is used to register an instance of a tap application
78 to the tap system.
79
80 *tapname 
81 is the name of the tap we want to listen to. I.e. the name used in
82 step 3 above.
83
84 *tapdata 
85 is the instance identifier. The tap system uses the value of this
86 pointer to distinguish between different instances of a tap.
87 Just make sure that it is unique by letting it be the pointer to a struct
88 holding all state variables. If you want to allow multiple concurrent
89 instances, just put ALL state variables inside a struct allocated by
90 g_malloc() and use that pointer.
91 (tap-rpcstat.c use this technique to allow multiple simultaneous instances)
92
93 *fstring 
94 is a pointer to a filter string. 
95 If this is NULL, then the tap system will provide ALL packets passing the
96 tapped protocol to your listener.
97 If you specify a filter string here the tap system will first try
98 to apply this string to the packet and then only pass those packets that
99 matched the filter to your listener.
100 The syntax for the filter string is identical to normal display filters.
101
102 NOTE: Specifying filter strings will have a significant performance impact
103 on your application and Wireshark. If possible it is MUCH better to take
104 unfiltered data and just filter it yourself in the packet-callback than
105 to specify a filter string.
106 ONLY use a filter string if no other option exist.
107
108 void (*reset)(void *tapdata)
109 This callback is called whenever Wireshark wants to inform your
110 listener that it is about to start [re]reading a capture file or a new capture
111 from an interface and that your application should reset any state it has
112 in the *tapdata instance.
113
114 int (*packet)(void *tapdata, packet_info *pinfo, epan_dissect_t *edt, void *data)
115 This callback is used whenever a new packet has arrived at the tap and that
116 it has passed the filter (if there were a filter).
117 The *data structure type is specific to each tap.
118 This function returns an int and it should return 
119  1, if the data in the packet caused state to be updated
120     (and thus a redraw of the window would later be required)
121  0, if we don't need to redraw the window.
122 NOTE: that (*packet) should be as fast and efficient as possible. Use this
123 function ONLY to store data for later and do the CPU-intensive processing
124 or GUI updates down in (*draw) instead.
125
126  
127 void (*draw)(void *tapdata)
128 This callback is used when Wireshark wants your application to redraw its
129 output. It will usually not be called unless your application has received
130 new data through the (*packet) callback.
131 On some ports of Wireshark (gtk2) (*draw) will be called asynchronously 
132 from a separate thread up to once every 2-3 seconds.
133 On other ports it might only be called once when the capture is finished
134 or the file has been [re]read completely.
135
136
137
138 So, create three callbacks:
139 1, reset   to reset the state variables in the structure passed to it.
140 2, packet  to update these state variables.
141 3, draw    to take these state variables and draw them on the screen.
142
143 then just make Wireshark call register_tap_listener() when you want to tap
144 and call remove_tap_listener() when you are finished.
145
146
147 WHEN DO TAP LISTENERS GET CALLED?
148 ===================================
149 Tap listeners are only called when Wireshark reads a new capture for
150 the first time or whenever Wireshark needs to rescan/redissect
151 the capture.
152 Redissection occurs when you apply a new display filter or if you
153 change and Save/Apply a preference setting that might affect how
154 packets are dissected.
155 After each individual packet has been completely dissected and all
156 dissectors have returned, all the tap listeners that has been flagged
157 to receive tap data during the dissection of the frame will be called in
158 sequence.
159 The order of which the tap listeners will be called is not defined.
160 Not until all tap listeners for the frame has been called and returned
161 will Wireshark continue to dissect the next packet.
162 This is why it is important to make the *_packet() callbacks execute as
163 quickly as possible, else we create an extra delay until the next packet
164 is dissected.
165
166 Keep in mind though: for some protocols, such as IP, the protocol can
167 appear multiple times in different layers inside the same packet.
168 For example, IP encapsulated over IP which will call the ip dissector
169 twice for the same packet.
170 IF the tap is going to return private data using the last parameter to 
171 tap_queue_packet() and IF the protocol can appear multiple times inside the 
172 same packet, you will have to make sure that each instance of 
173 tap_queue_packet() is using its own instance of private struct variable
174 so they don't overwrite each other.
175
176 See packet-ip.c which has a simple solution to the problem. It just
177 uses a static struct of 4 instances of the ip header struct and
178 cycles through them each time the dissector is called.
179 4 is just a number taken out of the blue but it should be enough for most
180 cases.
181 Of course, if someone would generate a capture with IP encapsulated
182 over IP over IP over IP over IP, so that there would be more than 4 IP headers
183 in the same packet, yes then this would fail.   The likelihood of this 
184 happening in real life is probably very low. If it turns out to be a problem
185 we can just increase the cycle length when that happens.
186
187
188 TIPS
189 ====
190 Of course, there is nothing that forces you to make (*draw) draw stuff
191 on the screen. 
192 You can hand register_tap_listener() NULL for both (*draw) and (*reset)
193 (well also for (*packet) but that would be a very boring extension).
194
195 Perhaps you want an extension that will execute a certain command
196 every time it sees a certain packet?
197 Well, try this :
198         int packet(void *tapdata,...) {
199                 ...
200                 system("mail ...");
201                 return0;
202         }
203
204         register_tap_listener("tcp", struct, "tcp.port==57", NULL, packet, NULL);
205
206         Let struct contain an email address?
207         Then you have something simple that will make Wireshark send an email
208         out automagically for each and every time it dissects 
209         a packet containing TCP traffic to port 57.
210         Please put in some rate limitation if you do this.
211
212         Let struct contain a command line and make (*packet) execute it?
213         The possibilities are rather large.
214
215
216
217 See tap-rpcstat.c for an example
218 See tap.c as well. It contains lots of comments and descriptions on the tap 
219 system.
220
221
222
223