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>
This commit is contained in:
Michael Mann 2017-05-26 07:52:17 -04:00 committed by Roland Knall
parent 44327d8a6c
commit 6c44f2017c
4 changed files with 105 additions and 6 deletions

View File

@ -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()

View File

@ -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)
{

View File

@ -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
@ -107,6 +113,16 @@ extcap_clear_interfaces(void);
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.

View File

@ -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");