[Spice-devel] [PATCH v3] usbredirserver: add support for bind specific address

Chen Hanxiao chen_han_xiao at 126.com
Fri Nov 17 15:44:19 UTC 2017


From: Chen Hanxiao <chenhanxiao at gmail.com>

We bind our listen address to in6addr_any, which may be
unsecure with multi network cards that belong to
internal or external networks.

This patch introduces option -4 and -6 to bind a specific
address.

Reviewed-by: Marc-André Lureau <marcandre.lureau at redhat.com>
Signed-off-by: Chen Hanxiao <chenhanxiao at gmail.com>
---
v3:
  use union for ipv4 ipv6 sockaddr

v2:
  replace strerror with perror
  fix some copy-paste errors

 usbredirserver/usbredirserver.1 |  3 ++-
 usbredirserver/usbredirserver.c | 59 ++++++++++++++++++++++++++++++++++-------
 2 files changed, 51 insertions(+), 11 deletions(-)

diff --git a/usbredirserver/usbredirserver.1 b/usbredirserver/usbredirserver.1
index e857190..8bbce07 100644
--- a/usbredirserver/usbredirserver.1
+++ b/usbredirserver/usbredirserver.1
@@ -3,7 +3,8 @@
 usbredirserver \- exporting an USB device for use from another (virtual) machine
 .SH SYNOPSIS
 .B usbredirserver
-[\fI-p|--port <port>\fR] [\fI-v|--verbose <0-5>\fR] \fI<busnum-devnum|vendorid:prodid>\fR
+[\fI-p|--port <port>\fR] [\fI-v|--verbose <0-5>\fR] [\fI-4 <ipv4_addr|I-6 <ipv6_addr>]
+\fI<busnum-devnum|vendorid:prodid>\fR
 .SH DESCRIPTION
 usbredirserver is a small standalone server for exporting an USB device for
 use from another (virtual) machine through the usbredir protocol.
diff --git a/usbredirserver/usbredirserver.c b/usbredirserver/usbredirserver.c
index 13965dc..c6aa654 100644
--- a/usbredirserver/usbredirserver.c
+++ b/usbredirserver/usbredirserver.c
@@ -36,6 +36,7 @@
 #include <sys/time.h>
 #include <netdb.h>
 #include <netinet/in.h>
+#include <arpa/inet.h>
 #include "usbredirhost.h"
 
 
@@ -49,6 +50,8 @@ static struct usbredirhost *host;
 static const struct option longopts[] = {
     { "port", required_argument, NULL, 'p' },
     { "verbose", required_argument, NULL, 'v' },
+    { "ipv4", required_argument, NULL, '4' },
+    { "ipv6", required_argument, NULL, '6' },
     { "help", no_argument, NULL, 'h' },
     { NULL, 0, NULL, 0 }
 };
@@ -93,7 +96,9 @@ static int usbredirserver_write(void *priv, uint8_t *data, int count)
 static void usage(int exit_code, char *argv0)
 {
     fprintf(exit_code? stderr:stdout,
-        "Usage: %s [-p|--port <port>] [-v|--verbose <0-5>] <busnum-devnum|vendorid:prodid>\n",
+        "Usage: %s [-p|--port <port>] [-v|--verbose <0-5>] "
+        "[[-4|--ipv4 ipaddr]|[-6|--ipv6 ipaddr]] "
+        "<busnum-devnum|vendorid:prodid>\n",
         argv0);
     exit(exit_code);
 }
@@ -198,11 +203,15 @@ int main(int argc, char *argv[])
     int usbvendor  = -1;
     int usbproduct = -1;
     int on = 1;
-    struct sockaddr_in6 serveraddr;
+    char *ipv4_addr = NULL, *ipv6_addr = NULL;
+    union {
+        struct sockaddr_in v4;
+        struct sockaddr_in6 v6;
+    } serveraddr;
     struct sigaction act;
     libusb_device_handle *handle = NULL;
 
-    while ((o = getopt_long(argc, argv, "hp:v:", longopts, NULL)) != -1) {
+    while ((o = getopt_long(argc, argv, "hp:v:4:6:", longopts, NULL)) != -1) {
         switch (o) {
         case 'p':
             port = strtol(optarg, &endptr, 10);
@@ -218,6 +227,12 @@ int main(int argc, char *argv[])
                 usage(1, argv[0]);
             }
             break;
+        case '4':
+            ipv4_addr = optarg;
+            break;
+        case '6':
+            ipv6_addr = optarg;
+            break;
         case '?':
         case 'h':
             usage(o == '?', argv[0]);
@@ -272,9 +287,13 @@ int main(int argc, char *argv[])
 
     libusb_set_debug(ctx, verbose);
 
-    server_fd = socket(AF_INET6, SOCK_STREAM, 0);
+    if (ipv4_addr) {
+        server_fd = socket(AF_INET, SOCK_STREAM, 0);
+    } else {
+        server_fd = socket(AF_INET6, SOCK_STREAM, 0);
+    }
     if (server_fd == -1) {
-        perror("Error creating ipv6 socket");
+        perror("Error creating ip socket");
         exit(1);
     }
 
@@ -284,12 +303,32 @@ int main(int argc, char *argv[])
     }
 
     memset(&serveraddr, 0, sizeof(serveraddr));
-    serveraddr.sin6_family = AF_INET6;
-    serveraddr.sin6_port   = htons(port);
-    serveraddr.sin6_addr   = in6addr_any;
 
-    if (bind(server_fd, (struct sockaddr *)&serveraddr, sizeof(serveraddr))) {
-        fprintf(stderr, "Error binding port %d: %s\n", port, strerror(errno));
+    if (ipv4_addr) {
+        serveraddr.v4.sin_family = AF_INET;
+        serveraddr.v4.sin_port   = htons(port);
+        if ((inet_pton(AF_INET, ipv4_addr,
+                       &serveraddr.v4.sin_addr)) != 1) {
+            perror("Error convert ipv4 address");
+            exit(1);
+        }
+    } else {
+        serveraddr.v6.sin6_family = AF_INET6;
+        serveraddr.v6.sin6_port   = htons(port);
+        if (ipv6_addr) {
+            if ((inet_pton(AF_INET6, ipv6_addr,
+                           &serveraddr.v6.sin6_addr)) != 1) {
+                perror("Error convert ipv6 address");
+                exit(1);
+            }
+        } else {
+            serveraddr.v6.sin6_addr   = in6addr_any;
+        }
+    }
+
+    if (bind(server_fd, (struct sockaddr *)&serveraddr,
+             sizeof(serveraddr))) {
+        perror("Error bind");
         exit(1);
     }
 
-- 
2.13.6



More information about the Spice-devel mailing list