From bbcaa4db847047bd9517ed47404fe8f6f3a79fa0 Mon Sep 17 00:00:00 2001 From: David Woodhouse Date: Mon, 28 Jul 2014 12:46:47 +0100 Subject: [PATCH] Add inet_pton() compatibility for Windows Windows XP doesn't have it, so just wrap WSAStringToAddressA(). Signed-off-by: David Woodhouse --- compat.c | 41 +++++++++++++++++++++++++++++++++++++++++ openconnect-internal.h | 3 +++ 2 files changed, 44 insertions(+) diff --git a/compat.c b/compat.c index 5844f6f9..26037b95 100644 --- a/compat.c +++ b/compat.c @@ -237,6 +237,47 @@ void openconnect__win32_sock_init() } } +int openconnect__win32_inet_pton(int af, const char *src, void *dst) +{ + union { + struct sockaddr_in s4; + struct sockaddr_in6 s6; + } sa; + int salen = sizeof(sa); + + if (af != AF_INET && af != AF_INET6) { + errno = EAFNOSUPPORT; + return -1; + } + + memset(&sa, 0, sizeof(sa)); + sa.s4.sin_family = af; + + if (WSAStringToAddressA((char *)src, af, NULL, (void *)&sa, &salen)) + return 0; + + /* For Legacy IP we need to filter out a lot of crap that + * inet_aton() (and WSAStringToAddress()) will support, but + * which inet_pton() should not. Not to mention the fact that + * Wine's implementation will even succeed for strings like + * "2001::1" (http://bugs.winehq.org/show_bug.cgi?id=36991) */ + if (af == AF_INET) { + char canon[16]; + unsigned char *a = (unsigned char *)&sa.s4.sin_addr; + + snprintf(canon, sizeof(canon), "%d.%d.%d.%d", + a[0], a[1], a[2], a[3]); + + if (strcmp(canon, src)) + return 0; + + memcpy(dst, &sa.s4.sin_addr, sizeof(sa.s4.sin_addr)); + return 1; + } else { + memcpy(dst, &sa.s6.sin6_addr, sizeof(sa.s6.sin6_addr)); + return 1; + } +} /* https://github.com/ncm/selectable-socketpair diff --git a/openconnect-internal.h b/openconnect-internal.h index 7c7d3bcc..819dbd89 100644 --- a/openconnect-internal.h +++ b/openconnect-internal.h @@ -497,6 +497,9 @@ static inline int set_fd_cloexec(int fd) #ifdef _WIN32 #define pipe(fds) _pipe(fds, 4096, O_BINARY) void openconnect__win32_sock_init(); +#undef inet_pton +#define inet_pton openconnect__win32_inet_pton +int openconnect__win32_inet_pton(int af, const char *src, void *dst); int dumb_socketpair(int socks[2], int make_overlapped); #else #define closesocket close