aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGuy Harris <guy@alum.mit.edu>2000-11-05 09:05:00 +0000
committerGuy Harris <guy@alum.mit.edu>2000-11-05 09:05:00 +0000
commit1964cfddf69833831f464e997579071208150d57 (patch)
treee84e70c5f7ffe323b46ebb0b75e87a31d193ef31
parent3f4e41dc383b6dc436e89a43af3d18bf749ef635 (diff)
downloadwireshark-1964cfddf69833831f464e997579071208150d57.tar.gz
wireshark-1964cfddf69833831f464e997579071208150d57.tar.bz2
wireshark-1964cfddf69833831f464e997579071208150d57.zip
Allow plugins to have, instead of "protocol" and "filter_string"
variables and a "dissector" routine, a "plugin_reg_handoff()" routine, which will act just like the "reg_handoff()" routine of a non-plugin dissector, registering the dissector with handoff tables. This lets them plug into both TCP and UDP, or plug into protocols other than TCP or UDP. Those new-style plugin are enabled and disabled using the standard "Edit->Protocols" mechanism (and thus should use "OLD_CHECK_DISPLAY_AS_DATA()" or "CHECK_DISPLAY_AS_DATA()"); they don't show up in the list of plugins, aren't enabled or disabled from that list, and, as they don't have a filter, can't have the filter changed from that list - instead, they should register preferences for port numbers and the like if they should be configurable to use different ports. Make the Gryphon protocol a new-style plugin. svn path=/trunk/; revision=2565
-rw-r--r--epan/plugins.c210
-rw-r--r--plugins/gryphon/packet-gryphon.c20
2 files changed, 185 insertions, 45 deletions
diff --git a/epan/plugins.c b/epan/plugins.c
index 462f31d4e0..aee68ec96f 100644
--- a/epan/plugins.c
+++ b/epan/plugins.c
@@ -1,7 +1,7 @@
/* plugins.c
* plugin routines
*
- * $Id: plugins.c,v 1.4 2000/10/27 02:22:07 gram Exp $
+ * $Id: plugins.c,v 1.5 2000/11/05 09:05:00 guy Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@zing.org>
@@ -73,6 +73,23 @@ plugin_address_table_t patable;
plugin *plugin_list;
guint32 enabled_plugins_number;
+/*
+ * New-style plugins, which don't have an enabled flag (you use the
+ * standard mechanism for enabling and disabling protocols), and which
+ * don't have a protocol or filter string (you use the register handoff
+ * mechanism).
+ */
+typedef struct _new_plugin {
+ GModule *handle; /* handle returned by dlopen */
+ gchar *name; /* plugin name */
+ gchar *version; /* plugin version */
+ void (*reg_handoff)(void); /* routine to call to register dissector handoff */
+ struct _new_plugin *next; /* forward link */
+} new_plugin;
+
+/* linked list of all new-style plugins */
+static new_plugin *new_plugin_list;
+
#ifdef WIN32
static gchar std_plug_dir[] = "c:/program files/ethereal/plugins/0.8.13";
static gchar local_plug_dir[] = "c:/ethereal/plugins/0.8.13";
@@ -357,6 +374,55 @@ check_plugin_status(gchar *name, gchar *version, GModule *handle,
g_free(ref_string);
}
+/*
+ * add a new new-style plugin to the list
+ * returns :
+ * - 0 : OK
+ * - ENOMEM : memory allocation problem
+ * - EEXIST : the same plugin (i.e. name/version) was already registered.
+ */
+static int
+new_add_plugin(void *handle, gchar *name, gchar *version,
+ void (*reg_handoff)(void))
+{
+ new_plugin *new_plug, *pt_plug;
+
+ pt_plug = new_plugin_list;
+ if (!pt_plug) /* the list is empty */
+ {
+ new_plug = (new_plugin *)g_malloc(sizeof(new_plugin));
+ if (new_plug == NULL) return ENOMEM;
+ new_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 = (new_plugin *)g_malloc(sizeof(new_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->reg_handoff = reg_handoff;
+ new_plug->next = NULL;
+ return 0;
+}
+
static void
plugins_scan_dir(const char *dirname)
{
@@ -367,6 +433,8 @@ plugins_scan_dir(const char *dirname)
GModule *handle; /* handle returned by dlopen */
gchar *name;
gchar *version;
+ void (*init)(void *);
+ void (*reg_handoff)(void);
gchar *protocol;
gchar *filter_string;
gchar *dot;
@@ -412,50 +480,103 @@ plugins_scan_dir(const char *dirname)
g_module_close(handle);
continue;
}
- if (g_module_symbol(handle, "protocol", (gpointer*)&protocol) == FALSE)
+
+ /*
+ * If we have a "plugin_reg_handoff()" routine, we don't require
+ * the plugin to have "protocol", "filter_string", or "dissector"
+ * variables - we'll call the "plugin_reg_handoff()" routine and
+ * assume it'll register the dissector with the appropriate
+ * handoff tables.
+ */
+ if (g_module_symbol(handle, "plugin_reg_handoff",
+ (gpointer*)&reg_handoff))
{
- g_warning("The plugin %s has no protocol symbol", name);
- g_module_close(handle);
- continue;
+ /*
+ * We require it to have a "plugin_init()" routine.
+ */
+ if (!g_module_symbol(handle, "plugin_init", (gpointer*)&init))
+ {
+ g_warning("The plugin %s has a plugin_reg_handoff symbol but no plugin_init routine", name);
+ g_module_close(handle);
+ continue;
+ }
+
+ /*
+ * We have a "plugin_reg_handoff()" routine, so we don't
+ * need the protocol, filter string, or dissector pointer.
+ */
+ if ((cr = new_add_plugin(handle, g_strdup(file->d_name), version,
+ reg_handoff)))
+ {
+ 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);
+ g_module_close(handle);
+ continue;
+ }
+
+ /*
+ * Call its init routine.
+ */
+#ifdef PLUGINS_NEED_ADDRESS_TABLE
+ init(&patable);
+#else
+ init(NULL);
+#endif
}
- if (g_module_symbol(handle, "filter_string", (gpointer*)&filter_string) == FALSE)
+ else
{
- g_warning("The plugin %s has no filter_string symbol", name);
- g_module_close(handle);
- continue;
- }
- if (dfilter_compile(filter_string, &filter) != 0) {
- g_warning("The plugin %s has a non compilable filter", name);
- g_module_close(handle);
- continue;
- }
- if (g_module_symbol(handle, "dissector", (gpointer*)&dissector) == FALSE) {
- if (filter != NULL)
- dfilter_destroy(filter);
- g_warning("The plugin %s has no dissector symbol", name);
- g_module_close(handle);
- continue;
- }
+ if (g_module_symbol(handle, "protocol", (gpointer*)&protocol) == FALSE)
+ {
+ g_warning("The plugin %s has no protocol symbol and no plugin_reg_handoff symbol", name);
+ g_module_close(handle);
+ continue;
+ }
+ if (g_module_symbol(handle, "filter_string", (gpointer*)&filter_string) == FALSE)
+ {
+ g_warning("The plugin %s has no filter_string symbol and no plugin_reg_handoff symbol", name);
+ g_module_close(handle);
+ continue;
+ }
+ if (dfilter_compile(filter_string, &filter) != 0)
+ {
+ g_warning("The plugin %s has a non-compilable filter", name);
+ g_module_close(handle);
+ continue;
+ }
+ if (g_module_symbol(handle, "dissector", (gpointer*)&dissector) == FALSE)
+ {
+ if (filter != NULL)
+ dfilter_destroy(filter);
+ g_warning("The plugin %s has no dissector symbol and no plugin_reg_handoff symbol", name);
+ g_module_close(handle);
+ 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"
+ 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"
+ else
+ fprintf(stderr, "Memory allocation problem\n"
"when processing plugin %s, version %sn",
name, version);
- if (filter != NULL)
- dfilter_destroy(filter);
- g_module_close(handle);
- continue;
- }
- if (statusfile) {
- check_plugin_status(file->d_name, version, handle,
+ if (filter != NULL)
+ dfilter_destroy(filter);
+ g_module_close(handle);
+ continue;
+ }
+ if (statusfile) {
+ check_plugin_status(file->d_name, version, handle,
filter_string, statusfile);
- rewind(statusfile);
+ rewind(statusfile);
+ }
}
}
closedir(dir);
@@ -470,6 +591,7 @@ void
init_plugins(const char *plugin_dir)
{
struct stat std_dir_stat, local_dir_stat, plugin_dir_stat;
+ new_plugin *pt_plug;
if (plugin_list == NULL) /* ensure init_plugins is only run once */
{
@@ -582,6 +704,20 @@ init_plugins(const char *plugin_dir)
}
plugins_scan_dir(user_plug_dir);
}
+
+ /*
+ * For all new-style plugins, call the register-handoff routine.
+ * (We defer this until after registering all new-style plugins,
+ * in case one plugin registers itself with another plugin; we
+ * need to register all plugins, so their dissector tables are
+ * initialized.)
+ *
+ * We treat those protocols as always being enabled; they should
+ * use the standard mechanism for enabling/disabling protocols, not
+ * the plugin-specific mechanism.
+ */
+ for (pt_plug = new_plugin_list; pt_plug != NULL; pt_plug = pt_plug->next)
+ (pt_plug->reg_handoff)();
}
#endif
diff --git a/plugins/gryphon/packet-gryphon.c b/plugins/gryphon/packet-gryphon.c
index a69dca64bc..f957e909d5 100644
--- a/plugins/gryphon/packet-gryphon.c
+++ b/plugins/gryphon/packet-gryphon.c
@@ -1,7 +1,7 @@
/* packet-gryphon.c
* Routines for Gryphon protocol packet disassembly
*
- * $Id: packet-gryphon.c,v 1.12 2000/11/01 00:16:17 guy Exp $
+ * $Id: packet-gryphon.c,v 1.13 2000/11/05 09:05:00 guy Exp $
*
* Ethereal - Network traffic analyzer
* By Steve Limkemann <stevelim@dgtech.com>
@@ -51,8 +51,6 @@
DLLEXPORT const gchar version[] = VERSION;
DLLEXPORT const gchar desc[] = "DG Gryphon Protocol";
-DLLEXPORT const gchar protocol[] = "tcp";
-DLLEXPORT const gchar filter_string[] = "tcp.port == 7000";
#ifndef G_HAVE_GINT64
#error "Sorry, this won't compile without 64-bit integer support"
@@ -87,8 +85,8 @@ static gint ett_gryphon_pgm_options = -1;
-DLLEXPORT void
-dissector(const u_char *pd, int offset, frame_data *fd, proto_tree *tree)
+static void
+dissect_gryphon(const u_char *pd, int offset, frame_data *fd, proto_tree *tree)
{
proto_tree *gryphon_tree, *header_tree, *body_tree, *localTree;
@@ -116,6 +114,8 @@ dissector(const u_char *pd, int offset, frame_data *fd, proto_tree *tree)
{-1, "- unknown -"},
};
+ OLD_CHECK_DISPLAY_AS_DATA(proto_gryphon, pd, offset, fd, tree);
+
data = &pd[offset];
if (fd) {
end_of_frame = END_OF_FRAME;
@@ -1228,7 +1228,7 @@ cmd_addresp (int src, const u_char **data, const u_char *dataend, int *offset, i
length += 3 - (length + 3) % 4;
item = proto_tree_add_text(pt, NullTVB, *offset, length, "Response block %d", i);
tree = proto_item_add_subtree (item, ett_gryphon_cmd_response_block);
- dissector((*data)-*offset, *offset, NULL, tree);
+ dissect_gryphon((*data)-*offset, *offset, NULL, tree);
BUMP (*offset, *data, length);
}
}
@@ -1702,7 +1702,6 @@ plugin_init(plugin_address_table_t *pat)
&ett_gryphon_pgm_options,
};
plugin_address_table_init(pat);
- dfilter_cleanup();
if (proto_gryphon == -1) {
/* first activation */
proto_gryphon = proto_register_protocol("DG Gryphon Protocol",
@@ -1713,5 +1712,10 @@ plugin_init(plugin_address_table_t *pat)
/* do nothing, this is in fact a re-activation with possibly
a new filter */
}
- dfilter_init();
+}
+
+void
+plugin_reg_handoff(void)
+{
+ old_dissector_add("tcp.port", 7000, &dissect_gryphon);
}