aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRoland Knall <roland.knall@br-automation.com>2015-12-29 07:57:36 +0100
committerRoland Knall <rknall@gmail.com>2016-02-01 12:12:41 +0000
commit927ffaa794d5fb24e0b4f3fba08c4c31f4dd7d63 (patch)
tree70676d0b7e00e0b10678d0f7f3ff7dd707eabcd2
parent5e89f9332228015c3e5c813939bf35dbcc5a105d (diff)
extcap: Add Save functionality to options dialog
This patch creates the functionality of saving all parameters for extcap devices in the general preference section. For now, multiselect and fileselect do not save their values but patches for this will be provided in the future Also, all preferences are stored as strings to make handling easier. This might change in the future, but for the first version it will stick. Restore to Defaults is not implemented as of yet, and will be in a future version, once the preference storing is finalized Bug: 11666 Change-Id: I178346405146d2e43f4f3481c05c92c0b3595af5 Reviewed-on: https://code.wireshark.org/review/13451 Petri-Dish: Roland Knall <rknall@gmail.com> Tested-by: Petri Dish Buildbot <buildbot-no-reply@wireshark.org> Reviewed-by: Roland Knall <rknall@gmail.com>
-rw-r--r--doc/README.extcap3
-rwxr-xr-xdoc/extcap_example.py5
-rw-r--r--epan/prefs.c22
-rw-r--r--epan/prefs.h3
-rw-r--r--extcap.c146
-rw-r--r--extcap.h4
-rw-r--r--extcap_parser.c6
-rw-r--r--extcap_parser.h4
-rw-r--r--ui/gtk/main.c8
-rw-r--r--ui/qt/extcap_argument.cpp59
-rw-r--r--ui/qt/extcap_argument.h4
-rw-r--r--ui/qt/extcap_options_dialog.cpp86
-rw-r--r--ui/qt/extcap_options_dialog.h1
-rw-r--r--ui/qt/extcap_options_dialog.ui19
-rw-r--r--wireshark-qt.cpp8
15 files changed, 343 insertions, 35 deletions
diff --git a/doc/README.extcap b/doc/README.extcap
index 7b53b7fcfd..6a4f33f44d 100644
--- a/doc/README.extcap
+++ b/doc/README.extcap
@@ -150,7 +150,8 @@ These options do have types, for which the following types are being supported:
the user input for validity beyond normal data type or range checks. Back-slashes
must be escaped (as in \\b for \b)
- * PASSWORD - Let the user provide a masked string to the capture
+ * PASSWORD - Let the user provide a masked string to the capture. Password strings are
+ not saved, when the extcap configuration is being saved
arg {number=0}{call=--password}{display=The user password}{tooltip=The password for the connection}{type=password}
diff --git a/doc/extcap_example.py b/doc/extcap_example.py
index 571605837e..ab9967c489 100755
--- a/doc/extcap_example.py
+++ b/doc/extcap_example.py
@@ -78,7 +78,10 @@ def extcap_config(interface):
args.append ( (2, '--verify', 'Verify', 'Verify package content', 'boolflag', '{default=yes}') )
args.append ( (3, '--remote', 'Remote Channel', 'Remote Channel Selector', 'selector', ''))
args.append ( (4, '--fake_ip', 'Fake IP Address', 'Use this ip address as sender', 'string', '{save=false}{validation=\\b(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\b}'))
- args.append ( (5, '--password', 'Password', 'Package message password', 'password', '') )
+ args.append ( (5, '--ltest', 'Long Test', 'Long Test Value', 'long', '{default=123123123123123123}'))
+ args.append ( (6, '--d1test', 'Double 1 Test', 'Long Test Value', 'double', '{default=123.456}'))
+ args.append ( (7, '--d2test', 'Double 2 Test', 'Long Test Value', 'double', '{default= 123,456}'))
+ args.append ( (8, '--password', 'Password', 'Package message password', 'password', '') )
values.append ( (3, "if1", "Remote1", "true" ) )
values.append ( (3, "if2", "Remote2", "false" ) )
diff --git a/epan/prefs.c b/epan/prefs.c
index 2fb1b0d567..fc471e00ad 100644
--- a/epan/prefs.c
+++ b/epan/prefs.c
@@ -2082,6 +2082,10 @@ prefs_register_modules(void)
{
module_t *printing, *capture_module, *console_module,
*gui_layout_module, *gui_font_module;
+#ifdef HAVE_EXTCAP
+ module_t *extcap_module;
+#endif
+
struct pref_custom_cbs custom_cbs;
if (protocols_module != NULL) {
@@ -2089,6 +2093,24 @@ prefs_register_modules(void)
return;
}
+#ifdef HAVE_EXTCAP
+ /* GUI
+ * These are "simple" GUI preferences that can be read/written using the
+ * preference module API. These preferences still use their own
+ * configuration screens for access, but this cuts down on the
+ * preference "string compare list" in set_pref()
+ */
+ extcap_module = prefs_register_module(NULL, "extcap", "Extcap Utilities",
+ "Extcap Utilities", NULL, FALSE);
+
+ /* Setting default value to true */
+ prefs.extcap_save_on_start = TRUE;
+ prefs_register_bool_preference(extcap_module, "gui_save_on_start",
+ "Save arguments on start of capture",
+ "Save arguments on start of capture",
+ &prefs.extcap_save_on_start);
+#endif
+
/* GUI
* These are "simple" GUI preferences that can be read/written using the
* preference module API. These preferences still use their own
diff --git a/epan/prefs.h b/epan/prefs.h
index 6bb48d70dd..fd8afce28b 100644
--- a/epan/prefs.h
+++ b/epan/prefs.h
@@ -236,6 +236,9 @@ typedef struct _e_prefs {
gint st_sort_defcolflag;
gboolean st_sort_defdescending;
gboolean st_sort_showfullname;
+#ifdef HAVE_EXTCAP
+ gboolean extcap_save_on_start;
+#endif
} e_prefs;
WS_DLL_PUBLIC e_prefs prefs;
diff --git a/extcap.c b/extcap.c
index df40bd1017..c2f01d102a 100644
--- a/extcap.c
+++ b/extcap.c
@@ -40,6 +40,9 @@
#include <glib.h>
#include <log.h>
+#include <epan/prefs.h>
+#include <epan/prefs-int.h>
+
#include <wsutil/file_util.h>
#include <wsutil/filesystem.h>
#include <wsutil/tempfile.h>
@@ -69,7 +72,7 @@ static GHashTable *ifaces = NULL;
static GHashTable *tools = NULL;
/* Callback definition for extcap_foreach */
-typedef gboolean (*extcap_cb_t)(const gchar *extcap, gchar *output, void *data,
+typedef gboolean (*extcap_cb_t)(const gchar *extcap, const gchar *ifname, gchar *output, void *data,
gchar **err_str);
/* #define ARG_DEBUG */
@@ -201,7 +204,7 @@ static void extcap_foreach(gint argc, gchar **args, extcap_cb_t cb,
&command_output, NULL, &exit_status, &error);
if (status && exit_status == 0)
- keep_going = cb(extcap_path->str, command_output, cb_data, err_str);
+ keep_going = cb(extcap_path->str, ifname, command_output, cb_data, err_str);
g_free(argv[0]);
g_free(command_output);
@@ -217,7 +220,7 @@ static void extcap_foreach(gint argc, gchar **args, extcap_cb_t cb,
g_free(argv);
}
-static gboolean dlt_cb(const gchar *extcap _U_, gchar *output, void *data,
+static gboolean dlt_cb(const gchar *extcap _U_, const gchar *ifname _U_, gchar *output, void *data,
char **err_str) {
extcap_token_sentence *tokens;
extcap_dlt *dlts, *dlt_iter, *next;
@@ -300,7 +303,7 @@ extcap_get_if_dlts(const gchar *ifname, char **err_str) {
return caps;
}
-static gboolean interfaces_cb(const gchar *extcap, gchar *output, void *data,
+static gboolean interfaces_cb(const gchar *extcap, const gchar *ifname _U_, gchar *output, void *data,
char **err_str _U_) {
GList **il = (GList **) data;
extcap_token_sentence *tokens;
@@ -422,6 +425,27 @@ static void extcap_free_arg_elem(gpointer data, gpointer user_data _U_) {
g_free(data);
}
+void extcap_register_preferences(void)
+{
+ GList * interfaces = NULL;
+
+ module_t * dev_module = prefs_find_module("extcap");
+
+ if ( !dev_module )
+ return;
+
+ if ( ! ifaces || g_hash_table_size(ifaces) == 0 )
+ extcap_interface_list(NULL);
+
+ interfaces = g_hash_table_get_keys(ifaces);
+
+ while ( interfaces ) {
+ extcap_get_if_configuration((gchar *)interfaces->data);
+
+ interfaces = g_list_next(interfaces);
+ }
+}
+
static void extcap_free_if_configuration(GList *list)
{
GList *elem, *sl;
@@ -438,11 +462,12 @@ static void extcap_free_if_configuration(GList *list)
g_list_free(list);
}
-static gboolean search_cb(const gchar *extcap _U_, gchar *output, void *data,
+static gboolean search_cb(const gchar *extcap _U_, const gchar *ifname _U_, gchar *output, void *data,
char **err_str _U_) {
extcap_token_sentence *tokens = NULL;
GList *arguments = NULL;
GList **il = (GList **) data;
+ module_t * dev_module = NULL;
tokens = extcap_tokenize_sentences(output);
arguments = extcap_parse_args(tokens);
@@ -453,6 +478,45 @@ static gboolean search_cb(const gchar *extcap _U_, gchar *output, void *data,
extcap_debug_arguments ( arguments );
#endif
+ dev_module = prefs_find_module("extcap");
+
+ if ( dev_module ) {
+ GList * walker = arguments;
+
+ GRegex * regex = g_regex_new ("[-]+", (GRegexCompileFlags) 0, (GRegexMatchFlags) 0, NULL );
+ if (regex) {
+ while ( walker != NULL ) {
+ extcap_arg * arg = (extcap_arg *)walker->data;
+
+ if ( arg->save ) {
+ struct preference * pref = NULL;
+
+ gchar * pref_name = g_regex_replace(regex, arg->call, strlen(arg->call), 0, "", (GRegexMatchFlags) 0, NULL );
+ gchar * pref_ifname = g_strdup(g_strconcat(ifname, ".", pref_name, NULL));
+
+ if ( ( pref = prefs_find_preference(dev_module, pref_ifname) ) == NULL ) {
+ /* Set an initial value */
+ if ( ! arg->storeval && arg->default_complex )
+ arg->storeval = g_strdup(arg->default_complex->_val);
+
+ prefs_register_string_preference(dev_module, g_strdup(pref_ifname),
+ arg->display, arg->display, (const gchar **)&(arg->storeval));
+ } else {
+ /* Been here before, restore stored value */
+ if (! arg->storeval && pref->varp.string)
+ arg->storeval = g_strdup(*(pref->varp.string));
+ }
+
+ g_free(pref_name);
+ g_free(pref_ifname);
+ }
+
+ walker = g_list_next(walker);
+ }
+ g_regex_unref(regex);
+ }
+ }
+
*il = g_list_append(*il, arguments);
/* By returning false, extcap_foreach will break on first found */
@@ -494,16 +558,33 @@ extcap_has_configuration(const char * ifname, gboolean is_required) {
arguments = extcap_get_if_configuration((const char *)( ifname ) );
walker = g_list_first(arguments);
- while ( walker != NULL && ! found )
- {
+ while ( walker != NULL && ! found ) {
item = g_list_first((GList *)(walker->data));
- while ( item != NULL && ! found )
- {
- if ( (extcap_arg *)(item->data) != NULL )
- {
+ while ( item != NULL && ! found ) {
+ if ( (extcap_arg *)(item->data) != NULL ) {
+ extcap_arg * arg = (extcap_arg *)(item->data);
/* Should required options be present, or any kind of options */
- if ( ! is_required || ((extcap_arg *)(item->data))->is_required )
+ if ( ! is_required )
found = TRUE;
+ else if ( arg->is_required ) {
+ gchar * stored = NULL;
+ gchar * defval = NULL;
+
+ if ( arg->storeval != NULL )
+ stored = arg->storeval;
+
+ if ( arg->default_complex != NULL && arg->default_complex->_val != NULL )
+ defval = arg->default_complex->_val;
+
+ if ( arg->is_required ) {
+ /* If stored and defval is identical and the argument is required,
+ * configuration is needed */
+ if ( defval && stored && g_strcmp0(stored, defval) == 0 )
+ found = TRUE;
+ else if ( ! defval && (!stored || strlen(g_strchomp(stored)) <= (size_t)0) )
+ found = TRUE;
+ }
+ }
}
item = item->next;
@@ -574,8 +655,8 @@ void extcap_cleanup(capture_options * capture_opts) {
}
}
-static void
-extcap_arg_cb(gpointer key, gpointer value, gpointer data) {
+static gboolean
+extcap_add_arg_and_remove_cb(gpointer key, gpointer value, gpointer data) {
GPtrArray *args = (GPtrArray *)data;
if ( key != NULL )
@@ -584,7 +665,11 @@ extcap_arg_cb(gpointer key, gpointer value, gpointer data) {
if ( value != NULL )
g_ptr_array_add(args, g_strdup((const gchar*)value));
+
+ return TRUE;
}
+
+ return FALSE;
}
static void extcap_child_watch_cb(GPid pid, gint status _U_, gpointer user_data)
@@ -650,7 +735,7 @@ extcap_init_interfaces(capture_options *capture_opts)
}
add_arg(EXTCAP_ARGUMENT_RUN_PIPE);
add_arg(interface_opts.extcap_fifo);
- if (interface_opts.extcap_args == NULL)
+ if (interface_opts.extcap_args == NULL || g_hash_table_size(interface_opts.extcap_args) == 0)
{
/* User did not perform interface configuration.
*
@@ -672,18 +757,29 @@ extcap_init_interfaces(capture_options *capture_opts)
}
arg_list = g_list_first((GList *)elem->data);
- while (arg_list != NULL)
- {
+ while (arg_list != NULL) {
+ gchar * stored = NULL, * defval = NULL;
/* In case of boolflags only first element in arg_list is relevant. */
arg_iter = (extcap_arg*) (arg_list->data);
-
- if (arg_iter->arg_type == EXTCAP_ARG_BOOLFLAG)
- {
- if (arg_iter->default_complex != NULL
- && extcap_complex_get_bool(arg_iter->default_complex))
- {
- add_arg(arg_iter->call);
+ if ( arg_iter->storeval != NULL )
+ stored = arg_iter->storeval;
+
+ if ( arg_iter->default_complex != NULL && arg_iter->default_complex->_val != NULL )
+ defval = arg_iter->default_complex->_val;
+
+ /* Different data in storage then set for default */
+ if ( g_strcmp0(stored, defval) != 0 ) {
+ if ( arg_iter->arg_type == EXTCAP_ARG_BOOLFLAG ) {
+ if ( g_strcmp0(stored, "true") == 0 )
+ add_arg(arg_iter->call);
+ } else {
+ gchar * call = g_strconcat(arg_iter->call, " ", stored, NULL);
+ add_arg(call);
+ g_free(call);
}
+ } else if (arg_iter->arg_type == EXTCAP_ARG_BOOLFLAG) {
+ if (extcap_complex_get_bool(arg_iter->default_complex))
+ add_arg(arg_iter->call);
}
arg_list = arg_list->next;
@@ -694,7 +790,7 @@ extcap_init_interfaces(capture_options *capture_opts)
}
else
{
- g_hash_table_foreach(interface_opts.extcap_args, extcap_arg_cb, args);
+ g_hash_table_foreach_remove(interface_opts.extcap_args, extcap_add_arg_and_remove_cb, args);
}
add_arg(NULL);
#undef add_arg
diff --git a/extcap.h b/extcap.h
index 02c230014f..b2b6b5fa43 100644
--- a/extcap.h
+++ b/extcap.h
@@ -63,6 +63,10 @@ typedef struct _extcap_info {
extern "C" {
#endif /* __cplusplus */
+/* Registers preferences for all interfaces */
+void
+extcap_register_preferences(void);
+
/* try to get if capabilities from extcap */
if_capabilities_t *
extcap_get_if_dlts(const gchar * ifname, char ** err_str);
diff --git a/extcap_parser.c b/extcap_parser.c
index 37c0e70728..652d7dde14 100644
--- a/extcap_parser.c
+++ b/extcap_parser.c
@@ -353,6 +353,7 @@ void extcap_free_arg(extcap_arg *a) {
g_free(a->tooltip);
g_free(a->fileextension);
g_free(a->regexp);
+ g_free(a->storeval);
if (a->range_start != NULL)
extcap_free_complex(a->range_start);
@@ -404,6 +405,7 @@ extcap_arg *extcap_parse_arg_sentence(GList * args, extcap_token_sentence *s) {
if (sent == EXTCAP_SENTENCE_ARG) {
target_arg = g_new0(extcap_arg, 1);
target_arg->arg_type = EXTCAP_ARG_UNKNOWN;
+ target_arg->save = TRUE;
if ((v = extcap_find_param_by_type(s->param_list, EXTCAP_PARAM_ARGNUM))
== NULL) {
@@ -489,7 +491,7 @@ extcap_arg *extcap_parse_arg_sentence(GList * args, extcap_token_sentence *s) {
} else if (g_ascii_strcasecmp(v->value, "password") == 0) {
target_arg->arg_type = EXTCAP_ARG_PASSWORD;
/* default setting is to not save passwords */
- target_arg->do_not_save = TRUE;
+ target_arg->save = FALSE;
} else if (g_ascii_strcasecmp(v->value, "fileselect") == 0) {
target_arg->arg_type = EXTCAP_ARG_FILESELECT;
} else if (g_ascii_strcasecmp(v->value, "multicheck") == 0) {
@@ -502,7 +504,7 @@ extcap_arg *extcap_parse_arg_sentence(GList * args, extcap_token_sentence *s) {
if ((v = extcap_find_param_by_type(s->param_list, EXTCAP_PARAM_SAVE))
!= NULL) {
- target_arg->do_not_save = ! g_regex_match_simple(EXTCAP_BOOLEAN_REGEX, v->value, G_REGEX_CASELESS, (GRegexMatchFlags)0 );
+ target_arg->save = g_regex_match_simple(EXTCAP_BOOLEAN_REGEX, v->value, G_REGEX_CASELESS, (GRegexMatchFlags)0 );
}
if ((v = extcap_find_param_by_type(s->param_list, EXTCAP_PARAM_RANGE))
diff --git a/extcap_parser.h b/extcap_parser.h
index d1074c8a9b..e43e1ac6db 100644
--- a/extcap_parser.h
+++ b/extcap_parser.h
@@ -107,7 +107,7 @@ typedef struct _extcap_arg {
gboolean fileexists;
gboolean is_required;
- gboolean do_not_save;
+ gboolean save;
gchar * regexp;
@@ -117,6 +117,8 @@ typedef struct _extcap_arg {
extcap_complex *range_end;
extcap_complex *default_complex;
+ gchar * storeval;
+
GList * values;
} extcap_arg;
diff --git a/ui/gtk/main.c b/ui/gtk/main.c
index fef29535bd..b5294bafa4 100644
--- a/ui/gtk/main.c
+++ b/ui/gtk/main.c
@@ -48,6 +48,10 @@
#include <zlib.h> /* to get the libz version number */
#endif
+#ifdef HAVE_EXTCAP
+#include <extcap.h>
+#endif
+
#ifdef HAVE_LIBPORTAUDIO
#include <portaudio.h>
#endif /* HAVE_LIBPORTAUDIO */
@@ -2591,6 +2595,10 @@ main(int argc, char *argv[])
register_all_plugin_tap_listeners();
#endif
+#ifdef HAVE_EXTCAP
+ extcap_register_preferences();
+#endif
+
register_all_tap_listeners();
conversation_table_set_gui_info(init_conversation_table);
hostlist_table_set_gui_info(init_hostlist_table);
diff --git a/ui/qt/extcap_argument.cpp b/ui/qt/extcap_argument.cpp
index 0c06107f3e..3200a7e1d6 100644
--- a/ui/qt/extcap_argument.cpp
+++ b/ui/qt/extcap_argument.cpp
@@ -40,9 +40,12 @@
#include <QStandardItem>
#include <QStandardItemModel>
#include <QItemSelectionModel>
+#include <QRegExp>
#include <glib.h>
#include <log.h>
+
+#include <extcap.h>
#include <epan/prefs.h>
#include <color_utils.h>
@@ -57,6 +60,7 @@ QWidget * ExtArgSelector::createEditor(QWidget * parent)
{
int counter = 0;
int selected = -1;
+ QString stored = _argument->storeval ? QString(_argument->storeval) : QString();
boxSelection = new QComboBox(parent);
@@ -67,7 +71,10 @@ QWidget * ExtArgSelector::createEditor(QWidget * parent)
while ( iter != values.constEnd() )
{
boxSelection->addItem((*iter).value(), (*iter).call());
- if ( (*iter).isDefault() )
+
+ if ( ! _argument->storeval && (*iter).isDefault() )
+ selected = counter;
+ else if ( _argument->storeval && stored.compare((*iter).call()) == 0 )
selected = counter;
counter++;
@@ -135,7 +142,7 @@ QWidget * ExtArgRadio::createEditor(QWidget * parent)
ExtcapValueList::const_iterator iter = values.constBegin();
while ( iter != values.constEnd() )
- {
+ {
QRadioButton * radio = new QRadioButton((*iter).value());
QString callString = (*iter).call();
callStrings->append(callString);
@@ -219,6 +226,15 @@ QWidget * ExtArgBool::createEditor(QWidget * parent)
if ( _argument->tooltip != NULL )
boolBox->setToolTip(QString().fromUtf8(_argument->tooltip));
+ if ( _argument->storeval )
+ {
+ QRegExp regexp(EXTCAP_BOOLEAN_REGEX);
+
+ bool savedstate = ( regexp.indexIn(QString(_argument->storeval[0]), 0) != -1 );
+ if ( savedstate != state )
+ state = savedstate;
+ }
+
boolBox->setCheckState(state ? Qt::Checked : Qt::Unchecked );
connect (boolBox, SIGNAL(stateChanged(int)), SLOT(onIntChanged(int)));
@@ -244,6 +260,13 @@ QString ExtArgBool::value()
return QString(boolBox->checkState() == Qt::Checked ? "true" : "false");
}
+QString ExtArgBool::prefValue()
+{
+ if ( boolBox == NULL )
+ return QString("false");
+ return QString(boolBox->checkState() == Qt::Checked ? "true" : "false");
+}
+
bool ExtArgBool::isValid()
{
/* A bool is allways valid, but the base function checks on string length,
@@ -279,8 +302,17 @@ ExtArgText::ExtArgText(extcap_arg * argument) :
QWidget * ExtArgText::createEditor(QWidget * parent)
{
+ QString storeValue;
QString text = defaultValue();
+ if ( _argument->storeval )
+ {
+ QString storeValue = _argument->storeval;
+
+ if ( storeValue.length() > 0 && storeValue.compare(text) != 0 )
+ text = storeValue.trimmed();
+ }
+
textBox = new QLineEdit(text, parent);
if ( _argument->tooltip != NULL )
@@ -334,7 +366,17 @@ ExtArgNumber::ExtArgNumber(extcap_arg * argument) :
QWidget * ExtArgNumber::createEditor(QWidget * parent)
{
+ QString storeValue;
QString text = defaultValue();
+
+ if ( _argument->storeval )
+ {
+ QString storeValue = _argument->storeval;
+
+ if ( storeValue.length() > 0 && storeValue.compare(text) != 0 )
+ text = storeValue;
+ }
+
textBox = (QLineEdit *)ExtArgText::createEditor(parent);
textBox->disconnect(SIGNAL(textChanged(QString)));
@@ -525,6 +567,10 @@ QString ExtcapArgument::value()
return QString();
}
+QString ExtcapArgument::prefValue()
+{
+ return value();
+}
bool ExtcapArgument::isValid()
{
@@ -544,10 +590,17 @@ QString ExtcapArgument::defaultValue()
if ( str != 0 )
return QString(str);
}
-
return QString();
}
+QString ExtcapArgument::prefKey()
+{
+ if ( ! _argument->save )
+ return QString();
+
+ return QString(_argument->call).replace("-", "");
+}
+
bool ExtcapArgument::isRequired()
{
if ( _argument != NULL )
diff --git a/ui/qt/extcap_argument.h b/ui/qt/extcap_argument.h
index c83111a2d3..2d605d2881 100644
--- a/ui/qt/extcap_argument.h
+++ b/ui/qt/extcap_argument.h
@@ -98,6 +98,9 @@ public:
bool isValid();
bool isRequired();
+ QString prefKey();
+ virtual QString prefValue();
+
static ExtcapArgument * create(extcap_arg * argument = 0);
Q_SIGNALS:
@@ -189,6 +192,7 @@ public:
virtual QString value();
virtual bool isValid();
virtual QString defaultValue();
+ virtual QString prefValue();
private:
diff --git a/ui/qt/extcap_options_dialog.cpp b/ui/qt/extcap_options_dialog.cpp
index f36d4afbd8..ed7a0150e4 100644
--- a/ui/qt/extcap_options_dialog.cpp
+++ b/ui/qt/extcap_options_dialog.cpp
@@ -54,6 +54,11 @@
#include "qt_ui_utils.h"
+#include <epan/prefs.h>
+#include <ui/preference_utils.h>
+
+#include <ui/qt/wireshark_application.h>
+
#include <ui/qt/extcap_argument.h>
#include <ui/qt/extcap_argument_file.h>
#include <ui/qt/extcap_argument_multiselect.h>
@@ -68,6 +73,7 @@ ExtcapOptionsDialog::ExtcapOptionsDialog(QWidget *parent) :
setWindowTitle(wsApp->windowTitleString(tr("Extcap Interface Options")));
+ ui->checkSaveOnStart->setCheckState(prefs.extcap_save_on_start ? Qt::Checked : Qt::Unchecked);
ui->buttonBox->button(QDialogButtonBox::Ok)->setText(tr("Start"));
}
@@ -118,6 +124,12 @@ ExtcapOptionsDialog::~ExtcapOptionsDialog()
void ExtcapOptionsDialog::on_buttonBox_accepted()
{
if (saveOptionToCaptureInfo()) {
+ /* Starting a new capture with those values */
+ prefs.extcap_save_on_start = ui->checkSaveOnStart->checkState() == Qt::Checked;
+
+ if ( prefs.extcap_save_on_start )
+ storeValues();
+
accept();
}
}
@@ -281,7 +293,7 @@ bool ExtcapOptionsDialog::saveOptionToCaptureInfo()
device = g_array_index(global_capture_opts.all_ifaces, interface_t, device_idx);
global_capture_opts.all_ifaces = g_array_remove_index(global_capture_opts.all_ifaces, device_idx);
- ret_args = g_hash_table_new(g_str_hash, g_str_equal);
+ ret_args = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free);
ExtcapArgumentList::const_iterator iter;
@@ -301,6 +313,7 @@ bool ExtcapOptionsDialog::saveOptionToCaptureInfo()
gchar * call_string = g_strdup(call.toStdString().c_str());
gchar * value_string = g_strdup(value.toStdString().c_str());
+
g_hash_table_insert(ret_args, call_string, value_string );
}
@@ -313,6 +326,77 @@ bool ExtcapOptionsDialog::saveOptionToCaptureInfo()
return true;
}
+void ExtcapOptionsDialog::storeValues()
+{
+ GHashTable * entries = g_hash_table_new(g_str_hash, g_str_equal);
+ ExtcapArgumentList::const_iterator iter;
+
+ QString value;
+
+ /* All arguments are being iterated, to ensure, that any error handling catches all arguments */
+ for(iter = extcapArguments.constBegin(); iter != extcapArguments.constEnd(); ++iter)
+ {
+ ExtcapArgument * argument = (ExtcapArgument *)(*iter);
+
+ /* The dynamic casts are necessary, because we come here using the Signal/Slot system
+ * of Qt, and -in short- Q_OBJECT classes cannot be multiple inherited. Another possibility
+ * would be to use Q_INTERFACE, but this causes way more nightmares, and we really just
+ * need here an explicit cast for the check functionality */
+ if ( dynamic_cast<ExtArgBool *>((*iter)) != NULL)
+ {
+ value = ((ExtArgBool *)*iter)->prefValue();
+ }
+ else if ( dynamic_cast<ExtArgRadio *>((*iter)) != NULL)
+ {
+ value = ((ExtArgRadio *)*iter)->prefValue();
+ }
+ else if ( dynamic_cast<ExtArgSelector *>((*iter)) != NULL)
+ {
+ value = ((ExtArgSelector *)*iter)->prefValue();
+ }
+ else if ( dynamic_cast<ExtArgMultiSelect *>((*iter)) != NULL)
+ {
+ value = ((ExtArgMultiSelect *)*iter)->prefValue();
+ }
+ else if ( dynamic_cast<ExtcapArgumentFileSelection *>((*iter)) != NULL)
+ {
+ value = ((ExtcapArgumentFileSelection *)*iter)->prefValue();
+ }
+ else if ( dynamic_cast<ExtArgNumber *>((*iter)) != NULL)
+ {
+ value = ((ExtArgNumber *)*iter)->prefValue();
+ }
+ else if ( dynamic_cast<ExtArgText *>((*iter)) != NULL)
+ {
+ value = ((ExtArgText *)*iter)->prefValue();
+ }
+ else
+ value = (*iter)->prefValue();
+
+ QString prefKey = QString("%1.%2").arg(device_name).arg(argument->prefKey());
+ if ( prefKey.length() > 0 )
+ {
+ gchar * key = g_strdup(prefKey.toStdString().c_str());
+ gchar * val = g_strdup(value.length() == 0 ? " " : value.toStdString().c_str());
+
+ /* Setting the internally stored value for the preference to the new value */
+ (*iter)->argument()->storeval = g_strdup(val);
+
+ g_hash_table_insert(entries, key, val);
+ }
+ }
+
+ if ( g_hash_table_size(entries) > 0 )
+ {
+ if ( prefs_store_ext_multiple("extcap", entries) )
+ {
+ wsApp->emitAppSignal(WiresharkApplication::PacketDissectionChanged);
+ wsApp->emitAppSignal(WiresharkApplication::PreferencesChanged);
+ }
+ }
+}
+
+
#endif /* HAVE_LIBPCAP */
/*
diff --git a/ui/qt/extcap_options_dialog.h b/ui/qt/extcap_options_dialog.h
index eb0761df8e..3ca859ed35 100644
--- a/ui/qt/extcap_options_dialog.h
+++ b/ui/qt/extcap_options_dialog.h
@@ -70,6 +70,7 @@ private:
ExtcapArgumentList extcapArguments;
bool saveOptionToCaptureInfo();
+ void storeValues();
};
#endif /* HAVE_EXTCAP */
diff --git a/ui/qt/extcap_options_dialog.ui b/ui/qt/extcap_options_dialog.ui
index d22380aee3..edd6c96c8c 100644
--- a/ui/qt/extcap_options_dialog.ui
+++ b/ui/qt/extcap_options_dialog.ui
@@ -7,7 +7,7 @@
<x>0</x>
<y>0</y>
<width>600</width>
- <height>55</height>
+ <height>92</height>
</rect>
</property>
<property name="minimumSize">
@@ -21,6 +21,23 @@
<layout class="QVBoxLayout" name="verticalLayout"/>
</item>
<item>
+ <widget class="Line" name="line">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QCheckBox" name="checkSaveOnStart">
+ <property name="text">
+ <string>Save parameter on capture start</string>
+ </property>
+ <property name="checked">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
<widget class="QDialogButtonBox" name="buttonBox">
<property name="standardButtons">
<set>QDialogButtonBox::Close|QDialogButtonBox::Help|QDialogButtonBox::Ok</set>
diff --git a/wireshark-qt.cpp b/wireshark-qt.cpp
index bd9277f0f7..1eaff2c89a 100644
--- a/wireshark-qt.cpp
+++ b/wireshark-qt.cpp
@@ -70,6 +70,10 @@
#include <codecs/codecs.h>
#endif
+#ifdef HAVE_EXTCAP
+#include <extcap.h>
+#endif
+
/* general (not Qt specific) */
#include "file.h"
#include "epan/color_filters.h"
@@ -839,6 +843,10 @@ int main(int argc, char *argv[])
register_all_plugin_tap_listeners();
#endif
+#ifdef HAVE_EXTCAP
+ extcap_register_preferences();
+#endif
+
register_all_tap_listeners();
conversation_table_set_gui_info(init_conversation_table);
hostlist_table_set_gui_info(init_endpoint_table);