diff options
author | ume <ume@FreeBSD.org> | 2005-04-25 17:36:28 +0000 |
---|---|---|
committer | ume <ume@FreeBSD.org> | 2005-04-25 17:36:28 +0000 |
commit | c5b4993c85e0d43326c139c8546a7620e37a6a41 (patch) | |
tree | 7354a3ee865b61c107c10dbbe961ea7801f8f5f8 /lib | |
parent | 1c27d898b4c751a3eaf3754898bbfefa174dec6a (diff) | |
download | FreeBSD-src-c5b4993c85e0d43326c139c8546a7620e37a6a41.zip FreeBSD-src-c5b4993c85e0d43326c139c8546a7620e37a6a41.tar.gz |
ensure parsing numeric address before any host query.
Inspired by: NetBSD
Diffstat (limited to 'lib')
-rw-r--r-- | lib/libc/net/gethostbydns.c | 87 | ||||
-rw-r--r-- | lib/libc/net/gethostnamadr.c | 139 |
2 files changed, 126 insertions, 100 deletions
diff --git a/lib/libc/net/gethostbydns.c b/lib/libc/net/gethostbydns.c index 33a0749..8491207 100644 --- a/lib/libc/net/gethostbydns.c +++ b/lib/libc/net/gethostbydns.c @@ -96,8 +96,6 @@ static char *host_aliases[MAXALIASES]; static char hostbuf[8*1024]; static u_char host_addr[16]; /* IPv4 or IPv6 */ -extern const char *_res_hostalias(const char *, char *, size_t); - #ifdef RESOLVSORT static void addrsort(char **, int); #endif @@ -476,20 +474,12 @@ _dns_gethostbyname(void *rval, void *cb_data, va_list ap) const char *name; int af; querybuf *buf; - const char *cp; - char *bp, *ep; int n, size, type; - char abuf[MAXDNAME]; name = va_arg(ap, const char *); af = va_arg(ap, int); *(struct hostent **)rval = NULL; - if ((_res.options & RES_INIT) == 0 && res_init() == -1) { - h_errno = NETDB_INTERNAL; - return NS_UNAVAIL; - } - switch (af) { case AF_INET: size = INADDRSZ; @@ -508,83 +498,6 @@ _dns_gethostbyname(void *rval, void *cb_data, va_list ap) host.h_addrtype = af; host.h_length = size; - /* - * if there aren't any dots, it could be a user-level alias. - * this is also done in res_query() since we are not the only - * function that looks up host names. - */ - if (!strchr(name, '.') && - (cp = _res_hostalias(name, abuf, sizeof abuf))) - name = cp; - - /* - * disallow names consisting only of digits/dots, unless - * they end in a dot. - */ - if (isdigit((unsigned char)name[0])) - for (cp = name;; ++cp) { - if (!*cp) { - if (*--cp == '.') - break; - /* - * All-numeric, no dot at the end. - * Fake up a hostent as if we'd actually - * done a lookup. - */ - if (inet_pton(af, name, host_addr) <= 0) { - h_errno = HOST_NOT_FOUND; - return NS_NOTFOUND; - } - strncpy(hostbuf, name, MAXDNAME); - hostbuf[MAXDNAME] = '\0'; - bp = hostbuf + MAXDNAME; - ep = hostbuf + sizeof hostbuf; - host.h_name = hostbuf; - host.h_aliases = host_aliases; - host_aliases[0] = NULL; - h_addr_ptrs[0] = (char *)host_addr; - h_addr_ptrs[1] = NULL; - host.h_addr_list = h_addr_ptrs; - if (_res.options & RES_USE_INET6) - _map_v4v6_hostent(&host, &bp, &ep); - h_errno = NETDB_SUCCESS; - *(struct hostent **)rval = &host; - return NS_SUCCESS; - } - if (!isdigit((unsigned char)*cp) && *cp != '.') - break; - } - if ((isxdigit((unsigned char)name[0]) && strchr(name, ':') != NULL) || - name[0] == ':') - for (cp = name;; ++cp) { - if (!*cp) { - if (*--cp == '.') - break; - /* - * All-IPv6-legal, no dot at the end. - * Fake up a hostent as if we'd actually - * done a lookup. - */ - if (inet_pton(af, name, host_addr) <= 0) { - h_errno = HOST_NOT_FOUND; - return NS_NOTFOUND; - } - strncpy(hostbuf, name, MAXDNAME); - hostbuf[MAXDNAME] = '\0'; - host.h_name = hostbuf; - host.h_aliases = host_aliases; - host_aliases[0] = NULL; - h_addr_ptrs[0] = (char *)host_addr; - h_addr_ptrs[1] = NULL; - host.h_addr_list = h_addr_ptrs; - h_errno = NETDB_SUCCESS; - *(struct hostent **)rval = &host; - return NS_SUCCESS; - } - if (!isxdigit((unsigned char)*cp) && *cp != ':' && *cp != '.') - break; - } - if ((buf = malloc(sizeof(*buf))) == NULL) { h_errno = NETDB_INTERNAL; return NS_NOTFOUND; diff --git a/lib/libc/net/gethostnamadr.c b/lib/libc/net/gethostnamadr.c index f5c3382..2409502 100644 --- a/lib/libc/net/gethostnamadr.c +++ b/lib/libc/net/gethostnamadr.c @@ -34,6 +34,7 @@ __FBSDID("$FreeBSD$"); #include <netdb.h> #include <stdio.h> #include <ctype.h> +#include <errno.h> #include <string.h> #include <stdarg.h> #include <nsswitch.h> @@ -47,9 +48,12 @@ extern int _nis_gethostbyname(void *, void *, va_list); extern int _ht_gethostbyaddr(void *, void *, va_list); extern int _dns_gethostbyaddr(void *, void *, va_list); extern int _nis_gethostbyaddr(void *, void *, va_list); +extern const char *_res_hostalias(const char *, char *, size_t); + +static struct hostent *gethostbyname_internal(const char *, int); /* Host lookup order if nsswitch.conf is broken or nonexistant */ -static const ns_src default_src[] = { +static const ns_src default_src[] = { { NSSRC_FILES, NS_SUCCESS }, { NSSRC_DNS, NS_SUCCESS }, { 0 } @@ -62,31 +66,140 @@ gethostbyname(const char *name) if ((_res.options & RES_INIT) == 0 && res_init() == -1) { h_errno = NETDB_INTERNAL; - return (NULL); + return NULL; + } + if (_res.options & RES_USE_INET6) { + hp = gethostbyname_internal(name, AF_INET6); + if (hp) + return hp; } - if (_res.options & RES_USE_INET6) { /* XXX */ - hp = gethostbyname2(name, AF_INET6); /* XXX */ - if (hp) /* XXX */ - return (hp); /* XXX */ - } /* XXX */ - return (gethostbyname2(name, AF_INET)); + return gethostbyname_internal(name, AF_INET); } struct hostent * -gethostbyname2(const char *name, int type) +gethostbyname2(const char *name, int af) +{ + if ((_res.options & RES_INIT) == 0 && res_init() == -1) { + h_errno = NETDB_INTERNAL; + return NULL; + } + return gethostbyname_internal(name, af); +} + +static struct hostent * +gethostbyname_internal(const char *name, int af) { + const char *cp; + char *bp, *ep; struct hostent *hp = 0; - int rval; + int size, rval; + char abuf[MAXDNAME]; + static struct hostent host; + static char *h_addr_ptrs[2]; + static char *host_aliases[1]; + static char hostbuf[MAXDNAME + IN6ADDRSZ + sizeof(uint32_t)]; + static uint32_t host_addr[4]; /* IPv4 or IPv6 */ static const ns_dtab dtab[] = { NS_FILES_CB(_ht_gethostbyname, NULL) { NSSRC_DNS, _dns_gethostbyname, NULL }, NS_NIS_CB(_nis_gethostbyname, NULL) /* force -DHESIOD */ { 0 } - }; - + }; + + switch (af) { + case AF_INET: + size = INADDRSZ; + break; + case AF_INET6: + size = IN6ADDRSZ; + break; + default: + h_errno = NETDB_INTERNAL; + errno = EAFNOSUPPORT; + return NULL; + } + + host.h_addrtype = af; + host.h_length = size; + + /* + * if there aren't any dots, it could be a user-level alias. + * this is also done in res_query() since we are not the only + * function that looks up host names. + */ + if (!strchr(name, '.') && + (cp = _res_hostalias(name, abuf, sizeof abuf))) + name = cp; + + /* + * disallow names consisting only of digits/dots, unless + * they end in a dot. + */ + if (isdigit((u_char)name[0])) + for (cp = name;; ++cp) { + if (!*cp) { + if (*--cp == '.') + break; + /* + * All-numeric, no dot at the end. + * Fake up a hostent as if we'd actually + * done a lookup. + */ + if (inet_pton(af, name, host_addr) <= 0) { + h_errno = HOST_NOT_FOUND; + return NULL; + } + strncpy(hostbuf, name, MAXDNAME); + hostbuf[MAXDNAME] = '\0'; + bp = hostbuf + MAXDNAME; + ep = hostbuf + sizeof hostbuf; + host.h_name = hostbuf; + host.h_aliases = host_aliases; + host_aliases[0] = NULL; + h_addr_ptrs[0] = (char *)host_addr; + h_addr_ptrs[1] = NULL; + host.h_addr_list = h_addr_ptrs; + if (_res.options & RES_USE_INET6) + _map_v4v6_hostent(&host, &bp, &ep); + h_errno = NETDB_SUCCESS; + return &host; + } + if (!isdigit((u_char)*cp) && *cp != '.') + break; + } + if ((isxdigit((u_char)name[0]) && strchr(name, ':') != NULL) || + name[0] == ':') + for (cp = name;; ++cp) { + if (!*cp) { + if (*--cp == '.') + break; + /* + * All-IPv6-legal, no dot at the end. + * Fake up a hostent as if we'd actually + * done a lookup. + */ + if (inet_pton(af, name, host_addr) <= 0) { + h_errno = HOST_NOT_FOUND; + return NULL; + } + strncpy(hostbuf, name, MAXDNAME); + hostbuf[MAXDNAME] = '\0'; + host.h_name = hostbuf; + host.h_aliases = host_aliases; + host_aliases[0] = NULL; + h_addr_ptrs[0] = (char *)host_addr; + h_addr_ptrs[1] = NULL; + host.h_addr_list = h_addr_ptrs; + h_errno = NETDB_SUCCESS; + return &host; + } + if (!isxdigit((u_char)*cp) && *cp != ':' && *cp != '.') + break; + } + rval = _nsdispatch((void *)&hp, dtab, NSDB_HOSTS, "gethostbyname", - default_src, name, type); + default_src, name, af); if (rval != NS_SUCCESS) return NULL; |