1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147
|
From 8985b45e1fe1a5d50c5e1dc4c7c306705e602445 Mon Sep 17 00:00:00 2001
From: "A. Maitland Bottoms" <bottoms@debian.org>
Date: Sun, 3 Sep 2017 16:22:55 -0400
Subject: [PATCH 18/33] rtl_tcp: Add IPv6 support
I've prepared this patch in response to Debian bug #870804
https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=870804
It passes the text from the -a and -p options through
getaddrinfo() and uses the first result that has a valid
socket with a successful bind.
While not a complete bind to all possible valid names, it
does appear to address the use case of the bug submitter
without completely changing the program flow.
---
src/rtl_tcp.c | 72 +++++++++++++++++++++++++++++++++++++++------------
1 file changed, 55 insertions(+), 17 deletions(-)
diff --git a/src/rtl_tcp.c b/src/rtl_tcp.c
index da6057b..42b90cb 100644
--- a/src/rtl_tcp.c
+++ b/src/rtl_tcp.c
@@ -30,6 +30,7 @@
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/time.h>
+#include <netdb.h>
#include <netinet/in.h>
#include <fcntl.h>
#else
@@ -371,10 +372,18 @@ static void *command_worker(void *arg)
int main(int argc, char **argv)
{
int r, opt, i;
- char* addr = "127.0.0.1";
- int port = 1234;
+ char *addr = "127.0.0.1";
+ char *port = "1234";
uint32_t frequency = 100000000, samp_rate = 2048000;
- struct sockaddr_in local, remote;
+ struct sockaddr_storage local, remote;
+ struct addrinfo *ai;
+ struct addrinfo *aiHead;
+ struct addrinfo hints;
+ char hostinfo[NI_MAXHOST];
+ char portinfo[NI_MAXSERV];
+ char remhostinfo[NI_MAXHOST];
+ char remportinfo[NI_MAXSERV];
+ int aiErr;
uint32_t buf_num = 0;
int dev_index = 0;
int dev_given = 0;
@@ -413,10 +422,10 @@ int main(int argc, char **argv)
samp_rate = (uint32_t)atofs(optarg);
break;
case 'a':
- addr = optarg;
+ addr = strdup(optarg);
break;
case 'p':
- port = atoi(optarg);
+ port = strdup(optarg);
break;
case 'b':
buf_num = atoi(optarg);
@@ -515,16 +524,42 @@ int main(int argc, char **argv)
pthread_cond_init(&cond, NULL);
pthread_cond_init(&exit_cond, NULL);
- memset(&local,0,sizeof(local));
- local.sin_family = AF_INET;
- local.sin_port = htons(port);
- local.sin_addr.s_addr = inet_addr(addr);
+ hints.ai_flags = AI_PASSIVE; /* Server mode. */
+ hints.ai_family = PF_UNSPEC; /* IPv4 or IPv6. */
+ hints.ai_socktype = SOCK_STREAM;
+ hints.ai_protocol = IPPROTO_TCP;
+
+ if ((aiErr = getaddrinfo(addr,
+ port,
+ &hints,
+ &aiHead )) != 0)
+ {
+ fprintf(stderr, "local address %s ERROR - %s.\n",
+ addr, gai_strerror(aiErr));
+ return(-1);
+ }
+ memcpy(&local, aiHead->ai_addr, aiHead->ai_addrlen);
+
+ for (ai = aiHead; ai != NULL; ai = ai->ai_next) {
+ aiErr = getnameinfo((struct sockaddr *)ai->ai_addr, ai->ai_addrlen,
+ hostinfo, NI_MAXHOST,
+ portinfo, NI_MAXSERV, NI_NUMERICSERV | NI_NUMERICHOST);
+ if (aiErr)
+ fprintf( stderr, "getnameinfo ERROR - %s.\n",hostinfo);
+
+ listensocket = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
+ if (listensocket < 0)
+ continue;
+
+ r = 1;
+ setsockopt(listensocket, SOL_SOCKET, SO_REUSEADDR, (char *)&r, sizeof(int));
+ setsockopt(listensocket, SOL_SOCKET, SO_LINGER, (char *)&ling, sizeof(ling));
- listensocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
- r = 1;
- setsockopt(listensocket, SOL_SOCKET, SO_REUSEADDR, (char *)&r, sizeof(int));
- setsockopt(listensocket, SOL_SOCKET, SO_LINGER, (char *)&ling, sizeof(ling));
- bind(listensocket,(struct sockaddr *)&local,sizeof(local));
+ if (bind(listensocket, (struct sockaddr *)&local, sizeof(local)))
+ fprintf(stderr, "rtl_tcp bind error: %s", strerror(errno));
+ else
+ break;
+ }
#ifdef _WIN32
ioctlsocket(listensocket, FIONBIO, &blockmode);
@@ -535,11 +570,11 @@ int main(int argc, char **argv)
while(1) {
printf("listening...\n");
- printf("Use the device argument 'rtl_tcp=%s:%d' in OsmoSDR "
+ printf("Use the device argument 'rtl_tcp=%s:%s' in OsmoSDR "
"(gr-osmosdr) source\n"
"to receive samples in GRC and control "
"rtl_tcp parameters (frequency, gain, ...).\n",
- addr, port);
+ hostinfo, portinfo);
listen(listensocket,1);
while(1) {
@@ -559,7 +594,10 @@ int main(int argc, char **argv)
setsockopt(s, SOL_SOCKET, SO_LINGER, (char *)&ling, sizeof(ling));
- printf("client accepted!\n");
+ getnameinfo((struct sockaddr *)&remote, rlen,
+ remhostinfo, NI_MAXHOST,
+ remportinfo, NI_MAXSERV, NI_NUMERICSERV);
+ printf("client accepted! %s %s\n", remhostinfo, remportinfo);
memset(&dongle_info, 0, sizeof(dongle_info));
memcpy(&dongle_info.magic, "RTL0", 4);
--
2.30.2
|