From 94c5d19efaa9269f184619a54e616e663c3b20bc Mon Sep 17 00:00:00 2001 From: Hans Dedecker Date: Mon, 20 Apr 2015 18:26:20 +0200 Subject: [PATCH] nat46: Refuse link local address as implicit source in 464xlat Signed-off-by: Hans Dedecker --- nat46/Makefile | 2 +- nat46/src/464xlatcfg.c | 40 ++++++++++++++++++++++++++++++---------- 2 files changed, 31 insertions(+), 11 deletions(-) diff --git a/nat46/Makefile b/nat46/Makefile index 4cbc494..3fa8b32 100644 --- a/nat46/Makefile +++ b/nat46/Makefile @@ -9,7 +9,7 @@ include $(TOPDIR)/rules.mk include $(INCLUDE_DIR)/kernel.mk PKG_NAME:=nat46 -PKG_VERSION:=3 +PKG_VERSION:=4 PKG_RELEASE:=$(PKG_SOURCE_VERSION) PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz diff --git a/nat46/src/464xlatcfg.c b/nat46/src/464xlatcfg.c index 1d9466e..f184616 100644 --- a/nat46/src/464xlatcfg.c +++ b/nat46/src/464xlatcfg.c @@ -71,19 +71,39 @@ int main(int argc, const char *argv[]) freeaddrinfo(res); } - struct sockaddr_in6 saddr = {.sin6_family = AF_INET6, .sin6_addr = {{{0x20, 0x01, 0x0d, 0xb8}}}}; - socklen_t saddrlen = sizeof(saddr); - int sock = socket(AF_INET6, SOCK_RAW, IPPROTO_ICMPV6); - struct icmp6_filter filt; - ICMP6_FILTER_SETBLOCKALL(&filt); - setsockopt(sock, IPPROTO_ICMPV6, ICMP6_FILTER, &filt, sizeof(filt)); - setsockopt(sock, SOL_SOCKET, SO_BINDTODEVICE, argv[2], strlen(argv[2])); - if (connect(sock, (struct sockaddr*)&saddr, sizeof(saddr)) || - getsockname(sock, (struct sockaddr*)&saddr, &saddrlen)) - return 3; + int i = 0; + int sock; + struct sockaddr_in6 saddr; + + do { + socklen_t saddrlen = sizeof(saddr); + struct icmp6_filter filt; + + sock = socket(AF_INET6, SOCK_RAW, IPPROTO_ICMPV6); + ICMP6_FILTER_SETBLOCKALL(&filt); + setsockopt(sock, IPPROTO_ICMPV6, ICMP6_FILTER, &filt, sizeof(filt)); + setsockopt(sock, SOL_SOCKET, SO_BINDTODEVICE, argv[2], strlen(argv[2])); + memset(&saddr, 0, sizeof(saddr)); + saddr.sin6_family = AF_INET6; + saddr.sin6_addr.s6_addr32[0] = htonl(0x2001); + saddr.sin6_addr.s6_addr32[1] = htonl(0xdb8); + if (connect(sock, (struct sockaddr*)&saddr, sizeof(saddr)) || + getsockname(sock, (struct sockaddr*)&saddr, &saddrlen)) + return 3; + + if (!IN6_IS_ADDR_LINKLOCAL(&saddr.sin6_addr) || argv[5]) + break; + + close(sock); + sleep(3); + i++; + } while (i < 3); struct ipv6_mreq mreq = {saddr.sin6_addr, if_nametoindex(argv[2])}; if (!argv[5]) { + if (IN6_IS_ADDR_LINKLOCAL(&mreq.ipv6mr_multiaddr)) + return 5; + srandom(mreq.ipv6mr_multiaddr.s6_addr32[0] ^ mreq.ipv6mr_multiaddr.s6_addr32[1] ^ mreq.ipv6mr_multiaddr.s6_addr32[2] ^ mreq.ipv6mr_multiaddr.s6_addr32[3]); mreq.ipv6mr_multiaddr.s6_addr32[2] = random(); -- 2.30.2