diff options
author | Roland Knall <roland.knall@br-automation.com> | 2015-12-29 07:57:36 +0100 |
---|---|---|
committer | Roland Knall <rknall@gmail.com> | 2016-02-01 12:12:41 +0000 |
commit | 927ffaa794d5fb24e0b4f3fba08c4c31f4dd7d63 (patch) | |
tree | 70676d0b7e00e0b10678d0f7f3ff7dd707eabcd2 | |
parent | 5e89f9332228015c3e5c813939bf35dbcc5a105d (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.extcap | 3 | ||||
-rwxr-xr-x | doc/extcap_example.py | 5 | ||||
-rw-r--r-- | epan/prefs.c | 22 | ||||
-rw-r--r-- | epan/prefs.h | 3 | ||||
-rw-r--r-- | extcap.c | 146 | ||||
-rw-r--r-- | extcap.h | 4 | ||||
-rw-r--r-- | extcap_parser.c | 6 | ||||
-rw-r--r-- | extcap_parser.h | 4 | ||||
-rw-r--r-- | ui/gtk/main.c | 8 | ||||
-rw-r--r-- | ui/qt/extcap_argument.cpp | 59 | ||||
-rw-r--r-- | ui/qt/extcap_argument.h | 4 | ||||
-rw-r--r-- | ui/qt/extcap_options_dialog.cpp | 86 | ||||
-rw-r--r-- | ui/qt/extcap_options_dialog.h | 1 | ||||
-rw-r--r-- | ui/qt/extcap_options_dialog.ui | 19 | ||||
-rw-r--r-- | wireshark-qt.cpp | 8 |
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; @@ -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 @@ -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); |