xref: /minix/minix/tests/test48.c (revision 9f81acbc)
1 #include <arpa/inet.h>
2 #include <assert.h>
3 #include <netdb.h>
4 #include <stdio.h>
5 #include <stdlib.h>
6 #include <string.h>
7 #include <unistd.h>
8 
9 int max_error = 3;
10 #include "common.h"
11 
12 #define err() e(__LINE__)
13 
14 static void printstr(const char *s)
15 {
16 	if (s)
17 		printf("\"%s\"", s);
18 	else
19 		printf("NULL");
20 }
21 
22 static void test_getaddrinfo_err(
23 	int n,
24 	const char *nodename,
25 	const char *servname,
26 	int passhints,
27 	int flags,
28 	int family,
29 	int socktype,
30 	const char *exp_result,
31 	const char *result)
32 {
33 	printf("error %d: getaddrinfo(", n);
34 	printstr(nodename);
35 	printf(", ");
36 	printstr(servname);
37 	printf(", ");
38 	if (passhints)
39 		printf("{ 0x%x, %d, %d }", flags, family, socktype);
40 	else
41 		printf("NULL");
42 
43 	printf("); result: ");
44 	printstr(result);
45 	printf("; expected: ");
46 	printstr(exp_result);
47 	printf("\n");
48 	err();
49 }
50 
51 /* yes, this is ugly, but not as ugly as repeating it all every time */
52 #define TEST_GETADDRINFO_ERR_PARAMS \
53 	nodename, servname, passhints, flags, family, socktype
54 
55 static void test_getaddrinfo_err_nr(
56 	int n,
57 	const char *nodename,
58 	const char *servname,
59 	int passhints,
60 	int flags,
61 	int family,
62 	int socktype,
63 	int exp_result,
64 	int result)
65 {
66 	char exp_result_s[23], result_s[23];
67 
68 	/* convert result to string */
69 	snprintf(exp_result_s, sizeof(exp_result_s), "%d/0x%x",
70 		exp_result, exp_result);
71 	snprintf(result_s, sizeof(result_s), "%d/0x%x", result, result);
72 	test_getaddrinfo_err(n, TEST_GETADDRINFO_ERR_PARAMS,
73 		exp_result_s, result_s);
74 }
75 
76 static void test_getnameinfo_err(
77 	int n,
78 	unsigned long ipaddr,
79 	unsigned short port,
80 	socklen_t nodelen,
81 	socklen_t servicelen,
82 	int flags,
83 	const char *exp_result,
84 	const char *result)
85 {
86 	printf("error %d: getnameinfo(0x%.8x, %d, %d, %d, 0x%x); result: ",
87 		n, ntohl(ipaddr), ntohs(port), nodelen, servicelen, flags);
88 	printstr(result);
89 	printf("; expected: ");
90 	printstr(exp_result);
91 	printf("\n");
92 	err();
93 }
94 
95 /* yes, this is ugly, but not as ugly as repeating it all every time */
96 #define TEST_GETNAMEINFO_ERR_PARAMS ipaddr, port, nodelen, servicelen, flags
97 
98 static void test_getnameinfo_err_nr(
99 	int n,
100 	unsigned long ipaddr,
101 	unsigned short port,
102 	socklen_t nodelen,
103 	socklen_t servicelen,
104 	int flags,
105 	int exp_result,
106 	int result)
107 {
108 	char exp_result_s[23], result_s[23];
109 
110 	/* convert result to string */
111 	snprintf(exp_result_s, sizeof(exp_result_s), "%d/0x%x",
112 		exp_result, exp_result);
113 	snprintf(result_s, sizeof(result_s), "%d/0x%x", result, result);
114 	test_getnameinfo_err(n, TEST_GETNAMEINFO_ERR_PARAMS,
115 		exp_result_s, result_s);
116 }
117 
118 static void test_getaddrinfo(
119 	const char *nodename,
120 	int nodename_numerical,
121 	const char *servname,
122 	int servname_numerical,
123 	int passhints,
124 	int flags,
125 	int family,
126 	int socktype,
127 	int exp_results,
128 	unsigned long exp_ip,
129 	int exp_canonname,
130 	unsigned short exp_port)
131 {
132 	struct addrinfo *ai, *ai_cur;
133 	struct addrinfo hints;
134 	struct sockaddr_in *sockaddr_in;
135 	int ai_count_dgram, ai_count_stream, r;
136 
137 	/* some parameters are only meaningful with hints */
138 	assert(passhints || !flags);
139 	assert(passhints || family == AF_UNSPEC);
140 	assert(passhints || !socktype);
141 
142 	/* a combination of parameters don't make sense to test */
143 	if (nodename == NULL && servname == NULL) return;
144 	if (nodename == NULL && (flags & AI_NUMERICHOST)) return;
145 	if (servname == NULL && (flags & AI_NUMERICSERV)) return;
146 
147 	/* initialize hints */
148 	memset(&hints, 0, sizeof(hints));
149 	hints.ai_flags = flags;
150 	hints.ai_family = family;
151 	hints.ai_socktype = socktype;
152 
153 	/* perform query and test result */
154 	ai = (struct addrinfo *) 0xDEADBEEF;
155 	r = getaddrinfo(nodename, servname, passhints ? &hints : NULL, &ai);
156 	if (r < 0 || r >= 32 || !((1 << r) & exp_results))
157 		test_getaddrinfo_err_nr(1, TEST_GETADDRINFO_ERR_PARAMS, exp_results, r);
158 
159 	if (r)
160 		return;
161 
162 	/* the function succeeded; do the results make sense? */
163 	ai_cur = ai;
164 	ai_count_dgram = 0;
165 	ai_count_stream = 0;
166 	while (ai_cur)
167 	{
168 		/*
169 		 * TODO: this test was written for IPv4.  For now, skip IPv6
170 		 * results altogether.  Later, we should add additional code
171 		 * for IPv6.  However, since this test now largely exercises
172 		 * NetBSD code, it is not as important as it once was.
173 		 */
174 		if (ai_cur->ai_family == AF_INET6) {
175 			ai_cur = ai_cur->ai_next;
176 			continue;
177 		}
178 
179 		/* test result fields */
180 		if (ai_cur->ai_family != AF_INET)
181 			test_getaddrinfo_err_nr(2, TEST_GETADDRINFO_ERR_PARAMS,
182 				AF_INET, ai_cur->ai_family);
183 
184 		if (socktype && ai_cur->ai_socktype != socktype)
185 			test_getaddrinfo_err_nr(3, TEST_GETADDRINFO_ERR_PARAMS,
186 				socktype, ai_cur->ai_socktype);
187 
188 		switch (ai_cur->ai_socktype)
189 		{
190 			case SOCK_DGRAM:  ai_count_dgram++;  break;
191 			case SOCK_STREAM: ai_count_stream++; break;
192 		}
193 
194 		/* do address and port match? */
195 		if (ai_cur->ai_addrlen != sizeof(struct sockaddr_in))
196 			test_getaddrinfo_err_nr(4, TEST_GETADDRINFO_ERR_PARAMS,
197 				sizeof(struct sockaddr_in),
198 				ai_cur->ai_addrlen);
199 		else
200 		{
201 			sockaddr_in = (struct sockaddr_in *) ai_cur->ai_addr;
202 			if (sockaddr_in->sin_addr.s_addr != exp_ip)
203 				test_getaddrinfo_err_nr(5,
204 					TEST_GETADDRINFO_ERR_PARAMS,
205 					ntohl(exp_ip),
206 					ntohl(sockaddr_in->sin_addr.s_addr));
207 
208 			if (sockaddr_in->sin_port != exp_port)
209 				test_getaddrinfo_err_nr(6,
210 					TEST_GETADDRINFO_ERR_PARAMS,
211 					ntohs(exp_port),
212 					ntohs(sockaddr_in->sin_port));
213 		}
214 
215 		/* If a hostname is numeric, there can't be a canonical name.
216 		 * Instead, the returned canonname (if requested) will be
217 		 * identical to the supplied hostname */
218 		if (nodename != NULL && nodename_numerical &&
219 		    (flags & AI_CANONNAME)) {
220 			if (strncmp(ai_cur->ai_canonname, nodename,
221 					strlen(nodename)))
222 			test_getaddrinfo_err(11,
223 				TEST_GETADDRINFO_ERR_PARAMS,
224 				nodename, ai_cur->ai_canonname);
225 		} else {
226 			/* is canonical supplied? */
227 			if (exp_canonname && nodename &&
228 			    (!ai_cur->ai_canonname || !*ai_cur->ai_canonname))
229 				test_getaddrinfo_err(7,
230 					TEST_GETADDRINFO_ERR_PARAMS,
231 					"(anything)", ai_cur->ai_canonname);
232 
233 			if (!exp_canonname && ai_cur->ai_canonname)
234 				test_getaddrinfo_err(8,
235 					TEST_GETADDRINFO_ERR_PARAMS,
236 					NULL, ai_cur->ai_canonname);
237 
238 		}
239 		/* move to next result */
240 		ai_cur = ai_cur->ai_next;
241 	}
242 
243 	/* If socket type is non-zero, make sure we got what we wanted. Else
244 	 * any result is okay. */
245 	if (socktype) {
246 		if (ai_count_dgram != ((socktype == SOCK_STREAM) ? 0 : 1))
247 			test_getaddrinfo_err_nr(9, TEST_GETADDRINFO_ERR_PARAMS,
248 			(socktype == SOCK_STREAM) ? 0 : 1, ai_count_dgram);
249 
250 		if (ai_count_stream != ((socktype == SOCK_DGRAM) ? 0 : 1))
251 			test_getaddrinfo_err_nr(10, TEST_GETADDRINFO_ERR_PARAMS,
252 			(socktype == SOCK_DGRAM) ? 0 : 1, ai_count_stream);
253 	}
254 
255 	/* clean up */
256 	freeaddrinfo(ai);
257 }
258 
259 static void memsetl(void *s, unsigned long c, size_t n)
260 {
261 	unsigned char *p = (unsigned char *) s;
262 	size_t i;
263 
264 	for (i = 0; i < n; i++)
265 		p[i] = c >> (8 * (i % sizeof(c)));
266 }
267 
268 static void test_getnameinfo(
269 	unsigned long ipaddr,
270 	unsigned short port,
271 	const char *exp_node,
272 	socklen_t nodelen,
273 	const char *exp_service,
274 	socklen_t servicelen,
275 	int flags,
276 	int exp_results)
277 {
278 	struct sockaddr_in sockaddr;
279 	char node[256], service[256];
280 	int r;
281 
282 	/* avoid buffer overflows */
283 	assert(nodelen <= sizeof(node));
284 	assert(servicelen <= sizeof(service));
285 
286 	/* perform query and test result */
287 	sockaddr.sin_family = AF_INET;
288 	sockaddr.sin_addr.s_addr = ipaddr;
289 	sockaddr.sin_port = port;
290 	memsetl(node, 0xDEADBEEF, nodelen);
291 	memsetl(service, 0xDEADBEEF, servicelen);
292 	r = getnameinfo((struct sockaddr *) &sockaddr, sizeof(sockaddr),
293 		node, nodelen, service, servicelen, flags);
294 
295 	if (r < 0 || r >= 32 || !((1 << r) & exp_results))
296 		test_getnameinfo_err_nr(1, TEST_GETNAMEINFO_ERR_PARAMS,
297 			exp_results, r);
298 
299 	if (r)
300 		return;
301 
302 	/* check results */
303 	if (nodelen && strcmp(exp_node, node) != 0)
304 		test_getnameinfo_err(2, TEST_GETNAMEINFO_ERR_PARAMS,
305 			exp_node, node);
306 
307 	if (servicelen && strcmp(exp_service, service) != 0)
308 		test_getnameinfo_err(2, TEST_GETNAMEINFO_ERR_PARAMS,
309 			exp_service, service);
310 }
311 
312 static struct
313 {
314 	const char *nodename;
315 	unsigned long ipaddr;
316 	int numeric;
317 	int canonname;
318 	int need_network;
319 	int exp_result;
320 } hosts[] = {
321 	{ NULL,             0x7f000001, 1, 1, 0, 0                 },
322 	{ "0.0.0.0",        0x00000000, 1, 0, 0, 0                 },
323 	{ "0.0.0.255",      0x000000ff, 1, 0, 0, 0                 },
324 	{ "0.0.255.0",      0x0000ff00, 1, 0, 0, 0                 },
325 	{ "0.255.0.0",      0x00ff0000, 1, 0, 0, 0                 },
326 	{ "255.0.0.0",      0xff000000, 1, 0, 0, 0                 },
327 	{ "127.0.0.1",      0x7f000001, 1, 0, 0, 0                 },
328 	{ "localhost",      0x7f000001, 0, 1, 0, 0,                },
329 	{ "test48.minix3.org", 0x7f010203, 0, 1, 1, 0,             },
330 	{ "minix3.example.com",     0x00000000, 0, 0, 1, (1<<EAI_NONAME)|(1<<EAI_FAIL)|(1<<EAI_NODATA)}};
331 
332 static struct
333 {
334 	const char *servname;
335 	unsigned short port;
336 	int numeric;
337 	int socktype;
338 	int exp_result;
339 } services[] = {
340 	{ NULL,        0, 1, 0,           0                  },
341 	{ "0",         0, 1, 0,           0                  },
342 	{ "1",         1, 1, 0,           0                  },
343 	{ "32767", 32767, 1, 0,           0                  },
344 	{ "32768", 32768, 1, 0,           0                  },
345 	{ "65535", 65535, 1, 0,           0                  },
346 	{ "echo",      7, 0, 0,           0                  },
347 	{ "ftp",      21, 0, 0, 0                  },
348 	{ "tftp",     69, 0, 0, 0                  },
349 	{ "-1",        0, 1, 0,           (1<<EAI_NONAME) | (1<<EAI_SERVICE) },
350 	{ "",          0, 1, 0,           (1<<EAI_NONAME) | (1<<EAI_SERVICE) },
351 	{ "65537",     0, 1, 0,           (1 << EAI_SERVICE) },
352 	{ "XXX",       0, 0, 0,           (1 << EAI_SERVICE) }};
353 
354 static struct
355 {
356 	int value;
357 	int exp_result;
358 } families[] = {
359 	{ AF_UNSPEC,               0                 },
360 	{ AF_INET,                 0                 },
361 	{ AF_UNSPEC + AF_INET + 1, (1 << EAI_FAMILY)    }};
362 
363 static struct
364 {
365 	int value;
366 	int exp_result;
367 } socktypes[] = {
368 	{ 0,                            0                   },
369 	{ SOCK_STREAM,                  0                   },
370 	{ SOCK_DGRAM,                   0                   },
371 	{ SOCK_STREAM + SOCK_DGRAM + 1,
372 		(1 << EAI_SOCKTYPE) | (1 << EAI_FAIL) | (1 << EAI_NONAME) }};
373 
374 #define LENGTH(a) (sizeof((a)) / sizeof((a)[0]))
375 
376 static void test_getaddrinfo_all(int use_network)
377 {
378 	int flag_PASSIVE, flag_CANONNAME, flag_NUMERICHOST, flag_NUMERICSERV;
379 	int exp_results, flags, flagcount, i, j, k, l, passhints;
380 	unsigned long ipaddr;
381 
382 	/* loop through various parameter values */
383 	for (i = 0; i < LENGTH(hosts);     i++)
384 	for (j = 0; j < LENGTH(services);  j++)
385 	for (k = 0; k < LENGTH(families);  k++)
386 	for (l = 0; l < LENGTH(socktypes); l++)
387 	for (flag_PASSIVE     = 0; flag_PASSIVE < 2;     flag_PASSIVE++)
388 	for (flag_CANONNAME   = 0; flag_CANONNAME < 2;   flag_CANONNAME++)
389 	for (flag_NUMERICHOST = 0; flag_NUMERICHOST < 2; flag_NUMERICHOST++)
390 	for (flag_NUMERICSERV = 0; flag_NUMERICSERV < 2; flag_NUMERICSERV++)
391 	for (passhints = 0; passhints < 2; passhints++)
392 	{
393 		/* skip some redundant combinations */
394 		flagcount = flag_PASSIVE + flag_CANONNAME +
395 			flag_NUMERICHOST + flag_NUMERICSERV;
396 		if (flagcount > 1 && flagcount < 4) continue;
397 
398 		/* skip tests that need but cannot use network */
399 		if (!use_network && hosts[i].need_network)
400 			continue;
401 
402 		/* determine flags */
403 		flags = (flag_PASSIVE     ? AI_PASSIVE : 0) |
404 			(flag_CANONNAME   ? AI_CANONNAME : 0) |
405 			(flag_NUMERICHOST ? AI_NUMERICHOST : 0) |
406 			(flag_NUMERICSERV ? AI_NUMERICSERV : 0);
407 
408 		/* some options require hints */
409 		if (families[k].value != AF_UNSPEC ||
410 		    socktypes[l].value != 0 || flags)  {
411 			passhints = 1;
412 		}
413 
414 		/* flags may influence IP address */
415 		ipaddr = hosts[i].ipaddr;
416 		if (!hosts[i].nodename && flag_PASSIVE)
417 			ipaddr = INADDR_ANY;
418 
419 		/* determine expected result */
420 		exp_results =
421 			hosts[i].exp_result |
422 			services[j].exp_result |
423 			families[k].exp_result |
424 			socktypes[l].exp_result;
425 		if (!hosts[i].nodename && !services[j].servname)
426 			exp_results |= (1 << EAI_NONAME);
427 
428 		if (flag_NUMERICHOST && !hosts[i].numeric)
429 			exp_results |= (1 << EAI_NONAME);
430 
431 		if (flag_NUMERICSERV && !services[j].numeric)
432 			exp_results |= (1 << EAI_NONAME);
433 
434 		/* When we don't pass hints, getaddrinfo will find suitable
435 		 * settings for us. If we do pass hints, there might be
436 		 * conflicts.
437 		 */
438 		if (passhints) {
439 			/* Can't have conflicting socket types */
440 			if (services[j].socktype &&
441 			    socktypes[l].value &&
442 			    socktypes[l].value != services[j].socktype) {
443 				exp_results |= (1 << EAI_SERVICE);
444 			}
445 		}
446 
447 		/* with no reason for failure, we demand success */
448 		if (!exp_results)
449 			exp_results |= (1 << 0);
450 
451 		/* test getaddrinfo function */
452 		test_getaddrinfo(
453 			hosts[i].nodename,
454 			hosts[i].numeric,
455 			services[j].servname,
456 			services[j].numeric,
457 			passhints,
458 			flags,
459 			families[k].value,
460 			socktypes[l].value,
461 			exp_results,
462 			htonl(ipaddr),
463 			flag_CANONNAME && hosts[i].canonname,
464 			htons(services[j].port));
465 	}
466 }
467 
468 static struct
469 {
470 	const char *nodename;
471 	const char *nodenum;
472 	unsigned long ipaddr;
473 	int havename;
474 } ipaddrs[] = {
475 	{ "0.0.0.0",    "0.0.0.0",      0x00000000, 0 },
476 	{ "0.0.0.255",  "0.0.0.255",    0x000000ff, 0 },
477 	{ "0.0.255.0",  "0.0.255.0",    0x0000ff00, 0 },
478 	{ "0.255.0.0",  "0.255.0.0",    0x00ff0000, 0 },
479 	{ "255.0.0.0",  "255.0.0.0",    0xff000000, 0 },
480 	{ "localhost",  "127.0.0.1",    0x7f000001, 1 },
481 	/* no reverse DNS unfortunately */
482 	/* { "minix3.org", "130.37.20.20", 0x82251414, 1 } */};
483 
484 static struct
485 {
486 	const char *servname;
487 	const char *servnum;
488 	unsigned short port;
489 	int socktype;
490 	struct servent *se_tcp; /* getservbyport() s_name on this port with "tcp" */
491 	struct servent *se_udp; /* getservbyport() s_name on this port with "udp" */
492 } ports[] = {
493 	{ "0",      "0",         0, 0           },
494 	{ "tcpmux", "1",         1, SOCK_STREAM },
495 	{ "32767",  "32767", 32767, 0           },
496 	{ "32768",  "32768", 32768, 0           },
497 	{ "65535",  "65535", 65535, 0           },
498 	{ "echo",   "7",         7, 0           },
499 	{ "ftp",    "21",       21, SOCK_STREAM },
500 	{ "tftp",   "69",       69, SOCK_DGRAM  }};
501 
502 static int buflens[] = { 0, 1, 2, 3, 4, 5, 6, 9, 10, 11, 255 };
503 
504 static void test_getnameinfo_all(void)
505 {
506 	int flag_NUMERICHOST, flag_NAMEREQD, flag_NUMERICSERV, flag_DGRAM;
507 	int exp_results, flagcount, flags, i, j, k, l;
508 	const char *nodename, *servname;
509 
510 	/* set ports servent structs */
511 	for (j = 0; j < LENGTH(ports);   j++) {
512 		struct servent *se_tcp, *se_udp;
513 
514 		se_tcp = getservbyport(htons(ports[j].port), "tcp");
515 		ports[j].se_tcp = se_tcp;
516 
517 		if(ports[j].se_tcp) {
518 			ports[j].se_tcp = malloc(sizeof(struct servent));
519 			memcpy(ports[j].se_tcp, se_tcp, sizeof(*se_tcp));
520 			assert(ports[j].se_tcp->s_name);
521 			ports[j].se_tcp->s_name = strdup(ports[j].se_tcp->s_name);
522 			assert(ports[j].se_tcp->s_name);
523 		}
524 
525 		se_udp = getservbyport(htons(ports[j].port), "udp");
526 		ports[j].se_udp = se_udp;
527 
528 		if(ports[j].se_udp) {
529 			ports[j].se_udp = malloc(sizeof(struct servent));
530 			memcpy(ports[j].se_udp, se_udp, sizeof(*se_udp));
531 			assert(ports[j].se_udp->s_name);
532 			ports[j].se_udp->s_name = strdup(ports[j].se_udp->s_name);
533 			assert(ports[j].se_udp->s_name);
534 		}
535 	}
536 
537 	/* loop through various parameter values */
538 	for (i = 0; i < LENGTH(ipaddrs); i++)
539 	for (j = 0; j < LENGTH(ports);   j++)
540 	for (k = 0; k < LENGTH(buflens); k++)
541 	for (l = 0; l < LENGTH(buflens); l++)
542 	for (flag_NUMERICHOST = 0; flag_NUMERICHOST < 2; flag_NUMERICHOST++)
543 	for (flag_NAMEREQD    = 0; flag_NAMEREQD < 2;    flag_NAMEREQD++)
544 	for (flag_NUMERICSERV = 0; flag_NUMERICSERV < 2; flag_NUMERICSERV++)
545 	for (flag_DGRAM       = 0; flag_DGRAM < 2;       flag_DGRAM++)
546 	{
547 		/* skip some redundant combinations */
548 		flagcount = flag_NUMERICHOST + flag_NAMEREQD +
549 			flag_NUMERICSERV + flag_DGRAM;
550 		if (flagcount > 1 && flagcount < 4) continue;
551 		if (k > 1 && k < LENGTH(buflens) - 2 &&
552 			l > 1 && l < LENGTH(buflens) - 2) continue;
553 
554 		/* determine flags */
555 		flags = (flag_NUMERICHOST ? NI_NUMERICHOST : 0) |
556 			(flag_NAMEREQD    ? NI_NAMEREQD : 0) |
557 			(flag_NUMERICSERV ? NI_NUMERICSERV : 0) |
558 			(flag_DGRAM       ? NI_DGRAM : 0);
559 
560 		/* determine expected result */
561 		exp_results = 0;
562 
563 		nodename = flag_NUMERICHOST ? ipaddrs[i].nodenum : ipaddrs[i].nodename;
564 		if (buflens[k] > 0 && buflens[k] <= strlen(nodename))
565 			exp_results |= (1 << EAI_OVERFLOW) | (1 << EAI_MEMORY);
566 
567 		struct servent *se = flag_DGRAM ? ports[j].se_udp : ports[j].se_tcp;
568 
569 		servname = (flag_NUMERICSERV) ?
570 			ports[j].servnum : (se ? se->s_name : ports[j].servname);
571 
572 		if (buflens[l] > 0 && buflens[l] <= strlen(servname))
573 			exp_results |= (1 << EAI_OVERFLOW) | (1 << EAI_MEMORY);
574 
575 		if (flag_NAMEREQD && (!ipaddrs[i].havename || flag_NUMERICHOST) && buflens[k])
576 			exp_results |= (1 << EAI_NONAME);
577 
578 		/* with no reason for failure, we demand success */
579 		if (!exp_results)
580 			exp_results |= (1 << 0);
581 
582 		/* perform the test */
583 		test_getnameinfo(
584 			htonl(ipaddrs[i].ipaddr),
585 			htons(ports[j].port),
586 			nodename,
587 			buflens[k],
588 			servname,
589 			buflens[l],
590 			flags,
591 			exp_results);
592 	}
593 }
594 
595 int main(void)
596 {
597 	int use_network;
598 
599 	start(48);
600 
601 	use_network = get_setting_use_network();
602 	test_getaddrinfo_all(use_network);
603 	test_getnameinfo_all();
604 
605 	quit();
606 	return 0;
607 }
608