aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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);