From 4abab5ad6c8465a7528ccdd5f49367da05f78bbd Mon Sep 17 00:00:00 2001 From: Vladimir Azarov Date: Tue, 1 Oct 2024 15:47:05 +0200 Subject: Initial version --- src/network/lookup_ipliteral.c | 55 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) create mode 100644 src/network/lookup_ipliteral.c (limited to 'src/network/lookup_ipliteral.c') diff --git a/src/network/lookup_ipliteral.c b/src/network/lookup_ipliteral.c new file mode 100644 index 0000000..1e76620 --- /dev/null +++ b/src/network/lookup_ipliteral.c @@ -0,0 +1,55 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "lookup.h" + +int __lookup_ipliteral(struct address buf[static 1], const char *name, int family) +{ + struct in_addr a4; + struct in6_addr a6; + if (__inet_aton(name, &a4) > 0) { + if (family == AF_INET6) /* wrong family */ + return EAI_NODATA; + memcpy(&buf[0].addr, &a4, sizeof a4); + buf[0].family = AF_INET; + buf[0].scopeid = 0; + return 1; + } + + char tmp[64]; + char *p = strchr(name, '%'), *z; + unsigned long long scopeid = 0; + if (p && p-name < 64) { + memcpy(tmp, name, p-name); + tmp[p-name] = 0; + name = tmp; + } + + if (inet_pton(AF_INET6, name, &a6) <= 0) + return 0; + if (family == AF_INET) /* wrong family */ + return EAI_NODATA; + + memcpy(&buf[0].addr, &a6, sizeof a6); + buf[0].family = AF_INET6; + if (p) { + if (isdigit(*++p)) scopeid = strtoull(p, &z, 10); + else z = p-1; + if (*z) { + if (!IN6_IS_ADDR_LINKLOCAL(&a6) && + !IN6_IS_ADDR_MC_LINKLOCAL(&a6)) + return EAI_NONAME; + scopeid = if_nametoindex(p); + if (!scopeid) return EAI_NONAME; + } + if (scopeid > UINT_MAX) return EAI_NONAME; + } + buf[0].scopeid = scopeid; + return 1; +} -- cgit v1.2.3