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 * SPDX-License-Identifier: GPL-2.0-or-later
12 #define WS_LOG_DOMAIN LOG_DOMAIN_EPAN
16 #include <sys/types.h>
18 #ifdef HAVE_NETINET_IN_H
19 # include <netinet/in.h>
26 #include <epan/packet_info.h>
27 #include <epan/dfilter/dfilter.h>
29 #include <wsutil/wslog.h>
31 static bool tapping_is_active
=false;
33 typedef struct _tap_dissector_t
{
34 struct _tap_dissector_t
*next
;
37 static tap_dissector_t
*tap_dissector_list
;
40 * This is the list of free and used packets queued for a tap.
41 * It is implemented here explicitly instead of using GLib objects
42 * in order to be as fast as possible as we need to build and tear down the
43 * queued list at least once for each packet we see and thus we must be able
44 * to build and tear it down as fast as possible.
46 * XXX - some fields in packet_info get overwritten in the dissection
47 * process, such as the addresses and the "this is an error packet" flag.
48 * A packet may be queued at multiple protocol layers, but the packet_info
49 * structure will, when the tap listeners are run, contain the values as
50 * set by the topmost protocol layers.
52 * This means that the tap listener code can't rely on pinfo->flags.in_error_pkt
53 * to determine whether the packet should be handed to the listener, as, for
54 * a protocol with error report packets that include a copy of the
55 * packet in error (ICMP, ICMPv6, CLNP), that flag changes during the
56 * processing of the packet depending on whether we're currently dissecting
57 * the packet in error or not.
59 * It also means that a tap listener can't depend on the source and destination
60 * addresses being the correct ones for the packet being processed if, for
61 * example, you have some tunneling that causes multiple layers of the same
64 * For now, we handle the error packet flag by setting a bit in the flags
65 * field of the tap_packet_t structure. We may ultimately want stacks of
66 * addresses for this and other reasons.
68 typedef struct _tap_packet_t
{
72 const void *tap_specific_data
;
75 #define TAP_PACKET_IS_ERROR_PACKET 0x00000001 /* packet being queued is an error packet */
77 #define TAP_PACKET_QUEUE_LEN 5000
78 static tap_packet_t tap_packet_array
[TAP_PACKET_QUEUE_LEN
];
79 static unsigned tap_packet_index
;
81 typedef struct _tap_listener_t
{
82 struct _tap_listener_t
*next
;
96 static tap_listener_t
*tap_listener_queue
;
98 static GSList
*tap_plugins
;
102 tap_register_plugin(const tap_plugin
*plug
)
104 tap_plugins
= g_slist_prepend(tap_plugins
, (tap_plugin
*)plug
);
106 #else /* HAVE_PLUGINS */
108 tap_register_plugin(const tap_plugin
*plug _U_
)
110 ws_warning("built without support for binary plugins");
112 #endif /* HAVE_PLUGINS */
115 call_plugin_register_tap_listener(void *data
, void *user_data _U_
)
117 tap_plugin
*plug
= (tap_plugin
*)data
;
119 if (plug
->register_tap_listener
) {
120 plug
->register_tap_listener();
125 * For all taps, call their register routines.
127 * The table of register routines is part of the main program, not
128 * part of libwireshark, so it must be passed to us as an argument.
131 register_all_tap_listeners(tap_reg_t
const *tap_reg_listeners
)
133 /* we register the plugin taps before the other taps because
134 * stats_tree taps plugins will be registered as tap listeners
135 * by stats_tree_stat.c and need to registered before that */
136 g_slist_foreach(tap_plugins
, call_plugin_register_tap_listener
, NULL
);
138 /* Register all builtin listeners. */
139 for (tap_reg_t
const *t
= &tap_reg_listeners
[0]; t
->cb_func
!= NULL
; t
++) {
144 /* **********************************************************************
145 * Init routine only called from epan at application startup
146 * ********************************************************************** */
147 /* This function is called once when wireshark starts up and is used
148 to init any data structures we may need later.
156 /* **********************************************************************
157 * Functions called from dissector when made tappable
158 * ********************************************************************** */
159 /* the following two functions are used from dissectors to
160 1. register the ability to tap packets from this subdissector
161 2. push packets encountered by the subdissector to anyone tapping
164 /* This function registers that a dissector has the packet tap ability
165 available. The name parameter is the name of this tap and extensions can
166 use open_tap(char *name,... to specify that it wants to receive packets/
167 events from this tap.
169 This function is only to be called once, when the dissector initializes.
171 The return value from this call is later used as a parameter to the
172 tap_packet(unsigned int *tap_id,...
173 call so that the tap subsystem knows to which tap point this tapped
174 packet is associated.
177 register_tap(const char *name
)
179 tap_dissector_t
*td
, *tdl
= NULL
, *tdl_prev
= NULL
;
182 if(tap_dissector_list
){
183 /* Check if we already have the name registered, if it is return the tap_id of that tap.
184 * After the for loop tdl_prev will point to the last element of the list, add the new one there.
186 for (i
= 1, tdl
= tap_dissector_list
; tdl
; i
++, tdl_prev
= tdl
, tdl
= tdl
->next
) {
187 if (!strcmp(tdl
->name
, name
)) {
194 td
=g_new(tap_dissector_t
, 1);
196 td
->name
= g_strdup(name
);
198 if(!tap_dissector_list
){
199 tap_dissector_list
=td
;
208 /* Every time the dissector has finished dissecting a packet (and all
209 subdissectors have returned) and if the dissector has been made "tappable"
210 it will push some data to everyone tapping this layer by a call
211 to tap_queue_packet().
212 The first parameter is the tap_id returned by the register_tap()
213 call for this dissector (so the tap system can keep track of who it came
214 from and who is listening to it)
215 The second is the packet_info structure which many tap readers will find
217 The third argument is specific to each tap point or NULL if no additional
218 data is available to this tap. A tap point in say IP will probably want to
219 push the IP header structure here. Same thing for TCP and ONCRPC.
221 The pinfo and the specific pointer are what is supplied to every listener
222 in the read_callback() call made to every one currently listening to this
225 The tap reader is responsible to know how to parse any structure pointed
226 to by the tap specific data pointer.
229 tap_queue_packet(int tap_id
, packet_info
*pinfo
, const void *tap_specific_data
)
233 if(!tapping_is_active
){
237 * XXX - should we allocate this with an ep_allocator,
238 * rather than having a fixed maximum number of entries?
240 if(tap_packet_index
>= TAP_PACKET_QUEUE_LEN
){
241 ws_warning("Too many taps queued");
245 tpt
=&tap_packet_array
[tap_packet_index
];
248 if (pinfo
->flags
.in_error_pkt
)
249 tpt
->flags
|= TAP_PACKET_IS_ERROR_PACKET
;
251 tpt
->tap_specific_data
=tap_specific_data
;
259 /* **********************************************************************
260 * Functions used by file.c to drive the tap subsystem
261 * ********************************************************************** */
263 void tap_build_interesting (epan_dissect_t
*edt
)
266 bool need_protocols
= false;
268 /* nothing to do, just return */
269 if(!tap_listener_queue
){
273 /* loop over all tap listeners and build the list of all
274 interesting hf_fields */
275 for(tl
=tap_listener_queue
;tl
;tl
=tl
->next
){
277 epan_dissect_prime_with_dfilter(edt
, tl
->code
);
279 if(tl
->flags
& TL_REQUIRES_PROTOCOLS
){
280 need_protocols
= true;
283 if (need_protocols
) {
284 epan_dissect_fake_protocols(edt
, false);
288 /* This function is used to delete/initialize the tap queue and prime an
289 epan_dissect_t with all the filters for tap listeners.
290 To free the tap queue, we just prepend the used queue to the free queue.
293 tap_queue_init(epan_dissect_t
*edt
)
295 /* nothing to do, just return */
296 if(!tap_listener_queue
){
300 tapping_is_active
=true;
304 tap_build_interesting (edt
);
307 /* this function is called after a packet has been fully dissected to push the tapped
308 data to all extensions that has callbacks registered.
311 tap_push_tapped_queue(epan_dissect_t
*edt
)
317 /* nothing to do, just return */
318 if(!tapping_is_active
){
322 tapping_is_active
=false;
324 /* nothing to do, just return */
325 if(!tap_packet_index
){
329 /* loop over all tap listeners and call the listener callback
330 for all packets that match the filter. */
331 for(i
=0;i
<tap_packet_index
;i
++){
332 for(tl
=tap_listener_queue
;tl
;tl
=tl
->next
){
333 tp
=&tap_packet_array
[i
];
334 /* Don't tap the packet if it's an "error packet"
335 * unless the listener has requested that we do so.
337 if (!(tp
->flags
& TAP_PACKET_IS_ERROR_PACKET
) || (tl
->flags
& TL_REQUIRES_ERROR_PACKETS
))
339 if(tp
->tap_id
==tl
->tap_id
){
341 /* There isn't a per-packet
342 * routine for this tap.
347 /* A previous call failed,
348 * meaning "stop running this
349 * tap", so don't call the
355 /* If we have a filter, see if the
358 unsigned flags
= tl
->flags
;
360 if (!dfilter_apply_edt(tl
->code
, edt
)){
362 * pass the filter. */
363 if (tl
->flags
& TL_IGNORE_DISPLAY_FILTER
)
364 flags
|= TL_DISPLAY_FILTER_IGNORED
;
370 /* So call the per-packet routine. */
371 tap_packet_status status
;
373 status
= tl
->packet(tl
->tapdata
, tp
->pinfo
, edt
, tp
->tap_specific_data
, flags
);
377 case TAP_PACKET_DONT_REDRAW
:
380 case TAP_PACKET_REDRAW
:
381 tl
->needs_redraw
=true;
384 case TAP_PACKET_FAILED
:
395 /* This function can be used by a dissector to fetch any tapped data before
397 * This can be useful if one wants to extract the data inside dissector BEFORE
398 * it exists as an alternative to the callbacks that are all called AFTER the
399 * dissection has completed.
401 * Example: SMB2 uses this mechanism to extract the data tapped from NTLMSSP
402 * containing the account and domain names before exiting.
403 * Note that the SMB2 tap listener specifies all three callbacks as NULL.
405 * Beware: when using this mechanism to extract the tapped data you can not
406 * use "filters" and should specify the "filter" as NULL when registering
410 fetch_tapped_data(int tap_id
, int idx
)
415 /* nothing to do, just return */
416 if(!tapping_is_active
){
420 /* nothing to do, just return */
421 if(!tap_packet_index
){
425 /* loop over all tapped packets and return the one with index idx */
426 for(i
=0;i
<tap_packet_index
;i
++){
427 tp
=&tap_packet_array
[i
];
428 if(tp
->tap_id
==tap_id
){
430 return tp
->tap_specific_data
;
438 /* This function is called when we need to reset all tap listeners, for example
439 when we open/start a new capture or if we need to rescan the packet list.
442 reset_tap_listeners(void)
446 for(tl
=tap_listener_queue
;tl
;tl
=tl
->next
){
448 tl
->reset(tl
->tapdata
);
450 tl
->needs_redraw
=true;
457 /* This function is called when we need to redraw all tap listeners, for example
458 when we open/start a new capture or if we need to rescan the packet list.
459 It should be called from a low priority thread say once every 3 seconds
461 If draw_all is true, redraw all applications regardless if they have
465 draw_tap_listeners(bool draw_all
)
469 for(tl
=tap_listener_queue
;tl
;tl
=tl
->next
){
470 if(tl
->needs_redraw
|| draw_all
){
472 tl
->draw(tl
->tapdata
);
475 tl
->needs_redraw
=false;
479 /* Gets a GList of the tap names. The content of the list
480 is owned by the tap table and should not be modified or freed.
481 Use g_list_free() when done using the list. */
488 for(td
=tap_dissector_list
; td
; td
=td
->next
) {
489 list
= g_list_prepend(list
, td
->name
);
492 return g_list_reverse(list
);
495 /* **********************************************************************
496 * Functions used by tap to
497 * 1. register that a really simple extension is available for use by
499 * 2. start tapping from a subdissector
500 * 3. close an already open tap
501 * ********************************************************************** */
502 /* this function will return the tap_id for the specific protocol tap
503 or 0 if no such tap was found.
506 find_tap_id(const char *name
)
511 for(i
=1,td
=tap_dissector_list
;td
;i
++,td
=td
->next
) {
512 if(!strcmp(td
->name
,name
)){
520 free_tap_listener(tap_listener_t
*tl
)
522 /* The free_tap_listener is called in the error path of
523 * register_tap_listener (when the dfilter fails to be registered)
524 * and the finish callback is set after that.
525 * If this is changed make sure the finish callback is not called
526 * twice to prevent double-free errors.
529 tl
->finish(tl
->tapdata
);
531 dfilter_free(tl
->code
);
536 /* this function attaches the tap_listener to the named tap.
539 * non-NULL: error, return value points to GString containing error
543 register_tap_listener(const char *tapname
, void *tapdata
, const char *fstring
,
544 unsigned flags
, tap_reset_cb reset
, tap_packet_cb packet
,
545 tap_draw_cb draw
, tap_finish_cb finish
)
549 dfilter_t
*code
=NULL
;
550 GString
*error_string
;
553 tap_id
=find_tap_id(tapname
);
555 error_string
= g_string_new("");
556 g_string_printf(error_string
, "Tap %s not found", tapname
);
560 tl
=g_new0(tap_listener_t
, 1);
561 tl
->needs_redraw
=true;
563 if (flags
& TL_REQUIRES_PROTOCOLS
) {
564 /* Requiring protocols implies needing a protocol tree.
567 flags
|= TL_REQUIRES_PROTO_TREE
;
570 if(fstring
&& *fstring
){
571 if(!dfilter_compile(fstring
, &code
, &df_err
)){
572 error_string
= g_string_new("");
573 g_string_printf(error_string
,
574 "Filter \"%s\" is invalid - %s",
575 fstring
, df_err
->msg
);
576 df_error_free(&df_err
);
577 free_tap_listener(tl
);
580 tl
->fstring
=g_strdup(fstring
);
590 tl
->next
=tap_listener_queue
;
592 tap_listener_queue
=tl
;
597 /* this function sets a new dfilter to a tap listener
600 set_tap_dfilter(void *tapdata
, const char *fstring
)
602 tap_listener_t
*tl
=NULL
,*tl2
;
603 dfilter_t
*code
=NULL
;
604 GString
*error_string
;
607 if(!tap_listener_queue
){
611 if(tap_listener_queue
->tapdata
==tapdata
){
612 tl
=tap_listener_queue
;
614 for(tl2
=tap_listener_queue
;tl2
->next
;tl2
=tl2
->next
){
615 if(tl2
->next
->tapdata
==tapdata
){
625 dfilter_free(tl
->code
);
628 tl
->needs_redraw
=true;
631 if(!dfilter_compile(fstring
, &code
, &df_err
)){
633 error_string
= g_string_new("");
634 g_string_printf(error_string
,
635 "Filter \"%s\" is invalid - %s",
636 fstring
, df_err
->msg
);
637 df_error_free(&df_err
);
641 tl
->fstring
=g_strdup(fstring
);
649 set_tap_flags(void *tapdata
, unsigned flags
)
651 tap_listener_t
*tl
=NULL
,*tl2
;
653 if(!tap_listener_queue
){
657 if(tap_listener_queue
->tapdata
==tapdata
){
658 tl
=tap_listener_queue
;
660 for(tl2
=tap_listener_queue
;tl2
->next
;tl2
=tl2
->next
){
661 if(tl2
->next
->tapdata
==tapdata
){
670 tl
->needs_redraw
=true;
677 /* this function recompiles dfilter for all registered tap listeners
680 tap_listeners_dfilter_recompile(void)
685 for(tl
=tap_listener_queue
;tl
;tl
=tl
->next
){
687 dfilter_free(tl
->code
);
690 tl
->needs_redraw
=true;
693 if(!dfilter_compile(tl
->fstring
, &code
, NULL
)){
694 /* Not valid, make a dfilter matching no packets */
695 dfilter_compile("frame.number == 0", &code
, NULL
);
702 /* this function removes a tap listener
705 remove_tap_listener(void *tapdata
)
707 tap_listener_t
*tl
=NULL
,*tl2
;
709 if(!tap_listener_queue
){
713 if(tap_listener_queue
->tapdata
==tapdata
){
714 tl
=tap_listener_queue
;
715 tap_listener_queue
=tap_listener_queue
->next
;
717 for(tl2
=tap_listener_queue
;tl2
->next
;tl2
=tl2
->next
){
718 if(tl2
->next
->tapdata
==tapdata
){
720 tl2
->next
=tl2
->next
->next
;
726 ws_warning("no listener found with that tap data");
730 free_tap_listener(tl
);
734 * Return true if we have one or more tap listeners that require dissection,
738 tap_listeners_require_dissection(void)
740 tap_listener_t
*tap_queue
= tap_listener_queue
;
743 if(!(tap_queue
->flags
& TL_IS_DISSECTOR_HELPER
))
746 tap_queue
= tap_queue
->next
;
754 * Return true if we have one or more tap listeners that require the columns,
758 tap_listeners_require_columns(void)
760 tap_listener_t
*tap_queue
= tap_listener_queue
;
763 if(tap_queue
->flags
& TL_REQUIRES_COLUMNS
)
766 if(dfilter_requires_columns(tap_queue
->code
))
769 tap_queue
= tap_queue
->next
;
776 /* Returns true there is an active tap listener for the specified tap id. */
778 have_tap_listener(int tap_id
)
780 tap_listener_t
*tap_queue
= tap_listener_queue
;
783 if(tap_queue
->tap_id
== tap_id
)
786 tap_queue
= tap_queue
->next
;
793 * Return true if we have any tap listeners with filters, false otherwise.
796 have_filtering_tap_listeners(void)
800 for(tl
=tap_listener_queue
;tl
;tl
=tl
->next
){
808 tap_listeners_load_field_references(epan_dissect_t
*edt
)
812 for(tl
=tap_listener_queue
;tl
;tl
=tl
->next
){
814 dfilter_load_field_references_edt(tl
->code
, edt
);
819 * Get the union of all the flags for all the tap listeners; that gives
820 * an indication of whether the protocol tree, or the columns, are
821 * required by any taps.
824 union_of_tap_listener_flags(void)
829 for(tl
=tap_listener_queue
;tl
;tl
=tl
->next
){
835 void tap_cleanup(void)
837 tap_listener_t
*elem_lq
;
838 tap_listener_t
*head_lq
= tap_listener_queue
;
839 tap_dissector_t
*elem_dl
;
840 tap_dissector_t
*head_dl
= tap_dissector_list
;
844 head_lq
= head_lq
->next
;
845 free_tap_listener(elem_lq
);
847 tap_listener_queue
= NULL
;
851 head_dl
= head_dl
->next
;
852 g_free(elem_dl
->name
);
853 g_free((void *)elem_dl
);
855 tap_dissector_list
= NULL
;
857 g_slist_free(tap_plugins
);
862 * Editor modelines - https://www.wireshark.org/tools/modelines.html
867 * indent-tabs-mode: t
870 * vi: set shiftwidth=8 tabstop=8 noexpandtab:
871 * :indentSize=8:tabSize=8:noTabs=false: