1 /* DNSTest - Tests InetAddr non-blocking functions
2  * Copyright (C) 2000-2002  David Helder
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Lesser General Public License for more details.
13 
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin Street, Fifth Floor,
17  * Boston, MA  02110-1301  USA
18  */
19 
20 #include <stdio.h>
21 #include <stdlib.h>
22 #include <unistd.h>
23 #include <string.h>
24 #include <glib.h>
25 
26 #include <gnet.h>
27 
28 #define PORT	0x1234
29 
30 gchar* host;
31 gboolean do_reverse = FALSE;
32 gboolean do_async = FALSE;
33 gboolean do_single = FALSE;
34 
35 gint   num_runs = 1;
36 gint   runs_done = 0;
37 
38 void lookup_block_single (int run);
39 void lookup_block_list (int run);
40 
41 void lookup_async_forward(int run);
42 void inetaddr_cb(GInetAddr* inetaddr, gpointer data);
43 
44 void lookup_async_forward_list (int run);
45 void list_cb(GList* ialist, gpointer data);
46 
47 void lookup_async_reverse(int run);
48 void reverse_inetaddr_cb(gchar* name, gpointer data);
49 
50 
51 void usage(void);
52 
53 
54 
55 
56 struct ReverseState
57 {
58   GInetAddr* ia;
59   gint num;
60 };
61 
62 
63 
64 int
main(int argc,char ** argv)65 main(int argc, char** argv)
66 {
67   extern char* optarg;
68   extern int   optind;
69   int c;
70 
71   gnet_init ();
72 
73   /* Parse arguments */
74   while ((c = getopt(argc, argv, "arsn:")) != -1)
75     {
76       switch (c)
77 	{
78 	case 'a':
79 	  do_async = TRUE;
80 	  break;
81 	case 'r':
82 	  do_reverse = TRUE;
83 	  break;
84 	case 's':
85 	  do_single = TRUE;
86 	  break;
87 	case 'n':
88 	  num_runs = atoi(optarg);
89 	  break;
90 	case 'h':
91 	case '?':
92 	  usage();
93 	  break;
94 	}
95     }
96 
97   if (argc == optind)
98     usage();
99 
100   host = argv[optind];
101 
102   if (!do_async)
103     {
104       int i;
105 
106       for (i = 0; i < num_runs; ++i)
107 	{
108 	  if (do_single)
109 	    lookup_block_single(i);
110 	  else
111 	    lookup_block_list(i);
112 	}
113     }
114   else
115     {
116       int i;
117       GMainLoop* main_loop = NULL;
118 
119       main_loop = g_main_new(FALSE);
120 
121       for (i = 0; i < num_runs; ++i)
122 	{
123 	  if (!do_reverse)
124 	    {
125 	      if (do_single)
126 		lookup_async_forward(i);
127 	      else
128 		lookup_async_forward_list(i);
129 	    }
130 	  else
131 	    lookup_async_reverse(i);
132 	}
133 
134       g_main_run(main_loop);
135     }
136 
137   exit(EXIT_SUCCESS);
138 }
139 
140 
141 void
lookup_block_single(int run)142 lookup_block_single (int run)
143 {
144   GInetAddr* ia;
145   gchar* name;
146 
147   ia = gnet_inetaddr_new (host, PORT);
148   if (ia == NULL)
149     {
150       fprintf (stderr, "DNS lookup for %s failed\n", host);
151       exit (EXIT_FAILURE);
152     }
153 
154   g_assert (gnet_inetaddr_get_port(ia) == PORT);
155 
156   if (do_reverse)
157     name = gnet_inetaddr_get_name(ia);
158   else
159     name = gnet_inetaddr_get_canonical_name(ia);
160   g_assert (name != NULL);
161 
162   g_print ("%d: %s -> %s\n", run, host, name);
163 
164   g_free (name);
165 
166   gnet_inetaddr_delete (ia);
167 }
168 
169 
170 void
lookup_block_list(int run)171 lookup_block_list (int run)
172 {
173   GList* ialist;
174   GList* i;
175   gchar* name;
176 
177   ialist = gnet_inetaddr_new_list(host, PORT);
178   if (ialist == NULL)
179     {
180       g_print ("DNS lookup for %s failed\n", host);
181       exit (EXIT_FAILURE);
182     }
183 
184   for (i = ialist; i != NULL; i = i->next)
185     {
186       GInetAddr* ia;
187 
188       ia = (GInetAddr*) i->data;
189 
190       g_assert (gnet_inetaddr_get_port(ia) == PORT);
191 
192       if (do_reverse)
193 	name = gnet_inetaddr_get_name(ia);
194       else
195 	name = gnet_inetaddr_get_canonical_name(ia);
196 
197       g_assert (name != NULL);
198 
199       g_print ("%d: %s -> %s\n", run, host, name);
200 
201       g_free (name);
202       gnet_inetaddr_delete (ia);
203     }
204 
205   g_list_free (ialist);
206 }
207 
208 
209 /* **************************************** */
210 
211 
212 void
lookup_async_forward(int run)213 lookup_async_forward (int run)
214 {
215   gnet_inetaddr_new_async(host, PORT, inetaddr_cb, GINT_TO_POINTER(run));
216 }
217 
218 
219 void
inetaddr_cb(GInetAddr * ia,gpointer data)220 inetaddr_cb(GInetAddr* ia, gpointer data)
221 {
222   int i = GPOINTER_TO_INT(data);
223 
224   if (ia)
225     {
226       gchar* cname;
227 
228       g_assert (gnet_inetaddr_get_port(ia) == PORT);
229 
230       cname = gnet_inetaddr_get_canonical_name(ia);
231       if (cname == NULL)
232 	{
233 	  g_print ("Reverse DNS lookup failed\n");
234 	  exit (EXIT_FAILURE);
235 	}
236 
237       g_print ("%d: %s -> %s\n", i, host, cname);
238 
239       g_free (cname);
240     }
241 
242   else
243     g_print ("%d: DNS lookup failed\n", i);
244 
245   runs_done++;
246 
247   if (runs_done == num_runs)
248     exit(EXIT_SUCCESS);
249 }
250 
251 /* ******************** */
252 
253 void
lookup_async_forward_list(int run)254 lookup_async_forward_list (int run)
255 {
256   gnet_inetaddr_new_list_async(host, PORT, list_cb, GINT_TO_POINTER(run));
257 }
258 
259 
260 void
list_cb(GList * ialist,gpointer data)261 list_cb(GList* ialist, gpointer data)
262 {
263   int run = GPOINTER_TO_INT(data);
264 
265   if (ialist)
266     {
267       GList* i;
268 
269       for (i = ialist; i != NULL; i = i->next)
270 	{
271 	  GInetAddr* ia;
272 	  gchar* cname;
273 
274 	  ia = (GInetAddr*) i->data;
275 
276 	  g_assert (gnet_inetaddr_get_port(ia) == PORT);
277 
278 	  cname = gnet_inetaddr_get_canonical_name(ia);
279 	  g_assert (cname);
280 
281 	  g_print ("%d: %s -> %s\n", run, host, cname);
282 
283 	  g_free (cname);
284 	  gnet_inetaddr_delete (ia);
285 	}
286       g_list_free (ialist);
287     }
288 
289   else
290     g_print ("%d: DNS lookup failed\n", run);
291 
292   runs_done++;
293 
294   if (runs_done == num_runs)
295     exit(EXIT_SUCCESS);
296 }
297 
298 
299 
300 /* ******************** */
301 
302 void
lookup_async_reverse(int run)303 lookup_async_reverse (int run)
304 {
305   GInetAddr* ia;
306   struct ReverseState* rs;
307 
308   ia = gnet_inetaddr_new(host, 0);
309   if (ia == NULL)
310     {
311       g_print ("DNS lookup for %s failed\n", host);
312       exit (EXIT_FAILURE);
313     }
314 
315   rs = g_new0(struct ReverseState, 1);
316   rs->ia = ia;
317   rs->num = run;
318 
319   gnet_inetaddr_get_name_async(ia, reverse_inetaddr_cb, rs);
320 }
321 
322 
323 void
reverse_inetaddr_cb(gchar * name,gpointer data)324 reverse_inetaddr_cb (gchar* name, gpointer data)
325 {
326   struct ReverseState* rs = (struct ReverseState*) data;
327 
328 
329   if (name)
330     {
331       gchar* cname;
332 
333       cname = gnet_inetaddr_get_canonical_name(rs->ia);
334       if (cname == NULL)
335 	{
336 	  g_print ("Reverse DNS lookup for %s failed\n", name);
337 	  exit (EXIT_FAILURE);
338 	}
339 
340       g_print ("%d: %s -> %s (reverse)\n", rs->num, cname, name);
341 
342       g_free(cname);
343     }
344   else
345     g_print ("%d: error\n", rs->num);
346 
347   gnet_inetaddr_delete (rs->ia);
348   g_free (rs);
349 
350   runs_done++;
351 
352   if (runs_done == num_runs)
353     exit(EXIT_SUCCESS);
354 }
355 
356 
357 /* **************************************** */
358 
359 
360 void
usage(void)361 usage(void)
362 {
363   g_print ("dnslookup -a -r -s -n <num runs> <host>\n");
364   g_print ("  -a                asynchronous\n");
365   g_print ("  -r                reverse lookup\n");
366   g_print ("  -s                single forward lookup\n");
367   g_print ("  -n <num runs>     number of lookups\n");
368 
369   exit (EXIT_FAILURE);
370 }
371