108ca345cSEnji Cooper /*- 208ca345cSEnji Cooper * Copyright (c) 2006 Michael Bushkov <bushman@freebsd.org> 308ca345cSEnji Cooper * All rights reserved. 408ca345cSEnji Cooper * 508ca345cSEnji Cooper * Redistribution and use in source and binary forms, with or without 608ca345cSEnji Cooper * modification, are permitted provided that the following conditions 708ca345cSEnji Cooper * are met: 808ca345cSEnji Cooper * 1. Redistributions of source code must retain the above copyright 908ca345cSEnji Cooper * notice, this list of conditions and the following disclaimer. 1008ca345cSEnji Cooper * 2. Redistributions in binary form must reproduce the above copyright 1108ca345cSEnji Cooper * notice, this list of conditions and the following disclaimer in the 1208ca345cSEnji Cooper * documentation and/or other materials provided with the distribution. 1308ca345cSEnji Cooper * 1408ca345cSEnji Cooper * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 1508ca345cSEnji Cooper * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 1608ca345cSEnji Cooper * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 1708ca345cSEnji Cooper * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 1808ca345cSEnji Cooper * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 1908ca345cSEnji Cooper * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2008ca345cSEnji Cooper * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2108ca345cSEnji Cooper * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2208ca345cSEnji Cooper * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2308ca345cSEnji Cooper * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 2408ca345cSEnji Cooper * SUCH DAMAGE. 2508ca345cSEnji Cooper * 2608ca345cSEnji Cooper */ 2708ca345cSEnji Cooper 2808ca345cSEnji Cooper #include <sys/cdefs.h> 2908ca345cSEnji Cooper __FBSDID("$FreeBSD$"); 3008ca345cSEnji Cooper 31bd8f63f2SEnji Cooper #include <sys/param.h> 3208ca345cSEnji Cooper #include <sys/socket.h> 3308ca345cSEnji Cooper #include <arpa/inet.h> 3408ca345cSEnji Cooper #include <netinet/in.h> 3508ca345cSEnji Cooper #include <errno.h> 3608ca345cSEnji Cooper #include <netdb.h> 3708ca345cSEnji Cooper #include <resolv.h> 3808ca345cSEnji Cooper #include <stdio.h> 3908ca345cSEnji Cooper #include <stdlib.h> 4008ca345cSEnji Cooper #include <string.h> 4108ca345cSEnji Cooper #include <stringlist.h> 4208ca345cSEnji Cooper #include <unistd.h> 4308ca345cSEnji Cooper 4408ca345cSEnji Cooper #include <atf-c.h> 4508ca345cSEnji Cooper 4608ca345cSEnji Cooper #include "freebsd_test_suite/macros.h" 4708ca345cSEnji Cooper #include "testutil.h" 4808ca345cSEnji Cooper 4908ca345cSEnji Cooper enum test_methods { 5008ca345cSEnji Cooper TEST_GETADDRINFO, 5108ca345cSEnji Cooper TEST_BUILD_SNAPSHOT 5208ca345cSEnji Cooper }; 5308ca345cSEnji Cooper 5408ca345cSEnji Cooper static struct addrinfo hints; 5508ca345cSEnji Cooper static enum test_methods method = TEST_GETADDRINFO; 5608ca345cSEnji Cooper 5708ca345cSEnji Cooper DECLARE_TEST_DATA(addrinfo) 5808ca345cSEnji Cooper DECLARE_TEST_FILE_SNAPSHOT(addrinfo) 5908ca345cSEnji Cooper DECLARE_2PASS_TEST(addrinfo) 6008ca345cSEnji Cooper 6108ca345cSEnji Cooper static void clone_addrinfo(struct addrinfo *, struct addrinfo const *); 6208ca345cSEnji Cooper static int compare_addrinfo(struct addrinfo *, struct addrinfo *, void *); 6308ca345cSEnji Cooper static void dump_addrinfo(struct addrinfo *); 6408ca345cSEnji Cooper 6508ca345cSEnji Cooper static void sdump_addrinfo(struct addrinfo *, char *, size_t); 6608ca345cSEnji Cooper 6708ca345cSEnji Cooper IMPLEMENT_TEST_DATA(addrinfo) 6808ca345cSEnji Cooper IMPLEMENT_TEST_FILE_SNAPSHOT(addrinfo) 6908ca345cSEnji Cooper IMPLEMENT_2PASS_TEST(addrinfo) 7008ca345cSEnji Cooper 7108ca345cSEnji Cooper static void 7208ca345cSEnji Cooper clone_addrinfo(struct addrinfo *dest, struct addrinfo const *src) 7308ca345cSEnji Cooper { 7408ca345cSEnji Cooper 7508ca345cSEnji Cooper ATF_REQUIRE(dest != NULL); 7608ca345cSEnji Cooper ATF_REQUIRE(src != NULL); 7708ca345cSEnji Cooper 7808ca345cSEnji Cooper memcpy(dest, src, sizeof(struct addrinfo)); 7908ca345cSEnji Cooper if (src->ai_canonname != NULL) 8008ca345cSEnji Cooper dest->ai_canonname = strdup(src->ai_canonname); 8108ca345cSEnji Cooper 8208ca345cSEnji Cooper if (src->ai_addr != NULL) { 8308ca345cSEnji Cooper dest->ai_addr = malloc(src->ai_addrlen); 8408ca345cSEnji Cooper ATF_REQUIRE(dest->ai_addr != NULL); 8508ca345cSEnji Cooper memcpy(dest->ai_addr, src->ai_addr, src->ai_addrlen); 8608ca345cSEnji Cooper } 8708ca345cSEnji Cooper 8808ca345cSEnji Cooper if (src->ai_next != NULL) { 8908ca345cSEnji Cooper dest->ai_next = malloc(sizeof(struct addrinfo)); 9008ca345cSEnji Cooper ATF_REQUIRE(dest->ai_next != NULL); 9108ca345cSEnji Cooper clone_addrinfo(dest->ai_next, src->ai_next); 9208ca345cSEnji Cooper } 9308ca345cSEnji Cooper } 9408ca345cSEnji Cooper 9508ca345cSEnji Cooper static int 9608ca345cSEnji Cooper compare_addrinfo_(struct addrinfo *ai1, struct addrinfo *ai2) 9708ca345cSEnji Cooper { 9808ca345cSEnji Cooper 9908ca345cSEnji Cooper if ((ai1 == NULL) || (ai2 == NULL)) 10008ca345cSEnji Cooper return (-1); 10108ca345cSEnji Cooper 10208ca345cSEnji Cooper if (ai1->ai_flags != ai2->ai_flags || 10308ca345cSEnji Cooper ai1->ai_family != ai2->ai_family || 10408ca345cSEnji Cooper ai1->ai_socktype != ai2->ai_socktype || 10508ca345cSEnji Cooper ai1->ai_protocol != ai2->ai_protocol || 10608ca345cSEnji Cooper ai1->ai_addrlen != ai2->ai_addrlen || 10708ca345cSEnji Cooper ((ai1->ai_addr == NULL || ai2->ai_addr == NULL) && 10808ca345cSEnji Cooper ai1->ai_addr != ai2->ai_addr) || 10908ca345cSEnji Cooper ((ai1->ai_canonname == NULL || ai2->ai_canonname == NULL) && 11008ca345cSEnji Cooper ai1->ai_canonname != ai2->ai_canonname)) 11108ca345cSEnji Cooper return (-1); 11208ca345cSEnji Cooper 11308ca345cSEnji Cooper if (ai1->ai_canonname != NULL && 11408ca345cSEnji Cooper strcmp(ai1->ai_canonname, ai2->ai_canonname) != 0) 11508ca345cSEnji Cooper return (-1); 11608ca345cSEnji Cooper 11708ca345cSEnji Cooper if (ai1->ai_addr != NULL && 11808ca345cSEnji Cooper memcmp(ai1->ai_addr, ai2->ai_addr, ai1->ai_addrlen) != 0) 11908ca345cSEnji Cooper return (-1); 12008ca345cSEnji Cooper 12108ca345cSEnji Cooper if (ai1->ai_next == NULL && ai2->ai_next == NULL) 12208ca345cSEnji Cooper return (0); 12308ca345cSEnji Cooper else 12408ca345cSEnji Cooper return (compare_addrinfo_(ai1->ai_next, ai2->ai_next)); 12508ca345cSEnji Cooper } 12608ca345cSEnji Cooper 12708ca345cSEnji Cooper static int 128bd8f63f2SEnji Cooper compare_addrinfo(struct addrinfo *ai1, struct addrinfo *ai2, 129bd8f63f2SEnji Cooper void *mdata __unused) 13008ca345cSEnji Cooper { 13108ca345cSEnji Cooper int rv; 13208ca345cSEnji Cooper 13308ca345cSEnji Cooper printf("testing equality of 2 addrinfo structures\n"); 13408ca345cSEnji Cooper 13508ca345cSEnji Cooper rv = compare_addrinfo_(ai1, ai2); 13608ca345cSEnji Cooper 13708ca345cSEnji Cooper if (rv == 0) 13808ca345cSEnji Cooper printf("equal\n"); 13908ca345cSEnji Cooper else { 14008ca345cSEnji Cooper dump_addrinfo(ai1); 14108ca345cSEnji Cooper dump_addrinfo(ai2); 14208ca345cSEnji Cooper printf("not equal\n"); 14308ca345cSEnji Cooper } 14408ca345cSEnji Cooper 14508ca345cSEnji Cooper return (rv); 14608ca345cSEnji Cooper } 14708ca345cSEnji Cooper 148bd874c6aSEnji Cooper static void 14908ca345cSEnji Cooper free_addrinfo(struct addrinfo *ai) 15008ca345cSEnji Cooper { 15108ca345cSEnji Cooper if (ai == NULL) 15208ca345cSEnji Cooper return; 15308ca345cSEnji Cooper 15408ca345cSEnji Cooper free(ai->ai_addr); 15508ca345cSEnji Cooper free(ai->ai_canonname); 15608ca345cSEnji Cooper free_addrinfo(ai->ai_next); 15708ca345cSEnji Cooper } 15808ca345cSEnji Cooper 15908ca345cSEnji Cooper void 16008ca345cSEnji Cooper sdump_addrinfo(struct addrinfo *ai, char *buffer, size_t buflen) 16108ca345cSEnji Cooper { 16208ca345cSEnji Cooper int written, i; 16308ca345cSEnji Cooper 16408ca345cSEnji Cooper written = snprintf(buffer, buflen, "%d %d %d %d %d ", 16508ca345cSEnji Cooper ai->ai_flags, ai->ai_family, ai->ai_socktype, ai->ai_protocol, 16608ca345cSEnji Cooper ai->ai_addrlen); 16708ca345cSEnji Cooper buffer += written; 168905de512SEnji Cooper if (written > (int)buflen) 16908ca345cSEnji Cooper return; 17008ca345cSEnji Cooper buflen -= written; 17108ca345cSEnji Cooper 17208ca345cSEnji Cooper written = snprintf(buffer, buflen, "%s ", 17308ca345cSEnji Cooper ai->ai_canonname == NULL ? "(null)" : ai->ai_canonname); 17408ca345cSEnji Cooper buffer += written; 175905de512SEnji Cooper if (written > (int)buflen) 17608ca345cSEnji Cooper return; 17708ca345cSEnji Cooper buflen -= written; 17808ca345cSEnji Cooper 17908ca345cSEnji Cooper if (ai->ai_addr == NULL) { 18008ca345cSEnji Cooper written = snprintf(buffer, buflen, "(null)"); 18108ca345cSEnji Cooper buffer += written; 182905de512SEnji Cooper if (written > (int)buflen) 18308ca345cSEnji Cooper return; 18408ca345cSEnji Cooper buflen -= written; 18508ca345cSEnji Cooper } else { 186905de512SEnji Cooper for (i = 0; i < (int)ai->ai_addrlen; i++) { 18708ca345cSEnji Cooper written = snprintf(buffer, buflen, 188905de512SEnji Cooper i + 1 != (int)ai->ai_addrlen ? "%d." : "%d", 18908ca345cSEnji Cooper ((unsigned char *)ai->ai_addr)[i]); 19008ca345cSEnji Cooper buffer += written; 191905de512SEnji Cooper if (written > (int)buflen) 19208ca345cSEnji Cooper return; 19308ca345cSEnji Cooper buflen -= written; 19408ca345cSEnji Cooper 19508ca345cSEnji Cooper if (buflen == 0) 19608ca345cSEnji Cooper return; 19708ca345cSEnji Cooper } 19808ca345cSEnji Cooper } 19908ca345cSEnji Cooper 20008ca345cSEnji Cooper if (ai->ai_next != NULL) { 20108ca345cSEnji Cooper written = snprintf(buffer, buflen, ":"); 20208ca345cSEnji Cooper buffer += written; 203905de512SEnji Cooper if (written > (int)buflen) 20408ca345cSEnji Cooper return; 20508ca345cSEnji Cooper buflen -= written; 20608ca345cSEnji Cooper 20708ca345cSEnji Cooper sdump_addrinfo(ai->ai_next, buffer, buflen); 20808ca345cSEnji Cooper } 20908ca345cSEnji Cooper } 21008ca345cSEnji Cooper 21108ca345cSEnji Cooper void 21208ca345cSEnji Cooper dump_addrinfo(struct addrinfo *result) 21308ca345cSEnji Cooper { 21408ca345cSEnji Cooper if (result != NULL) { 21508ca345cSEnji Cooper char buffer[2048]; 21608ca345cSEnji Cooper sdump_addrinfo(result, buffer, sizeof(buffer)); 21708ca345cSEnji Cooper printf("%s\n", buffer); 21808ca345cSEnji Cooper } else 21908ca345cSEnji Cooper printf("(null)\n"); 22008ca345cSEnji Cooper } 22108ca345cSEnji Cooper 22208ca345cSEnji Cooper static int 22308ca345cSEnji Cooper addrinfo_read_snapshot_addr(char *addr, unsigned char *result, size_t len) 22408ca345cSEnji Cooper { 22508ca345cSEnji Cooper char *s, *ps, *ts; 22608ca345cSEnji Cooper 22708ca345cSEnji Cooper ps = addr; 22808ca345cSEnji Cooper while ((s = strsep(&ps, ".")) != NULL) { 22908ca345cSEnji Cooper if (len == 0) 23008ca345cSEnji Cooper return (-1); 23108ca345cSEnji Cooper 23208ca345cSEnji Cooper *result = (unsigned char)strtol(s, &ts, 10); 23308ca345cSEnji Cooper ++result; 23408ca345cSEnji Cooper if (*ts != '\0') 23508ca345cSEnji Cooper return (-1); 23608ca345cSEnji Cooper 23708ca345cSEnji Cooper --len; 23808ca345cSEnji Cooper } 23908ca345cSEnji Cooper if (len != 0) 24008ca345cSEnji Cooper return (-1); 24108ca345cSEnji Cooper else 24208ca345cSEnji Cooper return (0); 24308ca345cSEnji Cooper } 24408ca345cSEnji Cooper 24508ca345cSEnji Cooper static int 24608ca345cSEnji Cooper addrinfo_read_snapshot_ai(struct addrinfo *ai, char *line) 24708ca345cSEnji Cooper { 24808ca345cSEnji Cooper char *s, *ps, *ts; 24908ca345cSEnji Cooper int i, rv, *pi; 25008ca345cSEnji Cooper 25108ca345cSEnji Cooper rv = 0; 25208ca345cSEnji Cooper i = 0; 25308ca345cSEnji Cooper ps = line; 25408ca345cSEnji Cooper memset(ai, 0, sizeof(struct addrinfo)); 25508ca345cSEnji Cooper while ((s = strsep(&ps, " ")) != NULL) { 25608ca345cSEnji Cooper switch (i) { 25708ca345cSEnji Cooper case 0: 25808ca345cSEnji Cooper case 1: 25908ca345cSEnji Cooper case 2: 26008ca345cSEnji Cooper case 3: 26108ca345cSEnji Cooper pi = &ai->ai_flags + i; 26208ca345cSEnji Cooper *pi = (int)strtol(s, &ts, 10); 26308ca345cSEnji Cooper if (*ts != '\0') 26408ca345cSEnji Cooper goto fin; 26508ca345cSEnji Cooper break; 26608ca345cSEnji Cooper case 4: 26708ca345cSEnji Cooper ai->ai_addrlen = (socklen_t)strtol(s, &ts, 10); 26808ca345cSEnji Cooper if (*ts != '\0') 26908ca345cSEnji Cooper goto fin; 27008ca345cSEnji Cooper break; 27108ca345cSEnji Cooper case 5: 27208ca345cSEnji Cooper if (strcmp(s, "(null)") != 0) { 27308ca345cSEnji Cooper ai->ai_canonname = strdup(s); 27408ca345cSEnji Cooper ATF_REQUIRE(ai->ai_canonname != NULL); 27508ca345cSEnji Cooper } 27608ca345cSEnji Cooper break; 27708ca345cSEnji Cooper case 6: 27808ca345cSEnji Cooper if (strcmp(s, "(null)") != 0) { 27908ca345cSEnji Cooper ai->ai_addr = calloc(1, ai->ai_addrlen); 28008ca345cSEnji Cooper ATF_REQUIRE(ai->ai_addr != NULL); 28108ca345cSEnji Cooper rv = addrinfo_read_snapshot_addr(s, 28208ca345cSEnji Cooper (unsigned char *)ai->ai_addr, 28308ca345cSEnji Cooper ai->ai_addrlen); 28408ca345cSEnji Cooper 28508ca345cSEnji Cooper if (rv != 0) 28608ca345cSEnji Cooper goto fin; 28708ca345cSEnji Cooper } 28808ca345cSEnji Cooper break; 28908ca345cSEnji Cooper default: 29008ca345cSEnji Cooper /* NOTE: should not be reachable */ 29108ca345cSEnji Cooper rv = -1; 29208ca345cSEnji Cooper goto fin; 29308ca345cSEnji Cooper } 29408ca345cSEnji Cooper 29508ca345cSEnji Cooper ++i; 29608ca345cSEnji Cooper } 29708ca345cSEnji Cooper 29808ca345cSEnji Cooper fin: 29908ca345cSEnji Cooper if (i != 7 || rv != 0) { 30008ca345cSEnji Cooper free_addrinfo(ai); 30108ca345cSEnji Cooper ai = NULL; 30208ca345cSEnji Cooper return (-1); 30308ca345cSEnji Cooper } 30408ca345cSEnji Cooper 30508ca345cSEnji Cooper return (0); 30608ca345cSEnji Cooper } 30708ca345cSEnji Cooper 30808ca345cSEnji Cooper static int 30908ca345cSEnji Cooper addrinfo_read_snapshot_func(struct addrinfo *ai, char *line) 31008ca345cSEnji Cooper { 31108ca345cSEnji Cooper struct addrinfo *ai2; 31208ca345cSEnji Cooper char *s, *ps; 313e1f54757SEnji Cooper int rv; 31408ca345cSEnji Cooper 31508ca345cSEnji Cooper printf("1 line read from snapshot:\n%s\n", line); 31608ca345cSEnji Cooper 31708ca345cSEnji Cooper rv = 0; 31808ca345cSEnji Cooper ps = line; 31908ca345cSEnji Cooper 32008ca345cSEnji Cooper s = strsep(&ps, ":"); 32108ca345cSEnji Cooper if (s == NULL) 32208ca345cSEnji Cooper return (-1); 32308ca345cSEnji Cooper 32408ca345cSEnji Cooper rv = addrinfo_read_snapshot_ai(ai, s); 32508ca345cSEnji Cooper if (rv != 0) 32608ca345cSEnji Cooper return (-1); 32708ca345cSEnji Cooper 32808ca345cSEnji Cooper ai2 = ai; 32908ca345cSEnji Cooper while ((s = strsep(&ps, ":")) != NULL) { 33008ca345cSEnji Cooper ai2->ai_next = calloc(1, sizeof(struct addrinfo)); 33108ca345cSEnji Cooper ATF_REQUIRE(ai2->ai_next != NULL); 33208ca345cSEnji Cooper 33308ca345cSEnji Cooper rv = addrinfo_read_snapshot_ai(ai2->ai_next, s); 33408ca345cSEnji Cooper if (rv != 0) { 33508ca345cSEnji Cooper free_addrinfo(ai); 33608ca345cSEnji Cooper ai = NULL; 33708ca345cSEnji Cooper return (-1); 33808ca345cSEnji Cooper } 33908ca345cSEnji Cooper 34008ca345cSEnji Cooper ai2 = ai2->ai_next; 34108ca345cSEnji Cooper } 34208ca345cSEnji Cooper 34308ca345cSEnji Cooper return (0); 34408ca345cSEnji Cooper } 34508ca345cSEnji Cooper 34608ca345cSEnji Cooper static int 347bd8f63f2SEnji Cooper addrinfo_test_correctness(struct addrinfo *ai, void *mdata __unused) 34808ca345cSEnji Cooper { 34908ca345cSEnji Cooper 35008ca345cSEnji Cooper printf("testing correctness with the following data:\n"); 35108ca345cSEnji Cooper dump_addrinfo(ai); 35208ca345cSEnji Cooper 35308ca345cSEnji Cooper if (ai == NULL) 35408ca345cSEnji Cooper goto errfin; 35508ca345cSEnji Cooper 35608ca345cSEnji Cooper if (!(ai->ai_family >= 0 && ai->ai_family < AF_MAX)) 35708ca345cSEnji Cooper goto errfin; 35808ca345cSEnji Cooper 35908ca345cSEnji Cooper if (ai->ai_socktype != 0 && ai->ai_socktype != SOCK_STREAM && 36008ca345cSEnji Cooper ai->ai_socktype != SOCK_DGRAM && ai->ai_socktype != SOCK_RAW) 36108ca345cSEnji Cooper goto errfin; 36208ca345cSEnji Cooper 36308ca345cSEnji Cooper if (ai->ai_protocol != 0 && ai->ai_protocol != IPPROTO_UDP && 36408ca345cSEnji Cooper ai->ai_protocol != IPPROTO_TCP) 36508ca345cSEnji Cooper goto errfin; 36608ca345cSEnji Cooper 36708ca345cSEnji Cooper if ((ai->ai_flags & ~(AI_CANONNAME | AI_NUMERICHOST | AI_PASSIVE)) != 0) 36808ca345cSEnji Cooper goto errfin; 36908ca345cSEnji Cooper 37008ca345cSEnji Cooper if (ai->ai_addrlen != ai->ai_addr->sa_len || 37108ca345cSEnji Cooper ai->ai_family != ai->ai_addr->sa_family) 37208ca345cSEnji Cooper goto errfin; 37308ca345cSEnji Cooper 37408ca345cSEnji Cooper printf("correct\n"); 37508ca345cSEnji Cooper 37608ca345cSEnji Cooper return (0); 37708ca345cSEnji Cooper errfin: 37808ca345cSEnji Cooper printf("incorrect\n"); 37908ca345cSEnji Cooper 38008ca345cSEnji Cooper return (-1); 38108ca345cSEnji Cooper } 38208ca345cSEnji Cooper 38308ca345cSEnji Cooper static int 38408ca345cSEnji Cooper addrinfo_read_hostlist_func(struct addrinfo *ai, char *line) 38508ca345cSEnji Cooper { 38608ca345cSEnji Cooper struct addrinfo *result; 38708ca345cSEnji Cooper int rv; 38808ca345cSEnji Cooper 38908ca345cSEnji Cooper printf("resolving %s: ", line); 39008ca345cSEnji Cooper rv = getaddrinfo(line, NULL, &hints, &result); 39108ca345cSEnji Cooper if (rv == 0) { 39208ca345cSEnji Cooper printf("found\n"); 39308ca345cSEnji Cooper 39408ca345cSEnji Cooper rv = addrinfo_test_correctness(result, NULL); 39508ca345cSEnji Cooper if (rv != 0) { 39608ca345cSEnji Cooper freeaddrinfo(result); 39708ca345cSEnji Cooper result = NULL; 39808ca345cSEnji Cooper return (rv); 39908ca345cSEnji Cooper } 40008ca345cSEnji Cooper 40108ca345cSEnji Cooper clone_addrinfo(ai, result); 40208ca345cSEnji Cooper freeaddrinfo(result); 40308ca345cSEnji Cooper result = NULL; 40408ca345cSEnji Cooper } else { 40508ca345cSEnji Cooper printf("not found\n"); 40608ca345cSEnji Cooper 40708ca345cSEnji Cooper memset(ai, 0, sizeof(struct addrinfo)); 40808ca345cSEnji Cooper } 40908ca345cSEnji Cooper return (0); 41008ca345cSEnji Cooper } 41108ca345cSEnji Cooper 412bd874c6aSEnji Cooper static void 413*8eb23675SEnji Cooper run_tests(char *hostlist_file, const char *snapshot_file, int ai_family) 41408ca345cSEnji Cooper { 41508ca345cSEnji Cooper struct addrinfo_test_data td, td_snap; 416*8eb23675SEnji Cooper char *snapshot_file_copy; 41708ca345cSEnji Cooper int rv; 41808ca345cSEnji Cooper 419*8eb23675SEnji Cooper if (snapshot_file == NULL) 420*8eb23675SEnji Cooper snapshot_file_copy = NULL; 421*8eb23675SEnji Cooper else { 422*8eb23675SEnji Cooper snapshot_file_copy = strdup(snapshot_file); 423*8eb23675SEnji Cooper ATF_REQUIRE(snapshot_file_copy != NULL); 424*8eb23675SEnji Cooper } 425*8eb23675SEnji Cooper 42608ca345cSEnji Cooper memset(&hints, 0, sizeof(struct addrinfo)); 42708ca345cSEnji Cooper hints.ai_family = ai_family; 42808ca345cSEnji Cooper hints.ai_flags = AI_CANONNAME; 42908ca345cSEnji Cooper 43008ca345cSEnji Cooper if (snapshot_file != NULL) 43108ca345cSEnji Cooper method = TEST_BUILD_SNAPSHOT; 43208ca345cSEnji Cooper 43308ca345cSEnji Cooper TEST_DATA_INIT(addrinfo, &td, clone_addrinfo, free_addrinfo); 43408ca345cSEnji Cooper TEST_DATA_INIT(addrinfo, &td_snap, clone_addrinfo, free_addrinfo); 43508ca345cSEnji Cooper 43608ca345cSEnji Cooper ATF_REQUIRE_MSG(access(hostlist_file, R_OK) == 0, 43708ca345cSEnji Cooper "can't access the hostlist file %s\n", hostlist_file); 43808ca345cSEnji Cooper 43908ca345cSEnji Cooper printf("building host lists from %s\n", hostlist_file); 44008ca345cSEnji Cooper 44108ca345cSEnji Cooper rv = TEST_SNAPSHOT_FILE_READ(addrinfo, hostlist_file, &td, 44208ca345cSEnji Cooper addrinfo_read_hostlist_func); 44308ca345cSEnji Cooper if (rv != 0) 44408ca345cSEnji Cooper goto fin; 44508ca345cSEnji Cooper 44608ca345cSEnji Cooper if (snapshot_file != NULL) { 44708ca345cSEnji Cooper if (access(snapshot_file, W_OK | R_OK) != 0) { 44808ca345cSEnji Cooper if (errno == ENOENT) 44908ca345cSEnji Cooper method = TEST_BUILD_SNAPSHOT; 45008ca345cSEnji Cooper else { 45108ca345cSEnji Cooper printf("can't access the snapshot " 45208ca345cSEnji Cooper "file %s\n", snapshot_file); 45308ca345cSEnji Cooper 45408ca345cSEnji Cooper rv = -1; 45508ca345cSEnji Cooper goto fin; 45608ca345cSEnji Cooper } 45708ca345cSEnji Cooper } else { 45808ca345cSEnji Cooper rv = TEST_SNAPSHOT_FILE_READ(addrinfo, snapshot_file, 45908ca345cSEnji Cooper &td_snap, addrinfo_read_snapshot_func); 46008ca345cSEnji Cooper if (rv != 0) { 46108ca345cSEnji Cooper printf("error reading snapshot file: %s\n", 46208ca345cSEnji Cooper strerror(errno)); 46308ca345cSEnji Cooper goto fin; 46408ca345cSEnji Cooper } 46508ca345cSEnji Cooper } 46608ca345cSEnji Cooper } 46708ca345cSEnji Cooper 46808ca345cSEnji Cooper switch (method) { 46908ca345cSEnji Cooper case TEST_GETADDRINFO: 47008ca345cSEnji Cooper if (snapshot_file != NULL) 47108ca345cSEnji Cooper ATF_CHECK(DO_2PASS_TEST(addrinfo, &td, &td_snap, 47208ca345cSEnji Cooper compare_addrinfo, NULL) == 0); 47308ca345cSEnji Cooper break; 47408ca345cSEnji Cooper case TEST_BUILD_SNAPSHOT: 47508ca345cSEnji Cooper if (snapshot_file != NULL) { 47608ca345cSEnji Cooper ATF_CHECK(TEST_SNAPSHOT_FILE_WRITE(addrinfo, 47708ca345cSEnji Cooper snapshot_file, &td, sdump_addrinfo) == 0); 47808ca345cSEnji Cooper } 47908ca345cSEnji Cooper break; 48008ca345cSEnji Cooper default: 48108ca345cSEnji Cooper break; 48208ca345cSEnji Cooper } 48308ca345cSEnji Cooper 48408ca345cSEnji Cooper fin: 48508ca345cSEnji Cooper TEST_DATA_DESTROY(addrinfo, &td_snap); 48608ca345cSEnji Cooper TEST_DATA_DESTROY(addrinfo, &td); 48708ca345cSEnji Cooper 488*8eb23675SEnji Cooper free(snapshot_file_copy); 48908ca345cSEnji Cooper } 49008ca345cSEnji Cooper 49108ca345cSEnji Cooper #define HOSTLIST_FILE "mach" 49208ca345cSEnji Cooper #define RUN_TESTS(tc, snapshot_file, ai_family) do { \ 49308ca345cSEnji Cooper char *_hostlist_file; \ 49408ca345cSEnji Cooper ATF_REQUIRE(0 < asprintf(&_hostlist_file, "%s/%s", \ 49508ca345cSEnji Cooper atf_tc_get_config_var(tc, "srcdir"), HOSTLIST_FILE)); \ 496*8eb23675SEnji Cooper run_tests(_hostlist_file, snapshot_file, ai_family); \ 497*8eb23675SEnji Cooper free(_hostlist_file); \ 49808ca345cSEnji Cooper } while (0) 49908ca345cSEnji Cooper 50008ca345cSEnji Cooper ATF_TC_WITHOUT_HEAD(pf_unspec); 50108ca345cSEnji Cooper ATF_TC_BODY(pf_unspec, tc) 50208ca345cSEnji Cooper { 50308ca345cSEnji Cooper 50408ca345cSEnji Cooper RUN_TESTS(tc, NULL, AF_UNSPEC); 50508ca345cSEnji Cooper } 50608ca345cSEnji Cooper 50708ca345cSEnji Cooper ATF_TC_WITHOUT_HEAD(pf_unspec_with_snapshot); 50808ca345cSEnji Cooper ATF_TC_BODY(pf_unspec_with_snapshot, tc) 50908ca345cSEnji Cooper { 51008ca345cSEnji Cooper 51108ca345cSEnji Cooper RUN_TESTS(tc, "snapshot_ai", AF_UNSPEC); 51208ca345cSEnji Cooper } 51308ca345cSEnji Cooper 51408ca345cSEnji Cooper ATF_TC_WITHOUT_HEAD(pf_inet); 51508ca345cSEnji Cooper ATF_TC_BODY(pf_inet, tc) 51608ca345cSEnji Cooper { 51708ca345cSEnji Cooper 51808ca345cSEnji Cooper ATF_REQUIRE_FEATURE("inet"); 51908ca345cSEnji Cooper RUN_TESTS(tc, NULL, AF_INET); 52008ca345cSEnji Cooper } 52108ca345cSEnji Cooper 52208ca345cSEnji Cooper ATF_TC_WITHOUT_HEAD(pf_inet_with_snapshot); 52308ca345cSEnji Cooper ATF_TC_BODY(pf_inet_with_snapshot, tc) 52408ca345cSEnji Cooper { 52508ca345cSEnji Cooper 52608ca345cSEnji Cooper ATF_REQUIRE_FEATURE("inet"); 52708ca345cSEnji Cooper RUN_TESTS(tc, "snapshot_ai4", AF_INET); 52808ca345cSEnji Cooper } 52908ca345cSEnji Cooper 53008ca345cSEnji Cooper ATF_TC_WITHOUT_HEAD(pf_inet6); 53108ca345cSEnji Cooper ATF_TC_BODY(pf_inet6, tc) 53208ca345cSEnji Cooper { 53308ca345cSEnji Cooper 53408ca345cSEnji Cooper ATF_REQUIRE_FEATURE("inet6"); 53508ca345cSEnji Cooper RUN_TESTS(tc, NULL, AF_INET6); 53608ca345cSEnji Cooper } 53708ca345cSEnji Cooper 53808ca345cSEnji Cooper ATF_TC_WITHOUT_HEAD(pf_inet6_with_snapshot); 53908ca345cSEnji Cooper ATF_TC_BODY(pf_inet6_with_snapshot, tc) 54008ca345cSEnji Cooper { 54108ca345cSEnji Cooper 54208ca345cSEnji Cooper ATF_REQUIRE_FEATURE("inet6"); 54308ca345cSEnji Cooper RUN_TESTS(tc, "snapshot_ai6", AF_INET6); 54408ca345cSEnji Cooper } 54508ca345cSEnji Cooper 54608ca345cSEnji Cooper ATF_TP_ADD_TCS(tp) 54708ca345cSEnji Cooper { 54808ca345cSEnji Cooper 54908ca345cSEnji Cooper ATF_TP_ADD_TC(tp, pf_unspec); 55008ca345cSEnji Cooper ATF_TP_ADD_TC(tp, pf_unspec_with_snapshot); 55108ca345cSEnji Cooper ATF_TP_ADD_TC(tp, pf_inet); 55208ca345cSEnji Cooper ATF_TP_ADD_TC(tp, pf_inet_with_snapshot); 55308ca345cSEnji Cooper ATF_TP_ADD_TC(tp, pf_inet6); 55408ca345cSEnji Cooper ATF_TP_ADD_TC(tp, pf_inet6_with_snapshot); 55508ca345cSEnji Cooper 55608ca345cSEnji Cooper return (atf_no_error()); 55708ca345cSEnji Cooper } 558