diff options
author | Oto Šťáva <oto.stava@nic.cz> | 2022-01-27 15:19:02 +0100 |
---|---|---|
committer | Oto Šťáva <oto.stava@nic.cz> | 2022-01-31 09:15:12 +0100 |
commit | d6cfa7f62020ad6b3d43fa811b703603b40346c5 (patch) | |
tree | 506beb8188d627abb50cc40e428cef48b9e601cd /daemon/bindings | |
parent | Merge branch 'update-tests' into 'master' (diff) | |
download | knot-resolver-d6cfa7f62020ad6b3d43fa811b703603b40346c5.tar.xz knot-resolver-d6cfa7f62020ad6b3d43fa811b703603b40346c5.zip |
daemon/bindings/net: add interface name to link-local IPv6 addresses
Diffstat (limited to 'daemon/bindings')
-rw-r--r-- | daemon/bindings/net.c | 25 |
1 files changed, 24 insertions, 1 deletions
diff --git a/daemon/bindings/net.c b/daemon/bindings/net.c index ec9c822c..ff6a6c37 100644 --- a/daemon/bindings/net.c +++ b/daemon/bindings/net.c @@ -5,6 +5,7 @@ #include "daemon/bindings/impl.h" #include "contrib/base64.h" +#include "contrib/cleanup.h" #include "daemon/network.h" #include "daemon/tls.h" @@ -303,6 +304,18 @@ static int net_close(lua_State *L) return 1; } +/** Check whether `addr` points to an `AF_INET6` address and whether the address + * is link-local. */ +static bool ip6_link_local(struct sockaddr_in6 *addr) +{ + if (addr->sin6_family != AF_INET6) + return false; + + /* Link-local: https://tools.ietf.org/html/rfc4291#section-2.4 */ + const uint8_t prefix[] = { 0xFE, 0x80 }; + return kr_bitcmp((char *) addr->sin6_addr.s6_addr, (char *) prefix, 10) == 0; +} + /** List available interfaces. */ static int net_interfaces(lua_State *L) { @@ -333,7 +346,17 @@ static int net_interfaces(lua_State *L) } else { buf[0] = '\0'; } - lua_pushstring(L, buf); + + if (ip6_link_local(&iface.address.address6)) { + /* Link-local IPv6: add %interface prefix */ + auto_free char *str = NULL; + int ret = asprintf(&str, "%s%%%s", buf, iface.name); + kr_assert(ret > 0); + lua_pushstring(L, str); + } else { + lua_pushstring(L, buf); + } + lua_rawseti(L, -2, lua_objlen(L, -2) + 1); lua_setfield(L, -2, "addr"); |