Created
October 29, 2015 03:57
-
-
Save fangdingjun/006fca8f6680d1166f1e to your computer and use it in GitHub Desktop.
inet_pton, inet_ntop implements for windowns
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 | |
#include <winsock2.h> | |
#include <Ws2tcpip.h> | |
#include <string.h> | |
#include <stdint.h> | |
#include <stdio.h> | |
int inet_pton4(const char *src, char *dst); | |
int inet_pton6(const char *src, char *dst); | |
int inet_pton(int af, const char *src, char *dst) | |
{ | |
switch (af) | |
{ | |
case AF_INET: | |
return inet_pton4(src, dst); | |
case AF_INET6: | |
return inet_pton6(src, dst); | |
default: | |
return -1; | |
} | |
} | |
#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; | |
} | |
const char* inet_ntop(int af, const void* src, char* dst, int cnt){ | |
struct sockaddr_in srcaddr; | |
memset(&srcaddr, 0, sizeof(struct sockaddr_in)); | |
memcpy(&(srcaddr.sin_addr), src, sizeof(srcaddr.sin_addr)); | |
srcaddr.sin_family = af; | |
if (WSAAddressToString((struct sockaddr*) &srcaddr, sizeof(struct sockaddr_in), 0, dst, (LPDWORD) &cnt) != 0) { | |
DWORD rv = WSAGetLastError(); | |
printf("WSAAddressToString() : %d\n",rv); | |
return NULL; | |
} | |
return dst; | |
} | |
#endif |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment