dcerpc-netlogon: improve NetrLogonGetCapabilities dissection
[wireshark-sm.git] / epan / tap.c
blob83f2efe54f851adb18482a6b44d1ad1a86bd771e
1 /* tap.c
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
9 */
11 #include <config.h>
12 #define WS_LOG_DOMAIN LOG_DOMAIN_EPAN
14 #include <stdio.h>
16 #include <sys/types.h>
18 #ifdef HAVE_NETINET_IN_H
19 # include <netinet/in.h>
20 #endif
22 #include <string.h>
24 #include <glib.h>
26 #include <epan/packet_info.h>
27 #include <epan/dfilter/dfilter.h>
28 #include <epan/tap.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;
35 char *name;
36 } tap_dissector_t;
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
62 * protocol.
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 {
69 int tap_id;
70 uint32_t flags;
71 packet_info *pinfo;
72 const void *tap_specific_data;
73 } tap_packet_t;
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;
83 int tap_id;
84 bool needs_redraw;
85 bool failed;
86 unsigned flags;
87 char *fstring;
88 dfilter_t *code;
89 void *tapdata;
90 tap_reset_cb reset;
91 tap_packet_cb packet;
92 tap_draw_cb draw;
93 tap_finish_cb finish;
94 } tap_listener_t;
96 static tap_listener_t *tap_listener_queue;
98 static GSList *tap_plugins;
100 #ifdef HAVE_PLUGINS
101 void
102 tap_register_plugin(const tap_plugin *plug)
104 tap_plugins = g_slist_prepend(tap_plugins, (tap_plugin *)plug);
106 #else /* HAVE_PLUGINS */
107 void
108 tap_register_plugin(const tap_plugin *plug _U_)
110 ws_warning("built without support for binary plugins");
112 #endif /* HAVE_PLUGINS */
114 static void
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.
130 void
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++) {
140 t->cb_func();
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.
150 void
151 tap_init(void)
153 tap_packet_index=0;
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;
180 int i=0;
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)) {
188 return i;
191 tdl = tdl_prev;
194 td=g_new(tap_dissector_t, 1);
195 td->next=NULL;
196 td->name = g_strdup(name);
198 if(!tap_dissector_list){
199 tap_dissector_list=td;
200 i=1;
201 } else {
202 tdl->next=td;
204 return i;
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
216 interesting.
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
223 tap.
225 The tap reader is responsible to know how to parse any structure pointed
226 to by the tap specific data pointer.
228 void
229 tap_queue_packet(int tap_id, packet_info *pinfo, const void *tap_specific_data)
231 tap_packet_t *tpt;
233 if(!tapping_is_active){
234 return;
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");
242 return;
245 tpt=&tap_packet_array[tap_packet_index];
246 tpt->tap_id=tap_id;
247 tpt->flags = 0;
248 if (pinfo->flags.in_error_pkt)
249 tpt->flags |= TAP_PACKET_IS_ERROR_PACKET;
250 tpt->pinfo=pinfo;
251 tpt->tap_specific_data=tap_specific_data;
252 tap_packet_index++;
259 /* **********************************************************************
260 * Functions used by file.c to drive the tap subsystem
261 * ********************************************************************** */
263 void tap_build_interesting (epan_dissect_t *edt)
265 tap_listener_t *tl;
266 bool need_protocols = false;
268 /* nothing to do, just return */
269 if(!tap_listener_queue){
270 return;
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){
276 if(tl->code){
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.
292 void
293 tap_queue_init(epan_dissect_t *edt)
295 /* nothing to do, just return */
296 if(!tap_listener_queue){
297 return;
300 tapping_is_active=true;
302 tap_packet_index=0;
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.
310 void
311 tap_push_tapped_queue(epan_dissect_t *edt)
313 tap_packet_t *tp;
314 tap_listener_t *tl;
315 unsigned i;
317 /* nothing to do, just return */
318 if(!tapping_is_active){
319 return;
322 tapping_is_active=false;
324 /* nothing to do, just return */
325 if(!tap_packet_index){
326 return;
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){
340 if(!tl->packet){
341 /* There isn't a per-packet
342 * routine for this tap.
344 continue;
346 if(tl->failed){
347 /* A previous call failed,
348 * meaning "stop running this
349 * tap", so don't call the
350 * packet routine.
352 continue;
355 /* If we have a filter, see if the
356 * packet passes.
358 unsigned flags = tl->flags;
359 if(tl->code){
360 if (!dfilter_apply_edt(tl->code, edt)){
361 /* The packet didn't
362 * pass the filter. */
363 if (tl->flags & TL_IGNORE_DISPLAY_FILTER)
364 flags |= TL_DISPLAY_FILTER_IGNORED;
365 else
366 continue;
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);
375 switch (status) {
377 case TAP_PACKET_DONT_REDRAW:
378 break;
380 case TAP_PACKET_REDRAW:
381 tl->needs_redraw=true;
382 break;
384 case TAP_PACKET_FAILED:
385 tl->failed=true;
386 break;
395 /* This function can be used by a dissector to fetch any tapped data before
396 * returning.
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
407 * the tap listener.
409 const void *
410 fetch_tapped_data(int tap_id, int idx)
412 tap_packet_t *tp;
413 unsigned i;
415 /* nothing to do, just return */
416 if(!tapping_is_active){
417 return NULL;
420 /* nothing to do, just return */
421 if(!tap_packet_index){
422 return NULL;
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){
429 if(!idx--){
430 return tp->tap_specific_data;
435 return NULL;
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.
441 void
442 reset_tap_listeners(void)
444 tap_listener_t *tl;
446 for(tl=tap_listener_queue;tl;tl=tl->next){
447 if(tl->reset){
448 tl->reset(tl->tapdata);
450 tl->needs_redraw=true;
451 tl->failed=false;
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
462 changed or not.
464 void
465 draw_tap_listeners(bool draw_all)
467 tap_listener_t *tl;
469 for(tl=tap_listener_queue;tl;tl=tl->next){
470 if(tl->needs_redraw || draw_all){
471 if(tl->draw){
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. */
482 GList*
483 get_tap_names(void)
485 GList *list = NULL;
486 tap_dissector_t *td;
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
498 * Wireshark.
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)
508 tap_dissector_t *td;
509 int i;
511 for(i=1,td=tap_dissector_list;td;i++,td=td->next) {
512 if(!strcmp(td->name,name)){
513 return i;
516 return 0;
519 static void
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.
528 if (tl->finish) {
529 tl->finish(tl->tapdata);
531 dfilter_free(tl->code);
532 g_free(tl->fstring);
533 g_free(tl);
536 /* this function attaches the tap_listener to the named tap.
537 * function returns :
538 * NULL: ok.
539 * non-NULL: error, return value points to GString containing error
540 * message.
542 GString *
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)
547 tap_listener_t *tl;
548 int tap_id;
549 dfilter_t *code=NULL;
550 GString *error_string;
551 df_error_t *df_err;
553 tap_id=find_tap_id(tapname);
554 if(!tap_id){
555 error_string = g_string_new("");
556 g_string_printf(error_string, "Tap %s not found", tapname);
557 return error_string;
560 tl=g_new0(tap_listener_t, 1);
561 tl->needs_redraw=true;
562 tl->failed=false;
563 if (flags & TL_REQUIRES_PROTOCOLS) {
564 /* Requiring protocols implies needing a protocol tree.
565 * XXX - Warn?
567 flags |= TL_REQUIRES_PROTO_TREE;
569 tl->flags=flags;
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);
578 return error_string;
580 tl->fstring=g_strdup(fstring);
581 tl->code=code;
584 tl->tap_id=tap_id;
585 tl->tapdata=tapdata;
586 tl->reset=reset;
587 tl->packet=packet;
588 tl->draw=draw;
589 tl->finish=finish;
590 tl->next=tap_listener_queue;
592 tap_listener_queue=tl;
594 return NULL;
597 /* this function sets a new dfilter to a tap listener
599 GString *
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;
605 df_error_t *df_err;
607 if(!tap_listener_queue){
608 return NULL;
611 if(tap_listener_queue->tapdata==tapdata){
612 tl=tap_listener_queue;
613 } else {
614 for(tl2=tap_listener_queue;tl2->next;tl2=tl2->next){
615 if(tl2->next->tapdata==tapdata){
616 tl=tl2->next;
617 break;
623 if(tl){
624 if(tl->code){
625 dfilter_free(tl->code);
626 tl->code=NULL;
628 tl->needs_redraw=true;
629 g_free(tl->fstring);
630 if(fstring){
631 if(!dfilter_compile(fstring, &code, &df_err)){
632 tl->fstring=NULL;
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);
638 return error_string;
641 tl->fstring=g_strdup(fstring);
642 tl->code=code;
645 return NULL;
648 GString *
649 set_tap_flags(void *tapdata, unsigned flags)
651 tap_listener_t *tl=NULL,*tl2;
653 if(!tap_listener_queue){
654 return NULL;
657 if(tap_listener_queue->tapdata==tapdata){
658 tl=tap_listener_queue;
659 } else {
660 for(tl2=tap_listener_queue;tl2->next;tl2=tl2->next){
661 if(tl2->next->tapdata==tapdata){
662 tl=tl2->next;
663 break;
669 if(tl){
670 tl->needs_redraw=true;
671 tl->flags=flags;
674 return NULL;
677 /* this function recompiles dfilter for all registered tap listeners
679 void
680 tap_listeners_dfilter_recompile(void)
682 tap_listener_t *tl;
683 dfilter_t *code;
685 for(tl=tap_listener_queue;tl;tl=tl->next){
686 if(tl->code){
687 dfilter_free(tl->code);
688 tl->code=NULL;
690 tl->needs_redraw=true;
691 code=NULL;
692 if(tl->fstring){
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);
698 tl->code=code;
702 /* this function removes a tap listener
704 void
705 remove_tap_listener(void *tapdata)
707 tap_listener_t *tl=NULL,*tl2;
709 if(!tap_listener_queue){
710 return;
713 if(tap_listener_queue->tapdata==tapdata){
714 tl=tap_listener_queue;
715 tap_listener_queue=tap_listener_queue->next;
716 } else {
717 for(tl2=tap_listener_queue;tl2->next;tl2=tl2->next){
718 if(tl2->next->tapdata==tapdata){
719 tl=tl2->next;
720 tl2->next=tl2->next->next;
721 break;
725 if(!tl) {
726 ws_warning("no listener found with that tap data");
727 return;
730 free_tap_listener(tl);
734 * Return true if we have one or more tap listeners that require dissection,
735 * false otherwise.
737 bool
738 tap_listeners_require_dissection(void)
740 tap_listener_t *tap_queue = tap_listener_queue;
742 while(tap_queue) {
743 if(!(tap_queue->flags & TL_IS_DISSECTOR_HELPER))
744 return true;
746 tap_queue = tap_queue->next;
749 return false;
754 * Return true if we have one or more tap listeners that require the columns,
755 * false otherwise.
757 bool
758 tap_listeners_require_columns(void)
760 tap_listener_t *tap_queue = tap_listener_queue;
762 while(tap_queue) {
763 if(tap_queue->flags & TL_REQUIRES_COLUMNS)
764 return true;
766 if(dfilter_requires_columns(tap_queue->code))
767 return true;
769 tap_queue = tap_queue->next;
772 return false;
776 /* Returns true there is an active tap listener for the specified tap id. */
777 bool
778 have_tap_listener(int tap_id)
780 tap_listener_t *tap_queue = tap_listener_queue;
782 while(tap_queue) {
783 if(tap_queue->tap_id == tap_id)
784 return true;
786 tap_queue = tap_queue->next;
789 return false;
793 * Return true if we have any tap listeners with filters, false otherwise.
795 bool
796 have_filtering_tap_listeners(void)
798 tap_listener_t *tl;
800 for(tl=tap_listener_queue;tl;tl=tl->next){
801 if(tl->code)
802 return true;
804 return false;
807 void
808 tap_listeners_load_field_references(epan_dissect_t *edt)
810 tap_listener_t *tl;
812 for(tl=tap_listener_queue;tl;tl=tl->next){
813 if(tl->code)
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.
823 unsigned
824 union_of_tap_listener_flags(void)
826 tap_listener_t *tl;
827 unsigned flags = 0;
829 for(tl=tap_listener_queue;tl;tl=tl->next){
830 flags|=tl->flags;
832 return flags;
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;
842 while(head_lq){
843 elem_lq = head_lq;
844 head_lq = head_lq->next;
845 free_tap_listener(elem_lq);
847 tap_listener_queue = NULL;
849 while(head_dl){
850 elem_dl = head_dl;
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);
858 tap_plugins = NULL;
862 * Editor modelines - https://www.wireshark.org/tools/modelines.html
864 * Local variables:
865 * c-basic-offset: 8
866 * tab-width: 8
867 * indent-tabs-mode: t
868 * End:
870 * vi: set shiftwidth=8 tabstop=8 noexpandtab:
871 * :indentSize=8:tabSize=8:noTabs=false: