diff options
Diffstat (limited to 'contrib/bind/lib/irs/getaddrinfo.c')
-rw-r--r-- | contrib/bind/lib/irs/getaddrinfo.c | 63 |
1 files changed, 37 insertions, 26 deletions
diff --git a/contrib/bind/lib/irs/getaddrinfo.c b/contrib/bind/lib/irs/getaddrinfo.c index 243f10656c3c..89db519fcfd7 100644 --- a/contrib/bind/lib/irs/getaddrinfo.c +++ b/contrib/bind/lib/irs/getaddrinfo.c @@ -101,17 +101,12 @@ #include <stdarg.h> #include <irs.h> +#include <isc/assertions.h> #include "port_after.h" #include "irs_data.h" -/* - * if we enable it, we will see duplicated addrinfo entries on reply if both - * AAAA and A6 records are found. disable it for default installation. - */ -#undef T_A6 - #define SUCCESS 0 #define ANY 0 #define YES 1 @@ -192,7 +187,8 @@ static int get_portmatch __P((const struct addrinfo *, const char *)); static int get_port __P((const struct addrinfo *, const char *, int)); static const struct afd *find_afd __P((int)); static int addrconfig __P((int)); -static int ip6_str2scopeid __P((char *, struct sockaddr_in6 *)); +static int ip6_str2scopeid __P((char *, struct sockaddr_in6 *, + u_int32_t *scopeidp)); static struct net_data *init __P((void)); struct addrinfo *hostent2addrinfo __P((struct hostent *, @@ -297,8 +293,9 @@ str_isnumber(p) if (*p == '\0') return NO; ep = NULL; + errno = 0; (void)strtoul(p, &ep, 10); - if (ep && *ep == '\0') + if (errno == 0 && ep && *ep == '\0') return YES; else return NO; @@ -595,7 +592,7 @@ explore_fqdn(pai, hostname, servname, res) char tmp[NS_MAXDNAME]; const char *cp; - result = NULL; + INSIST(res != NULL && *res == NULL); /* * if the servname does not match socktype/protocol, ignore it. @@ -854,13 +851,13 @@ explore_numeric_scope(pai, hostname, servname, res) error = explore_numeric(pai, addr, servname, res); if (error == 0) { - int scopeid; + u_int32_t scopeid = 0; for (cur = *res; cur; cur = cur->ai_next) { if (cur->ai_family != AF_INET6) continue; sin6 = (struct sockaddr_in6 *)(void *)cur->ai_addr; - if ((scopeid = ip6_str2scopeid(scope, sin6)) == -1) { + if (!ip6_str2scopeid(scope, sin6, &scopeid)) { free(hostname2); return(EAI_NONAME); /* XXX: is return OK? */ } @@ -990,7 +987,17 @@ get_port(const struct addrinfo *ai, const char *servname, int matchonly) { allownumeric = 1; break; case ANY: - allownumeric = 0; + switch (ai->ai_family) { + case AF_INET: +#ifdef AF_INET6 + case AF_INET6: +#endif + allownumeric = 1; + break; + default: + allownumeric = 0; + break; + } break; default: return EAI_SOCKTYPE; @@ -999,9 +1006,10 @@ get_port(const struct addrinfo *ai, const char *servname, int matchonly) { if (str_isnumber(servname)) { if (!allownumeric) return EAI_SERVICE; - port = htons(atoi(servname)); + port = atoi(servname); if (port < 0 || port > 65535) return EAI_SERVICE; + port = htons(port); } else { switch (ai->ai_socktype) { case SOCK_DGRAM: @@ -1075,17 +1083,17 @@ addrconfig(af) /* convert a string to a scope identifier. XXX: IPv6 specific */ static int -ip6_str2scopeid(scope, sin6) - char *scope; - struct sockaddr_in6 *sin6; +ip6_str2scopeid(char *scope, struct sockaddr_in6 *sin6, + u_int32_t *scopeidp) { - int scopeid; + u_int32_t scopeid; + u_long lscopeid; struct in6_addr *a6 = &sin6->sin6_addr; char *ep; - + /* empty scopeid portion is invalid */ if (*scope == '\0') - return -1; + return (0); #ifdef USE_IFNAMELINKID if (IN6_IS_ADDR_LINKLOCAL(a6) || IN6_IS_ADDR_MC_LINKLOCAL(a6)) { @@ -1096,8 +1104,8 @@ ip6_str2scopeid(scope, sin6) */ scopeid = if_nametoindex(scope); if (scopeid == 0) - goto trynumeric; - return(scopeid); + *scopeidp = scopeid; + return (1); } #endif @@ -1111,11 +1119,14 @@ ip6_str2scopeid(scope, sin6) /* try to convert to a numeric id as a last resort */ trynumeric: - scopeid = (int)strtoul(scope, &ep, 10); - if (*ep == '\0') - return scopeid; - else - return -1; + errno = 0; + lscopeid = strtoul(scope, &ep, 10); + scopeid = lscopeid & 0xffffffff; + if (errno == 0 && ep && *ep == '\0' && scopeid == lscopeid) { + *scopeidp = scopeid; + return (1); + } else + return (0); } struct addrinfo * |