ICMPv6: Send router advertisement from own link-local address
I'm not quite sure how I ended up doing this, but for some strange
reason the code before this commit is sending the ICMPv6 Router
Advertisements from some weird non-standard source address. This is
a violation of RFC4861 which clearly states that the source address
of router advertisements "MUST be the link-local address assigned to the
interface from which this message is sent."
Change-Id: Ib444af70fc8f0b433d371281601fd5a37b29039e
diff --git a/lib/tun.c b/lib/tun.c
index 76ac379..32a8d2d 100644
--- a/lib/tun.c
+++ b/lib/tun.c
@@ -748,3 +748,35 @@
}
return 0;
}
+
+#include <ifaddrs.h>
+
+/* obtain the link-local address of the tun device */
+int tun_ipv6_linklocal_get(const struct tun_t *tun, struct in6_addr *ia)
+{
+ struct ifaddrs *ifaddr, *ifa;
+ static const uint8_t ll_prefix[] = { 0xfe,0x80, 0,0, 0,0, 0,0 };
+
+ if (getifaddrs(&ifaddr) == -1) {
+ return -1;
+ }
+
+ for (ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next) {
+ struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *) ifa->ifa_addr;
+ if (ifa->ifa_addr == NULL)
+ continue;
+
+ if (ifa->ifa_addr->sa_family != AF_INET6)
+ continue;
+
+ if (strcmp(ifa->ifa_name, tun->devname))
+ continue;
+
+ if (memcmp(sin6->sin6_addr.s6_addr, ll_prefix, sizeof(ll_prefix)))
+ continue;
+
+ *ia = sin6->sin6_addr;
+ return 0;
+ }
+ return -1;
+}
diff --git a/lib/tun.h b/lib/tun.h
index 50ac806..95fff26 100644
--- a/lib/tun.h
+++ b/lib/tun.h
@@ -85,4 +85,6 @@
extern int tun_runscript(struct tun_t *tun, char *script);
+int tun_ipv6_linklocal_get(const struct tun_t *tun, struct in6_addr *ia);
+
#endif /* !_TUN_H */