summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorArnon Gilboa <agilboa@redhat.com>2012-07-30 09:31:11 +0300
committerArnon Gilboa <agilboa@redhat.com>2012-07-30 09:31:11 +0300
commitc726333eee4ecefcdef39bef8e14262f797f80cc (patch)
tree2ea8484b5104ecb8ed1407fd9520719f06551f13
parent54da3bd0fd30978f49bc23dea8fb82ec266c68cc (diff)
usbclerk: add usbredirfilter & stdint.h
until switching to mingw build
-rw-r--r--stdint.h256
-rw-r--r--usbclerk.vcproj40
-rw-r--r--usbredirfilter.c260
-rw-r--r--usbredirfilter.h127
4 files changed, 683 insertions, 0 deletions
diff --git a/stdint.h b/stdint.h
new file mode 100644
index 0000000..00988d9
--- /dev/null
+++ b/stdint.h
@@ -0,0 +1,256 @@
+/**
+ * This file has no copyright assigned and is placed in the Public Domain.
+ * This file was originally part of the w64 mingw-runtime package.
+ */
+
+/* ISO C9x 7.18 Integer types <stdint.h>
+ * Based on ISO/IEC SC22/WG14 9899 Committee draft (SC22 N2794)
+ *
+ * THIS SOFTWARE IS NOT COPYRIGHTED
+ *
+ * Contributor: Danny Smith <danny_r_smith_2001@yahoo.co.nz>
+ * Modified for libusb/MSVC: Pete Batard <pbatard@gmail.com>
+ *
+ * This source code is offered for use in the public domain. You may
+ * use, modify or distribute it freely.
+ *
+ * This code is distributed in the hope that it will be useful but
+ * WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESS OR IMPLIED ARE HEREBY
+ * DISCLAIMED. This includes but is not limited to warranties of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * Date: 2010-04-02
+ */
+
+#ifndef _MSC_VER
+#error This header should only be used with Microsoft compilers
+#endif
+
+#ifndef _STDINT_H
+#define _STDINT_H
+
+#ifndef _INTPTR_T_DEFINED
+#define _INTPTR_T_DEFINED
+#ifndef __intptr_t_defined
+#define __intptr_t_defined
+#undef intptr_t
+#ifdef _WIN64
+ typedef __int64 intptr_t;
+#else
+ typedef int intptr_t;
+#endif /* _WIN64 */
+#endif /* __intptr_t_defined */
+#endif /* _INTPTR_T_DEFINED */
+
+#ifndef _UINTPTR_T_DEFINED
+#define _UINTPTR_T_DEFINED
+#ifndef __uintptr_t_defined
+#define __uintptr_t_defined
+#undef uintptr_t
+#ifdef _WIN64
+ typedef unsigned __int64 uintptr_t;
+#else
+ typedef unsigned int uintptr_t;
+#endif /* _WIN64 */
+#endif /* __uintptr_t_defined */
+#endif /* _UINTPTR_T_DEFINED */
+
+#ifndef _PTRDIFF_T_DEFINED
+#define _PTRDIFF_T_DEFINED
+#ifndef _PTRDIFF_T_
+#define _PTRDIFF_T_
+#undef ptrdiff_t
+#ifdef _WIN64
+ typedef __int64 ptrdiff_t;
+#else
+ typedef int ptrdiff_t;
+#endif /* _WIN64 */
+#endif /* _PTRDIFF_T_ */
+#endif /* _PTRDIFF_T_DEFINED */
+
+#ifndef _WCHAR_T_DEFINED
+#define _WCHAR_T_DEFINED
+#ifndef __cplusplus
+ typedef unsigned short wchar_t;
+#endif /* C++ */
+#endif /* _WCHAR_T_DEFINED */
+
+#ifndef _WCTYPE_T_DEFINED
+#define _WCTYPE_T_DEFINED
+#ifndef _WINT_T
+#define _WINT_T
+ typedef unsigned short wint_t;
+ typedef unsigned short wctype_t;
+#endif /* _WINT_T */
+#endif /* _WCTYPE_T_DEFINED */
+
+/* 7.18.1.1 Exact-width integer types */
+typedef __int8 int8_t;
+typedef unsigned __int8 uint8_t;
+typedef __int16 int16_t;
+typedef unsigned __int16 uint16_t;
+typedef __int32 int32_t;
+typedef unsigned __int32 uint32_t;
+typedef __int64 int64_t;
+typedef unsigned __int64 uint64_t;
+
+/* 7.18.1.2 Minimum-width integer types */
+typedef signed char int_least8_t;
+typedef unsigned char uint_least8_t;
+typedef short int_least16_t;
+typedef unsigned short uint_least16_t;
+typedef int int_least32_t;
+typedef unsigned uint_least32_t;
+typedef __int64 int_least64_t;
+typedef unsigned __int64 uint_least64_t;
+
+/* 7.18.1.3 Fastest minimum-width integer types
+ * Not actually guaranteed to be fastest for all purposes
+ * Here we use the exact-width types for 8 and 16-bit ints.
+ */
+typedef __int8 int_fast8_t;
+typedef unsigned __int8 uint_fast8_t;
+typedef __int16 int_fast16_t;
+typedef unsigned __int16 uint_fast16_t;
+typedef __int32 int_fast32_t;
+typedef unsigned __int32 uint_fast32_t;
+typedef __int64 int_fast64_t;
+typedef unsigned __int64 uint_fast64_t;
+
+/* 7.18.1.5 Greatest-width integer types */
+typedef __int64 intmax_t;
+typedef unsigned __int64 uintmax_t;
+
+/* 7.18.2 Limits of specified-width integer types */
+
+/* 7.18.2.1 Limits of exact-width integer types */
+#define INT8_MIN (-128)
+#define INT16_MIN (-32768)
+#define INT32_MIN (-2147483647 - 1)
+#define INT64_MIN (-9223372036854775807LL - 1)
+
+#define INT8_MAX 127
+#define INT16_MAX 32767
+#define INT32_MAX 2147483647
+#define INT64_MAX 9223372036854775807LL
+
+#define UINT8_MAX 255
+#define UINT16_MAX 65535
+#define UINT32_MAX 0xffffffffU /* 4294967295U */
+#define UINT64_MAX 0xffffffffffffffffULL /* 18446744073709551615ULL */
+
+/* 7.18.2.2 Limits of minimum-width integer types */
+#define INT_LEAST8_MIN INT8_MIN
+#define INT_LEAST16_MIN INT16_MIN
+#define INT_LEAST32_MIN INT32_MIN
+#define INT_LEAST64_MIN INT64_MIN
+
+#define INT_LEAST8_MAX INT8_MAX
+#define INT_LEAST16_MAX INT16_MAX
+#define INT_LEAST32_MAX INT32_MAX
+#define INT_LEAST64_MAX INT64_MAX
+
+#define UINT_LEAST8_MAX UINT8_MAX
+#define UINT_LEAST16_MAX UINT16_MAX
+#define UINT_LEAST32_MAX UINT32_MAX
+#define UINT_LEAST64_MAX UINT64_MAX
+
+/* 7.18.2.3 Limits of fastest minimum-width integer types */
+#define INT_FAST8_MIN INT8_MIN
+#define INT_FAST16_MIN INT16_MIN
+#define INT_FAST32_MIN INT32_MIN
+#define INT_FAST64_MIN INT64_MIN
+
+#define INT_FAST8_MAX INT8_MAX
+#define INT_FAST16_MAX INT16_MAX
+#define INT_FAST32_MAX INT32_MAX
+#define INT_FAST64_MAX INT64_MAX
+
+#define UINT_FAST8_MAX UINT8_MAX
+#define UINT_FAST16_MAX UINT16_MAX
+#define UINT_FAST32_MAX UINT32_MAX
+#define UINT_FAST64_MAX UINT64_MAX
+
+/* 7.18.2.4 Limits of integer types capable of holding
+ object pointers */
+#ifdef _WIN64
+#define INTPTR_MIN INT64_MIN
+#define INTPTR_MAX INT64_MAX
+#define UINTPTR_MAX UINT64_MAX
+#else
+#define INTPTR_MIN INT32_MIN
+#define INTPTR_MAX INT32_MAX
+#define UINTPTR_MAX UINT32_MAX
+#endif
+
+/* 7.18.2.5 Limits of greatest-width integer types */
+#define INTMAX_MIN INT64_MIN
+#define INTMAX_MAX INT64_MAX
+#define UINTMAX_MAX UINT64_MAX
+
+/* 7.18.3 Limits of other integer types */
+#ifdef _WIN64
+#define PTRDIFF_MIN INT64_MIN
+#define PTRDIFF_MAX INT64_MAX
+#else
+#define PTRDIFF_MIN INT32_MIN
+#define PTRDIFF_MAX INT32_MAX
+#endif
+
+#define SIG_ATOMIC_MIN INT32_MIN
+#define SIG_ATOMIC_MAX INT32_MAX
+
+#ifndef SIZE_MAX
+#ifdef _WIN64
+#define SIZE_MAX UINT64_MAX
+#else
+#define SIZE_MAX UINT32_MAX
+#endif
+#endif
+
+#ifndef WCHAR_MIN /* also in wchar.h */
+#define WCHAR_MIN 0U
+#define WCHAR_MAX 0xffffU
+#endif
+
+/*
+ * wint_t is unsigned short for compatibility with MS runtime
+ */
+#define WINT_MIN 0U
+#define WINT_MAX 0xffffU
+
+
+/* 7.18.4 Macros for integer constants */
+
+/* 7.18.4.1 Macros for minimum-width integer constants
+
+ Accoding to Douglas Gwyn <gwyn@arl.mil>:
+ "This spec was changed in ISO/IEC 9899:1999 TC1; in ISO/IEC
+ 9899:1999 as initially published, the expansion was required
+ to be an integer constant of precisely matching type, which
+ is impossible to accomplish for the shorter types on most
+ platforms, because C99 provides no standard way to designate
+ an integer constant with width less than that of type int.
+ TC1 changed this to require just an integer constant
+ *expression* with *promoted* type."
+
+ The trick used here is from Clive D W Feather.
+*/
+
+#define INT8_C(val) (INT_LEAST8_MAX-INT_LEAST8_MAX+(val))
+#define INT16_C(val) (INT_LEAST16_MAX-INT_LEAST16_MAX+(val))
+#define INT32_C(val) (INT_LEAST32_MAX-INT_LEAST32_MAX+(val))
+/* The 'trick' doesn't work in C89 for long long because, without
+ suffix, (val) will be evaluated as int, not intmax_t */
+#define INT64_C(val) val##i64
+
+#define UINT8_C(val) (val)
+#define UINT16_C(val) (val)
+#define UINT32_C(val) (val##i32)
+#define UINT64_C(val) val##ui64
+
+/* 7.18.4.2 Macros for greatest-width integer constants */
+#define INTMAX_C(val) val##i64
+#define UINTMAX_C(val) val##ui64
+
+#endif
diff --git a/usbclerk.vcproj b/usbclerk.vcproj
index b692737..dc59ad5 100644
--- a/usbclerk.vcproj
+++ b/usbclerk.vcproj
@@ -347,6 +347,10 @@
>
</File>
<File
+ RelativePath=".\usbredirfilter.h"
+ >
+ </File>
+ <File
RelativePath=".\vdlog.h"
>
</File>
@@ -371,6 +375,42 @@
>
</File>
<File
+ RelativePath=".\usbredirfilter.c"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ CompileAs="2"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ CompileAs="2"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ CompileAs="2"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ CompileAs="2"
+ />
+ </FileConfiguration>
+ </File>
+ <File
RelativePath=".\vdlog.cpp"
>
</File>
diff --git a/usbredirfilter.c b/usbredirfilter.c
new file mode 100644
index 0000000..b55b2bf
--- /dev/null
+++ b/usbredirfilter.c
@@ -0,0 +1,260 @@
+/* usbredirfilter.h usb redirection filter header
+
+ Copyright 2012 Red Hat, Inc.
+
+ Red Hat Authors:
+ Hans de Goede <hdegoede@redhat.com>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+
+#include "usbredirfilter.h"
+
+int usbredirfilter_string_to_rules(
+ const char *filter_str, const char *token_sep, const char *rule_sep,
+ struct usbredirfilter_rule **rules_ret, int *rules_count_ret)
+{
+ char *rule, *token, *ep, *buf_end, *rule_end;
+ struct usbredirfilter_rule *rules = NULL;
+ int i, rules_count, *values, ret = 0;
+ char *buf = NULL;
+ const char *r;
+
+ *rules_ret = NULL;
+ *rules_count_ret = 0;
+
+ /* Figure out how much rules there are in the file, so we know how
+ much memory we must allocate for the rules array.
+ Note this will come up with a slightly too large number if there are
+ empty rule strings in the set. */
+ r = filter_str;
+ rules_count = 0;
+ while (r) {
+ r = strchr(r, rule_sep[0]);
+ if (r)
+ r++;
+ rules_count++;
+ }
+
+ rules = (struct usbredirfilter_rule *)calloc(rules_count, sizeof(struct usbredirfilter_rule));
+ if (!rules)
+ return -ENOMEM;
+
+ /* Make a copy since strtok mangles the string */
+ buf = strdup(filter_str);
+ if (!buf) {
+ ret = -ENOMEM;
+ goto leave;
+ }
+
+ /* And actually parse the string */
+ buf_end = buf + strlen(buf);
+ rules_count = 0;
+ rule = strtok(buf, rule_sep);
+ while (rule) {
+ rule_end = rule + strlen(rule);
+ /* We treat the filter rule as an array of ints for easier parsing */
+ values = (int *)&rules[rules_count];
+ token = strtok(rule, token_sep);
+ for (i = 0; i < 5 && token; i++) {
+ values[i] = strtol(token, &ep, 0);
+ if (*ep)
+ break;
+ token = strtok(NULL, token_sep);
+ }
+ if (i != 5 || token != NULL ||
+ usbredirfilter_verify(&rules[rules_count], 1)) {
+ ret = -EINVAL;
+ goto leave;
+ }
+ rules_count++;
+ if (rule_end < buf_end) {
+ rule = strtok(rule_end + 1, rule_sep);
+ } else {
+ rule = NULL;
+ }
+ }
+
+ *rules_ret = rules;
+ *rules_count_ret = rules_count;
+
+leave:
+ if (ret)
+ free(rules);
+ free(buf);
+ return ret;
+}
+
+char *usbredirfilter_rules_to_string(const struct usbredirfilter_rule *rules,
+ int rules_count, const char *token_sep, const char *rule_sep)
+{
+ int i;
+ char *str, *p;
+
+ if (usbredirfilter_verify(rules, rules_count))
+ return NULL;
+
+ /* We need 28 bytes per rule in the worst case */
+ str = (char *)malloc(28 * rules_count + 1);
+ if (!str)
+ return NULL;
+
+ p = str;
+ for (i = 0; i < rules_count; i++) {
+ if (rules[i].device_class != -1)
+ p += sprintf(p, "0x%02x%c", rules[i].device_class, *token_sep);
+ else
+ p += sprintf(p, "-1%c", *token_sep);
+
+ if (rules[i].vendor_id != -1)
+ p += sprintf(p, "0x%04x%c", rules[i].vendor_id, *token_sep);
+ else
+ p += sprintf(p, "-1%c", *token_sep);
+
+ if (rules[i].product_id != -1)
+ p += sprintf(p, "0x%04x%c", rules[i].product_id, *token_sep);
+ else
+ p += sprintf(p, "-1%c", *token_sep);
+
+ if (rules[i].device_version_bcd != -1)
+ p += sprintf(p, "0x%04x%c", rules[i].device_version_bcd, *token_sep);
+ else
+ p += sprintf(p, "-1%c", *token_sep);
+
+ p += sprintf(p, "%d%c", rules[i].allow ? 1:0, *rule_sep);
+ }
+
+ return str;
+}
+
+static int usbredirfilter_check1(const struct usbredirfilter_rule *rules,
+ int rules_count, uint8_t device_class, uint16_t vendor_id,
+ uint16_t product_id, uint16_t device_version_bcd, int default_allow)
+{
+ int i;
+
+ for (i = 0; i < rules_count; i++) {
+ if ((rules[i].device_class == -1 ||
+ rules[i].device_class == device_class) &&
+ (rules[i].vendor_id == -1 ||
+ rules[i].vendor_id == vendor_id) &&
+ (rules[i].product_id == -1 ||
+ rules[i].product_id == product_id) &&
+ (rules[i].device_version_bcd == -1 ||
+ rules[i].device_version_bcd == device_version_bcd)) {
+ /* Found a match ! */
+ return rules[i].allow ? 0 : -EPERM;
+ }
+ }
+
+ return default_allow ? 0 : -EPERM;
+}
+
+int usbredirfilter_check(
+ const struct usbredirfilter_rule *rules, int rules_count,
+ uint8_t device_class, uint8_t device_subclass, uint8_t device_protocol,
+ uint8_t *interface_class, uint8_t *interface_subclass,
+ uint8_t *interface_protocol, int interface_count,
+ uint16_t vendor_id, uint16_t product_id, uint16_t device_version_bcd,
+ int flags)
+{
+ int i, rc;
+
+ if (usbredirfilter_verify(rules, rules_count))
+ return -EINVAL;
+
+ /* Check the device_class */
+ if (device_class != 0x00 && device_class != 0xef) {
+ rc = usbredirfilter_check1(rules, rules_count, device_class,
+ vendor_id, product_id, device_version_bcd,
+ flags & usbredirfilter_fl_default_allow);
+ if (rc)
+ return rc;
+ }
+
+ /* Check the interface classes */
+ for (i = 0; i < interface_count; i++) {
+ if (!(flags & usbredirfilter_fl_dont_skip_non_boot_hid) &&
+ interface_count > 1 && interface_class[i] == 0x03 &&
+ interface_subclass[i] == 0x00 && interface_protocol[i] == 0x00)
+ continue;
+
+ rc = usbredirfilter_check1(rules, rules_count, interface_class[i],
+ vendor_id, product_id, device_version_bcd,
+ flags & usbredirfilter_fl_default_allow);
+ if (rc)
+ return rc;
+ }
+
+ return 0;
+}
+
+int usbredirfilter_verify(
+ const struct usbredirfilter_rule *rules, int rules_count)
+{
+ int i;
+
+ for (i = 0; i < rules_count; i++) {
+ if (rules[i].device_class < -1 || rules[i].device_class > 255)
+ return -EINVAL;
+ if (rules[i].vendor_id < -1 || rules[i].vendor_id > 65535)
+ return -EINVAL;
+ if (rules[i].product_id < -1 || rules[i].product_id > 65535)
+ return -EINVAL;
+ if (rules[i].device_version_bcd < -1 ||
+ rules[i].device_version_bcd > 65535)
+ return -EINVAL;
+ }
+ return 0;
+}
+
+void usbredirfilter_print(
+ const struct usbredirfilter_rule *rules, int rules_count, FILE *out)
+{
+ int i;
+ char device_class[16], vendor[16], product[16], version[16];
+
+ for (i = 0; i < rules_count; i++) {
+ if (rules[i].device_class != -1)
+ sprintf(device_class, " %02x", rules[i].device_class);
+ else
+ strcpy(device_class, "ANY");
+
+ if (rules[i].vendor_id != -1)
+ sprintf(vendor, "%04x", rules[i].vendor_id);
+ else
+ strcpy(vendor, " ANY");
+
+ if (rules[i].product_id != -1)
+ sprintf(product, "%04x", rules[i].product_id);
+ else
+ strcpy(product, " ANY");
+
+ if (rules[i].device_version_bcd != -1)
+ sprintf(version, "%2d.%02d",
+ ((rules[i].device_version_bcd & 0xf000) >> 12) * 10 +
+ ((rules[i].device_version_bcd & 0x0f00) >> 8),
+ ((rules[i].device_version_bcd & 0x00f0) >> 4) * 10 +
+ ((rules[i].device_version_bcd & 0x000f)));
+ else
+ strcpy(version, " ANY");
+
+ fprintf(out, "Class %s ID %s:%s Version %s %s\n", device_class, vendor,
+ product, version, rules[i].allow ? "Allow":"Block");
+ }
+}
diff --git a/usbredirfilter.h b/usbredirfilter.h
new file mode 100644
index 0000000..9574d56
--- /dev/null
+++ b/usbredirfilter.h
@@ -0,0 +1,127 @@
+/* usbredirfilter.h usb redirection filter header
+
+ Copyright 2012 Red Hat, Inc.
+
+ Red Hat Authors:
+ Hans de Goede <hdegoede@redhat.com>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, see <http://www.gnu.org/licenses/>.
+*/
+#ifndef __USBREDIRFILTER_H
+#define __USBREDIRFILTER_H
+
+#include <stdio.h>
+
+#pragma warning(disable : 4996)
+#include "stdint.h"
+
+struct usbredirfilter_rule {
+ int device_class; /* 0-255, -1 to match any class */
+ int vendor_id; /* 0-65535, -1 to match any id */
+ int product_id; /* 0-65535, -1 to match any id */
+ int device_version_bcd; /* 0-255, -1 to match any version */
+ int allow; /* 0: deny redir for this device, non 0: allow */
+};
+
+/* Read a filter string and parse it into an array of usbredirfilter_rule-s.
+
+ Where each rule has the form of:
+ <class>,<vendor>,<product>,<version>,<allow>
+ Assuming "," as the specified token_sep character.
+
+ And the rules are themselves are separated by the rule_sep character, ie:
+ <rule1>|<rule2>|<rule3>
+
+ Assuming "|" as the rule_sep character. Note that with the seperator used
+ in this example the format matches the format as written by the RHEV-M USB
+ filter editor tool.
+
+ Note that the seperators must be single character strings!
+
+ On success the rules get returned in rules_ret and rules_count_ret, the
+ returned rules array should be freed with free() when the caller is done
+ with it.
+
+ Return value: 0 on success, -ENOMEM when allocating the rules array fails,
+ or -EINVAL when there is on parsing error.
+*/
+int usbredirfilter_string_to_rules(
+ const char *filter_str, const char *token_sep, const char *rule_sep,
+ struct usbredirfilter_rule **rules_ret, int *rules_count_ret);
+
+/* Convert a set of rules back to a string suitable for passing to
+ usbredirfilter_string_to_rules(); The returned string must be free()-ed
+ by the caller when it is done with it.
+
+ Return value: The string on sucess, or NULL if the rules fail verification,
+ or when allocating the string fails.
+*/
+char *usbredirfilter_rules_to_string(const struct usbredirfilter_rule *rules,
+ int rules_count, const char *token_sep, const char *rule_sep);
+
+/* Check if redirection of a device with the passed in device info is allowed
+ by the passed set of filter rules.
+
+ Since a device has class info at both the device level and the interface
+ level, this function does multiple passes.
+
+ First the rules are checked one by one against the given device info using
+ the device class info, if a matching rule is found, the result of the check
+ is that of that rule. If the result is deny, -EPERM will be returned.
+
+ Then the same is done substituting the device class info with the class info
+ from the interfaces. If any of the interfaces class checks result in a deny,
+ then -EPERM will be returned.
+
+ Note that under certain circumstances some passes are skipped:
+ - For devices with a device class of 0x00 or 0xef, the pass which checks the
+ device class is skipped.
+ - If the usbredirfilter_fl_dont_skip_non_boot_hid flag is not passed then
+ for devices with more then 1 interface and an interface with an interface
+ class of 0x03, an interface subclass of 0x00 and an interface protocol
+ of 0x00. the check is skipped for that interface. This allows to skip ie
+ checking the interface for volume buttons one some usbaudio class devices.
+
+ If the result of all (not skipped) passes is allow, then 0 will be returned,
+ which indicates that redirection should be allowed.
+
+ If a given pass does not match any rules the result of that pass will be
+ deny. This behavior can be changed with the usbredirfilter_fl_default_allow
+ flag, if this flas is set the result on no matching rules will be allow.
+
+ Return value: 0 when redirection is allowed, -EINVAL for invalid parameters,
+ -EPERM when redirection is blocked by the filter rules.
+*/
+enum {
+ usbredirfilter_fl_default_allow = 0x01,
+ usbredirfilter_fl_dont_skip_non_boot_hid = 0x02,
+};
+int usbredirfilter_check(
+ const struct usbredirfilter_rule *rules, int rules_count,
+ uint8_t device_class, uint8_t device_subclass, uint8_t device_protocol,
+ uint8_t *interface_class, uint8_t *interface_subclass,
+ uint8_t *interface_protocol, int interface_count,
+ uint16_t vendor_id, uint16_t product_id, uint16_t device_version_bcd,
+ int flags);
+
+/* Sanity check the passed in rules
+
+ Return value: 0 on success, -EINVAL when some values are out of bound. */
+int usbredirfilter_verify(
+ const struct usbredirfilter_rule *rules, int rules_count);
+
+/* Print the passed in rules to FILE out in human readable format */
+void usbredirfilter_print(
+ const struct usbredirfilter_rule *rules, int rules_count, FILE *out);
+#endif