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 3108ca345cSEnji Cooper #include <sys/types.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 12808ca345cSEnji Cooper compare_addrinfo(struct addrinfo *ai1, struct addrinfo *ai2, void *mdata) 12908ca345cSEnji Cooper { 13008ca345cSEnji Cooper int rv; 13108ca345cSEnji Cooper 13208ca345cSEnji Cooper printf("testing equality of 2 addrinfo structures\n"); 13308ca345cSEnji Cooper 13408ca345cSEnji Cooper rv = compare_addrinfo_(ai1, ai2); 13508ca345cSEnji Cooper 13608ca345cSEnji Cooper if (rv == 0) 13708ca345cSEnji Cooper printf("equal\n"); 13808ca345cSEnji Cooper else { 13908ca345cSEnji Cooper dump_addrinfo(ai1); 14008ca345cSEnji Cooper dump_addrinfo(ai2); 14108ca345cSEnji Cooper printf("not equal\n"); 14208ca345cSEnji Cooper } 14308ca345cSEnji Cooper 14408ca345cSEnji Cooper return (rv); 14508ca345cSEnji Cooper } 14608ca345cSEnji Cooper 147*bd874c6aSEnji Cooper static void 14808ca345cSEnji Cooper free_addrinfo(struct addrinfo *ai) 14908ca345cSEnji Cooper { 15008ca345cSEnji Cooper if (ai == NULL) 15108ca345cSEnji Cooper return; 15208ca345cSEnji Cooper 15308ca345cSEnji Cooper free(ai->ai_addr); 15408ca345cSEnji Cooper free(ai->ai_canonname); 15508ca345cSEnji Cooper free_addrinfo(ai->ai_next); 15608ca345cSEnji Cooper } 15708ca345cSEnji Cooper 15808ca345cSEnji Cooper void 15908ca345cSEnji Cooper sdump_addrinfo(struct addrinfo *ai, char *buffer, size_t buflen) 16008ca345cSEnji Cooper { 16108ca345cSEnji Cooper int written, i; 16208ca345cSEnji Cooper 16308ca345cSEnji Cooper written = snprintf(buffer, buflen, "%d %d %d %d %d ", 16408ca345cSEnji Cooper ai->ai_flags, ai->ai_family, ai->ai_socktype, ai->ai_protocol, 16508ca345cSEnji Cooper ai->ai_addrlen); 16608ca345cSEnji Cooper buffer += written; 16708ca345cSEnji Cooper if (written > buflen) 16808ca345cSEnji Cooper return; 16908ca345cSEnji Cooper buflen -= written; 17008ca345cSEnji Cooper 17108ca345cSEnji Cooper written = snprintf(buffer, buflen, "%s ", 17208ca345cSEnji Cooper ai->ai_canonname == NULL ? "(null)" : ai->ai_canonname); 17308ca345cSEnji Cooper buffer += written; 17408ca345cSEnji Cooper if (written > buflen) 17508ca345cSEnji Cooper return; 17608ca345cSEnji Cooper buflen -= written; 17708ca345cSEnji Cooper 17808ca345cSEnji Cooper if (ai->ai_addr == NULL) { 17908ca345cSEnji Cooper written = snprintf(buffer, buflen, "(null)"); 18008ca345cSEnji Cooper buffer += written; 18108ca345cSEnji Cooper if (written > buflen) 18208ca345cSEnji Cooper return; 18308ca345cSEnji Cooper buflen -= written; 18408ca345cSEnji Cooper } else { 18508ca345cSEnji Cooper for (i = 0; i < ai->ai_addrlen; i++) { 18608ca345cSEnji Cooper written = snprintf(buffer, buflen, 18708ca345cSEnji Cooper i + 1 != ai->ai_addrlen ? "%d." : "%d", 18808ca345cSEnji Cooper ((unsigned char *)ai->ai_addr)[i]); 18908ca345cSEnji Cooper buffer += written; 19008ca345cSEnji Cooper if (written > buflen) 19108ca345cSEnji Cooper return; 19208ca345cSEnji Cooper buflen -= written; 19308ca345cSEnji Cooper 19408ca345cSEnji Cooper if (buflen == 0) 19508ca345cSEnji Cooper return; 19608ca345cSEnji Cooper } 19708ca345cSEnji Cooper } 19808ca345cSEnji Cooper 19908ca345cSEnji Cooper if (ai->ai_next != NULL) { 20008ca345cSEnji Cooper written = snprintf(buffer, buflen, ":"); 20108ca345cSEnji Cooper buffer += written; 20208ca345cSEnji Cooper if (written > buflen) 20308ca345cSEnji Cooper return; 20408ca345cSEnji Cooper buflen -= written; 20508ca345cSEnji Cooper 20608ca345cSEnji Cooper sdump_addrinfo(ai->ai_next, buffer, buflen); 20708ca345cSEnji Cooper } 20808ca345cSEnji Cooper } 20908ca345cSEnji Cooper 21008ca345cSEnji Cooper void 21108ca345cSEnji Cooper dump_addrinfo(struct addrinfo *result) 21208ca345cSEnji Cooper { 21308ca345cSEnji Cooper if (result != NULL) { 21408ca345cSEnji Cooper char buffer[2048]; 21508ca345cSEnji Cooper sdump_addrinfo(result, buffer, sizeof(buffer)); 21608ca345cSEnji Cooper printf("%s\n", buffer); 21708ca345cSEnji Cooper } else 21808ca345cSEnji Cooper printf("(null)\n"); 21908ca345cSEnji Cooper } 22008ca345cSEnji Cooper 22108ca345cSEnji Cooper static int 22208ca345cSEnji Cooper addrinfo_read_snapshot_addr(char *addr, unsigned char *result, size_t len) 22308ca345cSEnji Cooper { 22408ca345cSEnji Cooper char *s, *ps, *ts; 22508ca345cSEnji Cooper 22608ca345cSEnji Cooper ps = addr; 22708ca345cSEnji Cooper while ((s = strsep(&ps, ".")) != NULL) { 22808ca345cSEnji Cooper if (len == 0) 22908ca345cSEnji Cooper return (-1); 23008ca345cSEnji Cooper 23108ca345cSEnji Cooper *result = (unsigned char)strtol(s, &ts, 10); 23208ca345cSEnji Cooper ++result; 23308ca345cSEnji Cooper if (*ts != '\0') 23408ca345cSEnji Cooper return (-1); 23508ca345cSEnji Cooper 23608ca345cSEnji Cooper --len; 23708ca345cSEnji Cooper } 23808ca345cSEnji Cooper if (len != 0) 23908ca345cSEnji Cooper return (-1); 24008ca345cSEnji Cooper else 24108ca345cSEnji Cooper return (0); 24208ca345cSEnji Cooper } 24308ca345cSEnji Cooper 24408ca345cSEnji Cooper static int 24508ca345cSEnji Cooper addrinfo_read_snapshot_ai(struct addrinfo *ai, char *line) 24608ca345cSEnji Cooper { 24708ca345cSEnji Cooper char *s, *ps, *ts; 24808ca345cSEnji Cooper int i, rv, *pi; 24908ca345cSEnji Cooper 25008ca345cSEnji Cooper rv = 0; 25108ca345cSEnji Cooper i = 0; 25208ca345cSEnji Cooper ps = line; 25308ca345cSEnji Cooper memset(ai, 0, sizeof(struct addrinfo)); 25408ca345cSEnji Cooper while ((s = strsep(&ps, " ")) != NULL) { 25508ca345cSEnji Cooper switch (i) { 25608ca345cSEnji Cooper case 0: 25708ca345cSEnji Cooper case 1: 25808ca345cSEnji Cooper case 2: 25908ca345cSEnji Cooper case 3: 26008ca345cSEnji Cooper pi = &ai->ai_flags + i; 26108ca345cSEnji Cooper *pi = (int)strtol(s, &ts, 10); 26208ca345cSEnji Cooper if (*ts != '\0') 26308ca345cSEnji Cooper goto fin; 26408ca345cSEnji Cooper break; 26508ca345cSEnji Cooper case 4: 26608ca345cSEnji Cooper ai->ai_addrlen = (socklen_t)strtol(s, &ts, 10); 26708ca345cSEnji Cooper if (*ts != '\0') 26808ca345cSEnji Cooper goto fin; 26908ca345cSEnji Cooper break; 27008ca345cSEnji Cooper case 5: 27108ca345cSEnji Cooper if (strcmp(s, "(null)") != 0) { 27208ca345cSEnji Cooper ai->ai_canonname = strdup(s); 27308ca345cSEnji Cooper ATF_REQUIRE(ai->ai_canonname != NULL); 27408ca345cSEnji Cooper } 27508ca345cSEnji Cooper break; 27608ca345cSEnji Cooper case 6: 27708ca345cSEnji Cooper if (strcmp(s, "(null)") != 0) { 27808ca345cSEnji Cooper ai->ai_addr = calloc(1, ai->ai_addrlen); 27908ca345cSEnji Cooper ATF_REQUIRE(ai->ai_addr != NULL); 28008ca345cSEnji Cooper rv = addrinfo_read_snapshot_addr(s, 28108ca345cSEnji Cooper (unsigned char *)ai->ai_addr, 28208ca345cSEnji Cooper ai->ai_addrlen); 28308ca345cSEnji Cooper 28408ca345cSEnji Cooper if (rv != 0) 28508ca345cSEnji Cooper goto fin; 28608ca345cSEnji Cooper } 28708ca345cSEnji Cooper break; 28808ca345cSEnji Cooper default: 28908ca345cSEnji Cooper /* NOTE: should not be reachable */ 29008ca345cSEnji Cooper rv = -1; 29108ca345cSEnji Cooper goto fin; 29208ca345cSEnji Cooper } 29308ca345cSEnji Cooper 29408ca345cSEnji Cooper ++i; 29508ca345cSEnji Cooper } 29608ca345cSEnji Cooper 29708ca345cSEnji Cooper fin: 29808ca345cSEnji Cooper if (i != 7 || rv != 0) { 29908ca345cSEnji Cooper free_addrinfo(ai); 30008ca345cSEnji Cooper ai = NULL; 30108ca345cSEnji Cooper return (-1); 30208ca345cSEnji Cooper } 30308ca345cSEnji Cooper 30408ca345cSEnji Cooper return (0); 30508ca345cSEnji Cooper } 30608ca345cSEnji Cooper 30708ca345cSEnji Cooper static int 30808ca345cSEnji Cooper addrinfo_read_snapshot_func(struct addrinfo *ai, char *line) 30908ca345cSEnji Cooper { 31008ca345cSEnji Cooper struct addrinfo *ai2; 31108ca345cSEnji Cooper char *s, *ps; 31208ca345cSEnji Cooper int i, rv; 31308ca345cSEnji Cooper 31408ca345cSEnji Cooper printf("1 line read from snapshot:\n%s\n", line); 31508ca345cSEnji Cooper 31608ca345cSEnji Cooper rv = 0; 31708ca345cSEnji Cooper i = 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 34708ca345cSEnji Cooper addrinfo_test_correctness(struct addrinfo *ai, void *mdata) 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 412*bd874c6aSEnji Cooper static void 41308ca345cSEnji Cooper run_tests(char *hostlist_file, char *snapshot_file, int ai_family) 41408ca345cSEnji Cooper { 41508ca345cSEnji Cooper struct addrinfo_test_data td, td_snap; 41608ca345cSEnji Cooper int rv; 41708ca345cSEnji Cooper 41808ca345cSEnji Cooper memset(&hints, 0, sizeof(struct addrinfo)); 41908ca345cSEnji Cooper hints.ai_family = ai_family; 42008ca345cSEnji Cooper hints.ai_flags = AI_CANONNAME; 42108ca345cSEnji Cooper 42208ca345cSEnji Cooper if (snapshot_file != NULL) 42308ca345cSEnji Cooper method = TEST_BUILD_SNAPSHOT; 42408ca345cSEnji Cooper 42508ca345cSEnji Cooper TEST_DATA_INIT(addrinfo, &td, clone_addrinfo, free_addrinfo); 42608ca345cSEnji Cooper TEST_DATA_INIT(addrinfo, &td_snap, clone_addrinfo, free_addrinfo); 42708ca345cSEnji Cooper 42808ca345cSEnji Cooper ATF_REQUIRE_MSG(access(hostlist_file, R_OK) == 0, 42908ca345cSEnji Cooper "can't access the hostlist file %s\n", hostlist_file); 43008ca345cSEnji Cooper 43108ca345cSEnji Cooper printf("building host lists from %s\n", hostlist_file); 43208ca345cSEnji Cooper 43308ca345cSEnji Cooper rv = TEST_SNAPSHOT_FILE_READ(addrinfo, hostlist_file, &td, 43408ca345cSEnji Cooper addrinfo_read_hostlist_func); 43508ca345cSEnji Cooper if (rv != 0) 43608ca345cSEnji Cooper goto fin; 43708ca345cSEnji Cooper 43808ca345cSEnji Cooper if (snapshot_file != NULL) { 43908ca345cSEnji Cooper if (access(snapshot_file, W_OK | R_OK) != 0) { 44008ca345cSEnji Cooper if (errno == ENOENT) 44108ca345cSEnji Cooper method = TEST_BUILD_SNAPSHOT; 44208ca345cSEnji Cooper else { 44308ca345cSEnji Cooper printf("can't access the snapshot " 44408ca345cSEnji Cooper "file %s\n", snapshot_file); 44508ca345cSEnji Cooper 44608ca345cSEnji Cooper rv = -1; 44708ca345cSEnji Cooper goto fin; 44808ca345cSEnji Cooper } 44908ca345cSEnji Cooper } else { 45008ca345cSEnji Cooper rv = TEST_SNAPSHOT_FILE_READ(addrinfo, snapshot_file, 45108ca345cSEnji Cooper &td_snap, addrinfo_read_snapshot_func); 45208ca345cSEnji Cooper if (rv != 0) { 45308ca345cSEnji Cooper printf("error reading snapshot file: %s\n", 45408ca345cSEnji Cooper strerror(errno)); 45508ca345cSEnji Cooper goto fin; 45608ca345cSEnji Cooper } 45708ca345cSEnji Cooper } 45808ca345cSEnji Cooper } 45908ca345cSEnji Cooper 46008ca345cSEnji Cooper switch (method) { 46108ca345cSEnji Cooper case TEST_GETADDRINFO: 46208ca345cSEnji Cooper if (snapshot_file != NULL) 46308ca345cSEnji Cooper ATF_CHECK(DO_2PASS_TEST(addrinfo, &td, &td_snap, 46408ca345cSEnji Cooper compare_addrinfo, NULL) == 0); 46508ca345cSEnji Cooper break; 46608ca345cSEnji Cooper case TEST_BUILD_SNAPSHOT: 46708ca345cSEnji Cooper if (snapshot_file != NULL) { 46808ca345cSEnji Cooper ATF_CHECK(TEST_SNAPSHOT_FILE_WRITE(addrinfo, 46908ca345cSEnji Cooper snapshot_file, &td, sdump_addrinfo) == 0); 47008ca345cSEnji Cooper } 47108ca345cSEnji Cooper break; 47208ca345cSEnji Cooper default: 47308ca345cSEnji Cooper break; 47408ca345cSEnji Cooper } 47508ca345cSEnji Cooper 47608ca345cSEnji Cooper fin: 47708ca345cSEnji Cooper TEST_DATA_DESTROY(addrinfo, &td_snap); 47808ca345cSEnji Cooper TEST_DATA_DESTROY(addrinfo, &td); 47908ca345cSEnji Cooper 48008ca345cSEnji Cooper free(hostlist_file); 48108ca345cSEnji Cooper free(snapshot_file); 48208ca345cSEnji Cooper } 48308ca345cSEnji Cooper 48408ca345cSEnji Cooper #define HOSTLIST_FILE "mach" 48508ca345cSEnji Cooper #define RUN_TESTS(tc, snapshot_file, ai_family) do { \ 48608ca345cSEnji Cooper char *_hostlist_file; \ 48708ca345cSEnji Cooper char *_snapshot_file; \ 48808ca345cSEnji Cooper ATF_REQUIRE(0 < asprintf(&_hostlist_file, "%s/%s", \ 48908ca345cSEnji Cooper atf_tc_get_config_var(tc, "srcdir"), HOSTLIST_FILE)); \ 49008ca345cSEnji Cooper if (snapshot_file == NULL) \ 49108ca345cSEnji Cooper _snapshot_file = NULL; \ 49208ca345cSEnji Cooper else { \ 49308ca345cSEnji Cooper _snapshot_file = strdup(snapshot_file); \ 49408ca345cSEnji Cooper ATF_REQUIRE(_snapshot_file != NULL); \ 49508ca345cSEnji Cooper } \ 49608ca345cSEnji Cooper run_tests(_hostlist_file, _snapshot_file, ai_family); \ 49708ca345cSEnji Cooper } while(0) 49808ca345cSEnji Cooper 49908ca345cSEnji Cooper ATF_TC_WITHOUT_HEAD(pf_unspec); 50008ca345cSEnji Cooper ATF_TC_BODY(pf_unspec, tc) 50108ca345cSEnji Cooper { 50208ca345cSEnji Cooper 50308ca345cSEnji Cooper RUN_TESTS(tc, NULL, AF_UNSPEC); 50408ca345cSEnji Cooper } 50508ca345cSEnji Cooper 50608ca345cSEnji Cooper ATF_TC_WITHOUT_HEAD(pf_unspec_with_snapshot); 50708ca345cSEnji Cooper ATF_TC_BODY(pf_unspec_with_snapshot, tc) 50808ca345cSEnji Cooper { 50908ca345cSEnji Cooper 51008ca345cSEnji Cooper RUN_TESTS(tc, "snapshot_ai", AF_UNSPEC); 51108ca345cSEnji Cooper } 51208ca345cSEnji Cooper 51308ca345cSEnji Cooper ATF_TC_WITHOUT_HEAD(pf_inet); 51408ca345cSEnji Cooper ATF_TC_BODY(pf_inet, tc) 51508ca345cSEnji Cooper { 51608ca345cSEnji Cooper 51708ca345cSEnji Cooper ATF_REQUIRE_FEATURE("inet"); 51808ca345cSEnji Cooper RUN_TESTS(tc, NULL, AF_INET); 51908ca345cSEnji Cooper } 52008ca345cSEnji Cooper 52108ca345cSEnji Cooper ATF_TC_WITHOUT_HEAD(pf_inet_with_snapshot); 52208ca345cSEnji Cooper ATF_TC_BODY(pf_inet_with_snapshot, tc) 52308ca345cSEnji Cooper { 52408ca345cSEnji Cooper 52508ca345cSEnji Cooper ATF_REQUIRE_FEATURE("inet"); 52608ca345cSEnji Cooper RUN_TESTS(tc, "snapshot_ai4", AF_INET); 52708ca345cSEnji Cooper } 52808ca345cSEnji Cooper 52908ca345cSEnji Cooper ATF_TC_WITHOUT_HEAD(pf_inet6); 53008ca345cSEnji Cooper ATF_TC_BODY(pf_inet6, tc) 53108ca345cSEnji Cooper { 53208ca345cSEnji Cooper 53308ca345cSEnji Cooper ATF_REQUIRE_FEATURE("inet6"); 53408ca345cSEnji Cooper RUN_TESTS(tc, NULL, AF_INET6); 53508ca345cSEnji Cooper } 53608ca345cSEnji Cooper 53708ca345cSEnji Cooper ATF_TC_WITHOUT_HEAD(pf_inet6_with_snapshot); 53808ca345cSEnji Cooper ATF_TC_BODY(pf_inet6_with_snapshot, tc) 53908ca345cSEnji Cooper { 54008ca345cSEnji Cooper 54108ca345cSEnji Cooper ATF_REQUIRE_FEATURE("inet6"); 54208ca345cSEnji Cooper RUN_TESTS(tc, "snapshot_ai6", AF_INET6); 54308ca345cSEnji Cooper } 54408ca345cSEnji Cooper 54508ca345cSEnji Cooper ATF_TP_ADD_TCS(tp) 54608ca345cSEnji Cooper { 54708ca345cSEnji Cooper 54808ca345cSEnji Cooper ATF_TP_ADD_TC(tp, pf_unspec); 54908ca345cSEnji Cooper ATF_TP_ADD_TC(tp, pf_unspec_with_snapshot); 55008ca345cSEnji Cooper ATF_TP_ADD_TC(tp, pf_inet); 55108ca345cSEnji Cooper ATF_TP_ADD_TC(tp, pf_inet_with_snapshot); 55208ca345cSEnji Cooper ATF_TP_ADD_TC(tp, pf_inet6); 55308ca345cSEnji Cooper ATF_TP_ADD_TC(tp, pf_inet6_with_snapshot); 55408ca345cSEnji Cooper 55508ca345cSEnji Cooper return (atf_no_error()); 55608ca345cSEnji Cooper } 557