From 314b92c0e37c6896ecabc391a4e1594fc86c2fdb Mon Sep 17 00:00:00 2001 From: dec05eba Date: Sun, 28 Oct 2018 02:15:56 +0200 Subject: Fix build for mingw --- src/IpAddress.cpp | 172 +++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 170 insertions(+), 2 deletions(-) (limited to 'src/IpAddress.cpp') diff --git a/src/IpAddress.cpp b/src/IpAddress.cpp index 58ed661..75e4348 100644 --- a/src/IpAddress.cpp +++ b/src/IpAddress.cpp @@ -1,6 +1,171 @@ #include "../include/sibs/IpAddress.hpp" #include +#if OS_FAMILY == OS_FAMILY_WINDOWS +// Source: https://stackoverflow.com/questions/15370033/how-to-use-inet-pton-with-the-mingw-compiler +#define NS_INADDRSZ 4 +#define NS_IN6ADDRSZ 16 +#define NS_INT16SZ 2 + +int inet_pton(int af, const char *src, void *dst) +{ + switch (af) + { + case AF_INET: + return inet_pton4(src, dst); + case AF_INET6: + return inet_pton6(src, dst); + default: + return -1; + } +} + +int inet_pton4(const char *src, void *_dst) +{ + char *dst = (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, void *_dst) +{ + char *dst = (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; +} +#endif + namespace sibs { Ipv4::Ipv4() : Ipv4(nullptr, 0) @@ -44,8 +209,11 @@ namespace sibs std::string Ipv4::getAddress() const { std::string result; - result.resize(INET_ADDRSTRLEN); - inet_ntop(AF_INET, &address.sin_addr, &result[0], INET_ADDRSTRLEN); + const int addrLen = sizeof(address); + char host[NI_MAXHOST]; + char service[NI_MAXSERV]; + getnameinfo((sockaddr *)&address, addrLen, host, sizeof(host), service, sizeof(service), NI_NUMERICHOST | NI_NUMERICSERV); + result += host; return result; } -- cgit v1.2.3