13 static void quit(void)
17 printf("%d errors\n", errct
);
29 if (++errct
>= MAX_ERRORS
)
31 printf("aborted, too many errors\n");
36 static void printstr(const char *s
)
44 static void test_getaddrinfo_err(
52 const char *exp_result
,
55 printf("error %d: getaddrinfo(", n
);
61 printf("{ 0x%x, %d, %d }", flags
, family
, socktype
);
65 printf("); result: ");
67 printf("; expected: ");
73 /* yes, this is ugly, but not as ugly as repeating it all every time */
74 #define TEST_GETADDRINFO_ERR_PARAMS \
75 nodename, servname, passhints, flags, family, socktype
77 static void test_getaddrinfo_err_nr(
88 char exp_result_s
[23], result_s
[23];
90 /* convert result to string */
91 snprintf(exp_result_s
, sizeof(exp_result_s
), "%d/0x%x",
92 exp_result
, exp_result
);
93 snprintf(result_s
, sizeof(result_s
), "%d/0x%x", result
, result
);
94 test_getaddrinfo_err(n
, TEST_GETADDRINFO_ERR_PARAMS
,
95 exp_result_s
, result_s
);
98 static void test_getnameinfo_err(
100 unsigned long ipaddr
,
103 socklen_t servicelen
,
105 const char *exp_result
,
108 printf("error %d: getnameinfo(0x%.8x, %d, %d, %d, 0x%x); result: ",
109 n
, ntohl(ipaddr
), ntohs(port
), nodelen
, servicelen
, flags
);
111 printf("; expected: ");
112 printstr(exp_result
);
117 /* yes, this is ugly, but not as ugly as repeating it all every time */
118 #define TEST_GETNAMEINFO_ERR_PARAMS ipaddr, port, nodelen, servicelen, flags
120 static void test_getnameinfo_err_nr(
122 unsigned long ipaddr
,
125 socklen_t servicelen
,
130 char exp_result_s
[23], result_s
[23];
132 /* convert result to string */
133 snprintf(exp_result_s
, sizeof(exp_result_s
), "%d/0x%x",
134 exp_result
, exp_result
);
135 snprintf(result_s
, sizeof(result_s
), "%d/0x%x", result
, result
);
136 test_getnameinfo_err(n
, TEST_GETNAMEINFO_ERR_PARAMS
,
137 exp_result_s
, result_s
);
140 static void test_getaddrinfo(
141 const char *nodename
,
142 const char *servname
,
148 unsigned long exp_ip
,
150 unsigned short exp_port
)
152 struct addrinfo
*ai
, *ai_cur
;
153 struct addrinfo hints
;
154 struct sockaddr_in
*sockaddr_in
;
155 int ai_count_dgram
, ai_count_stream
, r
;
157 /* some parameters are only meaningful with hints */
158 assert(passhints
|| !flags
);
159 assert(passhints
|| family
== AF_UNSPEC
);
160 assert(passhints
|| !socktype
);
162 /* initialize hints */
163 memset(&hints
, 0, sizeof(hints
));
164 hints
.ai_flags
= flags
;
165 hints
.ai_family
= family
;
166 hints
.ai_socktype
= socktype
;
167 hints
.ai_family
= family
;
169 /* perform query and test result */
170 ai
= (struct addrinfo
*) 0xDEADBEEF;
171 r
= getaddrinfo(nodename
, servname
, passhints
? &hints
: NULL
, &ai
);
172 if (r
< 0 || r
>= 32 || !((1 << r
) & exp_results
))
173 test_getaddrinfo_err_nr(1, TEST_GETADDRINFO_ERR_PARAMS
, exp_results
, r
);
178 /* the function succeeded; do the results make sense? */
184 /* test result fields */
185 if (ai_cur
->ai_family
!= AF_INET
)
186 test_getaddrinfo_err_nr(2, TEST_GETADDRINFO_ERR_PARAMS
,
187 AF_INET
, ai_cur
->ai_family
);
189 if (socktype
&& ai_cur
->ai_socktype
!= socktype
)
190 test_getaddrinfo_err_nr(3, TEST_GETADDRINFO_ERR_PARAMS
,
191 socktype
, ai_cur
->ai_socktype
);
193 switch (ai_cur
->ai_socktype
)
195 case SOCK_DGRAM
: ai_count_dgram
++; break;
196 case SOCK_STREAM
: ai_count_stream
++; break;
199 /* do address and port match? */
200 if (ai_cur
->ai_addrlen
!= sizeof(struct sockaddr_in
))
201 test_getaddrinfo_err_nr(4, TEST_GETADDRINFO_ERR_PARAMS
,
202 sizeof(struct sockaddr_in
),
206 sockaddr_in
= (struct sockaddr_in
*) ai_cur
->ai_addr
;
207 if (sockaddr_in
->sin_addr
.s_addr
!= exp_ip
)
208 test_getaddrinfo_err_nr(5,
209 TEST_GETADDRINFO_ERR_PARAMS
,
211 ntohl(sockaddr_in
->sin_addr
.s_addr
));
213 if (sockaddr_in
->sin_port
!= exp_port
)
214 test_getaddrinfo_err_nr(6,
215 TEST_GETADDRINFO_ERR_PARAMS
,
217 ntohs(sockaddr_in
->sin_port
));
220 /* is canonical supplied? */
222 (!ai_cur
->ai_canonname
|| !*ai_cur
->ai_canonname
))
223 test_getaddrinfo_err(7,
224 TEST_GETADDRINFO_ERR_PARAMS
,
225 "(anything)", ai_cur
->ai_canonname
);
227 if (!exp_canonname
&& ai_cur
->ai_canonname
)
228 test_getaddrinfo_err(8,
229 TEST_GETADDRINFO_ERR_PARAMS
,
230 NULL
, ai_cur
->ai_canonname
);
232 /* move to next result */
233 ai_cur
= ai_cur
->ai_next
;
236 /* check number of results */
237 if (ai_count_dgram
!= ((socktype
== SOCK_STREAM
) ? 0 : 1))
238 test_getaddrinfo_err_nr(9, TEST_GETADDRINFO_ERR_PARAMS
,
239 (socktype
== SOCK_STREAM
) ? 0 : 1, ai_count_dgram
);
241 if (ai_count_stream
!= ((socktype
== SOCK_DGRAM
) ? 0 : 1))
242 test_getaddrinfo_err_nr(10, TEST_GETADDRINFO_ERR_PARAMS
,
243 (socktype
== SOCK_DGRAM
) ? 0 : 1, ai_count_stream
);
249 static void memsetl(void *s
, unsigned long c
, size_t n
)
251 unsigned char *p
= (unsigned char *) s
;
254 for (i
= 0; i
< n
; i
++)
255 p
[i
] = c
>> (8 * (i
% sizeof(c
)));
258 void test_getnameinfo(
259 unsigned long ipaddr
,
261 const char *exp_node
,
263 const char *exp_service
,
264 socklen_t servicelen
,
268 struct sockaddr_in sockaddr
;
269 char node
[256], service
[256];
272 /* avoid buffer overflows */
273 assert(nodelen
<= sizeof(node
));
274 assert(servicelen
<= sizeof(service
));
276 /* perform query and test result */
277 sockaddr
.sin_family
= AF_INET
;
278 sockaddr
.sin_addr
.s_addr
= ipaddr
;
279 sockaddr
.sin_port
= port
;
280 memsetl(node
, 0xDEADBEEF, nodelen
);
281 memsetl(service
, 0xDEADBEEF, servicelen
);
282 r
= getnameinfo((struct sockaddr
*) &sockaddr
, sizeof(sockaddr
),
283 node
, nodelen
, service
, servicelen
, flags
);
285 if (r
< 0 || r
>= 32 || !((1 << r
) & exp_results
))
286 test_getnameinfo_err_nr(1, TEST_GETNAMEINFO_ERR_PARAMS
,
293 if (nodelen
&& strcmp(exp_node
, node
) != 0)
294 test_getnameinfo_err(2, TEST_GETNAMEINFO_ERR_PARAMS
,
297 if (servicelen
&& strcmp(exp_service
, service
) != 0)
298 test_getnameinfo_err(2, TEST_GETNAMEINFO_ERR_PARAMS
,
299 exp_service
, service
);
304 const char *nodename
;
305 unsigned long ipaddr
;
311 { NULL
, 0x7f000001, 1, 1, 0, 0 },
312 { "0.0.0.0", 0x00000000, 1, 0, 0, 0, },
313 { "0.0.0.255", 0x000000ff, 1, 0, 0, 0, },
314 { "0.0.255.0", 0x0000ff00, 1, 0, 0, 0, },
315 { "0.255.0.0", 0x00ff0000, 1, 0, 0, 0, },
316 { "255.0.0.0", 0xff000000, 1, 0, 0, 0, },
317 { "127.0.0.1", 0x7f000001, 1, 0, 0, 0, },
318 { "localhost", 0x7f000001, 0, 1, 0, 0, },
319 { "minix3.org", 0x82251414, 0, 1, 1, 0, },
320 { "", 0x00000000, 1, 0, 0, (1 << EAI_NONAME
) },
321 { "256.256.256.256", 0x00000000, 1, 0, 0, (1 << EAI_NONAME
) },
322 { "minix3.xxx", 0x00000000, 0, 0, 1, (1 << EAI_NONAME
) }};
326 const char *servname
;
332 { NULL
, 0, 1, 0, 0 },
335 { "32767", 32767, 1, 0, 0 },
336 { "32768", 32768, 1, 0, 0 },
337 { "65535", 65535, 1, 0, 0 },
338 { "echo", 7, 0, 0, 0 },
339 { "ftp", 21, 0, SOCK_STREAM
, 0 },
340 { "tftp", 69, 0, SOCK_DGRAM
, 0 },
341 { "-1", 0, 1, 0, (1 << EAI_SERVICE
) },
342 { "", 0, 1, 0, (1 << EAI_SERVICE
) },
343 { "65537", 0, 1, 0, (1 << EAI_SERVICE
) },
344 { "XXX", 0, 0, 0, (1 << EAI_SERVICE
) }};
353 { AF_UNSPEC
+ AF_INET
+ 1, (1 << EAI_FAMILY
) }};
363 { SOCK_STREAM
+ SOCK_DGRAM
+ 1, (1 << EAI_SOCKTYPE
) }};
365 #define LENGTH(a) (sizeof((a)) / sizeof((a)[0]))
367 static void test_getaddrinfo_all(int use_network
)
369 int flag_PASSIVE
, flag_CANONNAME
, flag_NUMERICHOST
, flag_NUMERICSERV
;
370 int exp_results
, flags
, i
, j
, k
, l
, needhints
, passhints
;
371 unsigned long ipaddr
;
373 /* loop through various parameter values */
374 for (i
= 0; i
< LENGTH(hosts
); i
++)
375 for (j
= 0; j
< LENGTH(services
); j
++)
376 for (k
= 0; k
< LENGTH(families
); k
++)
377 for (l
= 0; l
< LENGTH(socktypes
); l
++)
378 for (flag_PASSIVE
= 0; flag_PASSIVE
< 2; flag_PASSIVE
++)
379 for (flag_CANONNAME
= 0; flag_CANONNAME
< 2; flag_CANONNAME
++)
380 for (flag_NUMERICHOST
= 0; flag_NUMERICHOST
< 2; flag_NUMERICHOST
++)
381 for (flag_NUMERICSERV
= 0; flag_NUMERICSERV
< 2; flag_NUMERICSERV
++)
383 /* skip tests that need but cannot use network */
384 if (!use_network
&& hosts
[i
].need_network
)
387 /* determine flags */
388 flags
= (flag_PASSIVE
? AI_PASSIVE
: 0) |
389 (flag_CANONNAME
? AI_CANONNAME
: 0) |
390 (flag_NUMERICHOST
? AI_NUMERICHOST
: 0) |
391 (flag_NUMERICSERV
? AI_NUMERICSERV
: 0);
393 /* flags may influence IP address */
394 ipaddr
= hosts
[i
].ipaddr
;
395 if (!hosts
[i
].nodename
&& flag_PASSIVE
)
398 /* determine expected result */
400 hosts
[i
].exp_result
|
401 services
[j
].exp_result
|
402 families
[k
].exp_result
|
403 socktypes
[l
].exp_result
;
404 if (!hosts
[i
].nodename
&& !services
[j
].servname
)
405 exp_results
|= (1 << EAI_NONAME
);
407 if (flag_NUMERICHOST
&& !hosts
[i
].numeric
)
408 exp_results
|= (1 << EAI_NONAME
);
410 if (flag_NUMERICSERV
&& !services
[j
].numeric
)
411 exp_results
|= (1 << EAI_SERVICE
);
413 if (services
[j
].socktype
&& socktypes
[l
].value
!= services
[j
].socktype
)
414 exp_results
|= (1 << EAI_SERVICE
);
416 /* with no reason for failure, we demand success */
418 exp_results
|= (1 << 0);
420 /* some options require hints */
421 needhints
= (families
[k
].value
!= AF_UNSPEC
||
422 socktypes
[l
].value
!= 0 || flags
) ? 1 : 0;
423 for (passhints
= needhints
; passhints
< 2; passhints
++)
425 /* test getaddrinfo function */
428 services
[j
].servname
,
435 flag_CANONNAME
&& hosts
[i
].canonname
,
436 htons(services
[j
].port
));
443 const char *nodename
;
445 unsigned long ipaddr
;
448 { "0.0.0.0", "0.0.0.0", 0x00000000, 0 },
449 { "0.0.0.255", "0.0.0.255", 0x000000ff, 0 },
450 { "0.0.255.0", "0.0.255.0", 0x0000ff00, 0 },
451 { "0.255.0.0", "0.255.0.0", 0x00ff0000, 0 },
452 { "255.0.0.0", "255.0.0.0", 0xff000000, 0 },
453 { "localhost", "127.0.0.1", 0x7f000001, 1 },
454 /* no reverse DNS unfortunately */
455 /* { "minix3.org", "130.37.20.20", 0x82251414, 1 } */};
459 const char *servname
;
465 { "tcpmux", "1", 1, SOCK_STREAM
},
466 { "32767", "32767", 32767, 0 },
467 { "32768", "32768", 32768, 0 },
468 { "65535", "65535", 65535, 0 },
469 { "echo", "7", 7, 0 },
470 { "ftp", "21", 21, SOCK_STREAM
},
471 { "tftp", "69", 69, SOCK_DGRAM
}};
473 static int buflens
[] = { 0, 1, 2, 3, 4, 5, 6, 9, 10, 11, 255 };
475 static void test_getnameinfo_all(void)
477 int flag_NUMERICHOST
, flag_NAMEREQD
, flag_NUMERICSERV
, flag_DGRAM
;
478 int exp_results
, flags
, i
, j
, k
, l
, socktypemismatch
;
479 const char *nodename
, *servname
;
481 /* loop through various parameter values */
482 for (i
= 0; i
< LENGTH(ipaddrs
); i
++)
483 for (j
= 0; j
< LENGTH(ports
); j
++)
484 for (k
= 0; k
< LENGTH(buflens
); k
++)
485 for (l
= 0; l
< LENGTH(buflens
); l
++)
486 for (flag_NUMERICHOST
= 0; flag_NUMERICHOST
< 2; flag_NUMERICHOST
++)
487 for (flag_NAMEREQD
= 0; flag_NAMEREQD
< 2; flag_NAMEREQD
++)
488 for (flag_NUMERICSERV
= 0; flag_NUMERICSERV
< 2; flag_NUMERICSERV
++)
489 for (flag_DGRAM
= 0; flag_DGRAM
< 2; flag_DGRAM
++)
491 /* determine flags */
492 flags
= (flag_NUMERICHOST
? NI_NUMERICHOST
: 0) |
493 (flag_NAMEREQD
? NI_NAMEREQD
: 0) |
494 (flag_NUMERICSERV
? NI_NUMERICSERV
: 0) |
495 (flag_DGRAM
? NI_DGRAM
: 0);
497 /* determine expected result */
499 if (!buflens
[k
] && !buflens
[l
])
500 exp_results
|= (1 << EAI_NONAME
);
502 nodename
= flag_NUMERICHOST
? ipaddrs
[i
].nodenum
: ipaddrs
[i
].nodename
;
503 if (buflens
[k
] > 0 && buflens
[k
] <= strlen(nodename
))
504 exp_results
|= (1 << EAI_OVERFLOW
);
507 (flag_DGRAM
&& ports
[j
].socktype
== SOCK_STREAM
) ||
508 (!flag_DGRAM
&& ports
[j
].socktype
== SOCK_DGRAM
);
509 servname
= (flag_NUMERICSERV
|| socktypemismatch
) ?
510 ports
[j
].servnum
: ports
[j
].servname
;
511 if (buflens
[l
] > 0 && buflens
[l
] <= strlen(servname
))
512 exp_results
|= (1 << EAI_OVERFLOW
);
514 if (flag_NAMEREQD
&& (!ipaddrs
[i
].havename
| flag_NUMERICHOST
) && buflens
[k
])
515 exp_results
|= (1 << EAI_NONAME
);
517 /* with no reason for failure, we demand success */
519 exp_results
|= (1 << 0);
521 /* perform the test */
523 htonl(ipaddrs
[i
].ipaddr
),
524 htons(ports
[j
].port
),
534 static int can_use_network(void)
539 /* try to ping minix3.org */
540 status
= system("ping www.minix3.org > /dev/null 2>&1");
543 printf("cannot execute ping\n");
557 use_network
= can_use_network();
559 printf("Warning: no network\n");
561 test_getaddrinfo_all(use_network
);
562 test_getnameinfo_all();