diff options
author | Michael Mann <mmann78@netscape.net> | 2017-05-26 07:52:17 -0400 |
---|---|---|
committer | Roland Knall <rknall@gmail.com> | 2017-05-30 18:10:03 +0000 |
commit | 6c44f2017c891e15045fca5c5cff79acd48ad4e5 (patch) | |
tree | e7270e94624e201819100fc67865cc938c608023 | |
parent | 44327d8a6c7a312642adcec775555ab8a3430787 (diff) | |
download | wireshark-6c44f2017c891e15045fca5c5cff79acd48ad4e5.tar.gz |
Qt: Add support to verify extcap capture filter
Bug: 11668
Change-Id: Ib218d87c1905e53ffdab4e3dd6f93ba2c3d07c8b
Reviewed-on: https://code.wireshark.org/review/21770
Petri-Dish: Stig Bjørlykke <stig@bjorlykke.org>
Tested-by: Petri Dish Buildbot <buildbot-no-reply@wireshark.org>
Reviewed-by: Michael Mann <mmann78@netscape.net>
Reviewed-by: Roland Knall <rknall@gmail.com>
-rwxr-xr-x | doc/extcap_example.py | 7 | ||||
-rw-r--r-- | extcap.c | 49 | ||||
-rw-r--r-- | extcap.h | 16 | ||||
-rw-r--r-- | ui/qt/capture_filter_syntax_worker.cpp | 39 |
4 files changed, 105 insertions, 6 deletions
diff --git a/doc/extcap_example.py b/doc/extcap_example.py index 27b9538479..e984b374aa 100755 --- a/doc/extcap_example.py +++ b/doc/extcap_example.py @@ -177,6 +177,10 @@ def extcap_dlts(interface): elif ( interface == '2' ): print ("dlt {number=148}{name=USER1}{display=Demo Implementation for Extcap}") +def validate_capture_filter(capture_filter): + if capture_filter != "filter" and capture_filter != "valid": + print("Illegal capture filter") + """ ### FAKE DATA GENERATOR @@ -446,6 +450,9 @@ if __name__ == '__main__': if ( args.extcap_interfaces == False and args.extcap_interface == None ): parser.exit("An interface must be provided or the selection must be displayed") + if ( args.extcap_capture_filter and not args.capture ): + validate_capture_filter(args.extcap_capture_filter) + sys.exit(0) if ( args.extcap_interfaces == True or args.extcap_interface == None ): extcap_interfaces() @@ -893,6 +893,55 @@ extcap_has_configuration(const char *ifname, gboolean is_required) return found; } +static gboolean cb_verify_filter(extcap_callback_info_t cb_info) +{ + extcap_filter_status *status = (extcap_filter_status *)cb_info.data; + size_t output_size, i; + + output_size = strlen(cb_info.output); + if (output_size == 0) { + *status = EXTCAP_FILTER_VALID; + } else { + *status = EXTCAP_FILTER_INVALID; + for (i = 0; i < output_size; i++) { + if (cb_info.output[i] == '\n' || cb_info.output[i] == '\r') { + cb_info.output[i] = '\0'; + break; + } + } + *cb_info.err_str = g_strdup(cb_info.output); + } + + return TRUE; +} + +extcap_filter_status +extcap_verify_capture_filter(const char *ifname, const char *filter, gchar **err_str) +{ + gchar *argv[4]; + extcap_filter_status status = EXTCAP_FILTER_UNKNOWN; + + if (extcap_if_exists(ifname)) + { + g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "Extcap path %s", + get_extcap_dir()); + + argv[0] = EXTCAP_ARGUMENT_CAPTURE_FILTER; + argv[1] = (gchar*)filter; + argv[2] = EXTCAP_ARGUMENT_INTERFACE; + argv[3] = (gchar*)ifname; + + extcap_callback_info_t cb_info; + cb_info.data = &status; + cb_info.err_str = err_str; + cb_info.ifname = ifname; + + extcap_foreach(4, argv, cb_verify_filter, cb_info); + } + + return status; +} + gboolean extcap_has_toolbar(const char *ifname) { @@ -62,6 +62,12 @@ typedef struct _extcap_info { GList * interfaces; } extcap_info; +typedef enum { + EXTCAP_FILTER_UNKNOWN, + EXTCAP_FILTER_VALID, + EXTCAP_FILTER_INVALID +} extcap_filter_status; + struct _extcap_arg; #ifdef __cplusplus @@ -108,6 +114,16 @@ GList * extcap_get_if_configuration(const char * ifname); /** + * Check if the capture filter for the given interface name is valid. + * @param ifname Interface to check + * @param filter Capture filter to check + * @param err_str Error string returned if filter is invalid + * @return Filter check status. + */ +extcap_filter_status +extcap_verify_capture_filter(const char *ifname, const char *filter, gchar **err_str); + +/** * Frees the memory from extcap_get_if_configuration. * @param list The list returned by extcap_get_if_configuration. * @param free_args TRUE if all arguments in the list must be freed too or FALSE diff --git a/ui/qt/capture_filter_syntax_worker.cpp b/ui/qt/capture_filter_syntax_worker.cpp index 83f9b13375..0a0733aff5 100644 --- a/ui/qt/capture_filter_syntax_worker.cpp +++ b/ui/qt/capture_filter_syntax_worker.cpp @@ -29,6 +29,9 @@ #include "capture_opts.h" #include "ui/capture_globals.h" #endif +#ifdef HAVE_EXTCAP +#include "extcap.h" +#endif #include "capture_filter_syntax_worker.h" #include "syntax_line_edit.h" @@ -60,6 +63,9 @@ void CaptureFilterSyntaxWorker::start() { forever { QString filter; QSet<gint> active_dlts; +#ifdef HAVE_EXTCAP + QSet<guint> active_extcap; +#endif struct bpf_program fcode; pcap_t *pd; int pc_err; @@ -88,8 +94,7 @@ void CaptureFilterSyntaxWorker::start() { device = g_array_index(global_capture_opts.all_ifaces, interface_t, if_idx); if (!device.locked && device.selected) { #ifdef HAVE_EXTCAP - if (device.if_info.extcap == NULL || strlen(device.if_info.extcap) == 0) - { + if (device.if_info.extcap == NULL || strlen(device.if_info.extcap) == 0) { #endif if (device.active_dlt >= DLT_USER0 && device.active_dlt <= DLT_USER15) { // Capture filter for DLT_USER is unknown @@ -99,10 +104,8 @@ void CaptureFilterSyntaxWorker::start() { active_dlts.insert(device.active_dlt); } #ifdef HAVE_EXTCAP - } - else - { - //TODO: Verify extcap capture file (bug 11668) + } else { + active_extcap.insert(if_idx); } #endif } @@ -139,6 +142,30 @@ void CaptureFilterSyntaxWorker::start() { if (state == SyntaxLineEdit::Invalid) break; } +#ifdef HAVE_EXTCAP + // If it's already invalid, don't bother to check extcap + if (state != SyntaxLineEdit::Invalid) { + foreach (guint extcapif, active_extcap.toList()) { + interface_t device; + gchar *error = NULL; + + device = g_array_index(global_capture_opts.all_ifaces, interface_t, extcapif); + extcap_filter_status status = extcap_verify_capture_filter(device.name, filter.toUtf8().constData(), &error); + if (status == EXTCAP_FILTER_VALID) { + DEBUG_SYNTAX_CHECK("unknown", "known good"); + } else if (status == EXTCAP_FILTER_INVALID) { + DEBUG_SYNTAX_CHECK("unknown", "known bad"); + state = SyntaxLineEdit::Invalid; + err_str = error; + break; + } else { + state = SyntaxLineEdit::Deprecated; + err_str = "Unable to check capture filter"; + } + g_free (error); + } + } +#endif emit syntaxResult(filter, state, err_str); DEBUG_SYNTAX_CHECK("known", "idle"); |