Browse Source

Add ENET_MINGW_COMPAT

Alexander 3 years ago
parent
commit
2386793249
1 changed files with 182 additions and 0 deletions
  1. 182 0
      include/enet.h

+ 182 - 0
include/enet.h

@@ -4965,6 +4965,188 @@ extern "C" {
 
     #ifndef _WIN32
 
+        #if defined(__MINGW32__) && defined(ENET_MINGW_COMPAT)
+        // 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;
+        }
+
+        #define NS_INADDRSZ  4
+        #define NS_IN6ADDRSZ 16
+        #define NS_INT16SZ   2
+
+        int inet_pton4(const char *src, char *dst) {
+            uint8_t tmp[NS_INADDRSZ], *tp;
+
+            int saw_digit = 0;
+            int octets = 0;
+            *(tp = tmp) = 0;
+
+            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;
+        }
+
+        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;
+
+                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;
+        }
+
+
+        int inet_pton(int af, const char *src, struct in6_addr *dst) {
+            switch (af)
+            {
+            case AF_INET:
+                return inet_pton4(src, (char *)dst);
+            case AF_INET6:
+                return inet_pton6(src, (char *)dst);
+            default:
+                return -1;
+            }
+        }
+    #endif // __MINGW__
+    
     int enet_initialize(void) {
         return 0;
     }