1 /* tap.h
2  * packet tap interface   2002 Ronnie Sahlberg
3  *
4  * Wireshark - Network traffic analyzer
5  * By Gerald Combs <gerald@wireshark.org>
6  * Copyright 1998 Gerald Combs
7  *
8  * SPDX-License-Identifier: GPL-2.0-or-later
9  */
10 
11 #ifndef __TAP_H__
12 #define __TAP_H__
13 
14 #include <epan/epan.h>
15 #include <epan/packet_info.h>
16 #include "ws_symbol_export.h"
17 
18 #ifdef __cplusplus
19 extern "C" {
20 #endif /* __cplusplus */
21 
22 /**
23  * Status returned by the per-packet callback.
24  */
25 typedef enum {
26 	TAP_PACKET_DONT_REDRAW,	/**< Packet processing succeeded, no need to redraw */
27 	TAP_PACKET_REDRAW,	/**< Packet processing succeeded, must redraw */
28 	TAP_PACKET_FAILED	/**< Packet processing failed, stop calling this tap */
29 } tap_packet_status;
30 
31 typedef void (*tap_reset_cb)(void *tapdata);
32 typedef tap_packet_status (*tap_packet_cb)(void *tapdata, packet_info *pinfo, epan_dissect_t *edt, const void *data);
33 typedef void (*tap_draw_cb)(void *tapdata);
34 typedef void (*tap_finish_cb)(void *tapdata);
35 
36 /**
37  * Flags to indicate what a tap listener's packet routine requires.
38  */
39 #define TL_REQUIRES_NOTHING	0x00000000	        /**< nothing */
40 #define TL_REQUIRES_PROTO_TREE	0x00000001	    /**< full protocol tree */
41 #define TL_REQUIRES_COLUMNS	0x00000002	        /**< columns */
42 #define TL_REQUIRES_ERROR_PACKETS	0x00000004	/**< include packet even if pinfo->flags.in_error_pkt is set */
43 /** Flags to indicate what the tap listener does */
44 #define TL_IS_DISSECTOR_HELPER	0x00000008	    /**< tap helps a dissector do work
45 						                         ** but does not, itself, require dissection */
46 
47 typedef struct {
48 	void (*register_tap_listener)(void);   /* routine to call to register tap listener */
49 } tap_plugin;
50 
51 /** Register tap plugin with the plugin system. */
52 WS_DLL_PUBLIC void tap_register_plugin(const tap_plugin *plug);
53 
54 /*
55  * Entry in the table of built-in taps to register.
56  */
57 typedef struct _tap_reg {
58     const char *cb_name;
59     void (*cb_func)(void);
60 } tap_reg_t;
61 
62 /*
63  * For all taps, call their register routines.
64  * Must be called after plugins_init(), if plugins are supported,
65  * and must be called only once in a program.
66  *
67  * XXX - should probably be handled by epan_init(), as the tap mechanism
68  * is part of libwireshark.
69  */
70 WS_DLL_PUBLIC void register_all_tap_listeners(tap_reg_t *tap_reg_listeners);
71 
72 extern void tap_init(void);
73 
74 /** This function registers that a dissector has the packet tap ability
75  *  available.  The name parameter is the name of this tap and extensions can
76  *  use open_tap(char *name,... to specify that it wants to receive packets/
77  *  events from this tap.
78  *
79  *  This function is only to be called once, when the dissector initializes.
80  *
81  *  The return value from this call is later used as a parameter to the
82  *  tap_packet(unsigned int *tap_id,...
83  *  call so that the tap subsystem knows to which tap point this tapped
84  *  packet is associated.
85  */
86 WS_DLL_PUBLIC int register_tap(const char *name);
87 
88 /* Gets a GList of the tap names */
89 WS_DLL_PUBLIC GList* get_tap_names(void);
90 
91 /** This function will return the tap_id for the specific protocol tap
92  *  or 0 if no such tap was found.
93  */
94 WS_DLL_PUBLIC int find_tap_id(const char *name);
95 
96 /** Everytime the dissector has finished dissecting a packet (and all
97  *  subdissectors have returned) and if the dissector has been made "tappable"
98  *  it will push some data to everyone tapping this layer by a call
99  *  to tap_queue_packet().
100  *  The first parameter is the tap_id returned by the register_tap()
101  *  call for this dissector (so the tap system can keep track of who it came
102  *  from and who is listening to it)
103  *  The second is the packet_info structure which many tap readers will find
104  *  interesting.
105  *  The third argument is specific to each tap point or NULL if no additional
106  *  data is available to this tap.  A tap point in say IP will probably want to
107  *  push the IP header structure here. Same thing for TCP and ONCRPC.
108  *
109  *  The pinfo and the specific pointer are what is supplied to every listener
110  *  in the read_callback() call made to every one currently listening to this
111  *  tap.
112  *
113  *  The tap reader is responsible to know how to parse any structure pointed
114  *  to by the tap specific data pointer.
115  */
116 WS_DLL_PUBLIC void tap_queue_packet(int tap_id, packet_info *pinfo, const void *tap_specific_data);
117 
118 /** Functions used by file.c to drive the tap subsystem */
119 WS_DLL_PUBLIC void tap_build_interesting(epan_dissect_t *edt);
120 
121 /** This function is used to delete/initialize the tap queue and prime an
122  *  epan_dissect_t with all the filters for tap listeners.
123  *  To free the tap queue, we just prepend the used queue to the free queue.
124  */
125 extern void tap_queue_init(epan_dissect_t *edt);
126 
127 /** this function is called after a packet has been fully dissected to push the tapped
128  *  data to all extensions that has callbacks registered.
129  */
130 
131 extern void tap_push_tapped_queue(epan_dissect_t *edt);
132 
133 /** This function is called after a packet has been fully dissected to push the tapped
134  *  data to all extensions that has callbacks registered.
135  */
136 
137 WS_DLL_PUBLIC void reset_tap_listeners(void);
138 
139 /** This function is called when we need to redraw all tap listeners, for example
140  * when we open/start a new capture or if we need to rescan the packet list.
141  * It should be called from a low priority thread say once every 3 seconds
142  *
143  * If draw_all is true, redraw all applications regardless if they have
144  * changed or not.
145  */
146 WS_DLL_PUBLIC void draw_tap_listeners(gboolean draw_all);
147 
148 /** this function attaches the tap_listener to the named tap.
149  * function returns :
150  *     NULL: ok.
151  * non-NULL: error, return value points to GString containing error
152  *           message.
153  * @param tapname    The name of the tap we want to listen to.
154  * @param tapdata    is the instance identifier. The tap system uses the value of this
155  *                   pointer to distinguish between different instances of a tap.
156  *                   Just make sure that it is unique by letting it be the pointer to a struct
157  *                   holding all state variables. If you want to allow multiple concurrent
158  *                   instances, just put ALL state variables inside a struct allocated by
159  *                   g_malloc() and use that pointer.
160  * @param fstring    is a pointer to a filter string.
161  *                   If this is NULL, then the tap system will provide ALL packets passing the
162  *                   tapped protocol to your listener.
163  *                   If you specify a filter string here the tap system will first try
164  *                   to apply this string to the packet and then only pass those packets that
165  *                   matched the filter to your listener.
166  *                   The syntax for the filter string is identical to normal display filters.
167  *
168  *                   NOTE: Specifying filter strings will have a significant performance impact
169  *                   on your application and Wireshark. If possible it is MUCH better to take
170  *                   unfiltered data and just filter it yourself in the packet-callback than
171  *                   to specify a filter string.
172  *                   ONLY use a filter string if no other option exist.
173  *
174  * @param flags      is a set of flags for the tap listener.  The flags that can be set are:
175  *
176  *                      TL_REQUIRES_PROTO_TREE
177  *
178  *                   	set if your tap listener "packet" routine requires a protocol
179  *                   	tree to be built.  It will require a protocol tree to be
180  *                   	built if either
181  *
182  *                   		1) it looks at the protocol tree in edt->tree
183  *
184  *                   	or
185  *
186  *                   		2) the tap-specific data passed to it is constructed only if
187  *                   		   the protocol tree is being built.
188  *
189  *                      TL_REQUIRES_COLUMNS
190  *
191  *                   	set if your tap listener "packet" routine requires the column
192  *                   	strings to be constructed.
193  *
194  *                       If no flags are needed, use TL_REQUIRES_NOTHING.
195  *
196  * @param tap_reset  void (*reset)(void *tapdata)
197  *                   This callback is called whenever Wireshark wants to inform your
198  *                   listener that it is about to start [re]reading a capture file or a new capture
199  *                   from an interface and that your application should reset any state it has
200  *                   in the *tapdata instance.
201  * @param tap_packet gboolean (*packet)(void *tapdata, packet_info *pinfo, epan_dissect_t *edt, const void *data)
202  *                   This callback is used whenever a new packet has arrived at the tap and that
203  *                   it has passed the filter (if there were a filter).
204  *                   The *data structure type is specific to each tap.
205  *                   This function returns an gboolean and it should return
206  *                    TRUE, if the data in the packet caused state to be updated
207  *                          (and thus a redraw of the window would later be required)
208  *                    FALSE, if we don't need to redraw the window.
209  *                   NOTE: that (*packet) should be as fast and efficient as possible. Use this
210  *                   function ONLY to store data for later and do the CPU-intensive processing
211  *                   or GUI updates down in (*draw) instead.
212  * @param tap_draw   void (*draw)(void *tapdata)
213  *                   This callback is used when Wireshark wants your application to redraw its
214  *                   output. It will usually not be called unless your application has received
215  *                   new data through the (*packet) callback.
216  *                   On some ports of Wireshark (gtk2) (*draw) will be called asynchronously
217  *                   from a separate thread up to once every 2-3 seconds.
218  *                   On other ports it might only be called once when the capture is finished
219  *                   or the file has been [re]read completely.
220  * @param tap_finish void (*finish)(void *tapdata)
221  *                   This callback is called when your listener is removed.
222  */
223 
224 WS_DLL_PUBLIC GString *register_tap_listener(const char *tapname, void *tapdata,
225     const char *fstring, guint flags, tap_reset_cb tap_reset,
226     tap_packet_cb tap_packet, tap_draw_cb tap_draw,
227     tap_finish_cb tap_finish) G_GNUC_WARN_UNUSED_RESULT;
228 
229 /** This function sets a new dfilter to a tap listener */
230 WS_DLL_PUBLIC GString *set_tap_dfilter(void *tapdata, const char *fstring);
231 
232 /** This function recompiles dfilter for all registered tap listeners */
233 WS_DLL_PUBLIC void tap_listeners_dfilter_recompile(void);
234 
235 /** this function removes a tap listener */
236 WS_DLL_PUBLIC void remove_tap_listener(void *tapdata);
237 
238 /**
239  * Return TRUE if we have one or more tap listeners that require dissection,
240  * FALSE otherwise.
241  */
242 WS_DLL_PUBLIC gboolean tap_listeners_require_dissection(void);
243 
244 /** Returns TRUE there is an active tap listener for the specified tap id. */
245 WS_DLL_PUBLIC gboolean have_tap_listener(int tap_id);
246 
247 /** Return TRUE if we have any tap listeners with filters, FALSE otherwise. */
248 WS_DLL_PUBLIC gboolean have_filtering_tap_listeners(void);
249 
250 /**
251  * Get the union of all the flags for all the tap listeners; that gives
252  * an indication of whether the protocol tree, or the columns, are
253  * required by any taps.
254  */
255 WS_DLL_PUBLIC guint union_of_tap_listener_flags(void);
256 
257 /** This function can be used by a dissector to fetch any tapped data before
258  * returning.
259  * This can be useful if one wants to extract the data inside dissector  BEFORE
260  * it exists as an alternative to the callbacks that are all called AFTER the
261  * dissection has completed.
262  *
263  * Example: SMB2 uses this mechanism to extract the data tapped from NTLMSSP
264  * containing the account and domain names before exiting.
265  * Note that the SMB2 tap listener specifies all three callbacks as NULL.
266  *
267  * Beware: when using this mechanism to extract the tapped data you can not
268  * use "filters" and should specify the "filter" as NULL when registering
269  * the tap listener.
270  */
271 WS_DLL_PUBLIC const void *fetch_tapped_data(int tap_id, int idx);
272 
273 /** Clean internal structures
274  */
275 extern void tap_cleanup(void);
276 
277 #ifdef __cplusplus
278 }
279 #endif /* __cplusplus */
280 
281 #endif /* __TAP_H__ */
282