summaryrefslogtreecommitdiffstats
path: root/lib/libc/net/gethostnamadr.c
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/libc/net/gethostnamadr.c
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/libc/net/gethostnamadr.c')
-rw-r--r--lib/libc/net/gethostnamadr.c37
1 files changed, 36 insertions, 1 deletions
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