diff options
-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); |