diff options
author | guy <guy@f5534014-38df-0310-8fa8-9805f1628bb7> | 2004-09-29 00:06:36 +0000 |
---|---|---|
committer | guy <guy@f5534014-38df-0310-8fa8-9805f1628bb7> | 2004-09-29 00:06:36 +0000 |
commit | 2cd9afcab8441dd3a26edc717e2b47bfa0f1839c (patch) | |
tree | d43921a8c5c3de76255c3c98ec29b5589838db95 /epan | |
parent | 1d14008984b2252d8ed60cbd0d9e8a08f2bc0553 (diff) |
Move the tap infrastructure to the epan directory.
git-svn-id: http://anonsvn.wireshark.org/wireshark/trunk@12128 f5534014-38df-0310-8fa8-9805f1628bb7
Diffstat (limited to 'epan')
33 files changed, 518 insertions, 31 deletions
diff --git a/epan/Makefile.common b/epan/Makefile.common index 994de14fdf..fcc409c07b 100644 --- a/epan/Makefile.common +++ b/epan/Makefile.common @@ -55,6 +55,7 @@ LIBETHEREAL_SRC = \ sha1.c \ sna-utils.c \ strutil.c \ + tap.c \ timestamp.c \ to_str.c \ tvbuff.c \ @@ -104,6 +105,7 @@ LIBETHEREAL_INCLUDES = \ slab.h \ sna-utils.h \ strutil.h \ + tap.h \ timestamp.h \ to_str.h \ tvbuff.h \ @@ -122,6 +124,5 @@ DISSECTOR_SUPPORT_SRC = \ ../reassemble.c \ ../req_resp_hdrs.c \ ../t35.c \ - ../tap.c \ ../xmlstub.c diff --git a/epan/dissectors/packet-ansi_a.c b/epan/dissectors/packet-ansi_a.c index 1d16dc539e..93d65c33c3 100644 --- a/epan/dissectors/packet-ansi_a.c +++ b/epan/dissectors/packet-ansi_a.c @@ -41,7 +41,7 @@ #include "epan/packet.h" #include <epan/prefs.h> -#include "tap.h" +#include <epan/tap.h> #include "packet-bssap.h" #include "packet-ansi_a.h" diff --git a/epan/dissectors/packet-ansi_map.c b/epan/dissectors/packet-ansi_map.c index 3cc58ede94..ad5928a32e 100644 --- a/epan/dissectors/packet-ansi_map.c +++ b/epan/dissectors/packet-ansi_map.c @@ -111,7 +111,7 @@ #include "epan/packet.h" #include "asn1.h" -#include "tap.h" +#include <epan/tap.h> #include "packet-ansi_a.h" #include "packet-ansi_map.h" diff --git a/epan/dissectors/packet-bootp.c b/epan/dissectors/packet-bootp.c index 5b9e3e6093..1fbcd3c738 100644 --- a/epan/dissectors/packet-bootp.c +++ b/epan/dissectors/packet-bootp.c @@ -51,7 +51,7 @@ #include "packet-dns.h" /* for get_dns_name() */ #include <epan/prefs.h> -#include "tap.h" +#include <epan/tap.h> static int bootp_dhcp_tap = -1; static int proto_bootp = -1; diff --git a/epan/dissectors/packet-dcerpc.c b/epan/dissectors/packet-dcerpc.c index 8faf2cc931..dd6f0a3cf4 100644 --- a/epan/dissectors/packet-dcerpc.c +++ b/epan/dissectors/packet-dcerpc.c @@ -37,7 +37,7 @@ #include <epan/conversation.h> #include <epan/prefs.h> #include "reassemble.h" -#include "tap.h" +#include <epan/tap.h> #include <epan/dissectors/packet-frame.h> #include <epan/dissectors/packet-dcerpc-nt.h> diff --git a/epan/dissectors/packet-eth.c b/epan/dissectors/packet-eth.c index 8147c7ea12..5d0f617ae5 100644 --- a/epan/dissectors/packet-eth.c +++ b/epan/dissectors/packet-eth.c @@ -37,7 +37,7 @@ #include "packet-isl.h" #include "packet-llc.h" #include <epan/crc32.h> -#include "tap.h" +#include <epan/tap.h> /* Interpret capture file as FW1 monitor file */ static gboolean eth_interpret_as_fw1_monitor = FALSE; diff --git a/epan/dissectors/packet-fc.c b/epan/dissectors/packet-fc.c index 8285b6072e..fe25f3cc29 100644 --- a/epan/dissectors/packet-fc.c +++ b/epan/dissectors/packet-fc.c @@ -56,7 +56,7 @@ #include "packet-fc.h" #include "packet-fclctl.h" #include "packet-fcbls.h" -#include "tap.h" +#include <epan/tap.h> #define FC_HEADER_SIZE 24 #define FC_RCTL_EISL 0x50 diff --git a/epan/dissectors/packet-fddi.c b/epan/dissectors/packet-fddi.c index b9ca93c508..9eb1de0664 100644 --- a/epan/dissectors/packet-fddi.c +++ b/epan/dissectors/packet-fddi.c @@ -36,7 +36,7 @@ #include <epan/prefs.h> #include "packet-fddi.h" #include "packet-llc.h" -#include "tap.h" +#include <epan/tap.h> #include <epan/addr_resolv.h> diff --git a/epan/dissectors/packet-frame.c b/epan/dissectors/packet-frame.c index 45221d7b5a..0a1e40e71f 100644 --- a/epan/dissectors/packet-frame.c +++ b/epan/dissectors/packet-frame.c @@ -33,7 +33,7 @@ #include <epan/tvbuff.h> #include "packet-frame.h" #include <epan/prefs.h> -#include "tap.h" +#include <epan/tap.h> int proto_frame = -1; int hf_frame_arrival_time = -1; diff --git a/epan/dissectors/packet-gsm_a.c b/epan/dissectors/packet-gsm_a.c index 7ee33fd642..e6d2d07075 100644 --- a/epan/dissectors/packet-gsm_a.c +++ b/epan/dissectors/packet-gsm_a.c @@ -70,7 +70,7 @@ #include "epan/packet.h" #include <epan/prefs.h> -#include "tap.h" +#include <epan/tap.h> #include "asn1.h" #include "packet-tcap.h" diff --git a/epan/dissectors/packet-gsm_map.c b/epan/dissectors/packet-gsm_map.c index aa357c7227..182a8ac4f8 100644 --- a/epan/dissectors/packet-gsm_map.c +++ b/epan/dissectors/packet-gsm_map.c @@ -43,7 +43,7 @@ #include <string.h> #include "epan/packet.h" -#include "tap.h" +#include <epan/tap.h> #include "asn1.h" #include "packet-tcap.h" diff --git a/epan/dissectors/packet-gsm_ss.c b/epan/dissectors/packet-gsm_ss.c index 01963aa756..2be9f7aef5 100644 --- a/epan/dissectors/packet-gsm_ss.c +++ b/epan/dissectors/packet-gsm_ss.c @@ -55,7 +55,7 @@ #include <string.h> #include "epan/packet.h" -#include "tap.h" +#include <epan/tap.h> #include "asn1.h" #include "packet-tcap.h" diff --git a/epan/dissectors/packet-h225.c b/epan/dissectors/packet-h225.c index 590a93a3c7..6f018d7523 100644 --- a/epan/dissectors/packet-h225.c +++ b/epan/dissectors/packet-h225.c @@ -37,7 +37,7 @@ #include <string.h> #include <epan/prefs.h> -#include "tap.h" +#include <epan/tap.h> #include "packet-tpkt.h" #include "packet-per.h" #include "packet-h225.h" diff --git a/epan/dissectors/packet-http.c b/epan/dissectors/packet-http.c index 7d502d2c9b..3233ae07cc 100644 --- a/epan/dissectors/packet-http.c +++ b/epan/dissectors/packet-http.c @@ -53,7 +53,7 @@ typedef enum _http_type { HTTP_OTHERS } http_type_t; -#include "tap.h" +#include <epan/tap.h> static int http_tap = -1; diff --git a/epan/dissectors/packet-ip.c b/epan/dissectors/packet-ip.c index 9cb368abed..7bb95d8da1 100644 --- a/epan/dissectors/packet-ip.c +++ b/epan/dissectors/packet-ip.c @@ -50,7 +50,7 @@ #include "packet-ipsec.h" #include <epan/in_cksum.h> #include "nlpid.h" -#include "tap.h" +#include <epan/tap.h> static int ip_tap = -1; diff --git a/epan/dissectors/packet-ipx.c b/epan/dissectors/packet-ipx.c index 4332eac66c..db3fabeec5 100644 --- a/epan/dissectors/packet-ipx.c +++ b/epan/dissectors/packet-ipx.c @@ -43,7 +43,7 @@ #include "aftypes.h" #include "arcnet_pids.h" #include <epan/conversation.h> -#include "tap.h" +#include <epan/tap.h> static int ipx_tap = -1; diff --git a/epan/dissectors/packet-ldap.c b/epan/dissectors/packet-ldap.c index 476e21d7d6..ceac5ca335 100644 --- a/epan/dissectors/packet-ldap.c +++ b/epan/dissectors/packet-ldap.c @@ -76,7 +76,7 @@ #include <epan/prefs.h> #include <epan/conversation.h> #include "packet-frame.h" -#include "tap.h" +#include <epan/tap.h> #include "packet-ber.h" #include "packet-ldap.h" diff --git a/epan/dissectors/packet-mtp3.c b/epan/dissectors/packet-mtp3.c index 86f2fb542a..c4061c2040 100644 --- a/epan/dissectors/packet-mtp3.c +++ b/epan/dissectors/packet-mtp3.c @@ -44,7 +44,7 @@ #endif #include <epan/packet.h> -#include "tap.h" +#include <epan/tap.h> #include <epan/prefs.h> /* Initialize the protocol and registered fields */ diff --git a/epan/dissectors/packet-rpc.c b/epan/dissectors/packet-rpc.c index a904ad38b6..151bde4e04 100644 --- a/epan/dissectors/packet-rpc.c +++ b/epan/dissectors/packet-rpc.c @@ -42,7 +42,7 @@ #include "reassemble.h" #include "rpc_defrag.h" #include "packet-nfs.h" -#include "tap.h" +#include <epan/tap.h> /* * See: diff --git a/epan/dissectors/packet-rtp.c b/epan/dissectors/packet-rtp.c index c6952c5865..6dd725636e 100644 --- a/epan/dissectors/packet-rtp.c +++ b/epan/dissectors/packet-rtp.c @@ -64,7 +64,7 @@ #include "packet-rtp.h" #include "rtp_pt.h" #include <epan/conversation.h> -#include "tap.h" +#include <epan/tap.h> #include <epan/prefs.h> diff --git a/epan/dissectors/packet-sctp.c b/epan/dissectors/packet-sctp.c index ba959a002b..632b758639 100644 --- a/epan/dissectors/packet-sctp.c +++ b/epan/dissectors/packet-sctp.c @@ -48,7 +48,7 @@ #include <string.h> #include <epan/prefs.h> #include <epan/packet.h> -#include "tap.h" +#include <epan/tap.h> #include "ipproto.h" #include "packet-sctp.h" #include "sctpppids.h" diff --git a/epan/dissectors/packet-sip.c b/epan/dissectors/packet-sip.c index 9fd487f1d9..a3c315ca09 100644 --- a/epan/dissectors/packet-sip.c +++ b/epan/dissectors/packet-sip.c @@ -56,7 +56,7 @@ #include <epan/packet.h> #include "packet-sip.h" -#include "tap.h" +#include <epan/tap.h> #define TCP_PORT_SIP 5060 #define UDP_PORT_SIP 5060 diff --git a/epan/dissectors/packet-smb-sidsnooping.c b/epan/dissectors/packet-smb-sidsnooping.c index 84cdb8125e..0ee0d4f999 100644 --- a/epan/dissectors/packet-smb-sidsnooping.c +++ b/epan/dissectors/packet-smb-sidsnooping.c @@ -32,7 +32,7 @@ #include "epan/packet_info.h" #include "epan/epan_dissect.h" #include "epan/proto.h" -#include "tap.h" +#include <epan/tap.h> #include "packet-dcerpc.h" #include "packet-dcerpc-nt.h" #include "register.h" diff --git a/epan/dissectors/packet-smb.c b/epan/dissectors/packet-smb.c index 5626603cb3..b788790769 100644 --- a/epan/dissectors/packet-smb.c +++ b/epan/dissectors/packet-smb.c @@ -42,7 +42,7 @@ #include <epan/strutil.h> #include <epan/prefs.h> #include "reassemble.h" -#include "tap.h" +#include <epan/tap.h> #include "packet-ipx.h" #include "packet-windows-common.h" diff --git a/epan/dissectors/packet-tcp.c b/epan/dissectors/packet-tcp.c index 3a229b40b1..bd6470aded 100644 --- a/epan/dissectors/packet-tcp.c +++ b/epan/dissectors/packet-tcp.c @@ -43,7 +43,7 @@ #include <epan/conversation.h> #include <epan/strutil.h> #include "reassemble.h" -#include "tap.h" +#include <epan/tap.h> static int tcp_tap = -1; diff --git a/epan/dissectors/packet-teredo.c b/epan/dissectors/packet-teredo.c index 052f970489..56c97abb63 100644 --- a/epan/dissectors/packet-teredo.c +++ b/epan/dissectors/packet-teredo.c @@ -42,7 +42,7 @@ #include <epan/prefs.h> #include "packet-ip.h" -#include "tap.h" +#include <epan/tap.h> #define UDP_PORT_TEREDO 3544 diff --git a/epan/dissectors/packet-tr.c b/epan/dissectors/packet-tr.c index d47c12e385..1668cea4bb 100644 --- a/epan/dissectors/packet-tr.c +++ b/epan/dissectors/packet-tr.c @@ -34,7 +34,7 @@ #include "packet-tr.h" #include "packet-llc.h" #include <epan/prefs.h> -#include "tap.h" +#include <epan/tap.h> static int proto_tr = -1; static int hf_tr_dst = -1; diff --git a/epan/dissectors/packet-udp.c b/epan/dissectors/packet-udp.c index 209048fdd7..a737d7e57b 100644 --- a/epan/dissectors/packet-udp.c +++ b/epan/dissectors/packet-udp.c @@ -44,7 +44,7 @@ #include "packet-ip.h" #include <epan/conversation.h> -#include "tap.h" +#include <epan/tap.h> static int udp_tap = -1; diff --git a/epan/dissectors/packet-wsp.c b/epan/dissectors/packet-wsp.c index e05bc1874c..13c5a9d2ed 100644 --- a/epan/dissectors/packet-wsp.c +++ b/epan/dissectors/packet-wsp.c @@ -82,7 +82,7 @@ #endif /* Statistics (see doc/README.tapping) */ -#include "tap.h" +#include <epan/tap.h> static int wsp_tap = -1; diff --git a/epan/epan.c b/epan/epan.c index 8331113361..e623d418dc 100644 --- a/epan/epan.c +++ b/epan/epan.c @@ -19,7 +19,7 @@ #include "except.h" #include "packet.h" #include "column-utils.h" -#include "../tap.h" +#include "tap.h" #include "addr_resolv.h" static void (*report_failure_func)(const char *, va_list); diff --git a/epan/plugins.c b/epan/plugins.c index 1e9f9c9575..79a4306fe1 100644 --- a/epan/plugins.c +++ b/epan/plugins.c @@ -66,7 +66,7 @@ #include <epan/dissectors/packet-tpkt.h> #include <epan/dissectors/packet-tcp.h> #include <epan/dissectors/packet-rpc.h> -#include "tap.h" +#include <epan/tap.h> #include "asn1.h" #include <epan/dissectors/packet-per.h> #include <epan/dissectors/packet-ber.h> diff --git a/epan/tap.c b/epan/tap.c new file mode 100644 index 0000000000..e73ab58a6f --- /dev/null +++ b/epan/tap.c @@ -0,0 +1,432 @@ +/* tap.c + * packet tap interface 2002 Ronnie Sahlberg + * + * $Id$ + * + * Ethereal - Network traffic analyzer + * By Gerald Combs <gerald@ethereal.com> + * Copyright 1998 Gerald Combs + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include <stdio.h> + +#ifdef HAVE_SYS_TYPES_H +# include <sys/types.h> +#endif + +#ifdef HAVE_NETINET_IN_H +# include <netinet/in.h> +#endif + +#include <string.h> +#include "epan/packet_info.h" +#include "epan/dfilter/dfilter.h" +#include <epan/tap.h> + +static gboolean tapping_is_active=FALSE; +int num_tap_filters=0; + +typedef struct _tap_dissector_t { + struct _tap_dissector_t *next; + char *name; +} tap_dissector_t; +static tap_dissector_t *tap_dissector_list=NULL; + +/* + * This is the list of free and used packets queued for a tap. + * It is implemented here explicitely instead of using GLib objects + * in order to be as fast as possible as we need to build and tear down the + * queued list at least once for each packet we see, thus we must be able + * to build and tear it down as fast as possible. + */ +typedef struct _tap_packet_t { + struct _tap_packet_t *next; + int tap_id; + packet_info *pinfo; + void *tap_specific_data; +} tap_packet_t; +static tap_packet_t *tap_packet_list_free=NULL; +static tap_packet_t *tap_packet_list_queue=NULL; +#define TAP_PACKET_QUEUE_LEN 100 + + +typedef struct _tap_listener_t { + struct _tap_listener_t *next; + int tap_id; + int needs_redraw; + dfilter_t *code; + void *tapdata; + tap_reset_cb reset; + tap_packet_cb packet; + tap_draw_cb draw; +} tap_listener_t; +static volatile tap_listener_t *tap_listener_queue=NULL; + +/* ********************************************************************** + * Init routine only called from epan at application startup + * ********************************************************************** */ +/* This function is called once when ethereal starts up and is used + to init any data structures we may need later. +*/ +void +tap_init(void) +{ + int i; + tap_packet_t *tpt; + + for(i=0;i<TAP_PACKET_QUEUE_LEN;i++){ + tpt=g_malloc(sizeof(tap_packet_t)); + tpt->next=tap_packet_list_free; + tap_packet_list_free=tpt; + } + tap_packet_list_queue=NULL; + + return; +} + + + +/* ********************************************************************** + * Functions called from dissector when made tappable + * ********************************************************************** */ +/* the following two functions are used from dissectors to + 1, register the ability to tap packets from this subdissector + 2, push packets encountered by the subdissector to anyone tapping +*/ + +/* This function registers that a dissector has the packet tap ability + available. The name parameter is the name of this tap and extensions can + use open_tap(char *name,... to specify that it wants to receive packets/ + events from this tap. + + This function is only to be called once, when the dissector initializes. + + The return value from this call is later used as a parameter to the + tap_packet(unsinged int *tap_id,... + call so that the tap subsystem knows to which tap point this tapped + packet is associated. +*/ +int +register_tap(char *name) +{ + tap_dissector_t *td, *tdl; + int i; + + td=g_malloc(sizeof(tap_dissector_t)); + td->next=NULL; + td->name = g_strdup(name); + + if(!tap_dissector_list){ + tap_dissector_list=td; + i=1; + } else { + for(i=2,tdl=tap_dissector_list;tdl->next;i++,tdl=tdl->next) + ; + tdl->next=td; + } + return i; +} + + +/* Everytime the dissector has finished dissecting a packet (and all + subdissectors have returned) and if the dissector has been made "tappable" + it will push some data to everyone tapping this layer by a call + to tap_queue_packet(). + The first parameter is the tap_id returned by the register_tap() + call for this dissector (so the tap system can keep track of who it came + from and who is listening to it) + The second is the packet_info structure which many tap readers will find + interesting. + The third argument is specific to each tap point or NULL if no additional + data is available to this tap. A tap point in say IP will probably want to + push the IP header structure here. Same thing for TCP and ONCRPC. + + The pinfo and the specific pointer are what is supplied to every listener + in the read_callback() call made to every one currently listening to this + tap. + + The tap reader is responsible to know how to parse any structure pointed + to by the tap specific data pointer. +*/ +void +tap_queue_packet(int tap_id, packet_info *pinfo, void *tap_specific_data) +{ + tap_packet_t *tpt; + + if(!tapping_is_active){ + return; + } + + /* get a free tap_packet structure, this is CHEAP */ + tpt=tap_packet_list_free; + tap_packet_list_free=tpt->next; + tpt->next=tap_packet_list_queue; + tap_packet_list_queue=tpt; + + tpt->tap_id=tap_id; + tpt->pinfo=pinfo; + tpt->tap_specific_data=tap_specific_data; + +} + + + + + +/* ********************************************************************** + * Functions used by file.c to drive the tap subsystem + * ********************************************************************** */ +/* This function is used to delete/initialize the tap queue and prime an + epan_dissect_t with all the filters for tap listeners. + To free the tap queue, we just prepend the used queue to the free queue. +*/ +void +tap_queue_init(epan_dissect_t *edt) +{ + tap_packet_t *tpt; + tap_listener_t *tl; + + /* nothing to do, just return */ + if(!tap_listener_queue){ + return; + } + + tapping_is_active=TRUE; + tpt=tap_packet_list_queue; + if(tpt){ + for(;tpt->next;tpt=tpt->next) + ; + + tpt->next=tap_packet_list_free; + tap_packet_list_free=tap_packet_list_queue; + tap_packet_list_queue=NULL; + } + + /* loop over all tap listeners and build the list of all + interesting hf_fields */ + for(tl=(tap_listener_t *)tap_listener_queue;tl;tl=tl->next){ + if(tl->code){ + epan_dissect_prime_dfilter(edt, tl->code); + } + } +} + +/* this function is called after a packet has been fully dissected to push the tapped + data to all extensions that has callbacks registered. +*/ +void +tap_push_tapped_queue(epan_dissect_t *edt) +{ + tap_packet_t *tp; + tap_listener_t *tl; + + /* nothing to do, just return */ + if(!tapping_is_active){ + return; + } + + tapping_is_active=FALSE; + + /* nothing to do, just return */ + if(!tap_packet_list_queue){ + return; + } + + /* loop over all tap listeners and call the listener callback + for all packets that match the filter. */ + for(tp=tap_packet_list_queue;tp;tp=tp->next){ + for(tl=(tap_listener_t *)tap_listener_queue;tl;tl=tl->next){ + if(tp->tap_id==tl->tap_id){ + int passed=TRUE; + if(tl->code){ + passed=dfilter_apply_edt(tl->code, edt); + } + if(passed && tl->packet){ + tl->needs_redraw|=tl->packet(tl->tapdata, tp->pinfo, edt, tp->tap_specific_data); + } + } + } + } +} + +/* This function is called when we need to reset all tap listeners, for example + when we open/start a new capture or if we need to rescan the packet list. +*/ +void +reset_tap_listeners(void) +{ + tap_listener_t *tl; + + for(tl=(tap_listener_t *)tap_listener_queue;tl;tl=tl->next){ + if(tl->reset){ + tl->reset(tl->tapdata); + } + tl->needs_redraw=1; + } + +} + + +/* This function is called when we need to redraw all tap listeners, for example + when we open/start a new capture or if we need to rescan the packet list. + this one should be called from a low priority thread say once every 3 seconds + + If draw_all is true, redraw all aplications regardless if they have + changed or not. +*/ +void +draw_tap_listeners(gboolean draw_all) +{ + tap_listener_t *tl; + + for(tl=(tap_listener_t *)tap_listener_queue;tl;tl=tl->next){ + if(tl->needs_redraw || draw_all){ + if(tl->draw){ + tl->draw(tl->tapdata); + } + } + tl->needs_redraw=0; + } +} + + + +/* ********************************************************************** + * Functions used by tap to + * 1, register that a really simple extension is available for use by + * ethereal. + * 2, start tapping from a subdissector + * 3, close an already open tap + * ********************************************************************** */ +/* this function will return the tap_id for the specific protocol tap + or 0 if no such tap was found. + */ +int +find_tap_id(char *name) +{ + tap_dissector_t *td; + int i; + + for(i=1,td=tap_dissector_list;td;i++,td=td->next) { + if(!strcmp(td->name,name)){ + return i; + } + } + return 0; +} + +/* this function attaches the tap_listener to the named tap. + * function returns : + * NULL: ok. + * non-NULL: error, return value points to GString containing error + * message. + */ +GString * +register_tap_listener(char *tapname, void *tapdata, char *fstring, tap_reset_cb reset, tap_packet_cb packet, tap_draw_cb draw) +{ + tap_listener_t *tl; + int tap_id; + GString *error_string; + + tap_id=find_tap_id(tapname); + if(!tap_id){ + error_string = g_string_new(""); + g_string_sprintf(error_string, "Tap %s not found", tapname); + return error_string; + } + + tl=g_malloc(sizeof(tap_listener_t)); + tl->code=NULL; + tl->needs_redraw=1; + if(fstring){ + if(!dfilter_compile(fstring, &tl->code)){ + error_string = g_string_new(""); + g_string_sprintf(error_string, + "Filter \"%s\" is invalid - %s", + fstring, dfilter_error_msg); + g_free(tl); + return error_string; + } else { + num_tap_filters++; + } + } + + tl->tap_id=tap_id; + tl->tapdata=tapdata; + tl->reset=reset; + tl->packet=packet; + tl->draw=draw; + tl->next=(tap_listener_t *)tap_listener_queue; + + tap_listener_queue=tl; + + return NULL; +} + +/* this function removes a tap listener + */ +void +remove_tap_listener(void *tapdata) +{ + tap_listener_t *tl=NULL,*tl2; + + if(!tap_listener_queue){ + return; + } + + if(tap_listener_queue->tapdata==tapdata){ + tl=(tap_listener_t *)tap_listener_queue; + tap_listener_queue=tap_listener_queue->next; + } else { + for(tl2=(tap_listener_t *)tap_listener_queue;tl2->next;tl2=tl2->next){ + if(tl2->next->tapdata==tapdata){ + tl=tl2->next; + tl2->next=tl2->next->next; + break; + } + + } + } + + if(tl){ + if(tl->code){ + dfilter_free(tl->code); + num_tap_filters--; + } + g_free(tl); + } + + return; +} + +/* + * Return TRUE if we have tap listeners, FALSE otherwise. + * Checking "num_tap_filters" isn't the right way to check whether we need + * to do any dissection in order to run taps, as not all taps necessarily + * have filters, and "num_tap_filters" is the number of tap filters, not + * the number of tap listeners; it's only the right way to check whether + * we need to build a protocol tree when doing dissection. + */ +gboolean +have_tap_listeners(void) +{ + return tap_listener_queue != NULL; +} diff --git a/epan/tap.h b/epan/tap.h new file mode 100644 index 0000000000..491ed3cae5 --- /dev/null +++ b/epan/tap.h @@ -0,0 +1,54 @@ +/* tap.h + * packet tap interface 2002 Ronnie Sahlberg + * + * $Id$ + * + * Ethereal - Network traffic analyzer + * By Gerald Combs <gerald@ethereal.com> + * Copyright 1998 Gerald Combs + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef _TAP_H_ +#define _TAP_H_ + +#include "epan/epan.h" + +/* With MSVC and a libethereal.dll, we need a + * special declaration of num_tap_filters. + */ +ETH_VAR_IMPORT int num_tap_filters; + +typedef void (*tap_reset_cb)(void *tapdata); +typedef int (*tap_packet_cb)(void *tapdata, packet_info *pinfo, epan_dissect_t *edt, void *data); +typedef void (*tap_draw_cb)(void *tapdata); + + +extern void tap_init(void); +extern int register_tap(char *name); +extern int find_tap_id(char *name); +extern void tap_queue_packet(int tap_id, packet_info *pinfo, void *tap_specific_data); +extern void tap_queue_init(epan_dissect_t *edt); +extern void tap_push_tapped_queue(epan_dissect_t *edt); +extern void reset_tap_listeners(void); +extern void draw_tap_listeners(gboolean draw_all); +extern GString *register_tap_listener(char *tapname, void *tapdata, + char *fstring, tap_reset_cb tap_reset, tap_packet_cb tap_packet, + tap_draw_cb tap_draw); +extern void remove_tap_listener(void *tapdata); +extern gboolean have_tap_listeners(void); + +#endif |