diff options
author | Stefan Metzmacher <metze@samba.org> | 2009-03-03 16:45:41 +0100 |
---|---|---|
committer | Stefan Metzmacher <metze@samba.org> | 2009-03-04 08:32:33 +0100 |
commit | 27cf23958b02b05becce6e7c68347f6fea5b7845 (patch) | |
tree | a280126f104c9eae26d6a58841656bc7abb9120e | |
parent | b99bb962aa70f8584212f18ba6368513e7485f5e (diff) | |
download | samba-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
-rw-r--r-- | lib/socket_wrapper/socket_wrapper.c | 49 |
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; |