aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--doc/README.plugins26
-rw-r--r--epan/CMakeLists.txt2
-rw-r--r--epan/Makefile.common4
-rw-r--r--epan/plugin_if.c (renamed from epan/ext_menubar.c)89
-rw-r--r--epan/plugin_if.h (renamed from epan/ext_menubar.h)42
-rw-r--r--ui/gtk/main_filter_toolbar.c24
-rw-r--r--ui/gtk/main_menubar.c2
-rw-r--r--ui/gtk/packet_list.c24
-rw-r--r--ui/preference_utils.c42
-rw-r--r--ui/preference_utils.h10
-rw-r--r--ui/qt/main_window.cpp44
-rw-r--r--ui/qt/main_window.h2
12 files changed, 292 insertions, 19 deletions
diff --git a/doc/README.plugins b/doc/README.plugins
index eca52da251..e8cac10246 100644
--- a/doc/README.plugins
+++ b/doc/README.plugins
@@ -321,12 +321,14 @@ is encouraged to update their plugins as outlined below:
the DOCSIS plugin.
-6 How to implement a plugin related menu
+6 How to plugin related interface options
+
+6.1 Implement a plugin GUI menu
A plugin (as well as built-in dissectors) may implement a menu within
Wireshark to be used to trigger options, start tools, open Websites, ...
-This menu structure is built using the ext_menubar.h interface and it's
+This menu structure is built using the plugin_if.h interface and it's
corresponding functions.
The menu items all call a callback provided by the plugin, which takes
@@ -365,7 +367,25 @@ Using the Gtk Version and a Mac OSX operating system, this will not work, and
the Gtk interface is currently not supported on this plattform. The Qt interface
on Mac provides the menu.
-For a more detailed information, please refer to ext_menubar.h
+For a more detailed information, please refer to plugin_if.h
+
+6.2 Implement interactions with the main interface
+
+Due to memory constraints on most plattforms, plugin functionality cannot be
+called directly from a DLL context. Instead special functions will be used, which
+will implement certain options for plugins to utilize.
+
+The following methods exist so far:
+
+ /* Applies the given filter string as display filter */
+ WS_DLL_PUBLIC void plugin_if_apply_filter
+ (const char * filter_string, gboolean force);
+
+ /* Saves the given preference to the main preference storage */
+ WS_DLL_PUBLIC void plugin_if_save_preference
+ (const char * pref_module, const char * pref_key, const char * pref_value);
+
+
----------------
diff --git a/epan/CMakeLists.txt b/epan/CMakeLists.txt
index aa37191ddc..36d141bf0d 100644
--- a/epan/CMakeLists.txt
+++ b/epan/CMakeLists.txt
@@ -1600,7 +1600,7 @@ set(LIBWIRESHARK_FILES
except.c
expert.c
exported_pdu.c
- ext_menubar.c
+ plugin_if.c
filter_expressions.c
follow.c
frame_data.c
diff --git a/epan/Makefile.common b/epan/Makefile.common
index a8c3bb5ad1..fe81b1c7ea 100644
--- a/epan/Makefile.common
+++ b/epan/Makefile.common
@@ -51,7 +51,7 @@ LIBWIRESHARK_SRC = \
except.c \
expert.c \
exported_pdu.c \
- ext_menubar.c \
+ plugin_if.c \
filter_expressions.c \
follow.c \
frame_data.c \
@@ -192,7 +192,7 @@ LIBWIRESHARK_INCLUDES = \
exceptions.h \
expert.h \
exported_pdu.h \
- ext_menubar.h \
+ plugin_if.h \
filter_expressions.h \
follow.h \
frame_data.h \
diff --git a/epan/ext_menubar.c b/epan/plugin_if.c
index 25501520c7..62244dd4fd 100644
--- a/epan/ext_menubar.c
+++ b/epan/plugin_if.c
@@ -1,9 +1,12 @@
-/* ext_menubar.c
- * A menubar API for Wireshark dissectors
+/* plugin_if.c
+ * An API for Wireshark plugins
*
* This enables wireshark dissectors, especially those implemented by plugins
* to register menubar entries, which then will call a pre-defined callback
- * function for the dissector or plugin
+ * function for the dissector or plugin.
+ *
+ * Also it implements additional methods, which allow plugins to interoperate
+ * with the main GUI.
*
* Wireshark - Network traffic analyzer
* By Gerald Combs <gerald@wireshark.org>
@@ -30,7 +33,7 @@
#include <epan/epan.h>
#include <epan/proto.h>
-#include "ext_menubar.h"
+#include "plugin_if.h"
static GList * menubar_entries = NULL;
static GList * menubar_menunames = NULL;
@@ -158,6 +161,84 @@ extern void ext_menubar_add_separator(ext_menu_t *parent)
ext_menubar_add_generic_entry ( EXT_MENUBAR_SEPARATOR, parent, g_strdup("-"), NULL, NULL, NULL );
}
+/* Implementation of GUI callback methods follows.
+ * This is a necessity, as using modern UI systems, gui interfaces often operate
+ * in different threads then the calling application. Even more so, if the calling
+ * application is implemented using a separate plugin. Therefore the external menubars
+ * cannot call gui functionality directly, the gui has to perform the function within
+ * it' own scope. */
+
+static GHashTable * plugin_if_callback_functions;
+
+static void
+plugin_if_init_hashtable(void)
+{
+ if ( plugin_if_callback_functions == 0 )
+ plugin_if_callback_functions = g_hash_table_new(g_int_hash, g_int_equal);
+}
+
+static void plugin_if_call_gui_cb(plugin_if_callback_t actionType, GHashTable * dataSet)
+{
+ plugin_if_gui_cb action;
+ gint * key = 0;
+
+ key = (gint *)g_malloc0(sizeof(gint));
+ *key = (gint) actionType;
+
+ plugin_if_init_hashtable();
+
+ if ( g_hash_table_size(plugin_if_callback_functions) != 0 )
+ {
+ if ( g_hash_table_contains(plugin_if_callback_functions, key) )
+ {
+ action = (plugin_if_gui_cb)g_hash_table_lookup(plugin_if_callback_functions, key);
+ if ( action != NULL )
+ action(dataSet);
+ }
+ }
+}
+
+extern void plugin_if_apply_filter(const char * filter_string, gboolean force)
+{
+ plugin_if_callback_t actionType;
+ GHashTable * dataSet = NULL;
+
+ actionType = ( force == TRUE ) ? PLUGIN_IF_FILTER_ACTION_APPLY : PLUGIN_IF_FILTER_ACTION_PREPARE;
+ dataSet = g_hash_table_new(g_str_hash, g_str_equal);
+
+ g_hash_table_insert( dataSet, g_strdup("action_type"), (gpointer) &actionType );
+ g_hash_table_insert( dataSet, g_strdup("filter_string"), g_strdup(filter_string) );
+ g_hash_table_insert( dataSet, g_strdup("force"), (gpointer) &force );
+
+ plugin_if_call_gui_cb(actionType, dataSet);
+}
+
+extern void plugin_if_save_preference(const char * pref_module, const char * pref_key, const char * pref_value)
+{
+ GHashTable * dataSet = NULL;
+
+ dataSet = g_hash_table_new(g_str_hash, g_str_equal);
+
+ g_hash_table_insert( dataSet, g_strdup("pref_module"), g_strdup(pref_module) );
+ g_hash_table_insert( dataSet, g_strdup("pref_key"), g_strdup(pref_key) );
+ g_hash_table_insert( dataSet, g_strdup("pref_value"), g_strdup(pref_value) );
+
+ plugin_if_call_gui_cb(PLUGIN_IF_PREFERENCE_SAVE, dataSet);
+}
+
+extern void plugin_if_register_gui_cb(plugin_if_callback_t actionType, plugin_if_gui_cb callback)
+{
+ gint * key = 0;
+
+ key = (gint *)g_malloc0(sizeof(gint));
+ *key = actionType;
+
+ plugin_if_init_hashtable();
+
+ if ( ! g_hash_table_contains(plugin_if_callback_functions, key ) )
+ g_hash_table_insert(plugin_if_callback_functions, key, callback);
+}
+
/*
* Editor modelines
*
diff --git a/epan/ext_menubar.h b/epan/plugin_if.h
index acffa8f2e8..df9ea6e846 100644
--- a/epan/ext_menubar.h
+++ b/epan/plugin_if.h
@@ -1,9 +1,12 @@
-/* ext_menubar.h
- * A menubar API for Wireshark dissectors
+/* plugin_if.h
+ * An API for Wireshark plugins
*
* This enables wireshark dissectors, especially those implemented by plugins
* to register menubar entries, which then will call a pre-defined callback
- * function for the dissector or plugin
+ * function for the dissector or plugin.
+ *
+ * Also it implements additional methods, which allow plugins to interoperate
+ * with the main GUI.
*
* Wireshark - Network traffic analyzer
* By Gerald Combs <gerald@wireshark.org>
@@ -23,8 +26,8 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
-#ifndef EPAN_EXT_MENUBAR_H_
-#define EPAN_EXT_MENUBAR_H_
+#ifndef EPAN_PLUGIN_IF_H
+#define EPAN_PLUGIN_IF_H
#include <config.h>
@@ -146,6 +149,33 @@ WS_DLL_PUBLIC void ext_menubar_add_separator(ext_menu_t *parent_menu);
WS_DLL_PUBLIC void ext_menubar_add_website(ext_menu_t * parent, const gchar *label,
const gchar *tooltip, const gchar *url);
+
+/*
+ * Enumeration of possible actions, which are registered in GUI interfaces
+ */
+typedef enum
+{
+ /* Applies a given string as filter */
+ PLUGIN_IF_FILTER_ACTION_APPLY,
+
+ /* Prepares the given string as filter */
+ PLUGIN_IF_FILTER_ACTION_PREPARE,
+
+ /* Saves a preference entry */
+ PLUGIN_IF_PREFERENCE_SAVE
+} plugin_if_callback_t;
+
+
+typedef void (*plugin_if_gui_cb)(gconstpointer user_data);
+
+WS_DLL_PUBLIC void plugin_if_register_gui_cb(plugin_if_callback_t actionType, plugin_if_gui_cb callback);
+
+/* Applies the given filter string as display filter */
+WS_DLL_PUBLIC void plugin_if_apply_filter(const char * filter_string, gboolean force);
+
+/* Saves the given preference to the main preference storage */
+WS_DLL_PUBLIC void plugin_if_save_preference(const char * pref_module, const char * pref_key, const char * pref_value);
+
/* Private Method for retrieving the menubar entries
*
* Is only to be used by the UI interfaces to retrieve the menu entries
@@ -156,7 +186,7 @@ WS_DLL_PUBLIC GList * ext_menubar_get_entries(void);
}
#endif /* __cplusplus */
-#endif /* EPAN_EXT_MENUBAR_H_ */
+#endif /* EPAN_PLUGIN_IF_H */
/*
* Editor modelines
diff --git a/ui/gtk/main_filter_toolbar.c b/ui/gtk/main_filter_toolbar.c
index f47e7819dc..eed3ee3cc2 100644
--- a/ui/gtk/main_filter_toolbar.c
+++ b/ui/gtk/main_filter_toolbar.c
@@ -39,6 +39,7 @@
#include "filter_autocomplete.h"
#include "epan/prefs.h"
+#include "epan/plugin_if.h"
#include "keys.h"
#include "gtkglobals.h"
@@ -109,6 +110,26 @@ filter_save_cb(GtkWidget *w _U_, GtkWindow *parent_w)
filter_expression_save_dlg(parent_w);
}
+static void
+plugin_if_filter_apply(gconstpointer filter_text)
+{
+ /* code is derived from voip_calls_dlg.c::voip_calls_on_filter */
+
+ int pos = 0;
+ size_t filter_length;
+ size_t max_filter_length = 2048;
+ gchar *filter_string;
+
+ if ( main_display_filter_widget != 0 )
+ {
+ filter_string = g_strndup((const char *)filter_text, max_filter_length);
+ filter_length = strlen(filter_string);
+ pos = (int)filter_length;
+
+ if ( filter_length < max_filter_length )
+ gtk_editable_insert_text(GTK_EDITABLE(main_display_filter_widget), filter_string, -1, &pos);
+ }
+}
GtkWidget *
filter_toolbar_new(void)
@@ -279,6 +300,9 @@ filter_toolbar_new(void)
/* make current preferences effective */
toolbar_redraw_all();
+ plugin_if_register_gui_cb(PLUGIN_IF_FILTER_ACTION_APPLY, plugin_if_filter_apply );
+ plugin_if_register_gui_cb(PLUGIN_IF_FILTER_ACTION_PREPARE, plugin_if_filter_apply );
+
return filter_tb;
}
diff --git a/ui/gtk/main_menubar.c b/ui/gtk/main_menubar.c
index b4c24d986a..50292d049e 100644
--- a/ui/gtk/main_menubar.c
+++ b/ui/gtk/main_menubar.c
@@ -36,7 +36,7 @@
#include <epan/epan_dissect.h>
#include <epan/column.h>
#include <epan/stats_tree_priv.h>
-#include <epan/ext_menubar.h>
+#include <epan/plugin_if.h>
#include "globals.h"
#include "color_filters.h"
diff --git a/ui/gtk/packet_list.c b/ui/gtk/packet_list.c
index f9a4f298e7..57ab4f95bb 100644
--- a/ui/gtk/packet_list.c
+++ b/ui/gtk/packet_list.c
@@ -34,6 +34,7 @@
#include <epan/packet.h>
#include <epan/column.h>
#include <epan/strutil.h>
+#include <epan/plugin_if.h>
#include "ui/main_statusbar.h"
#include "ui/packet_list_utils.h"
@@ -91,6 +92,7 @@ static void show_cell_data_func(GtkTreeViewColumn *col,
static gint row_number_from_iter(GtkTreeIter *iter);
static void scroll_to_current(void);
static gboolean query_packet_list_tooltip_cb(GtkWidget *widget, gint x, gint y, gboolean keyboard_tip, GtkTooltip *tooltip, gpointer data _U_);
+static void plugin_if_pktlist_preference(gconstpointer user_data);
GtkWidget *
packet_list_create(void)
@@ -105,6 +107,8 @@ packet_list_create(void)
g_object_set_data(G_OBJECT(popup_menu_object), E_MPACKET_LIST_KEY, view);
+ plugin_if_register_gui_cb(PLUGIN_IF_PREFERENCE_SAVE, plugin_if_pktlist_preference);
+
return scrollwin;
}
@@ -1730,6 +1734,26 @@ query_packet_list_tooltip_cb(GtkWidget *widget, gint x, gint y, gboolean keyboar
return result;
}
+void plugin_if_pktlist_preference(gconstpointer user_data)
+{
+ if ( packetlist != NULL && user_data != NULL )
+ {
+ GHashTable * dataSet = (GHashTable *) user_data;
+ if ( g_hash_table_contains(dataSet, "pref_module" ) &&
+ g_hash_table_contains(dataSet, "pref_value" ) &&
+ g_hash_table_contains(dataSet, "pref_value" ) )
+ {
+ const char * module_name = (const char *)g_hash_table_lookup(dataSet, "pref_module");
+ const char * pref_name = (const char *)g_hash_table_lookup(dataSet, "pref_key");
+ const char * pref_value = (const char *)g_hash_table_lookup(dataSet, "pref_value");
+
+ if ( prefs_store_ext(module_name, pref_name, pref_value) )
+ packet_list_recreate();
+
+ }
+ }
+}
+
/*
* Editor modelines - http://www.wireshark.org/tools/modelines.html
*
diff --git a/ui/preference_utils.c b/ui/preference_utils.c
index 1e358bd7d0..0f80ef6742 100644
--- a/ui/preference_utils.c
+++ b/ui/preference_utils.c
@@ -273,6 +273,48 @@ prefs_main_write(void)
}
}
+gboolean
+prefs_store_ext(const char * module_name, const char *pref_name, const char *pref_value)
+{
+ module_t * module = NULL;
+ pref_t * pref = NULL;
+ gboolean pref_changed = TRUE;
+
+ if ( ! prefs_is_registered_protocol(module_name))
+ return FALSE;
+
+ module = prefs_find_module(module_name);
+ if ( ! module )
+ return FALSE;
+
+ pref = prefs_find_preference(module, pref_name);
+
+ if (!pref)
+ return FALSE;
+
+ if ( pref->type == PREF_STRING )
+ {
+ g_free((void *)pref->stashed_val.string);
+ pref->stashed_val.string = (gchar *) g_strdup(pref_value);
+ /* unstash - taken from preferences_util */
+ if (strcmp(*pref->varp.string, pref->stashed_val.string) != 0)
+ {
+ pref_changed = TRUE;
+ g_free((void *)*pref->varp.string);
+ *pref->varp.string = g_strdup(pref->stashed_val.string);
+ }
+ }
+
+ if ( pref_changed )
+ {
+ prefs_main_write();
+ prefs_apply_all();
+ prefs_to_capture_opts();
+ }
+
+ return TRUE;
+}
+
gint
column_prefs_add_custom(gint fmt, const gchar *title, const gchar *custom_field, gint custom_occurrence)
{
diff --git a/ui/preference_utils.h b/ui/preference_utils.h
index 882555d70a..a0b345d043 100644
--- a/ui/preference_utils.h
+++ b/ui/preference_utils.h
@@ -80,6 +80,16 @@ extern void prefs_to_capture_opts(void);
*/
extern void prefs_main_write(void);
+/** Convenient function for plugin_if
+ *
+ * @param module the module for the preference
+ * @param key the key for the preference
+ * @param value the new value as string for the preference
+ *
+ * @return true if the value has been stored successfully
+ */
+extern gboolean prefs_store_ext(const char * module, const char * key, const char * value);
+
/** Add a custom column.
*
* @param fmt column format
diff --git a/ui/qt/main_window.cpp b/ui/qt/main_window.cpp
index abae150c71..35e110c39b 100644
--- a/ui/qt/main_window.cpp
+++ b/ui/qt/main_window.cpp
@@ -27,7 +27,7 @@
#include <wsutil/filesystem.h>
#include <epan/prefs.h>
#include <epan/stats_tree_priv.h>
-#include <epan/ext_menubar.h>
+#include <epan/plugin_if.h>
#ifdef HAVE_LIBPCAP
#include "ui/capture.h"
@@ -42,6 +42,7 @@
#include "ui/main_statusbar.h"
#include "ui/recent.h"
#include "ui/util.h"
+#include "ui/preference_utils.h"
#include "byte_view_tab.h"
#include "display_filter_edit.h"
@@ -83,6 +84,42 @@ void pipe_input_set_handler(gint source, gpointer user_data, ws_process_id *chil
gbl_cur_main_window_->setPipeInputHandler(source, user_data, child_process, input_cb);
}
+void plugin_if_mainwindow_apply_filter(gconstpointer user_data)
+{
+ if ( gbl_cur_main_window_ != NULL && user_data != NULL )
+ {
+ GHashTable * dataSet = (GHashTable *) user_data;
+
+ if ( g_hash_table_contains(dataSet, "filter_string" ) )
+ {
+ QString filter((const char *)g_hash_table_lookup(dataSet, "filter_string"));
+ gbl_cur_main_window_->filterPackets(filter);
+ }
+ }
+}
+
+void plugin_if_mainwindow_preference(gconstpointer user_data)
+{
+ if ( gbl_cur_main_window_ != NULL && user_data != NULL )
+ {
+ GHashTable * dataSet = (GHashTable *) user_data;
+ if ( g_hash_table_contains(dataSet, "pref_module" ) &&
+ g_hash_table_contains(dataSet, "pref_value" ) &&
+ g_hash_table_contains(dataSet, "pref_value" ) )
+ {
+ const char * module_name = (const char *)g_hash_table_lookup(dataSet, "pref_module");
+ const char * pref_name = (const char *)g_hash_table_lookup(dataSet, "pref_key");
+ const char * pref_value = (const char *)g_hash_table_lookup(dataSet, "pref_value");
+
+ if ( prefs_store_ext(module_name, pref_name, pref_value) )
+ {
+ wsApp->emitAppSignal(WiresharkApplication::PacketDissectionChanged);
+ wsApp->emitAppSignal(WiresharkApplication::PreferencesChanged);
+ }
+ }
+ }
+}
+
gpointer
simple_dialog(ESD_TYPE_E type, gint btn_mask, const gchar *msg_format, ...)
{
@@ -479,6 +516,11 @@ MainWindow::MainWindow(QWidget *parent) :
this->main_welcome_->getInterfaceTree(), SLOT(interfaceListChanged()));
#endif
+ /* Create plugin_if hooks */
+ plugin_if_register_gui_cb(PLUGIN_IF_FILTER_ACTION_APPLY, plugin_if_mainwindow_apply_filter );
+ plugin_if_register_gui_cb(PLUGIN_IF_FILTER_ACTION_PREPARE, plugin_if_mainwindow_apply_filter );
+ plugin_if_register_gui_cb(PLUGIN_IF_PREFERENCE_SAVE, plugin_if_mainwindow_preference);
+
main_ui_->mainStack->setCurrentWidget(main_welcome_);
}
diff --git a/ui/qt/main_window.h b/ui/qt/main_window.h
index 220bc63ffe..dbb85847aa 100644
--- a/ui/qt/main_window.h
+++ b/ui/qt/main_window.h
@@ -33,7 +33,7 @@
#include "ui/ui_util.h"
#include <epan/prefs.h>
-#include <epan/ext_menubar.h>
+#include <epan/plugin_if.h>
#ifdef HAVE_LIBPCAP
#include "capture_opts.h"