blob: 5113acdfc2e19af15de2a9484d1268f5a4c01248 [file] [log] [blame]
lh9ed821d2023-04-07 01:36:19 -07001/* Copyright 1998 by the Massachusetts Institute of Technology.
2 *
3 *
4 * Permission to use, copy, modify, and distribute this
5 * software and its documentation for any purpose and without
6 * fee is hereby granted, provided that the above copyright
7 * notice appear in all copies and that both that copyright
8 * notice and this permission notice appear in supporting
9 * documentation, and that the name of M.I.T. not be used in
10 * advertising or publicity pertaining to distribution of the
11 * software without specific, written prior permission.
12 * M.I.T. makes no representations about the suitability of
13 * this software for any purpose. It is provided "as is"
14 * without express or implied warranty.
15 */
16
17#include "ares_setup.h"
18
19#if !defined(WIN32) || defined(WATT32)
20#include <netinet/in.h>
21#include <arpa/inet.h>
22#include <netdb.h>
23#endif
24
25#ifdef HAVE_STRINGS_H
26#include <strings.h>
27#endif
28
29#include "ares.h"
30#include "ares_dns.h"
31#include "ares_getopt.h"
32#include "ares_ipv6.h"
33#include "ares_nowarn.h"
34
35#ifndef HAVE_STRDUP
36# include "ares_strdup.h"
37# define strdup(ptr) ares_strdup(ptr)
38#endif
39
40#ifndef HAVE_STRCASECMP
41# include "ares_strcasecmp.h"
42# define strcasecmp(p1,p2) ares_strcasecmp(p1,p2)
43#endif
44
45#ifndef HAVE_STRNCASECMP
46# include "ares_strcasecmp.h"
47# define strncasecmp(p1,p2,n) ares_strncasecmp(p1,p2,n)
48#endif
49
50static void callback(void *arg, int status, int timeouts, struct hostent *host);
51static void usage(void);
52
53
54int main(int argc, char **argv)
55{
56 struct ares_options options;
57 int optmask = 0;
58 ares_channel channel;
59 int status, nfds, c, addr_family = AF_INET;
60 fd_set read_fds, write_fds;
61 struct timeval *tvp, tv;
62 struct in_addr addr4;
63 struct ares_in6_addr addr6;
64 char *ares_dev = NULL;
65#ifdef USE_WINSOCK
66 WORD wVersionRequested = MAKEWORD(USE_WINSOCK,USE_WINSOCK);
67 WSADATA wsaData;
68 WSAStartup(wVersionRequested, &wsaData);
69#endif
70
71 memset(&options, 0, sizeof(options));
72
73 status = ares_library_init(ARES_LIB_INIT_NONE);
74 if (status != ARES_SUCCESS)
75 {
76 fprintf(stderr, "ares_library_init: %s\n", ares_strerror(status));
77 return 1;
78 }
79
80 while ((c = ares_getopt(argc,argv,"dt:hs:i:")) != -1)
81 {
82 switch (c)
83 {
84 case 'd':
85#ifdef WATT32
86 dbug_init();
87#endif
88 break;
89 case 's':
90 optmask |= ARES_OPT_DOMAINS;
91 options.ndomains++;
92 options.domains = (char **)realloc(options.domains,
93 options.ndomains * sizeof(char *));
94 options.domains[options.ndomains - 1] = strdup(optarg);
95 break;
96 case 'i':
97
98 ares_dev = (char * )strdup(optarg);
99 fprintf(stderr, "ares_dev is %s\n", ares_dev);
100 break;
101 case 't':
102 if (!strcasecmp(optarg,"a"))
103 addr_family = AF_INET;
104 else if (!strcasecmp(optarg,"aaaa"))
105 addr_family = AF_INET6;
106 else if (!strcasecmp(optarg,"u"))
107 addr_family = AF_UNSPEC;
108 else
109 usage();
110 break;
111 case 'h':
112 default:
113 usage();
114 break;
115 }
116 }
117
118 argc -= optind;
119 argv += optind;
120 if (argc < 1)
121 usage();
122
123 status = ares_init_options(&channel, &options, optmask, ares_dev);
124 //fprintf(stderr, "ares_init_options: %s\n", channel.local_dev_name);
125 if (status != ARES_SUCCESS)
126 {
127 fprintf(stderr, "ares_init: %s\n", ares_strerror(status));
128 return 1;
129 }
130
131 /* Initiate the queries, one per command-line argument. */
132 for ( ; *argv; argv++)
133 {
134 if (ares_inet_pton(AF_INET, *argv, &addr4) == 1)
135 {
136 ares_gethostbyaddr(channel, &addr4, sizeof(addr4), AF_INET, callback,
137 *argv);
138 }
139 else if (ares_inet_pton(AF_INET6, *argv, &addr6) == 1)
140 {
141 ares_gethostbyaddr(channel, &addr6, sizeof(addr6), AF_INET6, callback,
142 *argv);
143 }
144 else
145 {
146 ares_gethostbyname(channel, *argv, addr_family, callback, *argv);
147 }
148 }
149
150 /* Wait for all queries to complete. */
151 for (;;)
152 {
153 int res;
154 FD_ZERO(&read_fds);
155 FD_ZERO(&write_fds);
156 nfds = ares_fds(channel, &read_fds, &write_fds);
157 if (nfds == 0)
158 break;
159 tvp = ares_timeout(channel, NULL, &tv);
160 res = select(nfds, &read_fds, &write_fds, NULL, tvp);
161 if (-1 == res)
162 break;
163 ares_process(channel, &read_fds, &write_fds);
164 }
165
166 ares_destroy(channel);
167
168 ares_library_cleanup();
169
170#ifdef USE_WINSOCK
171 WSACleanup();
172#endif
173
174 return 0;
175}
176
177static void callback(void *arg, int status, int timeouts, struct hostent *host)
178{
179 char **p;
180
181 (void)timeouts;
182
183 if (status != ARES_SUCCESS)
184 {
185 fprintf(stderr, "%s: %s\n", (char *) arg, ares_strerror(status));
186 return;
187 }
188
189 for (p = host->h_addr_list; *p; p++)
190 {
191 char addr_buf[46] = "??";
192
193 ares_inet_ntop(host->h_addrtype, *p, addr_buf, sizeof(addr_buf));
194 printf("%-32s\t%s", host->h_name, addr_buf);
195#if 0
196 if (host->h_aliases[0])
197 {
198 int i;
199
200 printf (", Aliases: ");
201 for (i = 0; host->h_aliases[i]; i++)
202 printf("%s ", host->h_aliases[i]);
203 }
204#endif
205 puts("");
206 }
207}
208
209static void usage(void)
210{
211 fprintf(stderr, "usage: ahost [-t {a|aaaa|u}] {host|addr} ...\n");
212 exit(1);
213}