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