summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CMakeLists.txt8
-rw-r--r--Makefile.am15
-rw-r--r--Makefile.common6
-rw-r--r--Makefile.nmake3
-rw-r--r--capinfos.c27
-rw-r--r--codecs/Makefile.am41
-rw-r--r--codecs/Makefile.common41
-rw-r--r--codecs/Makefile.nmake27
-rw-r--r--codecs/codecs.c73
-rw-r--r--codecs/codecs.h20
-rw-r--r--dftest.c10
-rw-r--r--editcap.c24
-rw-r--r--epan/CMakeLists.txt1
-rw-r--r--epan/Makefile.common2
-rw-r--r--epan/epan.c14
-rw-r--r--epan/epan.h10
-rw-r--r--epan/packet.c1
-rw-r--r--epan/plugins.c575
-rw-r--r--epan/proto.c93
-rw-r--r--epan/proto.h4
-rw-r--r--epan/tap.c73
-rw-r--r--epan/tap.h14
-rw-r--r--epan/wslua/init_wslua.c35
-rw-r--r--epan/wslua/init_wslua.h8
-rw-r--r--rawshark.c2
-rw-r--r--tshark.c25
-rw-r--r--ui/gtk/about_dlg.c7
-rw-r--r--ui/gtk/main.c22
-rw-r--r--ui/gtk/main_menubar.c1
-rw-r--r--ui/gtk/packet_win.c1
-rw-r--r--ui/gtk/plugins_dlg.c63
-rw-r--r--ui/gtk/rtp_player.c3
-rw-r--r--ui/qt/main.cpp25
-rw-r--r--wiretap/wtap.c69
-rw-r--r--wiretap/wtap.h4
-rw-r--r--wsutil/CMakeLists.txt1
-rw-r--r--wsutil/Makefile.common2
-rw-r--r--wsutil/plugins.c415
-rw-r--r--wsutil/plugins.h (renamed from epan/plugins.h)34
39 files changed, 1038 insertions, 761 deletions
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 <wsutil/privileges.h>
#include <wsutil/filesystem.h>
-/*
- * 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 <epan/plugins.h>
-#undef WS_BUILD_DLL
-#define RESET_SYMBOL_EXPORT
+#ifdef HAVE_PLUGINS
+#include <wsutil/plugins.h>
+#endif
#include "wtap.h"
#include <wsutil/report_err.h>
@@ -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 <gerald@xxxxxxxxxxxxx>
+# By Gerald Combs <gerald@wireshark.org>
# 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 <gerald@wireshark.org>
+# 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 <glib.h>
#include "codecs.h"
+#ifdef HAVE_PLUGINS
+
+#include <gmodule.h>
+
+#include <wsutil/plugins.h>
+
+/*
+ * 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 <epan/epan.h>
+#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 <errno.h>
#include <glib.h>
-#include <epan/epan.h>
+#include <epan/epan.h>
#include <epan/timestamp.h>
-#include <epan/plugins.h>
+#include <epan/prefs.h>
+#include <epan/dfilter/dfilter.h>
+
+#include <wsutil/plugins.h>
#include <wsutil/filesystem.h>
#include <wsutil/privileges.h>
-#include <epan/prefs.h>
+
#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 <wsutil/report_err.h>
#include <wsutil/strnatcmp.h>
#include <wsutil/md5.h>
-
-/*
- * 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 <wsutil/plugins.h>
#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 <gerald@wireshark.org>
- * 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 <stdio.h>
-
-/* linked list of Lua plugins */
-wslua_plugin *wslua_plugin_list = NULL;
-
-#ifdef HAVE_PLUGINS
-
-#include <time.h>
-
-#ifdef HAVE_DIRENT_H
-#include <dirent.h>
-#endif
-
-#ifdef HAVE_DIRECT_H
-#include <direct.h>
-#endif
-
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
-
-#include "wsutil/filesystem.h"
-#include <wsutil/privileges.h>
-#include <wsutil/file_util.h>
-#include <wsutil/report_err.h>
-
-/* 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 <wsutil/plugins.h>
+
#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 <gmodule.h>
+
+#include <wsutil/plugins.h>
+
+/*
+ * 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 <math.h>
#include <epan/expert.h>
#include <epan/ex-opt.h>
-#include <epan/plugins.h>
#include <wsutil/privileges.h>
#include <wsutil/file_util.h>
+/* 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 <wsutil/privileges.h>
#include <wsutil/file_util.h>
#include <wsutil/filesystem.h>
+#include <wsutil/plugins.h>
#include "globals.h"
#include <epan/packet.h>
@@ -85,7 +86,6 @@
#include "clopts_common.h"
#include "cmdarg_err.h"
#include "version_info.h"
-#include <epan/plugins.h>
#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 <epan/timestamp.h>
#include <epan/packet.h>
+#include <epan/wslua/init_wslua.h>
#include "file.h"
#include "frame_tvbuff.h"
#include <epan/disabled_protos.h>
@@ -81,7 +82,6 @@
#include "clopts_common.h"
#include "cmdarg_err.h"
#include "version_info.h"
-#include <epan/plugins.h>
#include "register.h"
#include <epan/epan_dissect.h>
#include <epan/tap.h>
@@ -106,6 +106,10 @@
#include "log.h"
#include <epan/funnel.h>
+#ifdef HAVE_PLUGINS
+#include <wsutil/plugins.h>
+#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 <gtk/gtk.h>
-
#include <string.h>
+#include <gtk/gtk.h>
+
#include <wsutil/filesystem.h>
-#include <epan/plugins.h>
+#include <wsutil/plugins.h>
#ifdef HAVE_LIBSMI
#include <epan/oids.h>
#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 <epan/disabled_protos.h>
#include <epan/epan.h>
#include <epan/epan_dissect.h>
-#include <epan/plugins.h>
#include <epan/dfilter/dfilter.h>
#include <epan/strutil.h>
#include <epan/emem.h>
@@ -92,6 +91,8 @@
#include <epan/print.h>
#include <epan/timestamp.h>
+#include <wsutil/plugins.h>
+
/* 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 <epan/etypes.h>
#include <epan/dissector_filters.h>
#include <epan/strutil.h>
-#include <epan/plugins.h>
#include <epan/epan_dissect.h>
#include <epan/column.h>
#include <epan/stats_tree_priv.h>
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 <epan/prefs.h>
#include <epan/column.h>
#include <epan/addr_resolv.h>
-#include <epan/plugins.h>
#include <epan/epan_dissect.h>
#include <epan/strutil.h>
#include <epan/tvbuff-int.h>
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 <gtk/gtk.h>
-#include "epan/plugins.h"
+#include <epan/wslua/init_wslua.h>
+
+#include <wsutil/plugins.h>
#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_scan(GtkWidget *list)
+plugins_add_description(const char *name, const char *version,
+ const char *types, const char *filename,
+ void *user_data)
{
-#ifdef HAVE_PLUGINS
- plugin *pt_plug;
- const char *sep;
-#endif
-#ifdef HAVE_LUA
- wslua_plugin *lua_plug;
-#endif
- GString *type;
+ 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
- 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 <epan/addr_resolv.h>
#include <epan/dissectors/packet-rtp.h>
#include <epan/rtp_pt.h>
-#include <../codecs/codecs.h>
#include <epan/prefs.h>
+#include <codecs/codecs.h>
+
#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 <wsutil/filesystem.h>
#include <wsutil/file_util.h>
#include <wsutil/privileges.h>
+#ifdef HAVE_PLUGINS
+#include <wsutil/plugins.h>
+#endif
#include <wsutil/u3.h>
#include <wiretap/merge.h>
@@ -48,7 +51,6 @@
#include <epan/epan_dissect.h>
#include <epan/timestamp.h>
#include <epan/packet.h>
-#include <epan/plugins.h>
#include <epan/dfilter/dfilter.h>
#include <epan/strutil.h>
#include <epan/addr_resolv.h>
@@ -66,6 +68,10 @@
#include <epan/disabled_protos.h>
#include <epan/print.h>
+#ifdef HAVE_PLUGINS
+#include <codecs/codecs.h>
+#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 <wsutil/file_util.h>
#include "buffer.h"
+#ifdef HAVE_PLUGINS
+
+#include <wsutil/plugins.h>
+
+/*
+ * 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 <gerald@wireshark.org>
+ * 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 <time.h>
+
+#ifdef HAVE_DIRENT_H
+#include <dirent.h>
+#endif
+
+#ifdef HAVE_DIRECT_H
+#include <direct.h>
+#endif
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+#include <glib.h>
+#include <gmodule.h>
+
+#include <wsutil/filesystem.h>
+#include <wsutil/privileges.h>
+#include <wsutil/file_util.h>
+#include <wsutil/report_err.h>
+
+#include <wsutil/plugins.h>
+
+/* 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
index 10a4f5bfff..49d24970fa 100644
--- a/epan/plugins.h
+++ b/wsutil/plugins.h
@@ -32,38 +32,18 @@ extern "C" {
#include <glib.h>
#include <gmodule.h>
-#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 */