#include <mcheck.h> #include <netdb.h> #include <stdio.h> #include <string.h> #include <arpa/inet.h> #include <arpa/nameser.h> static int do_test (void) { mtrace (); int result = 0; struct addrinfo hints; struct addrinfo *ai_res; int s; #define T(no, fail, addr, fam, coraddr) \ s = getaddrinfo (addr, NULL, &hints, &ai_res); \ if (s != 0) \ { \ if (s != fail) \ { \ printf ("getaddrinfo test %d failed: %s\n", no, gai_strerror (s)); \ result = 1; \ } \ ai_res = NULL; \ } \ else if (fail) \ { \ printf ("getaddrinfo test %d should have failed but did not\n", no); \ result = 1; \ } \ else if (ai_res->ai_family != fam) \ { \ printf ("\ getaddrinfo test %d return address of family %d, expected %d\n", \ no, ai_res->ai_family, fam); \ result = 1; \ } \ else if (fam == AF_INET) \ { \ if (ai_res->ai_addrlen != sizeof (struct sockaddr_in)) \ { \ printf ("getaddrinfo test %d: address size %zu, expected %zu\n", \ no, (size_t) ai_res->ai_addrlen, \ sizeof (struct sockaddr_in)); \ result = 1; \ } \ else if (strcmp (coraddr, \ inet_ntoa (((struct sockaddr_in *) ai_res->ai_addr)->sin_addr))\ != 0) \ { \ printf ("getaddrinfo test %d: got value %s, expected %s\n", \ no, \ inet_ntoa (((struct sockaddr_in *) ai_res->ai_addr)->sin_addr), \ coraddr); \ result = 1; \ } \ } \ else \ { \ char buf[100]; \ \ if (ai_res->ai_addrlen != sizeof (struct sockaddr_in6)) \ { \ printf ("getaddrinfo test %d: address size %zu, expected %zu\n", \ no, (size_t) ai_res->ai_addrlen, \ sizeof (struct sockaddr_in6)); \ result = 1; \ } \ else if (strcmp (coraddr, \ inet_ntop (AF_INET6, \ &((struct sockaddr_in6 *) ai_res->ai_addr)->sin6_addr,\ buf, sizeof (buf))) \ != 0) \ { \ printf ("getaddrinfo test %d: got value %s, expected %s\n", \ no, \ inet_ntop (AF_INET6, \ & ((struct sockaddr_in6 *) ai_res->ai_addr)->sin6_addr, \ buf, sizeof (buf)), \ coraddr); \ result = 1; \ } \ } \ if (ai_res != NULL && ai_res->ai_next != NULL) \ { \ puts ("expected only one result"); \ result = 1; \ } \ freeaddrinfo (ai_res) memset (&hints, '\0', sizeof (hints)); hints.ai_family = AF_UNSPEC; hints.ai_socktype = SOCK_STREAM; T (1, 0, "127.0.0.1", AF_INET, "127.0.0.1"); memset (&hints, '\0', sizeof (hints)); hints.ai_family = AF_INET; hints.ai_socktype = SOCK_STREAM; T (2, 0, "127.0.0.1", AF_INET, "127.0.0.1"); memset (&hints, '\0', sizeof (hints)); hints.ai_family = AF_INET6; hints.ai_socktype = SOCK_STREAM; hints.ai_flags = AI_V4MAPPED; T (3, 0, "127.0.0.1", AF_INET6, "::ffff:127.0.0.1"); memset (&hints, '\0', sizeof (hints)); hints.ai_family = AF_INET6; hints.ai_socktype = SOCK_STREAM; T (4, EAI_ADDRFAMILY, "127.0.0.1", AF_INET6, ""); memset (&hints, '\0', sizeof (hints)); hints.ai_family = AF_UNSPEC; hints.ai_socktype = SOCK_STREAM; T (5, 0, "::1", AF_INET6, "::1"); memset (&hints, '\0', sizeof (hints)); hints.ai_family = AF_INET; hints.ai_socktype = SOCK_STREAM; T (6, EAI_ADDRFAMILY, "::1", AF_INET6, ""); memset (&hints, '\0', sizeof (hints)); hints.ai_family = AF_INET6; hints.ai_socktype = SOCK_STREAM; T (7, 0, "::1", AF_INET6, "::1"); memset (&hints, '\0', sizeof (hints)); hints.ai_family = AF_UNSPEC; hints.ai_socktype = SOCK_STREAM; T (8, 0, "::ffff:127.0.0.1", AF_INET6, "::ffff:127.0.0.1"); memset (&hints, '\0', sizeof (hints)); hints.ai_family = AF_INET; hints.ai_socktype = SOCK_STREAM; T (9, 0, "::ffff:127.0.0.1", AF_INET, "127.0.0.1"); memset (&hints, '\0', sizeof (hints)); hints.ai_family = AF_INET6; hints.ai_socktype = SOCK_STREAM; T (10, 0, "::ffff:127.0.0.1", AF_INET6, "::ffff:127.0.0.1"); return result; } #define TEST_FUNCTION do_test () #include "../test-skeleton.c"