mirror of
https://github.com/freebsd/freebsd-src
synced 2024-10-05 16:10:55 +00:00
- do validation check and IPv4-mapped IPv6 address handling before
any query. - don't query against IPv6 link-local address. - use IN6_IS_ADDR_V4{MAPPED,COMPAT} macros. - use memcpy() instead of bcopy(). Inspired by: NetBSD
This commit is contained in:
parent
5d1ae027f0
commit
2c08ac2b38
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=145687
|
@ -387,7 +387,7 @@ gethostanswer(const querybuf *answer, int anslen, const char *qname, int qtype,
|
|||
cp += n;
|
||||
continue;
|
||||
}
|
||||
bcopy(cp, *hap++ = bp, n);
|
||||
memcpy(*hap++ = bp, cp, n);
|
||||
bp += n;
|
||||
cp += n;
|
||||
if (cp != erdata) {
|
||||
|
@ -517,14 +517,11 @@ _dns_gethostbyname(void *rval, void *cb_data, va_list ap)
|
|||
int
|
||||
_dns_gethostbyaddr(void *rval, void *cb_data, va_list ap)
|
||||
{
|
||||
const char *addr; /* XXX should have been def'd as u_char! */
|
||||
const u_char *uaddr;
|
||||
int len, af;
|
||||
struct hostent *he;
|
||||
struct hostent_data *hed;
|
||||
const u_char *uaddr;
|
||||
static const u_char mapped[] = { 0,0, 0,0, 0,0, 0,0, 0,0, 0xff,0xff };
|
||||
static const u_char tunnelled[] = { 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 };
|
||||
int n, size, error;
|
||||
int n, error;
|
||||
querybuf *buf;
|
||||
char qbuf[MAXDNAME+1], *qp;
|
||||
#ifdef SUNSECURITY
|
||||
|
@ -535,8 +532,7 @@ _dns_gethostbyaddr(void *rval, void *cb_data, va_list ap)
|
|||
char hname2[MAXDNAME+1], numaddr[46];
|
||||
#endif /*SUNSECURITY*/
|
||||
|
||||
addr = va_arg(ap, const char *);
|
||||
uaddr = (const u_char *)addr;
|
||||
uaddr = va_arg(ap, const u_char *);
|
||||
len = va_arg(ap, int);
|
||||
af = va_arg(ap, int);
|
||||
he = va_arg(ap, struct hostent *);
|
||||
|
@ -546,32 +542,6 @@ _dns_gethostbyaddr(void *rval, void *cb_data, va_list ap)
|
|||
h_errno = NETDB_INTERNAL;
|
||||
return NS_UNAVAIL;
|
||||
}
|
||||
if (af == AF_INET6 && len == IN6ADDRSZ &&
|
||||
(!bcmp(uaddr, mapped, sizeof mapped) ||
|
||||
!bcmp(uaddr, tunnelled, sizeof tunnelled))) {
|
||||
/* Unmap. */
|
||||
addr += sizeof mapped;
|
||||
uaddr += sizeof mapped;
|
||||
af = AF_INET;
|
||||
len = INADDRSZ;
|
||||
}
|
||||
switch (af) {
|
||||
case AF_INET:
|
||||
size = INADDRSZ;
|
||||
break;
|
||||
case AF_INET6:
|
||||
size = IN6ADDRSZ;
|
||||
break;
|
||||
default:
|
||||
errno = EAFNOSUPPORT;
|
||||
h_errno = NETDB_INTERNAL;
|
||||
return NS_UNAVAIL;
|
||||
}
|
||||
if (size != len) {
|
||||
errno = EINVAL;
|
||||
h_errno = NETDB_INTERNAL;
|
||||
return NS_UNAVAIL;
|
||||
}
|
||||
switch (af) {
|
||||
case AF_INET:
|
||||
(void) sprintf(qbuf, "%u.%u.%u.%u.in-addr.arpa",
|
||||
|
@ -651,7 +621,7 @@ _dns_gethostbyaddr(void *rval, void *cb_data, va_list ap)
|
|||
#endif /*SUNSECURITY*/
|
||||
he->h_addrtype = af;
|
||||
he->h_length = len;
|
||||
bcopy(addr, hed->host_addr, len);
|
||||
memcpy(hed->host_addr, uaddr, len);
|
||||
hed->h_addr_ptrs[0] = (char *)hed->host_addr;
|
||||
hed->h_addr_ptrs[1] = NULL;
|
||||
if (af == AF_INET && (_res.options & RES_USE_INET6)) {
|
||||
|
|
|
@ -252,6 +252,9 @@ int
|
|||
gethostbyaddr_r(const char *addr, int len, int af, struct hostent *he,
|
||||
struct hostent_data *hed)
|
||||
{
|
||||
const u_char *uaddr = (const u_char *)addr;
|
||||
const struct in6_addr *addr6;
|
||||
socklen_t size;
|
||||
int rval;
|
||||
|
||||
static const ns_dtab dtab[] = {
|
||||
|
@ -261,8 +264,40 @@ gethostbyaddr_r(const char *addr, int len, int af, struct hostent *he,
|
|||
{ 0 }
|
||||
};
|
||||
|
||||
if (af == AF_INET6 && len == IN6ADDRSZ) {
|
||||
addr6 = (const struct in6_addr *)(const void *)uaddr;
|
||||
if (IN6_IS_ADDR_LINKLOCAL(addr6)) {
|
||||
h_errno = HOST_NOT_FOUND;
|
||||
return -1;
|
||||
}
|
||||
if (IN6_IS_ADDR_V4MAPPED(addr6) ||
|
||||
IN6_IS_ADDR_V4COMPAT(addr6)) {
|
||||
/* Unmap. */
|
||||
uaddr += IN6ADDRSZ - INADDRSZ;
|
||||
af = AF_INET;
|
||||
len = INADDRSZ;
|
||||
}
|
||||
}
|
||||
switch (af) {
|
||||
case AF_INET:
|
||||
size = INADDRSZ;
|
||||
break;
|
||||
case AF_INET6:
|
||||
size = IN6ADDRSZ;
|
||||
break;
|
||||
default:
|
||||
errno = EAFNOSUPPORT;
|
||||
h_errno = NETDB_INTERNAL;
|
||||
return -1;
|
||||
}
|
||||
if (size != len) {
|
||||
errno = EINVAL;
|
||||
h_errno = NETDB_INTERNAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
rval = _nsdispatch(NULL, dtab, NSDB_HOSTS, "gethostbyaddr",
|
||||
default_src, addr, len, af, he, hed);
|
||||
default_src, uaddr, len, af, he, hed);
|
||||
|
||||
return (rval == NS_SUCCESS) ? 0 : -1;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue