diff --git a/usr.sbin/traceroute/traceroute.c b/usr.sbin/traceroute/traceroute.c --- a/usr.sbin/traceroute/traceroute.c +++ b/usr.sbin/traceroute/traceroute.c @@ -1843,10 +1843,17 @@ char * inetname(struct in_addr in) { + struct sockaddr_in sin = { + .sin_len = sizeof(struct sockaddr_in), + .sin_family = AF_INET, + .sin_addr = in + }; register char *cp; - register struct hostent *hp; + struct addrinfo *res; static int first = 1; + int error; static char domain[MAXHOSTNAMELEN + 1], line[MAXHOSTNAMELEN + 1]; + char host[NI_MAXHOST]; if (first && !nflag) { first = 0; @@ -1856,13 +1863,26 @@ cp = strchr(domain, '.'); if (cp == NULL) { #ifdef WITH_CASPER - if (capdns != NULL) - hp = cap_gethostbyname(capdns, domain); + if (capdns != NULL) { + if (cap_getaddrinfo(capdns, domain, NULL, &(struct addrinfo){ + .ai_family = AF_INET + }, &res) == 0) { + if (cap_getnameinfo(capdns, res->ai_addr, res->ai_addrlen, + host, sizeof(host), NULL, 0, NI_NAMEREQD) == 0) + cp = strchr(host, '.'); + freeaddrinfo(res); + } + } else #endif - hp = gethostbyname(domain); - if (hp != NULL) - cp = strchr(hp->h_name, '.'); + if (getaddrinfo(domain, NULL, &(struct addrinfo){ + .ai_family = AF_INET + }, &res) == 0) { + if (getnameinfo(res->ai_addr, res->ai_addrlen, host, + sizeof(host), NULL, 0, NI_NAMEREQD) == 0) + cp = strchr(host, '.'); + freeaddrinfo(res); + } } if (cp == NULL) domain[0] = '\0'; @@ -1876,16 +1896,17 @@ if (!nflag && in.s_addr != INADDR_ANY) { #ifdef WITH_CASPER if (capdns != NULL) - hp = cap_gethostbyaddr(capdns, (char *)&in, sizeof(in), - AF_INET); + error = cap_getnameinfo(capdns, (struct sockaddr *)&sin, sin.sin_len, + host, sizeof(host), NULL, 0, NI_NAMEREQD); else #endif - hp = gethostbyaddr((char *)&in, sizeof(in), AF_INET); - if (hp != NULL) { - if ((cp = strchr(hp->h_name, '.')) != NULL && + error = getnameinfo((struct sockaddr *)&sin, sin.sin_len, host, + sizeof(host), NULL, 0, NI_NAMEREQD); + if (error == 0) { + if ((cp = strchr(host, '.')) != NULL && strcmp(cp + 1, domain) == 0) *cp = '\0'; - (void)strncpy(line, hp->h_name, sizeof(line) - 1); + (void)strncpy(line, host, sizeof(line) - 1); line[sizeof(line) - 1] = '\0'; return (line); } @@ -1896,10 +1917,10 @@ struct hostinfo * gethostinfo(register char *hostname) { - register int n; - register struct hostent *hp; + register int n, error; + struct addrinfo *res, *p; register struct hostinfo *hi; - register char **p; + char host[NI_MAXHOST]; register u_int32_t addr, *ap; if (strlen(hostname) >= MAXHOSTNAMELEN) { @@ -1928,20 +1949,33 @@ #ifdef WITH_CASPER if (capdns != NULL) - hp = cap_gethostbyname(capdns, hostname); + error = cap_getaddrinfo(capdns, hostname, NULL, &(struct addrinfo){ + .ai_family = AF_INET + }, &res); else #endif - hp = gethostbyname(hostname); - if (hp == NULL) { + error = getaddrinfo(hostname, NULL, &(struct addrinfo){ + .ai_family = AF_INET + }, &res); + if (error != 0) { Fprintf(stderr, "%s: unknown host %s\n", prog, hostname); exit(1); } - if (hp->h_addrtype != AF_INET || hp->h_length != 4) { - Fprintf(stderr, "%s: bad host %s\n", prog, hostname); +#ifdef WITH_CASPER + if (capdns != NULL) + error = cap_getnameinfo(capdns, res->ai_addr, res->ai_addrlen, host, + sizeof(host), NULL, 0, NI_NAMEREQD); + else +#endif + error = getnameinfo(res->ai_addr, res->ai_addrlen, host, sizeof(host), + NULL, 0, NI_NAMEREQD); + if (error != 0) { + Fprintf(stderr, "%s: failed to resolve host name %s\n", prog, hostname); + freeaddrinfo(res); exit(1); } - hi->name = strdup(hp->h_name); - for (n = 0, p = hp->h_addr_list; *p != NULL; ++n, ++p) + hi->name = strdup(host); + for (n = 0, p = res; p != NULL; ++n, p = p->ai_next) continue; hi->n = n; hi->addrs = calloc(n, sizeof(hi->addrs[0])); @@ -1949,8 +1983,9 @@ Fprintf(stderr, "%s: calloc %s\n", prog, strerror(errno)); exit(1); } - for (ap = hi->addrs, p = hp->h_addr_list; *p != NULL; ++ap, ++p) - memcpy(ap, *p, sizeof(*ap)); + for (ap = hi->addrs, p = res; p != NULL; ++ap, p = p->ai_next) + memcpy(ap, &((struct sockaddr_in *)p->ai_addr)->sin_addr.s_addr, sizeof(*ap)); + freeaddrinfo(res); return (hi); }