ahost should use ares_getaddrinfo() these days (#669)

ahost wasn't printing both ipv4 and ipv6 addresses. This day and age, it really should.

This PR also adds the ability to specify the servers to use.

Fix By: Brad House (@bradh352)
pull/673/head
Brad House 1 year ago committed by GitHub
parent eebfe0c15e
commit 44c59a91c3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 9
      docs/ahost.1
  2. 106
      src/tools/ahost.c

@ -39,11 +39,14 @@ Print some extra debugging output.
Display this help and exit.
.TP
\fB\-t\fR type
If type is "a", print the A record (default).
If type is "a", print the A record.
If type is "aaaa", print the AAAA record.
If type is "u", look for either AAAA or A record (in that order).
If type is "u", look for both AAAA and A records (default).
.TP
\fB\-s\fR \fIdomain\fP
\fB\-s\fR server
Set the server list to use for DNS lookups.
.TP
\fB\-D\fR \fIdomain\fP
Specify the \fIdomain\fP to search instead of using the default values from
.br
/etc/resolv.conf. This option only has an effect on platforms that use

@ -58,6 +58,8 @@
#endif
static void callback(void *arg, int status, int timeouts, struct hostent *host);
static void ai_callback(void *arg, int status, int timeouts,
struct ares_addrinfo *result);
static void usage(void);
static void print_help_info_ahost(void);
@ -69,7 +71,7 @@ int main(int argc, char **argv)
int status;
int nfds;
int c;
int addr_family = AF_INET;
int addr_family = AF_UNSPEC;
fd_set read_fds;
fd_set write_fds;
struct timeval *tvp;
@ -77,6 +79,7 @@ int main(int argc, char **argv)
struct in_addr addr4;
struct ares_in6_addr addr6;
ares_getopt_state_t state;
char *servers = NULL;
#ifdef USE_WINSOCK
WORD wVersionRequested = MAKEWORD(USE_WINSOCK, USE_WINSOCK);
@ -93,14 +96,14 @@ int main(int argc, char **argv)
}
ares_getopt_init(&state, argc, (const char **)argv);
while ((c = ares_getopt(&state, "dt:h?s:")) != -1) {
while ((c = ares_getopt(&state, "dt:h?D:s:")) != -1) {
switch (c) {
case 'd':
#ifdef WATT32
dbug_init();
#endif
break;
case 's':
case 'D':
optmask |= ARES_OPT_DOMAINS;
options.ndomains++;
options.domains = (char **)realloc(
@ -118,9 +121,18 @@ int main(int argc, char **argv)
usage();
}
break;
case 'h':
print_help_info_ahost();
case 's':
if (state.optarg == NULL) {
fprintf(stderr, "%s", "missing servers");
usage();
break;
}
if (servers) {
free(servers);
}
servers = strdup(state.optarg);
break;
case 'h':
case '?':
print_help_info_ahost();
break;
@ -138,10 +150,22 @@ int main(int argc, char **argv)
status = ares_init_options(&channel, &options, optmask);
if (status != ARES_SUCCESS) {
free(servers);
fprintf(stderr, "ares_init: %s\n", ares_strerror(status));
return 1;
}
if (servers) {
status = ares_set_servers_csv(channel, servers);
if (status != ARES_SUCCESS) {
fprintf(stderr, "ares_set_serveres_csv: %s\n", ares_strerror(status));
free(servers);
usage();
return 1;
}
free(servers);
}
/* Initiate the queries, one per command-line argument. */
for (; *argv; argv++) {
if (ares_inet_pton(AF_INET, *argv, &addr4) == 1) {
@ -151,7 +175,10 @@ int main(int argc, char **argv)
ares_gethostbyaddr(channel, &addr6, sizeof(addr6), AF_INET6, callback,
*argv);
} else {
ares_gethostbyname(channel, *argv, addr_family, callback, *argv);
struct ares_addrinfo_hints hints;
memset(&hints, 0, sizeof(hints));
hints.ai_family = addr_family;
ares_getaddrinfo(channel, *argv, NULL, &hints, ai_callback, *argv);
}
}
@ -202,25 +229,47 @@ static void callback(void *arg, int status, int timeouts, struct hostent *host)
ares_inet_ntop(host->h_addrtype, *p, addr_buf, sizeof(addr_buf));
printf("%-32s\t%s", host->h_name, addr_buf);
#if 0
if (host->h_aliases[0])
puts("");
}
}
static void ai_callback(void *arg, int status, int timeouts,
struct ares_addrinfo *result)
{
int i;
struct ares_addrinfo_node *node = NULL;
(void)timeouts;
printf (", Aliases: ");
for (i = 0; host->h_aliases[i]; i++)
printf("%s ", host->h_aliases[i]);
if (status != ARES_SUCCESS) {
fprintf(stderr, "%s: %s\n", (char *)arg, ares_strerror(status));
return;
}
#endif
puts("");
for (node = result->nodes; node != NULL; node = node->ai_next) {
char addr_buf[64] = "";
const void *ptr = NULL;
if (node->ai_family == AF_INET) {
struct sockaddr_in *in_addr =
(struct sockaddr_in *)((void *)node->ai_addr);
ptr = &in_addr->sin_addr;
} else if (node->ai_family == AF_INET6) {
struct sockaddr_in6 *in_addr =
(struct sockaddr_in6 *)((void *)node->ai_addr);
ptr = &in_addr->sin6_addr;
} else {
continue;
}
ares_inet_ntop(node->ai_family, ptr, addr_buf, sizeof(addr_buf));
printf("%-32s\t%s\n", result->name, addr_buf);
}
ares_freeaddrinfo(result);
}
static void usage(void)
{
fprintf(
stderr,
"usage: ahost [-h] [-d] [-s {domain}] [-t {a|aaaa|u}] {host|addr} ...\n");
fprintf(stderr, "usage: ahost [-h] [-d] [[-D {domain}] ...] [-s {server}] "
"[-t {a|aaaa|u}] {host|addr} ...\n");
exit(1);
}
@ -229,19 +278,18 @@ static void print_help_info_ahost(void)
{
printf("ahost, version %s\n\n", ARES_VERSION_STR);
printf(
"usage: ahost [-h] [-d] [[-s domain] ...] [-t a|aaaa|u] host|addr ...\n\n"
" h : Display this help and exit.\n"
" d : Print some extra debugging output.\n\n"
" s domain : Specify the domain to search instead of using the default "
"usage: ahost [-h] [-d] [-D domain] [-s server] [-t a|aaaa|u] host|addr "
"...\n\n"
" -h : Display this help and exit.\n"
" -d : Print some extra debugging output.\n\n"
" -D domain : Specify the domain to search instead of using the default "
"values\n"
" from /etc/resolv.conf. This option only has an effect on\n"
" platforms that use /etc/resolv.conf for DNS "
"configuration;\n"
" it has no effect on other platforms (such as Win32 or "
"Android).\n\n"
" t type : If type is \"a\", print the A record (default).\n"
" -s server : Connect to the specified DNS server, instead of the\n"
" system's default one(s). Servers are tried in round-robin,\n"
" if the previous one failed.\n"
" -t type : If type is \"a\", print the A record.\n"
" If type is \"aaaa\", print the AAAA record.\n"
" If type is \"u\", look for either AAAA or A record (in "
"that order).\n\n");
" If type is \"u\" (default), print both A and AAAA records.\n"
"\n");
exit(0);
}

Loading…
Cancel
Save