minix/test/test48.c
Thomas Veerman a209c3ae12 Fix a ton of compiler warnings
This patch fixes most of current reasons to generate compiler warnings.
The changes consist of:
 - adding missing casts
 - hiding or unhiding function declarations
 - including headers where missing
 - add __UNCONST when assigning a const char * to a char *
 - adding missing return statements
 - changing some types from unsigned to signed, as the code seems to want
   signed ints
 - converting old-style function definitions to current style (i.e.,
   void func(param1, param2) short param1, param2; {...} to
   void func (short param1, short param2) {...})
 - making the compiler silent about signed vs unsigned comparisons. We
   have too many of those in the new libc to fix.

A number of bugs in the test set were fixed. These bugs were never
triggered with our old libc. Consequently, these tests are now forced to
link with the new libc or they will generate errors (in particular tests 43
and 55).

Most changes in NetBSD libc are limited to moving aroudn "#ifndef __minix"
or stuff related to Minix-specific things (code in sys-minix or gen/minix).
2011-11-14 10:07:49 +00:00

598 lines
16 KiB
C
Executable file

#include <arpa/inet.h>
#include <assert.h>
#include <netdb.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#define MAX_ERRORS 3
static int errct;
static void quit(void)
{
if (errct > 0)
{
printf("%d errors\n", errct);
exit(1);
}
else
{
printf("ok\n");
exit(0);
}
}
static void err(void)
{
if (++errct >= MAX_ERRORS)
{
printf("aborted, too many errors\n");
quit();
}
}
static void printstr(const char *s)
{
if (s)
printf("\"%s\"", s);
else
printf("NULL");
}
static void test_getaddrinfo_err(
int n,
const char *nodename,
const char *servname,
int passhints,
int flags,
int family,
int socktype,
const char *exp_result,
const char *result)
{
printf("error %d: getaddrinfo(", n);
printstr(nodename);
printf(", ");
printstr(servname);
printf(", ");
if (passhints)
printf("{ 0x%x, %d, %d }", flags, family, socktype);
else
printf("NULL");
printf("); result: ");
printstr(result);
printf("; expected: ");
printstr(exp_result);
printf("\n");
err();
}
/* yes, this is ugly, but not as ugly as repeating it all every time */
#define TEST_GETADDRINFO_ERR_PARAMS \
nodename, servname, passhints, flags, family, socktype
static void test_getaddrinfo_err_nr(
int n,
const char *nodename,
const char *servname,
int passhints,
int flags,
int family,
int socktype,
int exp_result,
int result)
{
char exp_result_s[23], result_s[23];
/* convert result to string */
snprintf(exp_result_s, sizeof(exp_result_s), "%d/0x%x",
exp_result, exp_result);
snprintf(result_s, sizeof(result_s), "%d/0x%x", result, result);
test_getaddrinfo_err(n, TEST_GETADDRINFO_ERR_PARAMS,
exp_result_s, result_s);
}
static void test_getnameinfo_err(
int n,
unsigned long ipaddr,
unsigned short port,
socklen_t nodelen,
socklen_t servicelen,
int flags,
const char *exp_result,
const char *result)
{
printf("error %d: getnameinfo(0x%.8x, %d, %d, %d, 0x%x); result: ",
n, ntohl(ipaddr), ntohs(port), nodelen, servicelen, flags);
printstr(result);
printf("; expected: ");
printstr(exp_result);
printf("\n");
err();
}
/* yes, this is ugly, but not as ugly as repeating it all every time */
#define TEST_GETNAMEINFO_ERR_PARAMS ipaddr, port, nodelen, servicelen, flags
static void test_getnameinfo_err_nr(
int n,
unsigned long ipaddr,
unsigned short port,
socklen_t nodelen,
socklen_t servicelen,
int flags,
int exp_result,
int result)
{
char exp_result_s[23], result_s[23];
/* convert result to string */
snprintf(exp_result_s, sizeof(exp_result_s), "%d/0x%x",
exp_result, exp_result);
snprintf(result_s, sizeof(result_s), "%d/0x%x", result, result);
test_getnameinfo_err(n, TEST_GETNAMEINFO_ERR_PARAMS,
exp_result_s, result_s);
}
static void test_getaddrinfo(
const char *nodename,
int nodename_numerical,
const char *servname,
int servname_numerical,
int passhints,
int flags,
int family,
int socktype,
int exp_results,
unsigned long exp_ip,
int exp_canonname,
unsigned short exp_port)
{
struct addrinfo *ai, *ai_cur;
struct addrinfo hints;
struct sockaddr_in *sockaddr_in;
int ai_count_dgram, ai_count_stream, r;
/* some parameters are only meaningful with hints */
assert(passhints || !flags);
assert(passhints || family == AF_UNSPEC);
assert(passhints || !socktype);
/* a combination of parameters don't make sense to test */
if (nodename == NULL && servname == NULL) return;
if (nodename == NULL && (flags & AI_NUMERICHOST)) return;
if (servname == NULL && (flags & AI_NUMERICSERV)) return;
/* initialize hints */
memset(&hints, 0, sizeof(hints));
hints.ai_flags = flags;
hints.ai_family = family;
hints.ai_socktype = socktype;
/* perform query and test result */
ai = (struct addrinfo *) 0xDEADBEEF;
r = getaddrinfo(nodename, servname, passhints ? &hints : NULL, &ai);
if (r < 0 || r >= 32 || !((1 << r) & exp_results))
test_getaddrinfo_err_nr(1, TEST_GETADDRINFO_ERR_PARAMS, exp_results, r);
if (r)
return;
/* the function succeeded; do the results make sense? */
ai_cur = ai;
ai_count_dgram = 0;
ai_count_stream = 0;
while (ai_cur)
{
/* test result fields */
if (ai_cur->ai_family != AF_INET)
test_getaddrinfo_err_nr(2, TEST_GETADDRINFO_ERR_PARAMS,
AF_INET, ai_cur->ai_family);
if (socktype && ai_cur->ai_socktype != socktype)
test_getaddrinfo_err_nr(3, TEST_GETADDRINFO_ERR_PARAMS,
socktype, ai_cur->ai_socktype);
switch (ai_cur->ai_socktype)
{
case SOCK_DGRAM: ai_count_dgram++; break;
case SOCK_STREAM: ai_count_stream++; break;
}
/* do address and port match? */
if (ai_cur->ai_addrlen != sizeof(struct sockaddr_in))
test_getaddrinfo_err_nr(4, TEST_GETADDRINFO_ERR_PARAMS,
sizeof(struct sockaddr_in),
ai_cur->ai_addrlen);
else
{
sockaddr_in = (struct sockaddr_in *) ai_cur->ai_addr;
if (sockaddr_in->sin_addr.s_addr != exp_ip)
test_getaddrinfo_err_nr(5,
TEST_GETADDRINFO_ERR_PARAMS,
ntohl(exp_ip),
ntohl(sockaddr_in->sin_addr.s_addr));
if (sockaddr_in->sin_port != exp_port)
test_getaddrinfo_err_nr(6,
TEST_GETADDRINFO_ERR_PARAMS,
ntohs(exp_port),
ntohs(sockaddr_in->sin_port));
}
/* If a hostname is numeric, there can't be a canonical name.
* Instead, the returned canonname (if requested) will be
* identical to the supplied hostname */
if (nodename != NULL && nodename_numerical &&
(flags & AI_CANONNAME)) {
if (strncmp(ai_cur->ai_canonname, nodename,
strlen(nodename)))
test_getaddrinfo_err(11,
TEST_GETADDRINFO_ERR_PARAMS,
nodename, ai_cur->ai_canonname);
} else {
/* is canonical supplied? */
if (exp_canonname && nodename &&
(!ai_cur->ai_canonname || !*ai_cur->ai_canonname))
test_getaddrinfo_err(7,
TEST_GETADDRINFO_ERR_PARAMS,
"(anything)", ai_cur->ai_canonname);
if (!exp_canonname && ai_cur->ai_canonname)
test_getaddrinfo_err(8,
TEST_GETADDRINFO_ERR_PARAMS,
NULL, ai_cur->ai_canonname);
}
/* move to next result */
ai_cur = ai_cur->ai_next;
}
/* If socket type is non-zero, make sure we got what we wanted. Else
* any result is okay. */
if (socktype) {
if (ai_count_dgram != ((socktype == SOCK_STREAM) ? 0 : 1))
test_getaddrinfo_err_nr(9, TEST_GETADDRINFO_ERR_PARAMS,
(socktype == SOCK_STREAM) ? 0 : 1, ai_count_dgram);
if (ai_count_stream != ((socktype == SOCK_DGRAM) ? 0 : 1))
test_getaddrinfo_err_nr(10, TEST_GETADDRINFO_ERR_PARAMS,
(socktype == SOCK_DGRAM) ? 0 : 1, ai_count_stream);
}
/* clean up */
freeaddrinfo(ai);
}
static void memsetl(void *s, unsigned long c, size_t n)
{
unsigned char *p = (unsigned char *) s;
size_t i;
for (i = 0; i < n; i++)
p[i] = c >> (8 * (i % sizeof(c)));
}
void test_getnameinfo(
unsigned long ipaddr,
unsigned short port,
const char *exp_node,
socklen_t nodelen,
const char *exp_service,
socklen_t servicelen,
int flags,
int exp_results)
{
struct sockaddr_in sockaddr;
char node[256], service[256];
int r;
/* avoid buffer overflows */
assert(nodelen <= sizeof(node));
assert(servicelen <= sizeof(service));
/* perform query and test result */
sockaddr.sin_family = AF_INET;
sockaddr.sin_addr.s_addr = ipaddr;
sockaddr.sin_port = port;
memsetl(node, 0xDEADBEEF, nodelen);
memsetl(service, 0xDEADBEEF, servicelen);
r = getnameinfo((struct sockaddr *) &sockaddr, sizeof(sockaddr),
node, nodelen, service, servicelen, flags);
if (r < 0 || r >= 32 || !((1 << r) & exp_results))
test_getnameinfo_err_nr(1, TEST_GETNAMEINFO_ERR_PARAMS,
exp_results, r);
if (r)
return;
/* check results */
if (nodelen && strcmp(exp_node, node) != 0)
test_getnameinfo_err(2, TEST_GETNAMEINFO_ERR_PARAMS,
exp_node, node);
if (servicelen && strcmp(exp_service, service) != 0)
test_getnameinfo_err(2, TEST_GETNAMEINFO_ERR_PARAMS,
exp_service, service);
}
static struct
{
const char *nodename;
unsigned long ipaddr;
int numeric;
int canonname;
int need_network;
int exp_result;
} hosts[] = {
{ NULL, 0x7f000001, 1, 1, 0, 0 },
{ "0.0.0.0", 0x00000000, 1, 0, 0, 0 },
{ "0.0.0.255", 0x000000ff, 1, 0, 0, 0 },
{ "0.0.255.0", 0x0000ff00, 1, 0, 0, 0 },
{ "0.255.0.0", 0x00ff0000, 1, 0, 0, 0 },
{ "255.0.0.0", 0xff000000, 1, 0, 0, 0 },
{ "127.0.0.1", 0x7f000001, 1, 0, 0, 0 },
{ "localhost", 0x7f000001, 0, 1, 0, 0, },
{ "minix3.org", 0x82251414, 0, 1, 1, 0, },
{ "", 0x00000000, 1, 0, 0, (1<<EAI_NONAME)|(1<<EAI_FAIL)|(1<<EAI_NODATA)},
{ "256.256.256.256",0x00000000, 1, 0, 0, (1<<EAI_NONAME)|(1<<EAI_FAIL)|(1<<EAI_NODATA)},
{ "minix3.xxx", 0x00000000, 0, 0, 1, (1<<EAI_NONAME)|(1<<EAI_FAIL)|(1<<EAI_NODATA)}};
static struct
{
const char *servname;
unsigned short port;
int numeric;
int socktype;
int exp_result;
} services[] = {
{ NULL, 0, 1, 0, 0 },
{ "0", 0, 1, 0, 0 },
{ "1", 1, 1, 0, 0 },
{ "32767", 32767, 1, 0, 0 },
{ "32768", 32768, 1, 0, 0 },
{ "65535", 65535, 1, 0, 0 },
{ "echo", 7, 0, 0, 0 },
{ "ftp", 21, 0, SOCK_STREAM, 0 },
{ "tftp", 69, 0, SOCK_DGRAM , 0 },
{ "-1", 0, 1, 0, (1<<EAI_NONAME) | (1<<EAI_SERVICE) },
{ "", 0, 1, 0, (1<<EAI_NONAME) | (1<<EAI_SERVICE) },
{ "65537", 0, 1, 0, (1 << EAI_SERVICE) },
{ "XXX", 0, 0, 0, (1 << EAI_SERVICE) }};
static struct
{
int value;
int exp_result;
} families[] = {
{ AF_UNSPEC, 0 },
{ AF_INET, 0 },
{ AF_UNSPEC + AF_INET + 1, (1 << EAI_FAMILY) }};
static struct
{
int value;
int exp_result;
} socktypes[] = {
{ 0, 0 },
{ SOCK_STREAM, 0 },
{ SOCK_DGRAM, 0 },
{ SOCK_STREAM + SOCK_DGRAM + 1,
(1 << EAI_SOCKTYPE) | (1 << EAI_FAIL) | (1 << EAI_NONAME) }};
#define LENGTH(a) (sizeof((a)) / sizeof((a)[0]))
static void test_getaddrinfo_all(int use_network)
{
int flag_PASSIVE, flag_CANONNAME, flag_NUMERICHOST, flag_NUMERICSERV;
int exp_results, flags, i, j, k, l, passhints;
unsigned long ipaddr;
/* loop through various parameter values */
for (i = 0; i < LENGTH(hosts); i++)
for (j = 0; j < LENGTH(services); j++)
for (k = 0; k < LENGTH(families); k++)
for (l = 0; l < LENGTH(socktypes); l++)
for (flag_PASSIVE = 0; flag_PASSIVE < 2; flag_PASSIVE++)
for (flag_CANONNAME = 0; flag_CANONNAME < 2; flag_CANONNAME++)
for (flag_NUMERICHOST = 0; flag_NUMERICHOST < 2; flag_NUMERICHOST++)
for (flag_NUMERICSERV = 0; flag_NUMERICSERV < 2; flag_NUMERICSERV++)
for (passhints = 0; passhints < 2; passhints++)
{
/* skip tests that need but cannot use network */
if (!use_network && hosts[i].need_network)
continue;
/* determine flags */
flags = (flag_PASSIVE ? AI_PASSIVE : 0) |
(flag_CANONNAME ? AI_CANONNAME : 0) |
(flag_NUMERICHOST ? AI_NUMERICHOST : 0) |
(flag_NUMERICSERV ? AI_NUMERICSERV : 0);
/* some options require hints */
if (families[k].value != AF_UNSPEC ||
socktypes[l].value != 0 || flags) {
passhints = 1;
}
/* flags may influence IP address */
ipaddr = hosts[i].ipaddr;
if (!hosts[i].nodename && flag_PASSIVE)
ipaddr = INADDR_ANY;
/* determine expected result */
exp_results =
hosts[i].exp_result |
services[j].exp_result |
families[k].exp_result |
socktypes[l].exp_result;
if (!hosts[i].nodename && !services[j].servname)
exp_results |= (1 << EAI_NONAME);
if (flag_NUMERICHOST && !hosts[i].numeric)
exp_results |= (1 << EAI_NONAME);
if (flag_NUMERICSERV && !services[j].numeric)
exp_results |= (1 << EAI_NONAME);
/* When we don't pass hints, getaddrinfo will find suitable
* settings for us. If we do pass hints, there might be
* conflicts.
*/
if (passhints) {
/* Can't have conflicting socket types */
if (services[j].socktype &&
socktypes[l].value &&
socktypes[l].value != services[j].socktype) {
exp_results |= (1 << EAI_SERVICE);
}
}
/* with no reason for failure, we demand success */
if (!exp_results)
exp_results |= (1 << 0);
/* test getaddrinfo function */
test_getaddrinfo(
hosts[i].nodename,
hosts[i].numeric,
services[j].servname,
services[j].numeric,
passhints,
flags,
families[k].value,
socktypes[l].value,
exp_results,
htonl(ipaddr),
flag_CANONNAME && hosts[i].canonname,
htons(services[j].port));
}
}
static struct
{
const char *nodename;
const char *nodenum;
unsigned long ipaddr;
int havename;
} ipaddrs[] = {
{ "0.0.0.0", "0.0.0.0", 0x00000000, 0 },
{ "0.0.0.255", "0.0.0.255", 0x000000ff, 0 },
{ "0.0.255.0", "0.0.255.0", 0x0000ff00, 0 },
{ "0.255.0.0", "0.255.0.0", 0x00ff0000, 0 },
{ "255.0.0.0", "255.0.0.0", 0xff000000, 0 },
{ "localhost", "127.0.0.1", 0x7f000001, 1 },
/* no reverse DNS unfortunately */
/* { "minix3.org", "130.37.20.20", 0x82251414, 1 } */};
static struct
{
const char *servname;
const char *servnum;
unsigned short port;
int socktype;
} ports[] = {
{ "0", "0", 0, 0 },
{ "tcpmux", "1", 1, SOCK_STREAM },
{ "32767", "32767", 32767, 0 },
{ "32768", "32768", 32768, 0 },
{ "65535", "65535", 65535, 0 },
{ "echo", "7", 7, 0 },
{ "ftp", "21", 21, SOCK_STREAM },
{ "tftp", "69", 69, SOCK_DGRAM }};
static int buflens[] = { 0, 1, 2, 3, 4, 5, 6, 9, 10, 11, 255 };
static void test_getnameinfo_all(void)
{
int flag_NUMERICHOST, flag_NAMEREQD, flag_NUMERICSERV, flag_DGRAM;
int exp_results, flags, i, j, k, l, socktypemismatch;
const char *nodename, *servname;
/* loop through various parameter values */
for (i = 0; i < LENGTH(ipaddrs); i++)
for (j = 0; j < LENGTH(ports); j++)
for (k = 0; k < LENGTH(buflens); k++)
for (l = 0; l < LENGTH(buflens); l++)
for (flag_NUMERICHOST = 0; flag_NUMERICHOST < 2; flag_NUMERICHOST++)
for (flag_NAMEREQD = 0; flag_NAMEREQD < 2; flag_NAMEREQD++)
for (flag_NUMERICSERV = 0; flag_NUMERICSERV < 2; flag_NUMERICSERV++)
for (flag_DGRAM = 0; flag_DGRAM < 2; flag_DGRAM++)
{
/* determine flags */
flags = (flag_NUMERICHOST ? NI_NUMERICHOST : 0) |
(flag_NAMEREQD ? NI_NAMEREQD : 0) |
(flag_NUMERICSERV ? NI_NUMERICSERV : 0) |
(flag_DGRAM ? NI_DGRAM : 0);
/* determine expected result */
exp_results = 0;
nodename = flag_NUMERICHOST ? ipaddrs[i].nodenum : ipaddrs[i].nodename;
if (buflens[k] > 0 && buflens[k] <= strlen(nodename))
exp_results |= (1 << EAI_OVERFLOW) | (1 << EAI_MEMORY);
socktypemismatch =
(flag_DGRAM && ports[j].socktype == SOCK_STREAM) ||
(!flag_DGRAM && ports[j].socktype == SOCK_DGRAM);
servname = (flag_NUMERICSERV || socktypemismatch) ?
ports[j].servnum : ports[j].servname;
if (buflens[l] > 0 && buflens[l] <= strlen(servname))
exp_results |= (1 << EAI_OVERFLOW) | (1 << EAI_MEMORY);
if (flag_NAMEREQD && (!ipaddrs[i].havename || flag_NUMERICHOST) && buflens[k])
exp_results |= (1 << EAI_NONAME);
/* with no reason for failure, we demand success */
if (!exp_results)
exp_results |= (1 << 0);
/* perform the test */
test_getnameinfo(
htonl(ipaddrs[i].ipaddr),
htons(ports[j].port),
nodename,
buflens[k],
servname,
buflens[l],
flags,
exp_results);
}
}
static int can_use_network(void)
{
int status;
/* try to ping minix3.org */
status = system("ping www.minix3.org > /dev/null 2>&1");
if (status == 127)
{
printf("cannot execute ping\n");
err();
}
return status == 0;
}
int main(void)
{
int use_network;
printf("Test 48 ");
fflush(stdout);
use_network = can_use_network();
if (!use_network)
printf("Warning: no network\n");
test_getaddrinfo_all(use_network);
test_getnameinfo_all();
quit();
return 0;
}