summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStefan Metzmacher <metze@samba.org>2009-03-09 09:24:45 +0100
committerStefan Metzmacher <metze@samba.org>2009-03-09 10:21:30 +0100
commit5ff4cb580f5892754a208684dba6fef4834d6e7f (patch)
treebdcdf067e15deaceaf7215b5b4c3f8808ac02e07
parent3679e8243459f928b1a4d0998d47c6efdedd0301 (diff)
downloadsamba-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.c31
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);