From 83b8aebb19fe6e49e13a05d4e8f5ab9a06177642 Mon Sep 17 00:00:00 2001 From: Yves-Alexis Perez Date: Sat, 11 Apr 2015 22:03:59 +0200 Subject: Imported Upstream version 5.3.0 --- src/libstrongswan/utils/chunk.c | 2 +- src/libstrongswan/utils/compat/apple.h | 119 ++++++ src/libstrongswan/utils/compat/windows.c | 684 +++++++++++++++++++++++++++++++ src/libstrongswan/utils/compat/windows.h | 627 ++++++++++++++++++++++++++++ src/libstrongswan/utils/enum.c | 93 ++++- src/libstrongswan/utils/enum.h | 35 +- src/libstrongswan/utils/identification.c | 87 ++++ src/libstrongswan/utils/identification.h | 9 + src/libstrongswan/utils/utils.h | 6 +- src/libstrongswan/utils/windows.c | 641 ----------------------------- src/libstrongswan/utils/windows.h | 584 -------------------------- 11 files changed, 1654 insertions(+), 1233 deletions(-) create mode 100644 src/libstrongswan/utils/compat/apple.h create mode 100644 src/libstrongswan/utils/compat/windows.c create mode 100644 src/libstrongswan/utils/compat/windows.h delete mode 100644 src/libstrongswan/utils/windows.c delete mode 100644 src/libstrongswan/utils/windows.h (limited to 'src/libstrongswan/utils') diff --git a/src/libstrongswan/utils/chunk.c b/src/libstrongswan/utils/chunk.c index 4b24b37c2..c4471be70 100644 --- a/src/libstrongswan/utils/chunk.c +++ b/src/libstrongswan/utils/chunk.c @@ -992,7 +992,7 @@ u_int32_t chunk_hash_static(chunk_t chunk) */ u_int16_t chunk_internet_checksum_inc(chunk_t data, u_int16_t checksum) { - u_int32_t sum = ntohs(~checksum); + u_int32_t sum = ntohs((u_int16_t)~checksum); while (data.len > 1) { diff --git a/src/libstrongswan/utils/compat/apple.h b/src/libstrongswan/utils/compat/apple.h new file mode 100644 index 000000000..61afb9d9e --- /dev/null +++ b/src/libstrongswan/utils/compat/apple.h @@ -0,0 +1,119 @@ +/* + * Copyright (C) 2014 Martin Willi + * Copyright (C) 2014 revosec AG + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. See . + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + */ + +/** + * @defgroup apple apple + * @{ @ingroup compat + */ + +#ifndef APPLE_H_ +#define APPLE_H_ + +#include +#include +#include + +/* thread_create is a syscall used to create Mach kernel threads and although + * there are no errors or warnings during compilation or linkage the dynamic + * linker does not use our implementation, therefore we rename it here + */ +#define thread_create(main, arg) strongswan_thread_create(main, arg) + +/* Mach uses a semaphore_create() call, use a different name for ours */ +#define semaphore_create(x) strongswan_semaphore_create(x) + +/* Since OS X 10.10 XPC includes some additional conflicting Mach types */ +#define host_t strongswan_host_t +#define processor_t strongswan_processor_t +#define task_t strongswan_task_t +#define thread_t strongswan_thread_t + +/* forward declaration, see below */ +static inline int precancellable_poll(struct pollfd fds[], nfds_t nfds, + int timeout); + +/* on Mac OS X 10.5 several system calls we use are no cancellation points. + * fortunately, select isn't one of them, so we wrap some of the others with + * calls to select(2). + */ + +#define WRAP_WITH_POLL(func, socket, ...) \ + struct pollfd pfd = { \ + .fd = socket, \ + .events = POLLIN, \ + }; \ + if (precancellable_poll(&pfd, 1, -1) <= 0) \ + {\ + return -1; \ + }\ + return func(socket, __VA_ARGS__) + +static inline int cancellable_accept(int socket, struct sockaddr *address, + socklen_t *address_len) +{ + WRAP_WITH_POLL(accept, socket, address, address_len); +} +#define accept cancellable_accept +static inline int cancellable_recvfrom(int socket, void *buffer, size_t length, + int flags, struct sockaddr *address, socklen_t *address_len) +{ + WRAP_WITH_POLL(recvfrom, socket, buffer, length, flags, address, address_len); +} +#define recvfrom cancellable_recvfrom + +#include + +/* + * While select() is a cancellation point, it seems that OS X does not honor + * pending cancellation points when entering the function. We manually test for + * and honor pending cancellation requests, but this obviously can't prevent + * some race conditions where the the cancellation happens after the check, + * but before the select. + */ +static inline int precancellable_select(int nfds, fd_set *restrict readfds, + fd_set *restrict writefds, fd_set *restrict errorfds, + struct timeval *restrict timeout) +{ + if (thread_cancelability(TRUE)) + { + thread_cancellation_point(); + } + else + { + thread_cancelability(FALSE); + } + return select(nfds, readfds, writefds, errorfds, timeout); +} +#define select precancellable_select + +/* + * The same as to select(2) applies to poll(2) + */ +static inline int precancellable_poll(struct pollfd fds[], nfds_t nfds, + int timeout) +{ + if (thread_cancelability(TRUE)) + { + thread_cancellation_point(); + } + else + { + thread_cancelability(FALSE); + } + return poll(fds, nfds, timeout); +} +#define poll precancellable_poll + +#endif /** APPLE_H_ @}*/ diff --git a/src/libstrongswan/utils/compat/windows.c b/src/libstrongswan/utils/compat/windows.c new file mode 100644 index 000000000..1f22ffa02 --- /dev/null +++ b/src/libstrongswan/utils/compat/windows.c @@ -0,0 +1,684 @@ +/* + * Copyright (C) 2013 Martin Willi + * Copyright (C) 2013 revosec AG + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. See . + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + */ + +/* WSAPoll() */ +#define _WIN32_WINNT 0x0600 + +#include + +#include + +/** + * See header + */ +void windows_init() +{ + WSADATA wsad; + + /* initialize winsock2 */ + WSAStartup(MAKEWORD(2, 2), &wsad); +} + +/** + * See header + */ +void windows_deinit() +{ + WSACleanup(); +} + +/** + * See header + */ +int usleep(useconds_t usec) +{ + if (usec > 0 && usec < 1000) + { /* do not Sleep(0) for small values */ + usec = 1000; + } + SleepEx(usec / 1000, TRUE); + return 0; +} + +/** + * See header. + */ +char* strndup(const char *s, size_t n) +{ + char *dst; + + n = min(strnlen(s, n), n); + dst = malloc(n + 1); + memcpy(dst, s, n); + dst[n] = '\0'; + + return dst; +} + +/* + * See header. + */ +void *dlopen(const char *filename, int flag) +{ + return LoadLibrary(filename); +} + +/** + * Load a symbol from known default libs (monolithic build) + */ +static void* dlsym_default(const char *name) +{ + const char *dlls[] = { + "libstrongswan-0.dll", + "libhydra-0.dll", + "libcharon-0.dll", + "libtnccs-0.dll", + NULL /* .exe */ + }; + HANDLE handle; + void *sym = NULL; + int i; + + for (i = 0; i < countof(dlls); i++) + { + handle = GetModuleHandle(dlls[i]); + if (handle) + { + sym = GetProcAddress(handle, name); + if (sym) + { + break; + } + } + } + return sym; +} + +/** + * Emulate RTLD_NEXT for some known symbols + */ +static void* dlsym_next(const char *name) +{ + struct { + const char *dll; + const char *syms[4]; + } dlls[] = { + /* for leak detective */ + { "msvcrt", + { "malloc", "calloc", "realloc", "free" } + }, + }; + HANDLE handle = NULL; + int i, j; + + for (i = 0; i < countof(dlls); i++) + { + for (j = 0; j < countof(dlls[0].syms); j++) + { + if (dlls[i].syms[j] && streq(dlls[i].syms[j], name)) + { + handle = GetModuleHandle(dlls[i].dll); + break; + } + } + } + if (handle) + { + return GetProcAddress(handle, name); + } + return handle; +} + +/** + * See header. + */ +void* dlsym(void *handle, const char *symbol) +{ + if (handle == RTLD_DEFAULT) + { + return dlsym_default(symbol); + } + if (handle == RTLD_NEXT) + { + return dlsym_next(symbol); + } + return GetProcAddress((HMODULE)handle, symbol); +} + +/** + * See header. + */ +char* dlerror(void) +{ + static char buf[128]; + char *pos; + DWORD err; + + err = GetLastError(); + if (FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, err, 0, buf, sizeof(buf), NULL) > 0) + { + pos = strchr(buf, '\n'); + if (pos) + { + *pos = '\0'; + } + } + else + { + snprintf(buf, sizeof(buf), "(%u)", err); + } + return buf; +} + +/** + * See header. + */ +int dlclose(void *handle) +{ + return FreeLibrary((HMODULE)handle); +} + +/** + * See header + */ +int socketpair(int domain, int type, int protocol, int sv[2]) +{ + struct sockaddr_in addr = { + .sin_family = AF_INET, + .sin_addr.s_addr = htonl(INADDR_LOOPBACK), + }; + socklen_t len = sizeof(addr); + int s, c, sc; + BOOL on; + + /* We don't check domain for AF_INET, as we use it as replacement for + * AF_UNIX. */ + if (type != SOCK_STREAM) + { + errno = EINVAL; + return -1; + } + if (protocol != 0 && protocol != IPPROTO_TCP) + { + errno = EINVAL; + return -1; + } + s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (s == -1) + { + return -1; + } + c = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (c == -1) + { + closesocket(s); + return -1; + } + if (bind(s, (struct sockaddr*)&addr, sizeof(addr)) == 0 && + getsockname(s,(struct sockaddr*)&addr, &len) == 0 && + listen(s, 0) == 0 && + connect(c, (struct sockaddr*)&addr, sizeof(addr)) == 0) + { + sc = accept(s, NULL, NULL); + if (sc >= 0) + { + closesocket(s); + s = sc; + if (setsockopt(s, IPPROTO_TCP, TCP_NODELAY, + (void*)&on, sizeof(on)) == 0 && + setsockopt(c, IPPROTO_TCP, TCP_NODELAY, + (void*)&on, sizeof(on)) == 0) + { + sv[0] = s; + sv[1] = c; + return 0; + } + } + } + closesocket(s); + closesocket(c); + return -1; +} + +/** + * See header + */ +char* getpass(const char *prompt) +{ + static char buf[64] = ""; + char *pos; + HANDLE in, out; + DWORD mode, written = 0, total, done; + + out = GetStdHandle(STD_OUTPUT_HANDLE); + in = GetStdHandle(STD_INPUT_HANDLE); + + if (out == INVALID_HANDLE_VALUE || in == INVALID_HANDLE_VALUE || + !GetConsoleMode(out, &mode) || !GetConsoleMode(in, &mode)) + { + return NULL; + } + + total = strlen(prompt); + while (written < total) + { + if (!WriteConsole(out, prompt + written, total - written, &done, NULL)) + { + return NULL; + } + written += done; + } + + if (!SetConsoleMode(in, mode & ~ENABLE_ECHO_INPUT)) + { + return NULL; + } + + while (TRUE) + { + if (!ReadConsole(in, buf, sizeof(buf), &done, NULL)) + { + SetConsoleMode(in, mode); + return NULL; + } + buf[sizeof(buf)-1] = '\0'; + + if (done) + { + pos = strchr(buf, '\r'); + if (pos) + { + *pos = '\0'; + } + break; + } + } + SetConsoleMode(in, mode); + + /* append a newline, as we have no echo during input */ + WriteConsole(out, "\r\n", 2, &done, NULL); + + return buf; +} + +/** + * See header. + */ +#undef strerror_s +int strerror_s_extended(char *buf, size_t buflen, int errnum) +{ + const char *errstr [] = { + /* EADDRINUSE */ "Address in use", + /* EADDRNOTAVAIL */ "Address not available", + /* EAFNOSUPPORT */ "Address family not supported", + /* EALREADY */ "Connection already in progress", + /* EBADMSG */ "Bad message", + /* ECANCELED */ "Operation canceled", + /* ECONNABORTED */ "Connection aborted", + /* ECONNREFUSED */ "Connection refused", + /* ECONNRESET */ "Connection reset", + /* EDESTADDRREQ */ "Destination address required", + /* EHOSTUNREACH */ "Host is unreachable", + /* EIDRM */ "Identifier removed", + /* EINPROGRESS */ "Operation in progress", + /* EISCONN */ "Socket is connected", + /* ELOOP */ "Too many levels of symbolic links", + /* EMSGSIZE */ "Message too large", + /* ENETDOWN */ "Network is down", + /* ENETRESET */ "Connection aborted by network", + /* ENETUNREACH */ "Network unreachable", + /* ENOBUFS */ "No buffer space available", + /* ENODATA */ "No message is available", + /* ENOLINK */ "No link", + /* ENOMSG */ "No message of the desired type", + /* ENOPROTOOPT */ "Protocol not available", + /* ENOSR */ "No stream resources", + /* ENOSTR */ "Not a stream", + /* ENOTCONN */ "The socket is not connected", + /* ENOTRECOVERABLE */ "State not recoverable", + /* ENOTSOCK */ "Not a socket", + /* ENOTSUP */ "Not supported", + /* EOPNOTSUPP */ "Operation not supported on socket", + /* EOTHER */ "Other error", + /* EOVERFLOW */ "Value too large to be stored in data type", + /* EOWNERDEAD */ "Previous owner died", + /* EPROTO */ "Protocol error", + /* EPROTONOSUPPORT */ "Protocol not supported", + /* EPROTOTYPE */ "Protocol wrong type for socket", + /* ETIME */ "Timeout", + /* ETIMEDOUT */ "Connection timed out", + /* ETXTBSY */ "Text file busy", + /* EWOULDBLOCK */ "Operation would block", + }; + int offset = EADDRINUSE; + + if (errnum < offset || errnum >= offset + countof(errstr)) + { + return strerror_s(buf, buflen, errnum); + } + strncpy(buf, errstr[errnum - offset], buflen); + buf[buflen - 1] = '\0'; + return 0; +} + +/** + * Set errno for a function setting WSA error on failure + */ +static int wserr(int retval) +{ + if (retval < 0) + { + static const struct { + DWORD wsa; + int err; + } map[] = { + { WSANOTINITIALISED, EBADF }, + { WSAENETDOWN, ENETDOWN }, + { WSAENETRESET, ENETRESET }, + { WSAECONNABORTED, ECONNABORTED }, + { WSAESHUTDOWN, ECONNABORTED }, + { WSAEACCES, EACCES }, + { WSAEINTR, EINTR }, + { WSAEINPROGRESS, EINPROGRESS }, + { WSAEFAULT, EFAULT }, + { WSAENOBUFS, ENOBUFS }, + { WSAENOTSOCK, ENOTSOCK }, + { WSAEOPNOTSUPP, EOPNOTSUPP }, + { WSAEWOULDBLOCK, EWOULDBLOCK }, + { WSAEMSGSIZE, EMSGSIZE }, + { WSAEINVAL, EINVAL }, + { WSAENOTCONN, ENOTCONN }, + { WSAEHOSTUNREACH, EHOSTUNREACH }, + { WSAENETUNREACH, ENETUNREACH }, + { WSAECONNABORTED, ECONNABORTED }, + { WSAECONNRESET, ECONNRESET }, + { WSAETIMEDOUT, ETIMEDOUT }, + { WSAEMFILE, EMFILE }, + { WSAEALREADY, EALREADY }, + { WSAEDESTADDRREQ, EDESTADDRREQ }, + { WSAEISCONN, EISCONN }, + { WSAEOPNOTSUPP, EOPNOTSUPP }, + { WSAEPROTOTYPE, EPROTOTYPE }, + { WSAENOPROTOOPT, ENOPROTOOPT }, + { WSAEPROTONOSUPPORT, EPROTONOSUPPORT }, + { WSAEPFNOSUPPORT, EPROTONOSUPPORT }, + { WSAEAFNOSUPPORT, EAFNOSUPPORT }, + { WSAEADDRNOTAVAIL, EADDRNOTAVAIL }, + { WSAEADDRINUSE, EADDRINUSE }, + { WSAETIMEDOUT, ETIMEDOUT }, + { WSAECONNREFUSED, ECONNREFUSED }, + { WSAELOOP, ELOOP }, + { WSAENAMETOOLONG, ENAMETOOLONG }, + { WSAENOTEMPTY, ENOTEMPTY }, + { WSAEPROTOTYPE, EPROTOTYPE }, + { WSAVERNOTSUPPORTED, ENOTSUP }, + }; + DWORD wsa, i; + + wsa = WSAGetLastError(); + for (i = 0; i < countof(map); i++) + { + if (map[i].wsa == wsa) + { + errno = map[i].err; + return retval; + } + } + errno = ENOENT; + return retval; + } + errno = 0; + return retval; +} + +/** + * Check and clear the dontwait flag + */ +static bool check_dontwait(int *flags) +{ + if (*flags & MSG_DONTWAIT) + { + *flags &= ~MSG_DONTWAIT; + return TRUE; + } + return FALSE; +} + +/** + * See header + */ +#undef shutdown +int windows_shutdown(int sockfd, int how) +{ + return wserr(shutdown(sockfd, how)); +} + +/** + * See header + */ +#undef accept +int windows_accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen) +{ + return wserr(accept(sockfd, addr, addrlen)); +} + +/** + * See header + */ +#undef bind +int windows_bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen) +{ + return wserr(bind(sockfd, addr, addrlen)); +} + +/** + * See header + */ +#undef connect +int windows_connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen) +{ + return wserr(connect(sockfd, addr, addrlen)); +} + +/** + * See header + */ +#undef getsockname +int windows_getsockname(int sockfd, struct sockaddr *addr, socklen_t *addrlen) +{ + return wserr(getsockname(sockfd, addr, addrlen)); +} + +/** + * See header + */ +#undef getsockopt +int windows_getsockopt(int sockfd, int level, int optname, + void *optval, socklen_t *optlen) +{ + return wserr(getsockopt(sockfd, level, optname, optval, optlen)); +} + +/** + * See header + */ +#undef setsockopt +int windows_setsockopt(int sockfd, int level, int optname, + const void *optval, socklen_t optlen) +{ + return wserr(setsockopt(sockfd, level, optname, optval, optlen)); +} + +/** + * See header + */ +#undef socket +int windows_socket(int domain, int type, int protocol) +{ + return wserr(socket(domain, type, protocol)); +} + +/** + * See header + */ +#undef select +int windows_select(int nfds, fd_set *readfds, fd_set *writefds, + fd_set *exceptfds, struct timeval *timeout) +{ + return wserr(select(nfds, readfds, writefds, exceptfds, timeout)); +} + +/** + * See header + */ +#undef close +int windows_close(int fd) +{ + int ret; + + ret = close(fd); + if (ret == -1 && errno == EBADF) + { /* Winsock socket? */ + ret = wserr(closesocket(fd)); + } + return ret; +} + +/** + * See header + */ +#undef recv +ssize_t windows_recv(int sockfd, void *buf, size_t len, int flags) +{ + u_long on = 1, off = 0; + ssize_t outlen = -1; + + if (!check_dontwait(&flags)) + { + return wserr(recv(sockfd, buf, len, flags)); + } + if (wserr(ioctlsocket(sockfd, FIONBIO, &on) == 0)) + { + outlen = wserr(recv(sockfd, buf, len, flags)); + ioctlsocket(sockfd, FIONBIO, &off); + } + return outlen; +} + +/** + * See header + */ +#undef recvfrom +ssize_t windows_recvfrom(int sockfd, void *buf, size_t len, int flags, + struct sockaddr *src_addr, socklen_t *addrlen) +{ + u_long on = 1, off = 0; + ssize_t outlen = -1; + + if (!check_dontwait(&flags)) + { + return wserr(recvfrom(sockfd, buf, len, flags, src_addr, addrlen)); + } + if (wserr(ioctlsocket(sockfd, FIONBIO, &on)) == 0) + { + outlen = wserr(recvfrom(sockfd, buf, len, flags, src_addr, addrlen)); + ioctlsocket(sockfd, FIONBIO, &off); + } + return outlen; +} + +/** + * See header + */ +#undef send +ssize_t windows_send(int sockfd, const void *buf, size_t len, int flags) +{ + u_long on = 1, off = 0; + ssize_t outlen = -1; + + if (!check_dontwait(&flags)) + { + return wserr(send(sockfd, buf, len, flags)); + } + if (wserr(ioctlsocket(sockfd, FIONBIO, &on)) == 0) + { + outlen = wserr(send(sockfd, buf, len, flags)); + ioctlsocket(sockfd, FIONBIO, &off); + } + return outlen; +} + +/** + * See header + */ +#undef sendto +ssize_t windows_sendto(int sockfd, const void *buf, size_t len, int flags, + const struct sockaddr *dest_addr, socklen_t addrlen) +{ + u_long on = 1, off = 0; + ssize_t outlen = -1; + + if (!check_dontwait(&flags)) + { + return wserr(sendto(sockfd, buf, len, flags, dest_addr, addrlen)); + } + if (wserr(ioctlsocket(sockfd, FIONBIO, &on)) == 0) + { + outlen = wserr(sendto(sockfd, buf, len, flags, dest_addr, addrlen)); + ioctlsocket(sockfd, FIONBIO, &off); + } + return outlen; +} + +/** + * See header + */ +#undef read +ssize_t windows_read(int fd, void *buf, size_t count) +{ + ssize_t ret; + + ret = wserr(recv(fd, buf, count, 0)); + if (ret == -1 && errno == ENOTSOCK) + { + ret = read(fd, buf, count); + } + return ret; +} + +/** + * See header + */ +#undef write +ssize_t windows_write(int fd, void *buf, size_t count) +{ + ssize_t ret; + + ret = wserr(send(fd, buf, count, 0)); + if (ret == -1 && errno == ENOTSOCK) + { + ret = write(fd, buf, count); + } + return ret; +} + +/** + * See header + */ +int poll(struct pollfd *fds, int nfds, int timeout) +{ + return wserr(WSAPoll(fds, nfds, timeout)); +} diff --git a/src/libstrongswan/utils/compat/windows.h b/src/libstrongswan/utils/compat/windows.h new file mode 100644 index 000000000..fd4f1f196 --- /dev/null +++ b/src/libstrongswan/utils/compat/windows.h @@ -0,0 +1,627 @@ +/* + * Copyright (C) 2013 Martin Willi + * Copyright (C) 2013 revosec AG + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. See . + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + */ + +/** + * @defgroup windows windows + * @{ @ingroup compat + */ + +#ifndef WINDOWS_H_ +#define WINDOWS_H_ + +#include +#include +#include +#include +#include +#include + +/* undef Windows variants evaluating values more than once */ +#undef min +#undef max + +/* interface is defined as an alias to "struct" in basetypes.h, but + * we use it here and there as ordinary identifier. */ +#undef interface + +/* used by Windows API, but we have our own */ +#undef CALLBACK + +/* UID/GID types for capabilities, even if not supported */ +typedef u_int uid_t; +typedef u_int gid_t; + +/** + * Initialize Windows libraries + */ +void windows_init(); + +/** + * Deinitialize windows libraries + */ +void windows_deinit(); + +/** + * Replacement for random(3) + */ +static inline long random(void) +{ + return rand(); +} + +/** + * Replacement for srandom(3) + */ +static inline void srandom(unsigned int seed) +{ + srand(seed); +} + +/** + * Replacement of sched_yield(2) from + */ +static inline int sched_yield(void) +{ + Sleep(0); + return 0; +} + +/** + * Replacement of sleep(3), cancellable by thread_cancel() + */ +#define sleep sleep_cancellable +static inline int sleep_cancellable(unsigned int seconds) +{ + SleepEx(seconds * 1000, TRUE); + return 0; +} + +/** + * Replacement of usleep(3), cancellable, ms resolution only + */ +int usleep(useconds_t usec); + +/** + * strdup(3), the Windows variant can't free(strdup("")) and others + */ +#define strdup strdup_windows +static inline char* strdup_windows(const char *src) +{ + size_t len; + char *dst; + + len = strlen(src) + 1; + dst = malloc(len); + memcpy(dst, src, len); + return dst; +} + +/** + * strndup(3) + */ +char* strndup(const char *s, size_t n); + +/** + * Provided via ws2_32 + */ +#ifndef InetNtop +const char WINAPI *inet_ntop(int af, const void *src, char *dst, socklen_t size); +#endif + +/** + * Provided via ws2_32 + */ +#ifndef InetPton +int WINAPI inet_pton(int af, const char *src, void *dst); +#endif + +/** + * Provided by printf hook backend + */ +int asprintf(char **strp, const char *fmt, ...); + +/** + * Provided by printf hook backend + */ +int vasprintf(char **strp, const char *fmt, va_list ap); + +/** + * timeradd(3) from + */ +static inline void timeradd(struct timeval *a, struct timeval *b, + struct timeval *res) +{ + res->tv_sec = a->tv_sec + b->tv_sec; + res->tv_usec = a->tv_usec + b->tv_usec; + if (res->tv_usec >= 1000000) + { + res->tv_usec -= 1000000; + res->tv_sec++; + } +} + +/** + * timersub(3) from + */ +static inline void timersub(struct timeval *a, struct timeval *b, + struct timeval *res) +{ + res->tv_sec = a->tv_sec - b->tv_sec; + res->tv_usec = a->tv_usec - b->tv_usec; + if (res->tv_usec < 0) + { + res->tv_usec += 1000000; + res->tv_sec--; + } +} + +/** + * gmtime_r(3) from + */ +static inline struct tm *gmtime_r(const time_t *timep, struct tm *result) +{ + struct tm *ret; + + /* gmtime_s() and friends seem not to be implemented/functioning. + * Relying on gmtime() on Windows works as well, as it uses thread + * specific buffers. */ + ret = gmtime(timep); + if (ret) + { + memcpy(result, ret, sizeof(*result)); + } + return ret; +} + +/** + * localtime_r(3) from + */ +static inline struct tm *localtime_r(const time_t *timep, struct tm *result) +{ + struct tm *ret; + + /* localtime_s() and friends seem not to be implemented/functioning. + * Relying on localtime() on Windows works as well, as it uses thread + * specific buffers. */ + ret = localtime(timep); + if (ret) + { + memcpy(result, ret, sizeof(*result)); + } + return ret; +} + +/** + * setenv(3) from , overwrite flag is ignored + */ +static inline int setenv(const char *name, const char *value, int overwrite) +{ + if (SetEnvironmentVariableA(name, value) == 0) + { /* failed */ + return -1; + } + return 0; +} + +/** + * Lazy binding, ignored on Windows + */ +#define RTLD_LAZY 1 + +/** + * Default handle targeting .exe + */ +#define RTLD_DEFAULT (NULL) + +/** + * Find symbol in next library + */ +#define RTLD_NEXT ((void*)~(uintptr_t)0) + +/** + * dlopen(3) from + */ +void* dlopen(const char *filename, int flag); + +/** + * dlsym() from + */ +void* dlsym(void *handle, const char *symbol); + +/** + * dlerror(3) from , currently not thread save + */ +char* dlerror(void); + +/** + * dlclose() from + */ +int dlclose(void *handle); + +/** + * socketpair(2) for SOCK_STREAM, uses TCP on loopback + */ +int socketpair(int domain, int type, int protocol, int sv[2]); + +/** + * getpass(3) on Windows consoles + */ +char* getpass(const char *prompt); +#define HAVE_GETPASS + +/** + * Map MSG_DONTWAIT to the reserved, but deprecated MSG_INTERRUPT + */ +#define MSG_DONTWAIT MSG_INTERRUPT + +/** + * shutdown(2) "how"-aliases, to use Unix variant on Windows + */ +#define SHUT_RD SD_RECEIVE +#define SHUT_WR SD_SEND +#define SHUT_RDWR SD_BOTH + +/** + * shutdown(2) setting errno + */ +#define shutdown windows_shutdown +int windows_shutdown(int sockfd, int how); + +/** + * accept(2) setting errno + */ +#define accept windows_accept +int windows_accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen); + +/** + * bind(2) setting errno + */ +#define bind windows_bind +int windows_bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen); + +/** + * connect(2) setting errno + */ +#define connect windows_connect +int windows_connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen); + +/** + * getsockname(2) setting errno + */ +#define getsockname windows_getsockname +int windows_getsockname(int sockfd, struct sockaddr *addr, socklen_t *addrlen); + +/** + * getsockopt(2) setting errno + */ +#define getsockopt windows_getsockopt +int windows_getsockopt(int sockfd, int level, int optname, + void *optval, socklen_t *optlen); + +/** + * setsockopt(2) setting errno + */ +#define setsockopt windows_setsockopt +int windows_setsockopt(int sockfd, int level, int optname, + const void *optval, socklen_t optlen); + +/** + * socket(2) setting errno + */ +#define socket windows_socket +int windows_socket(int domain, int type, int protocol); + +/** + * select(2) setting errno + */ +#define select windows_select +int windows_select(int nfds, fd_set *readfds, fd_set *writefds, + fd_set *exceptfds, struct timeval *timeout); + +/** + * close(2) working for file handles and Winsock sockets + */ +#define close windows_close +int windows_close(int fd); + +/** + * recv(2) with support for MSG_DONTWAIT + */ +#define recv windows_recv +ssize_t windows_recv(int sockfd, void *buf, size_t len, int flags); + +/** + * recvfrom(2) with support for MSG_DONTWAIT + */ +#define recvfrom windows_recvfrom +ssize_t windows_recvfrom(int sockfd, void *buf, size_t len, int flags, + struct sockaddr *src_addr, socklen_t *addrlen); + +/** + * recvfrom(2) with support for MSG_DONTWAIT + */ +#define send windows_send +ssize_t windows_send(int sockfd, const void *buf, size_t len, int flags); + +/** + * recvfrom(2) with support for MSG_DONTWAIT + */ +#define sendto windows_send +ssize_t windows_sendto(int sockfd, const void *buf, size_t len, int flags, + const struct sockaddr *dest_addr, socklen_t addrlen); + +/** + * read(2) working on files and sockets, cancellable on sockets only + * + * On Windows, there does not seem to be a way how a cancellable read can + * be implemented on Low level I/O functions for files, _pipe()s or stdio. + */ +#define read windows_read +ssize_t windows_read(int fd, void *buf, size_t count); + +/** + * write(2) working on files and sockets + */ +#define write windows_write +ssize_t windows_write(int fd, void *buf, size_t count); + +#if _WIN32_WINNT < 0x0600 +/** + * Define pollfd and flags on our own if not specified + */ +struct pollfd { + SOCKET fd; + short events; + short revents; +}; +enum { + POLLERR = 0x0001, + POLLHUP = 0x0002, + POLLNVAL = 0x0004, + POLLWRNORM = 0x0010, + POLLWRBAND = 0x0020, + POLLPRI = 0x0400, + POLLRDNORM = 0x0100, + POLLRDBAND = 0x0200, + POLLIN = POLLRDNORM | POLLRDBAND, + POLLOUT = POLLWRNORM, +}; +#endif /* _WIN32_WINNT < 0x0600 */ + +/** + * poll(2), implemented using Winsock2 WSAPoll() + */ +int poll(struct pollfd *fds, int nfds, int timeout); + +/** + * Declaration missing on older WinGW + */ +_CRTIMP errno_t strerror_s(char *buf, size_t size, int errnum); + +/** + * strerror_s, but supporting POSIX compatibility errno >= 100 + */ +#define strerror_s strerror_s_extended +int strerror_s_extended(char *buf, size_t buflen, int errnum); + +/** + * strerror_r(2) replacement, XSI variant + */ +static inline int strerror_r(int errnum, char *buf, size_t buflen) +{ + return strerror_s(buf, buflen, errnum); +} +#define HAVE_STRERROR_R /* but not STRERROR_R_CHAR_P */ + +/** + * MinGW does provide extended errno values. Windows itself knowns them + * for POSIX compatibility; we define them as well. + */ +#ifndef EADDRINUSE +#define EADDRINUSE 100 +#endif +#ifndef EADDRNOTAVAIL +#define EADDRNOTAVAIL 101 +#endif +#ifndef EAFNOSUPPORT +#define EAFNOSUPPORT 102 +#endif +#ifndef EALREADY +#define EALREADY 103 +#endif +#ifndef EBADMSG +#define EBADMSG 104 +#endif +#ifndef ECANCELED +#define ECANCELED 105 +#endif +#ifndef ECONNABORTED +#define ECONNABORTED 106 +#endif +#ifndef ECONNREFUSED +#define ECONNREFUSED 107 +#endif +#ifndef ECONNRESET +#define ECONNRESET 108 +#endif +#ifndef EDESTADDRREQ +#define EDESTADDRREQ 109 +#endif +#ifndef EHOSTUNREACH +#define EHOSTUNREACH 110 +#endif +#ifndef EIDRM +#define EIDRM 111 +#endif +#ifndef EINPROGRESS +#define EINPROGRESS 112 +#endif +#ifndef EISCONN +#define EISCONN 113 +#endif +#ifndef ELOOP +#define ELOOP 114 +#endif +#ifndef EMSGSIZE +#define EMSGSIZE 115 +#endif +#ifndef ENETDOWN +#define ENETDOWN 116 +#endif +#ifndef ENETRESET +#define ENETRESET 117 +#endif +#ifndef ENETUNREACH +#define ENETUNREACH 118 +#endif +#ifndef ENOBUFS +#define ENOBUFS 119 +#endif +#ifndef ENODATA +#define ENODATA 120 +#endif +#ifndef ENOLINK +#define ENOLINK 121 +#endif +#ifndef ENOMSG +#define ENOMSG 122 +#endif +#ifndef ENOPROTOOPT +#define ENOPROTOOPT 123 +#endif +#ifndef ENOSR +#define ENOSR 124 +#endif +#ifndef ENOSTR +#define ENOSTR 125 +#endif +#ifndef ENOTCONN +#define ENOTCONN 126 +#endif +#ifndef ENOTRECOVERABLE +#define ENOTRECOVERABLE 127 +#endif +#ifndef ENOTSOCK +#define ENOTSOCK 128 +#endif +#ifndef ENOTSUP +#define ENOTSUP 129 +#endif +#ifndef EOPNOTSUPP +#define EOPNOTSUPP 130 +#endif +#ifndef EOTHER +#define EOTHER 131 +#endif +#ifndef EOVERFLOW +#define EOVERFLOW 132 +#endif +#ifndef EOWNERDEAD +#define EOWNERDEAD 133 +#endif +#ifndef EPROTO +#define EPROTO 134 +#endif +#ifndef EPROTONOSUPPORT +#define EPROTONOSUPPORT 135 +#endif +#ifndef EPROTOTYPE +#define EPROTOTYPE 136 +#endif +#ifndef ETIME +#define ETIME 137 +#endif +#ifndef ETIMEDOUT +#define ETIMEDOUT 138 +#endif +#ifndef ETXTBSY +#define ETXTBSY 139 +#endif +#ifndef EWOULDBLOCK +#define EWOULDBLOCK 140 +#endif + + +/* Windows does not support "ll" format printf length modifiers. Mingw + * therefore maps these to the Windows specific I64 length modifier. That + * won't work for us, as we use our own printf backend on Windows, which works + * just fine with "ll". */ +#undef PRId64 +#define PRId64 "lld" +#undef PRId64 +#define PRId64 "lld" +#undef PRIdLEAST64 +#define PRIdLEAST64 "lld" +#undef PRIdFAST64 +#define PRIdFAST64 "lld" +#undef PRIdMAX +#define PRIdMAX "lld" +#undef PRIi64 +#define PRIi64 "lli" +#undef PRIiLEAST64 +#define PRIiLEAST64 "lli" +#undef PRIiFAST64 +#define PRIiFAST64 "lli" +#undef PRIiMAX +#define PRIiMAX "lli" +#undef PRIo64 +#define PRIo64 "llo" +#undef PRIoLEAST64 +#define PRIoLEAST64 "llo" +#undef PRIoFAST64 +#define PRIoFAST64 "llo" +#undef PRIoMAX +#define PRIoMAX "llo" +#undef PRIu64 +#define PRIu64 "llu" +#undef PRIuLEAST64 +#define PRIuLEAST64 "llu" +#undef PRIuFAST64 +#define PRIuFAST64 "llu" +#undef PRIuMAX +#define PRIuMAX "llu" +#undef PRIx64 +#define PRIx64 "llx" +#undef PRIxLEAST64 +#define PRIxLEAST64 "llx" +#undef PRIxFAST64 +#define PRIxFAST64 "llx" +#undef PRIxMAX +#define PRIxMAX "llx" +#undef PRIX64 +#define PRIX64 "llX" +#undef PRIXLEAST64 +#define PRIXLEAST64 "llX" +#undef PRIXFAST64 +#define PRIXFAST64 "llX" +#undef PRIXMAX +#define PRIXMAX "llX" + +#ifdef _WIN64 +# undef PRIdPTR +# define PRIdPTR "lld" +# undef PRIiPTR +# define PRIiPTR "lli" +# undef PRIoPTR +# define PRIoPTR "llo" +# undef PRIuPTR +# define PRIuPTR "llu" +# undef PRIxPTR +# define PRIxPTR "llx" +# undef PRIXPTR +# define PRIXPTR "llX" +#endif /* _WIN64 */ + +#endif /** WINDOWS_H_ @}*/ diff --git a/src/libstrongswan/utils/enum.c b/src/libstrongswan/utils/enum.c index f96fe2989..089bebb79 100644 --- a/src/libstrongswan/utils/enum.c +++ b/src/libstrongswan/utils/enum.c @@ -59,21 +59,104 @@ bool enum_from_name_as_int(enum_name_t *e, const char *name, int *val) return FALSE; } +/** + * Get the position of a flag name using offset calculation + */ +static int find_flag_pos(u_int val, u_int first) +{ + int offset = 0; + + while (val != 0x01) + { + val = val >> 1; + offset++; + } + return first - offset; +} + /** * Described in header. */ +char *enum_flags_to_string(enum_name_t *e, u_int val, char *buf, size_t len) +{ + char *pos = buf, *delim = ""; + int i, wr; + + if (e->next != ENUM_FLAG_MAGIC) + { + if (snprintf(buf, len, "(%d)", (int)val) >= len) + { + return NULL; + } + return buf; + } + + if (snprintf(buf, len, "(unset)") >= len) + { + return NULL; + } + + for (i = 0; val; i++) + { + u_int flag = 1 << i; + + if (val & flag) + { + char *name = NULL, hex[32]; + + if (flag >= (u_int)e->first && flag <= (u_int)e->last) + { + name = e->names[find_flag_pos(e->first, i)]; + } + else + { + snprintf(hex, sizeof(hex), "(0x%X)", flag); + name = hex; + } + if (name) + { + wr = snprintf(pos, len, "%s%s", delim, name); + if (wr >= len) + { + return NULL; + } + len -= wr; + pos += wr; + delim = " | "; + } + val &= ~flag; + } + } + return buf; +} + +/** + * See header. + */ int enum_printf_hook(printf_hook_data_t *data, printf_hook_spec_t *spec, const void *const *args) { enum_name_t *ed = *((enum_name_t**)(args[0])); int val = *((int*)(args[1])); - char *name, buf[32]; + char *name, buf[512]; - name = enum_to_name(ed, val); - if (name == NULL) + if (ed->next == ENUM_FLAG_MAGIC) + { + name = enum_flags_to_string(ed, val, buf, sizeof(buf)); + if (name == NULL) + { + snprintf(buf, sizeof(buf), "(0x%X)", val); + name = buf; + } + } + else { - snprintf(buf, sizeof(buf), "(%d)", val); - name = buf; + name = enum_to_name(ed, val); + if (name == NULL) + { + snprintf(buf, sizeof(buf), "(%d)", val); + name = buf; + } } if (spec->minus) { diff --git a/src/libstrongswan/utils/enum.h b/src/libstrongswan/utils/enum.h index 3c03c2a7b..928f4079a 100644 --- a/src/libstrongswan/utils/enum.h +++ b/src/libstrongswan/utils/enum.h @@ -26,6 +26,11 @@ typedef struct enum_name_t enum_name_t; +/** + * Magic enum_name_t pointer indicating this is an enum name for flags + */ +#define ENUM_FLAG_MAGIC ((enum_name_t*)~(uintptr_t)0) + /** * Struct to store names for enums. * @@ -58,7 +63,7 @@ struct enum_name_t { int first; /** value of the last enum string */ int last; - /** next enum_name_t in list */ + /** next enum_name_t in list, or ENUM_FLAG_MAGIC */ enum_name_t *next; /** array of strings containing names from first to last */ char *names[]; @@ -106,6 +111,23 @@ struct enum_name_t { */ #define ENUM(name, first, last, ...) ENUM_BEGIN(name, first, last, __VA_ARGS__); ENUM_END(name, last) +/** + * Define a enum name with only one range for flags. + * + * Using an enum list for flags would be overkill. Hence we use a single + * range with all values in range. The next pointer is abused to mark + * that the enum name is for flags only. Use NULL if a particular flag + * is not meant to be printed. + * + * @param name name of the enum_name list + * @param first enum value of the first enum string + * @param last enum value of the last enum string + * @param ... a list of strings + */ +#define ENUM_FLAGS(name, first, last, ...) \ + static enum_name_t name##last = {first, last, ENUM_FLAG_MAGIC, { __VA_ARGS__ }}; \ + ENUM_END(name, last) + /** * Convert a enum value to its string representation. * @@ -145,6 +167,17 @@ char *enum_to_name(enum_name_t *e, int val); */ bool enum_from_name_as_int(enum_name_t *e, const char *name, int *val); +/** + * Convert a enum value containing flags to its string representation. + * + * @param e enum names for this enum value suitable for flags + * @param val enum value to get string for + * @param buf buffer to write flag string to + * @param len buffer size + * @return buf, NULL if buffer too small + */ +char *enum_flags_to_string(enum_name_t *e, u_int val, char *buf, size_t len); + /** * printf hook function for enum_names_t. * diff --git a/src/libstrongswan/utils/identification.c b/src/libstrongswan/utils/identification.c index 46ac7e890..b69adf399 100644 --- a/src/libstrongswan/utils/identification.c +++ b/src/libstrongswan/utils/identification.c @@ -17,6 +17,7 @@ #include #include +#include #include "identification.h" @@ -927,6 +928,82 @@ static private_identification_t *identification_create(id_type_t type) return this; } +/** + * Create an identity for a specific type, determined by prefix + */ +static private_identification_t* create_from_string_with_prefix_type(char *str) +{ + struct { + const char *str; + id_type_t type; + } prefixes[] = { + { "ipv4:", ID_IPV4_ADDR }, + { "ipv6:", ID_IPV6_ADDR }, + { "rfc822:", ID_RFC822_ADDR }, + { "email:", ID_RFC822_ADDR }, + { "userfqdn:", ID_USER_FQDN }, + { "fqdn:", ID_FQDN }, + { "dns:", ID_FQDN }, + { "asn1dn:", ID_DER_ASN1_DN }, + { "asn1gn:", ID_DER_ASN1_GN }, + { "keyid:", ID_KEY_ID }, + }; + private_identification_t *this; + int i; + + for (i = 0; i < countof(prefixes); i++) + { + if (strcasepfx(str, prefixes[i].str)) + { + this = identification_create(prefixes[i].type); + str += strlen(prefixes[i].str); + if (*str == '#') + { + this->encoded = chunk_from_hex(chunk_from_str(str + 1), NULL); + } + else + { + this->encoded = chunk_clone(chunk_from_str(str)); + } + return this; + } + } + return NULL; +} + +/** + * Create an identity for a specific type, determined by a numerical prefix + * + * The prefix is of the form "{x}:", where x denotes the numerical identity + * type. + */ +static private_identification_t* create_from_string_with_num_type(char *str) +{ + private_identification_t *this; + u_long type; + + if (*str++ != '{') + { + return NULL; + } + errno = 0; + type = strtoul(str, &str, 0); + if (errno || *str++ != '}' || *str++ != ':') + { + return NULL; + } + this = identification_create(type); + if (*str == '#') + { + this->encoded = chunk_from_hex(chunk_from_str(str + 1), NULL); + } + else + { + this->encoded = chunk_clone(chunk_from_str(str)); + } + return this; +} + /* * Described in header. */ @@ -939,6 +1016,16 @@ identification_t *identification_create_from_string(char *string) { string = "%any"; } + this = create_from_string_with_prefix_type(string); + if (this) + { + return &this->public; + } + this = create_from_string_with_num_type(string); + if (this) + { + return &this->public; + } if (strchr(string, '=') != NULL) { /* we interpret this as an ASCII X.501 ID_DER_ASN1_DN. diff --git a/src/libstrongswan/utils/identification.h b/src/libstrongswan/utils/identification.h index e62446879..e6a9fe1c6 100644 --- a/src/libstrongswan/utils/identification.h +++ b/src/libstrongswan/utils/identification.h @@ -302,6 +302,15 @@ struct identification_t { * N, G, I, dnQualifier, ID, EN, EmployeeNumber, E, Email, emailAddress, UN, * unstructuredName, TCGID. * + * To skip automatic type detection the following prefixes may be used to + * enforce a specific type: ipv4:, ipv6:, rfc822:, email:, userfqdn:, fqdn:, + * dns:, asn1dn:, asn1gn: and keyid:. If a # follows the :, the remaining data + * is interpreted as hex encoded binary data for that ID, otherwise the raw + * string following the prefix is used as identity data, without conversion. + * To specify a non-standard ID type, the numerical type may be prefixed + * between curly backets, building a prefix. For instance the "{1}:" prefix + * defines an ID_IPV4_ADDR type. + * * This constructor never returns NULL. If it does not find a suitable * conversion function, it will copy the string to an ID_KEY_ID. * diff --git a/src/libstrongswan/utils/utils.h b/src/libstrongswan/utils/utils.h index da253cc35..7c48d949f 100644 --- a/src/libstrongswan/utils/utils.h +++ b/src/libstrongswan/utils/utils.h @@ -29,7 +29,7 @@ #include #ifdef WIN32 -# include "windows.h" +# include "compat/windows.h" #else # define _GNU_SOURCE # include @@ -37,6 +37,7 @@ # include # include # include +# include #endif /** @@ -96,6 +97,9 @@ #include "enum.h" #include "utils/strerror.h" +#ifdef __APPLE__ +# include "compat/apple.h" +#endif /** * Directory separator character in paths on this platform diff --git a/src/libstrongswan/utils/windows.c b/src/libstrongswan/utils/windows.c deleted file mode 100644 index 8820287b1..000000000 --- a/src/libstrongswan/utils/windows.c +++ /dev/null @@ -1,641 +0,0 @@ -/* - * Copyright (C) 2013 Martin Willi - * Copyright (C) 2013 revosec AG - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. See . - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * for more details. - */ - -#include "utils.h" - -#include - -/** - * See header - */ -void windows_init() -{ - WSADATA wsad; - - /* initialize winsock2 */ - WSAStartup(MAKEWORD(2, 2), &wsad); -} - -/** - * See header - */ -void windows_deinit() -{ - WSACleanup(); -} - -/** - * See header - */ -int usleep(useconds_t usec) -{ - if (usec > 0 && usec < 1000) - { /* do not Sleep(0) for small values */ - usec = 1000; - } - SleepEx(usec / 1000, TRUE); - return 0; -} - -/** - * See header. - */ -char* strndup(const char *s, size_t n) -{ - char *dst; - - n = min(strnlen(s, n), n); - dst = malloc(n + 1); - memcpy(dst, s, n); - dst[n] = '\0'; - - return dst; -} - -/* - * See header. - */ -void *dlopen(const char *filename, int flag) -{ - return LoadLibrary(filename); -} - -/** - * Load a symbol from known default libs (monolithic build) - */ -static void* dlsym_default(const char *name) -{ - const char *dlls[] = { - "libstrongswan-0.dll", - "libhydra-0.dll", - "libcharon-0.dll", - "libtnccs-0.dll", - NULL /* .exe */ - }; - HANDLE handle; - void *sym = NULL; - int i; - - for (i = 0; i < countof(dlls); i++) - { - handle = GetModuleHandle(dlls[i]); - if (handle) - { - sym = GetProcAddress(handle, name); - if (sym) - { - break; - } - } - } - return sym; -} - -/** - * Emulate RTLD_NEXT for some known symbols - */ -static void* dlsym_next(const char *name) -{ - struct { - const char *dll; - const char *syms[4]; - } dlls[] = { - /* for leak detective */ - { "msvcrt", - { "malloc", "calloc", "realloc", "free" } - }, - }; - HANDLE handle = NULL; - int i, j; - - for (i = 0; i < countof(dlls); i++) - { - for (j = 0; j < countof(dlls[0].syms); j++) - { - if (dlls[i].syms[j] && streq(dlls[i].syms[j], name)) - { - handle = GetModuleHandle(dlls[i].dll); - break; - } - } - } - if (handle) - { - return GetProcAddress(handle, name); - } - return handle; -} - -/** - * See header. - */ -void* dlsym(void *handle, const char *symbol) -{ - if (handle == RTLD_DEFAULT) - { - return dlsym_default(symbol); - } - if (handle == RTLD_NEXT) - { - return dlsym_next(symbol); - } - return GetProcAddress((HMODULE)handle, symbol); -} - -/** - * See header. - */ -char* dlerror(void) -{ - static char buf[128]; - char *pos; - DWORD err; - - err = GetLastError(); - if (FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, - NULL, err, 0, buf, sizeof(buf), NULL) > 0) - { - pos = strchr(buf, '\n'); - if (pos) - { - *pos = '\0'; - } - } - else - { - snprintf(buf, sizeof(buf), "(%u)", err); - } - return buf; -} - -/** - * See header. - */ -int dlclose(void *handle) -{ - return FreeLibrary((HMODULE)handle); -} - -/** - * See header - */ -int socketpair(int domain, int type, int protocol, int sv[2]) -{ - struct sockaddr_in addr = { - .sin_family = AF_INET, - .sin_addr.s_addr = htonl(INADDR_LOOPBACK), - }; - socklen_t len = sizeof(addr); - int s, c, sc; - BOOL on; - - /* We don't check domain for AF_INET, as we use it as replacement for - * AF_UNIX. */ - if (type != SOCK_STREAM) - { - errno = EINVAL; - return -1; - } - if (protocol != 0 && protocol != IPPROTO_TCP) - { - errno = EINVAL; - return -1; - } - s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); - if (s == -1) - { - return -1; - } - c = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); - if (c == -1) - { - closesocket(s); - return -1; - } - if (bind(s, (struct sockaddr*)&addr, sizeof(addr)) == 0 && - getsockname(s,(struct sockaddr*)&addr, &len) == 0 && - listen(s, 0) == 0 && - connect(c, (struct sockaddr*)&addr, sizeof(addr)) == 0) - { - sc = accept(s, NULL, NULL); - if (sc >= 0) - { - closesocket(s); - s = sc; - if (setsockopt(s, IPPROTO_TCP, TCP_NODELAY, - (void*)&on, sizeof(on)) == 0 && - setsockopt(c, IPPROTO_TCP, TCP_NODELAY, - (void*)&on, sizeof(on)) == 0) - { - sv[0] = s; - sv[1] = c; - return 0; - } - } - } - closesocket(s); - closesocket(c); - return -1; -} - -/** - * See header - */ -char* getpass(const char *prompt) -{ - static char buf[64] = ""; - char *pos; - HANDLE in, out; - DWORD mode, written = 0, total, done; - - out = GetStdHandle(STD_OUTPUT_HANDLE); - in = GetStdHandle(STD_INPUT_HANDLE); - - if (out == INVALID_HANDLE_VALUE || in == INVALID_HANDLE_VALUE || - !GetConsoleMode(out, &mode) || !GetConsoleMode(in, &mode)) - { - return NULL; - } - - total = strlen(prompt); - while (written < total) - { - if (!WriteConsole(out, prompt + written, total - written, &done, NULL)) - { - return NULL; - } - written += done; - } - - if (!SetConsoleMode(in, mode & ~ENABLE_ECHO_INPUT)) - { - return NULL; - } - - while (TRUE) - { - if (!ReadConsole(in, buf, sizeof(buf), &done, NULL)) - { - SetConsoleMode(in, mode); - return NULL; - } - buf[sizeof(buf)-1] = '\0'; - - if (done) - { - pos = strchr(buf, '\r'); - if (pos) - { - *pos = '\0'; - } - break; - } - } - SetConsoleMode(in, mode); - - /* append a newline, as we have no echo during input */ - WriteConsole(out, "\r\n", 2, &done, NULL); - - return buf; -} - -/** - * See header. - */ -#undef strerror_s -int strerror_s_extended(char *buf, size_t buflen, int errnum) -{ - const char *errstr [] = { - /* EADDRINUSE */ "Address in use", - /* EADDRNOTAVAIL */ "Address not available", - /* EAFNOSUPPORT */ "Address family not supported", - /* EALREADY */ "Connection already in progress", - /* EBADMSG */ "Bad message", - /* ECANCELED */ "Operation canceled", - /* ECONNABORTED */ "Connection aborted", - /* ECONNREFUSED */ "Connection refused", - /* ECONNRESET */ "Connection reset", - /* EDESTADDRREQ */ "Destination address required", - /* EHOSTUNREACH */ "Host is unreachable", - /* EIDRM */ "Identifier removed", - /* EINPROGRESS */ "Operation in progress", - /* EISCONN */ "Socket is connected", - /* ELOOP */ "Too many levels of symbolic links", - /* EMSGSIZE */ "Message too large", - /* ENETDOWN */ "Network is down", - /* ENETRESET */ "Connection aborted by network", - /* ENETUNREACH */ "Network unreachable", - /* ENOBUFS */ "No buffer space available", - /* ENODATA */ "No message is available", - /* ENOLINK */ "No link", - /* ENOMSG */ "No message of the desired type", - /* ENOPROTOOPT */ "Protocol not available", - /* ENOSR */ "No stream resources", - /* ENOSTR */ "Not a stream", - /* ENOTCONN */ "The socket is not connected", - /* ENOTRECOVERABLE */ "State not recoverable", - /* ENOTSOCK */ "Not a socket", - /* ENOTSUP */ "Not supported", - /* EOPNOTSUPP */ "Operation not supported on socket", - /* EOTHER */ "Other error", - /* EOVERFLOW */ "Value too large to be stored in data type", - /* EOWNERDEAD */ "Previous owner died", - /* EPROTO */ "Protocol error", - /* EPROTONOSUPPORT */ "Protocol not supported", - /* EPROTOTYPE */ "Protocol wrong type for socket", - /* ETIME */ "Timeout", - /* ETIMEDOUT */ "Connection timed out", - /* ETXTBSY */ "Text file busy", - /* EWOULDBLOCK */ "Operation would block", - }; - int offset = EADDRINUSE; - - if (errnum < offset || errnum >= offset + countof(errstr)) - { - return strerror_s(buf, buflen, errnum); - } - strncpy(buf, errstr[errnum - offset], buflen); - buf[buflen - 1] = '\0'; - return 0; -} - -/** - * Set errno for a function setting WSA error on failure - */ -static int wserr(int retval) -{ - if (retval < 0) - { - static const struct { - DWORD wsa; - int err; - } map[] = { - { WSANOTINITIALISED, EBADF }, - { WSAENETDOWN, ENETDOWN }, - { WSAENETRESET, ENETRESET }, - { WSAECONNABORTED, ECONNABORTED }, - { WSAESHUTDOWN, ECONNABORTED }, - { WSAEACCES, EACCES }, - { WSAEINTR, EINTR }, - { WSAEINPROGRESS, EINPROGRESS }, - { WSAEFAULT, EFAULT }, - { WSAENOBUFS, ENOBUFS }, - { WSAENOTSOCK, ENOTSOCK }, - { WSAEOPNOTSUPP, EOPNOTSUPP }, - { WSAEWOULDBLOCK, EWOULDBLOCK }, - { WSAEMSGSIZE, EMSGSIZE }, - { WSAEINVAL, EINVAL }, - { WSAENOTCONN, ENOTCONN }, - { WSAEHOSTUNREACH, EHOSTUNREACH }, - { WSAENETUNREACH, ENETUNREACH }, - { WSAECONNABORTED, ECONNABORTED }, - { WSAECONNRESET, ECONNRESET }, - { WSAETIMEDOUT, ETIMEDOUT }, - { WSAEMFILE, EMFILE }, - { WSAEALREADY, EALREADY }, - { WSAEDESTADDRREQ, EDESTADDRREQ }, - { WSAEISCONN, EISCONN }, - { WSAEOPNOTSUPP, EOPNOTSUPP }, - { WSAEPROTOTYPE, EPROTOTYPE }, - { WSAENOPROTOOPT, ENOPROTOOPT }, - { WSAEPROTONOSUPPORT, EPROTONOSUPPORT }, - { WSAEPFNOSUPPORT, EPROTONOSUPPORT }, - { WSAEAFNOSUPPORT, EAFNOSUPPORT }, - { WSAEADDRNOTAVAIL, EADDRNOTAVAIL }, - { WSAEADDRINUSE, EADDRINUSE }, - { WSAETIMEDOUT, ETIMEDOUT }, - { WSAECONNREFUSED, ECONNREFUSED }, - { WSAELOOP, ELOOP }, - { WSAENAMETOOLONG, ENAMETOOLONG }, - { WSAENOTEMPTY, ENOTEMPTY }, - { WSAEPROTOTYPE, EPROTOTYPE }, - { WSAVERNOTSUPPORTED, ENOTSUP }, - }; - DWORD wsa, i; - - wsa = WSAGetLastError(); - for (i = 0; i < countof(map); i++) - { - if (map[i].wsa == wsa) - { - errno = map[i].err; - return retval; - } - } - errno = ENOENT; - return retval; - } - errno = 0; - return retval; -} - -/** - * Check and clear the dontwait flag - */ -static bool check_dontwait(int *flags) -{ - if (*flags & MSG_DONTWAIT) - { - *flags &= ~MSG_DONTWAIT; - return TRUE; - } - return FALSE; -} - -/** - * See header - */ -#undef shutdown -int windows_shutdown(int sockfd, int how) -{ - return wserr(shutdown(sockfd, how)); -} - -/** - * See header - */ -#undef accept -int windows_accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen) -{ - return wserr(accept(sockfd, addr, addrlen)); -} - -/** - * See header - */ -#undef bind -int windows_bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen) -{ - return wserr(bind(sockfd, addr, addrlen)); -} - -/** - * See header - */ -#undef connect -int windows_connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen) -{ - return wserr(connect(sockfd, addr, addrlen)); -} - -/** - * See header - */ -#undef getsockname -int windows_getsockname(int sockfd, struct sockaddr *addr, socklen_t *addrlen) -{ - return wserr(getsockname(sockfd, addr, addrlen)); -} - -/** - * See header - */ -#undef getsockopt -int windows_getsockopt(int sockfd, int level, int optname, - void *optval, socklen_t *optlen) -{ - return wserr(getsockopt(sockfd, level, optname, optval, optlen)); -} - -/** - * See header - */ -#undef setsockopt -int windows_setsockopt(int sockfd, int level, int optname, - const void *optval, socklen_t optlen) -{ - return wserr(setsockopt(sockfd, level, optname, optval, optlen)); -} - -/** - * See header - */ -#undef socket -int windows_socket(int domain, int type, int protocol) -{ - return wserr(socket(domain, type, protocol)); -} - -/** - * See header - */ -#undef select -int windows_select(int nfds, fd_set *readfds, fd_set *writefds, - fd_set *exceptfds, struct timeval *timeout) -{ - return wserr(select(nfds, readfds, writefds, exceptfds, timeout)); -} - -/** - * See header - */ -#undef close -int windows_close(int fd) -{ - int ret; - - ret = close(fd); - if (ret == -1 && errno == EBADF) - { /* Winsock socket? */ - ret = wserr(closesocket(fd)); - } - return ret; -} - -/** - * See header - */ -#undef recv -ssize_t windows_recv(int sockfd, void *buf, size_t len, int flags) -{ - u_long on = 1, off = 0; - ssize_t outlen = -1; - - if (!check_dontwait(&flags)) - { - return wserr(recv(sockfd, buf, len, flags)); - } - if (wserr(ioctlsocket(sockfd, FIONBIO, &on) == 0)) - { - outlen = wserr(recv(sockfd, buf, len, flags)); - ioctlsocket(sockfd, FIONBIO, &off); - } - return outlen; -} - -/** - * See header - */ -#undef recvfrom -ssize_t windows_recvfrom(int sockfd, void *buf, size_t len, int flags, - struct sockaddr *src_addr, socklen_t *addrlen) -{ - u_long on = 1, off = 0; - ssize_t outlen = -1; - - if (!check_dontwait(&flags)) - { - return wserr(recvfrom(sockfd, buf, len, flags, src_addr, addrlen)); - } - if (wserr(ioctlsocket(sockfd, FIONBIO, &on)) == 0) - { - outlen = wserr(recvfrom(sockfd, buf, len, flags, src_addr, addrlen)); - ioctlsocket(sockfd, FIONBIO, &off); - } - return outlen; -} - -/** - * See header - */ -#undef send -ssize_t windows_send(int sockfd, const void *buf, size_t len, int flags) -{ - u_long on = 1, off = 0; - ssize_t outlen = -1; - - if (!check_dontwait(&flags)) - { - return wserr(send(sockfd, buf, len, flags)); - } - if (wserr(ioctlsocket(sockfd, FIONBIO, &on)) == 0) - { - outlen = wserr(send(sockfd, buf, len, flags)); - ioctlsocket(sockfd, FIONBIO, &off); - } - return outlen; -} - -/** - * See header - */ -#undef sendto -ssize_t windows_sendto(int sockfd, const void *buf, size_t len, int flags, - const struct sockaddr *dest_addr, socklen_t addrlen) -{ - u_long on = 1, off = 0; - ssize_t outlen = -1; - - if (!check_dontwait(&flags)) - { - return wserr(sendto(sockfd, buf, len, flags, dest_addr, addrlen)); - } - if (wserr(ioctlsocket(sockfd, FIONBIO, &on)) == 0) - { - outlen = wserr(sendto(sockfd, buf, len, flags, dest_addr, addrlen)); - ioctlsocket(sockfd, FIONBIO, &off); - } - return outlen; -} diff --git a/src/libstrongswan/utils/windows.h b/src/libstrongswan/utils/windows.h deleted file mode 100644 index 3761e10ab..000000000 --- a/src/libstrongswan/utils/windows.h +++ /dev/null @@ -1,584 +0,0 @@ -/* - * Copyright (C) 2013 Martin Willi - * Copyright (C) 2013 revosec AG - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. See . - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * for more details. - */ - -/** - * @defgroup windows windows - * @{ @ingroup utils - */ - -#ifndef WINDOWS_H_ -#define WINDOWS_H_ - -#include -#include -#include -#include -#include -#include - -/* undef Windows variants evaluating values more than once */ -#undef min -#undef max - -/* interface is defined as an alias to "struct" in basetypes.h, but - * we use it here and there as ordinary identifier. */ -#undef interface - -/* used by Windows API, but we have our own */ -#undef CALLBACK - -/* UID/GID types for capabilities, even if not supported */ -typedef u_int uid_t; -typedef u_int gid_t; - -/** - * Initialize Windows libraries - */ -void windows_init(); - -/** - * Deinitialize windows libraries - */ -void windows_deinit(); - -/** - * Replacement for random(3) - */ -static inline long random(void) -{ - return rand(); -} - -/** - * Replacement for srandom(3) - */ -static inline void srandom(unsigned int seed) -{ - srand(seed); -} - -/** - * Replacement of sched_yield(2) from - */ -static inline int sched_yield(void) -{ - Sleep(0); - return 0; -} - -/** - * Replacement of sleep(3), cancellable by thread_cancel() - */ -#define sleep sleep_cancellable -static inline int sleep_cancellable(unsigned int seconds) -{ - SleepEx(seconds * 1000, TRUE); - return 0; -} - -/** - * Replacement of usleep(3), cancellable, ms resolution only - */ -int usleep(useconds_t usec); - -/** - * strdup(3), the Windows variant can't free(strdup("")) and others - */ -#define strdup strdup_windows -static inline char* strdup_windows(const char *src) -{ - size_t len; - char *dst; - - len = strlen(src) + 1; - dst = malloc(len); - memcpy(dst, src, len); - return dst; -} - -/** - * strndup(3) - */ -char* strndup(const char *s, size_t n); - -/** - * Provided via ws2_32 - */ -#ifndef InetNtop -const char WINAPI *inet_ntop(int af, const void *src, char *dst, socklen_t size); -#endif - -/** - * Provided via ws2_32 - */ -#ifndef InetPton -int WINAPI inet_pton(int af, const char *src, void *dst); -#endif - -/** - * Provided by printf hook backend - */ -int asprintf(char **strp, const char *fmt, ...); - -/** - * Provided by printf hook backend - */ -int vasprintf(char **strp, const char *fmt, va_list ap); - -/** - * timeradd(3) from - */ -static inline void timeradd(struct timeval *a, struct timeval *b, - struct timeval *res) -{ - res->tv_sec = a->tv_sec + b->tv_sec; - res->tv_usec = a->tv_usec + b->tv_usec; - if (res->tv_usec >= 1000000) - { - res->tv_usec -= 1000000; - res->tv_sec++; - } -} - -/** - * timersub(3) from - */ -static inline void timersub(struct timeval *a, struct timeval *b, - struct timeval *res) -{ - res->tv_sec = a->tv_sec - b->tv_sec; - res->tv_usec = a->tv_usec - b->tv_usec; - if (res->tv_usec < 0) - { - res->tv_usec += 1000000; - res->tv_sec--; - } -} - -/** - * gmtime_r(3) from - */ -static inline struct tm *gmtime_r(const time_t *timep, struct tm *result) -{ - struct tm *ret; - - /* gmtime_s() and friends seem not to be implemented/functioning. - * Relying on gmtime() on Windows works as well, as it uses thread - * specific buffers. */ - ret = gmtime(timep); - if (ret) - { - memcpy(result, ret, sizeof(*result)); - } - return ret; -} - -/** - * localtime_r(3) from - */ -static inline struct tm *localtime_r(const time_t *timep, struct tm *result) -{ - struct tm *ret; - - /* localtime_s() and friends seem not to be implemented/functioning. - * Relying on localtime() on Windows works as well, as it uses thread - * specific buffers. */ - ret = localtime(timep); - if (ret) - { - memcpy(result, ret, sizeof(*result)); - } - return ret; -} - -/** - * setenv(3) from , overwrite flag is ignored - */ -static inline int setenv(const char *name, const char *value, int overwrite) -{ - if (SetEnvironmentVariableA(name, value) == 0) - { /* failed */ - return -1; - } - return 0; -} - -/** - * Lazy binding, ignored on Windows - */ -#define RTLD_LAZY 1 - -/** - * Default handle targeting .exe - */ -#define RTLD_DEFAULT (NULL) - -/** - * Find symbol in next library - */ -#define RTLD_NEXT ((void*)~(uintptr_t)0) - -/** - * dlopen(3) from - */ -void* dlopen(const char *filename, int flag); - -/** - * dlsym() from - */ -void* dlsym(void *handle, const char *symbol); - -/** - * dlerror(3) from , currently not thread save - */ -char* dlerror(void); - -/** - * dlclose() from - */ -int dlclose(void *handle); - -/** - * socketpair(2) for SOCK_STREAM, uses TCP on loopback - */ -int socketpair(int domain, int type, int protocol, int sv[2]); - -/** - * getpass(3) on Windows consoles - */ -char* getpass(const char *prompt); -#define HAVE_GETPASS - -/** - * Map MSG_DONTWAIT to the reserved, but deprecated MSG_INTERRUPT - */ -#define MSG_DONTWAIT MSG_INTERRUPT - -/** - * shutdown(2) "how"-aliases, to use Unix variant on Windows - */ -#define SHUT_RD SD_RECEIVE -#define SHUT_WR SD_SEND -#define SHUT_RDWR SD_BOTH - -/** - * shutdown(2) setting errno - */ -#define shutdown windows_shutdown -int windows_shutdown(int sockfd, int how); - -/** - * accept(2) setting errno - */ -#define accept windows_accept -int windows_accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen); - -/** - * bind(2) setting errno - */ -#define bind windows_bind -int windows_bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen); - -/** - * connect(2) setting errno - */ -#define connect windows_connect -int windows_connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen); - -/** - * getsockname(2) setting errno - */ -#define getsockname windows_getsockname -int windows_getsockname(int sockfd, struct sockaddr *addr, socklen_t *addrlen); - -/** - * getsockopt(2) setting errno - */ -#define getsockopt windows_getsockopt -int windows_getsockopt(int sockfd, int level, int optname, - void *optval, socklen_t *optlen); - -/** - * setsockopt(2) setting errno - */ -#define setsockopt windows_setsockopt -int windows_setsockopt(int sockfd, int level, int optname, - const void *optval, socklen_t optlen); - -/** - * socket(2) setting errno - */ -#define socket windows_socket -int windows_socket(int domain, int type, int protocol); - -/** - * select(2) setting errno - */ -#define select windows_select -int windows_select(int nfds, fd_set *readfds, fd_set *writefds, - fd_set *exceptfds, struct timeval *timeout); - -/** - * close(2) working for file handles and Winsock sockets - */ -#define close windows_close -int windows_close(int fd); - -/** - * recv(2) with support for MSG_DONTWAIT - */ -#define recv windows_recv -ssize_t windows_recv(int sockfd, void *buf, size_t len, int flags); - -/** - * recvfrom(2) with support for MSG_DONTWAIT - */ -#define recvfrom windows_recvfrom -ssize_t windows_recvfrom(int sockfd, void *buf, size_t len, int flags, - struct sockaddr *src_addr, socklen_t *addrlen); - -/** - * recvfrom(2) with support for MSG_DONTWAIT - */ -#define send windows_send -ssize_t windows_send(int sockfd, const void *buf, size_t len, int flags); - -/** - * recvfrom(2) with support for MSG_DONTWAIT - */ -#define sendto windows_send -ssize_t windows_sendto(int sockfd, const void *buf, size_t len, int flags, - const struct sockaddr *dest_addr, socklen_t addrlen); - -/** - * Declaration missing on older WinGW - */ -_CRTIMP errno_t strerror_s(char *buf, size_t size, int errnum); - -/** - * strerror_s, but supporting POSIX compatibility errno >= 100 - */ -#define strerror_s strerror_s_extended -int strerror_s_extended(char *buf, size_t buflen, int errnum); - -/** - * strerror_r(2) replacement, XSI variant - */ -static inline int strerror_r(int errnum, char *buf, size_t buflen) -{ - return strerror_s(buf, buflen, errnum); -} -#define HAVE_STRERROR_R /* but not STRERROR_R_CHAR_P */ - -/** - * MinGW does provide extended errno values. Windows itself knowns them - * for POSIX compatibility; we define them as well. - */ -#ifndef EADDRINUSE -#define EADDRINUSE 100 -#endif -#ifndef EADDRNOTAVAIL -#define EADDRNOTAVAIL 101 -#endif -#ifndef EAFNOSUPPORT -#define EAFNOSUPPORT 102 -#endif -#ifndef EALREADY -#define EALREADY 103 -#endif -#ifndef EBADMSG -#define EBADMSG 104 -#endif -#ifndef ECANCELED -#define ECANCELED 105 -#endif -#ifndef ECONNABORTED -#define ECONNABORTED 106 -#endif -#ifndef ECONNREFUSED -#define ECONNREFUSED 107 -#endif -#ifndef ECONNRESET -#define ECONNRESET 108 -#endif -#ifndef EDESTADDRREQ -#define EDESTADDRREQ 109 -#endif -#ifndef EHOSTUNREACH -#define EHOSTUNREACH 110 -#endif -#ifndef EIDRM -#define EIDRM 111 -#endif -#ifndef EINPROGRESS -#define EINPROGRESS 112 -#endif -#ifndef EISCONN -#define EISCONN 113 -#endif -#ifndef ELOOP -#define ELOOP 114 -#endif -#ifndef EMSGSIZE -#define EMSGSIZE 115 -#endif -#ifndef ENETDOWN -#define ENETDOWN 116 -#endif -#ifndef ENETRESET -#define ENETRESET 117 -#endif -#ifndef ENETUNREACH -#define ENETUNREACH 118 -#endif -#ifndef ENOBUFS -#define ENOBUFS 119 -#endif -#ifndef ENODATA -#define ENODATA 120 -#endif -#ifndef ENOLINK -#define ENOLINK 121 -#endif -#ifndef ENOMSG -#define ENOMSG 122 -#endif -#ifndef ENOPROTOOPT -#define ENOPROTOOPT 123 -#endif -#ifndef ENOSR -#define ENOSR 124 -#endif -#ifndef ENOSTR -#define ENOSTR 125 -#endif -#ifndef ENOTCONN -#define ENOTCONN 126 -#endif -#ifndef ENOTRECOVERABLE -#define ENOTRECOVERABLE 127 -#endif -#ifndef ENOTSOCK -#define ENOTSOCK 128 -#endif -#ifndef ENOTSUP -#define ENOTSUP 129 -#endif -#ifndef EOPNOTSUPP -#define EOPNOTSUPP 130 -#endif -#ifndef EOTHER -#define EOTHER 131 -#endif -#ifndef EOVERFLOW -#define EOVERFLOW 132 -#endif -#ifndef EOWNERDEAD -#define EOWNERDEAD 133 -#endif -#ifndef EPROTO -#define EPROTO 134 -#endif -#ifndef EPROTONOSUPPORT -#define EPROTONOSUPPORT 135 -#endif -#ifndef EPROTOTYPE -#define EPROTOTYPE 136 -#endif -#ifndef ETIME -#define ETIME 137 -#endif -#ifndef ETIMEDOUT -#define ETIMEDOUT 138 -#endif -#ifndef ETXTBSY -#define ETXTBSY 139 -#endif -#ifndef EWOULDBLOCK -#define EWOULDBLOCK 140 -#endif - - -/* Windows does not support "ll" format printf length modifiers. Mingw - * therefore maps these to the Windows specific I64 length modifier. That - * won't work for us, as we use our own printf backend on Windows, which works - * just fine with "ll". */ -#undef PRId64 -#define PRId64 "lld" -#undef PRId64 -#define PRId64 "lld" -#undef PRIdLEAST64 -#define PRIdLEAST64 "lld" -#undef PRIdFAST64 -#define PRIdFAST64 "lld" -#undef PRIdMAX -#define PRIdMAX "lld" -#undef PRIi64 -#define PRIi64 "lli" -#undef PRIiLEAST64 -#define PRIiLEAST64 "lli" -#undef PRIiFAST64 -#define PRIiFAST64 "lli" -#undef PRIiMAX -#define PRIiMAX "lli" -#undef PRIo64 -#define PRIo64 "llo" -#undef PRIoLEAST64 -#define PRIoLEAST64 "llo" -#undef PRIoFAST64 -#define PRIoFAST64 "llo" -#undef PRIoMAX -#define PRIoMAX "llo" -#undef PRIu64 -#define PRIu64 "llu" -#undef PRIuLEAST64 -#define PRIuLEAST64 "llu" -#undef PRIuFAST64 -#define PRIuFAST64 "llu" -#undef PRIuMAX -#define PRIuMAX "llu" -#undef PRIx64 -#define PRIx64 "llx" -#undef PRIxLEAST64 -#define PRIxLEAST64 "llx" -#undef PRIxFAST64 -#define PRIxFAST64 "llx" -#undef PRIxMAX -#define PRIxMAX "llx" -#undef PRIX64 -#define PRIX64 "llX" -#undef PRIXLEAST64 -#define PRIXLEAST64 "llX" -#undef PRIXFAST64 -#define PRIXFAST64 "llX" -#undef PRIXMAX -#define PRIXMAX "llX" - -#ifdef _WIN64 -# undef PRIdPTR -# define PRIdPTR "lld" -# undef PRIiPTR -# define PRIiPTR "lli" -# undef PRIoPTR -# define PRIoPTR "llo" -# undef PRIuPTR -# define PRIuPTR "llu" -# undef PRIxPTR -# define PRIxPTR "llx" -# undef PRIXPTR -# define PRIXPTR "llX" -#endif /* _WIN64 */ - -#endif /** WINDOWS_H_ @}*/ -- cgit v1.2.3