ref bugnote
[oweals/gnunet.git] / src / util / gnunet-resolver.c
1 /*
2      This file is part of GNUnet.
3      Copyright (C) 2010 GNUnet e.V.
4
5      GNUnet is free software: you can redistribute it and/or modify it
6      under the terms of the GNU Affero General Public License as published
7      by the Free Software Foundation, either version 3 of the License,
8      or (at your option) any later version.
9
10      GNUnet is distributed in the hope that it will be useful, but
11      WITHOUT ANY WARRANTY; without even the implied warranty of
12      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13      Affero General Public License for more details.
14     
15      You should have received a copy of the GNU Affero General Public License
16      along with this program.  If not, see <http://www.gnu.org/licenses/>.
17
18      SPDX-License-Identifier: AGPL3.0-or-later
19 */
20
21 /**
22  * @file util/gnunet-resolver.c
23  * @brief tool to test resolver
24  * @author Christian Grothoff
25  */
26 #include "platform.h"
27 #include "gnunet_util_lib.h"
28 #include "gnunet_resolver_service.h"
29
30 #define GET_TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 5)
31
32 /**
33  * Flag for reverse lookup.
34  */
35 static int reverse;
36
37
38 /**
39  * Prints each hostname obtained from DNS.
40  *
41  * @param cls closure (unused)
42  * @param hostname one of the names for the host, NULL
43  *        on the last call to the callback
44  */
45 static void
46 print_hostname (void *cls,
47                 const char *hostname)
48 {
49   (void) cls;
50   if (NULL == hostname)
51     return;
52   FPRINTF (stdout,
53            "%s\n",
54            hostname);
55 }
56
57
58 /**
59  * Callback function to display address.
60  *
61  * @param cls closure (unused)
62  * @param addr one of the addresses of the host, NULL for the last address
63  * @param addrlen length of the address
64  */
65 static void
66 print_sockaddr (void *cls,
67                 const struct sockaddr *addr,
68                 socklen_t addrlen)
69 {
70   (void) cls;
71   if (NULL == addr)
72     return;
73   FPRINTF (stdout,
74            "%s\n",
75            GNUNET_a2s (addr,
76                        addrlen));
77 }
78
79
80 /**
81  * Main function that will be run by the scheduler.
82  *
83  * @param cls closure
84  * @param args remaining command-line arguments
85  * @param cfgfile name of the configuration file used (for saving, can be NULL!)
86  * @param cfg configuration
87  */
88 static void
89 run (void *cls,
90      char *const *args,
91      const char *cfgfile,
92      const struct GNUNET_CONFIGURATION_Handle *cfg)
93 {
94   const struct sockaddr *sa;
95   socklen_t salen;
96   struct sockaddr_in v4;
97   struct sockaddr_in6 v6;
98
99   (void) cls;
100   (void) cfgfile;
101   (void) cfg;
102   if (NULL == args[0])
103     return;
104   if (! reverse)
105   {
106     GNUNET_RESOLVER_ip_get (args[0],
107                             AF_UNSPEC,
108                             GET_TIMEOUT,
109                             &print_sockaddr,
110                             NULL);
111     return;
112   }
113
114   sa = NULL;
115   memset (&v4, 0, sizeof (v4));
116   v4.sin_family = AF_INET;
117 #if HAVE_SOCKADDR_IN_SIN_LEN
118   v4.sin_len = sizeof (v4);
119 #endif
120   if (1 == inet_pton (AF_INET,
121                       args[0],
122                       &v4.sin_addr))
123   {
124     sa = (struct sockaddr *) &v4;
125     salen = sizeof (v4);
126   }
127   memset (&v6, 0, sizeof (v6));
128   v6.sin6_family = AF_INET6;
129 #if HAVE_SOCKADDR_IN_SIN_LEN
130   v6.sin6_len = sizeof (v6);
131 #endif
132   if (1 == inet_pton (AF_INET6,
133                       args[0],
134                       &v6.sin6_addr))
135   {
136     sa = (struct sockaddr *) &v6;
137     salen = sizeof (v6);
138   }
139   if (NULL == sa)
140   {
141     fprintf (stderr,
142              "`%s' is not a valid IP: %s\n",
143              args[0],
144              strerror (errno));
145     return;
146   }
147   GNUNET_RESOLVER_hostname_get (sa, salen,
148                                 GNUNET_YES,
149                                 GET_TIMEOUT,
150                                 &print_hostname,
151                                 NULL);
152 }
153
154
155 /**
156  * The main function to access GNUnet's DNS resolver.
157  *
158  * @param argc number of arguments from the command line
159  * @param argv command line arguments
160  * @return 0 ok, 1 on error
161  */
162 int
163 main (int argc, char *const *argv)
164 {
165   struct GNUNET_GETOPT_CommandLineOption options[] = {
166     GNUNET_GETOPT_option_flag ('r',
167                                   "reverse",
168                                   gettext_noop ("perform a reverse lookup"),
169                                   &reverse),
170     GNUNET_GETOPT_OPTION_END
171   };
172   int ret;
173
174   if (GNUNET_OK != GNUNET_STRINGS_get_utf8_args (argc, argv, &argc, &argv))
175     return 2;
176
177   ret = (GNUNET_OK ==
178          GNUNET_PROGRAM_run (argc, argv, "gnunet-resolver [hostname]",
179                              gettext_noop ("Use build-in GNUnet stub resolver"),
180                              options, &run, NULL)) ? 0 : 1;
181   GNUNET_free ((void*) argv);
182   return ret;
183 }
184
185 /* end of gnunet-resolver.c */