From 67d36152cc3a86a54250ca1f27f4810a6d35d57e Mon Sep 17 00:00:00 2001 From: wh201906 Date: Tue, 17 Oct 2023 18:40:17 +0800 Subject: [PATCH] Add IPv6 support for UDP (Linux) --- client/src/uart/uart_posix.c | 56 +++++++++++++++++++++++++++++------- 1 file changed, 45 insertions(+), 11 deletions(-) diff --git a/client/src/uart/uart_posix.c b/client/src/uart/uart_posix.c index c67199164..5480e98b7 100644 --- a/client/src/uart/uart_posix.c +++ b/client/src/uart/uart_posix.c @@ -219,8 +219,10 @@ serial_port uart_open(const char *pcPortName, uint32_t speed) { struct addrinfo *addr = NULL, *rp; - char *addrstr = strdup(pcPortName + 4); - if (addrstr == NULL) { + char *addrPortStr = strdup(pcPortName + 4); + char *addrstr = addrPortStr; + const char *portstr; + if (addrPortStr == NULL) { PrintAndLogEx(ERR, "error: string duplication"); free(sp); return INVALID_SERIAL_PORT; @@ -228,20 +230,52 @@ serial_port uart_open(const char *pcPortName, uint32_t speed) { timeout.tv_usec = UART_TCP_CLIENT_RX_TIMEOUT_MS * 1000; - char *colon = strrchr(addrstr, ':'); - const char *portstr; - if (colon) { - portstr = colon + 1; - *colon = '\0'; - } else { + // find the start of the address + char *endBracket = strrchr(addrPortStr, ']'); + if (addrPortStr[0] == '[') { + addrstr += 1; + if (endBracket == NULL) { + PrintAndLogEx(ERR, "error: wrong address: [] unmatched"); + free(addrPortStr); + free(sp); + return INVALID_SERIAL_PORT; + } + } + + // find the port + char *lColon = strchr(addrPortStr, ':'); + char *rColon = strrchr(addrPortStr, ':'); + if (rColon == NULL) { + // no colon + // "tcp:", "tcp:[]" portstr = "18888"; + } else if (lColon == rColon) { + // only one colon + // "tcp::", "tcp:[]:" + portstr = rColon + 1; + } else { + // two or more colon, IPv6 address + // tcp:[]: + // "tcp:", "tcp:[]" + if (endBracket != NULL && rColon == endBracket + 1) { + portstr = rColon + 1; + } else { + portstr = "18888"; + } + } + + // handle the end of the address + if (endBracket != NULL) { + *endBracket = '\0'; + } else if (rColon != NULL && lColon == rColon) { + *rColon = '\0'; } struct addrinfo info; memset(&info, 0, sizeof(info)); - info.ai_family = AF_INET; + info.ai_family = PF_UNSPEC; info.ai_socktype = SOCK_DGRAM; // info.ai_protocol = SOL_UDP; @@ -249,7 +283,7 @@ serial_port uart_open(const char *pcPortName, uint32_t speed) { if (s != 0) { PrintAndLogEx(ERR, "error: getaddrinfo: %s", gai_strerror(s)); freeaddrinfo(addr); - free(addrstr); + free(addrPortStr); free(sp); return INVALID_SERIAL_PORT; } @@ -268,7 +302,7 @@ serial_port uart_open(const char *pcPortName, uint32_t speed) { } freeaddrinfo(addr); - free(addrstr); + free(addrPortStr); if (rp == NULL) { /* No address succeeded */ PrintAndLogEx(ERR, "error: Could not connect");