summaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorume <ume@FreeBSD.org>2005-04-29 19:55:23 +0000
committerume <ume@FreeBSD.org>2005-04-29 19:55:23 +0000
commit5acac5def141d4709680819f06b1a8c4fb8c641a (patch)
treeac7d19999bfe61a1d5647789758e160633cdc4c0 /lib
parentbb1e0b257abb86c2b6efe470eaa92b65967e6d1d (diff)
downloadFreeBSD-src-5acac5def141d4709680819f06b1a8c4fb8c641a.zip
FreeBSD-src-5acac5def141d4709680819f06b1a8c4fb8c641a.tar.gz
- 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
Diffstat (limited to 'lib')
-rw-r--r--lib/libc/net/gethostbydns.c40
-rw-r--r--lib/libc/net/gethostnamadr.c37
2 files changed, 41 insertions, 36 deletions
diff --git a/lib/libc/net/gethostbydns.c b/lib/libc/net/gethostbydns.c
index bd4d02d..6cb43f0 100644
--- a/lib/libc/net/gethostbydns.c
+++ b/lib/libc/net/gethostbydns.c
@@ -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)) {
diff --git a/lib/libc/net/gethostnamadr.c b/lib/libc/net/gethostnamadr.c
index 78b3a7a..8aae192 100644
--- a/lib/libc/net/gethostnamadr.c
+++ b/lib/libc/net/gethostnamadr.c
@@ -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;
}
OpenPOWER on IntegriCloud