Avoid some Visual Studio Code Anaylzer warnings
[metze/wireshark/wip.git] / epan / tap.c
1 /* tap.c
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  * 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.
12  *
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.
17  *
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.
21  */
22
23 #include "config.h"
24
25 #include <stdio.h>
26
27 #ifdef HAVE_SYS_TYPES_H
28 # include <sys/types.h>
29 #endif
30
31 #ifdef HAVE_NETINET_IN_H
32 # include <netinet/in.h>
33 #endif
34
35 #include <string.h>
36 #include <epan/packet_info.h>
37 #include <epan/dfilter/dfilter.h>
38 #include <epan/tap.h>
39
40 static gboolean tapping_is_active=FALSE;
41
42 typedef struct _tap_dissector_t {
43         struct _tap_dissector_t *next;
44         char *name;
45 } tap_dissector_t;
46 static tap_dissector_t *tap_dissector_list=NULL;
47
48 /*
49  * This is the list of free and used packets queued for a tap.
50  * It is implemented here explicitly instead of using GLib objects
51  * in order to be as fast as possible as we need to build and tear down the
52  * queued list at least once for each packet we see and thus we must be able
53  * to build and tear it down as fast as possible.
54  *
55  * XXX - some fields in packet_info get overwritten in the dissection
56  * process, such as the addresses and the "this is an error packet" flag.
57  * A packet may be queued at multiple protocol layers, but the packet_info
58  * structure will, when the tap listeners are run, contain the values as
59  * set by the topmost protocol layers.
60  *
61  * This means that the tap listener code can't rely on pinfo->flags.in_error_pkt
62  * to determine whether the packet should be handed to the listener, as, for
63  * a protocol with error report packets that include a copy of the
64  * packet in error (ICMP, ICMPv6, CLNP), that flag changes during the
65  * processing of the packet depending on whether we're currently dissecting
66  * the packet in error or not.
67  *
68  *
69  * It also means that a tap listener can't depend on the source and destination
70  * addresses being the correct ones for the packet being processed if, for
71  * example, you have some tunneling that causes multiple layers of the same
72  * protocol.
73  *
74  * For now, we handle the error packet flag by setting a bit in the flags
75  * field of the tap_packet_t structure.  We may ultimately want stacks of
76  * addresses for this and other reasons.
77  */
78 typedef struct _tap_packet_t {
79         int tap_id;
80         guint32 flags;
81         packet_info *pinfo;
82         const void *tap_specific_data;
83 } tap_packet_t;
84
85 #define TAP_PACKET_IS_ERROR_PACKET      0x00000001      /* packet being queued is an error packet */
86
87 #define TAP_PACKET_QUEUE_LEN 5000
88 static tap_packet_t tap_packet_array[TAP_PACKET_QUEUE_LEN];
89 static guint tap_packet_index;
90
91 typedef struct _tap_listener_t {
92         struct _tap_listener_t *next;
93         int tap_id;
94         gboolean needs_redraw;
95         guint flags;
96         dfilter_t *code;
97         void *tapdata;
98         tap_reset_cb reset;
99         tap_packet_cb packet;
100         tap_draw_cb draw;
101 } tap_listener_t;
102 static volatile tap_listener_t *tap_listener_queue=NULL;
103
104 #ifdef HAVE_PLUGINS
105
106 #include <gmodule.h>
107
108 #include <wsutil/plugins.h>
109
110 /*
111  * List of tap plugins.
112  */
113 typedef struct {
114         void (*register_tap_listener_fn)(void);   /* routine to call to register tap listener */
115 } tap_plugin;
116
117 static GSList *tap_plugins = NULL;
118
119 /*
120  * Callback for each plugin found.
121  */
122 static gboolean
123 check_for_tap_plugin(GModule *handle)
124 {
125         gpointer gp;
126         void (*register_tap_listener_fn)(void);
127         tap_plugin *plugin;
128
129         /*
130          * Do we have a register_tap_listener routine?
131          */
132         if (!g_module_symbol(handle, "plugin_register_tap_listener", &gp)) {
133                 /* No, so this isn't a tap plugin. */
134                 return FALSE;
135         }
136
137         /*
138          * Yes - this plugin includes one or more taps.
139          */
140         register_tap_listener_fn = (void (*)(void))gp;
141
142         /*
143          * Add this one to the list of tap plugins.
144          */
145         plugin = (tap_plugin *)g_malloc(sizeof (tap_plugin));
146         plugin->register_tap_listener_fn = register_tap_listener_fn;
147         tap_plugins = g_slist_append(tap_plugins, plugin);
148         return TRUE;
149 }
150
151 void
152 register_tap_plugin_type(void)
153 {
154         add_plugin_type("tap", check_for_tap_plugin);
155 }
156
157 static void
158 register_tap_plugin_listener(gpointer data, gpointer user_data _U_)
159 {
160         tap_plugin *plugin = (tap_plugin *)data;
161
162         (plugin->register_tap_listener_fn)();
163 }
164
165 /*
166  * For all tap plugins, call their register routines.
167  */
168 void
169 register_all_plugin_tap_listeners(void)
170 {
171         g_slist_foreach(tap_plugins, register_tap_plugin_listener, NULL);
172 }
173 #endif /* HAVE_PLUGINS */
174
175 /* **********************************************************************
176  * Init routine only called from epan at application startup
177  * ********************************************************************** */
178 /* This function is called once when wireshark starts up and is used
179    to init any data structures we may need later.
180 */
181 void
182 tap_init(void)
183 {
184         tap_packet_index=0;
185 }
186
187 /* **********************************************************************
188  * Functions called from dissector when made tappable
189  * ********************************************************************** */
190 /* the following two functions are used from dissectors to
191    1. register the ability to tap packets from this subdissector
192    2. push packets encountered by the subdissector to anyone tapping
193 */
194
195 /* This function registers that a dissector has the packet tap ability
196    available.  The name parameter is the name of this tap and extensions can
197    use open_tap(char *name,... to specify that it wants to receive packets/
198    events from this tap.
199
200    This function is only to be called once, when the dissector initializes.
201
202    The return value from this call is later used as a parameter to the
203    tap_packet(unsigned int *tap_id,...
204    call so that the tap subsystem knows to which tap point this tapped
205    packet is associated.
206 */
207 int
208 register_tap(const char *name)
209 {
210         tap_dissector_t *td, *tdl;
211         int i, tap_id;
212
213         if(tap_dissector_list){
214                 tap_id=find_tap_id(name);
215                 if (tap_id)
216                         return tap_id;
217         }
218
219         td=(tap_dissector_t *)g_malloc(sizeof(tap_dissector_t));
220         td->next=NULL;
221         td->name = g_strdup(name);
222
223         if(!tap_dissector_list){
224                 tap_dissector_list=td;
225                 i=1;
226         } else {
227                 for(i=2,tdl=tap_dissector_list;tdl->next;i++,tdl=tdl->next)
228                         ;
229                 tdl->next=td;
230         }
231         return i;
232 }
233
234
235 /* Everytime the dissector has finished dissecting a packet (and all
236    subdissectors have returned) and if the dissector has been made "tappable"
237    it will push some data to everyone tapping this layer by a call
238    to tap_queue_packet().
239    The first parameter is the tap_id returned by the register_tap()
240    call for this dissector (so the tap system can keep track of who it came
241    from and who is listening to it)
242    The second is the packet_info structure which many tap readers will find
243    interesting.
244    The third argument is specific to each tap point or NULL if no additional
245    data is available to this tap.  A tap point in say IP will probably want to
246    push the IP header structure here. Same thing for TCP and ONCRPC.
247
248    The pinfo and the specific pointer are what is supplied to every listener
249    in the read_callback() call made to every one currently listening to this
250    tap.
251
252    The tap reader is responsible to know how to parse any structure pointed
253    to by the tap specific data pointer.
254 */
255 void
256 tap_queue_packet(int tap_id, packet_info *pinfo, const void *tap_specific_data)
257 {
258         tap_packet_t *tpt;
259
260         if(!tapping_is_active){
261                 return;
262         }
263         /*
264          * XXX - should we allocate this with an ep_allocator,
265          * rather than having a fixed maximum number of entries?
266          */
267         if(tap_packet_index >= TAP_PACKET_QUEUE_LEN){
268                 g_warning("Too many taps queued");
269                 return;
270         }
271
272         tpt=&tap_packet_array[tap_packet_index];
273         tpt->tap_id=tap_id;
274         tpt->flags = 0;
275         if (pinfo->flags.in_error_pkt)
276                 tpt->flags |= TAP_PACKET_IS_ERROR_PACKET;
277         tpt->pinfo=pinfo;
278         tpt->tap_specific_data=tap_specific_data;
279         tap_packet_index++;
280 }
281
282
283
284
285
286 /* **********************************************************************
287  * Functions used by file.c to drive the tap subsystem
288  * ********************************************************************** */
289
290 void tap_build_interesting (epan_dissect_t *edt)
291 {
292         tap_listener_t *tl;
293
294         /* nothing to do, just return */
295         if(!tap_listener_queue){
296                 return;
297         }
298
299         /* loop over all tap listeners and build the list of all
300            interesting hf_fields */
301         for(tl=(tap_listener_t *)tap_listener_queue;tl;tl=tl->next){
302                 if(tl->code){
303                         epan_dissect_prime_dfilter(edt, tl->code);
304                 }
305         }
306 }
307
308 /* This function is used to delete/initialize the tap queue and prime an
309    epan_dissect_t with all the filters for tap listeners.
310    To free the tap queue, we just prepend the used queue to the free queue.
311 */
312 void
313 tap_queue_init(epan_dissect_t *edt)
314 {
315         /* nothing to do, just return */
316         if(!tap_listener_queue){
317                 return;
318         }
319
320         tapping_is_active=TRUE;
321
322         tap_packet_index=0;
323
324         tap_build_interesting (edt);
325 }
326
327 /* this function is called after a packet has been fully dissected to push the tapped
328    data to all extensions that has callbacks registered.
329 */
330 void
331 tap_push_tapped_queue(epan_dissect_t *edt)
332 {
333         tap_packet_t *tp;
334         tap_listener_t *tl;
335         guint i;
336
337         /* nothing to do, just return */
338         if(!tapping_is_active){
339                 return;
340         }
341
342         tapping_is_active=FALSE;
343
344         /* nothing to do, just return */
345         if(!tap_packet_index){
346                 return;
347         }
348
349         /* loop over all tap listeners and call the listener callback
350            for all packets that match the filter. */
351         for(i=0;i<tap_packet_index;i++){
352                 for(tl=(tap_listener_t *)tap_listener_queue;tl;tl=tl->next){
353                         tp=&tap_packet_array[i];
354                         /* Don't tap the packet if it's an "error" unless the listener tells us to */
355                         if (!(tp->flags & TAP_PACKET_IS_ERROR_PACKET) || (tl->flags & TL_REQUIRES_ERROR_PACKETS))
356                         {
357                                 if(tp->tap_id==tl->tap_id){
358                                         gboolean passed=TRUE;
359                                         if(tl->code){
360                                                 passed=dfilter_apply_edt(tl->code, edt);
361                                         }
362                                         if(passed && tl->packet){
363                                                 tl->needs_redraw|=tl->packet(tl->tapdata, tp->pinfo, edt, tp->tap_specific_data);
364                                         }
365                                 }
366             }
367                 }
368         }
369 }
370
371
372 /* This function can be used by a dissector to fetch any tapped data before
373  * returning.
374  * This can be useful if one wants to extract the data inside dissector  BEFORE
375  * it exists as an alternative to the callbacks that are all called AFTER the
376  * dissection has completed.
377  *
378  * Example: SMB2 uses this mechanism to extract the data tapped from NTLMSSP
379  * containing the account and domain names before exiting.
380  * Note that the SMB2 tap listener specifies all three callbacks as NULL.
381  *
382  * Beware: when using this mechanism to extract the tapped data you can not
383  * use "filters" and should specify the "filter" as NULL when registering
384  * the tap listener.
385  */
386 const void *
387 fetch_tapped_data(int tap_id, int idx)
388 {
389         tap_packet_t *tp;
390         guint i;
391
392         /* nothing to do, just return */
393         if(!tapping_is_active){
394                 return NULL;
395         }
396
397         /* nothing to do, just return */
398         if(!tap_packet_index){
399                 return NULL;
400         }
401
402         /* loop over all tapped packets and return the one with index idx */
403         for(i=0;i<tap_packet_index;i++){
404                 tp=&tap_packet_array[i];
405                 if(tp->tap_id==tap_id){
406                         if(!idx--){
407                                 return tp->tap_specific_data;
408                         }
409                 }
410         }
411
412         return NULL;
413 }
414
415 /* This function is called when we need to reset all tap listeners, for example
416    when we open/start a new capture or if we need to rescan the packet list.
417 */
418 void
419 reset_tap_listeners(void)
420 {
421         tap_listener_t *tl;
422
423         for(tl=(tap_listener_t *)tap_listener_queue;tl;tl=tl->next){
424                 if(tl->reset){
425                         tl->reset(tl->tapdata);
426                 }
427                 tl->needs_redraw=TRUE;
428         }
429
430 }
431
432
433 /* This function is called when we need to redraw all tap listeners, for example
434    when we open/start a new capture or if we need to rescan the packet list.
435    It should be called from a low priority thread say once every 3 seconds
436
437    If draw_all is true, redraw all aplications regardless if they have
438    changed or not.
439 */
440 void
441 draw_tap_listeners(gboolean draw_all)
442 {
443         tap_listener_t *tl;
444
445         for(tl=(tap_listener_t *)tap_listener_queue;tl;tl=tl->next){
446                 if(tl->needs_redraw || draw_all){
447                         if(tl->draw){
448                                 tl->draw(tl->tapdata);
449                         }
450                 }
451                 tl->needs_redraw=FALSE;
452         }
453 }
454
455 /* Gets a GList of the tap names. The content of the list
456    is owned by the tap table and should not be modified or freed.
457    Use g_list_free() when done using the list. */
458 GList*
459 get_tap_names(void)
460 {
461         GList *list = NULL;
462         tap_dissector_t *td;
463
464         for(td=tap_dissector_list; td; td=td->next) {
465                 list = g_list_prepend(list, td->name);
466         }
467
468         return g_list_reverse(list);
469 }
470
471 /* **********************************************************************
472  * Functions used by tap to
473  * 1. register that a really simple extension is available for use by
474  *    Wireshark.
475  * 2. start tapping from a subdissector
476  * 3. close an already open tap
477  * ********************************************************************** */
478 /* this function will return the tap_id for the specific protocol tap
479    or 0 if no such tap was found.
480  */
481 int
482 find_tap_id(const char *name)
483 {
484         tap_dissector_t *td;
485         int i;
486
487         for(i=1,td=tap_dissector_list;td;i++,td=td->next) {
488                 if(!strcmp(td->name,name)){
489                         return i;
490                 }
491         }
492         return 0;
493 }
494
495 /* this function attaches the tap_listener to the named tap.
496  * function returns :
497  *     NULL: ok.
498  * non-NULL: error, return value points to GString containing error
499  *           message.
500  */
501 GString *
502 register_tap_listener(const char *tapname, void *tapdata, const char *fstring,
503                       guint flags, tap_reset_cb reset, tap_packet_cb packet, tap_draw_cb draw)
504 {
505         tap_listener_t *tl;
506         int tap_id;
507         GString *error_string;
508         gchar *err_msg;
509
510         tap_id=find_tap_id(tapname);
511         if(!tap_id){
512                 error_string = g_string_new("");
513                 g_string_printf(error_string, "Tap %s not found", tapname);
514                 return error_string;
515         }
516
517         tl=(tap_listener_t *)g_malloc(sizeof(tap_listener_t));
518         tl->code=NULL;
519         tl->needs_redraw=TRUE;
520         tl->flags=flags;
521         if(fstring){
522                 if(!dfilter_compile(fstring, &tl->code, &err_msg)){
523                         error_string = g_string_new("");
524                         g_string_printf(error_string,
525                             "Filter \"%s\" is invalid - %s",
526                             fstring, err_msg);
527                         g_free(err_msg);
528                         g_free(tl);
529                         return error_string;
530                 }
531         }
532
533         tl->tap_id=tap_id;
534         tl->tapdata=tapdata;
535         tl->reset=reset;
536         tl->packet=packet;
537         tl->draw=draw;
538         tl->next=(tap_listener_t *)tap_listener_queue;
539
540         tap_listener_queue=tl;
541
542         return NULL;
543 }
544
545 /* this function sets a new dfilter to a tap listener
546  */
547 GString *
548 set_tap_dfilter(void *tapdata, const char *fstring)
549 {
550         tap_listener_t *tl=NULL,*tl2;
551         GString *error_string;
552         gchar *err_msg;
553
554         if(!tap_listener_queue){
555                 return NULL;
556         }
557
558         if(tap_listener_queue->tapdata==tapdata){
559                 tl=(tap_listener_t *)tap_listener_queue;
560         } else {
561                 for(tl2=(tap_listener_t *)tap_listener_queue;tl2->next;tl2=tl2->next){
562                         if(tl2->next->tapdata==tapdata){
563                                 tl=tl2->next;
564                                 break;
565                         }
566
567                 }
568         }
569
570         if(tl){
571                 if(tl->code){
572                         dfilter_free(tl->code);
573                         tl->code=NULL;
574                 }
575                 tl->needs_redraw=TRUE;
576                 if(fstring){
577                         if(!dfilter_compile(fstring, &tl->code, &err_msg)){
578                                 error_string = g_string_new("");
579                                 g_string_printf(error_string,
580                                                  "Filter \"%s\" is invalid - %s",
581                                                  fstring, err_msg);
582                                 g_free(err_msg);
583                                 return error_string;
584                         }
585                 }
586         }
587
588         return NULL;
589 }
590
591 /* this function removes a tap listener
592  */
593 void
594 remove_tap_listener(void *tapdata)
595 {
596         tap_listener_t *tl=NULL,*tl2;
597
598         if(!tap_listener_queue){
599                 return;
600         }
601
602         if(tap_listener_queue->tapdata==tapdata){
603                 tl=(tap_listener_t *)tap_listener_queue;
604                 tap_listener_queue=tap_listener_queue->next;
605         } else {
606                 for(tl2=(tap_listener_t *)tap_listener_queue;tl2->next;tl2=tl2->next){
607                         if(tl2->next->tapdata==tapdata){
608                                 tl=tl2->next;
609                                 tl2->next=tl2->next->next;
610                                 break;
611                         }
612
613                 }
614         }
615
616         if(tl){
617                 if(tl->code){
618                         dfilter_free(tl->code);
619                 }
620                 g_free(tl);
621         }
622
623         return;
624 }
625
626 /*
627  * Return TRUE if we have one or more tap listeners that require dissection,
628  * FALSE otherwise.
629  */
630 gboolean
631 tap_listeners_require_dissection(void)
632 {
633         volatile tap_listener_t *tap_queue = tap_listener_queue;
634
635         while(tap_queue) {
636                 if(!(tap_queue->flags & TL_IS_DISSECTOR_HELPER))
637                         return TRUE;
638
639                 tap_queue = tap_queue->next;
640         }
641
642         return FALSE;
643
644 }
645
646 /* Returns TRUE there is an active tap listener for the specified tap id. */
647 gboolean
648 have_tap_listener(int tap_id)
649 {
650         volatile tap_listener_t *tap_queue = tap_listener_queue;
651
652         while(tap_queue) {
653                 if(tap_queue->tap_id == tap_id)
654                         return TRUE;
655
656                 tap_queue = tap_queue->next;
657         }
658
659         return FALSE;
660 }
661
662 /*
663  * Return TRUE if we have any tap listeners with filters, FALSE otherwise.
664  */
665 gboolean
666 have_filtering_tap_listeners(void)
667 {
668         tap_listener_t *tl;
669
670         for(tl=(tap_listener_t *)tap_listener_queue;tl;tl=tl->next){
671                 if(tl->code)
672                         return TRUE;
673         }
674         return FALSE;
675 }
676
677 /*
678  * Get the union of all the flags for all the tap listeners; that gives
679  * an indication of whether the protocol tree, or the columns, are
680  * required by any taps.
681  */
682 guint
683 union_of_tap_listener_flags(void)
684 {
685         tap_listener_t *tl;
686         guint flags = 0;
687
688         for(tl=(tap_listener_t *)tap_listener_queue;tl;tl=tl->next){
689                 flags|=tl->flags;
690         }
691         return flags;
692 }
693
694 /*
695  * Editor modelines  -  http://www.wireshark.org/tools/modelines.html
696  *
697  * Local variables:
698  * c-basic-offset: 8
699  * tab-width: 8
700  * indent-tabs-mode: t
701  * End:
702  *
703  * vi: set shiftwidth=8 tabstop=8 noexpandtab:
704  * :indentSize=8:tabSize=8:noTabs=false:
705  */