1999-12-09 20:43:38 +00:00
|
|
|
/* plugins.c
|
1999-12-09 20:55:49 +00:00
|
|
|
* plugin routines
|
|
|
|
*
|
2000-08-19 17:53:02 +00:00
|
|
|
* $Id: plugins.c,v 1.23 2000/08/19 17:53:02 deniel Exp $
|
1999-12-09 20:43:38 +00:00
|
|
|
*
|
|
|
|
* Ethereal - Network traffic analyzer
|
|
|
|
* By Gerald Combs <gerald@zing.org>
|
1999-12-09 20:55:49 +00:00
|
|
|
* Copyright 1999 Gerald Combs
|
1999-12-09 20:43:38 +00:00
|
|
|
*
|
|
|
|
*
|
|
|
|
* This program is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU General Public License
|
|
|
|
* as published by the Free Software Foundation; either version 2
|
|
|
|
* of the License, or (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
* along with this program; if not, write to the Free Software
|
|
|
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#ifdef HAVE_CONFIG_H
|
|
|
|
# include "config.h"
|
|
|
|
#endif
|
|
|
|
|
2000-01-15 00:23:13 +00:00
|
|
|
#include "plugins.h"
|
|
|
|
|
|
|
|
#ifdef HAVE_PLUGINS
|
1999-12-09 20:43:38 +00:00
|
|
|
|
|
|
|
#include <time.h>
|
2000-01-15 00:23:13 +00:00
|
|
|
|
|
|
|
#ifdef HAVE_DIRENT_H
|
2000-01-04 20:37:18 +00:00
|
|
|
#include <dirent.h>
|
2000-01-15 00:23:13 +00:00
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifdef HAVE_DIRECT_H
|
|
|
|
#include <direct.h>
|
|
|
|
#endif
|
|
|
|
|
2000-01-04 20:37:18 +00:00
|
|
|
#include <string.h>
|
2000-01-15 00:23:13 +00:00
|
|
|
#include <stdlib.h>
|
2000-08-11 13:37:21 +00:00
|
|
|
|
|
|
|
#ifdef HAVE_SYS_STAT_H
|
2000-01-04 21:29:43 +00:00
|
|
|
#include <sys/stat.h>
|
2000-08-11 13:37:21 +00:00
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifdef HAVE_SYS_TYPES_H
|
2000-01-04 21:29:43 +00:00
|
|
|
#include <sys/types.h>
|
2000-08-11 13:37:21 +00:00
|
|
|
#endif
|
2000-01-15 00:23:13 +00:00
|
|
|
|
|
|
|
#ifdef HAVE_FCNTL_H
|
2000-01-04 21:29:43 +00:00
|
|
|
#include <fcntl.h>
|
2000-01-15 00:23:13 +00:00
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifdef HAVE_UNISTD_H
|
2000-01-04 21:29:43 +00:00
|
|
|
#include <unistd.h>
|
2000-01-15 00:23:13 +00:00
|
|
|
#endif
|
1999-12-09 20:43:38 +00:00
|
|
|
|
|
|
|
#include "globals.h"
|
2000-01-29 16:41:28 +00:00
|
|
|
#include "util.h"
|
1999-12-09 20:43:38 +00:00
|
|
|
|
2000-02-07 17:08:27 +00:00
|
|
|
#ifdef PLUGINS_NEED_ADDRESS_TABLE
|
2000-03-15 19:09:52 +00:00
|
|
|
#include "plugins/plugin_table.h"
|
2000-02-07 17:08:27 +00:00
|
|
|
plugin_address_table_t patable;
|
|
|
|
#endif
|
1999-12-09 20:43:38 +00:00
|
|
|
|
|
|
|
/* linked list of all plugins */
|
|
|
|
plugin *plugin_list;
|
2000-03-31 21:42:24 +00:00
|
|
|
guint32 enabled_plugins_number;
|
1999-12-09 20:43:38 +00:00
|
|
|
|
2000-02-07 17:08:27 +00:00
|
|
|
#ifdef WIN32
|
2000-08-03 01:54:53 +00:00
|
|
|
static gchar std_plug_dir[] = "c:/program files/ethereal/plugins/0.8.11";
|
|
|
|
static gchar local_plug_dir[] = "c:/ethereal/plugins/0.8.11";
|
2000-02-07 17:08:27 +00:00
|
|
|
#else
|
2000-08-03 01:54:53 +00:00
|
|
|
static gchar std_plug_dir[] = "/usr/lib/ethereal/plugins/0.8.11";
|
|
|
|
static gchar local_plug_dir[] = "/usr/local/lib/ethereal/plugins/0.8.11";
|
2000-02-07 17:08:27 +00:00
|
|
|
#endif
|
2000-01-04 20:37:18 +00:00
|
|
|
static gchar *user_plug_dir = NULL;
|
|
|
|
static gchar *plugin_status_file = NULL;
|
|
|
|
|
2000-08-19 17:53:02 +00:00
|
|
|
#define PLUGINS_STATUS "plugins.status"
|
|
|
|
#define PLUGINS_DIR_NAME "plugins"
|
|
|
|
|
1999-12-09 20:43:38 +00:00
|
|
|
/*
|
|
|
|
* 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.
|
|
|
|
*/
|
|
|
|
int
|
|
|
|
add_plugin(void *handle, gchar *name, gchar *version, gchar *protocol,
|
|
|
|
gchar *filter_string, dfilter *filter,
|
|
|
|
void (*dissector) (const u_char *,
|
|
|
|
int,
|
|
|
|
frame_data *,
|
|
|
|
proto_tree *))
|
|
|
|
{
|
|
|
|
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 = handle;
|
|
|
|
new_plug->name = name;
|
|
|
|
new_plug->version = version;
|
|
|
|
new_plug->enabled = FALSE;
|
|
|
|
new_plug->protocol = protocol;
|
|
|
|
new_plug->filter_string = g_strdup(filter_string);
|
|
|
|
new_plug->filter = filter;
|
|
|
|
new_plug->dissector = dissector;
|
|
|
|
new_plug->next = NULL;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* enable a plugin
|
|
|
|
* returns a pointer to the enabled plugin, or NULL if the plugin wasn't found
|
|
|
|
* in the list
|
|
|
|
*/
|
|
|
|
void *
|
|
|
|
enable_plugin(const gchar *name, const gchar *version)
|
|
|
|
{
|
|
|
|
plugin *pt_plug;
|
|
|
|
|
|
|
|
pt_plug = plugin_list;
|
|
|
|
while (pt_plug)
|
|
|
|
{
|
|
|
|
if (!strcmp(pt_plug->name, name) && !strcmp(pt_plug->version, version))
|
|
|
|
{
|
|
|
|
pt_plug->enabled = TRUE;
|
2000-03-31 21:42:24 +00:00
|
|
|
enabled_plugins_number++;
|
1999-12-09 20:43:38 +00:00
|
|
|
return pt_plug;
|
|
|
|
}
|
|
|
|
pt_plug = pt_plug->next;
|
|
|
|
}
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* disable a plugin
|
|
|
|
* returns a pointer to the disabled plugin, or NULL if the plugin wasn't found
|
|
|
|
* in the list
|
|
|
|
*/
|
|
|
|
void *
|
|
|
|
disable_plugin(const gchar *name, const gchar *version)
|
|
|
|
{
|
|
|
|
plugin *pt_plug;
|
|
|
|
|
|
|
|
pt_plug = plugin_list;
|
|
|
|
while (pt_plug)
|
|
|
|
{
|
|
|
|
if (!strcmp(pt_plug->name, name) && !strcmp(pt_plug->version, version))
|
|
|
|
{
|
|
|
|
pt_plug->enabled = FALSE;
|
2000-03-31 21:42:24 +00:00
|
|
|
enabled_plugins_number--;
|
1999-12-09 20:43:38 +00:00
|
|
|
return pt_plug;
|
|
|
|
}
|
|
|
|
pt_plug = pt_plug->next;
|
|
|
|
}
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* find a plugin using its name/version
|
|
|
|
*/
|
|
|
|
void *
|
|
|
|
find_plugin(const gchar *name, const gchar *version)
|
|
|
|
{
|
|
|
|
plugin *pt_plug;
|
|
|
|
|
|
|
|
pt_plug = plugin_list;
|
|
|
|
while (pt_plug)
|
|
|
|
{
|
|
|
|
if (!strcmp(pt_plug->name, name) && !strcmp(pt_plug->version, version))
|
|
|
|
{
|
|
|
|
return pt_plug;
|
|
|
|
}
|
|
|
|
pt_plug = pt_plug->next;
|
|
|
|
}
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* check if a plugin is enabled
|
|
|
|
*/
|
|
|
|
gboolean
|
|
|
|
is_enabled(const gchar *name, const gchar *version)
|
|
|
|
{
|
|
|
|
plugin *pt_plug;
|
|
|
|
|
|
|
|
pt_plug = plugin_list;
|
|
|
|
while (pt_plug)
|
|
|
|
{
|
|
|
|
if (!strcmp(pt_plug->name, name) && !strcmp(pt_plug->version, version))
|
|
|
|
return pt_plug->enabled;
|
|
|
|
pt_plug = pt_plug->next;
|
|
|
|
}
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* replace the filter used by a plugin (filter string and dfilter)
|
|
|
|
*/
|
|
|
|
void
|
|
|
|
plugin_replace_filter(const gchar *name, const gchar *version,
|
|
|
|
const gchar *filter_string, dfilter *filter)
|
|
|
|
{
|
|
|
|
plugin *pt_plug;
|
|
|
|
|
|
|
|
pt_plug = plugin_list;
|
|
|
|
while (pt_plug)
|
|
|
|
{
|
|
|
|
if (!strcmp(pt_plug->name, name) && !strcmp(pt_plug->version, version))
|
|
|
|
{
|
|
|
|
g_free(pt_plug->filter_string);
|
|
|
|
pt_plug->filter_string = g_strdup(filter_string);
|
|
|
|
dfilter_destroy(pt_plug->filter);
|
|
|
|
pt_plug->filter = filter;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
pt_plug = pt_plug->next;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2000-01-04 20:37:18 +00:00
|
|
|
/*
|
|
|
|
* save plugin status, returns 0 on success, -1 on failure:
|
|
|
|
* file format :
|
|
|
|
* for each plugin, two lines are saved :
|
|
|
|
* plugin_name plugin_version [0|1] (0: disabled, 1: enabled)
|
|
|
|
* filter_string
|
|
|
|
*
|
|
|
|
* Ex :
|
|
|
|
* gryphon.so 0.8.0 1
|
|
|
|
* tcp.port == 7000
|
|
|
|
*/
|
2000-08-19 17:53:02 +00:00
|
|
|
|
2000-01-04 20:37:18 +00:00
|
|
|
int
|
|
|
|
save_plugin_status()
|
|
|
|
{
|
2000-01-04 21:29:43 +00:00
|
|
|
gchar *pf_path;
|
2000-01-04 20:37:18 +00:00
|
|
|
FILE *statusfile;
|
|
|
|
plugin *pt_plug;
|
|
|
|
|
2000-01-04 21:29:43 +00:00
|
|
|
if (!plugin_status_file) {
|
2000-08-19 17:53:02 +00:00
|
|
|
plugin_status_file = (gchar *)g_malloc(strlen(get_home_dir()) +
|
|
|
|
strlen(PF_DIR) +
|
|
|
|
strlen(PLUGINS_STATUS) + 3);
|
|
|
|
sprintf(plugin_status_file, "%s/%s/%s",
|
|
|
|
get_home_dir(), PF_DIR, PLUGINS_STATUS);
|
2000-01-04 21:29:43 +00:00
|
|
|
}
|
2000-01-04 20:37:18 +00:00
|
|
|
statusfile=fopen(plugin_status_file, "w");
|
2000-01-04 21:29:43 +00:00
|
|
|
if (!statusfile) {
|
2000-01-29 16:41:28 +00:00
|
|
|
pf_path = g_malloc(strlen(get_home_dir()) + strlen(PF_DIR) + 2);
|
|
|
|
sprintf(pf_path, "%s/%s", get_home_dir(), PF_DIR);
|
2000-08-18 14:22:20 +00:00
|
|
|
#ifdef WIN32
|
2000-01-15 00:23:13 +00:00
|
|
|
mkdir(pf_path);
|
2000-08-18 14:22:20 +00:00
|
|
|
#else
|
2000-01-04 21:29:43 +00:00
|
|
|
mkdir(pf_path, 0755);
|
2000-08-18 14:22:20 +00:00
|
|
|
#endif
|
2000-01-04 21:29:43 +00:00
|
|
|
g_free(pf_path);
|
|
|
|
statusfile=fopen(plugin_status_file, "w");
|
|
|
|
if (!statusfile) return -1;
|
|
|
|
}
|
2000-01-04 20:37:18 +00:00
|
|
|
|
|
|
|
pt_plug = plugin_list;
|
|
|
|
while (pt_plug)
|
|
|
|
{
|
|
|
|
fprintf(statusfile,"%s %s %s\n%s\n", pt_plug->name, pt_plug->version,
|
|
|
|
(pt_plug->enabled ? "1" : "0"), pt_plug->filter_string);
|
|
|
|
pt_plug = pt_plug->next;
|
|
|
|
}
|
|
|
|
fclose(statusfile);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Check if the status of this plugin has been saved.
|
|
|
|
* If necessary, enable the plugin, and change the filter.
|
|
|
|
*/
|
|
|
|
static void
|
2000-01-15 00:23:13 +00:00
|
|
|
check_plugin_status(gchar *name, gchar *version, GModule *handle,
|
2000-01-04 20:37:18 +00:00
|
|
|
gchar *filter_string, FILE *statusfile)
|
|
|
|
{
|
|
|
|
gchar *ref_string;
|
|
|
|
guint16 ref_string_len;
|
|
|
|
gchar line[512];
|
2000-02-07 17:08:27 +00:00
|
|
|
void (*plugin_init)(void*);
|
2000-01-04 20:37:18 +00:00
|
|
|
dfilter *filter;
|
|
|
|
|
|
|
|
if (!statusfile) return;
|
|
|
|
|
|
|
|
ref_string = (gchar *)g_malloc(strlen(name) + strlen(version) + 2);
|
|
|
|
ref_string_len = sprintf(ref_string, "%s %s", name, version);
|
|
|
|
|
|
|
|
while (!feof(statusfile))
|
|
|
|
{
|
|
|
|
if (fgets(line, 512, statusfile) == NULL) return;
|
|
|
|
if (strncmp(line, ref_string, ref_string_len) != 0) { /* not the right plugin */
|
|
|
|
if (fgets(line, 512, statusfile) == NULL) return;
|
|
|
|
}
|
|
|
|
else { /* found the plugin */
|
|
|
|
if (line[ref_string_len+1] == '1') {
|
|
|
|
enable_plugin(name, version);
|
2000-02-07 17:08:27 +00:00
|
|
|
if (g_module_symbol(handle, "plugin_init", (gpointer*)&plugin_init) == TRUE) {
|
|
|
|
#ifdef PLUGINS_NEED_ADDRESS_TABLE
|
|
|
|
plugin_init(&patable);
|
|
|
|
#else
|
|
|
|
plugin_init(NULL);
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
#ifdef PLUGINS_NEED_ADDRESS_TABLE
|
|
|
|
else {
|
|
|
|
return;
|
2000-01-15 00:23:13 +00:00
|
|
|
}
|
2000-02-07 17:08:27 +00:00
|
|
|
#endif
|
2000-01-04 20:37:18 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (fgets(line, 512, statusfile) == NULL) return;
|
|
|
|
if (line[strlen(line)-1] == '\n') line[strlen(line)-1] = '\0';
|
|
|
|
/* only compile the new filter if it is different from the default */
|
|
|
|
if (strcmp(line, filter_string) && dfilter_compile(line, &filter) == 0)
|
|
|
|
plugin_replace_filter(name, version, line, filter);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
2000-01-04 21:29:43 +00:00
|
|
|
g_free(ref_string);
|
2000-01-04 20:37:18 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
plugins_scan_dir(const char *dirname)
|
|
|
|
{
|
2000-08-19 17:53:02 +00:00
|
|
|
#define FILENAME_LEN 1024
|
2000-01-04 20:37:18 +00:00
|
|
|
DIR *dir; /* scanned directory */
|
|
|
|
struct dirent *file; /* current file */
|
2000-08-19 17:53:02 +00:00
|
|
|
gchar filename[FILENAME_LEN]; /* current file name */
|
2000-01-15 00:23:13 +00:00
|
|
|
GModule *handle; /* handle returned by dlopen */
|
2000-01-04 20:37:18 +00:00
|
|
|
gchar *name;
|
|
|
|
gchar *version;
|
|
|
|
gchar *protocol;
|
|
|
|
gchar *filter_string;
|
|
|
|
gchar *dot;
|
|
|
|
dfilter *filter = NULL;
|
|
|
|
void (*dissector) (const u_char *, int, frame_data *, proto_tree *);
|
|
|
|
int cr;
|
|
|
|
FILE *statusfile;
|
|
|
|
|
2000-01-15 00:23:13 +00:00
|
|
|
#ifdef WIN32
|
|
|
|
#define LT_LIB_EXT ".dll"
|
|
|
|
#else
|
2000-02-09 19:37:47 +00:00
|
|
|
#define LT_LIB_EXT ".so"
|
2000-01-15 00:23:13 +00:00
|
|
|
#endif
|
2000-01-04 20:37:18 +00:00
|
|
|
|
|
|
|
if (!plugin_status_file)
|
|
|
|
{
|
2000-08-19 17:53:02 +00:00
|
|
|
plugin_status_file = (gchar *)g_malloc(strlen(get_home_dir()) +
|
|
|
|
strlen(PF_DIR) +
|
|
|
|
strlen(PLUGINS_STATUS) + 3);
|
|
|
|
sprintf(plugin_status_file, "%s/%s/%s",
|
|
|
|
get_home_dir(), PF_DIR, PLUGINS_STATUS);
|
2000-01-04 20:37:18 +00:00
|
|
|
}
|
|
|
|
statusfile = fopen(plugin_status_file, "r");
|
|
|
|
|
|
|
|
if ((dir = opendir(dirname)) != NULL)
|
|
|
|
{
|
|
|
|
while ((file = readdir(dir)) != NULL)
|
|
|
|
{
|
|
|
|
/* don't try to open "." and ".." */
|
|
|
|
if (!(strcmp(file->d_name, "..") &&
|
|
|
|
strcmp(file->d_name, "."))) continue;
|
|
|
|
|
2000-02-07 17:08:27 +00:00
|
|
|
/* skip anything but files with LT_LIB_EXT */
|
2000-01-04 20:37:18 +00:00
|
|
|
dot = strrchr(file->d_name, '.');
|
2000-02-07 17:08:27 +00:00
|
|
|
if (dot == NULL || strcmp(dot, LT_LIB_EXT) != 0) continue;
|
2000-01-04 20:37:18 +00:00
|
|
|
|
2000-08-19 17:53:02 +00:00
|
|
|
snprintf(filename, FILENAME_LEN, "%s/%s", dirname, file->d_name);
|
2000-01-15 00:23:13 +00:00
|
|
|
if ((handle = g_module_open(filename, 0)) == NULL) continue;
|
2000-01-04 20:37:18 +00:00
|
|
|
name = (gchar *)file->d_name;
|
2000-01-15 00:23:13 +00:00
|
|
|
if (g_module_symbol(handle, "version", (gpointer*)&version) == FALSE)
|
2000-01-04 20:37:18 +00:00
|
|
|
{
|
2000-08-18 14:22:20 +00:00
|
|
|
g_warning("The plugin %s has no version symbol", name);
|
2000-01-15 00:23:13 +00:00
|
|
|
g_module_close(handle);
|
2000-01-04 20:37:18 +00:00
|
|
|
continue;
|
|
|
|
}
|
2000-01-15 00:23:13 +00:00
|
|
|
if (g_module_symbol(handle, "protocol", (gpointer*)&protocol) == FALSE)
|
2000-01-04 20:37:18 +00:00
|
|
|
{
|
2000-08-18 14:22:20 +00:00
|
|
|
g_warning("The plugin %s has no protocol symbol", name);
|
2000-01-15 00:23:13 +00:00
|
|
|
g_module_close(handle);
|
2000-01-04 20:37:18 +00:00
|
|
|
continue;
|
|
|
|
}
|
2000-01-15 00:23:13 +00:00
|
|
|
if (g_module_symbol(handle, "filter_string", (gpointer*)&filter_string) == FALSE)
|
2000-01-04 20:37:18 +00:00
|
|
|
{
|
2000-08-18 14:22:20 +00:00
|
|
|
g_warning("The plugin %s has no filter_string symbol", name);
|
2000-01-15 00:23:13 +00:00
|
|
|
g_module_close(handle);
|
2000-01-04 20:37:18 +00:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
if (dfilter_compile(filter_string, &filter) != 0) {
|
2000-08-18 14:22:20 +00:00
|
|
|
g_warning("The plugin %s has a non compilable filter", name);
|
2000-01-15 00:23:13 +00:00
|
|
|
g_module_close(handle);
|
2000-01-04 20:37:18 +00:00
|
|
|
continue;
|
|
|
|
}
|
2000-01-15 00:23:13 +00:00
|
|
|
if (g_module_symbol(handle, "dissector", (gpointer*)&dissector) == FALSE) {
|
2000-01-04 20:37:18 +00:00
|
|
|
if (filter != NULL)
|
|
|
|
dfilter_destroy(filter);
|
2000-08-18 14:22:20 +00:00
|
|
|
g_warning("The plugin %s has no dissector symbol", name);
|
2000-01-15 00:23:13 +00:00
|
|
|
g_module_close(handle);
|
2000-01-04 20:37:18 +00:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ((cr = add_plugin(handle, g_strdup(file->d_name), version,
|
|
|
|
protocol, filter_string, filter, dissector)))
|
|
|
|
{
|
|
|
|
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 %sn",
|
|
|
|
name, version);
|
|
|
|
if (filter != NULL)
|
|
|
|
dfilter_destroy(filter);
|
2000-01-15 00:23:13 +00:00
|
|
|
g_module_close(handle);
|
2000-01-04 20:37:18 +00:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
if (statusfile) {
|
|
|
|
check_plugin_status(file->d_name, version, handle,
|
|
|
|
filter_string, statusfile);
|
|
|
|
rewind(statusfile);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
closedir(dir);
|
|
|
|
}
|
|
|
|
if (statusfile) fclose(statusfile);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* init plugins
|
|
|
|
*/
|
|
|
|
void
|
|
|
|
init_plugins()
|
|
|
|
{
|
2000-01-31 19:50:58 +00:00
|
|
|
struct stat std_dir_stat, local_dir_stat, plugin_dir_stat;
|
|
|
|
|
2000-01-04 20:37:18 +00:00
|
|
|
if (plugin_list == NULL) /* ensure init_plugins is only run once */
|
|
|
|
{
|
2000-03-31 21:42:24 +00:00
|
|
|
enabled_plugins_number = 0;
|
2000-02-07 17:08:27 +00:00
|
|
|
|
|
|
|
#ifdef PLUGINS_NEED_ADDRESS_TABLE
|
|
|
|
/* Intialize address table */
|
2000-03-15 19:09:52 +00:00
|
|
|
patable.p_check_col = check_col;
|
|
|
|
patable.p_col_add_fstr = col_add_fstr;
|
|
|
|
patable.p_col_append_fstr = col_append_str;
|
|
|
|
patable.p_col_add_str = col_add_str;
|
|
|
|
patable.p_col_append_str = col_append_str;
|
|
|
|
|
|
|
|
patable.p_dfilter_init = dfilter_init;
|
|
|
|
patable.p_dfilter_cleanup = dfilter_cleanup;
|
|
|
|
|
|
|
|
patable.p_pi = π
|
|
|
|
|
|
|
|
patable.p_proto_register_protocol = proto_register_protocol;
|
|
|
|
patable.p_proto_register_field_array = proto_register_field_array;
|
|
|
|
patable.p_proto_register_subtree_array = proto_register_subtree_array;
|
|
|
|
|
Add routines to:
register lists of "heuristic" dissectors, which are handed a
frame that may or may contain a payload for the protocol they
dissect, and that return FALSE if it's not or dissect the packet
and return TRUE if it is;
add a dissector to such a list;
go through such a list, calling each dissector until either a
dissector returns TRUE, in which case the routine returns TRUE,
or it runs out of entries in the list, in which case the routine
returns FALSE.
Have lists of heuristic dissectors for TCP and for COTP when used with
the Inactive Subset of CLNP, and add the GIOP and Yahoo Messenger
dissectors to the first list and the Sinec H1 dissector to the second
list.
Make the dissector name argument to "dissector_add()" and
"dissector_delete()" a "const char *" rarther than just a "char *".
Add "heur_dissector_add()", the routine to add a heuristic dissector to
a list of heuristic dissectors, to the set of routines we can export to
plugins through a table on platforms where dynamically-loaded code can't
call stuff in the main program, and initialize the element in the table
in question for "dissector_add()" (which we'd forgotten to do).
svn path=/trunk/; revision=1909
2000-05-05 09:32:36 +00:00
|
|
|
patable.p_dissector_add = dissector_add;
|
|
|
|
|
|
|
|
patable.p_heur_dissector_add = heur_dissector_add;
|
|
|
|
|
2000-03-15 19:09:52 +00:00
|
|
|
patable.p_proto_item_add_subtree = proto_item_add_subtree;
|
|
|
|
patable.p_proto_tree_add_item = proto_tree_add_item;
|
|
|
|
patable.p_proto_tree_add_item_hidden = proto_tree_add_item_hidden;
|
|
|
|
patable.p_proto_tree_add_protocol_format = proto_tree_add_protocol_format;
|
2000-05-31 18:32:15 +00:00
|
|
|
patable.p_proto_tree_add_bytes = proto_tree_add_bytes;
|
|
|
|
patable.p_proto_tree_add_bytes_hidden = proto_tree_add_bytes_hidden;
|
2000-03-15 19:09:52 +00:00
|
|
|
patable.p_proto_tree_add_bytes_format = proto_tree_add_bytes_format;
|
2000-05-31 18:32:15 +00:00
|
|
|
patable.p_proto_tree_add_time = proto_tree_add_time;
|
|
|
|
patable.p_proto_tree_add_time_hidden = proto_tree_add_time_hidden;
|
2000-03-15 19:09:52 +00:00
|
|
|
patable.p_proto_tree_add_time_format = proto_tree_add_time_format;
|
2000-05-31 18:32:15 +00:00
|
|
|
patable.p_proto_tree_add_ipxnet = proto_tree_add_ipxnet;
|
|
|
|
patable.p_proto_tree_add_ipxnet_hidden = proto_tree_add_ipxnet_hidden;
|
2000-03-15 19:09:52 +00:00
|
|
|
patable.p_proto_tree_add_ipxnet_format = proto_tree_add_ipxnet_format;
|
2000-05-31 18:32:15 +00:00
|
|
|
patable.p_proto_tree_add_ipv4 = proto_tree_add_ipv4;
|
|
|
|
patable.p_proto_tree_add_ipv4_hidden = proto_tree_add_ipv4_hidden;
|
2000-03-15 19:09:52 +00:00
|
|
|
patable.p_proto_tree_add_ipv4_format = proto_tree_add_ipv4_format;
|
2000-05-31 18:32:15 +00:00
|
|
|
patable.p_proto_tree_add_ipv6 = proto_tree_add_ipv6;
|
|
|
|
patable.p_proto_tree_add_ipv6_hidden = proto_tree_add_ipv6_hidden;
|
2000-03-15 19:09:52 +00:00
|
|
|
patable.p_proto_tree_add_ipv6_format = proto_tree_add_ipv6_format;
|
2000-05-31 18:32:15 +00:00
|
|
|
patable.p_proto_tree_add_ether = proto_tree_add_ether;
|
|
|
|
patable.p_proto_tree_add_ether_hidden = proto_tree_add_ether_hidden;
|
2000-03-15 19:09:52 +00:00
|
|
|
patable.p_proto_tree_add_ether_format = proto_tree_add_ether_format;
|
2000-05-31 18:32:15 +00:00
|
|
|
patable.p_proto_tree_add_string = proto_tree_add_string;
|
|
|
|
patable.p_proto_tree_add_string_hidden = proto_tree_add_string_hidden;
|
2000-03-15 19:09:52 +00:00
|
|
|
patable.p_proto_tree_add_string_format = proto_tree_add_string_format;
|
2000-05-31 18:32:15 +00:00
|
|
|
patable.p_proto_tree_add_boolean = proto_tree_add_boolean;
|
|
|
|
patable.p_proto_tree_add_boolean_hidden = proto_tree_add_boolean_hidden;
|
2000-03-15 19:09:52 +00:00
|
|
|
patable.p_proto_tree_add_boolean_format = proto_tree_add_boolean_format;
|
2000-05-31 18:32:15 +00:00
|
|
|
patable.p_proto_tree_add_double = proto_tree_add_double;
|
|
|
|
patable.p_proto_tree_add_double_hidden = proto_tree_add_double_hidden;
|
|
|
|
patable.p_proto_tree_add_double_format = proto_tree_add_double_format;
|
|
|
|
patable.p_proto_tree_add_uint = proto_tree_add_uint;
|
|
|
|
patable.p_proto_tree_add_uint_hidden = proto_tree_add_uint_hidden;
|
2000-03-15 19:09:52 +00:00
|
|
|
patable.p_proto_tree_add_uint_format = proto_tree_add_uint_format;
|
2000-05-31 18:32:15 +00:00
|
|
|
patable.p_proto_tree_add_int = proto_tree_add_int;
|
|
|
|
patable.p_proto_tree_add_int_hidden = proto_tree_add_int_hidden;
|
|
|
|
patable.p_proto_tree_add_int_format = proto_tree_add_int_format;
|
2000-03-15 19:09:52 +00:00
|
|
|
patable.p_proto_tree_add_text = proto_tree_add_text;
|
|
|
|
patable.p_proto_tree_add_notext = proto_tree_add_notext;
|
2000-02-07 17:08:27 +00:00
|
|
|
#endif
|
|
|
|
|
2000-01-04 20:37:18 +00:00
|
|
|
plugins_scan_dir(std_plug_dir);
|
|
|
|
plugins_scan_dir(local_plug_dir);
|
2000-02-03 21:31:03 +00:00
|
|
|
if ((strcmp(std_plug_dir, PLUGIN_DIR) != 0) &&
|
|
|
|
(strcmp(local_plug_dir, PLUGIN_DIR) != 0))
|
|
|
|
{
|
|
|
|
if (stat(PLUGIN_DIR, &plugin_dir_stat) == 0)
|
2000-01-31 19:50:58 +00:00
|
|
|
{
|
2000-02-03 21:31:03 +00:00
|
|
|
/* check if PLUGIN_DIR is really different from std_dir and
|
|
|
|
* local_dir if they exist ! */
|
|
|
|
if (stat(std_plug_dir, &std_dir_stat) == 0)
|
|
|
|
{
|
|
|
|
if (stat(local_plug_dir, &local_dir_stat) == 0)
|
|
|
|
{
|
|
|
|
if ((plugin_dir_stat.st_dev != std_dir_stat.st_dev ||
|
|
|
|
plugin_dir_stat.st_ino != std_dir_stat.st_ino) &&
|
|
|
|
(plugin_dir_stat.st_dev != local_dir_stat.st_dev ||
|
|
|
|
plugin_dir_stat.st_ino != local_dir_stat.st_ino))
|
|
|
|
plugins_scan_dir(PLUGIN_DIR);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if ((plugin_dir_stat.st_dev != std_dir_stat.st_dev ||
|
|
|
|
plugin_dir_stat.st_ino != std_dir_stat.st_ino))
|
|
|
|
plugins_scan_dir(PLUGIN_DIR);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (stat(local_plug_dir, &local_dir_stat) == 0)
|
|
|
|
{
|
|
|
|
if ((plugin_dir_stat.st_dev != local_dir_stat.st_dev ||
|
|
|
|
plugin_dir_stat.st_ino != local_dir_stat.st_ino))
|
|
|
|
plugins_scan_dir(PLUGIN_DIR);
|
|
|
|
}
|
|
|
|
else plugins_scan_dir(PLUGIN_DIR);
|
2000-01-31 19:50:58 +00:00
|
|
|
}
|
2000-02-03 21:31:03 +00:00
|
|
|
}
|
2000-01-04 20:37:18 +00:00
|
|
|
if (!user_plug_dir)
|
|
|
|
{
|
2000-08-19 17:53:02 +00:00
|
|
|
user_plug_dir = (gchar *)g_malloc(strlen(get_home_dir()) +
|
|
|
|
strlen(PF_DIR) +
|
|
|
|
strlen(PLUGINS_DIR_NAME) + 3);
|
|
|
|
sprintf(user_plug_dir, "%s/%s/%s", get_home_dir(),
|
|
|
|
PF_DIR, PLUGINS_DIR_NAME);
|
2000-01-04 20:37:18 +00:00
|
|
|
}
|
|
|
|
plugins_scan_dir(user_plug_dir);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
1999-12-09 20:43:38 +00:00
|
|
|
#endif
|