1*08ca345cSEnji Cooper /*- 2*08ca345cSEnji Cooper * Copyright (c) 2006 Michael Bushkov <bushman@freebsd.org> 3*08ca345cSEnji Cooper * All rights reserved. 4*08ca345cSEnji Cooper * 5*08ca345cSEnji Cooper * Redistribution and use in source and binary forms, with or without 6*08ca345cSEnji Cooper * modification, are permitted provided that the following conditions 7*08ca345cSEnji Cooper * are met: 8*08ca345cSEnji Cooper * 1. Redistributions of source code must retain the above copyright 9*08ca345cSEnji Cooper * notice, this list of conditions and the following disclaimer. 10*08ca345cSEnji Cooper * 2. Redistributions in binary form must reproduce the above copyright 11*08ca345cSEnji Cooper * notice, this list of conditions and the following disclaimer in the 12*08ca345cSEnji Cooper * documentation and/or other materials provided with the distribution. 13*08ca345cSEnji Cooper * 14*08ca345cSEnji Cooper * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15*08ca345cSEnji Cooper * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16*08ca345cSEnji Cooper * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17*08ca345cSEnji Cooper * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18*08ca345cSEnji Cooper * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19*08ca345cSEnji Cooper * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20*08ca345cSEnji Cooper * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21*08ca345cSEnji Cooper * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22*08ca345cSEnji Cooper * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23*08ca345cSEnji Cooper * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24*08ca345cSEnji Cooper * SUCH DAMAGE. 25*08ca345cSEnji Cooper * 26*08ca345cSEnji Cooper */ 27*08ca345cSEnji Cooper 28*08ca345cSEnji Cooper #include <sys/cdefs.h> 29*08ca345cSEnji Cooper __FBSDID("$FreeBSD$"); 30*08ca345cSEnji Cooper 31*08ca345cSEnji Cooper #include <sys/types.h> 32*08ca345cSEnji Cooper #include <sys/socket.h> 33*08ca345cSEnji Cooper #include <arpa/inet.h> 34*08ca345cSEnji Cooper #include <netinet/in.h> 35*08ca345cSEnji Cooper #include <errno.h> 36*08ca345cSEnji Cooper #include <netdb.h> 37*08ca345cSEnji Cooper #include <resolv.h> 38*08ca345cSEnji Cooper #include <stdio.h> 39*08ca345cSEnji Cooper #include <stdlib.h> 40*08ca345cSEnji Cooper #include <string.h> 41*08ca345cSEnji Cooper #include <stringlist.h> 42*08ca345cSEnji Cooper #include <unistd.h> 43*08ca345cSEnji Cooper 44*08ca345cSEnji Cooper #include <atf-c.h> 45*08ca345cSEnji Cooper 46*08ca345cSEnji Cooper #include "freebsd_test_suite/macros.h" 47*08ca345cSEnji Cooper #include "testutil.h" 48*08ca345cSEnji Cooper 49*08ca345cSEnji Cooper enum test_methods { 50*08ca345cSEnji Cooper TEST_GETADDRINFO, 51*08ca345cSEnji Cooper TEST_BUILD_SNAPSHOT 52*08ca345cSEnji Cooper }; 53*08ca345cSEnji Cooper 54*08ca345cSEnji Cooper static struct addrinfo hints; 55*08ca345cSEnji Cooper static enum test_methods method = TEST_GETADDRINFO; 56*08ca345cSEnji Cooper 57*08ca345cSEnji Cooper DECLARE_TEST_DATA(addrinfo) 58*08ca345cSEnji Cooper DECLARE_TEST_FILE_SNAPSHOT(addrinfo) 59*08ca345cSEnji Cooper DECLARE_2PASS_TEST(addrinfo) 60*08ca345cSEnji Cooper 61*08ca345cSEnji Cooper static void clone_addrinfo(struct addrinfo *, struct addrinfo const *); 62*08ca345cSEnji Cooper static int compare_addrinfo(struct addrinfo *, struct addrinfo *, void *); 63*08ca345cSEnji Cooper static void dump_addrinfo(struct addrinfo *); 64*08ca345cSEnji Cooper 65*08ca345cSEnji Cooper static void sdump_addrinfo(struct addrinfo *, char *, size_t); 66*08ca345cSEnji Cooper 67*08ca345cSEnji Cooper IMPLEMENT_TEST_DATA(addrinfo) 68*08ca345cSEnji Cooper IMPLEMENT_TEST_FILE_SNAPSHOT(addrinfo) 69*08ca345cSEnji Cooper IMPLEMENT_2PASS_TEST(addrinfo) 70*08ca345cSEnji Cooper 71*08ca345cSEnji Cooper static void 72*08ca345cSEnji Cooper clone_addrinfo(struct addrinfo *dest, struct addrinfo const *src) 73*08ca345cSEnji Cooper { 74*08ca345cSEnji Cooper 75*08ca345cSEnji Cooper ATF_REQUIRE(dest != NULL); 76*08ca345cSEnji Cooper ATF_REQUIRE(src != NULL); 77*08ca345cSEnji Cooper 78*08ca345cSEnji Cooper memcpy(dest, src, sizeof(struct addrinfo)); 79*08ca345cSEnji Cooper if (src->ai_canonname != NULL) 80*08ca345cSEnji Cooper dest->ai_canonname = strdup(src->ai_canonname); 81*08ca345cSEnji Cooper 82*08ca345cSEnji Cooper if (src->ai_addr != NULL) { 83*08ca345cSEnji Cooper dest->ai_addr = malloc(src->ai_addrlen); 84*08ca345cSEnji Cooper ATF_REQUIRE(dest->ai_addr != NULL); 85*08ca345cSEnji Cooper memcpy(dest->ai_addr, src->ai_addr, src->ai_addrlen); 86*08ca345cSEnji Cooper } 87*08ca345cSEnji Cooper 88*08ca345cSEnji Cooper if (src->ai_next != NULL) { 89*08ca345cSEnji Cooper dest->ai_next = malloc(sizeof(struct addrinfo)); 90*08ca345cSEnji Cooper ATF_REQUIRE(dest->ai_next != NULL); 91*08ca345cSEnji Cooper clone_addrinfo(dest->ai_next, src->ai_next); 92*08ca345cSEnji Cooper } 93*08ca345cSEnji Cooper } 94*08ca345cSEnji Cooper 95*08ca345cSEnji Cooper static int 96*08ca345cSEnji Cooper compare_addrinfo_(struct addrinfo *ai1, struct addrinfo *ai2) 97*08ca345cSEnji Cooper { 98*08ca345cSEnji Cooper 99*08ca345cSEnji Cooper if ((ai1 == NULL) || (ai2 == NULL)) 100*08ca345cSEnji Cooper return (-1); 101*08ca345cSEnji Cooper 102*08ca345cSEnji Cooper if (ai1->ai_flags != ai2->ai_flags || 103*08ca345cSEnji Cooper ai1->ai_family != ai2->ai_family || 104*08ca345cSEnji Cooper ai1->ai_socktype != ai2->ai_socktype || 105*08ca345cSEnji Cooper ai1->ai_protocol != ai2->ai_protocol || 106*08ca345cSEnji Cooper ai1->ai_addrlen != ai2->ai_addrlen || 107*08ca345cSEnji Cooper ((ai1->ai_addr == NULL || ai2->ai_addr == NULL) && 108*08ca345cSEnji Cooper ai1->ai_addr != ai2->ai_addr) || 109*08ca345cSEnji Cooper ((ai1->ai_canonname == NULL || ai2->ai_canonname == NULL) && 110*08ca345cSEnji Cooper ai1->ai_canonname != ai2->ai_canonname)) 111*08ca345cSEnji Cooper return (-1); 112*08ca345cSEnji Cooper 113*08ca345cSEnji Cooper if (ai1->ai_canonname != NULL && 114*08ca345cSEnji Cooper strcmp(ai1->ai_canonname, ai2->ai_canonname) != 0) 115*08ca345cSEnji Cooper return (-1); 116*08ca345cSEnji Cooper 117*08ca345cSEnji Cooper if (ai1->ai_addr != NULL && 118*08ca345cSEnji Cooper memcmp(ai1->ai_addr, ai2->ai_addr, ai1->ai_addrlen) != 0) 119*08ca345cSEnji Cooper return (-1); 120*08ca345cSEnji Cooper 121*08ca345cSEnji Cooper if (ai1->ai_next == NULL && ai2->ai_next == NULL) 122*08ca345cSEnji Cooper return (0); 123*08ca345cSEnji Cooper else 124*08ca345cSEnji Cooper return (compare_addrinfo_(ai1->ai_next, ai2->ai_next)); 125*08ca345cSEnji Cooper } 126*08ca345cSEnji Cooper 127*08ca345cSEnji Cooper static int 128*08ca345cSEnji Cooper compare_addrinfo(struct addrinfo *ai1, struct addrinfo *ai2, void *mdata) 129*08ca345cSEnji Cooper { 130*08ca345cSEnji Cooper int rv; 131*08ca345cSEnji Cooper 132*08ca345cSEnji Cooper printf("testing equality of 2 addrinfo structures\n"); 133*08ca345cSEnji Cooper 134*08ca345cSEnji Cooper rv = compare_addrinfo_(ai1, ai2); 135*08ca345cSEnji Cooper 136*08ca345cSEnji Cooper if (rv == 0) 137*08ca345cSEnji Cooper printf("equal\n"); 138*08ca345cSEnji Cooper else { 139*08ca345cSEnji Cooper dump_addrinfo(ai1); 140*08ca345cSEnji Cooper dump_addrinfo(ai2); 141*08ca345cSEnji Cooper printf("not equal\n"); 142*08ca345cSEnji Cooper } 143*08ca345cSEnji Cooper 144*08ca345cSEnji Cooper return (rv); 145*08ca345cSEnji Cooper } 146*08ca345cSEnji Cooper 147*08ca345cSEnji Cooper void 148*08ca345cSEnji Cooper free_addrinfo(struct addrinfo *ai) 149*08ca345cSEnji Cooper { 150*08ca345cSEnji Cooper if (ai == NULL) 151*08ca345cSEnji Cooper return; 152*08ca345cSEnji Cooper 153*08ca345cSEnji Cooper free(ai->ai_addr); 154*08ca345cSEnji Cooper free(ai->ai_canonname); 155*08ca345cSEnji Cooper free_addrinfo(ai->ai_next); 156*08ca345cSEnji Cooper } 157*08ca345cSEnji Cooper 158*08ca345cSEnji Cooper void 159*08ca345cSEnji Cooper sdump_addrinfo(struct addrinfo *ai, char *buffer, size_t buflen) 160*08ca345cSEnji Cooper { 161*08ca345cSEnji Cooper int written, i; 162*08ca345cSEnji Cooper 163*08ca345cSEnji Cooper written = snprintf(buffer, buflen, "%d %d %d %d %d ", 164*08ca345cSEnji Cooper ai->ai_flags, ai->ai_family, ai->ai_socktype, ai->ai_protocol, 165*08ca345cSEnji Cooper ai->ai_addrlen); 166*08ca345cSEnji Cooper buffer += written; 167*08ca345cSEnji Cooper if (written > buflen) 168*08ca345cSEnji Cooper return; 169*08ca345cSEnji Cooper buflen -= written; 170*08ca345cSEnji Cooper 171*08ca345cSEnji Cooper written = snprintf(buffer, buflen, "%s ", 172*08ca345cSEnji Cooper ai->ai_canonname == NULL ? "(null)" : ai->ai_canonname); 173*08ca345cSEnji Cooper buffer += written; 174*08ca345cSEnji Cooper if (written > buflen) 175*08ca345cSEnji Cooper return; 176*08ca345cSEnji Cooper buflen -= written; 177*08ca345cSEnji Cooper 178*08ca345cSEnji Cooper if (ai->ai_addr == NULL) { 179*08ca345cSEnji Cooper written = snprintf(buffer, buflen, "(null)"); 180*08ca345cSEnji Cooper buffer += written; 181*08ca345cSEnji Cooper if (written > buflen) 182*08ca345cSEnji Cooper return; 183*08ca345cSEnji Cooper buflen -= written; 184*08ca345cSEnji Cooper } else { 185*08ca345cSEnji Cooper for (i = 0; i < ai->ai_addrlen; i++) { 186*08ca345cSEnji Cooper written = snprintf(buffer, buflen, 187*08ca345cSEnji Cooper i + 1 != ai->ai_addrlen ? "%d." : "%d", 188*08ca345cSEnji Cooper ((unsigned char *)ai->ai_addr)[i]); 189*08ca345cSEnji Cooper buffer += written; 190*08ca345cSEnji Cooper if (written > buflen) 191*08ca345cSEnji Cooper return; 192*08ca345cSEnji Cooper buflen -= written; 193*08ca345cSEnji Cooper 194*08ca345cSEnji Cooper if (buflen == 0) 195*08ca345cSEnji Cooper return; 196*08ca345cSEnji Cooper } 197*08ca345cSEnji Cooper } 198*08ca345cSEnji Cooper 199*08ca345cSEnji Cooper if (ai->ai_next != NULL) { 200*08ca345cSEnji Cooper written = snprintf(buffer, buflen, ":"); 201*08ca345cSEnji Cooper buffer += written; 202*08ca345cSEnji Cooper if (written > buflen) 203*08ca345cSEnji Cooper return; 204*08ca345cSEnji Cooper buflen -= written; 205*08ca345cSEnji Cooper 206*08ca345cSEnji Cooper sdump_addrinfo(ai->ai_next, buffer, buflen); 207*08ca345cSEnji Cooper } 208*08ca345cSEnji Cooper } 209*08ca345cSEnji Cooper 210*08ca345cSEnji Cooper void 211*08ca345cSEnji Cooper dump_addrinfo(struct addrinfo *result) 212*08ca345cSEnji Cooper { 213*08ca345cSEnji Cooper if (result != NULL) { 214*08ca345cSEnji Cooper char buffer[2048]; 215*08ca345cSEnji Cooper sdump_addrinfo(result, buffer, sizeof(buffer)); 216*08ca345cSEnji Cooper printf("%s\n", buffer); 217*08ca345cSEnji Cooper } else 218*08ca345cSEnji Cooper printf("(null)\n"); 219*08ca345cSEnji Cooper } 220*08ca345cSEnji Cooper 221*08ca345cSEnji Cooper static int 222*08ca345cSEnji Cooper addrinfo_read_snapshot_addr(char *addr, unsigned char *result, size_t len) 223*08ca345cSEnji Cooper { 224*08ca345cSEnji Cooper char *s, *ps, *ts; 225*08ca345cSEnji Cooper 226*08ca345cSEnji Cooper ps = addr; 227*08ca345cSEnji Cooper while ((s = strsep(&ps, ".")) != NULL) { 228*08ca345cSEnji Cooper if (len == 0) 229*08ca345cSEnji Cooper return (-1); 230*08ca345cSEnji Cooper 231*08ca345cSEnji Cooper *result = (unsigned char)strtol(s, &ts, 10); 232*08ca345cSEnji Cooper ++result; 233*08ca345cSEnji Cooper if (*ts != '\0') 234*08ca345cSEnji Cooper return (-1); 235*08ca345cSEnji Cooper 236*08ca345cSEnji Cooper --len; 237*08ca345cSEnji Cooper } 238*08ca345cSEnji Cooper if (len != 0) 239*08ca345cSEnji Cooper return (-1); 240*08ca345cSEnji Cooper else 241*08ca345cSEnji Cooper return (0); 242*08ca345cSEnji Cooper } 243*08ca345cSEnji Cooper 244*08ca345cSEnji Cooper static int 245*08ca345cSEnji Cooper addrinfo_read_snapshot_ai(struct addrinfo *ai, char *line) 246*08ca345cSEnji Cooper { 247*08ca345cSEnji Cooper char *s, *ps, *ts; 248*08ca345cSEnji Cooper int i, rv, *pi; 249*08ca345cSEnji Cooper 250*08ca345cSEnji Cooper rv = 0; 251*08ca345cSEnji Cooper i = 0; 252*08ca345cSEnji Cooper ps = line; 253*08ca345cSEnji Cooper memset(ai, 0, sizeof(struct addrinfo)); 254*08ca345cSEnji Cooper while ((s = strsep(&ps, " ")) != NULL) { 255*08ca345cSEnji Cooper switch (i) { 256*08ca345cSEnji Cooper case 0: 257*08ca345cSEnji Cooper case 1: 258*08ca345cSEnji Cooper case 2: 259*08ca345cSEnji Cooper case 3: 260*08ca345cSEnji Cooper pi = &ai->ai_flags + i; 261*08ca345cSEnji Cooper *pi = (int)strtol(s, &ts, 10); 262*08ca345cSEnji Cooper if (*ts != '\0') 263*08ca345cSEnji Cooper goto fin; 264*08ca345cSEnji Cooper break; 265*08ca345cSEnji Cooper case 4: 266*08ca345cSEnji Cooper ai->ai_addrlen = (socklen_t)strtol(s, &ts, 10); 267*08ca345cSEnji Cooper if (*ts != '\0') 268*08ca345cSEnji Cooper goto fin; 269*08ca345cSEnji Cooper break; 270*08ca345cSEnji Cooper case 5: 271*08ca345cSEnji Cooper if (strcmp(s, "(null)") != 0) { 272*08ca345cSEnji Cooper ai->ai_canonname = strdup(s); 273*08ca345cSEnji Cooper ATF_REQUIRE(ai->ai_canonname != NULL); 274*08ca345cSEnji Cooper } 275*08ca345cSEnji Cooper break; 276*08ca345cSEnji Cooper case 6: 277*08ca345cSEnji Cooper if (strcmp(s, "(null)") != 0) { 278*08ca345cSEnji Cooper ai->ai_addr = calloc(1, ai->ai_addrlen); 279*08ca345cSEnji Cooper ATF_REQUIRE(ai->ai_addr != NULL); 280*08ca345cSEnji Cooper rv = addrinfo_read_snapshot_addr(s, 281*08ca345cSEnji Cooper (unsigned char *)ai->ai_addr, 282*08ca345cSEnji Cooper ai->ai_addrlen); 283*08ca345cSEnji Cooper 284*08ca345cSEnji Cooper if (rv != 0) 285*08ca345cSEnji Cooper goto fin; 286*08ca345cSEnji Cooper } 287*08ca345cSEnji Cooper break; 288*08ca345cSEnji Cooper default: 289*08ca345cSEnji Cooper /* NOTE: should not be reachable */ 290*08ca345cSEnji Cooper rv = -1; 291*08ca345cSEnji Cooper goto fin; 292*08ca345cSEnji Cooper } 293*08ca345cSEnji Cooper 294*08ca345cSEnji Cooper ++i; 295*08ca345cSEnji Cooper } 296*08ca345cSEnji Cooper 297*08ca345cSEnji Cooper fin: 298*08ca345cSEnji Cooper if (i != 7 || rv != 0) { 299*08ca345cSEnji Cooper free_addrinfo(ai); 300*08ca345cSEnji Cooper ai = NULL; 301*08ca345cSEnji Cooper return (-1); 302*08ca345cSEnji Cooper } 303*08ca345cSEnji Cooper 304*08ca345cSEnji Cooper return (0); 305*08ca345cSEnji Cooper } 306*08ca345cSEnji Cooper 307*08ca345cSEnji Cooper static int 308*08ca345cSEnji Cooper addrinfo_read_snapshot_func(struct addrinfo *ai, char *line) 309*08ca345cSEnji Cooper { 310*08ca345cSEnji Cooper struct addrinfo *ai2; 311*08ca345cSEnji Cooper char *s, *ps; 312*08ca345cSEnji Cooper int i, rv; 313*08ca345cSEnji Cooper 314*08ca345cSEnji Cooper printf("1 line read from snapshot:\n%s\n", line); 315*08ca345cSEnji Cooper 316*08ca345cSEnji Cooper rv = 0; 317*08ca345cSEnji Cooper i = 0; 318*08ca345cSEnji Cooper ps = line; 319*08ca345cSEnji Cooper 320*08ca345cSEnji Cooper s = strsep(&ps, ":"); 321*08ca345cSEnji Cooper if (s == NULL) 322*08ca345cSEnji Cooper return (-1); 323*08ca345cSEnji Cooper 324*08ca345cSEnji Cooper rv = addrinfo_read_snapshot_ai(ai, s); 325*08ca345cSEnji Cooper if (rv != 0) 326*08ca345cSEnji Cooper return (-1); 327*08ca345cSEnji Cooper 328*08ca345cSEnji Cooper ai2 = ai; 329*08ca345cSEnji Cooper while ((s = strsep(&ps, ":")) != NULL) { 330*08ca345cSEnji Cooper ai2->ai_next = calloc(1, sizeof(struct addrinfo)); 331*08ca345cSEnji Cooper ATF_REQUIRE(ai2->ai_next != NULL); 332*08ca345cSEnji Cooper 333*08ca345cSEnji Cooper rv = addrinfo_read_snapshot_ai(ai2->ai_next, s); 334*08ca345cSEnji Cooper if (rv != 0) { 335*08ca345cSEnji Cooper free_addrinfo(ai); 336*08ca345cSEnji Cooper ai = NULL; 337*08ca345cSEnji Cooper return (-1); 338*08ca345cSEnji Cooper } 339*08ca345cSEnji Cooper 340*08ca345cSEnji Cooper ai2 = ai2->ai_next; 341*08ca345cSEnji Cooper } 342*08ca345cSEnji Cooper 343*08ca345cSEnji Cooper return (0); 344*08ca345cSEnji Cooper } 345*08ca345cSEnji Cooper 346*08ca345cSEnji Cooper static int 347*08ca345cSEnji Cooper addrinfo_test_correctness(struct addrinfo *ai, void *mdata) 348*08ca345cSEnji Cooper { 349*08ca345cSEnji Cooper 350*08ca345cSEnji Cooper printf("testing correctness with the following data:\n"); 351*08ca345cSEnji Cooper dump_addrinfo(ai); 352*08ca345cSEnji Cooper 353*08ca345cSEnji Cooper if (ai == NULL) 354*08ca345cSEnji Cooper goto errfin; 355*08ca345cSEnji Cooper 356*08ca345cSEnji Cooper if (!(ai->ai_family >= 0 && ai->ai_family < AF_MAX)) 357*08ca345cSEnji Cooper goto errfin; 358*08ca345cSEnji Cooper 359*08ca345cSEnji Cooper if (ai->ai_socktype != 0 && ai->ai_socktype != SOCK_STREAM && 360*08ca345cSEnji Cooper ai->ai_socktype != SOCK_DGRAM && ai->ai_socktype != SOCK_RAW) 361*08ca345cSEnji Cooper goto errfin; 362*08ca345cSEnji Cooper 363*08ca345cSEnji Cooper if (ai->ai_protocol != 0 && ai->ai_protocol != IPPROTO_UDP && 364*08ca345cSEnji Cooper ai->ai_protocol != IPPROTO_TCP) 365*08ca345cSEnji Cooper goto errfin; 366*08ca345cSEnji Cooper 367*08ca345cSEnji Cooper if ((ai->ai_flags & ~(AI_CANONNAME | AI_NUMERICHOST | AI_PASSIVE)) != 0) 368*08ca345cSEnji Cooper goto errfin; 369*08ca345cSEnji Cooper 370*08ca345cSEnji Cooper if (ai->ai_addrlen != ai->ai_addr->sa_len || 371*08ca345cSEnji Cooper ai->ai_family != ai->ai_addr->sa_family) 372*08ca345cSEnji Cooper goto errfin; 373*08ca345cSEnji Cooper 374*08ca345cSEnji Cooper printf("correct\n"); 375*08ca345cSEnji Cooper 376*08ca345cSEnji Cooper return (0); 377*08ca345cSEnji Cooper errfin: 378*08ca345cSEnji Cooper printf("incorrect\n"); 379*08ca345cSEnji Cooper 380*08ca345cSEnji Cooper return (-1); 381*08ca345cSEnji Cooper } 382*08ca345cSEnji Cooper 383*08ca345cSEnji Cooper static int 384*08ca345cSEnji Cooper addrinfo_read_hostlist_func(struct addrinfo *ai, char *line) 385*08ca345cSEnji Cooper { 386*08ca345cSEnji Cooper struct addrinfo *result; 387*08ca345cSEnji Cooper int rv; 388*08ca345cSEnji Cooper 389*08ca345cSEnji Cooper printf("resolving %s: ", line); 390*08ca345cSEnji Cooper rv = getaddrinfo(line, NULL, &hints, &result); 391*08ca345cSEnji Cooper if (rv == 0) { 392*08ca345cSEnji Cooper printf("found\n"); 393*08ca345cSEnji Cooper 394*08ca345cSEnji Cooper rv = addrinfo_test_correctness(result, NULL); 395*08ca345cSEnji Cooper if (rv != 0) { 396*08ca345cSEnji Cooper freeaddrinfo(result); 397*08ca345cSEnji Cooper result = NULL; 398*08ca345cSEnji Cooper return (rv); 399*08ca345cSEnji Cooper } 400*08ca345cSEnji Cooper 401*08ca345cSEnji Cooper clone_addrinfo(ai, result); 402*08ca345cSEnji Cooper freeaddrinfo(result); 403*08ca345cSEnji Cooper result = NULL; 404*08ca345cSEnji Cooper } else { 405*08ca345cSEnji Cooper printf("not found\n"); 406*08ca345cSEnji Cooper 407*08ca345cSEnji Cooper memset(ai, 0, sizeof(struct addrinfo)); 408*08ca345cSEnji Cooper } 409*08ca345cSEnji Cooper return (0); 410*08ca345cSEnji Cooper } 411*08ca345cSEnji Cooper 412*08ca345cSEnji Cooper void 413*08ca345cSEnji Cooper run_tests(char *hostlist_file, char *snapshot_file, int ai_family) 414*08ca345cSEnji Cooper { 415*08ca345cSEnji Cooper struct addrinfo_test_data td, td_snap; 416*08ca345cSEnji Cooper int rv; 417*08ca345cSEnji Cooper 418*08ca345cSEnji Cooper memset(&hints, 0, sizeof(struct addrinfo)); 419*08ca345cSEnji Cooper hints.ai_family = ai_family; 420*08ca345cSEnji Cooper hints.ai_flags = AI_CANONNAME; 421*08ca345cSEnji Cooper 422*08ca345cSEnji Cooper if (snapshot_file != NULL) 423*08ca345cSEnji Cooper method = TEST_BUILD_SNAPSHOT; 424*08ca345cSEnji Cooper 425*08ca345cSEnji Cooper TEST_DATA_INIT(addrinfo, &td, clone_addrinfo, free_addrinfo); 426*08ca345cSEnji Cooper TEST_DATA_INIT(addrinfo, &td_snap, clone_addrinfo, free_addrinfo); 427*08ca345cSEnji Cooper 428*08ca345cSEnji Cooper ATF_REQUIRE_MSG(access(hostlist_file, R_OK) == 0, 429*08ca345cSEnji Cooper "can't access the hostlist file %s\n", hostlist_file); 430*08ca345cSEnji Cooper 431*08ca345cSEnji Cooper printf("building host lists from %s\n", hostlist_file); 432*08ca345cSEnji Cooper 433*08ca345cSEnji Cooper rv = TEST_SNAPSHOT_FILE_READ(addrinfo, hostlist_file, &td, 434*08ca345cSEnji Cooper addrinfo_read_hostlist_func); 435*08ca345cSEnji Cooper if (rv != 0) 436*08ca345cSEnji Cooper goto fin; 437*08ca345cSEnji Cooper 438*08ca345cSEnji Cooper if (snapshot_file != NULL) { 439*08ca345cSEnji Cooper if (access(snapshot_file, W_OK | R_OK) != 0) { 440*08ca345cSEnji Cooper if (errno == ENOENT) 441*08ca345cSEnji Cooper method = TEST_BUILD_SNAPSHOT; 442*08ca345cSEnji Cooper else { 443*08ca345cSEnji Cooper printf("can't access the snapshot " 444*08ca345cSEnji Cooper "file %s\n", snapshot_file); 445*08ca345cSEnji Cooper 446*08ca345cSEnji Cooper rv = -1; 447*08ca345cSEnji Cooper goto fin; 448*08ca345cSEnji Cooper } 449*08ca345cSEnji Cooper } else { 450*08ca345cSEnji Cooper rv = TEST_SNAPSHOT_FILE_READ(addrinfo, snapshot_file, 451*08ca345cSEnji Cooper &td_snap, addrinfo_read_snapshot_func); 452*08ca345cSEnji Cooper if (rv != 0) { 453*08ca345cSEnji Cooper printf("error reading snapshot file: %s\n", 454*08ca345cSEnji Cooper strerror(errno)); 455*08ca345cSEnji Cooper goto fin; 456*08ca345cSEnji Cooper } 457*08ca345cSEnji Cooper } 458*08ca345cSEnji Cooper } 459*08ca345cSEnji Cooper 460*08ca345cSEnji Cooper switch (method) { 461*08ca345cSEnji Cooper case TEST_GETADDRINFO: 462*08ca345cSEnji Cooper if (snapshot_file != NULL) 463*08ca345cSEnji Cooper ATF_CHECK(DO_2PASS_TEST(addrinfo, &td, &td_snap, 464*08ca345cSEnji Cooper compare_addrinfo, NULL) == 0); 465*08ca345cSEnji Cooper break; 466*08ca345cSEnji Cooper case TEST_BUILD_SNAPSHOT: 467*08ca345cSEnji Cooper if (snapshot_file != NULL) { 468*08ca345cSEnji Cooper ATF_CHECK(TEST_SNAPSHOT_FILE_WRITE(addrinfo, 469*08ca345cSEnji Cooper snapshot_file, &td, sdump_addrinfo) == 0); 470*08ca345cSEnji Cooper } 471*08ca345cSEnji Cooper break; 472*08ca345cSEnji Cooper default: 473*08ca345cSEnji Cooper break; 474*08ca345cSEnji Cooper } 475*08ca345cSEnji Cooper 476*08ca345cSEnji Cooper fin: 477*08ca345cSEnji Cooper TEST_DATA_DESTROY(addrinfo, &td_snap); 478*08ca345cSEnji Cooper TEST_DATA_DESTROY(addrinfo, &td); 479*08ca345cSEnji Cooper 480*08ca345cSEnji Cooper free(hostlist_file); 481*08ca345cSEnji Cooper free(snapshot_file); 482*08ca345cSEnji Cooper } 483*08ca345cSEnji Cooper 484*08ca345cSEnji Cooper #define HOSTLIST_FILE "mach" 485*08ca345cSEnji Cooper #define RUN_TESTS(tc, snapshot_file, ai_family) do { \ 486*08ca345cSEnji Cooper char *_hostlist_file; \ 487*08ca345cSEnji Cooper char *_snapshot_file; \ 488*08ca345cSEnji Cooper ATF_REQUIRE(0 < asprintf(&_hostlist_file, "%s/%s", \ 489*08ca345cSEnji Cooper atf_tc_get_config_var(tc, "srcdir"), HOSTLIST_FILE)); \ 490*08ca345cSEnji Cooper if (snapshot_file == NULL) \ 491*08ca345cSEnji Cooper _snapshot_file = NULL; \ 492*08ca345cSEnji Cooper else { \ 493*08ca345cSEnji Cooper _snapshot_file = strdup(snapshot_file); \ 494*08ca345cSEnji Cooper ATF_REQUIRE(_snapshot_file != NULL); \ 495*08ca345cSEnji Cooper } \ 496*08ca345cSEnji Cooper run_tests(_hostlist_file, _snapshot_file, ai_family); \ 497*08ca345cSEnji Cooper } while(0) 498*08ca345cSEnji Cooper 499*08ca345cSEnji Cooper ATF_TC_WITHOUT_HEAD(pf_unspec); 500*08ca345cSEnji Cooper ATF_TC_BODY(pf_unspec, tc) 501*08ca345cSEnji Cooper { 502*08ca345cSEnji Cooper 503*08ca345cSEnji Cooper RUN_TESTS(tc, NULL, AF_UNSPEC); 504*08ca345cSEnji Cooper } 505*08ca345cSEnji Cooper 506*08ca345cSEnji Cooper ATF_TC_WITHOUT_HEAD(pf_unspec_with_snapshot); 507*08ca345cSEnji Cooper ATF_TC_BODY(pf_unspec_with_snapshot, tc) 508*08ca345cSEnji Cooper { 509*08ca345cSEnji Cooper 510*08ca345cSEnji Cooper RUN_TESTS(tc, "snapshot_ai", AF_UNSPEC); 511*08ca345cSEnji Cooper } 512*08ca345cSEnji Cooper 513*08ca345cSEnji Cooper ATF_TC_WITHOUT_HEAD(pf_inet); 514*08ca345cSEnji Cooper ATF_TC_BODY(pf_inet, tc) 515*08ca345cSEnji Cooper { 516*08ca345cSEnji Cooper 517*08ca345cSEnji Cooper ATF_REQUIRE_FEATURE("inet"); 518*08ca345cSEnji Cooper RUN_TESTS(tc, NULL, AF_INET); 519*08ca345cSEnji Cooper } 520*08ca345cSEnji Cooper 521*08ca345cSEnji Cooper ATF_TC_WITHOUT_HEAD(pf_inet_with_snapshot); 522*08ca345cSEnji Cooper ATF_TC_BODY(pf_inet_with_snapshot, tc) 523*08ca345cSEnji Cooper { 524*08ca345cSEnji Cooper 525*08ca345cSEnji Cooper ATF_REQUIRE_FEATURE("inet"); 526*08ca345cSEnji Cooper RUN_TESTS(tc, "snapshot_ai4", AF_INET); 527*08ca345cSEnji Cooper } 528*08ca345cSEnji Cooper 529*08ca345cSEnji Cooper ATF_TC_WITHOUT_HEAD(pf_inet6); 530*08ca345cSEnji Cooper ATF_TC_BODY(pf_inet6, tc) 531*08ca345cSEnji Cooper { 532*08ca345cSEnji Cooper 533*08ca345cSEnji Cooper ATF_REQUIRE_FEATURE("inet6"); 534*08ca345cSEnji Cooper RUN_TESTS(tc, NULL, AF_INET6); 535*08ca345cSEnji Cooper } 536*08ca345cSEnji Cooper 537*08ca345cSEnji Cooper ATF_TC_WITHOUT_HEAD(pf_inet6_with_snapshot); 538*08ca345cSEnji Cooper ATF_TC_BODY(pf_inet6_with_snapshot, tc) 539*08ca345cSEnji Cooper { 540*08ca345cSEnji Cooper 541*08ca345cSEnji Cooper ATF_REQUIRE_FEATURE("inet6"); 542*08ca345cSEnji Cooper RUN_TESTS(tc, "snapshot_ai6", AF_INET6); 543*08ca345cSEnji Cooper } 544*08ca345cSEnji Cooper 545*08ca345cSEnji Cooper ATF_TP_ADD_TCS(tp) 546*08ca345cSEnji Cooper { 547*08ca345cSEnji Cooper 548*08ca345cSEnji Cooper ATF_TP_ADD_TC(tp, pf_unspec); 549*08ca345cSEnji Cooper ATF_TP_ADD_TC(tp, pf_unspec_with_snapshot); 550*08ca345cSEnji Cooper ATF_TP_ADD_TC(tp, pf_inet); 551*08ca345cSEnji Cooper ATF_TP_ADD_TC(tp, pf_inet_with_snapshot); 552*08ca345cSEnji Cooper ATF_TP_ADD_TC(tp, pf_inet6); 553*08ca345cSEnji Cooper ATF_TP_ADD_TC(tp, pf_inet6_with_snapshot); 554*08ca345cSEnji Cooper 555*08ca345cSEnji Cooper return (atf_no_error()); 556*08ca345cSEnji Cooper } 557