diff options
author | Stefan Metzmacher <metze@samba.org> | 2009-03-09 09:24:45 +0100 |
---|---|---|
committer | Stefan Metzmacher <metze@samba.org> | 2009-03-09 10:21:30 +0100 |
commit | 5ff4cb580f5892754a208684dba6fef4834d6e7f (patch) | |
tree | bdcdf067e15deaceaf7215b5b4c3f8808ac02e07 | |
parent | 3679e8243459f928b1a4d0998d47c6efdedd0301 (diff) | |
download | samba-5ff4cb580f5892754a208684dba6fef4834d6e7f.tar.gz samba-5ff4cb580f5892754a208684dba6fef4834d6e7f.tar.bz2 samba-5ff4cb580f5892754a208684dba6fef4834d6e7f.zip |
socket_wrapper: try to make ipv6 support more portable
The internal structure of in6_addr isn't always the same.
metze
-rw-r--r-- | lib/socket_wrapper/socket_wrapper.c | 31 |
1 files changed, 22 insertions, 9 deletions
diff --git a/lib/socket_wrapper/socket_wrapper.c b/lib/socket_wrapper/socket_wrapper.c index 733a33217c..97e60468c4 100644 --- a/lib/socket_wrapper/socket_wrapper.c +++ b/lib/socket_wrapper/socket_wrapper.c @@ -149,11 +149,24 @@ /* * FD00::5357:5FXX */ -static const struct in6_addr swrap_ipv6 = -{ { { -0xFD,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x53,0x57,0x5F,0x00 -} } }; +static const struct in6_addr *swrap_ipv6(void) +{ + static struct in6_addr v; + static int initialized; + int ret; + + if (initialized) { + return &v; + } + initialized = 1; + + ret = inet_pton(AF_INET6, "FD00::5357:5F00", &v); + if (ret <= 0) { + abort(); + } + + return &v; +} #endif static struct sockaddr *sockaddr_dup(const void *data, socklen_t len) @@ -305,7 +318,7 @@ static int convert_un_in(const struct sockaddr_un *un, struct sockaddr *in, sock memset(in2, 0, sizeof(*in2)); in2->sin6_family = AF_INET6; - in2->sin6_addr = swrap_ipv6; + in2->sin6_addr = *swrap_ipv6(); in2->sin6_addr.s6_addr[15] = iface; in2->sin6_port = htons(prt); @@ -395,7 +408,7 @@ static int convert_in_un_remote(struct socket_info *si, const struct sockaddr *i cmp = in->sin6_addr; cmp.s6_addr[15] = 0; - if (IN6_ARE_ADDR_EQUAL(&swrap_ipv6, &cmp)) { + if (IN6_ARE_ADDR_EQUAL(swrap_ipv6(), &cmp)) { iface = in->sin6_addr.s6_addr[15]; } else { errno = ENETUNREACH; @@ -513,7 +526,7 @@ static int convert_in_un_alloc(struct socket_info *si, const struct sockaddr *in cmp.s6_addr[15] = 0; if (IN6_IS_ADDR_UNSPECIFIED(&in->sin6_addr)) { iface = socket_wrapper_default_iface(); - } else if (IN6_ARE_ADDR_EQUAL(&swrap_ipv6, &cmp)) { + } else if (IN6_ARE_ADDR_EQUAL(swrap_ipv6(), &cmp)) { iface = in->sin6_addr.s6_addr[15]; } else { errno = EADDRNOTAVAIL; @@ -1605,7 +1618,7 @@ static int swrap_auto_bind(struct socket_info *si, int family) memset(&in6, 0, sizeof(in6)); in6.sin6_family = AF_INET6; - in6.sin6_addr = swrap_ipv6; + in6.sin6_addr = *swrap_ipv6(); in6.sin6_addr.s6_addr[15] = socket_wrapper_default_iface(); si->myname_len = sizeof(in6); si->myname = sockaddr_dup(&in6, si->myname_len); |