6 * Wireshark - Network traffic analyzer
7 * By Gerald Combs <gerald@wireshark.org>
8 * Copyright 1998 Gerald Combs
10 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License
12 * as published by the Free Software Foundation; either version 2
13 * of the License, or (at your option) any later version.
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
32 /* linked list of Lua plugins */
33 wslua_plugin *wslua_plugin_list = NULL;
55 #include "filesystem.h"
56 #include <wsutil/privileges.h>
57 #include <wsutil/file_util.h>
58 #include "report_err.h"
60 /* linked list of all plugins */
61 plugin *plugin_list = NULL;
64 * add a new plugin to the list
67 * - ENOMEM : memory allocation problem
68 * - EEXIST : the same plugin (i.e. name/version) was already registered.
71 add_plugin(void *handle, gchar *name, gchar *version,
72 void (*register_protoinfo)(void),
73 void (*reg_handoff)(void),
74 void (*register_tap_listener)(void),
75 void (*register_wtap_module)(void),
76 void (*register_codec_module)(void))
78 plugin *new_plug, *pt_plug;
80 pt_plug = plugin_list;
81 if (!pt_plug) /* the list is empty */
83 new_plug = (plugin *)g_malloc(sizeof(plugin));
86 plugin_list = new_plug;
92 /* check if the same name/version is already registered */
93 if (!strcmp(pt_plug->name, name) &&
94 !strcmp(pt_plug->version, version))
99 /* we found the last plugin in the list */
100 if (pt_plug->next == NULL)
103 pt_plug = pt_plug->next;
105 new_plug = (plugin *)g_malloc(sizeof(plugin));
106 if (new_plug == NULL)
108 pt_plug->next = new_plug;
111 new_plug->handle = handle;
112 new_plug->name = name;
113 new_plug->version = version;
114 new_plug->register_protoinfo = register_protoinfo;
115 new_plug->reg_handoff = reg_handoff;
116 new_plug->register_tap_listener = register_tap_listener;
117 new_plug->register_wtap_module = register_wtap_module;
118 new_plug->register_codec_module = register_codec_module;
119 new_plug->next = NULL;
125 * XXX - when we remove support for old-style plugins (which we should
126 * probably do eventually, as all plugins should be written as new-style
127 * ones), we may want to have "init_plugins()" merely save a pointer
128 * to the plugin's "init" routine, just as we save a pointer to its
129 * "reg_handoff" routine, and have a "register_all_plugins()" routine
130 * to go through the list of plugins and call all of them.
132 * Then we'd have "epan_init()", or perhaps even something higher up
133 * in the call tree, call "init_plugins()", and have "proto_init()"
134 * call "register_all_plugins()" right after calling "register_all_protocols()";
135 * this might be a bit cleaner.
138 plugins_scan_dir(const char *dirname)
140 #define FILENAME_LEN 1024
141 WS_DIR *dir; /* scanned directory */
142 WS_DIRENT *file; /* current file */
144 gchar filename[FILENAME_LEN]; /* current file name */
145 GModule *handle; /* handle returned by g_module_open */
148 void (*register_protoinfo)(void);
149 void (*reg_handoff)(void);
150 void (*register_tap_listener)(void);
151 void (*register_wtap_module)(void);
152 void (*register_codec_module)(void);
157 if ((dir = ws_dir_open(dirname, 0, NULL)) != NULL)
159 while ((file = ws_dir_read_name(dir)) != NULL)
161 name = ws_dir_get_name(file);
164 * GLib 2.x defines G_MODULE_SUFFIX as the extension used on
165 * this platform for loadable modules.
167 /* skip anything but files with G_MODULE_SUFFIX */
168 dot = strrchr(name, '.');
169 if (dot == NULL || strcmp(dot+1, G_MODULE_SUFFIX) != 0)
172 g_snprintf(filename, FILENAME_LEN, "%s" G_DIR_SEPARATOR_S "%s",
174 if ((handle = g_module_open(filename, 0)) == NULL)
176 report_failure("Couldn't load module %s: %s", filename,
181 if (!g_module_symbol(handle, "version", &gp))
183 report_failure("The plugin %s has no version symbol", name);
184 g_module_close(handle);
190 * Do we have a register routine?
192 if (g_module_symbol(handle, "plugin_register", &gp))
195 * Yes - this plugin includes one or more dissectors.
197 register_protoinfo = gp;
202 * No - no dissectors.
204 register_protoinfo = NULL;
208 * Do we have a reg_handoff routine?
210 if (g_module_symbol(handle, "plugin_reg_handoff", &gp))
220 * No - that's OK even if we have dissectors, as long
221 * as the plugin registers by name *and* there's
222 * a caller looking for that name.
228 * Do we have a register_tap_listener routine?
230 if (g_module_symbol(handle, "plugin_register_tap_listener", &gp))
233 * Yes - this plugin includes one or more taps.
235 register_tap_listener = gp;
242 register_tap_listener = NULL;
246 * Do we have an old-style init routine?
248 if (g_module_symbol(handle, "plugin_init", &gp))
251 * Yes - do we also have a register routine or a
252 * register_tap_listener routine? If so, this is a bogus
253 * hybrid of an old-style and new-style plugin.
255 if (register_protoinfo != NULL || register_tap_listener != NULL)
257 report_failure("The plugin '%s' has an old plugin init routine\nand a new register or register_tap_listener routine.",
259 g_module_close(handle);
264 * It's just an unsupported old-style plugin;
266 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",
268 g_module_close(handle);
273 * Do we have a register_wtap_module routine?
275 if (g_module_symbol(handle, "register_wtap_module", &gp))
277 register_wtap_module = gp;
281 register_wtap_module = NULL;
285 * Do we have a register_codec_module routine?
287 if (g_module_symbol(handle, "register_codec_module", &gp))
289 register_codec_module = gp;
293 register_codec_module = NULL;
297 * Does this dissector do anything useful?
299 if (register_protoinfo == NULL &&
300 register_tap_listener == NULL &&
301 register_wtap_module == NULL &&
302 register_codec_module == NULL )
307 report_failure("The plugin '%s' has neither a register routine, "
308 "a register_tap_listener or a register_wtap_module or a register_codec_module routine",
310 g_module_close(handle);
315 * OK, attempt to add it to the list of plugins.
317 if ((cr = add_plugin(handle, g_strdup(name), version,
318 register_protoinfo, reg_handoff,
319 register_tap_listener,register_wtap_module,register_codec_module)))
322 fprintf(stderr, "The plugin %s, version %s\n"
323 "was found in multiple directories\n", name, version);
325 fprintf(stderr, "Memory allocation problem\n"
326 "when processing plugin %s, version %s\n",
328 g_module_close(handle);
344 const char *plugin_dir;
346 char *plugin_dir_path;
347 char *plugins_pers_dir;
348 WS_DIR *dir; /* scanned directory */
349 WS_DIRENT *file; /* current file */
351 if (plugin_list == NULL) /* ensure init_plugins is only run once */
354 * Scan the global plugin directory.
355 * If we're running from a build directory, scan the subdirectories
356 * of that directory, as the global plugin directory is the
357 * "plugins" directory of the source tree, and the subdirectories
358 * are the source directories for the plugins, with the plugins
359 * built in those subdirectories.
361 plugin_dir = get_plugin_dir();
362 if (running_in_build_directory())
364 if ((dir = ws_dir_open(plugin_dir, 0, NULL)) != NULL)
366 while ((file = ws_dir_read_name(dir)) != NULL)
368 name = ws_dir_get_name(file);
369 if (strcmp(name, ".") == 0 || strcmp(name, "..") == 0)
370 continue; /* skip "." and ".." */
372 * Get the full path of a ".libs" subdirectory of that
375 plugin_dir_path = g_strdup_printf(
376 "%s" G_DIR_SEPARATOR_S "%s" G_DIR_SEPARATOR_S ".libs",
378 if (test_for_directory(plugin_dir_path) != EISDIR) {
380 * Either it doesn't refer to a directory or it
381 * refers to something that doesn't exist.
383 * Assume that means that the plugins are in
384 * the subdirectory of the plugin directory, not
385 * a ".libs" subdirectory of that subdirectory.
387 g_free(plugin_dir_path);
388 plugin_dir_path = g_strdup_printf("%s" G_DIR_SEPARATOR_S "%s",
391 plugins_scan_dir(plugin_dir_path);
392 g_free(plugin_dir_path);
398 plugins_scan_dir(plugin_dir);
401 * If the program wasn't started with special privileges,
402 * scan the users plugin directory. (Even if we relinquish
403 * them, plugins aren't safe unless we've *permanently*
404 * relinquished them, and we can't do that in Wireshark as,
405 * if we need privileges to start capturing, we'd need to
406 * reclaim them before each time we start capturing.)
408 if (!started_with_special_privs())
410 plugins_pers_dir = get_plugins_pers_dir();
411 plugins_scan_dir(plugins_pers_dir);
412 g_free(plugins_pers_dir);
416 register_all_wiretap_modules();
417 register_all_codecs();
421 register_all_plugin_registrations(void)
426 * For all plugins with register-handoff routines, call the routines.
427 * This is called from "proto_init()"; it must be called after
428 * "register_all_protocols()" and "init_plugins()" are called,
429 * in case one plugin registers itself either with a built-in
430 * dissector or with another plugin; we must first register all
431 * dissectors, whether built-in or plugin, so their dissector tables
432 * are initialized, and only then register all handoffs.
434 for (pt_plug = plugin_list; pt_plug != NULL; pt_plug = pt_plug->next)
436 if (pt_plug->register_protoinfo)
437 (pt_plug->register_protoinfo)();
442 register_all_plugin_handoffs(void)
447 * For all plugins with register-handoff routines, call the routines.
448 * This is called from "proto_init()"; it must be called after
449 * "register_all_protocols()" and "init_plugins()" are called,
450 * in case one plugin registers itself either with a built-in
451 * dissector or with another plugin; we must first register all
452 * dissectors, whether built-in or plugin, so their dissector tables
453 * are initialized, and only then register all handoffs.
455 for (pt_plug = plugin_list; pt_plug != NULL; pt_plug = pt_plug->next)
457 if (pt_plug->reg_handoff)
458 (pt_plug->reg_handoff)();
463 register_all_plugin_tap_listeners(void)
468 * For all plugins with register-tap-listener routines, call the
471 for (pt_plug = plugin_list; pt_plug != NULL; pt_plug = pt_plug->next)
473 if (pt_plug->register_tap_listener)
474 (pt_plug->register_tap_listener)();
479 register_all_wiretap_modules(void)
484 * For all plugins with register_wtap_module routines, call the
487 for (pt_plug = plugin_list; pt_plug != NULL; pt_plug = pt_plug->next)
489 if (pt_plug->register_wtap_module)
490 (pt_plug->register_wtap_module)();
495 register_all_codecs(void)
500 * For all plugins with register_wtap_module routines, call the
503 for (pt_plug = plugin_list; pt_plug != NULL; pt_plug = pt_plug->next)
505 if (pt_plug->register_codec_module)
506 (pt_plug->register_codec_module)();
510 #endif /* big HAVE_PLUGINS */
513 * Dump plugin info to stdout. Copied from gtk/plugins_dlg.c:plugins_scan.
516 plugins_dump_all(void)
523 wslua_plugin *lua_plug;
527 for (pt_plug = plugin_list; pt_plug != NULL; pt_plug = pt_plug->next)
531 printf("%s\t%s\t", pt_plug->name, pt_plug->version);
532 if (pt_plug->register_protoinfo)
537 if (pt_plug->register_tap_listener)
539 printf("%stap", sep);
542 if (pt_plug->register_wtap_module)
544 printf("%sfile format", sep);
547 if (pt_plug->register_codec_module)
549 printf("%scodec", sep);
551 printf("\t%s\n", g_module_name(pt_plug->handle));
556 for (lua_plug = wslua_plugin_list; lua_plug != NULL; lua_plug = lua_plug->next)
558 printf("%s\t%s\tlua script\t%s\n", lua_plug->name, lua_plug->version, lua_plug->filename);