[Spice-devel] [PATCH 4/5] Add a connectkernel utility to support the usbredir kernel module.
Jeremy White
jwhite at codeweavers.com
Tue Jun 30 13:57:41 PDT 2015
This utility will connect to a remote system running usbredirserver,
and then write the socket to the sysfs attach point of usbredir,
thereby injecting the remote device into the local kernel.
Signed-off-by: Jeremy White <jwhite at codeweavers.com>
---
Makefile.am | 2 +-
configure.ac | 1 +
connectkernel/.gitignore | 3 +
connectkernel/Makefile.am | 5 ++
connectkernel/connectkernel.1 | 33 +++++++++++
connectkernel/connectkernel.c | 126 ++++++++++++++++++++++++++++++++++++++++++
6 files changed, 169 insertions(+), 1 deletion(-)
create mode 100644 connectkernel/.gitignore
create mode 100644 connectkernel/Makefile.am
create mode 100644 connectkernel/connectkernel.1
create mode 100644 connectkernel/connectkernel.c
diff --git a/Makefile.am b/Makefile.am
index f69a859..03ef2d0 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -1,6 +1,6 @@
SUBDIRS = usbredirparser usbredirhost
if ! OS_WIN32
-SUBDIRS += usbredirserver usbredirtestclient
+SUBDIRS += usbredirserver connectkernel usbredirtestclient
endif
EXTRA_DIST = README.multi-thread usb-redirection-protocol.txt
diff --git a/configure.ac b/configure.ac
index 25c9a5b..b3d6598 100644
--- a/configure.ac
+++ b/configure.ac
@@ -64,6 +64,7 @@ usbredirhost/libusbredirhost.pc
usbredirparser/Makefile
usbredirparser/libusbredirparser-0.5.pc
usbredirserver/Makefile
+connectkernel/Makefile
usbredirtestclient/Makefile
])
AC_OUTPUT
diff --git a/connectkernel/.gitignore b/connectkernel/.gitignore
new file mode 100644
index 0000000..f6c7921
--- /dev/null
+++ b/connectkernel/.gitignore
@@ -0,0 +1,3 @@
+Makefile
+Makefile.in
+connectkernel
diff --git a/connectkernel/Makefile.am b/connectkernel/Makefile.am
new file mode 100644
index 0000000..72b2a86
--- /dev/null
+++ b/connectkernel/Makefile.am
@@ -0,0 +1,5 @@
+sbin_PROGRAMS = connectkernel
+
+connectkernel_SOURCES = connectkernel.c
+
+dist_man_MANS = connectkernel.1
diff --git a/connectkernel/connectkernel.1 b/connectkernel/connectkernel.1
new file mode 100644
index 0000000..90883a8
--- /dev/null
+++ b/connectkernel/connectkernel.1
@@ -0,0 +1,33 @@
+.TH CONNECTKERNEL "1" "July 2015" "connectkernel" "User Commands"
+.SH NAME
+connectkernel\- registering an exported USB device with a kernel running usbredir
+.SH SYNOPSIS
+.B connectkernel
+devid server port [\fI--attach <sysfs_file>\fR]
+.SH DESCRIPTION
+connectkernel is a small standalone utility which will connect to a
+remote usbredirserver and give the connection handle to the linux
+kernel, thereby importing the remote device into the running linux kernel.
+.PP
+You need to specify a unique identifier for the remote device, and a
+server and port where the device can be found.
+.PP
+Notice that an invocation of connectkernel can only be used to export a
+single USB device. If you want to connect multiple devices you will need
+to invoke it once for each remote device.
+.SH OPTIONS
+.TP
+\fB\-\-attach\fR \fIFILE\fR
+Set the file to write socket and devid to \fIFILE\fR. The default
+is /sys/bus/platform/drivers/usbredir/attach.
+.SH AUTHOR
+Written by Jeremy White <jwhite at codeweavers.com>
+.SH REPORTING BUGS
+Report bugs to the spice-devel mailinglist:
+http://lists.freedesktop.org/mailman/listinfo/spice-devel
+.SH COPYRIGHT
+Copyright 2015 CodeWeavers, Inc.
+License GPLv2+: GNU GPL version 2 or later <http://gnu.org/licenses/gpl.html>.
+.br
+This is free software: you are free to change and redistribute it.
+There is NO WARRANTY, to the extent permitted by law.
diff --git a/connectkernel/connectkernel.c b/connectkernel/connectkernel.c
new file mode 100644
index 0000000..607ece0
--- /dev/null
+++ b/connectkernel/connectkernel.c
@@ -0,0 +1,126 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <netdb.h>
+#include <unistd.h>
+
+void usage(const char *argv0)
+{
+ fprintf(stderr, "%s: Connect a remote USB device to the usbredir kernel module.\n", argv0);
+ fprintf(stderr, "Usage:\n");
+ fprintf(stderr, " %s devid server port [--attach attach]\n", argv0);
+ fprintf(stderr, "where devid is a unique identifier for this connection, server:port\n");
+ fprintf(stderr, "is the address of a TCP server that is listening, waiting to export a USBREDIR device.\n");
+ fprintf(stderr, "Generally, you invoke %s to connect to a usbredirserver process.\n", argv0);
+}
+
+
+int main(int argc, char *argv[])
+{
+ struct addrinfo hints, *res, *rp;
+ int rc;
+ int s;
+ int fd;
+ int i;
+ char buf[256 + 8];
+ char *attach_file = "/sys/bus/platform/drivers/usbredir/attach";
+ char *devid = NULL;
+ char *server = NULL;
+ char *port = NULL;
+
+
+ /* Poor man's argument parsing */
+ for (i = 1; i < argc; i++)
+ {
+ if (strcmp(argv[i], "--attach") == 0)
+ {
+ if (i == (argc - 1))
+ {
+ fprintf(stderr, "Error: you must supply a path to the sysfs attach file.\n");
+ exit(1);
+ }
+ i++;
+ attach_file = argv[i];
+ break;
+ }
+ else if (!devid)
+ devid = argv[i];
+ else if (!server)
+ server = argv[i];
+ else if (!port)
+ port = argv[i];
+ else
+ {
+ fprintf(stderr, "Error: too many arguments.\n");
+ usage(argv[0]);
+ exit(1);
+ }
+ }
+
+ if (!devid || !server || !port)
+ {
+ fprintf(stderr, "Error: specify device id, server and port\n");
+ usage(argv[0]);
+ exit(1);
+ }
+
+ memset(&hints, 0, sizeof(hints));
+ hints.ai_family = AF_INET;
+ hints.ai_socktype = SOCK_STREAM;
+ hints.ai_flags = AI_NUMERICSERV;
+
+ /* get all possible addresses */
+ rc = getaddrinfo(server, port, &hints, &res);
+ if (rc < 0)
+ {
+
+ fprintf(stderr, "Error resolving %s:%s\n", server, port);
+ exit(1);
+ }
+
+ for (rp = res; rp; rp = rp->ai_next)
+ {
+ s = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol);
+ if (s < 0)
+ {
+ perror("socket");
+ exit(2);
+ }
+
+ rc = connect(s, rp->ai_addr, rp->ai_addrlen);
+ if (rc == 0)
+ break;
+
+ }
+
+ if (! rp)
+ {
+ fprintf(stderr, "Error: unable to connect.\n");
+ exit(3);
+ }
+
+ freeaddrinfo(res);
+
+ fd = open(attach_file, O_WRONLY);
+ if (fd == -1)
+ {
+ fprintf(stderr, "Could not write to %s\n", attach_file);
+ exit(1);
+ }
+
+ snprintf(buf, sizeof(buf), "%d %s", s, devid);
+ if (write(fd, buf, strlen(buf)) < 0)
+ {
+ fprintf(stderr, "Attach of '%s' to kernel failed\n", buf);
+ exit(1);
+ }
+ close(fd);
+
+ sleep(1);
+
+ return 0;
+}
--
2.1.4
More information about the Spice-devel
mailing list