1 /***************************************************************************
2 * _ _ ____ _
3 * Project ___| | | | _ \| |
4 * / __| | | | |_) | |
5 * | (__| |_| | _ <| |___
6 * \___|\___/|_| \_\_____|
7 *
8 * Copyright (C) Daniel Stenberg, <daniel@haxx.se>, et al.
9 *
10 * This software is licensed as described in the file COPYING, which
11 * you should have received as part of this distribution. The terms
12 * are also available at https://curl.se/docs/copyright.html.
13 *
14 * You may opt to use, copy, modify, merge, publish, distribute and/or sell
15 * copies of the Software, and permit persons to whom the Software is
16 * furnished to do so, under the terms of the COPYING file.
17 *
18 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
19 * KIND, either express or implied.
20 *
21 * SPDX-License-Identifier: curl
22 *
23 ***************************************************************************/
24 #ifndef CURL_NO_GETADDRINFO_OVERRIDE
25 #define CURL_NO_GETADDRINFO_OVERRIDE
26 #endif
27
28 #include "server_setup.h"
29
30 /* Purpose
31 *
32 * Resolve the given name, using system name resolve functions (NOT any
33 * function provided by libcurl). Used to see if the name exists and thus if
34 * we can allow a test case to use it for testing.
35 *
36 * Like if 'localhost' actual exists etc.
37 *
38 */
39
40 #include <signal.h>
41 #ifdef HAVE_NETINET_IN_H
42 #include <netinet/in.h>
43 #endif
44 #ifdef _XOPEN_SOURCE_EXTENDED
45 /* This define is "almost" required to build on HP-UX 11 */
46 #include <arpa/inet.h>
47 #endif
48 #ifdef HAVE_NETDB_H
49 #include <netdb.h>
50 #endif
51
52 #include "curlx.h" /* from the private lib dir */
53 #include "util.h"
54
55 /* include memdebug.h last */
56 #include "memdebug.h"
57
58 static bool use_ipv6 = FALSE;
59 static const char *ipv_inuse = "IPv4";
60
61 const char *serverlogfile = ""; /* for a util.c function we don't use */
62
main(int argc,char * argv[])63 int main(int argc, char *argv[])
64 {
65 int arg = 1;
66 const char *host = NULL;
67 int rc = 0;
68
69 while(argc > arg) {
70 if(!strcmp("--version", argv[arg])) {
71 printf("resolve IPv4%s\n",
72 #if defined(CURLRES_IPV6)
73 "/IPv6"
74 #else
75 ""
76 #endif
77 );
78 return 0;
79 }
80 else if(!strcmp("--ipv6", argv[arg])) {
81 ipv_inuse = "IPv6";
82 use_ipv6 = TRUE;
83 arg++;
84 }
85 else if(!strcmp("--ipv4", argv[arg])) {
86 /* for completeness, we support this option as well */
87 ipv_inuse = "IPv4";
88 use_ipv6 = FALSE;
89 arg++;
90 }
91 else {
92 host = argv[arg++];
93 }
94 }
95 if(!host) {
96 puts("Usage: resolve [option] <host>\n"
97 " --version\n"
98 " --ipv4"
99 #if defined(CURLRES_IPV6)
100 "\n --ipv6"
101 #endif
102 );
103 return 1;
104 }
105
106 #ifdef _WIN32
107 win32_init();
108 atexit(win32_cleanup);
109 #endif
110
111 #if defined(CURLRES_IPV6)
112 if(use_ipv6) {
113 /* Check that the system has IPv6 enabled before checking the resolver */
114 curl_socket_t s = socket(PF_INET6, SOCK_DGRAM, 0);
115 if(s == CURL_SOCKET_BAD)
116 /* an IPv6 address was requested and we can't get/use one */
117 rc = -1;
118 else {
119 sclose(s);
120 }
121 }
122
123 if(rc == 0) {
124 /* getaddrinfo() resolve */
125 struct addrinfo *ai;
126 struct addrinfo hints;
127
128 memset(&hints, 0, sizeof(hints));
129 hints.ai_family = use_ipv6 ? PF_INET6 : PF_INET;
130 hints.ai_socktype = SOCK_STREAM;
131 hints.ai_flags = 0;
132 rc = getaddrinfo(host, "80", &hints, &ai);
133 if(rc == 0)
134 freeaddrinfo(ai);
135 }
136 #else
137 if(use_ipv6) {
138 puts("IPv6 support has been disabled in this program");
139 return 1;
140 }
141 else {
142 /* gethostbyname() resolve */
143 struct hostent *he;
144
145 he = gethostbyname(host);
146
147 rc = !he;
148 }
149 #endif
150
151 if(rc)
152 printf("Resolving %s '%s' didn't work\n", ipv_inuse, host);
153
154 return !!rc;
155 }
156