2 * packet tap interface 2002 Ronnie Sahlberg
4 * Wireshark - Network traffic analyzer
5 * By Gerald Combs <gerald@wireshark.org>
6 * Copyright 1998 Gerald Combs
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * as published by the Free Software Foundation; either version 2
11 * of the License, or (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
27 #ifdef HAVE_SYS_TYPES_H
28 # include <sys/types.h>
31 #ifdef HAVE_NETINET_IN_H
32 # include <netinet/in.h>
39 #include <epan/packet_info.h>
40 #include <epan/dfilter/dfilter.h>
43 static gboolean tapping_is_active=FALSE;
45 typedef struct _tap_dissector_t {
46 struct _tap_dissector_t *next;
49 static tap_dissector_t *tap_dissector_list=NULL;
52 * This is the list of free and used packets queued for a tap.
53 * It is implemented here explicitly instead of using GLib objects
54 * in order to be as fast as possible as we need to build and tear down the
55 * queued list at least once for each packet we see and thus we must be able
56 * to build and tear it down as fast as possible.
58 * XXX - some fields in packet_info get overwritten in the dissection
59 * process, such as the addresses and the "this is an error packet" flag.
60 * A packet may be queued at multiple protocol layers, but the packet_info
61 * structure will, when the tap listeners are run, contain the values as
62 * set by the topmost protocol layers.
64 * This means that the tap listener code can't rely on pinfo->flags.in_error_pkt
65 * to determine whether the packet should be handed to the listener, as, for
66 * a protocol with error report packets that include a copy of the
67 * packet in error (ICMP, ICMPv6, CLNP), that flag changes during the
68 * processing of the packet depending on whether we're currently dissecting
69 * the packet in error or not.
72 * It also means that a tap listener can't depend on the source and destination
73 * addresses being the correct ones for the packet being processed if, for
74 * example, you have some tunneling that causes multiple layers of the same
77 * For now, we handle the error packet flag by setting a bit in the flags
78 * field of the tap_packet_t structure. We may ultimately want stacks of
79 * addresses for this and other reasons.
81 typedef struct _tap_packet_t {
85 const void *tap_specific_data;
88 #define TAP_PACKET_IS_ERROR_PACKET 0x00000001 /* packet being queued is an error packet */
90 #define TAP_PACKET_QUEUE_LEN 5000
91 static tap_packet_t tap_packet_array[TAP_PACKET_QUEUE_LEN];
92 static guint tap_packet_index;
94 typedef struct _tap_listener_t {
95 volatile struct _tap_listener_t *next;
97 gboolean needs_redraw;
103 tap_packet_cb packet;
106 static volatile tap_listener_t *tap_listener_queue=NULL;
112 #include <wsutil/plugins.h>
115 * List of tap plugins.
118 void (*register_tap_listener_fn)(void); /* routine to call to register tap listener */
121 static GSList *tap_plugins = NULL;
124 * Callback for each plugin found.
127 check_for_tap_plugin(GModule *handle)
130 void (*register_tap_listener_fn)(void);
134 * Do we have a register_tap_listener routine?
136 if (!g_module_symbol(handle, "plugin_register_tap_listener", &gp)) {
137 /* No, so this isn't a tap plugin. */
142 * Yes - this plugin includes one or more taps.
145 register_tap_listener_fn = (void (*)(void))gp;
149 * Add this one to the list of tap plugins.
151 plugin = (tap_plugin *)g_malloc(sizeof (tap_plugin));
152 plugin->register_tap_listener_fn = register_tap_listener_fn;
153 tap_plugins = g_slist_append(tap_plugins, plugin);
158 register_tap_plugin_type(void)
160 add_plugin_type("tap", check_for_tap_plugin);
164 register_tap_plugin_listener(gpointer data, gpointer user_data _U_)
166 tap_plugin *plugin = (tap_plugin *)data;
168 (plugin->register_tap_listener_fn)();
172 * For all tap plugins, call their register routines.
175 register_all_plugin_tap_listeners(void)
177 g_slist_foreach(tap_plugins, register_tap_plugin_listener, NULL);
179 #endif /* HAVE_PLUGINS */
181 /* **********************************************************************
182 * Init routine only called from epan at application startup
183 * ********************************************************************** */
184 /* This function is called once when wireshark starts up and is used
185 to init any data structures we may need later.
193 /* **********************************************************************
194 * Functions called from dissector when made tappable
195 * ********************************************************************** */
196 /* the following two functions are used from dissectors to
197 1. register the ability to tap packets from this subdissector
198 2. push packets encountered by the subdissector to anyone tapping
201 /* This function registers that a dissector has the packet tap ability
202 available. The name parameter is the name of this tap and extensions can
203 use open_tap(char *name,... to specify that it wants to receive packets/
204 events from this tap.
206 This function is only to be called once, when the dissector initializes.
208 The return value from this call is later used as a parameter to the
209 tap_packet(unsigned int *tap_id,...
210 call so that the tap subsystem knows to which tap point this tapped
211 packet is associated.
214 register_tap(const char *name)
216 tap_dissector_t *td, *tdl;
219 if(tap_dissector_list){
220 tap_id=find_tap_id(name);
225 td=(tap_dissector_t *)g_malloc(sizeof(tap_dissector_t));
227 td->name = g_strdup(name);
229 if(!tap_dissector_list){
230 tap_dissector_list=td;
233 for(i=2,tdl=tap_dissector_list;tdl->next;i++,tdl=tdl->next)
241 /* Everytime the dissector has finished dissecting a packet (and all
242 subdissectors have returned) and if the dissector has been made "tappable"
243 it will push some data to everyone tapping this layer by a call
244 to tap_queue_packet().
245 The first parameter is the tap_id returned by the register_tap()
246 call for this dissector (so the tap system can keep track of who it came
247 from and who is listening to it)
248 The second is the packet_info structure which many tap readers will find
250 The third argument is specific to each tap point or NULL if no additional
251 data is available to this tap. A tap point in say IP will probably want to
252 push the IP header structure here. Same thing for TCP and ONCRPC.
254 The pinfo and the specific pointer are what is supplied to every listener
255 in the read_callback() call made to every one currently listening to this
258 The tap reader is responsible to know how to parse any structure pointed
259 to by the tap specific data pointer.
262 tap_queue_packet(int tap_id, packet_info *pinfo, const void *tap_specific_data)
266 if(!tapping_is_active){
270 * XXX - should we allocate this with an ep_allocator,
271 * rather than having a fixed maximum number of entries?
273 if(tap_packet_index >= TAP_PACKET_QUEUE_LEN){
274 g_warning("Too many taps queued");
278 tpt=&tap_packet_array[tap_packet_index];
281 if (pinfo->flags.in_error_pkt)
282 tpt->flags |= TAP_PACKET_IS_ERROR_PACKET;
284 tpt->tap_specific_data=tap_specific_data;
292 /* **********************************************************************
293 * Functions used by file.c to drive the tap subsystem
294 * ********************************************************************** */
296 void tap_build_interesting (epan_dissect_t *edt)
298 volatile tap_listener_t *tl;
300 /* nothing to do, just return */
301 if(!tap_listener_queue){
305 /* loop over all tap listeners and build the list of all
306 interesting hf_fields */
307 for(tl=tap_listener_queue;tl;tl=tl->next){
309 epan_dissect_prime_dfilter(edt, tl->code);
314 /* This function is used to delete/initialize the tap queue and prime an
315 epan_dissect_t with all the filters for tap listeners.
316 To free the tap queue, we just prepend the used queue to the free queue.
319 tap_queue_init(epan_dissect_t *edt)
321 /* nothing to do, just return */
322 if(!tap_listener_queue){
326 tapping_is_active=TRUE;
330 tap_build_interesting (edt);
333 /* this function is called after a packet has been fully dissected to push the tapped
334 data to all extensions that has callbacks registered.
337 tap_push_tapped_queue(epan_dissect_t *edt)
340 volatile tap_listener_t *tl;
343 /* nothing to do, just return */
344 if(!tapping_is_active){
348 tapping_is_active=FALSE;
350 /* nothing to do, just return */
351 if(!tap_packet_index){
355 /* loop over all tap listeners and call the listener callback
356 for all packets that match the filter. */
357 for(i=0;i<tap_packet_index;i++){
358 for(tl=tap_listener_queue;tl;tl=tl->next){
359 tp=&tap_packet_array[i];
360 /* Don't tap the packet if it's an "error" unless the listener tells us to */
361 if (!(tp->flags & TAP_PACKET_IS_ERROR_PACKET) || (tl->flags & TL_REQUIRES_ERROR_PACKETS))
363 if(tp->tap_id==tl->tap_id){
364 gboolean passed=TRUE;
366 passed=dfilter_apply_edt(tl->code, edt);
368 if(passed && tl->packet){
369 tl->needs_redraw|=tl->packet(tl->tapdata, tp->pinfo, edt, tp->tap_specific_data);
378 /* This function can be used by a dissector to fetch any tapped data before
380 * This can be useful if one wants to extract the data inside dissector BEFORE
381 * it exists as an alternative to the callbacks that are all called AFTER the
382 * dissection has completed.
384 * Example: SMB2 uses this mechanism to extract the data tapped from NTLMSSP
385 * containing the account and domain names before exiting.
386 * Note that the SMB2 tap listener specifies all three callbacks as NULL.
388 * Beware: when using this mechanism to extract the tapped data you can not
389 * use "filters" and should specify the "filter" as NULL when registering
393 fetch_tapped_data(int tap_id, int idx)
398 /* nothing to do, just return */
399 if(!tapping_is_active){
403 /* nothing to do, just return */
404 if(!tap_packet_index){
408 /* loop over all tapped packets and return the one with index idx */
409 for(i=0;i<tap_packet_index;i++){
410 tp=&tap_packet_array[i];
411 if(tp->tap_id==tap_id){
413 return tp->tap_specific_data;
421 /* This function is called when we need to reset all tap listeners, for example
422 when we open/start a new capture or if we need to rescan the packet list.
425 reset_tap_listeners(void)
427 volatile tap_listener_t *tl;
429 for(tl=tap_listener_queue;tl;tl=tl->next){
431 tl->reset(tl->tapdata);
433 tl->needs_redraw=TRUE;
439 /* This function is called when we need to redraw all tap listeners, for example
440 when we open/start a new capture or if we need to rescan the packet list.
441 It should be called from a low priority thread say once every 3 seconds
443 If draw_all is true, redraw all aplications regardless if they have
447 draw_tap_listeners(gboolean draw_all)
449 volatile tap_listener_t *tl;
451 for(tl=tap_listener_queue;tl;tl=tl->next){
452 if(tl->needs_redraw || draw_all){
454 tl->draw(tl->tapdata);
457 tl->needs_redraw=FALSE;
461 /* Gets a GList of the tap names. The content of the list
462 is owned by the tap table and should not be modified or freed.
463 Use g_list_free() when done using the list. */
470 for(td=tap_dissector_list; td; td=td->next) {
471 list = g_list_prepend(list, td->name);
474 return g_list_reverse(list);
477 /* **********************************************************************
478 * Functions used by tap to
479 * 1. register that a really simple extension is available for use by
481 * 2. start tapping from a subdissector
482 * 3. close an already open tap
483 * ********************************************************************** */
484 /* this function will return the tap_id for the specific protocol tap
485 or 0 if no such tap was found.
488 find_tap_id(const char *name)
493 for(i=1,td=tap_dissector_list;td;i++,td=td->next) {
494 if(!strcmp(td->name,name)){
502 free_tap_listener(volatile tap_listener_t *tl)
507 dfilter_free(tl->code);
511 g_free((gpointer)tl);
515 /* this function attaches the tap_listener to the named tap.
518 * non-NULL: error, return value points to GString containing error
522 register_tap_listener(const char *tapname, void *tapdata, const char *fstring,
523 guint flags, tap_reset_cb reset, tap_packet_cb packet, tap_draw_cb draw)
525 volatile tap_listener_t *tl;
527 dfilter_t *code=NULL;
528 GString *error_string;
531 tap_id=find_tap_id(tapname);
533 error_string = g_string_new("");
534 g_string_printf(error_string, "Tap %s not found", tapname);
538 tl=(volatile tap_listener_t *)g_malloc0(sizeof(tap_listener_t));
539 tl->needs_redraw=TRUE;
542 if(!dfilter_compile(fstring, &code, &err_msg)){
543 error_string = g_string_new("");
544 g_string_printf(error_string,
545 "Filter \"%s\" is invalid - %s",
548 free_tap_listener(tl);
552 tl->fstring=g_strdup(fstring);
560 tl->next=tap_listener_queue;
562 tap_listener_queue=tl;
567 /* this function sets a new dfilter to a tap listener
570 set_tap_dfilter(void *tapdata, const char *fstring)
572 volatile tap_listener_t *tl=NULL,*tl2;
573 dfilter_t *code=NULL;
574 GString *error_string;
577 if(!tap_listener_queue){
581 if(tap_listener_queue->tapdata==tapdata){
582 tl=tap_listener_queue;
584 for(tl2=tap_listener_queue;tl2->next;tl2=tl2->next){
585 if(tl2->next->tapdata==tapdata){
595 dfilter_free(tl->code);
598 tl->needs_redraw=TRUE;
601 if(!dfilter_compile(fstring, &code, &err_msg)){
603 error_string = g_string_new("");
604 g_string_printf(error_string,
605 "Filter \"%s\" is invalid - %s",
611 tl->fstring=g_strdup(fstring);
618 /* this function recompiles dfilter for all registered tap listeners
621 tap_listeners_dfilter_recompile(void)
623 volatile tap_listener_t *tl;
627 for(tl=tap_listener_queue;tl;tl=tl->next){
629 dfilter_free(tl->code);
632 tl->needs_redraw=TRUE;
635 if(!dfilter_compile(tl->fstring, &code, &err_msg)){
637 /* Not valid, make a dfilter matching no packets */
638 dfilter_compile("frame.number == 0", &code, &err_msg);
645 /* this function removes a tap listener
648 remove_tap_listener(void *tapdata)
650 volatile tap_listener_t *tl=NULL,*tl2;
652 if(!tap_listener_queue){
656 if(tap_listener_queue->tapdata==tapdata){
657 tl=tap_listener_queue;
658 tap_listener_queue=tap_listener_queue->next;
660 for(tl2=tap_listener_queue;tl2->next;tl2=tl2->next){
661 if(tl2->next->tapdata==tapdata){
663 tl2->next=tl2->next->next;
669 free_tap_listener(tl);
673 * Return TRUE if we have one or more tap listeners that require dissection,
677 tap_listeners_require_dissection(void)
679 volatile tap_listener_t *tap_queue = tap_listener_queue;
682 if(!(tap_queue->flags & TL_IS_DISSECTOR_HELPER))
685 tap_queue = tap_queue->next;
692 /* Returns TRUE there is an active tap listener for the specified tap id. */
694 have_tap_listener(int tap_id)
696 volatile tap_listener_t *tap_queue = tap_listener_queue;
699 if(tap_queue->tap_id == tap_id)
702 tap_queue = tap_queue->next;
709 * Return TRUE if we have any tap listeners with filters, FALSE otherwise.
712 have_filtering_tap_listeners(void)
714 volatile tap_listener_t *tl;
716 for(tl=tap_listener_queue;tl;tl=tl->next){
724 * Get the union of all the flags for all the tap listeners; that gives
725 * an indication of whether the protocol tree, or the columns, are
726 * required by any taps.
729 union_of_tap_listener_flags(void)
731 volatile tap_listener_t *tl;
734 for(tl=tap_listener_queue;tl;tl=tl->next){
741 * Editor modelines - http://www.wireshark.org/tools/modelines.html
746 * indent-tabs-mode: t
749 * vi: set shiftwidth=8 tabstop=8 noexpandtab:
750 * :indentSize=8:tabSize=8:noTabs=false: