|
@@ -58,6 +58,13 @@
|
|
|
#define NOT_UNDERSCORED_INTERLOCKED_EXCHANGE
|
|
|
#endif
|
|
|
|
|
|
+ #ifdef __GNUC__
|
|
|
+ #if (_WIN32_WINNT < 0x0501)
|
|
|
+ #undef _WIN32_WINNT
|
|
|
+ #define _WIN32_WINNT 0x0501
|
|
|
+ #endif
|
|
|
+ #endif
|
|
|
+
|
|
|
#include <winsock2.h>
|
|
|
#include <ws2tcpip.h>
|
|
|
#include <mmsystem.h>
|
|
@@ -5148,49 +5155,189 @@ extern "C" {
|
|
|
#ifdef _WIN32
|
|
|
|
|
|
#ifdef __MINGW32__
|
|
|
- // inet_ntop/inet_pton for MinGW from http://mingw-users.1079350.n2.nabble.com/IPv6-getaddrinfo-amp-inet-ntop-td5891996.html
|
|
|
- const char *inet_ntop(int af, const void *src, char *dst, socklen_t cnt) {
|
|
|
- if (af == AF_INET) {
|
|
|
- struct sockaddr_in in;
|
|
|
- memset(&in, 0, sizeof(in));
|
|
|
- in.sin_family = AF_INET;
|
|
|
- memcpy(&in.sin_addr, src, sizeof(struct in_addr));
|
|
|
- getnameinfo((struct sockaddr *)&in, sizeof(struct sockaddr_in), dst, cnt, NULL, 0, NI_NUMERICHOST);
|
|
|
- return dst;
|
|
|
- }
|
|
|
- else if (af == AF_INET6) {
|
|
|
- struct sockaddr_in6 in;
|
|
|
- memset(&in, 0, sizeof(in));
|
|
|
- in.sin6_family = AF_INET6;
|
|
|
- memcpy(&in.sin6_addr, src, sizeof(struct in_addr6));
|
|
|
- getnameinfo((struct sockaddr *)&in, sizeof(struct sockaddr_in6), dst, cnt, NULL, 0, NI_NUMERICHOST);
|
|
|
- return dst;
|
|
|
+ // inet_ntop/inet_pton for MinGW from http://mingw-users.1079350.n2.nabble.com/IPv6-getaddrinfo-amp-inet-ntop-td5891996.html
|
|
|
+ const char *inet_ntop(int af, const void *src, char *dst, socklen_t cnt) {
|
|
|
+ if (af == AF_INET) {
|
|
|
+ struct sockaddr_in in;
|
|
|
+ memset(&in, 0, sizeof(in));
|
|
|
+ in.sin_family = AF_INET;
|
|
|
+ memcpy(&in.sin_addr, src, sizeof(struct in_addr));
|
|
|
+ getnameinfo((struct sockaddr *)&in, sizeof(struct sockaddr_in), dst, cnt, NULL, 0, NI_NUMERICHOST);
|
|
|
+ return dst;
|
|
|
+ }
|
|
|
+ else if (af == AF_INET6) {
|
|
|
+ struct sockaddr_in6 in;
|
|
|
+ memset(&in, 0, sizeof(in));
|
|
|
+ in.sin6_family = AF_INET6;
|
|
|
+ memcpy(&in.sin6_addr, src, sizeof(struct in_addr6));
|
|
|
+ getnameinfo((struct sockaddr *)&in, sizeof(struct sockaddr_in6), dst, cnt, NULL, 0, NI_NUMERICHOST);
|
|
|
+ return dst;
|
|
|
+ }
|
|
|
+
|
|
|
+ return NULL;
|
|
|
}
|
|
|
|
|
|
- return NULL;
|
|
|
- }
|
|
|
+ #define NS_INADDRSZ 4
|
|
|
+ #define NS_IN6ADDRSZ 16
|
|
|
+ #define NS_INT16SZ 2
|
|
|
|
|
|
- int inet_pton(int af, const char *src, void *dst) {
|
|
|
- struct addrinfo hints, *res, *ressave;
|
|
|
+ int inet_pton4(const char *src, char *dst)
|
|
|
+ {
|
|
|
+ uint8_t tmp[NS_INADDRSZ], *tp;
|
|
|
|
|
|
- memset(&hints, 0, sizeof(struct addrinfo));
|
|
|
- hints.ai_family = af;
|
|
|
+ int saw_digit = 0;
|
|
|
+ int octets = 0;
|
|
|
+ *(tp = tmp) = 0;
|
|
|
|
|
|
- if (getaddrinfo(src, NULL, &hints, &res) != 0) {
|
|
|
- return -1;
|
|
|
+ int ch;
|
|
|
+ while ((ch = *src++) != '\0')
|
|
|
+ {
|
|
|
+ if (ch >= '0' && ch <= '9')
|
|
|
+ {
|
|
|
+ uint32_t n = *tp * 10 + (ch - '0');
|
|
|
+
|
|
|
+ if (saw_digit && *tp == 0)
|
|
|
+ return 0;
|
|
|
+
|
|
|
+ if (n > 255)
|
|
|
+ return 0;
|
|
|
+
|
|
|
+ *tp = n;
|
|
|
+ if (!saw_digit)
|
|
|
+ {
|
|
|
+ if (++octets > 4)
|
|
|
+ return 0;
|
|
|
+ saw_digit = 1;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else if (ch == '.' && saw_digit)
|
|
|
+ {
|
|
|
+ if (octets == 4)
|
|
|
+ return 0;
|
|
|
+ *++tp = 0;
|
|
|
+ saw_digit = 0;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+ if (octets < 4)
|
|
|
+ return 0;
|
|
|
+
|
|
|
+ memcpy(dst, tmp, NS_INADDRSZ);
|
|
|
+
|
|
|
+ return 1;
|
|
|
}
|
|
|
|
|
|
- ressave = res;
|
|
|
+ int inet_pton6(const char *src, char *dst)
|
|
|
+ {
|
|
|
+ static const char xdigits[] = "0123456789abcdef";
|
|
|
+ uint8_t tmp[NS_IN6ADDRSZ];
|
|
|
+
|
|
|
+ uint8_t *tp = (uint8_t*) memset(tmp, '\0', NS_IN6ADDRSZ);
|
|
|
+ uint8_t *endp = tp + NS_IN6ADDRSZ;
|
|
|
+ uint8_t *colonp = NULL;
|
|
|
+
|
|
|
+ /* Leading :: requires some special handling. */
|
|
|
+ if (*src == ':')
|
|
|
+ {
|
|
|
+ if (*++src != ':')
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ const char *curtok = src;
|
|
|
+ int saw_xdigit = 0;
|
|
|
+ uint32_t val = 0;
|
|
|
+ int ch;
|
|
|
+ while ((ch = tolower(*src++)) != '\0')
|
|
|
+ {
|
|
|
+ const char *pch = strchr(xdigits, ch);
|
|
|
+ if (pch != NULL)
|
|
|
+ {
|
|
|
+ val <<= 4;
|
|
|
+ val |= (pch - xdigits);
|
|
|
+ if (val > 0xffff)
|
|
|
+ return 0;
|
|
|
+ saw_xdigit = 1;
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ if (ch == ':')
|
|
|
+ {
|
|
|
+ curtok = src;
|
|
|
+ if (!saw_xdigit)
|
|
|
+ {
|
|
|
+ if (colonp)
|
|
|
+ return 0;
|
|
|
+ colonp = tp;
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ else if (*src == '\0')
|
|
|
+ {
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+ if (tp + NS_INT16SZ > endp)
|
|
|
+ return 0;
|
|
|
+ *tp++ = (uint8_t) (val >> 8) & 0xff;
|
|
|
+ *tp++ = (uint8_t) val & 0xff;
|
|
|
+ saw_xdigit = 0;
|
|
|
+ val = 0;
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ if (ch == '.' && ((tp + NS_INADDRSZ) <= endp) &&
|
|
|
+ inet_pton4(curtok, (char*) tp) > 0)
|
|
|
+ {
|
|
|
+ tp += NS_INADDRSZ;
|
|
|
+ saw_xdigit = 0;
|
|
|
+ break; /* '\0' was seen by inet_pton4(). */
|
|
|
+ }
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+ if (saw_xdigit)
|
|
|
+ {
|
|
|
+ if (tp + NS_INT16SZ > endp)
|
|
|
+ return 0;
|
|
|
+ *tp++ = (uint8_t) (val >> 8) & 0xff;
|
|
|
+ *tp++ = (uint8_t) val & 0xff;
|
|
|
+ }
|
|
|
+ if (colonp != NULL)
|
|
|
+ {
|
|
|
+ /*
|
|
|
+ * Since some memmove()'s erroneously fail to handle
|
|
|
+ * overlapping regions, we'll do the shift by hand.
|
|
|
+ */
|
|
|
+ const int n = tp - colonp;
|
|
|
+
|
|
|
+ if (tp == endp)
|
|
|
+ return 0;
|
|
|
|
|
|
- while (res) {
|
|
|
- memcpy(dst, res->ai_addr, res->ai_addrlen);
|
|
|
- res = res->ai_next;
|
|
|
+ for (int i = 1; i <= n; i++)
|
|
|
+ {
|
|
|
+ endp[-i] = colonp[n - i];
|
|
|
+ colonp[n - i] = 0;
|
|
|
+ }
|
|
|
+ tp = endp;
|
|
|
+ }
|
|
|
+ if (tp != endp)
|
|
|
+ return 0;
|
|
|
+
|
|
|
+ memcpy(dst, tmp, NS_IN6ADDRSZ);
|
|
|
+
|
|
|
+ return 1;
|
|
|
}
|
|
|
|
|
|
- freeaddrinfo(ressave);
|
|
|
- return 0;
|
|
|
- }
|
|
|
- #endif
|
|
|
+
|
|
|
+ int inet_pton(int af, const char *src, char *dst)
|
|
|
+ {
|
|
|
+ switch (af)
|
|
|
+ {
|
|
|
+ case AF_INET:
|
|
|
+ return inet_pton4(src, dst);
|
|
|
+ case AF_INET6:
|
|
|
+ return inet_pton6(src, dst);
|
|
|
+ default:
|
|
|
+ return -1;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ #endif // __MINGW__
|
|
|
|
|
|
int enet_initialize(void) {
|
|
|
WORD versionRequested = MAKEWORD(1, 1);
|