Hi list, It looks like IPv6 parsing may lead to errors. The logic cannot distinguish from ‘2001:db8::1234:80’ as : - a plain IPv6 address 2001:db8::1234:80 - IPv6 2001:db8::1234 on port 80
It always default to the latter, considering any valid word made only of digits as a port.
(see https://gist.github.com/mildis/4ab2c3ff3a9ad56c9970)The proposed patch allows IPv6 literal addresses to be enclose in square brackets as per https://www.ietf.org/rfc/rfc2732.txt
Mildis
From 5ab1cdaffbd48d5776dc94365c7581c6b0b84124 Mon Sep 17 00:00:00 2001 From: mildis <[email protected]> Date: Mon, 5 Oct 2015 09:52:43 +0200 Subject: [PATCH] OPTIM/MINOR: decode IPv6 literal addresses --- src/standard.c | 28 ++++++++++++++++++++++++---- 1 file changed, 24 insertions(+), 4 deletions(-) diff --git a/src/standard.c b/src/standard.c index b5f4bf4..00af8dc 100644 --- a/src/standard.c +++ b/src/standard.c @@ -637,11 +637,31 @@ struct sockaddr_storage *str2ip2(const char *str, struct sockaddr_storage *sa, i return sa; } + /* check IPv6 literal */ + if (str[0] == '[') { + if (strrchr(str, ']') != NULL) + sa->ss_family = AF_INET6; + else + goto fail; + } + /* check for IPv6 first */ - if ((!sa->ss_family || sa->ss_family == AF_UNSPEC || sa->ss_family == AF_INET6) && - inet_pton(AF_INET6, str, &((struct sockaddr_in6 *)sa)->sin6_addr)) { - sa->ss_family = AF_INET6; - return sa; + if (!sa->ss_family || sa->ss_family == AF_UNSPEC || sa->ss_family == AF_INET6) { + /* IPv6 literal with opening and closing bracket ? */ + if (str[0] == '[' && strchr(str, ']') != NULL) { + /* strip the closing bracket */ + *(strchr(str, ']')) = '\0'; + /* if inet_pton is OK, it is a valid IPv6 address */ + if (inet_pton(AF_INET6, str+1, &((struct sockaddr_in6 *)sa)->sin6_addr)) { + sa->ss_family = AF_INET6; + return sa; + } + } + /* IPv6 without brackets */ + else if (inet_pton(AF_INET6, str, &((struct sockaddr_in6 *)sa)->sin6_addr)) { + sa->ss_family = AF_INET6; + return sa; + } } /* then check for IPv4 */ -- 1.8.4

