Add inet_pton for Windows XP support
This commit is contained in:
parent
c1a28c6459
commit
8e64433c3a
@ -24,13 +24,6 @@
|
|||||||
# include <winsock2.h>
|
# include <winsock2.h>
|
||||||
# include <ws2tcpip.h>
|
# include <ws2tcpip.h>
|
||||||
|
|
||||||
extern "C"
|
|
||||||
{
|
|
||||||
#ifndef InetPtopN
|
|
||||||
WINSOCK_API_LINKAGE INT WSAAPI inet_pton(INT Family, PCSTR pszAddrString, PVOID pAddrBuf);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
#else
|
#else
|
||||||
# include <winsock2.h>
|
# include <winsock2.h>
|
||||||
# include <in6addr.h>
|
# include <in6addr.h>
|
||||||
@ -52,6 +45,157 @@ extern "C"
|
|||||||
#include <array>
|
#include <array>
|
||||||
#include <string>
|
#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
|
// Android STK seems to crash when using inet_ntop so we copy it from linux
|
||||||
static const char *
|
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)
|
extern "C" int64_t upperIPv6(const char* ipv6)
|
||||||
{
|
{
|
||||||
struct in6_addr v6_in;
|
struct in6_addr v6_in;
|
||||||
if (inet_pton(AF_INET6, ipv6, &v6_in) != 1)
|
if (stk_inet_pton6(ipv6, &v6_in) != 1)
|
||||||
return 0;
|
return 0;
|
||||||
uint64_t result = 0;
|
uint64_t result = 0;
|
||||||
unsigned shift = 56;
|
unsigned shift = 56;
|
||||||
@ -303,13 +447,13 @@ extern "C" int insideIPv6CIDR(const char* ipv6_cidr, const char* ipv6_in)
|
|||||||
if (mask_location == NULL)
|
if (mask_location == NULL)
|
||||||
return 0;
|
return 0;
|
||||||
struct in6_addr v6_in;
|
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;
|
return 0;
|
||||||
|
|
||||||
char ipv6[INET6_ADDRSTRLEN] = {};
|
char ipv6[INET6_ADDRSTRLEN] = {};
|
||||||
memcpy(ipv6, ipv6_cidr, mask_location - ipv6_cidr);
|
memcpy(ipv6, ipv6_cidr, mask_location - ipv6_cidr);
|
||||||
struct in6_addr cidr;
|
struct in6_addr cidr;
|
||||||
if (inet_pton(AF_INET6, ipv6, &cidr) != 1)
|
if (stk_inet_pton6(ipv6, &cidr) != 1)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
int mask_length = atoi(mask_location + 1);
|
int mask_length = atoi(mask_location + 1);
|
||||||
|
Loading…
Reference in New Issue
Block a user