Bug 168228: added IPv6 support for Darwin (Mac OS X). Added two new
feature macros _PR_HAVE_INET_NTOP and _PR_GHBA_DISALLOW_V4MAPPED to handle the differences of Darwin's IPv6 sockets implementation and other platforms' implementations. Modified files: _aix.h _bsdi.h _darwin.h _freebsd.h _irix.h _linux.h _netbsd.h _openvms.h _osf1.h _solaris.h prnetdb.c
This commit is contained in:
Родитель
226f1e0db0
Коммит
a693f5b3da
|
@ -72,6 +72,7 @@
|
|||
#define _PR_USE_POLL
|
||||
#define _PR_STAT_HAS_ONLY_ST_ATIME
|
||||
#ifdef _PR_INET6
|
||||
#define _PR_HAVE_INET_NTOP
|
||||
#define _PR_HAVE_GETHOSTBYNAME2
|
||||
#endif
|
||||
#define _PR_HAVE_SYSV_SEMAPHORES
|
||||
|
|
|
@ -66,6 +66,7 @@
|
|||
/* BSD/OS 4.3 and newer all have IPv6 support */
|
||||
#if _BSDI_VERSION >= 200105
|
||||
#define _PR_INET6
|
||||
#define _PR_HAVE_INET_NTOP
|
||||
#define _PR_HAVE_GETIPNODEBYNAME
|
||||
#define _PR_HAVE_GETIPNODEBYADDR
|
||||
#define _PR_INET6_PROBE
|
||||
|
|
|
@ -61,6 +61,27 @@
|
|||
#define _PR_NO_LARGE_FILES
|
||||
#define PR_HAVE_SYSV_NAMED_SHARED_MEMORY
|
||||
|
||||
#define _PR_INET6
|
||||
/*
|
||||
* I'd prefer to use getipnodebyname and getipnodebyaddr but the
|
||||
* getipnodebyname(3) man page on Mac OS X 10.2 says they are not
|
||||
* thread-safe. AI_V4MAPPED|AI_ADDRCONFIG doesn't work either.
|
||||
*/
|
||||
#define _PR_HAVE_GETHOSTBYNAME2
|
||||
/*
|
||||
* On Mac OS X 10.2, gethostbyaddr fails with h_errno=NO_RECOVERY
|
||||
* if you pass an IPv4-mapped IPv6 address to it.
|
||||
*/
|
||||
#define _PR_GHBA_DISALLOW_V4MAPPED
|
||||
/* socket(AF_INET6) fails with EPROTONOSUPPORT on Mac OS X 10.1. */
|
||||
#if MACOS_DEPLOYMENT_TARGET < 100200
|
||||
#define _PR_INET6_PROBE
|
||||
#endif
|
||||
/* Mac OS X 10.2 has inet_ntop and inet_pton. */
|
||||
#if MACOS_DEPLOYMENT_TARGET >= 100200
|
||||
#define _PR_HAVE_INET_NTOP
|
||||
#endif
|
||||
|
||||
#define USE_SETJMP
|
||||
|
||||
#if !defined(_PR_PTHREADS)
|
||||
|
|
|
@ -90,6 +90,7 @@
|
|||
|
||||
#if __FreeBSD_version >= 400014
|
||||
#define _PR_INET6
|
||||
#define _PR_HAVE_INET_NTOP
|
||||
#define _PR_HAVE_GETHOSTBYNAME2
|
||||
#define _PR_INET6_PROBE
|
||||
#endif
|
||||
|
|
|
@ -79,6 +79,7 @@
|
|||
#define _PR_ACCEPT_INHERIT_NONBLOCK
|
||||
|
||||
#ifdef _PR_INET6
|
||||
#define _PR_HAVE_INET_NTOP
|
||||
#define _PR_HAVE_GETIPNODEBYNAME
|
||||
#define _PR_HAVE_GETIPNODEBYADDR
|
||||
#endif
|
||||
|
|
|
@ -118,6 +118,7 @@ extern PRInt32 _PR_ia64_AtomicSet(PRInt32 *val, PRInt32 newval);
|
|||
#endif
|
||||
#if (__GLIBC__ > 2) || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 1)
|
||||
#define _PR_INET6
|
||||
#define _PR_HAVE_INET_NTOP
|
||||
#define _PR_HAVE_GETHOSTBYNAME2
|
||||
#define _PR_INET6_PROBE
|
||||
#endif
|
||||
|
|
|
@ -80,6 +80,7 @@
|
|||
|
||||
#if __NetBSD_Version__ >= 105000000
|
||||
#define _PR_INET6
|
||||
#define _PR_HAVE_INET_NTOP
|
||||
#define _PR_HAVE_GETHOSTBYNAME2
|
||||
#define _PR_INET6_PROBE
|
||||
#endif
|
||||
|
|
|
@ -106,7 +106,9 @@ struct ip_mreq {
|
|||
#define _PR_HAVE_GETIPNODEBYNAME
|
||||
#define _PR_HAVE_GETIPNODEBYADDR
|
||||
#define _PR_INET6_PROBE
|
||||
#ifndef _PR_INET6
|
||||
#ifdef _PR_INET6
|
||||
#define _PR_HAVE_INET_NTOP
|
||||
#else
|
||||
#define AF_INET6 26
|
||||
#define AI_V4MAPPED 0x00000010
|
||||
#define AI_ALL 0x00000008
|
||||
|
|
|
@ -72,7 +72,9 @@
|
|||
#define _PR_HAVE_GETIPNODEBYNAME
|
||||
#define _PR_HAVE_GETIPNODEBYADDR
|
||||
#define _PR_INET6_PROBE
|
||||
#ifndef _PR_INET6
|
||||
#ifdef _PR_INET6
|
||||
#define _PR_HAVE_INET_NTOP
|
||||
#else
|
||||
#define AF_INET6 26
|
||||
#define AI_V4MAPPED 0x00000010
|
||||
#define AI_ALL 0x00000008
|
||||
|
|
|
@ -111,7 +111,9 @@
|
|||
#define _PR_HAVE_GETIPNODEBYADDR
|
||||
#define _PR_INET6_PROBE
|
||||
#define _PR_ACCEPT_INHERIT_NONBLOCK
|
||||
#ifndef _PR_INET6
|
||||
#ifdef _PR_INET6
|
||||
#define _PR_HAVE_INET_NTOP
|
||||
#else
|
||||
#define AF_INET6 26
|
||||
#define AI_V4MAPPED 0x0001
|
||||
#define AI_ALL 0x0002
|
||||
|
|
|
@ -182,7 +182,10 @@ static PRBool _pr_have_inet6_if = PR_FALSE;
|
|||
|
||||
#undef DEBUG_QUERY_IFS
|
||||
|
||||
#if defined(AIX)
|
||||
#if defined(AIX) \
|
||||
|| (defined(DARWIN) && (!defined(HAVE_GETIFADDRS) \
|
||||
|| (defined(MACOS_DEPLOYMENT_TARGET) \
|
||||
&& MACOS_DEPLOYMENT_TARGET < 100200)))
|
||||
|
||||
/*
|
||||
* Use SIOCGIFCONF ioctl on platforms that don't have routing
|
||||
|
@ -288,7 +291,8 @@ _pr_QueryNetIfs(void)
|
|||
}
|
||||
} else if (sa->sa_family == AF_INET6) {
|
||||
struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *) sa;
|
||||
if (!IN6_IS_ADDR_LOOPBACK(&sin6->sin6_addr)) {
|
||||
if (!IN6_IS_ADDR_LOOPBACK(&sin6->sin6_addr)
|
||||
&& !IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)) {
|
||||
_pr_have_inet6_if = PR_TRUE;
|
||||
}
|
||||
}
|
||||
|
@ -315,6 +319,75 @@ _pr_QueryNetIfs(void)
|
|||
PR_Free(buf);
|
||||
}
|
||||
|
||||
#elif (defined(DARWIN) && defined(HAVE_GETIFADDRS))
|
||||
|
||||
/*
|
||||
* Use the BSD getifaddrs function.
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <ifaddrs.h>
|
||||
#include <netinet/in.h>
|
||||
|
||||
#ifdef DEBUG_QUERY_IFS
|
||||
static void
|
||||
_pr_PrintIfaddrs(struct ifaddrs *ifa)
|
||||
{
|
||||
struct sockaddr *sa;
|
||||
const char* family;
|
||||
void *addrp;
|
||||
char addrstr[64];
|
||||
|
||||
sa = ifa->ifa_addr;
|
||||
if (sa->sa_family == AF_INET) {
|
||||
struct sockaddr_in *sin = (struct sockaddr_in *)sa;
|
||||
family = "inet";
|
||||
addrp = &sin->sin_addr;
|
||||
} else if (sa->sa_family == AF_INET6) {
|
||||
struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)sa;
|
||||
family = "inet6";
|
||||
addrp = &sin6->sin6_addr;
|
||||
} else {
|
||||
return; /* skip if not AF_INET or AF_INET6 */
|
||||
}
|
||||
inet_ntop(sa->sa_family, addrp, addrstr, sizeof(addrstr));
|
||||
printf("%s: %s %s\n", ifa->ifa_name, family, addrstr);
|
||||
}
|
||||
#endif
|
||||
|
||||
static void
|
||||
_pr_QueryNetIfs(void)
|
||||
{
|
||||
struct ifaddrs *ifp;
|
||||
struct ifaddrs *ifa;
|
||||
|
||||
if (getifaddrs(&ifp) == -1) {
|
||||
return;
|
||||
}
|
||||
for (ifa = ifp; ifa; ifa = ifa->ifa_next) {
|
||||
struct sockaddr *sa;
|
||||
|
||||
#ifdef DEBUG_QUERY_IFS
|
||||
_pr_PrintIfaddrs(ifa);
|
||||
#endif
|
||||
sa = ifa->ifa_addr;
|
||||
if (sa->sa_family == AF_INET) {
|
||||
struct sockaddr_in *sin = (struct sockaddr_in *) sa;
|
||||
if (sin->sin_addr.s_addr != htonl(INADDR_LOOPBACK)) {
|
||||
_pr_have_inet_if = 1;
|
||||
}
|
||||
} else if (sa->sa_family == AF_INET6) {
|
||||
struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *) sa;
|
||||
if (!IN6_IS_ADDR_LOOPBACK(&sin6->sin6_addr)
|
||||
&& !IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)) {
|
||||
_pr_have_inet6_if = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
freeifaddrs(ifp);
|
||||
}
|
||||
|
||||
#else /* default */
|
||||
|
||||
/*
|
||||
|
@ -886,6 +959,10 @@ PR_IMPLEMENT(PRStatus) PR_GetHostByAddr(
|
|||
af = AF_INET6;
|
||||
#else
|
||||
af = AF_INET;
|
||||
#endif
|
||||
#if defined(_PR_GHBA_DISALLOW_V4MAPPED)
|
||||
if (_PR_IN6_IS_ADDR_V4MAPPED(&hostaddr->ipv6.ip))
|
||||
af = AF_INET;
|
||||
#endif
|
||||
}
|
||||
else
|
||||
|
@ -1370,7 +1447,7 @@ PR_IsNetAddrType(const PRNetAddr *addr, PRNetAddrValue val)
|
|||
return PR_FALSE;
|
||||
}
|
||||
|
||||
#ifndef _PR_INET6
|
||||
#ifndef _PR_HAVE_INET_NTOP
|
||||
#define XX 127
|
||||
static const unsigned char index_hex[256] = {
|
||||
XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX,
|
||||
|
@ -1610,14 +1687,14 @@ static const char *V6AddrToString(
|
|||
#undef STUFF
|
||||
}
|
||||
|
||||
#endif /* !_PR_INET6 */
|
||||
#endif /* !_PR_HAVE_INET_NTOP */
|
||||
|
||||
PR_IMPLEMENT(PRStatus) PR_StringToNetAddr(const char *string, PRNetAddr *addr)
|
||||
{
|
||||
PRStatus status = PR_SUCCESS;
|
||||
PRIntn rv;
|
||||
|
||||
#if defined(_PR_INET6)
|
||||
#if defined(_PR_HAVE_INET_NTOP)
|
||||
rv = inet_pton(AF_INET6, string, &addr->ipv6.ip);
|
||||
if (1 == rv)
|
||||
{
|
||||
|
@ -1640,7 +1717,7 @@ PR_IMPLEMENT(PRStatus) PR_StringToNetAddr(const char *string, PRNetAddr *addr)
|
|||
status = PR_FAILURE;
|
||||
}
|
||||
}
|
||||
#else /* _PR_INET6 */
|
||||
#else /* _PR_HAVE_INET_NTOP */
|
||||
rv = StringToV6Addr(string, &addr->ipv6.ip);
|
||||
if (1 == rv) {
|
||||
addr->raw.family = PR_AF_INET6;
|
||||
|
@ -1664,7 +1741,7 @@ PR_IMPLEMENT(PRStatus) PR_StringToNetAddr(const char *string, PRNetAddr *addr)
|
|||
PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
|
||||
status = PR_FAILURE;
|
||||
}
|
||||
#endif /* _PR_INET6 */
|
||||
#endif /* _PR_HAVE_INET_NTOP */
|
||||
|
||||
return status;
|
||||
}
|
||||
|
@ -1674,7 +1751,7 @@ PR_IMPLEMENT(PRStatus) PR_NetAddrToString(
|
|||
{
|
||||
if (PR_AF_INET6 == addr->raw.family)
|
||||
{
|
||||
#if defined(_PR_INET6)
|
||||
#if defined(_PR_HAVE_INET_NTOP)
|
||||
if (NULL == inet_ntop(AF_INET6, &addr->ipv6.ip, string, size))
|
||||
#else
|
||||
if (NULL == V6AddrToString(&addr->ipv6.ip, string, size))
|
||||
|
|
Загрузка…
Ссылка в новой задаче