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@xxxxxxxxxxxxxxx> --- 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@xxxxxxxxxxxxxxx> +.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 _______________________________________________ Spice-devel mailing list Spice-devel@xxxxxxxxxxxxxxxxxxxxx http://lists.freedesktop.org/mailman/listinfo/spice-devel