From fbb54ee97a1b1509452b4d07e74099c5ee0582e9 Mon Sep 17 00:00:00 2001 From: Christian Spielberger Date: Mon, 21 Jun 2021 09:13:00 +0200 Subject: [PATCH] sa: add support for interface suffix for IPv6ll --- src/sa/sa.c | 31 +++++++++++++++++++++++++++++-- 1 file changed, 29 insertions(+), 2 deletions(-) diff --git a/src/sa/sa.c b/src/sa/sa.c index b2b20663e..59eb200ba 100644 --- a/src/sa/sa.c +++ b/src/sa/sa.c @@ -12,10 +12,14 @@ #include #endif #include +#include +#include +#include #include #include #include #include +#include #define DEBUG_MODULE "sa" @@ -68,7 +72,11 @@ int sa_set(struct sa *sa, const struct pl *addr, uint16_t port) */ int sa_pton(const char *addr, struct sa *sa) { - if (!addr) + struct addrinfo *res, *res0 = NULL; + struct addrinfo hints; + int err = 0; + + if (!addr || !sa) return EINVAL; if (inet_pton(AF_INET, addr, &sa->u.in.sin_addr) > 0) { @@ -86,12 +94,31 @@ int sa_pton(const char *addr, struct sa *sa) sa->u.in6.sin6_family = AF_INET6; } } + else if (!strncmp(addr, "fe80:", 5) && strchr(addr, '%')) { + memset(&hints, 0, sizeof(hints)); + hints.ai_family = AF_UNSPEC; + hints.ai_flags = AI_V4MAPPED | AI_ADDRCONFIG | AI_NUMERICHOST; + + if (getaddrinfo(addr, NULL, &hints, &res0)) + return EADDRNOTAVAIL; + + for (res = res0; res; res = res->ai_next) { + + err = sa_set_sa(sa, res->ai_addr); + if (err) + continue; + + break; + } + + freeaddrinfo(res0); + } #endif else { return EINVAL; } - return 0; + return err; }