summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSteven Barth2015-04-22 09:21:48 +0000
committerSteven Barth2015-04-22 09:21:48 +0000
commite318b03d19472d631dbdad46aaafee986801c15d (patch)
tree8f8bc9a6e997ceccec05822724a5c71d0af8ae08
parentc5f795cc38cd79e688bba70fe1fad9b460c4bca7 (diff)
parent94c5d19efaa9269f184619a54e616e663c3b20bc (diff)
downloadrouting-e318b03d19472d631dbdad46aaafee986801c15d.tar.gz
Merge pull request #91 from dedeckeh/master
nat46: Refuse link local address as implicit source in 464xlat
-rw-r--r--nat46/src/464xlatcfg.c40
1 files changed, 30 insertions, 10 deletions
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();