diff --git a/CMakeLists.txt b/CMakeLists.txt index 75db872ef8..d578351c24 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -761,10 +761,6 @@ if(WIN32) ) endif() -set(WTAP_PLUGIN_SOURCES - epan/plugins.c -) - set(SHARK_COMMON_CAPTURE_SRC capture_ifinfo.c capture_ui_utils.c @@ -1071,7 +1067,6 @@ if(BUILD_mergecap) set(mergecap_FILES mergecap.c svnversion.h - ${WTAP_PLUGIN_SOURCES} ) add_executable(mergecap ${mergecap_FILES}) add_dependencies(mergecap svnversion) @@ -1090,7 +1085,6 @@ if(BUILD_reordercap) set(reordercap_FILES reordercap.c svnversion.h - ${WTAP_PLUGIN_SOURCES} ) add_executable(reordercap ${reordercap_FILES}) add_dependencies(reordercap svnversion) @@ -1110,7 +1104,6 @@ if(BUILD_capinfos) ) set(capinfos_FILES capinfos.c - ${WTAP_PLUGIN_SOURCES} ) add_executable(capinfos ${capinfos_FILES}) add_dependencies(capinfos svnversion) @@ -1128,7 +1121,6 @@ if(BUILD_editcap) ) set(editcap_FILES editcap.c - ${WTAP_PLUGIN_SOURCES} ) add_executable(editcap ${editcap_FILES}) add_dependencies(editcap svnversion) diff --git a/Makefile.am b/Makefile.am index 3ea7abaab6..6a46f4c9ac 100644 --- a/Makefile.am +++ b/Makefile.am @@ -311,13 +311,9 @@ plugin_ldadd = $(_CUSTOM_plugin_ldadd_) \ -dlopen plugins/wimax/wimax.la \ -dlopen plugins/wimaxmacphy/wimaxmacphy.la -WTAP_PLUGIN_SOURCES = \ - epan/plugins.c - else # HAVE_PLUGINS plugin_ldadd = -WTAP_PLUGIN_SOURCES = endif # HAVE_PLUGINS @@ -389,7 +385,11 @@ if HAVE_Qt wireshark_qt_SOURCES = $(WIRESHARK_COMMON_SRC) wireshark_qt_INCLUDES = $(WIRESHARK_COMMON_INCLUDES) wireshark_qt_CFLAGS = $(AM_CLEAN_CFLAGS) $(py_dissectors_dir) -wireshark_qt_LDADD = ui/qt/libqtui.a $(wireshark_ldadd) @Qt_LIBS@ +wireshark_qt_LDADD = \ + ui/qt/libqtui.a \ + $(wireshark_ldadd) \ + @Qt_LIBS@ + # # XXX - this makes wireshark_qt_LDFLAGS not work; we should figure out # another way to get wireshark-qt linked as a C++ program, perhaps by @@ -403,7 +403,10 @@ if HAVE_GTK wireshark_SOURCES = $(WIRESHARK_COMMON_SRC) wireshark_INCLUDES = $(WIRESHARK_COMMON_INCLUDES) wireshark_CFLAGS = $(AM_CLEAN_CFLAGS) $(py_dissectors_dir) -wireshark_LDADD = ui/gtk/libgtkui.a $(wireshark_ldadd) @GTK_LIBS@ +wireshark_LDADD = \ + ui/gtk/libgtkui.a \ + $(wireshark_ldadd) \ + @GTK_LIBS@ endif # Ideally we could trigger automatic c++ linking here with diff --git a/Makefile.common b/Makefile.common index 5e2f255071..1462286479 100644 --- a/Makefile.common +++ b/Makefile.common @@ -147,8 +147,7 @@ mergecap_SOURCES = \ # editcap specifics editcap_SOURCES = \ - editcap.c \ - $(WTAP_PLUGIN_SOURCES) + editcap.c # reordercap specifics reordercap_SOURCES = \ @@ -157,8 +156,7 @@ reordercap_SOURCES = \ # capinfos specifics capinfos_SOURCES = \ - capinfos.c \ - $(WTAP_PLUGIN_SOURCES) + capinfos.c # dftest specifics dftest_SOURCES = \ diff --git a/Makefile.nmake b/Makefile.nmake index 64119998ff..03d575f869 100644 --- a/Makefile.nmake +++ b/Makefile.nmake @@ -53,9 +53,6 @@ CFLAGS=$(WARNINGS_ARE_ERRORS) $(GENERATED_CFLAGS) PLATFORM_SRC = capture-wpcap.c capture_wpcap_packet.c capture_win_ifnames.c -WTAP_PLUGIN_SOURCES = \ - epan/plugins.c - include Makefile.common wireshark_OBJECTS = $(WIRESHARK_COMMON_SRC:.c=.obj) diff --git a/capinfos.c b/capinfos.c index 893901579c..29a3fe03dc 100644 --- a/capinfos.c +++ b/capinfos.c @@ -78,17 +78,9 @@ #include #include -/* - * The symbols declared in the below are exported from libwireshark, - * but we don't want to link whole libwireshark to capinfos. - * We link the object directly instead and this needs a little trick - * with the WS_BUILD_DLL #define. - */ -#define WS_BUILD_DLL -#define RESET_SYMBOL_EXPORT -#include -#undef WS_BUILD_DLL -#define RESET_SYMBOL_EXPORT +#ifdef HAVE_PLUGINS +#include +#endif #include "wtap.h" #include @@ -1144,14 +1136,21 @@ main(int argc, char *argv[]) init_process_policies(); #ifdef HAVE_PLUGINS - /* Register wiretap plugins */ - if ((init_progfile_dir_error = init_progfile_dir(argv[0], main))) { g_warning("capinfos: init_progfile_dir(): %s", init_progfile_dir_error); g_free(init_progfile_dir_error); } else { + /* Register all the plugin types we have. */ + wtap_register_plugin_types(); /* Types known to libwiretap */ + init_report_err(failure_message,NULL,NULL,NULL); - init_plugins(); + + /* Scan for plugins. This does *not* call their registration routines; + that's done later. */ + scan_plugins(); + + /* Register all libwiretap plugin modules. */ + register_all_wiretap_modules(); } #endif diff --git a/codecs/Makefile.am b/codecs/Makefile.am index 73f9612864..1ce407f129 100644 --- a/codecs/Makefile.am +++ b/codecs/Makefile.am @@ -1,10 +1,10 @@ # Makefile.am -# Automake file for the codecs for Wireshark +# Automake file for the libcodec library for Wireshark # # $Id$ # # Wireshark - Network traffic analyzer -# By Gerald Combs +# By Gerald Combs # Copyright 1998 Gerald Combs # # This program is free software; you can redistribute it and/or @@ -21,6 +21,9 @@ # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +include Makefile.common +include ../Makefile.am.inc + if HAVE_WARNINGS_AS_ERRORS AM_CFLAGS = -Werror endif @@ -28,31 +31,27 @@ endif noinst_LIBRARIES = libcodec.a CLEANFILES = \ - libcodec.a \ - *~ + libcodec.a \ + *~ MAINTAINERCLEANFILES = \ - Makefile.in + Makefile.in +# All sources that should be put in the source distribution tarball libcodec_a_SOURCES = \ - codecs.c codecs.h \ - G711a/G711adecode.c G711a/G711adecode.h G711a/G711atable.h \ - G711u/G711udecode.c G711u/G711udecode.h G711u/G711utable.h \ - G722/G722decode.c G722/G722decode.h \ - G726/G726decode.c G726/G726decode.h \ - sbc/sbc.c sbc/sbc.h + $(LIBCODEC_SRC) \ + $(noinst_HEADERS) libcodec_a_DEPENDENCIES = -EXTRA_DIST = \ - Makefile.nmake \ - CMakeLists.txt +# Common headers +AM_CPPFLAGS = -I$(top_srcdir) -I$(top_srcdir)/wiretap -checkapi: +checkapi: $(PERL) ../tools/checkAPIs.pl -g abort -g termoutput -build \ - codecs.c \ - G711a/G711adecode.c \ - G711u/G711udecode.c \ - G722/G722decode.c \ - G726/G726decode.c \ - sbc/sbc.c + $(LIBCODEC_SRC) + +EXTRA_DIST = \ + CMakeLists.txt \ + Makefile.common \ + Makefile.nmake diff --git a/codecs/Makefile.common b/codecs/Makefile.common new file mode 100644 index 0000000000..42009472c0 --- /dev/null +++ b/codecs/Makefile.common @@ -0,0 +1,41 @@ +# Makefile.common +# Contains the stuff from Makefile.am and Makefile.nmake that is +# a) common to both files and +# b) portable between both files +# +# $Id$ +# +# Wireshark - Network traffic analyzer +# By Gerald Combs +# 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + +LIBCODEC_SRC = \ + codecs.c \ + G711a/G711adecode.c \ + G711u/G711udecode.c \ + G722/G722decode.c \ + G726/G726decode.c \ + sbc/sbc.c + +noinst_HEADERS = \ + codecs.h \ + G711a/G711adecode.h G711a/G711atable.h \ + G711u/G711udecode.h G711u/G711utable.h \ + G722/G722decode.h \ + G726/G726decode.h \ + sbc/sbc.h + diff --git a/codecs/Makefile.nmake b/codecs/Makefile.nmake index 821cd5c00a..d2cbc4e35e 100644 --- a/codecs/Makefile.nmake +++ b/codecs/Makefile.nmake @@ -4,6 +4,7 @@ # $Id$ include ..\config.nmake +include ..\Makefile.nmake.inc ############### no need to modify below this line ######### @@ -11,9 +12,16 @@ CFLAGS=/I.. $(WARNINGS_ARE_ERRORS) $(STANDARD_CFLAGS) \ $(GLIB_CFLAGS) .c.obj:: - $(CC) $(CFLAGS) -Fd.\ -c $< + $(CC) $(CFLAGS) -Fd.\ -c $< -CODEC_OBJECTS= \ +include Makefile.common + +# if you add files here, be sure to include them also in Makefile.am EXTRA_DIST +# XXX - if the codec files weren't in subdirectories, we could just do +# LIBCODEC_OBJECTS = $(LIBCODEC_SRC:.c=.obj), and wouldn't need rules +# for each of the codecs below +# +LIBCODEC_OBJECTS= \ codecs.obj \ G711udecode.obj \ G711adecode.obj \ @@ -21,10 +29,8 @@ CODEC_OBJECTS= \ G726decode.obj \ sbc.obj - -codecs.lib : $(CODEC_OBJECTS) - link /lib /out:codecs.lib $(CODEC_OBJECTS) - +codecs.lib : $(LIBCODEC_OBJECTS) + link /lib /out:codecs.lib $(LIBCODEC_OBJECTS) codecs.obj: codecs.c codecs.h $(CC) $(CFLAGS) -Fd.\ -c codecs.c /Fo%|fF.obj @@ -45,7 +51,7 @@ sbc.obj: sbc\sbc.c sbc\sbc.h $(CC) $(CFLAGS) -Fd.\ -c sbc\sbc.c /Fo%|fF.obj clean: - rm -f $(CODEC_OBJECTS) codecs.lib *.pdb *.sbr + rm -f $(LIBCODEC_OBJECTS) codecs.lib *.pdb *.sbr distclean: clean @@ -53,9 +59,4 @@ maintainer-clean: distclean checkapi: $(PERL) ../tools/checkAPIs.pl -g abort -g termoutput -build \ - codecs.c \ - G711a/G711adecode.c \ - G711u/G711udecode.c \ - G722/G722decode.c \ - G726/G726decode.c \ - sbc/sbc.c + $(LIBCODEC_SRC) diff --git a/codecs/codecs.c b/codecs/codecs.c index 0cb397f99b..abe3eaa714 100644 --- a/codecs/codecs.c +++ b/codecs/codecs.c @@ -22,9 +22,82 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ +#include "config.h" + #include #include "codecs.h" +#ifdef HAVE_PLUGINS + +#include + +#include + +/* + * List of codec plugins. + */ +typedef struct { + void (*register_codec_module)(void); /* routine to call to register a codec */ +} codec_plugin; + +static GSList *codec_plugins = NULL; + +/* + * Callback for each plugin found. + */ +static gboolean +check_for_codec_plugin(GModule *handle) +{ + gpointer gp; + void (*register_codec_module)(void); + codec_plugin *plugin; + + /* + * Do we have a register_codec_module routine? + */ + if (!g_module_symbol(handle, "register_codec_module", &gp)) { + /* No, so this isn't a codec plugin. */ + return FALSE; + } + + /* + * Yes - this plugin includes one or more codecs. + */ + register_codec_module = (void (*)(void))gp; + + /* + * Add this one to the list of codec plugins. + */ + plugin = (codec_plugin *)g_malloc(sizeof (codec_plugin)); + plugin->register_codec_module = register_codec_module; + codec_plugins = g_slist_append(codec_plugins, plugin); + return TRUE; +} + +void +codec_register_plugin_types(void) +{ + add_plugin_type("codec", check_for_codec_plugin); +} + +static void +register_codec_plugin(gpointer data, gpointer user_data _U_) +{ + codec_plugin *plugin = (codec_plugin *)data; + + (plugin->register_codec_module)(); +} + +/* + * For all codec plugins, call their register routines. + */ +void +register_all_codecs(void) +{ + g_slist_foreach(codec_plugins, register_codec_plugin, NULL); +} +#endif /* HAVE_PLUGINS */ + struct codec_handle { const char *name; codec_init_fn init_fn; diff --git a/codecs/codecs.h b/codecs/codecs.h index 9231fe8455..f293e26f2d 100644 --- a/codecs/codecs.h +++ b/codecs/codecs.h @@ -25,6 +25,20 @@ #ifndef _CODECS_H_ #define _CODECS_H_ +#include "config.h" + +#include +#include "ws_symbol_export.h" + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#ifdef HAVE_PLUGINS +extern void codec_register_plugin_types(void); +extern void register_all_codecs(void); +#endif + struct codec_handle; typedef struct codec_handle *codec_handle_t; @@ -38,4 +52,8 @@ extern void *codec_init(codec_handle_t codec); extern void codec_release(codec_handle_t codec, void *context); extern int codec_decode(codec_handle_t codec, void *context, const void *input, int inputSizeBytes, void *output, int *outputSizeBytes); -#endif +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* _CODECS_H_ */ diff --git a/dftest.c b/dftest.c index 3192d3e9f8..d4f4cdf251 100644 --- a/dftest.c +++ b/dftest.c @@ -31,15 +31,17 @@ #include #include -#include +#include #include -#include +#include +#include + +#include #include #include -#include + #include "ui/util.h" -#include "epan/dfilter/dfilter.h" #include "register.h" static void failure_message(const char *msg_format, va_list ap); diff --git a/editcap.c b/editcap.c index e28f8b2676..7f9bdba555 100644 --- a/editcap.c +++ b/editcap.c @@ -80,18 +80,7 @@ #include #include #include - -/* - * The symbols declared in the below are exported from libwireshark, - * but we don't want to link whole libwireshark to editcap. - * We link the object directly instead and this needs a little trick - * with the WS_BUILD_DLL #define. - */ -#define WS_BUILD_DLL -#define RESET_SYMBOL_EXPORT /* wsutil/wsgetopt.h set export behavior above. */ -#include "epan/plugins.h" -#undef WS_BUILD_DLL -#define RESET_SYMBOL_EXPORT +#include #include "svnversion.h" @@ -910,8 +899,17 @@ main(int argc, char *argv[]) g_warning("editcap: init_progfile_dir(): %s", init_progfile_dir_error); g_free(init_progfile_dir_error); } else { + /* Register all the plugin types we have. */ + wtap_register_plugin_types(); /* Types known to libwiretap */ + init_report_err(failure_message,NULL,NULL,NULL); - init_plugins(); + + /* Scan for plugins. This does *not* call their registration routines; + that's done later. */ + scan_plugins(); + + /* Register all libwiretap plugin modules. */ + register_all_wiretap_modules(); } #endif diff --git a/epan/CMakeLists.txt b/epan/CMakeLists.txt index dea24df3a2..21dd8d2605 100644 --- a/epan/CMakeLists.txt +++ b/epan/CMakeLists.txt @@ -1503,7 +1503,6 @@ set(LIBWIRESHARK_FILES osi-utils.c packet-range.c packet.c - plugins.c print.c prefs.c proto.c diff --git a/epan/Makefile.common b/epan/Makefile.common index b3462760ee..0cb1052e19 100644 --- a/epan/Makefile.common +++ b/epan/Makefile.common @@ -70,7 +70,6 @@ LIBWIRESHARK_SRC = \ osi-utils.c \ packet-range.c \ packet.c \ - plugins.c \ prefs.c \ print.c \ proto.c \ @@ -218,7 +217,6 @@ LIBWIRESHARK_INCLUDES = \ packet.h \ packet_info.h \ params.h \ - plugins.h \ ppptypes.h \ print.h \ prefs.h \ diff --git a/epan/epan.c b/epan/epan.c index 6cb06f4c7b..80a4648e73 100644 --- a/epan/epan.c +++ b/epan/epan.c @@ -74,6 +74,20 @@ epan_get_version(void) { return VERSION; } +/* + * Register all the plugin types that are part of libwireshark, namely + * dissector and tap plugins. + * + * Must be called before init_plugins(), which must be called before + * any registration routines are called. + */ +void +epan_register_plugin_types(void) +{ + register_dissector_plugin_type(); + register_tap_plugin_type(); +} + void epan_init(void (*register_all_protocols_func)(register_cb cb, gpointer client_data), void (*register_all_handoffs_func)(register_cb cb, gpointer client_data), diff --git a/epan/epan.h b/epan/epan.h index 44f2d4c51b..9347fb69f7 100644 --- a/epan/epan.h +++ b/epan/epan.h @@ -81,6 +81,16 @@ Ref2 for further edits - delete when done - \ref airpcapdefs - \ref radiotap */ +/* + * Register all the plugin types that are part of libwireshark. + * + * Must be called before init_plugins(), which must be called before + * any registration routines are called, i.e. before epan_init(). + * + * Must be called only once in a program. + */ +WS_DLL_PUBLIC void epan_register_plugin_types(void); + /** init the whole epan module, this is used to be called only once in a program */ WS_DLL_PUBLIC void epan_init(void (*register_all_protocols_func)(register_cb cb, gpointer client_data), diff --git a/epan/packet.c b/epan/packet.c index 0ad68a5547..9befce39d1 100644 --- a/epan/packet.c +++ b/epan/packet.c @@ -47,7 +47,6 @@ #include "addr_resolv.h" #include "tvbuff.h" -#include "plugins.h" #include "epan_dissect.h" #include "emem.h" diff --git a/epan/plugins.c b/epan/plugins.c deleted file mode 100644 index 1104267118..0000000000 --- a/epan/plugins.c +++ /dev/null @@ -1,575 +0,0 @@ -/* plugins.c - * plugin routines - * - * $Id$ - * - * Wireshark - Network traffic analyzer - * By Gerald Combs - * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -#include "config.h" - -#include "plugins.h" -#include - -/* linked list of Lua plugins */ -wslua_plugin *wslua_plugin_list = NULL; - -#ifdef HAVE_PLUGINS - -#include - -#ifdef HAVE_DIRENT_H -#include -#endif - -#ifdef HAVE_DIRECT_H -#include -#endif - -#include -#include -#include - -#ifdef HAVE_UNISTD_H -#include -#endif - -#include "wsutil/filesystem.h" -#include -#include -#include - -/* linked list of all plugins */ -plugin *plugin_list = NULL; - -static void register_all_wiretap_modules(void); -static void register_all_codecs(void); - -/* - * add a new plugin to the list - * returns : - * - 0 : OK - * - ENOMEM : memory allocation problem - * - EEXIST : the same plugin (i.e. name/version) was already registered. - */ -static int -add_plugin(void *handle, gchar *name, gchar *version, - void (*register_protoinfo)(void), - void (*reg_handoff)(void), - void (*register_tap_listener)(void), - void (*register_wtap_module)(void), - void (*register_codec_module)(void)) -{ - plugin *new_plug, *pt_plug; - - pt_plug = plugin_list; - if (!pt_plug) /* the list is empty */ - { - new_plug = (plugin *)g_malloc(sizeof(plugin)); - if (new_plug == NULL) - return ENOMEM; - plugin_list = new_plug; - } - else - { - while (1) - { - /* check if the same name/version is already registered */ - if (!strcmp(pt_plug->name, name) && - !strcmp(pt_plug->version, version)) - { - return EEXIST; - } - - /* we found the last plugin in the list */ - if (pt_plug->next == NULL) - break; - - pt_plug = pt_plug->next; - } - new_plug = (plugin *)g_malloc(sizeof(plugin)); - if (new_plug == NULL) - return ENOMEM; - pt_plug->next = new_plug; - } - - new_plug->handle = (GModule *)handle; - new_plug->name = name; - new_plug->version = version; - new_plug->register_protoinfo = register_protoinfo; - new_plug->reg_handoff = reg_handoff; - new_plug->register_tap_listener = register_tap_listener; - new_plug->register_wtap_module = register_wtap_module; - new_plug->register_codec_module = register_codec_module; - new_plug->next = NULL; - - return 0; -} - -/* - * XXX - when we remove support for old-style plugins (which we should - * probably do eventually, as all plugins should be written as new-style - * ones), we may want to have "init_plugins()" merely save a pointer - * to the plugin's "init" routine, just as we save a pointer to its - * "reg_handoff" routine, and have a "register_all_plugins()" routine - * to go through the list of plugins and call all of them. - * - * Then we'd have "epan_init()", or perhaps even something higher up - * in the call tree, call "init_plugins()", and have "proto_init()" - * call "register_all_plugins()" right after calling "register_all_protocols()"; - * this might be a bit cleaner. - */ -static void -plugins_scan_dir(const char *dirname) -{ -#define FILENAME_LEN 1024 - WS_DIR *dir; /* scanned directory */ - WS_DIRENT *file; /* current file */ - const char *name; - gchar filename[FILENAME_LEN]; /* current file name */ - GModule *handle; /* handle returned by g_module_open */ - gchar *version; - gpointer gp; - void (*register_protoinfo)(void); - void (*reg_handoff)(void); - void (*register_tap_listener)(void); - void (*register_wtap_module)(void); - void (*register_codec_module)(void); - - gchar *dot; - int cr; - - if ((dir = ws_dir_open(dirname, 0, NULL)) != NULL) - { - while ((file = ws_dir_read_name(dir)) != NULL) - { - name = ws_dir_get_name(file); - - /* - * GLib 2.x defines G_MODULE_SUFFIX as the extension used on - * this platform for loadable modules. - */ - /* skip anything but files with G_MODULE_SUFFIX */ - dot = strrchr(name, '.'); - if (dot == NULL || strcmp(dot+1, G_MODULE_SUFFIX) != 0) - continue; - - g_snprintf(filename, FILENAME_LEN, "%s" G_DIR_SEPARATOR_S "%s", - dirname, name); - if ((handle = g_module_open(filename, (GModuleFlags)0)) == NULL) - { - report_failure("Couldn't load module %s: %s", filename, - g_module_error()); - continue; - } - - if (!g_module_symbol(handle, "version", &gp)) - { - report_failure("The plugin %s has no version symbol", name); - g_module_close(handle); - continue; - } - version = (char *)gp; - - /* - * Do we have a register routine? - */ - if (g_module_symbol(handle, "plugin_register", &gp)) - { - /* - * Yes - this plugin includes one or more dissectors. - */ - register_protoinfo = (void (*)(void))gp; - } - else - { - /* - * No - no dissectors. - */ - register_protoinfo = NULL; - } - - /* - * Do we have a reg_handoff routine? - */ - if (g_module_symbol(handle, "plugin_reg_handoff", &gp)) - { - /* - * Yes. - */ - reg_handoff = (void (*)(void))gp; - } - else - { - /* - * No - that's OK even if we have dissectors, as long - * as the plugin registers by name *and* there's - * a caller looking for that name. - */ - reg_handoff = NULL; - } - - /* - * Do we have a register_tap_listener routine? - */ - if (g_module_symbol(handle, "plugin_register_tap_listener", &gp)) - { - /* - * Yes - this plugin includes one or more taps. - */ - register_tap_listener = (void (*)(void))gp; - } - else - { - /* - * No - no taps here. - */ - register_tap_listener = NULL; - } - - /* - * Do we have an old-style init routine? - */ - if (g_module_symbol(handle, "plugin_init", &gp)) - { - /* - * Yes - do we also have a register routine or a - * register_tap_listener routine? If so, this is a bogus - * hybrid of an old-style and new-style plugin. - */ - if (register_protoinfo != NULL || register_tap_listener != NULL) - { - report_failure("The plugin '%s' has an old plugin init routine\nand a new register or register_tap_listener routine.", - name); - g_module_close(handle); - continue; - } - - /* - * It's just an unsupported old-style plugin; - */ - report_failure("The plugin '%s' has an old plugin init routine. Support has been dropped.\n Information on how to update your plugin is available at \nhttp://anonsvn.wireshark.org/wireshark/trunk/doc/README.plugins", - name); - g_module_close(handle); - continue; - } - - /* - * Do we have a register_wtap_module routine? - */ - if (g_module_symbol(handle, "register_wtap_module", &gp)) - { - register_wtap_module = (void (*)(void))gp; - } - else - { - register_wtap_module = NULL; - } - - /* - * Do we have a register_codec_module routine? - */ - if (g_module_symbol(handle, "register_codec_module", &gp)) - { - register_codec_module = (void (*)(void))gp; - } - else - { - register_codec_module = NULL; - } - - /* - * Does this dissector do anything useful? - */ - if (register_protoinfo == NULL && - register_tap_listener == NULL && - register_wtap_module == NULL && - register_codec_module == NULL ) - { - /* - * No. - */ - report_failure("The plugin '%s' has neither a register routine, " - "a register_tap_listener or a register_wtap_module or a register_codec_module routine", - name); - g_module_close(handle); - continue; - } - - /* - * OK, attempt to add it to the list of plugins. - */ - if ((cr = add_plugin(handle, g_strdup(name), version, - register_protoinfo, reg_handoff, - register_tap_listener,register_wtap_module,register_codec_module))) - { - if (cr == EEXIST) - fprintf(stderr, "The plugin %s, version %s\n" - "was found in multiple directories\n", name, version); - else - fprintf(stderr, "Memory allocation problem\n" - "when processing plugin %s, version %s\n", - name, version); - g_module_close(handle); - continue; - } - - } - ws_dir_close(dir); - } -} - - -/* - * init plugins - */ -void -init_plugins(void) -{ - const char *plugin_dir; - const char *name; - char *plugin_dir_path; - char *plugins_pers_dir; - WS_DIR *dir; /* scanned directory */ - WS_DIRENT *file; /* current file */ - - if (plugin_list == NULL) /* ensure init_plugins is only run once */ - { - /* - * Scan the global plugin directory. - * If we're running from a build directory, scan the subdirectories - * of that directory, as the global plugin directory is the - * "plugins" directory of the source tree, and the subdirectories - * are the source directories for the plugins, with the plugins - * built in those subdirectories. - */ - plugin_dir = get_plugin_dir(); - if (running_in_build_directory()) - { - if ((dir = ws_dir_open(plugin_dir, 0, NULL)) != NULL) - { - while ((file = ws_dir_read_name(dir)) != NULL) - { - name = ws_dir_get_name(file); - if (strcmp(name, ".") == 0 || strcmp(name, "..") == 0) - continue; /* skip "." and ".." */ - /* - * Get the full path of a ".libs" subdirectory of that - * directory. - */ - plugin_dir_path = g_strdup_printf( - "%s" G_DIR_SEPARATOR_S "%s" G_DIR_SEPARATOR_S ".libs", - plugin_dir, name); - if (test_for_directory(plugin_dir_path) != EISDIR) { - /* - * Either it doesn't refer to a directory or it - * refers to something that doesn't exist. - * - * Assume that means that the plugins are in - * the subdirectory of the plugin directory, not - * a ".libs" subdirectory of that subdirectory. - */ - g_free(plugin_dir_path); - plugin_dir_path = g_strdup_printf("%s" G_DIR_SEPARATOR_S "%s", - plugin_dir, name); - } - plugins_scan_dir(plugin_dir_path); - g_free(plugin_dir_path); - } - ws_dir_close(dir); - } - } - else - plugins_scan_dir(plugin_dir); - - /* - * If the program wasn't started with special privileges, - * scan the users plugin directory. (Even if we relinquish - * them, plugins aren't safe unless we've *permanently* - * relinquished them, and we can't do that in Wireshark as, - * if we need privileges to start capturing, we'd need to - * reclaim them before each time we start capturing.) - */ - if (!started_with_special_privs()) - { - plugins_pers_dir = get_plugins_pers_dir(); - plugins_scan_dir(plugins_pers_dir); - g_free(plugins_pers_dir); - } - } - - register_all_wiretap_modules(); - register_all_codecs(); -} - -void -register_all_plugin_registrations(void) -{ - plugin *pt_plug; - - /* - * For all plugins with register-handoff routines, call the routines. - * This is called from "proto_init()"; it must be called after - * "register_all_protocols()" and "init_plugins()" are called, - * in case one plugin registers itself either with a built-in - * dissector or with another plugin; we must first register all - * dissectors, whether built-in or plugin, so their dissector tables - * are initialized, and only then register all handoffs. - */ - for (pt_plug = plugin_list; pt_plug != NULL; pt_plug = pt_plug->next) - { - if (pt_plug->register_protoinfo) - (pt_plug->register_protoinfo)(); - } -} - -void -register_all_plugin_handoffs(void) -{ - plugin *pt_plug; - - /* - * For all plugins with register-handoff routines, call the routines. - * This is called from "proto_init()"; it must be called after - * "register_all_protocols()" and "init_plugins()" are called, - * in case one plugin registers itself either with a built-in - * dissector or with another plugin; we must first register all - * dissectors, whether built-in or plugin, so their dissector tables - * are initialized, and only then register all handoffs. - */ - for (pt_plug = plugin_list; pt_plug != NULL; pt_plug = pt_plug->next) - { - if (pt_plug->reg_handoff) - (pt_plug->reg_handoff)(); - } -} - -void -register_all_plugin_tap_listeners(void) -{ - plugin *pt_plug; - - /* - * For all plugins with register-tap-listener routines, call the - * routines. - */ - for (pt_plug = plugin_list; pt_plug != NULL; pt_plug = pt_plug->next) - { - if (pt_plug->register_tap_listener) - (pt_plug->register_tap_listener)(); - } -} - -static void -register_all_wiretap_modules(void) -{ - plugin *pt_plug; - - /* - * For all plugins with register_wtap_module routines, call the - * routines. - */ - for (pt_plug = plugin_list; pt_plug != NULL; pt_plug = pt_plug->next) - { - if (pt_plug->register_wtap_module) - (pt_plug->register_wtap_module)(); - } -} - -static void -register_all_codecs(void) -{ - plugin *pt_plug; - - /* - * For all plugins with register_wtap_module routines, call the - * routines. - */ - for (pt_plug = plugin_list; pt_plug != NULL; pt_plug = pt_plug->next) - { - if (pt_plug->register_codec_module) - (pt_plug->register_codec_module)(); - } -} - -#endif /* big HAVE_PLUGINS */ - -/* - * Dump plugin info to stdout. Copied from ui/gtk/plugins_dlg.c:plugins_scan. - */ -void -plugins_dump_all(void) -{ -#ifdef HAVE_PLUGINS - plugin *pt_plug; - const char *sep; -#endif -#ifdef HAVE_LUA - wslua_plugin *lua_plug; -#endif - -#ifdef HAVE_PLUGINS - for (pt_plug = plugin_list; pt_plug != NULL; pt_plug = pt_plug->next) - { - sep = ""; - - printf("%s\t%s\t", pt_plug->name, pt_plug->version); - if (pt_plug->register_protoinfo) - { - printf("dissector"); - sep = ", "; - } - if (pt_plug->register_tap_listener) - { - printf("%stap", sep); - sep = ", "; - } - if (pt_plug->register_wtap_module) - { - printf("%sfile format", sep); - sep = ", "; - } - if (pt_plug->register_codec_module) - { - printf("%scodec", sep); - } - printf("\t%s\n", g_module_name(pt_plug->handle)); - } -#endif - -#ifdef HAVE_LUA - for (lua_plug = wslua_plugin_list; lua_plug != NULL; lua_plug = lua_plug->next) - { - printf("%s\t%s\tlua script\t%s\n", lua_plug->name, lua_plug->version, lua_plug->filename); - } -#endif -} - -/* - * Editor modelines - * - * Local Variables: - * c-basic-offset: 4 - * tab-width: 8 - * indent-tabs-mode: nil - * End: - * - * ex: set shiftwidth=4 tabstop=8 expandtab: - * :indentSize=4:tabSize=8:noTabs=true: - */ diff --git a/epan/proto.c b/epan/proto.c index f5c1f4205e..f3df3254a6 100644 --- a/epan/proto.c +++ b/epan/proto.c @@ -41,7 +41,6 @@ #include "strutil.h" #include "addr_resolv.h" #include "oids.h" -#include "plugins.h" #include "proto.h" #include "epan_dissect.h" #include "tvbuff.h" @@ -57,6 +56,8 @@ #include "wspython/wspy_register.h" +#include + #define SUBTREE_ONCE_ALLOCATION_NUMBER 8 #define SUBTREE_MAX_LEVELS 256 /* Throw an exception if we exceed this many tree items. */ @@ -324,6 +325,87 @@ proto_compare_name(gconstpointer p1_arg, gconstpointer p2_arg) return g_ascii_strcasecmp(p1->short_name, p2->short_name); } +#ifdef HAVE_PLUGINS +/* + * List of dissector plugins. + */ +typedef struct { + void (*register_protoinfo)(void); /* routine to call to register protocol information */ + void (*reg_handoff)(void); /* routine to call to register dissector handoff */ +} dissector_plugin; + +static GSList *dissector_plugins = NULL; + +/* + * Callback for each plugin found. + */ +static gboolean +check_for_dissector_plugin(GModule *handle) +{ + gpointer gp; + void (*register_protoinfo)(void); + void (*reg_handoff)(void); + dissector_plugin *plugin; + + /* + * Do we have a register routine? + */ + if (g_module_symbol(handle, "plugin_register", &gp)) + register_protoinfo = (void (*)(void))gp; + else + register_protoinfo = NULL; + + /* + * Do we have a reg_handoff routine? + */ + if (g_module_symbol(handle, "plugin_reg_handoff", &gp)) + reg_handoff = (void (*)(void))gp; + else + reg_handoff = NULL; + + /* + * If we have neither, we're not a dissector plugin. + */ + if (register_protoinfo == NULL && reg_handoff == NULL) + return FALSE; + + /* + * Add this one to the list of dissector plugins. + */ + plugin = (dissector_plugin *)g_malloc(sizeof (dissector_plugin)); + plugin->register_protoinfo = register_protoinfo; + plugin->reg_handoff = reg_handoff; + dissector_plugins = g_slist_append(dissector_plugins, plugin); + return TRUE; +} + +static void +register_dissector_plugin(gpointer data, gpointer user_data _U_) +{ + dissector_plugin *plugin = (dissector_plugin *)data; + + if (plugin->register_protoinfo) + (plugin->register_protoinfo)(); +} + +static void +reg_handoff_dissector_plugin(gpointer data, gpointer user_data _U_) +{ + dissector_plugin *plugin = (dissector_plugin *)data; + + if (plugin->reg_handoff) + (plugin->reg_handoff)(); +} + +/* + * Register dissector plugin type. + */ +void +register_dissector_plugin_type(void) +{ + add_plugin_type("dissector", check_for_dissector_plugin); +} +#endif /* HAVE_PLUGINS */ /* initialize data structures and register protocols and fields */ void @@ -368,12 +450,11 @@ proto_init(void (register_all_protocols_func)(register_cb cb, gpointer client_da #endif #ifdef HAVE_PLUGINS - /* Now scan for plugins and load all the ones we find, calling - their register routines to do the stuff described above. */ + /* Now call the registration routines for all disssector + plugins. */ if (cb) (*cb)(RA_PLUGIN_REGISTER, NULL, client_data); - init_plugins(); - register_all_plugin_registrations(); + g_slist_foreach(dissector_plugins, register_dissector_plugin, NULL); #endif /* Now call the "handoff registration" routines of all built-in @@ -393,7 +474,7 @@ proto_init(void (register_all_protocols_func)(register_cb cb, gpointer client_da /* Now do the same with plugins. */ if (cb) (*cb)(RA_PLUGIN_HANDOFF, NULL, client_data); - register_all_plugin_handoffs(); + g_slist_foreach(dissector_plugins, reg_handoff_dissector_plugin, NULL); #endif /* sort the protocols by protocol name */ diff --git a/epan/proto.h b/epan/proto.h index ad12588f6f..0578325d17 100644 --- a/epan/proto.h +++ b/epan/proto.h @@ -603,6 +603,10 @@ WS_DLL_PUBLIC void proto_tree_children_foreach(proto_tree *tree, /** Retrieve the wmem_allocator_t from a proto_node */ #define PNODE_POOL(proto_node) ((proto_node)->tree_data->pinfo->pool) +/** Register dissector plugin type with the plugin system. + Called by epan_register_plugin_types(); do not call it yourself. */ +extern void register_dissector_plugin_type(void); + /** Sets up memory used by proto routines. Called at program startup */ void proto_init(void (register_all_protocols_func)(register_cb cb, gpointer client_data), void (register_all_handoffs_func)(register_cb cb, gpointer client_data), diff --git a/epan/tap.c b/epan/tap.c index 7ac5e54bc6..f4036afdb6 100644 --- a/epan/tap.c +++ b/epan/tap.c @@ -77,6 +77,77 @@ typedef struct _tap_listener_t { } tap_listener_t; static volatile tap_listener_t *tap_listener_queue=NULL; +#ifdef HAVE_PLUGINS + +#include + +#include + +/* + * List of tap plugins. + */ +typedef struct { + void (*register_tap_listener_fn)(void); /* routine to call to register tap listener */ +} tap_plugin; + +static GSList *tap_plugins = NULL; + +/* + * Callback for each plugin found. + */ +static gboolean +check_for_tap_plugin(GModule *handle) +{ + gpointer gp; + void (*register_tap_listener_fn)(void); + tap_plugin *plugin; + + /* + * Do we have a register_tap_listener routine? + */ + if (!g_module_symbol(handle, "plugin_register_tap_listener", &gp)) { + /* No, so this isn't a tap plugin. */ + return FALSE; + } + + /* + * Yes - this plugin includes one or more taps. + */ + register_tap_listener_fn = (void (*)(void))gp; + + /* + * Add this one to the list of tap plugins. + */ + plugin = (tap_plugin *)g_malloc(sizeof (tap_plugin)); + plugin->register_tap_listener_fn = register_tap_listener_fn; + tap_plugins = g_slist_append(tap_plugins, plugin); + return TRUE; +} + +void +register_tap_plugin_type(void) +{ + add_plugin_type("tap", check_for_tap_plugin); +} + +static void +register_tap_plugin_listener(gpointer data, gpointer user_data _U_) +{ + tap_plugin *plugin = (tap_plugin *)data; + + (plugin->register_tap_listener_fn)(); +} + +/* + * For all tap plugins, call their register routines. + */ +void +register_all_plugin_tap_listeners(void) +{ + g_slist_foreach(tap_plugins, register_tap_plugin_listener, NULL); +} +#endif /* HAVE_PLUGINS */ + /* ********************************************************************** * Init routine only called from epan at application startup * ********************************************************************** */ @@ -87,8 +158,6 @@ void tap_init(void) { tap_packet_index=0; - - return; } /* ********************************************************************** diff --git a/epan/tap.h b/epan/tap.h index b95b98df94..692cd39c22 100644 --- a/epan/tap.h +++ b/epan/tap.h @@ -46,6 +46,20 @@ typedef void (*tap_draw_cb)(void *tapdata); #define TL_IS_DISSECTOR_HELPER 0x00000004 /**< tap helps a dissector do work ** but does not, itself, require dissection */ +/** Register tap plugin type with the plugin system. + Called by epan_register_plugin_types(); do not call it yourself. */ +extern void register_tap_plugin_type(void); + +/* + * For all tap plugins, call their register routines. + * Must be called after init_plugins(), and must be called only once in + * a program. + * + * XXX - should probably be handled by epan_init(), as the tap mechanism + * is part of libwireshark. + */ +WS_DLL_PUBLIC void register_all_plugin_tap_listeners(void); + extern void tap_init(void); /** This function registers that a dissector has the packet tap ability diff --git a/epan/wslua/init_wslua.c b/epan/wslua/init_wslua.c index afee46d91c..0f353e48e2 100644 --- a/epan/wslua/init_wslua.c +++ b/epan/wslua/init_wslua.c @@ -34,10 +34,19 @@ #include #include #include -#include #include #include +/* linked list of Lua plugins */ +typedef struct _wslua_plugin { + gchar *name; /**< plugin name */ + gchar *version; /**< plugin version */ + gchar *filename; /**< plugin filename */ + struct _wslua_plugin *next; +} wslua_plugin; + +static wslua_plugin *wslua_plugin_list = NULL; + static lua_State* L = NULL; packet_info* lua_pinfo; @@ -360,6 +369,30 @@ int wslua_count_plugins(void) { return plugins_counter; } +void wslua_plugins_get_descriptions(wslua_plugin_description_callback callback, void *user_data) { + wslua_plugin *lua_plug; + + for (lua_plug = wslua_plugin_list; lua_plug != NULL; lua_plug = lua_plug->next) + { + callback(lua_plug->name, lua_plug->version, "lua script", + lua_plug->filename, user_data); + } +} + +static void +print_wslua_plugin_description(const char *name, const char *version, + const char *description, const char *filename, + void *user_data _U_) +{ + printf("%s\t%s\t%s\t%s\n", name, version, description, filename); +} + +void +wslua_plugins_dump_all(void) +{ + wslua_plugins_get_descriptions(print_wslua_plugin_description, NULL); +} + int wslua_init(register_cb cb, gpointer client_data) { gchar* filename; const funnel_ops_t* ops = funnel_get_funnel_ops(); diff --git a/epan/wslua/init_wslua.h b/epan/wslua/init_wslua.h index 9072e6b9b1..72d083eb96 100644 --- a/epan/wslua/init_wslua.h +++ b/epan/wslua/init_wslua.h @@ -25,6 +25,14 @@ #ifndef __INIT_WSLUA_H__ #define __INIT_WSLUA_H__ +#include "ws_symbol_export.h" + WS_DLL_PUBLIC int wslua_count_plugins(void); +typedef void (*wslua_plugin_description_callback)(const char *, const char *, + const char *, const char *, + void *); +WS_DLL_PUBLIC void wslua_plugins_get_descriptions(wslua_plugin_description_callback callback, void *user_data); +WS_DLL_PUBLIC void wslua_plugins_dump_all(void); + #endif /* __INIT_WSLUA_H__ */ diff --git a/rawshark.c b/rawshark.c index b86de656b3..7dd8b793d3 100644 --- a/rawshark.c +++ b/rawshark.c @@ -70,6 +70,7 @@ #include #include #include +#include #include "globals.h" #include @@ -85,7 +86,6 @@ #include "clopts_common.h" #include "cmdarg_err.h" #include "version_info.h" -#include #include "register.h" #include "conditions.h" #include "capture_stop_conditions.h" diff --git a/tshark.c b/tshark.c index c8d9c5bd9e..73d0ed8309 100644 --- a/tshark.c +++ b/tshark.c @@ -70,6 +70,7 @@ #include "globals.h" #include #include +#include #include "file.h" #include "frame_tvbuff.h" #include @@ -81,7 +82,6 @@ #include "clopts_common.h" #include "cmdarg_err.h" #include "version_info.h" -#include #include "register.h" #include #include @@ -106,6 +106,10 @@ #include "log.h" #include +#ifdef HAVE_PLUGINS +#include +#endif + /* * This is the template for the decode as option; it is shared between the * various functions that output the usage for this parameter. @@ -1097,6 +1101,19 @@ main(int argc, char *argv[]) timestamp_set_precision(TS_PREC_AUTO); timestamp_set_seconds_type(TS_SECONDS_DEFAULT); +#ifdef HAVE_PLUGINS + /* Register all the plugin types we have. */ + epan_register_plugin_types(); /* Types known to libwireshark */ + wtap_register_plugin_types(); /* Types known to libwiretap */ + + /* Scan for plugins. This does *not* call their registration routines; + that's done later. */ + scan_plugins(); + + /* Register all libwiretap plugin modules. */ + register_all_wiretap_modules(); +#endif + /* Register all dissectors; we must do this before checking for the "-G" flag, as the "-G" flag dumps information registered by the dissectors, and we must do it before we read the preferences, in @@ -1147,8 +1164,12 @@ main(int argc, char *argv[]) proto_registrar_dump_ftypes(); else if (strcmp(argv[2], "heuristic-decodes") == 0) dissector_dump_heur_decodes(); - else if (strcmp(argv[2], "plugins") == 0) +#ifdef HAVE_PLUGINS + else if (strcmp(argv[2], "plugins") == 0) { plugins_dump_all(); + wslua_plugins_dump_all(); + } +#endif else if (strcmp(argv[2], "protocols") == 0) proto_registrar_dump_protocols(); else if (strcmp(argv[2], "values") == 0) diff --git a/ui/gtk/about_dlg.c b/ui/gtk/about_dlg.c index 8d22e55665..c4e38346f6 100644 --- a/ui/gtk/about_dlg.c +++ b/ui/gtk/about_dlg.c @@ -25,12 +25,12 @@ #include "config.h" -#include - #include +#include + #include -#include +#include #ifdef HAVE_LIBSMI #include #endif @@ -43,6 +43,7 @@ #include "../log.h" #include "../version_info.h" +#include "../register.h" #include "ui/last_open_dir.h" diff --git a/ui/gtk/main.c b/ui/gtk/main.c index 72739e55b3..6affd20ea1 100644 --- a/ui/gtk/main.c +++ b/ui/gtk/main.c @@ -76,7 +76,6 @@ #include #include #include -#include #include #include #include @@ -92,6 +91,8 @@ #include #include +#include + /* general (not GTK specific) */ #include "../file.h" #include "../frame_tvbuff.h" @@ -124,6 +125,8 @@ #include "ui/iface_lists.h" #endif +#include "codecs/codecs.h" + #ifdef HAVE_LIBPCAP #include "capture_ui_utils.h" #include "capture-pcap-util.h" @@ -2518,6 +2521,23 @@ main(int argc, char *argv[]) g_free(init_progfile_dir_error); } +#ifdef HAVE_PLUGINS + /* Register all the plugin types we have. */ + epan_register_plugin_types(); /* Types known to libwireshark */ + wtap_register_plugin_types(); /* Types known to libwiretap */ + codec_register_plugin_types(); /* Types known to libcodec */ + + /* Scan for plugins. This does *not* call their registration routines; + that's done later. */ + scan_plugins(); + + /* Register all libwiretap plugin modules. */ + register_all_wiretap_modules(); + + /* Register all audio codec plugins. */ + register_all_codecs(); +#endif + splash_update(RA_DISSECTORS, NULL, (gpointer)splash_win); /* Register all dissectors; we must do this before checking for the diff --git a/ui/gtk/main_menubar.c b/ui/gtk/main_menubar.c index 03e617623b..ed677ba858 100644 --- a/ui/gtk/main_menubar.c +++ b/ui/gtk/main_menubar.c @@ -39,7 +39,6 @@ #include #include #include -#include #include #include #include diff --git a/ui/gtk/packet_win.c b/ui/gtk/packet_win.c index adc2c6c0a2..8b7de8906e 100644 --- a/ui/gtk/packet_win.c +++ b/ui/gtk/packet_win.c @@ -47,7 +47,6 @@ #include #include #include -#include #include #include #include diff --git a/ui/gtk/plugins_dlg.c b/ui/gtk/plugins_dlg.c index 3658969163..7cea52b5a7 100644 --- a/ui/gtk/plugins_dlg.c +++ b/ui/gtk/plugins_dlg.c @@ -26,7 +26,9 @@ #include -#include "epan/plugins.h" +#include + +#include #include "ui/gtk/dlg_utils.h" #include "ui/gtk/gui_utils.h" @@ -72,59 +74,24 @@ about_plugins_callback(GtkWidget *widget, GdkEventButton *event, gint id _U_) * XXX - We might want to combine this with plugins_dump_all(). */ static void +plugins_add_description(const char *name, const char *version, + const char *types, const char *filename, + void *user_data) +{ + GtkWidget *list = (GtkWidget *)user_data; + + simple_list_append(list, 0, name, 1, version, + 2, types, 3, filename, -1); +} +static void plugins_scan(GtkWidget *list) { #ifdef HAVE_PLUGINS - plugin *pt_plug; - const char *sep; -#endif -#ifdef HAVE_LUA - wslua_plugin *lua_plug; -#endif - GString *type; - -#ifdef HAVE_PLUGINS - for (pt_plug = plugin_list; pt_plug != NULL; pt_plug = pt_plug->next) - { - type = g_string_new(""); - sep = ""; - if (pt_plug->register_protoinfo) - { - type = g_string_append(type, "dissector"); - sep = ", "; - } - if (pt_plug->register_tap_listener) - { - type = g_string_append(type, sep); - type = g_string_append(type, "tap"); - sep = ", "; - } - if (pt_plug->register_wtap_module) - { - type = g_string_append(type, sep); - type = g_string_append(type, "file format"); - sep = ", "; - } - if (pt_plug->register_codec_module) - { - type = g_string_append(type, sep); - type = g_string_append(type, "codec"); - } - simple_list_append(list, 0, pt_plug->name, 1, pt_plug->version, - 2, type->str, 3, g_module_name(pt_plug->handle), -1); - g_string_free(type, TRUE); - } + plugins_get_descriptions(plugins_add_description, list); #endif #ifdef HAVE_LUA - for (lua_plug = wslua_plugin_list; lua_plug != NULL; lua_plug = lua_plug->next) - { - type = g_string_new(""); - type = g_string_append(type, "lua script"); - - simple_list_append(list, 0, lua_plug->name, 1, lua_plug->version, 2, type->str, 3, lua_plug->filename, -1); - g_string_free(type, TRUE); - } + wslua_plugins_get_descriptions(plugins_add_description, list); #endif } diff --git a/ui/gtk/rtp_player.c b/ui/gtk/rtp_player.c index 98a20f8795..acee55f804 100644 --- a/ui/gtk/rtp_player.c +++ b/ui/gtk/rtp_player.c @@ -64,9 +64,10 @@ #include #include #include -#include <../codecs/codecs.h> #include +#include + #include "../globals.h" #include "../codecs/G711a/G711adecode.h" #include "../codecs/G711u/G711udecode.h" diff --git a/ui/qt/main.cpp b/ui/qt/main.cpp index 85b8dbb004..b63692dac9 100644 --- a/ui/qt/main.cpp +++ b/ui/qt/main.cpp @@ -40,6 +40,9 @@ #include #include #include +#ifdef HAVE_PLUGINS +#include +#endif #include #include @@ -48,7 +51,6 @@ #include #include #include -#include #include #include #include @@ -66,6 +68,10 @@ #include #include +#ifdef HAVE_PLUGINS +#include +#endif + /* general (not Qt specific) */ #include "file.h" #include "summary.h" @@ -821,6 +827,23 @@ int main(int argc, char *argv[]) capture_session_init(&global_capture_session, (void *)&cfile); #endif +#ifdef HAVE_PLUGINS + /* Register all the plugin types we have. */ + epan_register_plugin_types(); /* Types known to libwireshark */ + wtap_register_plugin_types(); /* Types known to libwiretap */ + codec_register_plugin_types(); /* Types known to libcodec */ + + /* Scan for plugins. This does *not* call their registration routines; + that's done later. */ + scan_plugins(); + + /* Register all libwiretap plugin modules. */ + register_all_wiretap_modules(); + + /* Register all audio codec plugins. */ + register_all_codecs(); +#endif + /* Register all dissectors; we must do this before checking for the "-G" flag, as the "-G" flag dumps information registered by the dissectors, and we must do it before we read the preferences, in diff --git a/wiretap/wtap.c b/wiretap/wtap.c index c932d24c86..712a11b7da 100644 --- a/wiretap/wtap.c +++ b/wiretap/wtap.c @@ -43,6 +43,75 @@ #include #include "buffer.h" +#ifdef HAVE_PLUGINS + +#include + +/* + * List of wiretap plugins. + */ +typedef struct { + void (*register_wtap_module)(void); /* routine to call to register a wiretap module */ +} wtap_plugin; + +static GSList *wtap_plugins = NULL; + +/* + * Callback for each plugin found. + */ +static gboolean +check_for_wtap_plugin(GModule *handle) +{ + gpointer gp; + void (*register_wtap_module)(void); + wtap_plugin *plugin; + + /* + * Do we have a register_wtap_module routine? + */ + if (!g_module_symbol(handle, "register_wtap_module", &gp)) { + /* No, so this isn't a wiretap module plugin. */ + return FALSE; + } + + /* + * Yes - this plugin includes one or more wiretap modules. + */ + register_wtap_module = (void (*)(void))gp; + + /* + * Add this one to the list of wiretap module plugins. + */ + plugin = (wtap_plugin *)g_malloc(sizeof (wtap_plugin)); + plugin->register_wtap_module = register_wtap_module; + wtap_plugins = g_slist_append(wtap_plugins, plugin); + return TRUE; +} + +void +wtap_register_plugin_types(void) +{ + add_plugin_type("file format", check_for_wtap_plugin); +} + +static void +register_wtap_module_plugin(gpointer data, gpointer user_data _U_) +{ + wtap_plugin *plugin = (wtap_plugin *)data; + + (plugin->register_wtap_module)(); +} + +/* + * For all wiretap module plugins, call their register routines. + */ +void +register_all_wiretap_modules(void) +{ + g_slist_foreach(wtap_plugins, register_wtap_module_plugin, NULL); +} +#endif /* HAVE_PLUGINS */ + /* * Return the size of the file, as reported by the OS. * (gint64, in case that's 64 bits.) diff --git a/wiretap/wtap.h b/wiretap/wtap.h index eacdec32c0..1a89bfd7f5 100644 --- a/wiretap/wtap.h +++ b/wiretap/wtap.h @@ -1394,6 +1394,10 @@ GSList *wtap_get_file_extension_type_extensions(guint extension_type); /*** dynamically register new file types and encapsulations ***/ WS_DLL_PUBLIC +void wtap_register_plugin_types(void); +WS_DLL_PUBLIC +void register_all_wiretap_modules(void); +WS_DLL_PUBLIC void wtap_register_file_type_extension(const struct file_extension_info *ei); WS_DLL_PUBLIC void wtap_register_open_routine(wtap_open_routine_t, gboolean has_magic); diff --git a/wsutil/CMakeLists.txt b/wsutil/CMakeLists.txt index 283bd567a1..9ad86e8247 100644 --- a/wsutil/CMakeLists.txt +++ b/wsutil/CMakeLists.txt @@ -58,6 +58,7 @@ set(WSUTIL_FILES md5.c mpeg-audio.c nstime.c + plugins.c privileges.c sha1.c strnatcmp.c diff --git a/wsutil/Makefile.common b/wsutil/Makefile.common index 063c2a95b3..9a802b83e0 100644 --- a/wsutil/Makefile.common +++ b/wsutil/Makefile.common @@ -51,6 +51,7 @@ LIBWSUTIL_SRC = \ md5.c \ mpeg-audio.c \ nstime.c \ + plugins.c \ privileges.c \ sha1.c \ strnatcmp.c \ @@ -86,6 +87,7 @@ LIBWSUTIL_INCLUDES = \ md5.h \ mpeg-audio.h \ nstime.h \ + plugins.h \ privileges.h \ sha1.h \ strnatcmp.h \ diff --git a/wsutil/plugins.c b/wsutil/plugins.c new file mode 100644 index 0000000000..ebd337ca43 --- /dev/null +++ b/wsutil/plugins.c @@ -0,0 +1,415 @@ +/* plugins.c + * plugin routines + * + * $Id$ + * + * Wireshark - Network traffic analyzer + * By Gerald Combs + * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include "config.h" + +#ifdef HAVE_PLUGINS + +#include + +#ifdef HAVE_DIRENT_H +#include +#endif + +#ifdef HAVE_DIRECT_H +#include +#endif + +#include +#include +#include +#include + +#ifdef HAVE_UNISTD_H +#include +#endif + +#include +#include + +#include +#include +#include +#include + +#include + +/* linked list of all plugins */ +typedef struct _plugin { + GModule *handle; /* handle returned by g_module_open */ + gchar *name; /* plugin name */ + gchar *version; /* plugin version */ + guint32 types; /* bitmask of plugin types this plugin supports */ + struct _plugin *next; /* forward link */ +} plugin; + +static plugin *plugin_list = NULL; + +/* + * Add a new plugin type. + * Takes a callback routine as an argument; it is called for each plugin + * we find, and handed a handle for the plugin, the name of the plugin, + * and the version string for the plugin. The plugin returns TRUE if + * it's a plugin for that type and FALSE if not. + */ +typedef struct { + const char *type; + plugin_callback callback; + guint type_val; +} plugin_type; + +static GSList *plugin_types = NULL; + +void +add_plugin_type(const char *type, plugin_callback callback) +{ + plugin_type *new_type; + static guint type_val; + + if (type_val >= 32) { + /* + * There's a bitmask of types that a plugin provides, and it's + * 32 bits, so we don't support types > 31. + */ + report_failure("At most 32 plugin types can be supported, so the plugin type '%s' won't be supported.", + type); + return; + } + new_type = (plugin_type *)g_malloc(sizeof (plugin_type)); + new_type->type = type; + new_type->callback = callback; + new_type->type_val = type_val; + plugin_types = g_slist_append(plugin_types, new_type); + type_val++; +} + +/* + * add a new plugin to the list + * returns : + * - 0 : OK + * - ENOMEM : memory allocation problem + * - EEXIST : the same plugin (i.e. name/version) was already registered. + */ +static int +add_plugin(plugin *new_plug) +{ + plugin *pt_plug; + + pt_plug = plugin_list; + if (!pt_plug) /* the list is empty */ + { + plugin_list = new_plug; + } + else + { + while (1) + { + /* check if the same name/version is already registered */ + if (strcmp(pt_plug->name, new_plug->name) == 0 && + strcmp(pt_plug->version, new_plug->version) == 0) + { + return EEXIST; + } + + /* we found the last plugin in the list */ + if (pt_plug->next == NULL) + break; + + pt_plug = pt_plug->next; + } + pt_plug->next = new_plug; + } + + return 0; +} + +static void +call_plugin_callback(gpointer data, gpointer user_data) +{ + plugin_type *type = (plugin_type *)data; + plugin *new_plug = (plugin *)user_data; + + if ((*type->callback)(new_plug->handle)) { + /* The plugin supports this type */ + new_plug->types |= 1 << type->type_val; + } +} + +static void +plugins_scan_dir(const char *dirname) +{ +#define FILENAME_LEN 1024 + WS_DIR *dir; /* scanned directory */ + WS_DIRENT *file; /* current file */ + const char *name; + gchar filename[FILENAME_LEN]; /* current file name */ + GModule *handle; /* handle returned by g_module_open */ + gpointer gp; + plugin *new_plug; + gchar *dot; + int cr; + + if ((dir = ws_dir_open(dirname, 0, NULL)) != NULL) + { + while ((file = ws_dir_read_name(dir)) != NULL) + { + name = ws_dir_get_name(file); + + /* + * GLib 2.x defines G_MODULE_SUFFIX as the extension used on + * this platform for loadable modules. + */ + /* skip anything but files with G_MODULE_SUFFIX */ + dot = strrchr(name, '.'); + if (dot == NULL || strcmp(dot+1, G_MODULE_SUFFIX) != 0) + continue; + + g_snprintf(filename, FILENAME_LEN, "%s" G_DIR_SEPARATOR_S "%s", + dirname, name); + if ((handle = g_module_open(filename, (GModuleFlags)0)) == NULL) + { + report_failure("Couldn't load module %s: %s", filename, + g_module_error()); + continue; + } + + if (!g_module_symbol(handle, "version", &gp)) + { + report_failure("The plugin %s has no version symbol", name); + g_module_close(handle); + continue; + } + + new_plug = (plugin *)g_malloc(sizeof(plugin)); + new_plug->handle = handle; + new_plug->name = g_strdup(name); + new_plug->version = (char *)gp; + new_plug->types = 0; + new_plug->next = NULL; + + /* + * Hand the plugin to each of the plugin type callbacks. + */ + g_slist_foreach(plugin_types, call_plugin_callback, new_plug); + + /* + * Does this dissector do anything useful? + */ + if (new_plug->types == 0) + { + /* + * No. + */ + report_failure("The plugin '%s' has no registration routines", + name); + g_module_close(handle); + g_free(new_plug->name); + g_free(new_plug); + continue; + } + + /* + * OK, attempt to add it to the list of plugins. + */ + if ((cr = add_plugin(new_plug))) + { + if (cr == EEXIST) + fprintf(stderr, "The plugin %s, version %s\n" + "was found in multiple directories\n", + new_plug->name, new_plug->version); + else + fprintf(stderr, "Memory allocation problem\n" + "when processing plugin %s, version %s\n", + new_plug->name, new_plug->version); + g_module_close(handle); + g_free(new_plug->name); + g_free(new_plug); + continue; + } + + } + ws_dir_close(dir); + } +} + + +/* + * Scan for plugins. + */ +void +scan_plugins(void) +{ + const char *plugin_dir; + const char *name; + char *plugin_dir_path; + char *plugins_pers_dir; + WS_DIR *dir; /* scanned directory */ + WS_DIRENT *file; /* current file */ + + if (plugin_list == NULL) /* ensure scan_plugins is only run once */ + { + /* + * Scan the global plugin directory. + * If we're running from a build directory, scan the subdirectories + * of that directory, as the global plugin directory is the + * "plugins" directory of the source tree, and the subdirectories + * are the source directories for the plugins, with the plugins + * built in those subdirectories. + */ + plugin_dir = get_plugin_dir(); + if (running_in_build_directory()) + { + if ((dir = ws_dir_open(plugin_dir, 0, NULL)) != NULL) + { + while ((file = ws_dir_read_name(dir)) != NULL) + { + name = ws_dir_get_name(file); + if (strcmp(name, ".") == 0 || strcmp(name, "..") == 0) + continue; /* skip "." and ".." */ + /* + * Get the full path of a ".libs" subdirectory of that + * directory. + */ + plugin_dir_path = g_strdup_printf( + "%s" G_DIR_SEPARATOR_S "%s" G_DIR_SEPARATOR_S ".libs", + plugin_dir, name); + if (test_for_directory(plugin_dir_path) != EISDIR) { + /* + * Either it doesn't refer to a directory or it + * refers to something that doesn't exist. + * + * Assume that means that the plugins are in + * the subdirectory of the plugin directory, not + * a ".libs" subdirectory of that subdirectory. + */ + g_free(plugin_dir_path); + plugin_dir_path = g_strdup_printf("%s" G_DIR_SEPARATOR_S "%s", + plugin_dir, name); + } + plugins_scan_dir(plugin_dir_path); + g_free(plugin_dir_path); + } + ws_dir_close(dir); + } + } + else + plugins_scan_dir(plugin_dir); + + /* + * If the program wasn't started with special privileges, + * scan the users plugin directory. (Even if we relinquish + * them, plugins aren't safe unless we've *permanently* + * relinquished them, and we can't do that in Wireshark as, + * if we need privileges to start capturing, we'd need to + * reclaim them before each time we start capturing.) + */ + if (!started_with_special_privs()) + { + plugins_pers_dir = get_plugins_pers_dir(); + plugins_scan_dir(plugins_pers_dir); + g_free(plugins_pers_dir); + } + } +} + +/* + * Iterate over all plugins, calling a callback with information about + * the plugin. + */ +typedef struct { + plugin *pt_plug; + GString *types; + const char *sep; +} type_callback_info; + +static void +add_plugin_type_description(gpointer data, gpointer user_data) +{ + plugin_type *type = (plugin_type *)data; + type_callback_info *info = (type_callback_info *)user_data; + + /* + * If the plugin handles this type, add the type to the list of types. + */ + if (info->pt_plug->types & (1 << type->type_val)) { + g_string_append_printf(info->types, "%s%s", info->sep, type->type); + info->sep = ", "; + } +} + +WS_DLL_PUBLIC void +plugins_get_descriptions(plugin_description_callback callback, void *user_data) +{ + type_callback_info info; + + info.types = NULL; /* FUCK LLVM UP THE ASS WITH A RED HOT POKER */ + for (info.pt_plug = plugin_list; info.pt_plug != NULL; + info.pt_plug = info.pt_plug->next) + { + info.sep = ""; + info.types = g_string_new(""); + + /* + * Build a list of all the plugin types. + */ + g_slist_foreach(plugin_types, add_plugin_type_description, &info); + + /* + * And hand the information to the callback. + */ + callback(info.pt_plug->name, info.pt_plug->version, info.types->str, + g_module_name(info.pt_plug->handle), user_data); + + g_string_free(info.types, TRUE); + } +} + +static void +print_plugin_description(const char *name, const char *version, + const char *description, const char *filename, + void *user_data _U_) +{ + printf("%s\t%s\t%s\t%s\n", name, version, description, filename); +} + +void +plugins_dump_all(void) +{ + plugins_get_descriptions(print_plugin_description, NULL); +} + +#endif /* HAVE_PLUGINS */ + +/* + * Editor modelines + * + * Local Variables: + * c-basic-offset: 4 + * tab-width: 8 + * indent-tabs-mode: nil + * End: + * + * ex: set shiftwidth=4 tabstop=8 expandtab: + * :indentSize=4:tabSize=8:noTabs=true: + */ diff --git a/epan/plugins.h b/wsutil/plugins.h similarity index 52% rename from epan/plugins.h rename to wsutil/plugins.h index 10a4f5bfff..49d24970fa 100644 --- a/epan/plugins.h +++ b/wsutil/plugins.h @@ -32,38 +32,18 @@ extern "C" { #include #include -#include "packet.h" #include "ws_symbol_export.h" -typedef struct _plugin { - GModule *handle; /* handle returned by g_module_open */ - gchar *name; /* plugin name */ - gchar *version; /* plugin version */ - void (*register_protoinfo)(void); /* routine to call to register protocol information */ - void (*reg_handoff)(void); /* routine to call to register dissector handoff */ - void (*register_tap_listener)(void); /* routine to call to register tap listener */ - void (*register_wtap_module)(void); /* routine to call to register a wiretap module */ - void (*register_codec_module)(void); /* routine to call to register a codec */ - struct _plugin *next; /* forward link */ -} plugin; +typedef gboolean (*plugin_callback)(GModule *handle); -WS_DLL_PUBLIC plugin *plugin_list; - -extern void init_plugins(void); -extern void register_all_plugin_registrations(void); -extern void register_all_plugin_handoffs(void); -WS_DLL_PUBLIC void register_all_plugin_tap_listeners(void); +WS_DLL_PUBLIC void scan_plugins(void); +WS_DLL_PUBLIC void add_plugin_type(const char *type, plugin_callback callback); +typedef void (*plugin_description_callback)(const char *, const char *, + const char *, const char *, + void *); +WS_DLL_PUBLIC void plugins_get_descriptions(plugin_description_callback callback, void *user_data); WS_DLL_PUBLIC void plugins_dump_all(void); -typedef struct _wslua_plugin { - gchar *name; /**< plugin name */ - gchar *version; /**< plugin version */ - gchar *filename; /**< plugin filename */ - struct _wslua_plugin *next; -} wslua_plugin; - -WS_DLL_PUBLIC wslua_plugin *wslua_plugin_list; - #ifdef __cplusplus } #endif /* __cplusplus */