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 * SPDX-License-Identifier: GPL-2.0-or-later 9 */ 10 11 #include <config.h> 12 #define WS_LOG_DOMAIN LOG_DOMAIN_EPAN 13 14 #include <stdio.h> 15 16 #include <sys/types.h> 17 18 #ifdef HAVE_NETINET_IN_H 19 # include <netinet/in.h> 20 #endif 21 22 #include <string.h> 23 24 #include <glib.h> 25 26 #include <epan/packet_info.h> 27 #include <epan/dfilter/dfilter.h> 28 #include <epan/tap.h> 29 #include <wsutil/wslog.h> 30 31 static gboolean tapping_is_active=FALSE; 32 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=NULL; 38 39 /* 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. 45 * 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. 51 * 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. 58 * 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. 63 * 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. 67 */ 68 typedef struct _tap_packet_t { 69 int tap_id; 70 guint32 flags; 71 packet_info *pinfo; 72 const void *tap_specific_data; 73 } tap_packet_t; 74 75 #define TAP_PACKET_IS_ERROR_PACKET 0x00000001 /* packet being queued is an error packet */ 76 77 #define TAP_PACKET_QUEUE_LEN 5000 78 static tap_packet_t tap_packet_array[TAP_PACKET_QUEUE_LEN]; 79 static guint tap_packet_index; 80 81 typedef struct _tap_listener_t { 82 struct _tap_listener_t *next; 83 int tap_id; 84 gboolean needs_redraw; 85 gboolean failed; 86 guint flags; 87 gchar *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; 95 96 static tap_listener_t *tap_listener_queue=NULL; 97 98 static GSList *tap_plugins = NULL; 99 100 #ifdef HAVE_PLUGINS 101 void 102 tap_register_plugin(const tap_plugin *plug) 103 { 104 tap_plugins = g_slist_prepend(tap_plugins, (tap_plugin *)plug); 105 } 106 #else /* HAVE_PLUGINS */ 107 void 108 tap_register_plugin(const tap_plugin *plug _U_) 109 { 110 ws_warning("tap_register_plugin: built without support for binary plugins"); 111 } 112 #endif /* HAVE_PLUGINS */ 113 114 static void 115 call_plugin_register_tap_listener(gpointer data, gpointer user_data _U_) 116 { 117 tap_plugin *plug = (tap_plugin *)data; 118 119 if (plug->register_tap_listener) { 120 plug->register_tap_listener(); 121 } 122 } 123 124 /* 125 * For all taps, call their register routines. 126 * 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. 129 */ 130 void 131 register_all_tap_listeners(tap_reg_t *tap_reg_listeners) 132 { 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); 137 138 /* Register all builtin listeners. */ 139 for (tap_reg_t *t = &tap_reg_listeners[0]; t->cb_func != NULL; t++) { 140 t->cb_func(); 141 } 142 } 143 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. 149 */ 150 void 151 tap_init(void) 152 { 153 tap_packet_index=0; 154 } 155 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 162 */ 163 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. 168 169 This function is only to be called once, when the dissector initializes. 170 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. 175 */ 176 int 177 register_tap(const char *name) 178 { 179 tap_dissector_t *td, *tdl = NULL, *tdl_prev = NULL; 180 int i=0; 181 182 if(tap_dissector_list){ 183 /* Check if we allready 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. 185 */ 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; 189 } 190 } 191 tdl = tdl_prev; 192 } 193 194 td=g_new(tap_dissector_t, 1); 195 td->next=NULL; 196 td->name = g_strdup(name); 197 198 if(!tap_dissector_list){ 199 tap_dissector_list=td; 200 i=1; 201 } else { 202 tdl->next=td; 203 } 204 return i; 205 } 206 207 208 /* Everytime 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. 220 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. 224 225 The tap reader is responsible to know how to parse any structure pointed 226 to by the tap specific data pointer. 227 */ 228 void 229 tap_queue_packet(int tap_id, packet_info *pinfo, const void *tap_specific_data) 230 { 231 tap_packet_t *tpt; 232 233 if(!tapping_is_active){ 234 return; 235 } 236 /* 237 * XXX - should we allocate this with an ep_allocator, 238 * rather than having a fixed maximum number of entries? 239 */ 240 if(tap_packet_index >= TAP_PACKET_QUEUE_LEN){ 241 ws_warning("Too many taps queued"); 242 return; 243 } 244 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++; 253 } 254 255 256 257 258 259 /* ********************************************************************** 260 * Functions used by file.c to drive the tap subsystem 261 * ********************************************************************** */ 262 263 void tap_build_interesting (epan_dissect_t *edt) 264 { 265 tap_listener_t *tl; 266 267 /* nothing to do, just return */ 268 if(!tap_listener_queue){ 269 return; 270 } 271 272 /* loop over all tap listeners and build the list of all 273 interesting hf_fields */ 274 for(tl=tap_listener_queue;tl;tl=tl->next){ 275 if(tl->code){ 276 epan_dissect_prime_with_dfilter(edt, tl->code); 277 } 278 } 279 } 280 281 /* This function is used to delete/initialize the tap queue and prime an 282 epan_dissect_t with all the filters for tap listeners. 283 To free the tap queue, we just prepend the used queue to the free queue. 284 */ 285 void 286 tap_queue_init(epan_dissect_t *edt) 287 { 288 /* nothing to do, just return */ 289 if(!tap_listener_queue){ 290 return; 291 } 292 293 tapping_is_active=TRUE; 294 295 tap_packet_index=0; 296 297 tap_build_interesting (edt); 298 } 299 300 /* this function is called after a packet has been fully dissected to push the tapped 301 data to all extensions that has callbacks registered. 302 */ 303 void 304 tap_push_tapped_queue(epan_dissect_t *edt) 305 { 306 tap_packet_t *tp; 307 tap_listener_t *tl; 308 guint i; 309 310 /* nothing to do, just return */ 311 if(!tapping_is_active){ 312 return; 313 } 314 315 tapping_is_active=FALSE; 316 317 /* nothing to do, just return */ 318 if(!tap_packet_index){ 319 return; 320 } 321 322 /* loop over all tap listeners and call the listener callback 323 for all packets that match the filter. */ 324 for(i=0;i<tap_packet_index;i++){ 325 for(tl=tap_listener_queue;tl;tl=tl->next){ 326 tp=&tap_packet_array[i]; 327 /* Don't tap the packet if it's an "error packet" 328 * unless the listener has requested that we do so. 329 */ 330 if (!(tp->flags & TAP_PACKET_IS_ERROR_PACKET) || (tl->flags & TL_REQUIRES_ERROR_PACKETS)) 331 { 332 if(tp->tap_id==tl->tap_id){ 333 if(!tl->packet){ 334 /* There isn't a per-packet 335 * routine for this tap. 336 */ 337 continue; 338 } 339 if(tl->failed){ 340 /* A previous call failed, 341 * meaning "stop running this 342 * tap", so don't call the 343 * packet routine. 344 */ 345 continue; 346 } 347 348 /* If we have a filter, see if the 349 * packet passes. 350 */ 351 if(tl->code){ 352 if (!dfilter_apply_edt(tl->code, edt)){ 353 /* The packet didn't 354 * pass the filter. */ 355 continue; 356 } 357 } 358 359 /* So call the per-packet routine. */ 360 tap_packet_status status; 361 362 status = tl->packet(tl->tapdata, tp->pinfo, edt, tp->tap_specific_data); 363 364 switch (status) { 365 366 case TAP_PACKET_DONT_REDRAW: 367 break; 368 369 case TAP_PACKET_REDRAW: 370 tl->needs_redraw=TRUE; 371 break; 372 373 case TAP_PACKET_FAILED: 374 tl->failed=TRUE; 375 break; 376 } 377 } 378 } 379 } 380 } 381 } 382 383 384 /* This function can be used by a dissector to fetch any tapped data before 385 * returning. 386 * This can be useful if one wants to extract the data inside dissector BEFORE 387 * it exists as an alternative to the callbacks that are all called AFTER the 388 * dissection has completed. 389 * 390 * Example: SMB2 uses this mechanism to extract the data tapped from NTLMSSP 391 * containing the account and domain names before exiting. 392 * Note that the SMB2 tap listener specifies all three callbacks as NULL. 393 * 394 * Beware: when using this mechanism to extract the tapped data you can not 395 * use "filters" and should specify the "filter" as NULL when registering 396 * the tap listener. 397 */ 398 const void * 399 fetch_tapped_data(int tap_id, int idx) 400 { 401 tap_packet_t *tp; 402 guint i; 403 404 /* nothing to do, just return */ 405 if(!tapping_is_active){ 406 return NULL; 407 } 408 409 /* nothing to do, just return */ 410 if(!tap_packet_index){ 411 return NULL; 412 } 413 414 /* loop over all tapped packets and return the one with index idx */ 415 for(i=0;i<tap_packet_index;i++){ 416 tp=&tap_packet_array[i]; 417 if(tp->tap_id==tap_id){ 418 if(!idx--){ 419 return tp->tap_specific_data; 420 } 421 } 422 } 423 424 return NULL; 425 } 426 427 /* This function is called when we need to reset all tap listeners, for example 428 when we open/start a new capture or if we need to rescan the packet list. 429 */ 430 void 431 reset_tap_listeners(void) 432 { 433 tap_listener_t *tl; 434 435 for(tl=tap_listener_queue;tl;tl=tl->next){ 436 if(tl->reset){ 437 tl->reset(tl->tapdata); 438 } 439 tl->needs_redraw=TRUE; 440 tl->failed=FALSE; 441 } 442 443 } 444 445 446 /* This function is called when we need to redraw all tap listeners, for example 447 when we open/start a new capture or if we need to rescan the packet list. 448 It should be called from a low priority thread say once every 3 seconds 449 450 If draw_all is true, redraw all applications regardless if they have 451 changed or not. 452 */ 453 void 454 draw_tap_listeners(gboolean draw_all) 455 { 456 tap_listener_t *tl; 457 458 for(tl=tap_listener_queue;tl;tl=tl->next){ 459 if(tl->needs_redraw || draw_all){ 460 if(tl->draw){ 461 tl->draw(tl->tapdata); 462 } 463 } 464 tl->needs_redraw=FALSE; 465 } 466 } 467 468 /* Gets a GList of the tap names. The content of the list 469 is owned by the tap table and should not be modified or freed. 470 Use g_list_free() when done using the list. */ 471 GList* 472 get_tap_names(void) 473 { 474 GList *list = NULL; 475 tap_dissector_t *td; 476 477 for(td=tap_dissector_list; td; td=td->next) { 478 list = g_list_prepend(list, td->name); 479 } 480 481 return g_list_reverse(list); 482 } 483 484 /* ********************************************************************** 485 * Functions used by tap to 486 * 1. register that a really simple extension is available for use by 487 * Wireshark. 488 * 2. start tapping from a subdissector 489 * 3. close an already open tap 490 * ********************************************************************** */ 491 /* this function will return the tap_id for the specific protocol tap 492 or 0 if no such tap was found. 493 */ 494 int 495 find_tap_id(const char *name) 496 { 497 tap_dissector_t *td; 498 int i; 499 500 for(i=1,td=tap_dissector_list;td;i++,td=td->next) { 501 if(!strcmp(td->name,name)){ 502 return i; 503 } 504 } 505 return 0; 506 } 507 508 static void 509 free_tap_listener(tap_listener_t *tl) 510 { 511 /* The free_tap_listener is called in the error path of 512 * register_tap_listener (when the dfilter fails to be registered) 513 * and the finish callback is set after that. 514 * If this is changed make sure the finish callback is not called 515 * twice to prevent double-free errors. 516 */ 517 if (tl->finish) { 518 tl->finish(tl->tapdata); 519 } 520 dfilter_free(tl->code); 521 g_free(tl->fstring); 522 g_free(tl); 523 } 524 525 /* this function attaches the tap_listener to the named tap. 526 * function returns : 527 * NULL: ok. 528 * non-NULL: error, return value points to GString containing error 529 * message. 530 */ 531 GString * 532 register_tap_listener(const char *tapname, void *tapdata, const char *fstring, 533 guint flags, tap_reset_cb reset, tap_packet_cb packet, 534 tap_draw_cb draw, tap_finish_cb finish) 535 { 536 tap_listener_t *tl; 537 int tap_id; 538 dfilter_t *code=NULL; 539 GString *error_string; 540 gchar *err_msg; 541 542 tap_id=find_tap_id(tapname); 543 if(!tap_id){ 544 error_string = g_string_new(""); 545 g_string_printf(error_string, "Tap %s not found", tapname); 546 return error_string; 547 } 548 549 tl=g_new0(tap_listener_t, 1); 550 tl->needs_redraw=TRUE; 551 tl->failed=FALSE; 552 tl->flags=flags; 553 if(fstring){ 554 if(!dfilter_compile(fstring, &code, &err_msg)){ 555 error_string = g_string_new(""); 556 g_string_printf(error_string, 557 "Filter \"%s\" is invalid - %s", 558 fstring, err_msg); 559 g_free(err_msg); 560 free_tap_listener(tl); 561 return error_string; 562 } 563 } 564 tl->fstring=g_strdup(fstring); 565 tl->code=code; 566 567 tl->tap_id=tap_id; 568 tl->tapdata=tapdata; 569 tl->reset=reset; 570 tl->packet=packet; 571 tl->draw=draw; 572 tl->finish=finish; 573 tl->next=tap_listener_queue; 574 575 tap_listener_queue=tl; 576 577 return NULL; 578 } 579 580 /* this function sets a new dfilter to a tap listener 581 */ 582 GString * 583 set_tap_dfilter(void *tapdata, const char *fstring) 584 { 585 tap_listener_t *tl=NULL,*tl2; 586 dfilter_t *code=NULL; 587 GString *error_string; 588 gchar *err_msg; 589 590 if(!tap_listener_queue){ 591 return NULL; 592 } 593 594 if(tap_listener_queue->tapdata==tapdata){ 595 tl=tap_listener_queue; 596 } else { 597 for(tl2=tap_listener_queue;tl2->next;tl2=tl2->next){ 598 if(tl2->next->tapdata==tapdata){ 599 tl=tl2->next; 600 break; 601 } 602 603 } 604 } 605 606 if(tl){ 607 if(tl->code){ 608 dfilter_free(tl->code); 609 tl->code=NULL; 610 } 611 tl->needs_redraw=TRUE; 612 g_free(tl->fstring); 613 if(fstring){ 614 if(!dfilter_compile(fstring, &code, &err_msg)){ 615 tl->fstring=NULL; 616 error_string = g_string_new(""); 617 g_string_printf(error_string, 618 "Filter \"%s\" is invalid - %s", 619 fstring, err_msg); 620 g_free(err_msg); 621 return error_string; 622 } 623 } 624 tl->fstring=g_strdup(fstring); 625 tl->code=code; 626 } 627 628 return NULL; 629 } 630 631 /* this function recompiles dfilter for all registered tap listeners 632 */ 633 void 634 tap_listeners_dfilter_recompile(void) 635 { 636 tap_listener_t *tl; 637 dfilter_t *code; 638 gchar *err_msg; 639 640 for(tl=tap_listener_queue;tl;tl=tl->next){ 641 if(tl->code){ 642 dfilter_free(tl->code); 643 tl->code=NULL; 644 } 645 tl->needs_redraw=TRUE; 646 code=NULL; 647 if(tl->fstring){ 648 if(!dfilter_compile(tl->fstring, &code, &err_msg)){ 649 g_free(err_msg); 650 err_msg = NULL; 651 /* Not valid, make a dfilter matching no packets */ 652 if (!dfilter_compile("frame.number == 0", &code, &err_msg)) 653 g_free(err_msg); 654 } 655 } 656 tl->code=code; 657 } 658 } 659 660 /* this function removes a tap listener 661 */ 662 void 663 remove_tap_listener(void *tapdata) 664 { 665 tap_listener_t *tl=NULL,*tl2; 666 667 if(!tap_listener_queue){ 668 return; 669 } 670 671 if(tap_listener_queue->tapdata==tapdata){ 672 tl=tap_listener_queue; 673 tap_listener_queue=tap_listener_queue->next; 674 } else { 675 for(tl2=tap_listener_queue;tl2->next;tl2=tl2->next){ 676 if(tl2->next->tapdata==tapdata){ 677 tl=tl2->next; 678 tl2->next=tl2->next->next; 679 break; 680 } 681 682 } 683 if(!tl) { 684 ws_warning("remove_tap_listener(): no listener found with that tap data"); 685 return; 686 } 687 } 688 free_tap_listener(tl); 689 } 690 691 /* 692 * Return TRUE if we have one or more tap listeners that require dissection, 693 * FALSE otherwise. 694 */ 695 gboolean 696 tap_listeners_require_dissection(void) 697 { 698 tap_listener_t *tap_queue = tap_listener_queue; 699 700 while(tap_queue) { 701 if(!(tap_queue->flags & TL_IS_DISSECTOR_HELPER)) 702 return TRUE; 703 704 tap_queue = tap_queue->next; 705 } 706 707 return FALSE; 708 709 } 710 711 /* Returns TRUE there is an active tap listener for the specified tap id. */ 712 gboolean 713 have_tap_listener(int tap_id) 714 { 715 tap_listener_t *tap_queue = tap_listener_queue; 716 717 while(tap_queue) { 718 if(tap_queue->tap_id == tap_id) 719 return TRUE; 720 721 tap_queue = tap_queue->next; 722 } 723 724 return FALSE; 725 } 726 727 /* 728 * Return TRUE if we have any tap listeners with filters, FALSE otherwise. 729 */ 730 gboolean 731 have_filtering_tap_listeners(void) 732 { 733 tap_listener_t *tl; 734 735 for(tl=tap_listener_queue;tl;tl=tl->next){ 736 if(tl->code) 737 return TRUE; 738 } 739 return FALSE; 740 } 741 742 /* 743 * Get the union of all the flags for all the tap listeners; that gives 744 * an indication of whether the protocol tree, or the columns, are 745 * required by any taps. 746 */ 747 guint 748 union_of_tap_listener_flags(void) 749 { 750 tap_listener_t *tl; 751 guint flags = 0; 752 753 for(tl=tap_listener_queue;tl;tl=tl->next){ 754 flags|=tl->flags; 755 } 756 return flags; 757 } 758 759 void tap_cleanup(void) 760 { 761 tap_listener_t *elem_lq; 762 tap_listener_t *head_lq = tap_listener_queue; 763 tap_dissector_t *elem_dl; 764 tap_dissector_t *head_dl = tap_dissector_list; 765 766 while(head_lq){ 767 elem_lq = head_lq; 768 head_lq = head_lq->next; 769 free_tap_listener(elem_lq); 770 } 771 tap_listener_queue = NULL; 772 773 while(head_dl){ 774 elem_dl = head_dl; 775 head_dl = head_dl->next; 776 g_free(elem_dl->name); 777 g_free((gpointer)elem_dl); 778 } 779 tap_dissector_list = NULL; 780 781 g_slist_free(tap_plugins); 782 tap_plugins = NULL; 783 } 784 785 /* 786 * Editor modelines - https://www.wireshark.org/tools/modelines.html 787 * 788 * Local variables: 789 * c-basic-offset: 8 790 * tab-width: 8 791 * indent-tabs-mode: t 792 * End: 793 * 794 * vi: set shiftwidth=8 tabstop=8 noexpandtab: 795 * :indentSize=8:tabSize=8:noTabs=false: 796 */ 797