From 3d3bcb6f4c0fab6298a5799ac9ab893c6f64fb15 Mon Sep 17 00:00:00 2001 From: shefty Date: Thu, 23 Apr 2009 20:01:10 +0000 Subject: [PATCH] etc/inet: add inet_ntop implementation Someday windows will decide to support networking... sigh... Signed-off-by: Sean Hefty git-svn-id: svn://openib.tc.cornell.edu/gen1@2131 ad392aa1-c5ef-ae45-8dd8-e69d62a5ef86 --- trunk/etc/user/inet.c | 62 ++++++++++++++++++++++++++++++-- trunk/inc/user/linux/arpa/inet.h | 9 +++++ 2 files changed, 69 insertions(+), 2 deletions(-) diff --git a/trunk/etc/user/inet.c b/trunk/etc/user/inet.c index 28e3d5bd..47ff212c 100644 --- a/trunk/etc/user/inet.c +++ b/trunk/etc/user/inet.c @@ -32,6 +32,8 @@ */ #include +#include +#include static int inet_pton4(const char *src, struct in_addr *addr) { @@ -149,10 +151,66 @@ int inet_pton(int af, const char *src, void *dst) { switch (af) { case AF_INET: - return inet_pton4(src, dst); + return inet_pton4(src, (struct in_addr *) dst); case AF_INET6: - return inet_pton6(src, dst); + return inet_pton6(src, (struct in6_addr *) dst); default: return -1; } } + +static const char *inet_ntop4(const void *src, char *dst, socklen_t cnt) +{ + struct sockaddr_in in; + + in.sin_family = AF_INET; + memcpy(&in.sin_addr, src, 4); + if (getnameinfo((struct sockaddr *) &in, + (socklen_t) sizeof(struct sockaddr_in), + dst, cnt, NULL, 0, NI_NUMERICHOST)) + return NULL; + + return dst; +} + +static const char *inet_ntop6(const void *src, char *dst, socklen_t cnt) +{ + struct sockaddr_in6 in6; + char tmp[sizeof "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"]; + int i, n = 0; + + memset(&in6, 0, sizeof in6); + in6.sin6_family = AF_INET6; + memcpy(&in6.sin6_addr, src, sizeof(struct in_addr6)); + + /* + * If no ipv6 support return simple IPv6 format rule: + * A series of "0's in a 16bit block can be represented by "0" + */ + if (getnameinfo((struct sockaddr *) &in6, (socklen_t) (sizeof in6), + dst, cnt, NULL, 0, NI_NUMERICHOST)) + { + + if (cnt < sizeof(tmp)) + return NULL; + + for (i = 0; i < 8; i++) + n += sprintf(tmp+n, "%s%x", i ? ":" : "", + ntohs(((unsigned short*) src)[i])); + tmp[n] = '\0'; + strcpy(dst, tmp); + } + return dst; +} + +const char *inet_ntop(int af, const void *src, char *dst, socklen_t cnt) +{ + switch (af) { + case AF_INET: + return inet_ntop4(src, dst, cnt); + case AF_INET6: + return inet_ntop6(src, dst, cnt); + default: + return NULL; + } +} diff --git a/trunk/inc/user/linux/arpa/inet.h b/trunk/inc/user/linux/arpa/inet.h index 2c7b53c3..18c13a06 100644 --- a/trunk/inc/user/linux/arpa/inet.h +++ b/trunk/inc/user/linux/arpa/inet.h @@ -36,8 +36,17 @@ #include +#ifdef __cplusplus +extern "C" { +#endif + #if WINVER < 0x600 int inet_pton(int af, const char *src, void *dst); +const char *inet_ntop(int af, const void *src, char *dst, socklen_t cnt); +#endif + +#ifdef __cplusplus +} #endif #endif /* _INET_H_ */ -- 2.46.0