Handle sockaddr_in.sin_len and sockaddr_in6.sin6_len

Check sockaddr_in.sin_len and sockaddr_in6.sin6_len are available and
assign values to them properly.  This change fixes unit test error and
most error related to getnameinfo() on netbsd.
pull/20/head
Tatsuhiro Tsujikawa 2012-05-16 22:43:25 +09:00
parent 448f03fa7e
commit 36051cca5e
2 changed files with 37 additions and 19 deletions

View File

@ -541,7 +541,21 @@ AC_CHECK_MEMBER([struct sockaddr_in.sin_len],
[AC_DEFINE([HAVE_SOCKADDR_IN_SIN_LEN],[1], [AC_DEFINE([HAVE_SOCKADDR_IN_SIN_LEN],[1],
[Define to 1 if struct sockaddr_in has sin_len member.])], [Define to 1 if struct sockaddr_in has sin_len member.])],
[], [],
[[#include <netinet/in.h>]]) [[
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
]])
AC_CHECK_MEMBER([struct sockaddr_in6.sin6_len],
[AC_DEFINE([HAVE_SOCKADDR_IN6_SIN6_LEN],[1],
[Define to 1 if struct sockaddr_in6 has sin6_len member.])],
[],
[[
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
]])
# Check struct option.name is assignable from const char*. struct # Check struct option.name is assignable from const char*. struct
# option.name in opensolaris is of type char*. In Linux, it is const # option.name in opensolaris is of type char*. In Linux, it is const

View File

@ -1282,19 +1282,23 @@ int callGetaddrinfo
int inetNtop(int af, const void* src, char* dst, socklen_t size) int inetNtop(int af, const void* src, char* dst, socklen_t size)
{ {
int s; int s;
sockaddr_union su;
memset(&su, 0, sizeof(su));
if(af == AF_INET) { if(af == AF_INET) {
sockaddr_in sa; su.in.sin_family = AF_INET;
memset(&sa, 0, sizeof(sa)); #ifdef HAVE_SOCKADDR_IN_SIN_LEN
sa.sin_family = AF_INET; su.in.sin_len = sizeof(su.in);
memcpy(&sa.sin_addr, src, sizeof(in_addr)); #endif // HAVE_SOCKADDR_IN_SIN_LEN
s = getnameinfo(reinterpret_cast<const sockaddr*>(&sa), sizeof(sa), memcpy(&su.in.sin_addr, src, sizeof(su.in.sin_addr));
s = getnameinfo(&su.sa, sizeof(su.in),
dst, size, 0, 0, NI_NUMERICHOST); dst, size, 0, 0, NI_NUMERICHOST);
} else if(af == AF_INET6) { } else if(af == AF_INET6) {
sockaddr_in6 sa; su.in6.sin6_family = AF_INET6;
memset(&sa, 0, sizeof(sa)); #ifdef HAVE_SOCKADDR_IN6_SIN6_LEN
sa.sin6_family = AF_INET6; su.in6.sin6_len = sizeof(su.in6);
memcpy(&sa.sin6_addr, src, sizeof(in6_addr)); #endif // HAVE_SOCKADDR_IN6_SIN6_LEN
s = getnameinfo(reinterpret_cast<const sockaddr*>(&sa), sizeof(sa), memcpy(&su.in6.sin6_addr, src, sizeof(su.in6.sin6_addr));
s = getnameinfo(&su.sa, sizeof(su.in6),
dst, size, 0, 0, NI_NUMERICHOST); dst, size, 0, 0, NI_NUMERICHOST);
} else { } else {
s = EAI_FAMILY; s = EAI_FAMILY;
@ -1339,16 +1343,16 @@ size_t getBinAddr(void* dest, const std::string& ip)
} }
WSAAPI_AUTO_DELETE<addrinfo*> resDeleter(res, freeaddrinfo); WSAAPI_AUTO_DELETE<addrinfo*> resDeleter(res, freeaddrinfo);
for(addrinfo* rp = res; rp; rp = rp->ai_next) { for(addrinfo* rp = res; rp; rp = rp->ai_next) {
sockaddr_union su;
memcpy(&su, rp->ai_addr, rp->ai_addrlen);
if(rp->ai_family == AF_INET) { if(rp->ai_family == AF_INET) {
sockaddr_in* addr = &reinterpret_cast<sockaddr_union*>(rp->ai_addr)->in; len = sizeof(in_addr);
len = 4; memcpy(dest, &(su.in.sin_addr), len);
memcpy(dest, &(addr->sin_addr), len); break;
return len;
} else if(rp->ai_family == AF_INET6) { } else if(rp->ai_family == AF_INET6) {
sockaddr_in6* addr = &reinterpret_cast<sockaddr_union*>(rp->ai_addr)->in6; len = sizeof(in6_addr);
len = 16; memcpy(dest, &(su.in6.sin6_addr), len);
memcpy(dest, &(addr->sin6_addr), len); break;
return len;
} }
} }
return len; return len;