From 995812c5f1add94df1c237596939130c1704b099 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Valverde?= Date: Sun, 1 Oct 2017 00:56:03 +0100 Subject: [PATCH] Refactor plugin registration and loading MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Put different types of plugins (libwiretap, libwireshark) in different subdirectories, give libwiretap and libwireshark init routines that load the plugins, and have them scan the appropriate subdirectories so that we don't even *try* to, for example, load libwireshark plugins in programs that only use libwiretap. Compiled plugins are stored in subfolders of the plugin folders, with the subfolder name being the Wireshark minor version number (X.Y). There is another hierarchical level for each Wireshark library (libwireshark, libwscodecs and libwiretap). The folder names are respectively plugins/X.Y/{epan,codecs,wiretap}. Currently we only distribute "epan" (libwireshark) plugins. Change-Id: I3438787a6f45820d64ba4ca91cbe3c8864708acb Reviewed-on: https://code.wireshark.org/review/23983 Petri-Dish: João Valverde Tested-by: Petri Dish Buildbot Reviewed-by: João Valverde --- capinfos.c | 18 +- captype.c | 18 +- cmake/modules/WiresharkPlugin.cmake | 12 +- codecs/codecs.c | 75 ++--- codecs/codecs.h | 13 +- debian/libwireshark0.install | 2 +- debian/libwireshark0.symbols | 4 +- debian/libwiretap0.symbols | 2 +- debian/libwscodecs0.symbols | 5 +- debian/libwsutil0.symbols | 3 +- dftest.c | 9 - doc/README.plugins | 41 ++- doc/plugins.example/Makefile.am | 10 +- doc/plugins.example/configure.ac | 9 + doc/plugins.example/hello.c | 21 +- docbook/wsug_src/WSUG_app_files.asciidoc | 7 +- editcap.c | 19 +- epan/epan.c | 31 +- epan/epan.h | 14 +- epan/prefs.c | 36 +++ epan/prefs.h | 13 + epan/proto.c | 114 ++----- epan/proto.h | 13 +- epan/tap.c | 70 +---- epan/tap.h | 14 +- extcap/androiddump.c | 3 - mergecap.c | 20 +- packaging/nsis/wireshark.nsi | 34 +-- packaging/wix/DirectoryStructure.wxi | 4 +- packaging/wix/Plugins.wxi | 34 +-- plugins/Makefile.am.inc | 6 + plugins/docsis/CMakeLists.txt | 8 +- plugins/docsis/Makefile.am | 2 +- plugins/ethercat/CMakeLists.txt | 8 +- plugins/ethercat/Makefile.am | 2 +- plugins/gryphon/CMakeLists.txt | 8 +- plugins/gryphon/Makefile.am | 2 +- plugins/irda/CMakeLists.txt | 8 +- plugins/irda/Makefile.am | 2 +- plugins/mate/CMakeLists.txt | 8 +- plugins/mate/Makefile.am | 2 +- plugins/opcua/CMakeLists.txt | 8 +- plugins/opcua/Makefile.am | 2 +- plugins/pluginifdemo/CMakeLists.txt | 8 +- plugins/pluginifdemo/Makefile.am | 2 +- plugins/profinet/CMakeLists.txt | 8 +- plugins/profinet/Makefile.am | 2 +- plugins/stats_tree/CMakeLists.txt | 8 +- plugins/stats_tree/Makefile.am | 2 +- plugins/stats_tree/pinfo_stats_tree.h | 2 - plugins/stats_tree/stats_tree_plugin.c | 8 +- plugins/transum/CMakeLists.txt | 8 +- plugins/transum/Makefile.am | 2 +- plugins/unistim/CMakeLists.txt | 8 +- plugins/unistim/Makefile.am | 2 +- plugins/wimax/CMakeLists.txt | 8 +- plugins/wimax/Makefile.am | 2 +- plugins/wimaxasncp/CMakeLists.txt | 8 +- plugins/wimaxasncp/Makefile.am | 2 +- plugins/wimaxmacphy/CMakeLists.txt | 8 +- plugins/wimaxmacphy/Makefile.am | 2 +- randpkt.c | 21 +- reordercap.c | 19 +- sharkd.c | 20 +- tfshark.c | 10 - tools/make-plugin-reg.py | 74 ++--- tools/oss-fuzzshark/fuzzshark.c | 14 - tshark.c | 15 - ui/gtk/main.c | 23 +- wireshark-qt.cpp | 23 +- wireshark.pc.in | 1 + wiretap/wtap.c | 83 ++--- wiretap/wtap.h | 14 +- wsutil/plugins.c | 373 +++++++++-------------- wsutil/plugins.h | 18 +- 75 files changed, 578 insertions(+), 954 deletions(-) diff --git a/capinfos.c b/capinfos.c index 10de75e5f4..e51d6eaf15 100644 --- a/capinfos.c +++ b/capinfos.c @@ -1464,23 +1464,10 @@ main(int argc, char *argv[]) g_free(init_progfile_dir_error); } - wtap_init(); - -#ifdef HAVE_PLUGINS init_report_message(failure_warning_message, failure_warning_message, NULL, NULL, NULL); - /* Scan for plugins. This does *not* call their registration routines; - that's done later. - - Don't report failures to load plugins because most (non-wiretap) - plugins *should* fail to load (because we're not linked against - libwireshark and dissector plugins need libwireshark). */ - scan_plugins(DONT_REPORT_LOAD_FAILURE); - - /* Register all libwiretap plugin modules. */ - register_all_wiretap_modules(); -#endif + wtap_init(); /* Process the options */ while ((opt = getopt_long(argc, argv, "abcdehiklmoqrstuvxyzABCEFHIKLMNQRST", long_options, NULL)) !=-1) { @@ -1732,9 +1719,6 @@ exit: g_free(hash_buf); wtap_cleanup(); free_progdirs(); -#ifdef HAVE_PLUGINS - plugins_cleanup(); -#endif return overall_error_status; } diff --git a/captype.c b/captype.c index 826b6e6b9d..8cf0469e7b 100644 --- a/captype.c +++ b/captype.c @@ -142,23 +142,10 @@ main(int argc, char *argv[]) g_free(init_progfile_dir_error); } - wtap_init(); - -#ifdef HAVE_PLUGINS init_report_message(failure_warning_message, failure_warning_message, NULL, NULL, NULL); - /* Scan for plugins. This does *not* call their registration routines; - that's done later. - - Don't report failures to load plugins because most (non-wiretap) - plugins *should* fail to load (because we're not linked against - libwireshark and dissector plugins need libwireshark). */ - scan_plugins(DONT_REPORT_LOAD_FAILURE); - - /* Register all libwiretap plugin modules. */ - register_all_wiretap_modules(); -#endif + wtap_init(); /* Process the options */ while ((opt = getopt_long(argc, argv, "hv", long_options, NULL)) !=-1) { @@ -216,9 +203,6 @@ main(int argc, char *argv[]) wtap_cleanup(); free_progdirs(); -#ifdef HAVE_PLUGINS - plugins_cleanup(); -#endif return overall_error_status; } diff --git a/cmake/modules/WiresharkPlugin.cmake b/cmake/modules/WiresharkPlugin.cmake index f6f85678dc..161b68fe4a 100644 --- a/cmake/modules/WiresharkPlugin.cmake +++ b/cmake/modules/WiresharkPlugin.cmake @@ -25,7 +25,7 @@ macro(SET_MODULE_INFO _plugin _ver_major _ver_minor _ver_micro _ver_extra) configure_file(plugin.rc.in plugin.rc @ONLY) endmacro() -macro(ADD_PLUGIN_LIBRARY _plugin) +macro(ADD_PLUGIN_LIBRARY _plugin _subfolder) add_library(${_plugin} MODULE ${PLUGIN_FILES} ${CMAKE_CURRENT_BINARY_DIR}/plugin.rc @@ -49,10 +49,18 @@ macro(ADD_PLUGIN_LIBRARY _plugin) foreach(_config_type ${CMAKE_CONFIGURATION_TYPES}) string(TOUPPER ${_config_type} _config_upper) set_target_properties(${_plugin} PROPERTIES - LIBRARY_OUTPUT_DIRECTORY_${_config_upper} ${CMAKE_BINARY_DIR}/run/${_config_type}/${PLUGIN_VERSION_DIR} + LIBRARY_OUTPUT_DIRECTORY_${_config_upper} ${CMAKE_BINARY_DIR}/run/${_config_type}/${PLUGIN_VERSION_DIR}/${_subfolder} ) endforeach() target_link_libraries(${_plugin} epan) add_dependencies(plugins ${_plugin}) endmacro() + +macro(INSTALL_PLUGIN _plugin _subfolder) + install(TARGETS ${_plugin} + LIBRARY DESTINATION ${PLUGIN_INSTALL_LIBDIR}/${_subfolder} NAMELINK_SKIP + RUNTIME DESTINATION ${PLUGIN_INSTALL_LIBDIR} + ARCHIVE DESTINATION ${PLUGIN_INSTALL_LIBDIR} +) +endmacro() diff --git a/codecs/codecs.c b/codecs/codecs.c index 4e7eb60edd..b109a6af2b 100644 --- a/codecs/codecs.c +++ b/codecs/codecs.c @@ -43,65 +43,24 @@ #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. - */ -DIAG_OFF(pedantic) -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_prepend(codec_plugins, plugin); - return TRUE; -} -DIAG_ON(pedantic) +static plugins_t *libwscodecs_plugins; +static GSList *codecs_plugins = NULL; void -codec_register_plugin_types(void) +codecs_register_plugin(const codecs_plugin *plug) { - add_plugin_type("codec", check_for_codec_plugin); + codecs_plugins = g_slist_prepend(codecs_plugins, (codecs_plugin *)plug); } static void -register_codec_plugin(gpointer data, gpointer user_data _U_) +call_plugin_register_codec_module(gpointer data, gpointer user_data _U_) { - codec_plugin *plugin = (codec_plugin *)data; + codecs_plugin *plug = (codecs_plugin *)data; - (plugin->register_codec_module)(); + if (plug->register_codec_module) { + plug->register_codec_module(); + } } #endif /* HAVE_PLUGINS */ @@ -110,7 +69,7 @@ register_codec_plugin(gpointer data, gpointer user_data _U_) * For all codec plugins, call their register routines. */ void -register_all_codecs(void) +codecs_init(void) { register_codec("g711U", codec_g711u_init, codec_g711u_release, codec_g711u_get_channels, codec_g711u_get_frequency, codec_g711u_decode); @@ -150,10 +109,22 @@ register_all_codecs(void) #endif #ifdef HAVE_PLUGINS - g_slist_foreach(codec_plugins, register_codec_plugin, NULL); + libwscodecs_plugins = plugins_init("codecs"); + g_slist_foreach(codecs_plugins, call_plugin_register_codec_module, NULL); #endif /* HAVE_PLUGINS */ } +void +codecs_cleanup(void) +{ +#ifdef HAVE_PLUGINS + g_slist_free(codecs_plugins); + codecs_plugins = NULL; + plugins_cleanup(libwscodecs_plugins); + libwscodecs_plugins = NULL; +#endif +} + struct codec_handle { const char *name; diff --git a/codecs/codecs.h b/codecs/codecs.h index fabc734206..e8fe4fa12f 100644 --- a/codecs/codecs.h +++ b/codecs/codecs.h @@ -26,19 +26,28 @@ #include #include "ws_symbol_export.h" #include "ws_attributes.h" +#ifdef HAVE_PLUGINS +#include "wsutil/plugins.h" +#endif #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ #ifdef HAVE_PLUGINS -WS_DLL_PUBLIC void codec_register_plugin_types(void); +typedef struct { + void (*register_codec_module)(void); /* routine to call to register a codec */ +} codecs_plugin; + +WS_DLL_PUBLIC void codecs_register_plugin(const codecs_plugin *plug); #endif /** * For all built-in codecs and codec plugins, call their register routines. */ -WS_DLL_PUBLIC void register_all_codecs(void); +WS_DLL_PUBLIC void codecs_init(void); + +WS_DLL_PUBLIC void codecs_cleanup(void); /** * Get compile-time information for libraries used by libwscodecs. diff --git a/debian/libwireshark0.install b/debian/libwireshark0.install index 087cd229da..ce0509437c 100644 --- a/debian/libwireshark0.install +++ b/debian/libwireshark0.install @@ -1,2 +1,2 @@ usr/lib/*/libwireshark.so.* -usr/lib/*/wireshark/plugins/*/*.so +usr/lib/*/wireshark/plugins/*/epan/*.so diff --git a/debian/libwireshark0.symbols b/debian/libwireshark0.symbols index e9a3dc5e94..320cbbae79 100644 --- a/debian/libwireshark0.symbols +++ b/debian/libwireshark0.symbols @@ -533,7 +533,6 @@ libwireshark.so.0 libwireshark0 #MINVER# epan_load_settings@Base 2.3.0 epan_memmem@Base 1.9.1 epan_new@Base 1.12.0~rc1 - epan_register_plugin_types@Base 1.12.0~rc1 epan_strcasestr@Base 1.9.1 escape_string@Base 1.9.1 escape_string_len@Base 1.9.1 @@ -1116,6 +1115,7 @@ libwireshark.so.0 libwireshark0 #MINVER# proto_register_field_array@Base 1.9.1 proto_register_fields_manual@Base 1.12.0~rc1 proto_register_fields_section@Base 1.12.0~rc1 + proto_register_plugin@Base 2.5.0 proto_register_prefix@Base 1.9.1 proto_register_protocol@Base 1.9.1 proto_register_protocol_in_name_only@Base 2.3.0 @@ -1283,7 +1283,6 @@ libwireshark.so.0 libwireshark0 #MINVER# reassembly_table_register@Base 2.3.0 reassembly_table_destroy@Base 1.9.1 reassembly_table_init@Base 1.9.1 - register_all_plugin_tap_listeners@Base 1.9.1 register_all_protocol_handoffs@Base 1.9.1 register_all_protocols@Base 1.9.1 register_ber_oid_dissector@Base 2.1.0 @@ -1498,6 +1497,7 @@ libwireshark.so.0 libwireshark0 #MINVER# tap_listeners_dfilter_recompile@Base 2.0.0 tap_listeners_require_dissection@Base 1.9.1 tap_queue_packet@Base 1.9.1 + tap_register_plugin@Base 2.5.0 tcp_dissect_pdus@Base 1.9.1 tcp_port_to_display@Base 1.99.2 tfs_accept_reject@Base 1.9.1 diff --git a/debian/libwiretap0.symbols b/debian/libwiretap0.symbols index 9bd1a34b8e..b6a25d9008 100644 --- a/debian/libwiretap0.symbols +++ b/debian/libwiretap0.symbols @@ -16,7 +16,6 @@ libwiretap.so.0 libwiretap0 #MINVER# merge_string_to_idb_merge_mode@Base 1.99.9 open_info_name_to_type@Base 1.12.0~rc1 open_routines@Base 1.12.0~rc1 - register_all_wiretap_modules@Base 1.12.0~rc1 register_pcapng_block_type_handler@Base 1.99.0 register_pcapng_option_handler@Base 1.99.2 wtap_block_add_custom_option@Base 2.1.2 @@ -127,6 +126,7 @@ libwiretap.so.0 libwiretap0 #MINVER# wtap_register_file_type_extension@Base 1.12.0~rc1 wtap_register_file_type_subtypes@Base 1.12.0~rc1 wtap_register_open_info@Base 1.12.0~rc1 + wtap_register_plugin@Base 2.5.0 wtap_seek_read@Base 1.9.1 wtap_sequential_close@Base 1.9.1 wtap_set_bytes_dumped@Base 1.9.1 diff --git a/debian/libwscodecs0.symbols b/debian/libwscodecs0.symbols index 522525c5e3..b83aa5f1b5 100644 --- a/debian/libwscodecs0.symbols +++ b/debian/libwscodecs0.symbols @@ -3,11 +3,12 @@ libwscodecs.so.0 libwscodecs0 #MINVER# codec_get_channels@Base 2.1.0 codec_get_frequency@Base 2.1.0 codec_init@Base 2.1.0 - codec_register_plugin_types@Base 2.1.0 codec_release@Base 2.1.0 deregister_codec@Base 2.1.0 find_codec@Base 2.1.0 - register_all_codecs@Base 2.1.0 + codecs_init@Base 2.5.0 + codecs_cleanup@Base 2.5.0 + codecs_register_plugin@Base 2.5.0 codec_get_compiled_version_info@Base 2.3.0 register_codec@Base 2.1.0 ws_codec_resampler_destroy@Base 2.1.0 diff --git a/debian/libwsutil0.symbols b/debian/libwsutil0.symbols index e3fc6d4e85..dec3b35c7e 100644 --- a/debian/libwsutil0.symbols +++ b/debian/libwsutil0.symbols @@ -1,7 +1,6 @@ libwsutil.so.0 libwsutil0 #MINVER# AirPDcapWepDecrypt@Base 1.10.0 Eax_Decrypt@Base 1.12.0~rc1 - add_plugin_type@Base 1.12.0~rc1 adler32_bytes@Base 1.12.0~rc1 adler32_str@Base 1.12.0~rc1 alaw2linear@Base 1.12.0~rc1 @@ -139,7 +138,7 @@ libwsutil.so.0 libwsutil0 #MINVER# rsa_privkey_to_sexp@Base 2.5.0 running_in_build_directory@Base 1.12.0~rc1 running_with_special_privs@Base 1.10.0 - scan_plugins@Base 1.12.0~rc1 + plugins_init@Base 2.5.0 set_persconffile_dir@Base 1.12.0~rc1 set_persdatafile_dir@Base 1.12.0~rc1 set_profile_name@Base 1.12.0~rc1 diff --git a/dftest.c b/dftest.c index 481b5979c6..8ab101f604 100644 --- a/dftest.c +++ b/dftest.c @@ -72,15 +72,6 @@ main(int argc, char **argv) timestamp_set_type(TS_RELATIVE); 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 */ - - /* Scan for plugins. This does *not* call their registration routines; - that's done later. */ - scan_plugins(REPORT_LOAD_FAILURE); -#endif - wtap_init(); /* Register all dissectors; we must do this before checking for the diff --git a/doc/README.plugins b/doc/README.plugins index f66f993938..e06842571a 100644 --- a/doc/README.plugins +++ b/doc/README.plugins @@ -42,8 +42,8 @@ For your plugins/foo/Makefile.am file, see the corresponding file in plugins/gryphon. Replace all occurrences of "gryphon" in those files with "foo". -Your plugins/foo/Makefile.am also needs to list the main source file(s), -which exports register_*() and handoff_*(), for your dissector in the +Your plugins/foo/Makefile.am also needs to list the main source file +which exports plugin_register() for your dissector in the DISSECTOR_SRC variable. All other supporting source files should be listed in the DISSECTOR_SUPPORT_SRC variable. The header files for your dissector, if any, must be listed in the @@ -236,7 +236,39 @@ make install 5. Update "old style" plugins -5.1 How to update an "old style" plugin (using plugin_register and +5.1 How to update an "old style" plugin (since Wireshark 2.5) + +Plugins need exactly three visible symbols: plugin_version, plugin_release and +plugin_register. Each plugin is either a libwscodecs plugin, libwiretap plugin or +libwireshark plugin and the library will call "plugin_register" after +loading the plugin. "plugin_register" in turn calls all the hooks necessary +to enable the plugin. So if you had two function like so: + + WS_DLL_PUBLIC void plugin_register(void); + WS_DLL_PUBLIC void plugin_reg_handoff(void); + + void plugin_register(void) {...}; + void plugin_reg_handoff(void) {...}; + +You'll have to rewrite it as: + + WS_DLL_PUBLIC void plugin_register(void); + + static void proto_register_foo(void) {...}; + static void proto_reg_handoff_foo(void) {...}; + + void plugin_register(void) + { + static proto_plugin plugin_foo; + + plugin_foo.register_protoinfo = proto_register_foo; + plugin_foo.register_handoff = proto_reg_handoff_foo; + proto_register_plugin(&plugin_foo); + } + +See doc/plugins.example for an example. + +5.2 How to update an "old style" plugin (using plugin_register and plugin_reg_handoff functions). The plugin registration has changed with the extension of the build @@ -269,7 +301,7 @@ stips the parts outlined below: This will leave a clean dissector source file without plugin specifics. -5.2 How to update an "old style" plugin (using plugin_init function) +5.3 How to update an "old style" plugin (using plugin_init function) The plugin registering has changed between 0.10.9 and 0.10.10; everyone is encouraged to update their plugins as outlined below: @@ -283,7 +315,6 @@ is encouraged to update their plugins as outlined below: o Change the Makefile.am file to match the one of the DOCSIS plugin. - 6 How to plugin related interface options To demonstrate the functionality of the plugin interface options, a demonstration diff --git a/doc/plugins.example/Makefile.am b/doc/plugins.example/Makefile.am index df90503908..d33e186757 100644 --- a/doc/plugins.example/Makefile.am +++ b/doc/plugins.example/Makefile.am @@ -11,13 +11,15 @@ WARNFLAGS = -Wall -Wextra plugindir := $(shell PKG_CONFIG_PATH=$(PKG_CONFIG_PATH) $(PKG_CONFIG) --define-variable=libdir=$(libdir) --variable plugindir wireshark) -release_version := $(notdir $(plugindir)) +epan_plugindir = $(plugindir)/epan -plugin_LTLIBRARIES = hello.la +VERSION_RELEASE := $(shell PKG_CONFIG_PATH=$(PKG_CONFIG_PATH) $(PKG_CONFIG) --variable VERSION_RELEASE wireshark) + +epan_plugin_LTLIBRARIES = hello.la hello_la_SOURCES = hello.c -hello_la_CPPFLAGS = -DVERSION_RELEASE=\"$(release_version)\" +hello_la_CPPFLAGS = -DVERSION_RELEASE=\"$(VERSION_RELEASE)\" hello_la_CFLAGS = $(WIRESHARK_CFLAGS) -fvisibility=hidden $(WARNFLAGS) @@ -25,7 +27,7 @@ hello_la_LDFLAGS = -module -avoid-version -shared hello_la_LIBADD = $(WIRESHARK_LIBS) -homedir = $${HOME}/.local/lib/wireshark/plugins/$(release_version) +homedir = $${HOME}/.local/lib/wireshark/plugins/$(VERSION_RELEASE)/epan install-home: $(MKDIR_P) $(homedir) || exit 1; \ diff --git a/doc/plugins.example/configure.ac b/doc/plugins.example/configure.ac index 07e9845d10..df66a02cc2 100644 --- a/doc/plugins.example/configure.ac +++ b/doc/plugins.example/configure.ac @@ -22,6 +22,15 @@ AC_CONFIG_SRCDIR([hello.c]) dnl Requires Wireshark 2.5.0 or greater. PKG_CHECK_MODULES([WIRESHARK], [wireshark >= 2.5]) +saved_CFLAGS="$CFLAGS"; saved_LIBS="$LIBS"; +CFLAGS="$WIRESHARK_CFLAGS" +LIBS="$WIRESHARK_LIBS" +AC_CHECK_FUNCS([proto_register_plugin], + [AC_DEFINE([HAVE_PLUGINS], 1, [Define to 1 if Wireshark supports loading plugins])], + [AC_MSG_ERROR([Wireshark was compiled without support for plugins])] +) +CFLAGS="$saved_CFLAGS"; LIBS="$saved_LIBS" + AC_CONFIG_HEADER([config.h]) AC_CONFIG_FILES([Makefile]) diff --git a/doc/plugins.example/hello.c b/doc/plugins.example/hello.c index fce0a5372b..455b4741a6 100644 --- a/doc/plugins.example/hello.c +++ b/doc/plugins.example/hello.c @@ -12,6 +12,7 @@ #endif #include +#include #include #ifndef VERSION @@ -25,8 +26,6 @@ DLL_PUBLIC const gchar plugin_release[] = VERSION_RELEASE; DLL_PUBLIC void plugin_register(void); -DLL_PUBLIC void plugin_reg_handoff(void); - static int proto_hello = -1; static dissector_handle_t handle_hello; @@ -38,14 +37,26 @@ dissect_hello(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, void *dat return tvb_captured_length(tvb); } -void plugin_register(void) +static void +proto_register_hello(void) { - proto_hello = proto_register_protocol("Wireshark Hello Plugin", "Hello", "hello"); + proto_hello = proto_register_protocol("Wireshark Hello Plugin", "Hello WS", "hello_ws"); handle_hello = create_dissector_handle(dissect_hello, proto_hello); register_postdissector(handle_hello); } -void plugin_reg_handoff(void) +static void +proto_reg_handoff_hello(void) { /* empty */ } + +void +plugin_register(void) +{ + static proto_plugin plug; + + plug.register_protoinfo = proto_register_hello; + plug.register_handoff = proto_reg_handoff_hello; /* or NULL */ + proto_register_plugin(&plug); +} diff --git a/docbook/wsug_src/WSUG_app_files.asciidoc b/docbook/wsug_src/WSUG_app_files.asciidoc index 53deb2be80..d86db8eb62 100644 --- a/docbook/wsug_src/WSUG_app_files.asciidoc +++ b/docbook/wsug_src/WSUG_app_files.asciidoc @@ -461,7 +461,12 @@ machine code. Wireshark looks for plugins in both a personal plugin folder and a global plugin folder. Lua plugins are stored in the plugin folders; compiled plugins are stored in subfolders of the plugin folders, with -the subfolder name being the Wireshark minor version number (X.Y). +the subfolder name being the Wireshark minor version number (X.Y). There is +another hierarchical level for each Wireshark library (libwireshark, libwscodecs +and libwiretap). So for example the location for a libwireshark plugin +++foo.so++ (++foo.dll++ on Windows) would be __PLUGINDIR__++/X.Y/epan++ +(libwireshark used to be called libepan; the other folder names are ++codecs++ +and ++wiretap++). On Windows: diff --git a/editcap.c b/editcap.c index cc75f6baf5..1aaa136190 100644 --- a/editcap.c +++ b/editcap.c @@ -1027,24 +1027,10 @@ main(int argc, char *argv[]) g_free(init_progfile_dir_error); } - wtap_init(); - -#ifdef HAVE_PLUGINS - /* Register wiretap plugins */ init_report_message(failure_warning_message, failure_warning_message, NULL, NULL, NULL); - /* Scan for plugins. This does *not* call their registration routines; - that's done later. - - Don't report failures to load plugins because most (non-wiretap) - plugins *should* fail to load (because we're not linked against - libwireshark and dissector plugins need libwireshark). */ - scan_plugins(DONT_REPORT_LOAD_FAILURE); - - /* Register all libwiretap plugin modules. */ - register_all_wiretap_modules(); -#endif + wtap_init(); /* Process the options */ while ((opt = getopt_long(argc, argv, ":a:A:B:c:C:dD:E:F:hi:I:Lo:rs:S:t:T:vVw:", long_options, NULL)) != -1) { @@ -1846,9 +1832,6 @@ clean_exit: wtap_close(wth); wtap_cleanup(); free_progdirs(); -#ifdef HAVE_PLUGINS - plugins_cleanup(); -#endif return ret; } diff --git a/epan/epan.c b/epan/epan.c index 1940f21fbf..5b7a64ac74 100644 --- a/epan/epan.c +++ b/epan/epan.c @@ -94,6 +94,10 @@ static wmem_allocator_t *pinfo_pool_cache = NULL; +#ifdef HAVE_PLUGINS +plugins_t *libwireshark_plugins = NULL; +#endif + const gchar* epan_get_version(void) { return VERSION; @@ -136,22 +140,6 @@ quiet_gcrypt_logger (void *dummy _U_, int level, const char *format, va_list arg } #endif // _WIN32 -/* - * 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) -{ -#ifdef HAVE_PLUGINS - register_dissector_plugin_type(); - register_tap_plugin_type(); -#endif -} - gboolean epan_init(void (*register_all_protocols_func)(register_cb cb, gpointer client_data), void (*register_all_handoffs_func)(register_cb cb, gpointer client_data), @@ -170,8 +158,12 @@ epan_init(void (*register_all_protocols_func)(register_cb cb, gpointer client_da addr_resolv_init(); except_init(); - /* initialize libgcrypt (beware, it won't be thread-safe) */ +#ifdef HAVE_PLUGINS + libwireshark_plugins = plugins_init("epan"); +#endif + + /* initialize libgcrypt (beware, it won't be thread-safe) */ gcry_check_version(NULL); #if defined(_WIN32) gcry_set_log_handler (quiet_gcrypt_logger, NULL); @@ -278,6 +270,11 @@ epan_cleanup(void) except_deinit(); addr_resolv_cleanup(); +#ifdef HAVE_PLUGINS + plugins_cleanup(libwireshark_plugins); + libwireshark_plugins = NULL; +#endif + if (pinfo_pool_cache != NULL) { wmem_destroy_allocator(pinfo_pool_cache); pinfo_pool_cache = NULL; diff --git a/epan/epan.h b/epan/epan.h index 5cafb780dc..8dc87451f9 100644 --- a/epan/epan.h +++ b/epan/epan.h @@ -30,6 +30,7 @@ extern "C" { #include #include #include +#include #include "register.h" #include "ws_symbol_export.h" @@ -57,6 +58,10 @@ struct packet_provider_funcs { const char *(*get_user_comment)(struct packet_provider_data *prov, const frame_data *fd); }; +#ifdef HAVE_PLUGINS +extern plugins_t *libwireshark_plugins; +#endif + /** @mainpage Wireshark EPAN the packet analyzing engine. Source code can be found in the epan directory @@ -100,15 +105,6 @@ 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. diff --git a/epan/prefs.c b/epan/prefs.c index 9ae9cfd21b..a3dfdd8859 100644 --- a/epan/prefs.c +++ b/epan/prefs.c @@ -737,6 +737,38 @@ prefs_register_stat(const char *name, const char *title, apply_cb, TRUE); } +/* + * Register that a codec has preferences. + * + * "name" is a name for the codec to use on the command line with "-o" + * and in preference files. + * + * "title" is a short human-readable name for the codec. + * + * "description" is a longer human-readable description of the codec. + */ +module_t *codecs_module = NULL; + +module_t * +prefs_register_codec(const char *name, const char *title, + const char *description, void (*apply_cb)(void)) +{ + /* + * Have we yet created the "Codecs" subtree? + */ + if (codecs_module == NULL) { + /* + * No. Register Codecs subtree as well as any preferences + * for non-dissector modules. + */ + pre_init_prefs(); + prefs_register_modules(); + } + + return prefs_register_module(codecs_module, name, title, description, + apply_cb, TRUE); +} + module_t * prefs_find_module(const char *name) { @@ -3479,6 +3511,10 @@ prefs_register_modules(void) "This is the file that gets written to when the destination is set to \"file\"", &prefs.pr_file, PREF_SAVE_FILENAME, NULL, TRUE); + /* Codecs */ + codecs_module = prefs_register_module(NULL, "codecs", "Codecs", + "Codecs", NULL, TRUE); + /* Statistics */ stats_module = prefs_register_module(NULL, "statistics", "Statistics", "Statistics", &stats_callback, TRUE); diff --git a/epan/prefs.h b/epan/prefs.h index f1eceb78bc..2eead89225 100644 --- a/epan/prefs.h +++ b/epan/prefs.h @@ -298,6 +298,19 @@ void prefs_deregister_protocol(int id); WS_DLL_PUBLIC module_t *prefs_register_stat(const char *name, const char *title, const char *description, void (*apply_cb)(void)); +/* + * Register that a codec has preferences. + * + * "name" is a name for the codec to use on the command line with "-o" + * and in preference files. + * + * "title" is a short human-readable name for the codec. + * + * "description" is a longer human-readable description of the codec. + */ +WS_DLL_PUBLIC module_t *prefs_register_codec(const char *name, const char *title, + const char *description, void (*apply_cb)(void)); + /* * Register that a protocol has preferences and group it under a single * subtree diff --git a/epan/proto.c b/epan/proto.c index 29d2d8d360..373eaa5af6 100644 --- a/epan/proto.c +++ b/epan/proto.c @@ -55,7 +55,6 @@ #include "show_exception.h" #include "in_cksum.h" -#include #include /* ws_debug_printf/ws_g_warning */ #include @@ -434,98 +433,37 @@ check_charset(const guint8 table[256], const char *str) } #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. - */ -DIAG_OFF(pedantic) -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_prepend(dissector_plugins, plugin); - return TRUE; -} -DIAG_ON(pedantic) - -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) +proto_register_plugin(const proto_plugin *plug) { - add_plugin_type("dissector", check_for_dissector_plugin); + if (!plug) { + /* XXX print useful warning */ + return; + } + dissector_plugins = g_slist_prepend(dissector_plugins, (proto_plugin *)plug); } static void -dissector_plugin_destroy(gpointer p) +call_plugin_register_protoinfo(gpointer data, gpointer user_data _U_) { - g_free(p); + proto_plugin *plug = (proto_plugin *)data; + + if (plug->register_protoinfo) { + plug->register_protoinfo(); + } } +static void +call_plugin_register_handoff(gpointer data, gpointer user_data _U_) +{ + proto_plugin *plug = (proto_plugin *)data; + + if (plug->register_handoff) { + plug->register_handoff(); + } +} #endif /* HAVE_PLUGINS */ /* initialize data structures and register protocols and fields */ @@ -578,7 +516,7 @@ proto_init(void (register_all_protocols_func)(register_cb cb, gpointer client_da plugins. */ if (cb) (*cb)(RA_PLUGIN_REGISTER, NULL, client_data); - g_slist_foreach(dissector_plugins, register_dissector_plugin, NULL); + g_slist_foreach(dissector_plugins, call_plugin_register_protoinfo, NULL); #endif /* Now call the "handoff registration" routines of all built-in @@ -591,7 +529,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); - g_slist_foreach(dissector_plugins, reg_handoff_dissector_plugin, NULL); + g_slist_foreach(dissector_plugins, call_plugin_register_handoff, NULL); #endif /* sort the protocols by protocol name */ @@ -686,10 +624,8 @@ proto_cleanup(void) proto_cleanup_base(); #ifdef HAVE_PLUGINS - if (dissector_plugins) { - g_slist_free_full(dissector_plugins, dissector_plugin_destroy); - dissector_plugins = NULL; - } + g_slist_free(dissector_plugins); + dissector_plugins = NULL; #endif } diff --git a/epan/proto.h b/epan/proto.h index eee7650873..914ee5c7b8 100644 --- a/epan/proto.h +++ b/epan/proto.h @@ -52,6 +52,9 @@ #include "register.h" #include "ws_symbol_export.h" #include "ws_attributes.h" +#ifdef HAVE_PLUGINS +#include "wsutil/plugins.h" +#endif #ifdef __cplusplus extern "C" { @@ -908,9 +911,13 @@ WS_DLL_PUBLIC void proto_tree_children_foreach(proto_tree *tree, #define PNODE_POOL(proto_node) ((proto_node)->tree_data->pinfo->pool) #ifdef HAVE_PLUGINS -/** 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); +typedef struct { + void (*register_protoinfo)(void); /* routine to call to register protocol information */ + void (*register_handoff)(void); /* routine to call to register dissector handoff */ +} proto_plugin; + +/** Register dissector plugin with the plugin system. */ +WS_DLL_PUBLIC void proto_register_plugin(const proto_plugin *plugin); #endif /** Sets up memory used by proto routines. Called at program startup */ diff --git a/epan/tap.c b/epan/tap.c index b942383a3c..45fa2f5aca 100644 --- a/epan/tap.c +++ b/epan/tap.c @@ -108,66 +108,22 @@ typedef struct _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. - */ -DIAG_OFF(pedantic) -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_prepend(tap_plugins, plugin); - return TRUE; -} -DIAG_ON(pedantic) - void -register_tap_plugin_type(void) +tap_register_plugin(const tap_plugin *plug) { - add_plugin_type("tap", check_for_tap_plugin); + tap_plugins = g_slist_prepend(tap_plugins, (tap_plugin *)plug); } static void -register_tap_plugin_listener(gpointer data, gpointer user_data _U_) +call_plugin_register_tap_listener(gpointer data, gpointer user_data _U_) { - tap_plugin *plugin = (tap_plugin *)data; + tap_plugin *plug = (tap_plugin *)data; - (plugin->register_tap_listener_fn)(); + if (plug->register_tap_listener) { + plug->register_tap_listener(); + } } /* @@ -176,15 +132,8 @@ register_tap_plugin_listener(gpointer data, gpointer user_data _U_) void register_all_plugin_tap_listeners(void) { - g_slist_foreach(tap_plugins, register_tap_plugin_listener, NULL); + g_slist_foreach(tap_plugins, call_plugin_register_tap_listener, NULL); } - -static void -tap_plugin_destroy(gpointer p) -{ - g_free(p); -} - #endif /* HAVE_PLUGINS */ /* ********************************************************************** @@ -771,7 +720,8 @@ void tap_cleanup(void) } #ifdef HAVE_PLUGINS - g_slist_free_full(tap_plugins, tap_plugin_destroy); + g_slist_free(tap_plugins); + tap_plugins = NULL; #endif /* HAVE_PLUGINS */ } diff --git a/epan/tap.h b/epan/tap.h index 395bf19ce8..f35aad9bdd 100644 --- a/epan/tap.h +++ b/epan/tap.h @@ -26,6 +26,9 @@ #include #include #include "ws_symbol_export.h" +#ifdef HAVE_PLUGINS +#include "wsutil/plugins.h" +#endif #ifdef __cplusplus extern "C" { @@ -47,14 +50,17 @@ typedef void (*tap_draw_cb)(void *tapdata); ** but does not, itself, require dissection */ #ifdef HAVE_PLUGINS -/** 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); +typedef struct { + void (*register_tap_listener)(void); /* routine to call to register tap listener */ +} tap_plugin; + +/** Register tap plugin with the plugin system. */ +WS_DLL_PUBLIC void tap_register_plugin(const tap_plugin *plug); #endif /* * For all tap plugins, call their register routines. - * Must be called after init_plugins(), and must be called only once in + * Must be called after plugins_init(), and must be called only once in * a program. * * XXX - should probably be handled by epan_init(), as the tap mechanism diff --git a/extcap/androiddump.c b/extcap/androiddump.c index ad1f59c5f0..fe9e1cc7ea 100644 --- a/extcap/androiddump.c +++ b/extcap/androiddump.c @@ -432,9 +432,6 @@ static struct extcap_dumper extcap_dumper_open(char *fifo, int encap) { int err = 0; wtap_init(); -#ifdef HAVE_PLUGINS - register_all_wiretap_modules(); -#endif extcap_dumper.dumper.wtap = wtap_dump_open(fifo, WTAP_FILE_TYPE_SUBTYPE_PCAP_NSEC, encap, PACKET_LENGTH, FALSE, &err); if (!extcap_dumper.dumper.wtap) { diff --git a/mergecap.c b/mergecap.c index 3f7b08d65a..e59a16d364 100644 --- a/mergecap.c +++ b/mergecap.c @@ -117,7 +117,6 @@ string_elem_print(gpointer data, gpointer not_used _U_) ((struct string_elem *)data)->lstr); } -#ifdef HAVE_PLUGINS /* * General errors and warnings are reported with an console message * in mergecap. @@ -129,7 +128,6 @@ failure_warning_message(const char *msg_format, va_list ap) vfprintf(stderr, msg_format, ap); fprintf(stderr, "\n"); } -#endif static void list_capture_types(void) { @@ -298,23 +296,10 @@ main(int argc, char *argv[]) g_free(init_progfile_dir_error); } - wtap_init(); - -#ifdef HAVE_PLUGINS init_report_message(failure_warning_message, failure_warning_message, NULL, NULL, NULL); - /* Scan for plugins. This does *not* call their registration routines; - that's done later. - - Don't report failures to load plugins because most (non-wiretap) - plugins *should* fail to load (because we're not linked against - libwireshark and dissector plugins need libwireshark).*/ - scan_plugins(DONT_REPORT_LOAD_FAILURE); - - /* Register all libwiretap plugin modules. */ - register_all_wiretap_modules(); -#endif + wtap_init(); /* Process the options first */ while ((opt = getopt_long(argc, argv, "aF:hI:s:vVw:", long_options, NULL)) != -1) { @@ -485,9 +470,6 @@ main(int argc, char *argv[]) clean_exit: wtap_cleanup(); free_progdirs(); -#ifdef HAVE_PLUGINS - plugins_cleanup(); -#endif return (status == MERGE_OK) ? 0 : 2; } diff --git a/packaging/nsis/wireshark.nsi b/packaging/nsis/wireshark.nsi index 6a6bbe689d..bc8770c8dd 100644 --- a/packaging/nsis/wireshark.nsi +++ b/packaging/nsis/wireshark.nsi @@ -1013,37 +1013,37 @@ SectionGroup "Plugins & Extensions" SecPluginsGroup Section "Dissector Plugins" SecPlugins ;------------------------------------------- -SetOutPath '$INSTDIR\plugins\${VERSION_MAJOR}.${VERSION_MINOR}' -File "${STAGING_DIR}\plugins\${VERSION_MAJOR}.${VERSION_MINOR}\docsis.dll" -File "${STAGING_DIR}\plugins\${VERSION_MAJOR}.${VERSION_MINOR}\ethercat.dll" -File "${STAGING_DIR}\plugins\${VERSION_MAJOR}.${VERSION_MINOR}\gryphon.dll" -File "${STAGING_DIR}\plugins\${VERSION_MAJOR}.${VERSION_MINOR}\irda.dll" -File "${STAGING_DIR}\plugins\${VERSION_MAJOR}.${VERSION_MINOR}\opcua.dll" -File "${STAGING_DIR}\plugins\${VERSION_MAJOR}.${VERSION_MINOR}\profinet.dll" -File "${STAGING_DIR}\plugins\${VERSION_MAJOR}.${VERSION_MINOR}\unistim.dll" -File "${STAGING_DIR}\plugins\${VERSION_MAJOR}.${VERSION_MINOR}\wimax.dll" -File "${STAGING_DIR}\plugins\${VERSION_MAJOR}.${VERSION_MINOR}\wimaxasncp.dll" -File "${STAGING_DIR}\plugins\${VERSION_MAJOR}.${VERSION_MINOR}\wimaxmacphy.dll" +SetOutPath '$INSTDIR\plugins\${VERSION_MAJOR}.${VERSION_MINOR}\epan' +File "${STAGING_DIR}\plugins\${VERSION_MAJOR}.${VERSION_MINOR}\epan\docsis.dll" +File "${STAGING_DIR}\plugins\${VERSION_MAJOR}.${VERSION_MINOR}\epan\ethercat.dll" +File "${STAGING_DIR}\plugins\${VERSION_MAJOR}.${VERSION_MINOR}\epan\gryphon.dll" +File "${STAGING_DIR}\plugins\${VERSION_MAJOR}.${VERSION_MINOR}\epan\irda.dll" +File "${STAGING_DIR}\plugins\${VERSION_MAJOR}.${VERSION_MINOR}\epan\opcua.dll" +File "${STAGING_DIR}\plugins\${VERSION_MAJOR}.${VERSION_MINOR}\epan\profinet.dll" +File "${STAGING_DIR}\plugins\${VERSION_MAJOR}.${VERSION_MINOR}\epan\unistim.dll" +File "${STAGING_DIR}\plugins\${VERSION_MAJOR}.${VERSION_MINOR}\epan\wimax.dll" +File "${STAGING_DIR}\plugins\${VERSION_MAJOR}.${VERSION_MINOR}\epan\wimaxasncp.dll" +File "${STAGING_DIR}\plugins\${VERSION_MAJOR}.${VERSION_MINOR}\epan\wimaxmacphy.dll" !include "custom_plugins.txt" SectionEnd Section "Tree Statistics Plugin" SecStatsTree ;------------------------------------------- -SetOutPath '$INSTDIR\plugins\${VERSION_MAJOR}.${VERSION_MINOR}' -File "${STAGING_DIR}\plugins\${VERSION_MAJOR}.${VERSION_MINOR}\stats_tree.dll" +SetOutPath '$INSTDIR\plugins\${VERSION_MAJOR}.${VERSION_MINOR}\epan' +File "${STAGING_DIR}\plugins\${VERSION_MAJOR}.${VERSION_MINOR}\epan\stats_tree.dll" SectionEnd Section "Mate - Meta Analysis and Tracing Engine" SecMate ;------------------------------------------- -SetOutPath '$INSTDIR\plugins\${VERSION_MAJOR}.${VERSION_MINOR}' -File "${STAGING_DIR}\plugins\${VERSION_MAJOR}.${VERSION_MINOR}\mate.dll" +SetOutPath '$INSTDIR\plugins\${VERSION_MAJOR}.${VERSION_MINOR}\epan' +File "${STAGING_DIR}\plugins\${VERSION_MAJOR}.${VERSION_MINOR}\epan\mate.dll" SectionEnd Section "TRANSUM - network and application performance analysis" SecTransum ;------------------------------------------- -SetOutPath '$INSTDIR\plugins\${VERSION_MAJOR}.${VERSION_MINOR}' -File "${STAGING_DIR}\plugins\${VERSION_MAJOR}.${VERSION_MINOR}\transum.dll" +SetOutPath '$INSTDIR\plugins\${VERSION_MAJOR}.${VERSION_MINOR}\epan' +File "${STAGING_DIR}\plugins\${VERSION_MAJOR}.${VERSION_MINOR}\epan\transum.dll" SectionEnd Section "Configuration Profiles" SecProfiles diff --git a/packaging/wix/DirectoryStructure.wxi b/packaging/wix/DirectoryStructure.wxi index 00c2dbfb5e..2e17841ec8 100644 --- a/packaging/wix/DirectoryStructure.wxi +++ b/packaging/wix/DirectoryStructure.wxi @@ -28,7 +28,9 @@ - + + + diff --git a/packaging/wix/Plugins.wxi b/packaging/wix/Plugins.wxi index fbf064f2f9..fc9f684ad2 100644 --- a/packaging/wix/Plugins.wxi +++ b/packaging/wix/Plugins.wxi @@ -3,36 +3,36 @@ - + - + - + - + - + - + - + - + - + - + - + @@ -55,9 +55,9 @@ - + - + @@ -69,9 +69,9 @@ - + - + @@ -83,9 +83,9 @@ - + - + diff --git a/plugins/Makefile.am.inc b/plugins/Makefile.am.inc index e3731c1039..62c8ae1002 100644 --- a/plugins/Makefile.am.inc +++ b/plugins/Makefile.am.inc @@ -28,6 +28,12 @@ PLUGIN_CFLAGS = PLUGIN_LDFLAGS = -module -avoid-version +epan_plugindir = $(plugindir)/epan + +wiretap_plugindir = $(plugindir)/wiretap + +codecs_plugindir = $(plugindir)/codecs + # # Source files are divided up along several axes: # diff --git a/plugins/docsis/CMakeLists.txt b/plugins/docsis/CMakeLists.txt index 3c43e8723c..190a6491eb 100644 --- a/plugins/docsis/CMakeLists.txt +++ b/plugins/docsis/CMakeLists.txt @@ -54,13 +54,9 @@ register_plugin_files(plugin.c ${DISSECTOR_SRC} ) -add_plugin_library(docsis) +add_plugin_library(docsis epan) -install(TARGETS docsis - LIBRARY DESTINATION ${PLUGIN_INSTALL_LIBDIR} NAMELINK_SKIP - RUNTIME DESTINATION ${PLUGIN_INSTALL_LIBDIR} - ARCHIVE DESTINATION ${PLUGIN_INSTALL_LIBDIR} -) +install_plugin(docsis epan) file(GLOB DISSECTOR_HEADERS RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}" "*.h") CHECKAPI( diff --git a/plugins/docsis/Makefile.am b/plugins/docsis/Makefile.am index 30462edb11..03c9e9b55a 100644 --- a/plugins/docsis/Makefile.am +++ b/plugins/docsis/Makefile.am @@ -46,7 +46,7 @@ HEADER_FILES = \ $(FLEX_GENERATED_HEADER_FILES) \ $(CLEAN_HEADER_FILES) -plugin_LTLIBRARIES = docsis.la +epan_plugin_LTLIBRARIES = docsis.la docsis_la_SOURCES = \ moduleinfo.h \ diff --git a/plugins/ethercat/CMakeLists.txt b/plugins/ethercat/CMakeLists.txt index 540e103c35..6c227b46ec 100644 --- a/plugins/ethercat/CMakeLists.txt +++ b/plugins/ethercat/CMakeLists.txt @@ -56,13 +56,9 @@ register_plugin_files(plugin.c ${DISSECTOR_SRC} ) -add_plugin_library(ethercat) +add_plugin_library(ethercat epan) -install(TARGETS ethercat - LIBRARY DESTINATION ${PLUGIN_INSTALL_LIBDIR} NAMELINK_SKIP - RUNTIME DESTINATION ${PLUGIN_INSTALL_LIBDIR} - ARCHIVE DESTINATION ${PLUGIN_INSTALL_LIBDIR} -) +install_plugin(ethercat epan) file(GLOB DISSECTOR_HEADERS RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}" "*.h") CHECKAPI( diff --git a/plugins/ethercat/Makefile.am b/plugins/ethercat/Makefile.am index d05cb72b11..a9c470714b 100644 --- a/plugins/ethercat/Makefile.am +++ b/plugins/ethercat/Makefile.am @@ -53,7 +53,7 @@ CLEAN_HEADER_FILES = \ HEADER_FILES = \ $(CLEAN_HEADER_FILES) -plugin_LTLIBRARIES = ethercat.la +epan_plugin_LTLIBRARIES = ethercat.la ethercat_la_SOURCES = \ moduleinfo.h \ diff --git a/plugins/gryphon/CMakeLists.txt b/plugins/gryphon/CMakeLists.txt index 5ed378d9cc..d6ecb662f4 100644 --- a/plugins/gryphon/CMakeLists.txt +++ b/plugins/gryphon/CMakeLists.txt @@ -50,13 +50,9 @@ register_plugin_files(plugin.c ${DISSECTOR_SRC} ) -add_plugin_library(gryphon) +add_plugin_library(gryphon epan) -install(TARGETS gryphon - LIBRARY DESTINATION ${PLUGIN_INSTALL_LIBDIR} NAMELINK_SKIP - RUNTIME DESTINATION ${PLUGIN_INSTALL_LIBDIR} - ARCHIVE DESTINATION ${PLUGIN_INSTALL_LIBDIR} -) +install_plugin(gryphon epan) file(GLOB DISSECTOR_HEADERS RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}" "*.h") CHECKAPI( diff --git a/plugins/gryphon/Makefile.am b/plugins/gryphon/Makefile.am index b114653f40..b794d14d5d 100644 --- a/plugins/gryphon/Makefile.am +++ b/plugins/gryphon/Makefile.am @@ -42,7 +42,7 @@ CLEAN_HEADER_FILES = \ HEADER_FILES = \ $(CLEAN_HEADER_FILES) -plugin_LTLIBRARIES = gryphon.la +epan_plugin_LTLIBRARIES = gryphon.la gryphon_la_SOURCES = \ moduleinfo.h \ diff --git a/plugins/irda/CMakeLists.txt b/plugins/irda/CMakeLists.txt index 26ddaa288e..c30026b91d 100644 --- a/plugins/irda/CMakeLists.txt +++ b/plugins/irda/CMakeLists.txt @@ -52,13 +52,9 @@ register_plugin_files(plugin.c ${DISSECTOR_SRC} ) -add_plugin_library(irda) +add_plugin_library(irda epan) -install(TARGETS irda - LIBRARY DESTINATION ${PLUGIN_INSTALL_LIBDIR} NAMELINK_SKIP - RUNTIME DESTINATION ${PLUGIN_INSTALL_LIBDIR} - ARCHIVE DESTINATION ${PLUGIN_INSTALL_LIBDIR} -) +install_plugin(irda epan) file(GLOB DISSECTOR_HEADERS RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}" "*.h") CHECKAPI( diff --git a/plugins/irda/Makefile.am b/plugins/irda/Makefile.am index 0435845931..fe24fdfd02 100644 --- a/plugins/irda/Makefile.am +++ b/plugins/irda/Makefile.am @@ -44,7 +44,7 @@ CLEAN_HEADER_FILES = \ HEADER_FILES = \ $(CLEAN_HEADER_FILES) -plugin_LTLIBRARIES = irda.la +epan_plugin_LTLIBRARIES = irda.la irda_la_SOURCES = \ moduleinfo.h \ diff --git a/plugins/mate/CMakeLists.txt b/plugins/mate/CMakeLists.txt index 4ff179c396..509145447f 100644 --- a/plugins/mate/CMakeLists.txt +++ b/plugins/mate/CMakeLists.txt @@ -72,13 +72,9 @@ register_plugin_files(plugin.c ${DISSECTOR_SUPPORT_SRC} ) -add_plugin_library(mate) +add_plugin_library(mate epan) -install(TARGETS mate - LIBRARY DESTINATION ${PLUGIN_INSTALL_LIBDIR} NAMELINK_SKIP - RUNTIME DESTINATION ${PLUGIN_INSTALL_LIBDIR} - ARCHIVE DESTINATION ${PLUGIN_INSTALL_LIBDIR} -) +install_plugin(mate epan) file(GLOB DISSECTOR_HEADERS RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}" "*.h") CHECKAPI( diff --git a/plugins/mate/Makefile.am b/plugins/mate/Makefile.am index f894233d8b..171701a3de 100644 --- a/plugins/mate/Makefile.am +++ b/plugins/mate/Makefile.am @@ -74,7 +74,7 @@ HEADER_FILES = \ #AM_CFLAGS += -Werror #endif -plugin_LTLIBRARIES = mate.la +epan_plugin_LTLIBRARIES = mate.la mate_la_SOURCES = \ moduleinfo.h \ diff --git a/plugins/opcua/CMakeLists.txt b/plugins/opcua/CMakeLists.txt index a05ed4da01..ca1dc9e34e 100644 --- a/plugins/opcua/CMakeLists.txt +++ b/plugins/opcua/CMakeLists.txt @@ -66,13 +66,9 @@ register_plugin_files(plugin.c ${DISSECTOR_SUPPORT_SRC} ) -add_plugin_library(opcua) +add_plugin_library(opcua epan) -install(TARGETS opcua - LIBRARY DESTINATION ${PLUGIN_INSTALL_LIBDIR} NAMELINK_SKIP - RUNTIME DESTINATION ${PLUGIN_INSTALL_LIBDIR} - ARCHIVE DESTINATION ${PLUGIN_INSTALL_LIBDIR} -) +install_plugin(opcua epan) file(GLOB DISSECTOR_HEADERS RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}" "*.h") CHECKAPI( diff --git a/plugins/opcua/Makefile.am b/plugins/opcua/Makefile.am index bc2d383486..6617da7d79 100644 --- a/plugins/opcua/Makefile.am +++ b/plugins/opcua/Makefile.am @@ -66,7 +66,7 @@ CLEAN_HEADER_FILES = \ HEADER_FILES = \ $(CLEAN_HEADER_FILES) -plugin_LTLIBRARIES = opcua.la +epan_plugin_LTLIBRARIES = opcua.la opcua_la_SOURCES = \ moduleinfo.h \ diff --git a/plugins/pluginifdemo/CMakeLists.txt b/plugins/pluginifdemo/CMakeLists.txt index cc1b3a1eb1..2125a1e9b3 100644 --- a/plugins/pluginifdemo/CMakeLists.txt +++ b/plugins/pluginifdemo/CMakeLists.txt @@ -65,15 +65,11 @@ register_plugin_files(plugin.c ${DISSECTOR_SRC} ) -add_plugin_library(pluginifdemo) +add_plugin_library(pluginifdemo epan) target_link_libraries(pluginifdemo Qt5::Core Qt5::Widgets Qt5::PrintSupport) -install(TARGETS pluginifdemo - LIBRARY DESTINATION ${PLUGIN_INSTALL_LIBDIR} NAMELINK_SKIP - RUNTIME DESTINATION ${PLUGIN_INSTALL_LIBDIR} - ARCHIVE DESTINATION ${PLUGIN_INSTALL_LIBDIR} -) +install_plugin(pluginifdemo epan) file(GLOB DISSECTOR_HEADERS RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}" "*.h") CHECKAPI( diff --git a/plugins/pluginifdemo/Makefile.am b/plugins/pluginifdemo/Makefile.am index efe26b8642..c91d380305 100644 --- a/plugins/pluginifdemo/Makefile.am +++ b/plugins/pluginifdemo/Makefile.am @@ -42,7 +42,7 @@ CLEAN_HEADER_FILES = \ HEADER_FILES = \ $(CLEAN_HEADER_FILES) -plugin_LTLIBRARIES = pluginifdemo.la +epan_plugin_LTLIBRARIES = pluginifdemo.la pluginifdemo_la_SOURCES = \ moduleinfo.h \ diff --git a/plugins/profinet/CMakeLists.txt b/plugins/profinet/CMakeLists.txt index cc5d228e1e..86798676f1 100644 --- a/plugins/profinet/CMakeLists.txt +++ b/plugins/profinet/CMakeLists.txt @@ -64,13 +64,9 @@ register_plugin_files(plugin.c ${DISSECTOR_SUPPORT_SRC} ) -add_plugin_library(profinet) +add_plugin_library(profinet epan) -install(TARGETS profinet - LIBRARY DESTINATION ${PLUGIN_INSTALL_LIBDIR} NAMELINK_SKIP - RUNTIME DESTINATION ${PLUGIN_INSTALL_LIBDIR} - ARCHIVE DESTINATION ${PLUGIN_INSTALL_LIBDIR} -) +install_plugin(profinet epan) file(GLOB DISSECTOR_HEADERS RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}" "*.h") CHECKAPI( diff --git a/plugins/profinet/Makefile.am b/plugins/profinet/Makefile.am index ef59001ca8..6e636d7c19 100644 --- a/plugins/profinet/Makefile.am +++ b/plugins/profinet/Makefile.am @@ -52,7 +52,7 @@ CLEAN_HEADER_FILES = \ HEADER_FILES = \ $(CLEAN_HEADER_FILES) -plugin_LTLIBRARIES = profinet.la +epan_plugin_LTLIBRARIES = profinet.la profinet_la_SOURCES = \ moduleinfo.h \ diff --git a/plugins/stats_tree/CMakeLists.txt b/plugins/stats_tree/CMakeLists.txt index dff44ee105..92172c72d3 100644 --- a/plugins/stats_tree/CMakeLists.txt +++ b/plugins/stats_tree/CMakeLists.txt @@ -39,13 +39,9 @@ set_source_files_properties( COMPILE_FLAGS "${WERROR_COMMON_FLAGS}" ) -add_plugin_library(stats_tree) +add_plugin_library(stats_tree epan) -install(TARGETS stats_tree - LIBRARY DESTINATION ${PLUGIN_INSTALL_LIBDIR} NAMELINK_SKIP - RUNTIME DESTINATION ${PLUGIN_INSTALL_LIBDIR} - ARCHIVE DESTINATION ${PLUGIN_INSTALL_LIBDIR} -) +install_plugin(stats_tree epan) file(GLOB PLUGIN_HEADERS RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}" "*.h") CHECKAPI( diff --git a/plugins/stats_tree/Makefile.am b/plugins/stats_tree/Makefile.am index 91f4bd7bc7..513cd2b7fa 100644 --- a/plugins/stats_tree/Makefile.am +++ b/plugins/stats_tree/Makefile.am @@ -37,7 +37,7 @@ CLEAN_HEADER_FILES = \ HEADER_FILES = \ $(CLEAN_HEADER_FILES) -plugin_LTLIBRARIES = stats_tree.la +epan_plugin_LTLIBRARIES = stats_tree.la stats_tree_la_SOURCES = \ $(SRC_FILES) \ diff --git a/plugins/stats_tree/pinfo_stats_tree.h b/plugins/stats_tree/pinfo_stats_tree.h index a2bc0a1ce4..ef8952ca5a 100644 --- a/plugins/stats_tree/pinfo_stats_tree.h +++ b/plugins/stats_tree/pinfo_stats_tree.h @@ -23,5 +23,3 @@ */ extern void register_pinfo_stat_trees(void); - -WS_DLL_PUBLIC void plugin_register_tap_listener(void); diff --git a/plugins/stats_tree/stats_tree_plugin.c b/plugins/stats_tree/stats_tree_plugin.c index b2d685e332..ad82f105c9 100644 --- a/plugins/stats_tree/stats_tree_plugin.c +++ b/plugins/stats_tree/stats_tree_plugin.c @@ -30,15 +30,17 @@ #include "ws_symbol_export.h" #include - #include "pinfo_stats_tree.h" WS_DLL_PUBLIC_DEF const gchar plugin_version[] = "0.0.1"; WS_DLL_PUBLIC_DEF const gchar plugin_release[] = VERSION_RELEASE; -WS_DLL_PUBLIC_DEF void plugin_register_tap_listener(void) +WS_DLL_PUBLIC_DEF void plugin_register(void) { - register_pinfo_stat_trees(); + static tap_plugin plug; + + plug.register_tap_listener = register_pinfo_stat_trees; + tap_register_plugin(&plug); } /* diff --git a/plugins/transum/CMakeLists.txt b/plugins/transum/CMakeLists.txt index bf3ca9057c..c814704da8 100644 --- a/plugins/transum/CMakeLists.txt +++ b/plugins/transum/CMakeLists.txt @@ -57,13 +57,9 @@ register_plugin_files(plugin.c ${DISSECTOR_SUPPORT_SRC} ) -add_plugin_library(transum) +add_plugin_library(transum epan) -install(TARGETS transum - LIBRARY DESTINATION ${PLUGIN_INSTALL_LIBDIR} NAMELINK_SKIP - RUNTIME DESTINATION ${PLUGIN_INSTALL_LIBDIR} - ARCHIVE DESTINATION ${PLUGIN_INSTALL_LIBDIR} -) +install_plugin(transum epan) file(GLOB DISSECTOR_HEADERS RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}" "*.h") CHECKAPI( diff --git a/plugins/transum/Makefile.am b/plugins/transum/Makefile.am index c058b98467..c277eec746 100644 --- a/plugins/transum/Makefile.am +++ b/plugins/transum/Makefile.am @@ -47,7 +47,7 @@ CLEAN_HEADER_FILES = \ HEADER_FILES = \ $(CLEAN_HEADER_FILES) -plugin_LTLIBRARIES = transum.la +epan_plugin_LTLIBRARIES = transum.la transum_la_SOURCES = \ moduleinfo.h \ diff --git a/plugins/unistim/CMakeLists.txt b/plugins/unistim/CMakeLists.txt index c6c01abeff..e9472df64e 100644 --- a/plugins/unistim/CMakeLists.txt +++ b/plugins/unistim/CMakeLists.txt @@ -50,13 +50,9 @@ register_plugin_files(plugin.c ${DISSECTOR_SRC} ) -add_plugin_library(unistim) +add_plugin_library(unistim epan) -install(TARGETS unistim - LIBRARY DESTINATION ${PLUGIN_INSTALL_LIBDIR} NAMELINK_SKIP - RUNTIME DESTINATION ${PLUGIN_INSTALL_LIBDIR} - ARCHIVE DESTINATION ${PLUGIN_INSTALL_LIBDIR} -) +install_plugin(unistim epan) file(GLOB DISSECTOR_HEADERS RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}" "*.h") CHECKAPI( diff --git a/plugins/unistim/Makefile.am b/plugins/unistim/Makefile.am index 13f6655b52..db3cf331f4 100644 --- a/plugins/unistim/Makefile.am +++ b/plugins/unistim/Makefile.am @@ -51,7 +51,7 @@ CLEAN_HEADER_FILES = \ HEADER_FILES = \ $(CLEAN_HEADER_FILES) -plugin_LTLIBRARIES = unistim.la +epan_plugin_LTLIBRARIES = unistim.la unistim_la_SOURCES = \ moduleinfo.h \ diff --git a/plugins/wimax/CMakeLists.txt b/plugins/wimax/CMakeLists.txt index dd52bdfede..8d7d201060 100644 --- a/plugins/wimax/CMakeLists.txt +++ b/plugins/wimax/CMakeLists.txt @@ -97,13 +97,9 @@ register_plugin_files(plugin.c ${DISSECTOR_SUPPORT_SRC} ) -add_plugin_library(wimax) +add_plugin_library(wimax epan) -install(TARGETS wimax - LIBRARY DESTINATION ${PLUGIN_INSTALL_LIBDIR} NAMELINK_SKIP - RUNTIME DESTINATION ${PLUGIN_INSTALL_LIBDIR} - ARCHIVE DESTINATION ${PLUGIN_INSTALL_LIBDIR} -) +install_plugin(wimax epan) file(GLOB DISSECTOR_HEADERS RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}" "*.h") CHECKAPI( diff --git a/plugins/wimax/Makefile.am b/plugins/wimax/Makefile.am index 0dc0d90d02..33ee4897e2 100644 --- a/plugins/wimax/Makefile.am +++ b/plugins/wimax/Makefile.am @@ -91,7 +91,7 @@ CLEAN_HEADER_FILES = \ HEADER_FILES = \ $(CLEAN_HEADER_FILES) -plugin_LTLIBRARIES = wimax.la +epan_plugin_LTLIBRARIES = wimax.la wimax_la_SOURCES = \ moduleinfo.h \ diff --git a/plugins/wimaxasncp/CMakeLists.txt b/plugins/wimaxasncp/CMakeLists.txt index 65bb7c3c3b..b2abc0ca31 100644 --- a/plugins/wimaxasncp/CMakeLists.txt +++ b/plugins/wimaxasncp/CMakeLists.txt @@ -55,13 +55,9 @@ register_plugin_files(plugin.c ${DISSECTOR_SRC} ) -add_plugin_library(wimaxasncp) +add_plugin_library(wimaxasncp epan) -install(TARGETS wimaxasncp - LIBRARY DESTINATION ${PLUGIN_INSTALL_LIBDIR} NAMELINK_SKIP - RUNTIME DESTINATION ${PLUGIN_INSTALL_LIBDIR} - ARCHIVE DESTINATION ${PLUGIN_INSTALL_LIBDIR} -) +install_plugin(wimaxasncp epan) file(GLOB DISSECTOR_HEADERS RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}" "*.h") CHECKAPI( diff --git a/plugins/wimaxasncp/Makefile.am b/plugins/wimaxasncp/Makefile.am index 001fd4b86f..1780926429 100644 --- a/plugins/wimaxasncp/Makefile.am +++ b/plugins/wimaxasncp/Makefile.am @@ -61,7 +61,7 @@ HEADER_FILES = \ #AM_CFLAGS += -Werror #endif -plugin_LTLIBRARIES = wimaxasncp.la +epan_plugin_LTLIBRARIES = wimaxasncp.la wimaxasncp_la_SOURCES = \ moduleinfo.h \ diff --git a/plugins/wimaxmacphy/CMakeLists.txt b/plugins/wimaxmacphy/CMakeLists.txt index 22cd50ad82..62040932c6 100644 --- a/plugins/wimaxmacphy/CMakeLists.txt +++ b/plugins/wimaxmacphy/CMakeLists.txt @@ -50,13 +50,9 @@ register_plugin_files(plugin.c ${DISSECTOR_SRC} ) -add_plugin_library(wimaxmacphy) +add_plugin_library(wimaxmacphy epan) -install(TARGETS wimaxmacphy - LIBRARY DESTINATION ${PLUGIN_INSTALL_LIBDIR} NAMELINK_SKIP - RUNTIME DESTINATION ${PLUGIN_INSTALL_LIBDIR} - ARCHIVE DESTINATION ${PLUGIN_INSTALL_LIBDIR} -) +install_plugin(wimaxmacphy epan) file(GLOB DISSECTOR_HEADERS RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}" "*.h") CHECKAPI( diff --git a/plugins/wimaxmacphy/Makefile.am b/plugins/wimaxmacphy/Makefile.am index b145943dc4..27750a8ca6 100644 --- a/plugins/wimaxmacphy/Makefile.am +++ b/plugins/wimaxmacphy/Makefile.am @@ -42,7 +42,7 @@ CLEAN_HEADER_FILES = \ HEADER_FILES = \ $(CLEAN_HEADER_FILES) -plugin_LTLIBRARIES = wimaxmacphy.la +epan_plugin_LTLIBRARIES = wimaxmacphy.la wimaxmacphy_la_SOURCES = \ moduleinfo.h \ diff --git a/randpkt.c b/randpkt.c index 17662416b5..b904bc30c2 100644 --- a/randpkt.c +++ b/randpkt.c @@ -135,6 +135,9 @@ main(int argc, char **argv) g_free(init_progfile_dir_error); } + init_report_message(failure_warning_message, failure_warning_message, + NULL, NULL, NULL); + wtap_init(); cmdarg_err_init(failure_warning_message, failure_message_cont); @@ -144,24 +147,6 @@ main(int argc, char **argv) create_app_running_mutex(); #endif /* _WIN32 */ -#ifdef HAVE_PLUGINS - /* Register wiretap plugins */ - init_report_message(failure_warning_message, failure_warning_message, - NULL, NULL, NULL); - - /* Scan for plugins. This does *not* call their registration routines; - that's done later. - - Don't report failures to load plugins because most - (non-wiretap) plugins *should* fail to load (because - we're not linked against libwireshark and dissector - plugins need libwireshark). */ - scan_plugins(DONT_REPORT_LOAD_FAILURE); - - /* Register all libwiretap plugin modules. */ - register_all_wiretap_modules(); -#endif - while ((opt = getopt_long(argc, argv, "b:c:ht:r", long_options, NULL)) != -1) { switch (opt) { case 'b': /* max bytes */ diff --git a/reordercap.c b/reordercap.c index b08634dd61..f1207b8e3e 100644 --- a/reordercap.c +++ b/reordercap.c @@ -230,24 +230,10 @@ main(int argc, char *argv[]) g_free(init_progfile_dir_error); } - wtap_init(); - -#ifdef HAVE_PLUGINS - /* Register wiretap plugins */ init_report_message(failure_warning_message, failure_warning_message, NULL, NULL, NULL); - /* Scan for plugins. This does *not* call their registration routines; - that's done later. - - Don't report failures to load plugins because most (non-wiretap) - plugins *should* fail to load (because we're not linked against - libwireshark and dissector plugins need libwireshark). */ - scan_plugins(DONT_REPORT_LOAD_FAILURE); - - /* Register all libwiretap plugin modules. */ - register_all_wiretap_modules(); -#endif + wtap_init(); /* Process the options first */ while ((opt = getopt_long(argc, argv, "hnv", long_options, NULL)) != -1) { @@ -399,9 +385,6 @@ main(int argc, char *argv[]) clean_exit: wtap_cleanup(); free_progdirs(); -#ifdef HAVE_PLUGINS - plugins_cleanup(); -#endif return ret; } diff --git a/sharkd.c b/sharkd.c index 903d9bd540..0b36c3ef5d 100644 --- a/sharkd.c +++ b/sharkd.c @@ -163,20 +163,6 @@ main(int argc, char *argv[]) wtap_init(); -#ifdef HAVE_PLUGINS - /* Register all the plugin types we have. */ - epan_register_plugin_types(); /* Types known to libwireshark */ - - /* Scan for plugins. This does *not* call their registration routines; - that's done later. */ - scan_plugins(REPORT_LOAD_FAILURE); - - /* Register all libwiretap plugin modules. */ - register_all_wiretap_modules(); -#endif - - register_all_codecs(); - /* 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 @@ -187,6 +173,8 @@ main(int argc, char *argv[]) goto clean_exit; } + codecs_init(); + /* Load libwireshark settings from the current profile. */ prefs_p = epan_load_settings(); @@ -211,11 +199,9 @@ main(int argc, char *argv[]) clean_exit: col_cleanup(&cfile.cinfo); free_filter_lists(); + codecs_cleanup(); wtap_cleanup(); free_progdirs(); -#ifdef HAVE_PLUGINS - plugins_cleanup(); -#endif return ret; } diff --git a/tfshark.c b/tfshark.c index 3b69005802..f0e4b92ecc 100644 --- a/tfshark.c +++ b/tfshark.c @@ -492,16 +492,6 @@ main(int argc, char *argv[]) wtap_init(); -#ifdef HAVE_PLUGINS - /* Register all the plugin types we have. */ - epan_register_plugin_types(); /* Types known to libwireshark */ - - /* Scan for plugins. This does *not* call their registration routines; - that's done later. */ - scan_plugins(REPORT_LOAD_FAILURE); - -#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/tools/make-plugin-reg.py b/tools/make-plugin-reg.py index 84053d3834..7a899d6d20 100755 --- a/tools/make-plugin-reg.py +++ b/tools/make-plugin-reg.py @@ -54,11 +54,11 @@ regs = { # For those that don't know Python, r"" indicates a raw string, # devoid of Python escapes. -proto_regex = r"(?P\bproto_register_[_A-Za-z0-9]+)\s*\(\s*void\s*\)[^;]*$" +proto_regex = r"\bproto_register_(?P[_A-Za-z0-9]+)\s*\(\s*void\s*\)[^;]*$" -handoff_regex = r"(?P\bproto_reg_handoff_[_A-Za-z0-9]+)\s*\(\s*void\s*\)[^;]*$" +handoff_regex = r"\bproto_reg_handoff_(?P[_A-Za-z0-9]+)\s*\(\s*void\s*\)[^;]*$" -wtap_reg_regex = r"(?P\bwtap_register_[_A-Za-z0-9]+)\s*\([^;]+$" +wtap_reg_regex = r"\bwtap_register_(?P[_A-Za-z0-9]+)\s*\([^;]+$" # This table drives the pattern-matching and symbol-harvesting patterns = [ @@ -107,52 +107,44 @@ reg_code += """ #define WS_BUILD_DLL #include "ws_symbol_export.h" -WS_DLL_PUBLIC_DEF void plugin_register (void); +""" +if registertype == "plugin": + reg_code += "#include \n\n" +if registertype == "plugin_wtap": + reg_code += "#include \n\n" + +for symbol in regs['proto_reg']: + reg_code += "void proto_register_%s(void);\n" % (symbol) +for symbol in regs['handoff_reg']: + reg_code += "void proto_reg_handoff_%s(void);\n" % (symbol) +for symbol in regs['wtap_register']: + reg_code += "void wtap_register_%s(void);\n" % (symbol) + +reg_code += """ WS_DLL_PUBLIC_DEF const gchar plugin_version[] = VERSION; WS_DLL_PUBLIC_DEF const gchar plugin_release[] = VERSION_RELEASE; -""" - -for symbol in regs['proto_reg']: - reg_code += "extern void %s(void);\n" % (symbol) - -reg_code += """ -WS_DLL_PUBLIC_DEF void -plugin_register (void) -{ -""" - -for symbol in regs['proto_reg']: - reg_code += " %s();\n" % (symbol) - -reg_code += "}\n\n" - -for symbol in regs['handoff_reg']: - reg_code += "extern void %s(void);\n" % (symbol) - -reg_code += """ -WS_DLL_PUBLIC_DEF void plugin_reg_handoff(void); - -WS_DLL_PUBLIC_DEF void -plugin_reg_handoff(void) -{ -""" - -for symbol in regs['handoff_reg']: - reg_code += " %s();\n" % (symbol) -reg_code += "}\n" - -if registertype == "plugin_wtap": - reg_code += """ -WS_DLL_PUBLIC_DEF void -register_wtap_module(void) +WS_DLL_PUBLIC_DEF void plugin_register(void) { """ +if registertype == "plugin": + for symbol in regs['proto_reg']: + reg_code +=" static proto_plugin plug_%s;\n\n" % (symbol) + reg_code +=" plug_%s.register_protoinfo = proto_register_%s;\n" % (symbol, symbol) + if symbol in regs['handoff_reg']: + reg_code +=" plug_%s.register_handoff = proto_reg_handoff_%s;\n" % (symbol, symbol) + else: + reg_code +=" plug_%s.register_handoff = NULL;\n" % (symbol) + reg_code += " proto_register_plugin(&plug_%s);\n" % (symbol) +else: for symbol in regs['wtap_register']: - reg_code += " {extern void %s (void); %s ();}\n" % (symbol, symbol) - reg_code += "}" + reg_code += " static wtap_plugin plug_%s;\n\n" % (symbol) + reg_code += " plug_%s.register_wtap_module = wtap_register_%s;\n" % (symbol, symbol) + reg_code += " wtap_register_plugin(&plug_%s);\n" % (symbol) + +reg_code += "};\n" try: print(('Updating ' + final_filename)) diff --git a/tools/oss-fuzzshark/fuzzshark.c b/tools/oss-fuzzshark/fuzzshark.c index b4b93dacef..1b6c606302 100644 --- a/tools/oss-fuzzshark/fuzzshark.c +++ b/tools/oss-fuzzshark/fuzzshark.c @@ -219,17 +219,6 @@ fuzz_init(int argc _U_, char **argv) wtap_init(); -#ifdef HAVE_PLUGINS - /* Register all the plugin types we have. */ - epan_register_plugin_types(); /* Types known to libwireshark */ - - /* Scan for plugins. This does *not* call their registration routines; that's done later. */ - scan_plugins(REPORT_LOAD_FAILURE); - - /* 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 @@ -285,9 +274,6 @@ fuzz_init(int argc _U_, char **argv) clean_exit: wtap_cleanup(); free_progdirs(); -#ifdef HAVE_PLUGINS - plugins_cleanup(); -#endif return ret; } diff --git a/tshark.c b/tshark.c index c8e3d97c8d..affd4885b6 100644 --- a/tshark.c +++ b/tshark.c @@ -900,18 +900,6 @@ main(int argc, char *argv[]) wtap_init(); -#ifdef HAVE_PLUGINS - /* Register all the plugin types we have. */ - epan_register_plugin_types(); /* Types known to libwireshark */ - - /* Scan for plugins. This does *not* call their registration routines; - that's done later. */ - scan_plugins(REPORT_LOAD_FAILURE); - - /* 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 @@ -2227,9 +2215,6 @@ clean_exit: free_filter_lists(); wtap_cleanup(); free_progdirs(); -#ifdef HAVE_PLUGINS - plugins_cleanup(); -#endif cf_close(&cfile); return exit_status; } diff --git a/ui/gtk/main.c b/ui/gtk/main.c index 075f4995bf..3153a214e2 100644 --- a/ui/gtk/main.c +++ b/ui/gtk/main.c @@ -2196,22 +2196,6 @@ main(int argc, char *argv[]) wtap_init(); -#ifdef HAVE_PLUGINS - /* Register all the plugin types we have. */ - epan_register_plugin_types(); /* Types known to libwireshark */ - codec_register_plugin_types(); /* Types known to libwscodecs */ - - /* Scan for plugins. This does *not* call their registration routines; - that's done later. */ - scan_plugins(REPORT_LOAD_FAILURE); - - /* Register all libwiretap plugin modules. */ - register_all_wiretap_modules(); -#endif - - /* Register all audio codec plugins. */ - register_all_codecs(); - splash_update(RA_DISSECTORS, NULL, (gpointer)splash_win); /* Register all dissectors; we must do this before checking for the @@ -2224,6 +2208,9 @@ main(int argc, char *argv[]) goto clean_exit; } + /* Register all audio codecs. */ + codecs_init(); + splash_update(RA_LISTENERS, NULL, (gpointer)splash_win); /* Register all tap listeners; we do this before we parse the arguments, @@ -2680,11 +2667,9 @@ clean_exit: #endif col_cleanup(&cfile.cinfo); free_filter_lists(); + codecs_cleanup(); wtap_cleanup(); free_progdirs(); -#ifdef HAVE_PLUGINS - plugins_cleanup(); -#endif return ret; } diff --git a/wireshark-qt.cpp b/wireshark-qt.cpp index 059f2e0335..94b20298a6 100644 --- a/wireshark-qt.cpp +++ b/wireshark-qt.cpp @@ -598,22 +598,6 @@ int main(int argc, char *qt_argv[]) wtap_init(); -#ifdef HAVE_PLUGINS - /* Register all the plugin types we have. */ - epan_register_plugin_types(); /* Types known to libwireshark */ - codec_register_plugin_types(); /* Types known to libwscodecs */ - - /* Scan for plugins. This does *not* call their registration routines; - that's done later. */ - scan_plugins(REPORT_LOAD_FAILURE); - - /* Register all libwiretap plugin modules. */ - register_all_wiretap_modules(); -#endif - - /* Register all audio codec plugins. */ - register_all_codecs(); - splash_update(RA_DISSECTORS, NULL, NULL); #ifdef DEBUG_STARTUP_TIME g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_INFO, "Calling epan init, elapsed time %" G_GUINT64_FORMAT " us \n", g_get_monotonic_time() - start_time); @@ -635,6 +619,9 @@ int main(int argc, char *qt_argv[]) g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_INFO, "epan done, elapsed time %" G_GUINT64_FORMAT " us \n", g_get_monotonic_time() - start_time); #endif + /* Register all audio codecs. */ + codecs_init(); + // Read the dynamic part of the recent file. This determines whether or // not the recent list appears in the main window so the earlier we can // call this the better. @@ -958,11 +945,9 @@ clean_exit: capture_opts_cleanup(&global_capture_opts); #endif col_cleanup(&CaptureFile::globalCapFile()->cinfo); + codecs_cleanup(); wtap_cleanup(); free_progdirs(); -#ifdef HAVE_PLUGINS - plugins_cleanup(); -#endif return ret_val; } diff --git a/wireshark.pc.in b/wireshark.pc.in index 588917812b..82b520ee20 100644 --- a/wireshark.pc.in +++ b/wireshark.pc.in @@ -4,6 +4,7 @@ libdir=@libdir@ includedir=@includedir@ sharedlibdir=${libdir} plugindir=@plugindir@ +VERSION_RELEASE=@VERSION_RELEASE@ Name: Wireshark Description: Network Packet Dissection Library diff --git a/wiretap/wtap.c b/wiretap/wtap.c index 4d81d982e1..58fd2c1d7b 100644 --- a/wiretap/wtap.c +++ b/wiretap/wtap.c @@ -37,72 +37,24 @@ #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 plugins_t *libwiretap_plugins; static GSList *wtap_plugins = NULL; -/* - * Callback for each plugin found. - */ -DIAG_OFF(pedantic) -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_prepend(wtap_plugins, plugin); - return TRUE; -} -DIAG_ON(pedantic) - -static void -wtap_register_plugin_types(void) -{ - add_plugin_type("libwiretap", 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) +wtap_register_plugin(const wtap_plugin *plug) { - g_slist_foreach(wtap_plugins, register_wtap_module_plugin, NULL); + wtap_plugins = g_slist_prepend(wtap_plugins, (wtap_plugin *)plug); +} + +static void +call_plugin_register_wtap_module(gpointer data, gpointer user_data _U_) +{ + wtap_plugin *plug = (wtap_plugin *)data; + + if (plug->register_wtap_module) { + plug->register_wtap_module(); + } } #endif /* HAVE_PLUGINS */ @@ -1481,7 +1433,8 @@ wtap_init(void) wtap_opttypes_initialize(); wtap_init_encap_types(); #ifdef HAVE_PLUGINS - wtap_register_plugin_types(); + libwiretap_plugins = plugins_init("wiretap"); + g_slist_foreach(wtap_plugins, call_plugin_register_wtap_module, NULL); #endif } @@ -1495,6 +1448,12 @@ wtap_cleanup(void) wtap_opttypes_cleanup(); ws_buffer_cleanup(); cleanup_open_routines(); +#ifdef HAVE_PLUGINS + g_slist_free(wtap_plugins); + wtap_plugins = NULL; + plugins_cleanup(libwiretap_plugins); + libwiretap_plugins = NULL; +#endif } /* diff --git a/wiretap/wtap.h b/wiretap/wtap.h index 567c961e24..4e11751d4c 100644 --- a/wiretap/wtap.h +++ b/wiretap/wtap.h @@ -29,6 +29,9 @@ #include "wtap_opttypes.h" #include "ws_symbol_export.h" #include "ws_attributes.h" +#ifdef HAVE_PLUGINS +#include "wsutil/plugins.h" +#endif #ifdef __cplusplus extern "C" { @@ -2002,10 +2005,17 @@ GSList *wtap_get_file_extension_type_extensions(guint extension_type); /*** dynamically register new file types and encapsulations ***/ WS_DLL_PUBLIC -void register_all_wiretap_modules(void); -WS_DLL_PUBLIC void wtap_register_file_type_extension(const struct file_extension_info *ei); +#ifdef HAVE_PLUGINS +typedef struct { + void (*register_wtap_module)(void); /* routine to call to register a wiretap module */ +} wtap_plugin; + +WS_DLL_PUBLIC +void wtap_register_plugin(const wtap_plugin *plug); +#endif + WS_DLL_PUBLIC void wtap_register_open_info(struct open_info *oi, const gboolean first_routine); WS_DLL_PUBLIC diff --git a/wsutil/plugins.c b/wsutil/plugins.c index 503889ae71..c4ef3f26ce 100644 --- a/wsutil/plugins.c +++ b/wsutil/plugins.c @@ -34,218 +34,140 @@ typedef struct _plugin { GModule *handle; /* handle returned by g_module_open */ gchar *name; /* plugin name */ const gchar *version; /* plugin version */ - GString *types; /* description with types this plugin supports */ + const gchar *type; /* type of plugin */ } plugin; +/* array of plugins */ +static GPtrArray *plugins_array = NULL; +/* map of names to plugin */ static GHashTable *plugins_table = NULL; static void -free_plugin(gpointer _p) +free_plugin(gpointer data) { - plugin *p = (plugin *)_p; + plugin *p = (plugin *)data; g_module_close(p->handle); g_free(p->name); - g_string_free(p->types, TRUE); g_free(p); } -/* - * 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 *name; - plugin_check_type_callback check_type; -} plugin_type; - -static GSList *plugin_types = NULL; - -static void -free_plugin_type(gpointer p, gpointer user_data _U_) +static gint +compare_plugins(gconstpointer a, gconstpointer b) { - g_free(p); -} - -void -add_plugin_type(const char *name, plugin_check_type_callback check_type) -{ - plugin_type *new_type; - - new_type = (plugin_type *)g_malloc(sizeof (plugin_type)); - new_type->name = name; - new_type->check_type = check_type; - plugin_types = g_slist_prepend(plugin_types, new_type); + return g_strcmp0((*(const plugin **)a)->name, (*(const plugin **)b)->name); } static void -call_plugin_callback(gpointer data, gpointer user_data) +plugins_scan_dir(GPtrArray **plugins_ptr, const char *dirpath, const char *type_name, gboolean build_dir) { - plugin_type *type = (plugin_type *)data; - plugin *new_plug = (plugin *)user_data; - - if (type->check_type(new_plug->handle)) { - /* The plugin supports this type */ - if (new_plug->types->len > 0) - g_string_append(new_plug->types, ", "); - g_string_append(new_plug->types, type->name); - } -} - -static void -plugins_scan_dir(const char *dirname, plugin_load_failure_mode mode) -{ - WS_DIR *dir; /* scanned directory */ - WS_DIRENT *file; /* current file */ - const char *name; - gchar *filename; /* current file name */ + GDir *dir; + const char *name; /* current file name */ + gchar *path; /* current file full path */ GModule *handle; /* handle returned by g_module_open */ gpointer symbol; const char *plug_version, *plug_release; plugin *new_plug; gchar *dot; - if (!g_file_test(dirname, G_FILE_TEST_EXISTS) || !g_file_test(dirname, G_FILE_TEST_IS_DIR)) { + dir = g_dir_open(dirpath, 0, NULL); + if (dir == NULL) return; - } - 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; + while ((name = g_dir_read_name(dir)) != NULL) { + /* Skip anything but files with G_MODULE_SUFFIX. */ + dot = strrchr(name, '.'); + if (dot == NULL || strcmp(dot+1, G_MODULE_SUFFIX) != 0) + continue; #if WIN32 - if (strncmp(name, "nordic_ble.dll", 14) == 0) - /* - * Skip the Nordic BLE Sniffer dll on WIN32 because - * the dissector has been added as internal. - */ - continue; + if (strncmp(name, "nordic_ble.dll", 14) == 0) { + /* + * Skip the Nordic BLE Sniffer dll on WIN32 because + * the dissector has been added as internal. + */ + continue; + } #endif - /* - * Check if the same name is already registered. - */ - if (g_hash_table_lookup(plugins_table, name)) { - /* Yes, it is. */ - if (mode == REPORT_LOAD_FAILURE) { - report_warning("The plugin '%s' was found " - "in multiple directories", name); - } - continue; + /* + * Check if the same name is already registered. + */ + if (g_hash_table_lookup(plugins_table, name)) { + /* Yes, it is. */ + if (!build_dir) { + report_warning("The plugin '%s' was found " + "in multiple directories", name); } - - filename = g_build_filename(dirname, name, (gchar *)NULL); - handle = g_module_open(filename, G_MODULE_BIND_LOCAL); - g_free(filename); - if (handle == NULL) - { - /* - * Only report load failures if we were asked to. - * - * XXX - we really should put different types of plugins - * (libwiretap, libwireshark) in different subdirectories, - * give libwiretap and libwireshark init routines that - * load the plugins, and have them scan the appropriate - * subdirectories so tha we don't even *try* to, for - * example, load libwireshark plugins in programs that - * only use libwiretap. - */ - if (mode == REPORT_LOAD_FAILURE) { - /* g_module_error() provides filename. */ - report_failure("Couldn't load plugin '%s': %s", name, - g_module_error()); - } - continue; - } - - if (!g_module_symbol(handle, "plugin_version", &symbol)) - { - report_failure("The plugin '%s' has no \"plugin_version\" symbol", name); - g_module_close(handle); - continue; - } - plug_version = (const char *)symbol; - - if (!g_module_symbol(handle, "plugin_release", &symbol)) - { - report_failure("The plugin '%s' has no \"plugin_release\" symbol", name); - g_module_close(handle); - continue; - } - plug_release = (const char *)symbol; - if (strcmp(plug_release, VERSION_RELEASE) != 0) { - report_failure("The plugin '%s' was compiled for Wireshark version %s", name, plug_release); - 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 = plug_version; - new_plug->types = g_string_new(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->len == 0) - { - /* - * No. - * - * Only report this failure if we were asked to; it might - * just mean that it's a plugin type that this program - * doesn't support, such as a libwireshark plugin in - * a program that doesn't use libwireshark. - * - * XXX - we really should put different types of plugins - * (libwiretap, libwireshark) in different subdirectories, - * give libwiretap and libwireshark init routines that - * load the plugins, and have them scan the appropriate - * subdirectories so tha we don't even *try* to, for - * example, load libwireshark plugins in programs that - * only use libwiretap. - */ - if (mode == REPORT_LOAD_FAILURE) { - report_failure("The plugin '%s' has no registration routines", - name); - } - free_plugin(new_plug); - continue; - } - - /* - * OK, add it to the list of plugins. - */ - g_hash_table_insert(plugins_table, new_plug->name, new_plug); + continue; } - ws_dir_close(dir); + + path = g_build_filename(dirpath, name, (gchar *)NULL); + handle = g_module_open(path, G_MODULE_BIND_LOCAL); + g_free(path); + if (handle == NULL) { + /* g_module_error() provides file path. */ + report_failure("Couldn't load plugin '%s': %s", name, + g_module_error()); + continue; + } + + if (!g_module_symbol(handle, "plugin_version", &symbol)) + { + report_failure("The plugin '%s' has no \"plugin_version\" symbol", name); + g_module_close(handle); + continue; + } + plug_version = (const char *)symbol; + + if (!g_module_symbol(handle, "plugin_release", &symbol)) + { + report_failure("The plugin '%s' has no \"plugin_release\" symbol", name); + g_module_close(handle); + continue; + } + plug_release = (const char *)symbol; + if (strcmp(plug_release, VERSION_RELEASE) != 0) { + report_failure("The plugin '%s' was compiled for Wireshark version %s", name, plug_release); + g_module_close(handle); + continue; + } + + /* Search for the entry point for the plugin type */ + if (!g_module_symbol(handle, "plugin_register", &symbol)) { + report_failure("The plugin '%s' has no \"plugin_register\" symbol", name); + g_module_close(handle); + continue; + } + +DIAG_OFF(pedantic) + /* Found it, call the plugin registration function. */ + ((plugin_register_func)symbol)(); +DIAG_ON(pedantic) + + new_plug = (plugin *)g_malloc(sizeof(plugin)); + new_plug->handle = handle; + new_plug->name = g_strdup(name); + new_plug->version = plug_version; + if (build_dir) + new_plug->type = "[build]"; + else + new_plug->type = type_name; + + /* Add it to the list of plugins. */ + if (*plugins_ptr == NULL) + *plugins_ptr = g_ptr_array_new_with_free_func(free_plugin); + g_ptr_array_add(*plugins_ptr, new_plug); + g_ptr_array_add(plugins_array, new_plug); + g_hash_table_insert(plugins_table, new_plug->name, new_plug); } + ws_dir_close(dir); } /* * Scan the buildir for plugins. */ static void -scan_plugins_build_dir(plugin_load_failure_mode mode) +scan_plugins_build_dir(GPtrArray **plugins_ptr, const char *type_name) { const char *plugin_dir; const char *name; @@ -257,7 +179,7 @@ scan_plugins_build_dir(plugin_load_failure_mode mode) if ((dir = ws_dir_open(plugin_dir, 0, NULL)) == NULL) return; - plugins_scan_dir(plugin_dir, mode); + plugins_scan_dir(plugins_ptr, plugin_dir, type_name, TRUE); while ((file = ws_dir_read_name(dir)) != NULL) { name = ws_dir_get_name(file); @@ -280,7 +202,7 @@ scan_plugins_build_dir(plugin_load_failure_mode mode) g_free(plugin_dir_path); plugin_dir_path = g_build_filename(plugin_dir, name, (gchar *)NULL); } - plugins_scan_dir(plugin_dir_path, mode); + plugins_scan_dir(plugins_ptr, plugin_dir_path, type_name, TRUE); g_free(plugin_dir_path); } ws_dir_close(dir); @@ -289,16 +211,20 @@ scan_plugins_build_dir(plugin_load_failure_mode mode) /* * Scan for plugins. */ -void -scan_plugins(plugin_load_failure_mode mode) +plugins_t * +plugins_init(const char *type_name) { if (!g_module_supported()) - return; /* nothing to do */ + return NULL; /* nothing to do */ - if (plugins_table != NULL) - return; /* only scan for plugins once */ + gchar *dirpath; + GPtrArray *plugins = NULL; + + if (plugins_table == NULL) + plugins_table = g_hash_table_new(g_str_hash, g_str_equal); + if (plugins_array == NULL) + plugins_array = g_ptr_array_new(); - plugins_table = g_hash_table_new_full(g_str_hash, g_str_equal, NULL, free_plugin); /* * Scan the global plugin directory. * If we're running from a build directory, scan the "plugins" @@ -308,11 +234,13 @@ scan_plugins(plugin_load_failure_mode mode) */ if (running_in_build_directory()) { - scan_plugins_build_dir(mode); + scan_plugins_build_dir(&plugins, type_name); } else { - plugins_scan_dir(get_plugins_dir_with_version(), mode); + dirpath = g_build_filename(get_plugins_dir_with_version(), type_name, (gchar *)NULL); + plugins_scan_dir(&plugins, dirpath, type_name, FALSE); + g_free(dirpath); } /* @@ -325,55 +253,26 @@ scan_plugins(plugin_load_failure_mode mode) */ if (!started_with_special_privs()) { - plugins_scan_dir(get_plugins_pers_dir_with_version(), mode); + dirpath = g_build_filename(get_plugins_pers_dir_with_version(), type_name, (gchar *)NULL); + plugins_scan_dir(&plugins, dirpath, type_name, FALSE); + g_free(dirpath); } -} -static void -add_plugin_to_descriptions(gpointer key _U_, gpointer value, gpointer user_data) -{ - g_ptr_array_add((GPtrArray *)user_data, value); -} + g_ptr_array_sort(plugins_array, compare_plugins); -static int -compare_plugins(gconstpointer _a, gconstpointer _b) -{ - const plugin *a = *(const plugin **)_a; - const plugin *b = *(const plugin **)_b; - - return strcmp(a->name, b->name); -} - -struct description_callback { - plugin_description_callback callback; - gpointer callback_data; -}; - -static void -call_description_callback(gpointer data, gpointer user_data) -{ - plugin *plug = (plugin *)data; - struct description_callback *desc = (struct description_callback *)user_data; - - desc->callback(plug->name, plug->version, plug->types->str, g_module_name(plug->handle), desc->callback_data); + return plugins; } WS_DLL_PUBLIC void -plugins_get_descriptions(plugin_description_callback callback, void *user_data) +plugins_get_descriptions(plugin_description_callback callback, void *callback_data) { - GPtrArray *descriptions; - struct description_callback cb; - - if (!plugins_table) + if (!plugins_array) return; - descriptions = g_ptr_array_sized_new(g_hash_table_size(plugins_table)); - g_hash_table_foreach(plugins_table, add_plugin_to_descriptions, descriptions); - g_ptr_array_sort(descriptions, compare_plugins); - cb.callback = callback; - cb.callback_data = user_data; - g_ptr_array_foreach(descriptions, call_description_callback, &cb); - g_ptr_array_free(descriptions, FALSE); + for (guint i = 0; i < plugins_array->len; i++) { + plugin *plug = (plugin *)plugins_array->pdata[i]; + callback(plug->name, plug->version, plug->type, g_module_name(plug->handle), callback_data); + } } static void @@ -399,12 +298,28 @@ plugins_get_count(void) } void -plugins_cleanup(void) +plugins_cleanup(plugins_t *plugins) { - if (plugins_table) + if (plugins) + g_ptr_array_free((GPtrArray *)plugins, TRUE); + + /* + * This module uses global bookkeeping data structures and per-library + * objects sharing data. To avoid having to walk the plugins GPtrArray + * and delete each plugin from the global data structures we purge them + * once the first plugin cleanup function is called. This means that after + * calling ONE OF POSSIBLY MANY plugin cleanup function NO OTHER plugin + * APIs can be used except plugins_cleanup. If it ever becomes an issue + * it will be easy to change, for a small performance penalty. + */ + if (plugins_table) { g_hash_table_destroy(plugins_table); - g_slist_foreach(plugin_types, free_plugin_type, NULL); - g_slist_free(plugin_types); + plugins_table = NULL; + } + if (plugins_array) { + g_ptr_array_free(plugins_array, FALSE); + plugins_array = NULL; + } } #endif /* HAVE_PLUGINS */ diff --git a/wsutil/plugins.h b/wsutil/plugins.h index 2fa37c1073..c476211d92 100644 --- a/wsutil/plugins.h +++ b/wsutil/plugins.h @@ -20,21 +20,23 @@ extern "C" { #include "ws_symbol_export.h" -typedef gboolean (*plugin_check_type_callback)(GModule *handle); +typedef void (*plugin_register_func)(void); + +typedef void plugins_t; + +WS_DLL_PUBLIC plugins_t *plugins_init(const char *type_name); -typedef enum { - REPORT_LOAD_FAILURE, - DONT_REPORT_LOAD_FAILURE -} plugin_load_failure_mode; -WS_DLL_PUBLIC void scan_plugins(plugin_load_failure_mode mode); -WS_DLL_PUBLIC void add_plugin_type(const char *type, plugin_check_type_callback callback); typedef void (*plugin_description_callback)(const char *name, const char *version, const char *types, const char *filename, void *user_data); + WS_DLL_PUBLIC void plugins_get_descriptions(plugin_description_callback callback, void *user_data); + WS_DLL_PUBLIC void plugins_dump_all(void); + WS_DLL_PUBLIC int plugins_get_count(void); -WS_DLL_PUBLIC void plugins_cleanup(void); + +WS_DLL_PUBLIC void plugins_cleanup(plugins_t *plugins); #ifdef __cplusplus }