Add inet_pton for Windows XP support
This commit is contained in:
parent
c1a28c6459
commit
8e64433c3a
@ -24,13 +24,6 @@
|
||||
# include <winsock2.h>
|
||||
# include <ws2tcpip.h>
|
||||
|
||||
extern "C"
|
||||
{
|
||||
#ifndef InetPtopN
|
||||
WINSOCK_API_LINKAGE INT WSAAPI inet_pton(INT Family, PCSTR pszAddrString, PVOID pAddrBuf);
|
||||
#endif
|
||||
}
|
||||
|
||||
#else
|
||||
# include <winsock2.h>
|
||||
# include <in6addr.h>
|
||||
@ -52,6 +45,157 @@ extern "C"
|
||||
#include <array>
|
||||
#include <string>
|
||||
|
||||
// ============================================================================
|
||||
// For Windows XP support
|
||||
#define IN6ADDRSZ 16
|
||||
#define INADDRSZ 4
|
||||
#define INT16SZ 2
|
||||
|
||||
static int
|
||||
stk_inet_pton4(const char *src, unsigned char *dst)
|
||||
{
|
||||
static const char digits[] = "0123456789";
|
||||
int saw_digit, octets, ch;
|
||||
unsigned char tmp[INADDRSZ], *tp;
|
||||
|
||||
saw_digit = 0;
|
||||
octets = 0;
|
||||
tp = tmp;
|
||||
*tp = 0;
|
||||
while((ch = *src++) != '\0')
|
||||
{
|
||||
const char *pch;
|
||||
|
||||
pch = strchr(digits, ch);
|
||||
if(pch)
|
||||
{
|
||||
unsigned int val = *tp * 10 + (unsigned int)(pch - digits);
|
||||
|
||||
if(saw_digit && *tp == 0)
|
||||
return (0);
|
||||
if(val > 255)
|
||||
return (0);
|
||||
*tp = (unsigned char)val;
|
||||
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, INADDRSZ);
|
||||
return (1);
|
||||
}
|
||||
|
||||
static int
|
||||
stk_inet_pton6(const char *src, void *dest)
|
||||
{
|
||||
unsigned char *dst = (unsigned char*)dest;
|
||||
static const char xdigits_l[] = "0123456789abcdef",
|
||||
xdigits_u[] = "0123456789ABCDEF";
|
||||
unsigned char tmp[IN6ADDRSZ], *tp, *endp, *colonp;
|
||||
const char *curtok;
|
||||
int ch, saw_xdigit;
|
||||
size_t val;
|
||||
|
||||
memset((tp = tmp), 0, IN6ADDRSZ);
|
||||
endp = tp + IN6ADDRSZ;
|
||||
colonp = NULL;
|
||||
/* Leading :: requires some special handling. */
|
||||
if(*src == ':')
|
||||
{
|
||||
if(*++src != ':')
|
||||
return (0);
|
||||
}
|
||||
curtok = src;
|
||||
saw_xdigit = 0;
|
||||
val = 0;
|
||||
while((ch = *src++) != '\0')
|
||||
{
|
||||
const char *xdigits;
|
||||
const char *pch;
|
||||
|
||||
pch = strchr((xdigits = xdigits_l), ch);
|
||||
if(!pch)
|
||||
pch = strchr((xdigits = xdigits_u), ch);
|
||||
if(pch != NULL)
|
||||
{
|
||||
val <<= 4;
|
||||
val |= (pch - xdigits);
|
||||
if(++saw_xdigit > 4)
|
||||
return (0);
|
||||
continue;
|
||||
}
|
||||
if(ch == ':')
|
||||
{
|
||||
curtok = src;
|
||||
if(!saw_xdigit)
|
||||
{
|
||||
if(colonp)
|
||||
return (0);
|
||||
colonp = tp;
|
||||
continue;
|
||||
}
|
||||
if(tp + INT16SZ > endp)
|
||||
return (0);
|
||||
*tp++ = (unsigned char) ((val >> 8) & 0xff);
|
||||
*tp++ = (unsigned char) (val & 0xff);
|
||||
saw_xdigit = 0;
|
||||
val = 0;
|
||||
continue;
|
||||
}
|
||||
if(ch == '.' && ((tp + INADDRSZ) <= endp) &&
|
||||
stk_inet_pton4(curtok, tp) > 0)
|
||||
{
|
||||
tp += INADDRSZ;
|
||||
saw_xdigit = 0;
|
||||
break; /* '\0' was seen by stk_inet_pton4(). */
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
if(saw_xdigit)
|
||||
{
|
||||
if(tp + INT16SZ > endp)
|
||||
return (0);
|
||||
*tp++ = (unsigned char) ((val >> 8) & 0xff);
|
||||
*tp++ = (unsigned char) (val & 0xff);
|
||||
}
|
||||
if(colonp != NULL)
|
||||
{
|
||||
/*
|
||||
* Since some memmove()'s erroneously fail to handle
|
||||
* overlapping regions, we'll do the shift by hand.
|
||||
*/
|
||||
const ssize_t n = tp - colonp;
|
||||
ssize_t i;
|
||||
|
||||
if(tp == endp)
|
||||
return (0);
|
||||
for(i = 1; i <= n; i++)
|
||||
{
|
||||
*(endp - i) = *(colonp + n - i);
|
||||
*(colonp + n - i) = 0;
|
||||
}
|
||||
tp = endp;
|
||||
}
|
||||
if(tp != endp)
|
||||
return (0);
|
||||
memcpy(dst, tmp, IN6ADDRSZ);
|
||||
return (1);
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// Android STK seems to crash when using inet_ntop so we copy it from linux
|
||||
static const char *
|
||||
@ -283,7 +427,7 @@ void andIPv6(struct in6_addr* ipv6, const struct in6_addr* mask)
|
||||
extern "C" int64_t upperIPv6(const char* ipv6)
|
||||
{
|
||||
struct in6_addr v6_in;
|
||||
if (inet_pton(AF_INET6, ipv6, &v6_in) != 1)
|
||||
if (stk_inet_pton6(ipv6, &v6_in) != 1)
|
||||
return 0;
|
||||
uint64_t result = 0;
|
||||
unsigned shift = 56;
|
||||
@ -303,13 +447,13 @@ extern "C" int insideIPv6CIDR(const char* ipv6_cidr, const char* ipv6_in)
|
||||
if (mask_location == NULL)
|
||||
return 0;
|
||||
struct in6_addr v6_in;
|
||||
if (inet_pton(AF_INET6, ipv6_in, &v6_in) != 1)
|
||||
if (stk_inet_pton6(ipv6_in, &v6_in) != 1)
|
||||
return 0;
|
||||
|
||||
char ipv6[INET6_ADDRSTRLEN] = {};
|
||||
memcpy(ipv6, ipv6_cidr, mask_location - ipv6_cidr);
|
||||
struct in6_addr cidr;
|
||||
if (inet_pton(AF_INET6, ipv6, &cidr) != 1)
|
||||
if (stk_inet_pton6(ipv6, &cidr) != 1)
|
||||
return 0;
|
||||
|
||||
int mask_length = atoi(mask_location + 1);
|
||||
|
Loading…
Reference in New Issue
Block a user