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