mirror of
https://github.com/samba-team/samba.git
synced 2024-12-25 23:21:54 +03:00
lib/util_net: move ipv6 linklocal handling into interpret_string_addr_internal()
Signed-off-by: Stefan Metzmacher <metze@samba.org> Reviewed-by: Günther Deschner <gd@samba.org> Reviewed-by: Andrew Bartlett <abartlet@samba.org>
This commit is contained in:
parent
f7116f0ad0
commit
771042a238
@ -49,6 +49,10 @@ bool interpret_string_addr_internal(struct addrinfo **ppres,
|
||||
{
|
||||
int ret;
|
||||
struct addrinfo hints;
|
||||
#if defined(HAVE_IPV6)
|
||||
char addr[INET6_ADDRSTRLEN] = { 0, };
|
||||
unsigned int scope_id = 0;
|
||||
#endif
|
||||
|
||||
ZERO_STRUCT(hints);
|
||||
|
||||
@ -58,8 +62,60 @@ bool interpret_string_addr_internal(struct addrinfo **ppres,
|
||||
/* always try as a numeric host first. This prevents unnecessary name
|
||||
* lookups, and also ensures we accept IPv6 addresses */
|
||||
hints.ai_flags = AI_PASSIVE | AI_NUMERICHOST;
|
||||
|
||||
#if defined(HAVE_IPV6)
|
||||
if (strchr_m(str, ':')) {
|
||||
char *p = strchr_m(str, '%');
|
||||
|
||||
/*
|
||||
* Cope with link-local.
|
||||
* This is IP:v6:addr%ifname.
|
||||
*/
|
||||
|
||||
if (p && (p > str) && ((scope_id = if_nametoindex(p+1)) != 0)) {
|
||||
/* Length of string we want to copy.
|
||||
This is IP:v6:addr (removing the %ifname).
|
||||
*/
|
||||
size_t len = PTR_DIFF(p,str);
|
||||
|
||||
if (len+1 > sizeof(addr)) {
|
||||
/* string+nul too long for array. */
|
||||
return false;
|
||||
}
|
||||
memcpy(addr, str, len);
|
||||
addr[len] = '\0';
|
||||
|
||||
str = addr;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
ret = getaddrinfo(str, NULL, &hints, ppres);
|
||||
if (ret == 0) {
|
||||
#if defined(HAVE_IPV6)
|
||||
struct sockaddr_in6 *ps6 = NULL;
|
||||
|
||||
if (scope_id == 0) {
|
||||
return true;
|
||||
}
|
||||
if (ppres == NULL) {
|
||||
return true;
|
||||
}
|
||||
if ((*ppres) == NULL) {
|
||||
return true;
|
||||
}
|
||||
if ((*ppres)->ai_addr->sa_family != AF_INET6) {
|
||||
return true;
|
||||
}
|
||||
|
||||
ps6 = (struct sockaddr_in6 *)(*ppres)->ai_addr;
|
||||
|
||||
if (IN6_IS_ADDR_LINKLOCAL(&ps6->sin6_addr) &&
|
||||
ps6->sin6_scope_id == 0) {
|
||||
ps6->sin6_scope_id = scope_id;
|
||||
}
|
||||
#endif
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -94,35 +150,6 @@ static bool interpret_string_addr_pref(struct sockaddr_storage *pss,
|
||||
{
|
||||
struct addrinfo *res = NULL;
|
||||
int int_flags;
|
||||
#if defined(HAVE_IPV6)
|
||||
char addr[INET6_ADDRSTRLEN];
|
||||
unsigned int scope_id = 0;
|
||||
|
||||
if (strchr_m(str, ':')) {
|
||||
char *p = strchr_m(str, '%');
|
||||
|
||||
/*
|
||||
* Cope with link-local.
|
||||
* This is IP:v6:addr%ifname.
|
||||
*/
|
||||
|
||||
if (p && (p > str) && ((scope_id = if_nametoindex(p+1)) != 0)) {
|
||||
/* Length of string we want to copy.
|
||||
This is IP:v6:addr (removing the %ifname).
|
||||
*/
|
||||
size_t len = PTR_DIFF(p,str);
|
||||
|
||||
if (len+1 > sizeof(addr)) {
|
||||
/* string+nul too long for array. */
|
||||
return false;
|
||||
}
|
||||
memcpy(addr, str, len);
|
||||
addr[len] = '\0';
|
||||
|
||||
str = addr;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
zero_sockaddr(pss);
|
||||
|
||||
@ -157,16 +184,6 @@ static bool interpret_string_addr_pref(struct sockaddr_storage *pss,
|
||||
memcpy(pss, res->ai_addr, res->ai_addrlen);
|
||||
}
|
||||
|
||||
#if defined(HAVE_IPV6)
|
||||
if (pss->ss_family == AF_INET6 && scope_id) {
|
||||
struct sockaddr_in6 *ps6 = (struct sockaddr_in6 *)pss;
|
||||
if (IN6_IS_ADDR_LINKLOCAL(&ps6->sin6_addr) &&
|
||||
ps6->sin6_scope_id == 0) {
|
||||
ps6->sin6_scope_id = scope_id;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
freeaddrinfo(res);
|
||||
return true;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user