summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorStefan Metzmacher <metze@samba.org>2009-03-03 16:45:41 +0100
committerStefan Metzmacher <metze@samba.org>2009-03-04 08:32:33 +0100
commit27cf23958b02b05becce6e7c68347f6fea5b7845 (patch)
treea280126f104c9eae26d6a58841656bc7abb9120e /lib
parentb99bb962aa70f8584212f18ba6368513e7485f5e (diff)
downloadsamba-27cf23958b02b05becce6e7c68347f6fea5b7845.tar.gz
samba-27cf23958b02b05becce6e7c68347f6fea5b7845.tar.bz2
samba-27cf23958b02b05becce6e7c68347f6fea5b7845.zip
socket_wrapper: add multiple interface support for ipv6
We use FD00::5357:5FXX in the same way we use 127.0.0.XX metze
Diffstat (limited to 'lib')
-rw-r--r--lib/socket_wrapper/socket_wrapper.c49
1 files changed, 39 insertions, 10 deletions
diff --git a/lib/socket_wrapper/socket_wrapper.c b/lib/socket_wrapper/socket_wrapper.c
index 9527bb5e0e..f9ef48e4d6 100644
--- a/lib/socket_wrapper/socket_wrapper.c
+++ b/lib/socket_wrapper/socket_wrapper.c
@@ -145,7 +145,16 @@
#define MAX_WRAPPED_INTERFACES 16
-#define SW_IPV6_ADDRESS 1
+#ifdef HAVE_IPV6
+/*
+ * 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
+} } };
+#endif
static struct sockaddr *sockaddr_dup(const void *data, socklen_t len)
{
@@ -295,7 +304,8 @@ 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.s6_addr[0] = SW_IPV6_ADDRESS;
+ in2->sin6_addr = swrap_ipv6;
+ in2->sin6_addr.s6_addr[15] = iface;
in2->sin6_port = htons(prt);
*len = sizeof(*in2);
@@ -367,6 +377,7 @@ static int convert_in_un_remote(struct socket_info *si, const struct sockaddr *i
case AF_INET6: {
const struct sockaddr_in6 *in =
(const struct sockaddr_in6 *)inaddr;
+ struct in6_addr cmp;
switch (si->type) {
case SOCK_STREAM:
@@ -380,8 +391,16 @@ static int convert_in_un_remote(struct socket_info *si, const struct sockaddr *i
/* XXX no multicast/broadcast */
prt = ntohs(in->sin6_port);
- iface = SW_IPV6_ADDRESS;
-
+
+ cmp = in->sin6_addr;
+ cmp.s6_addr[15] = 0;
+ if (IN6_ARE_ADDR_EQUAL(&swrap_ipv6, &cmp)) {
+ iface = in->sin6_addr.s6_addr[15];
+ } else {
+ errno = ENETUNREACH;
+ return -1;
+ }
+
break;
}
#endif
@@ -474,6 +493,7 @@ static int convert_in_un_alloc(struct socket_info *si, const struct sockaddr *in
case AF_INET6: {
const struct sockaddr_in6 *in =
(const struct sockaddr_in6 *)inaddr;
+ struct in6_addr cmp;
switch (si->type) {
case SOCK_STREAM:
@@ -487,13 +507,21 @@ static int convert_in_un_alloc(struct socket_info *si, const struct sockaddr *in
/* XXX no multicast/broadcast */
prt = ntohs(in->sin6_port);
- iface = SW_IPV6_ADDRESS;
-
+
+ cmp = in->sin6_addr;
+ cmp.s6_addr[15] = 0;
+ if (IN6_ARE_ADDR_EQUAL(&swrap_ipv6, &cmp)) {
+ iface = in->sin6_addr.s6_addr[15];
+ } else {
+ errno = EADDRNOTAVAIL;
+ return -1;
+ }
+
break;
}
#endif
default:
- errno = ENETUNREACH;
+ errno = EADDRNOTAVAIL;
return -1;
}
@@ -1560,13 +1588,14 @@ static int swrap_auto_bind(struct socket_info *si)
type = SOCKET_TYPE_CHAR_UDP_V6;
break;
default:
- errno = ESOCKTNOSUPPORT;
- return -1;
+ errno = ESOCKTNOSUPPORT;
+ return -1;
}
memset(&in6, 0, sizeof(in6));
in6.sin6_family = AF_INET6;
- in6.sin6_addr.s6_addr[0] = SW_IPV6_ADDRESS;
+ 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);
break;