Add sa6_checkzone_ifp() function. It checks correctness of struct

sockaddr_in6, usually obtained from the user level through ioctl.
It initializes sin6_scope_id using given interface.

Sponsored by:	Yandex LLC
This commit is contained in:
Andrey V. Elsukov 2014-11-10 16:12:51 +00:00
parent e0c0711e01
commit 002c24396d
2 changed files with 22 additions and 0 deletions

View File

@ -532,4 +532,25 @@ sa6_checkzone(struct sockaddr_in6 *sa6)
return (sa6->sin6_scope_id ? 0: EADDRNOTAVAIL);
}
/*
* This function is similar to sa6_checkzone, but it uses given ifp
* to initialize sin6_scope_id.
*/
int
sa6_checkzone_ifp(struct ifnet *ifp, struct sockaddr_in6 *sa6)
{
int scope;
scope = in6_addrscope(&sa6->sin6_addr);
if (scope == IPV6_ADDR_SCOPE_LINKLOCAL ||
scope == IPV6_ADDR_SCOPE_INTFACELOCAL) {
if (sa6->sin6_scope_id == 0) {
sa6->sin6_scope_id = in6_getscopezone(ifp, scope);
return (0);
} else if (sa6->sin6_scope_id != in6_getscopezone(ifp, scope))
return (EADDRNOTAVAIL);
}
return (sa6_checkzone(sa6));
}

View File

@ -58,6 +58,7 @@ u_int32_t scope6_addr2default(struct in6_addr *);
int sa6_embedscope(struct sockaddr_in6 *, int);
int sa6_recoverscope(struct sockaddr_in6 *);
int sa6_checkzone(struct sockaddr_in6 *);
int sa6_checkzone_ifp(struct ifnet *, struct sockaddr_in6 *);
int in6_setscope(struct in6_addr *, struct ifnet *, u_int32_t *);
int in6_clearscope(struct in6_addr *);
uint16_t in6_getscope(struct in6_addr *);