Last active
June 20, 2018 21:30
-
-
Save pps83/96bbffef32fb73a538fc0faacff149d9 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#ifdef _WIN32 // inet_pton is available from Vista only (based on inet_pton.c from wireshark) | |
#define NS_INADDRSZ_ 4 | |
#define NS_IN6ADDRSZ_ 16 | |
#define NS_INT16SZ_ 2 | |
static int inet_pton4(const char *src, unsigned char *dst) | |
{ | |
char saw_digit = 0, octets = 0, ch; | |
unsigned char tmp[NS_INADDRSZ_], *tp = tmp; | |
*tp = 0; | |
while ((ch = *src++) != '\0') | |
{ | |
if (ch >= '0' && ch <= '9') | |
{ | |
unsigned n = *tp * 10 + (ch - '0'); | |
if (n > 255) | |
return 0; | |
*tp = (unsigned char)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; | |
} | |
static bool nextHex(unsigned int& val, char c) | |
{ | |
if (c <= '9') | |
{ | |
int ret = c - '0'; | |
if (ret >= 0) | |
{ | |
val = val * 16 + ret; | |
return true; | |
} | |
} | |
else if ((c | ' ') <= 'f') | |
{ | |
int ret = ((c | ' ') - 'a'); | |
if (ret >= 0) | |
{ | |
val = val * 16 + 10 + ret; | |
return true; | |
} | |
} | |
return false; | |
} | |
static int inet_pton6(const char* src, unsigned char* dst) | |
{ | |
unsigned char tmp[NS_IN6ADDRSZ_] = { 0 }, *tp = tmp, *endp = tp + NS_IN6ADDRSZ_, *colonp = NULL; | |
const char* curtok; | |
char ch, saw_xdigit; | |
unsigned int val; | |
// Leading :: requires some special handling. | |
if (*src == ':') | |
{ | |
if (*++src != ':') | |
return 0; | |
} | |
curtok = src; | |
saw_xdigit = 0; | |
val = 0; | |
while ((ch = *src++) != '\0') | |
{ | |
if (nextHex(val, ch)) | |
{ | |
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++ = (unsigned char)(val >> 8) & 0xff; | |
*tp++ = (unsigned char)val & 0xff; | |
saw_xdigit = 0; | |
val = 0; | |
continue; | |
} | |
if (ch == '.' && (tp + NS_INADDRSZ_) <= endp && inet_pton4(curtok, 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++ = (unsigned char)(val >> 8) & 0xff; | |
*tp++ = (unsigned char)val & 0xff; | |
} | |
if (colonp != NULL) | |
{ | |
const int n = (int)(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; | |
} | |
#define inet_pton inet_pton_ | |
int inet_pton_(int af, const char *src, void *dst) | |
{ | |
if (AF_INET == af) | |
return inet_pton4(src, (unsigned char*)dst); | |
else if (AF_INET6 == af) | |
return inet_pton6(src, (unsigned char*)dst); | |
else | |
{ | |
WSASetLastError(EAFNOSUPPORT); | |
return -1; | |
} | |
} | |
#endif |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment