diff --git a/usr.bin/getent/getent.c b/usr.bin/getent/getent.c --- a/usr.bin/getent/getent.c +++ b/usr.bin/getent/getent.c @@ -276,42 +276,70 @@ printfmtstrings(he->h_aliases, " ", " ", "%-16s %s", buf, he->h_name); } +static void +addrprint(const struct addrinfo *addr, char *argv_host) +{ + struct sockaddr_in sin, sin_2; + struct sockaddr_in6 sin6, sin6_2; + char buf[INET6_ADDRSTRLEN]; + char host[NI_MAXHOST]; + char *alias[] = {NULL}; /* empty alias list, getaddrinfo(3) don't return alias */ + void *addr_ptr = NULL; + + assert(addr != NULL); + + if (addr->ai_family == AF_INET) { + memcpy(&sin, addr->ai_addr, addr->ai_addrlen); + addr_ptr = &sin.sin_addr; + } + else if (addr->ai_family == AF_INET6) { + memcpy(&sin6, addr->ai_addr, addr->ai_addrlen); + addr_ptr = &sin6.sin6_addr; + } + + if (addr_ptr == NULL || + inet_ntop(addr->ai_family, addr_ptr, buf, sizeof(buf)) == NULL) + strlcpy(buf, "# unknown", sizeof(buf)); + + /* Check argv_host is FQDN or not */ + if (inet_pton(addr->ai_family, argv_host, addr->ai_family == AF_INET ? + (void *)&(sin_2.sin_addr) : (void *)&(sin6_2.sin6_addr)) == 1) + if (getnameinfo(addr->ai_addr, addr->ai_addrlen, + host, sizeof(host), NULL, 0, NI_NAMEREQD) != 0) + printfmtstrings(alias, " ", " ", "%-16s %s", buf, argv_host); + else + printfmtstrings(alias, " ", " ", "%-16s %s", buf, host); + else + printfmtstrings(alias, " ", " ", "%-16s %s", buf, argv_host); +} + static int hosts(int argc, char *argv[]) { - struct hostent *he4, *he6; - char addr[IN6ADDRSZ]; + struct hostent *he4; + struct addrinfo *res, *p; int i, rv; assert(argc > 1); assert(argv != NULL); sethostent(1); - he4 = he6 = NULL; + he4 = NULL; rv = RV_OK; if (argc == 2) { while ((he4 = gethostent()) != NULL) hostsprint(he4); } else { for (i = 2; i < argc; i++) { - if (inet_pton(AF_INET6, argv[i], (void *)addr) > 0) { - he6 = gethostbyaddr(addr, IN6ADDRSZ, AF_INET6); - if (he6 != NULL) - hostsprint(he6); - } else if (inet_pton(AF_INET, argv[i], - (void *)addr) > 0) { - he4 = gethostbyaddr(addr, INADDRSZ, AF_INET); - if (he4 != NULL) - hostsprint(he4); - } else { - he6 = gethostbyname2(argv[i], AF_INET6); - if (he6 != NULL) - hostsprint(he6); - he4 = gethostbyname(argv[i]); - if (he4 != NULL) - hostsprint(he4); + if (getaddrinfo(argv[i], NULL, &(struct addrinfo){ + .ai_family = AF_UNSPEC, + .ai_socktype = SOCK_STREAM + }, &res) == 0) { + for (p = res; p != NULL; p = p->ai_next) + addrprint(p, argv[i]); + freeaddrinfo(res); } - if ( he4 == NULL && he6 == NULL ) { + else { rv = RV_NOTFOUND; break; }