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