1168754Sbushman/*- 2168754Sbushman * Copyright (c) 2006 Michael Bushkov <bushman@freebsd.org> 3251867Seadler * All rights reserved. 4168754Sbushman * 5168754Sbushman * Redistribution and use in source and binary forms, with or without 6168754Sbushman * modification, are permitted provided that the following conditions 7168754Sbushman * are met: 8168754Sbushman * 1. Redistributions of source code must retain the above copyright 9168754Sbushman * notice, this list of conditions and the following disclaimer. 10168754Sbushman * 2. Redistributions in binary form must reproduce the above copyright 11168754Sbushman * notice, this list of conditions and the following disclaimer in the 12168754Sbushman * documentation and/or other materials provided with the distribution. 13168754Sbushman * 14168754Sbushman * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15168754Sbushman * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16168754Sbushman * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17168754Sbushman * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18168754Sbushman * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19168754Sbushman * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20168754Sbushman * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21168754Sbushman * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22168754Sbushman * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23168754Sbushman * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24168754Sbushman * SUCH DAMAGE. 25168754Sbushman * 26168754Sbushman */ 27168754Sbushman 28168754Sbushman#include <sys/cdefs.h> 29168754Sbushman__FBSDID("$FreeBSD$"); 30168754Sbushman 31168754Sbushman#include <arpa/inet.h> 32168754Sbushman#include <sys/socket.h> 33168754Sbushman#include <sys/types.h> 34168754Sbushman#include <netinet/in.h> 35168754Sbushman#include <assert.h> 36168754Sbushman#include <errno.h> 37168754Sbushman#include <netdb.h> 38168754Sbushman#include <resolv.h> 39168754Sbushman#include <stdio.h> 40168754Sbushman#include <stdlib.h> 41168754Sbushman#include <string.h> 42168754Sbushman#include <stringlist.h> 43168754Sbushman#include <unistd.h> 44168754Sbushman#include "testutil.h" 45168754Sbushman 46168754Sbushmanenum test_methods { 47168754Sbushman TEST_GETADDRINFO, 48168754Sbushman TEST_BUILD_SNAPSHOT 49168754Sbushman}; 50168754Sbushman 51168754Sbushmanstatic int debug = 0; 52168754Sbushmanstatic struct addrinfo hints; 53168754Sbushmanstatic enum test_methods method = TEST_GETADDRINFO; 54168754Sbushman 55168754SbushmanDECLARE_TEST_DATA(addrinfo) 56168754SbushmanDECLARE_TEST_FILE_SNAPSHOT(addrinfo) 57168754SbushmanDECLARE_2PASS_TEST(addrinfo) 58168754Sbushman 59168754Sbushmanstatic void clone_addrinfo(struct addrinfo *, struct addrinfo const *); 60168754Sbushmanstatic int compare_addrinfo(struct addrinfo *, struct addrinfo *, void *); 61168754Sbushmanstatic void dump_addrinfo(struct addrinfo *); 62168754Sbushmanstatic void free_addrinfo(struct addrinfo *); 63168754Sbushman 64168754Sbushmanstatic void sdump_addrinfo(struct addrinfo *, char *, size_t); 65168754Sbushman 66168754SbushmanIMPLEMENT_TEST_DATA(addrinfo) 67168754SbushmanIMPLEMENT_TEST_FILE_SNAPSHOT(addrinfo) 68168754SbushmanIMPLEMENT_2PASS_TEST(addrinfo) 69168754Sbushman 70168754Sbushmanstatic void 71168754Sbushmanclone_addrinfo(struct addrinfo *dest, struct addrinfo const *src) 72168754Sbushman{ 73168754Sbushman assert(dest != NULL); 74168754Sbushman assert(src != NULL); 75168754Sbushman 76168754Sbushman memcpy(dest, src, sizeof(struct addrinfo)); 77168754Sbushman if (src->ai_canonname != NULL) 78168754Sbushman dest->ai_canonname = strdup(src->ai_canonname); 79168754Sbushman 80168754Sbushman if (src->ai_addr != NULL) { 81168754Sbushman dest->ai_addr = (struct sockaddr *)malloc(src->ai_addrlen); 82168754Sbushman assert(dest->ai_addr != NULL); 83168754Sbushman memcpy(dest->ai_addr, src->ai_addr, src->ai_addrlen); 84168754Sbushman } 85168754Sbushman 86168754Sbushman if (src->ai_next != NULL) { 87168754Sbushman dest->ai_next = (struct addrinfo *)malloc( 88168754Sbushman sizeof(struct addrinfo)); 89168754Sbushman assert(dest->ai_next != NULL); 90168754Sbushman clone_addrinfo(dest->ai_next, src->ai_next); 91168754Sbushman } 92168754Sbushman} 93168754Sbushman 94168754Sbushmanstatic int 95168754Sbushmancompare_addrinfo_(struct addrinfo *ai1, struct addrinfo *ai2) 96168754Sbushman{ 97168754Sbushman if ((ai1 == NULL) || (ai2 == NULL)) 98168754Sbushman return (-1); 99168754Sbushman 100168754Sbushman if ((ai1->ai_flags != ai2->ai_flags) || 101168754Sbushman (ai1->ai_family != ai2->ai_family) || 102168754Sbushman (ai1->ai_socktype != ai2->ai_socktype) || 103168754Sbushman (ai1->ai_protocol != ai2->ai_protocol) || 104168754Sbushman (ai1->ai_addrlen != ai2->ai_addrlen) || 105168754Sbushman (((ai1->ai_addr == NULL) || (ai2->ai_addr == NULL)) && 106168754Sbushman (ai1->ai_addr != ai2->ai_addr)) || 107168754Sbushman (((ai1->ai_canonname == NULL) || (ai2->ai_canonname == NULL)) && 108168754Sbushman (ai1->ai_canonname != ai2->ai_canonname))) 109168754Sbushman return (-1); 110168754Sbushman 111168754Sbushman if ((ai1->ai_canonname != NULL) && 112168754Sbushman (strcmp(ai1->ai_canonname, ai2->ai_canonname) != 0)) 113168754Sbushman return (-1); 114168754Sbushman 115168754Sbushman if ((ai1->ai_addr != NULL) && 116168754Sbushman (memcmp(ai1->ai_addr, ai2->ai_addr, ai1->ai_addrlen) != 0)) 117168754Sbushman return (-1); 118168754Sbushman 119168754Sbushman if ((ai1->ai_next == NULL) && (ai2->ai_next == NULL)) 120168754Sbushman return (0); 121168754Sbushman else 122168754Sbushman return (compare_addrinfo_(ai1->ai_next, ai2->ai_next)); 123168754Sbushman} 124168754Sbushman 125168754Sbushmanstatic int 126168754Sbushmancompare_addrinfo(struct addrinfo *ai1, struct addrinfo *ai2, void *mdata) 127168754Sbushman{ 128168754Sbushman int rv; 129168754Sbushman 130168754Sbushman if (debug) { 131168754Sbushman printf("testing equality of 2 addrinfo structures\n"); 132168754Sbushman } 133168754Sbushman 134168754Sbushman rv = compare_addrinfo_(ai1, ai2); 135168754Sbushman 136168754Sbushman if (debug) { 137168754Sbushman if (rv == 0) 138168754Sbushman printf("equal\n"); 139168754Sbushman else { 140168754Sbushman dump_addrinfo(ai1); 141168754Sbushman dump_addrinfo(ai2); 142168754Sbushman printf("not equal\n"); 143168754Sbushman } 144168754Sbushman } 145168754Sbushman 146168754Sbushman return (rv); 147168754Sbushman} 148168754Sbushman 149168754Sbushmanvoid 150168754Sbushmanfree_addrinfo(struct addrinfo *ai) 151168754Sbushman{ 152168754Sbushman if (ai == NULL) 153168754Sbushman return; 154168754Sbushman 155168754Sbushman free(ai->ai_addr); 156168754Sbushman free(ai->ai_canonname); 157168754Sbushman free_addrinfo(ai->ai_next); 158168754Sbushman} 159168754Sbushman 160168754Sbushmanvoid 161168754Sbushmansdump_addrinfo(struct addrinfo *ai, char *buffer, size_t buflen) 162168754Sbushman{ 163168754Sbushman int written, i; 164168754Sbushman 165168754Sbushman written = snprintf(buffer, buflen, "%d %d %d %d %d ", 166168754Sbushman ai->ai_flags, ai->ai_family, ai->ai_socktype, ai->ai_protocol, 167168754Sbushman ai->ai_addrlen); 168168754Sbushman buffer += written; 169168754Sbushman if (written > buflen) 170168754Sbushman return; 171168754Sbushman buflen -= written; 172168754Sbushman 173168754Sbushman written = snprintf(buffer, buflen, "%s ", 174168754Sbushman ai->ai_canonname == NULL ? "(null)" : ai->ai_canonname); 175168754Sbushman buffer += written; 176168754Sbushman if (written > buflen) 177168754Sbushman return; 178168754Sbushman buflen -= written; 179168754Sbushman 180168754Sbushman if (ai->ai_addr == NULL) { 181168754Sbushman written = snprintf(buffer, buflen, "(null)"); 182168754Sbushman buffer += written; 183168754Sbushman if (written > buflen) 184168754Sbushman return; 185168754Sbushman buflen -= written; 186168754Sbushman } else { 187168754Sbushman for (i = 0; i < ai->ai_addrlen; ++i ) { 188168754Sbushman written = snprintf(buffer, buflen, 189168754Sbushman i + 1 != ai->ai_addrlen ? "%d." : "%d", 190168754Sbushman ((unsigned char *)ai->ai_addr)[i]); 191168754Sbushman buffer += written; 192168754Sbushman if (written > buflen) 193168754Sbushman return; 194168754Sbushman buflen -= written; 195168754Sbushman 196168754Sbushman if (buflen == 0) 197168754Sbushman return; 198168754Sbushman } 199168754Sbushman } 200168754Sbushman 201168754Sbushman if (ai->ai_next != NULL) { 202168754Sbushman written = snprintf(buffer, buflen, ":"); 203168754Sbushman buffer += written; 204168754Sbushman if (written > buflen) 205168754Sbushman return; 206168754Sbushman buflen -= written; 207168754Sbushman 208168754Sbushman sdump_addrinfo(ai->ai_next, buffer, buflen); 209168754Sbushman } 210168754Sbushman} 211168754Sbushman 212168754Sbushmanvoid 213168754Sbushmandump_addrinfo(struct addrinfo *result) 214168754Sbushman{ 215168754Sbushman if (result != NULL) { 216168754Sbushman char buffer[2048]; 217168754Sbushman sdump_addrinfo(result, buffer, sizeof(buffer)); 218168754Sbushman printf("%s\n", buffer); 219168754Sbushman } else 220168754Sbushman printf("(null)\n"); 221168754Sbushman} 222168754Sbushman 223168754Sbushmanstatic int 224168754Sbushmanaddrinfo_read_snapshot_addr(char *addr, unsigned char *result, size_t len) 225168754Sbushman{ 226168754Sbushman char *s, *ps, *ts; 227168754Sbushman 228168754Sbushman ps = addr; 229168754Sbushman while ( (s = strsep(&ps, ".")) != NULL) { 230168754Sbushman if (len == 0) 231168754Sbushman return (-1); 232168754Sbushman 233168754Sbushman *result = (unsigned char)strtol(s, &ts, 10); 234168754Sbushman ++result; 235168754Sbushman if (*ts != '\0') 236168754Sbushman return (-1); 237168754Sbushman 238168754Sbushman --len; 239168754Sbushman } 240168754Sbushman if (len != 0) 241168754Sbushman return (-1); 242168754Sbushman else 243168754Sbushman return (0); 244168754Sbushman} 245168754Sbushman 246168754Sbushmanstatic int 247168754Sbushmanaddrinfo_read_snapshot_ai(struct addrinfo *ai, char *line) 248168754Sbushman{ 249168754Sbushman char *s, *ps, *ts; 250168754Sbushman int i, rv, *pi; 251168754Sbushman 252168754Sbushman rv = 0; 253168754Sbushman i = 0; 254168754Sbushman ps = line; 255168754Sbushman memset(ai, 0, sizeof(struct addrinfo)); 256168754Sbushman while ( (s = strsep(&ps, " ")) != NULL) { 257168754Sbushman switch (i) { 258168754Sbushman case 0: 259168754Sbushman case 1: 260168754Sbushman case 2: 261168754Sbushman case 3: 262168754Sbushman pi = &ai->ai_flags + i; 263168754Sbushman *pi = (int)strtol(s, &ts, 10); 264168754Sbushman if (*ts != '\0') 265168754Sbushman goto fin; 266168754Sbushman break; 267168754Sbushman case 4: 268168754Sbushman ai->ai_addrlen = (socklen_t)strtol(s, &ts, 10); 269168754Sbushman if (*ts != '\0') 270168754Sbushman goto fin; 271168754Sbushman break; 272168754Sbushman case 5: 273168754Sbushman if (strcmp(s, "(null)") != 0) { 274168754Sbushman ai->ai_canonname = strdup(s); 275168754Sbushman assert(ai->ai_canonname != NULL); 276168754Sbushman } 277168754Sbushman break; 278168754Sbushman case 6: 279168754Sbushman if (strcmp(s, "(null)") != 0) { 280168754Sbushman ai->ai_addr = (struct sockaddr *)malloc( 281168754Sbushman ai->ai_addrlen); 282168754Sbushman assert(ai->ai_addr != NULL); 283168754Sbushman memset(ai->ai_addr, 0, ai->ai_addrlen); 284168754Sbushman rv = addrinfo_read_snapshot_addr(s, 285168754Sbushman (unsigned char *)ai->ai_addr, 286168754Sbushman ai->ai_addrlen); 287168754Sbushman 288168754Sbushman if (rv != 0) 289168754Sbushman goto fin; 290168754Sbushman } 291168754Sbushman break; 292168754Sbushman default: 293168754Sbushman /* NOTE: should not be reachable */ 294168754Sbushman rv = -1; 295168754Sbushman goto fin; 296168754Sbushman }; 297168754Sbushman 298168754Sbushman ++i; 299168754Sbushman } 300168754Sbushman 301168754Sbushmanfin: 302168754Sbushman if ((i != 7) || (rv != 0)) { 303168754Sbushman free_addrinfo(ai); 304168754Sbushman memset(ai, 0, sizeof(struct addrinfo)); 305168754Sbushman return (-1); 306168754Sbushman } 307168754Sbushman 308168754Sbushman return (0); 309168754Sbushman} 310168754Sbushman 311168754Sbushmanstatic int 312168754Sbushmanaddrinfo_read_snapshot_func(struct addrinfo *ai, char *line) 313168754Sbushman{ 314168754Sbushman struct addrinfo *ai2; 315168754Sbushman char *s, *ps; 316168754Sbushman int i, rv; 317168754Sbushman 318168754Sbushman if (debug) 319168754Sbushman printf("1 line read from snapshot:\n%s\n", line); 320168754Sbushman 321168754Sbushman rv = 0; 322168754Sbushman i = 0; 323168754Sbushman ps = line; 324168754Sbushman 325168754Sbushman s = strsep(&ps, ":"); 326168754Sbushman if (s == NULL) 327168754Sbushman return (-1); 328168754Sbushman 329168754Sbushman rv = addrinfo_read_snapshot_ai(ai, s); 330168754Sbushman if (rv != 0) 331168754Sbushman return (-1); 332168754Sbushman 333168754Sbushman ai2 = ai; 334168754Sbushman while ( (s = strsep(&ps, ":")) != NULL) { 335168754Sbushman ai2->ai_next = (struct addrinfo *)malloc( 336168754Sbushman sizeof(struct addrinfo)); 337168754Sbushman assert(ai2->ai_next != NULL); 338168754Sbushman memset(ai2->ai_next, 0, sizeof(struct addrinfo)); 339168754Sbushman 340168754Sbushman rv = addrinfo_read_snapshot_ai(ai2->ai_next, s); 341168754Sbushman if (rv != 0) { 342168754Sbushman free_addrinfo(ai); 343168754Sbushman return (-1); 344168754Sbushman } 345168754Sbushman 346168754Sbushman ai2 = ai2->ai_next; 347168754Sbushman } 348168754Sbushman 349168754Sbushman return (0); 350168754Sbushman} 351168754Sbushman 352168754Sbushmanstatic int 353168754Sbushmanaddrinfo_test_correctness(struct addrinfo *ai, void *mdata) 354168754Sbushman{ 355168754Sbushman if (debug) { 356168754Sbushman printf("testing correctness with the following data:\n"); 357168754Sbushman dump_addrinfo(ai); 358168754Sbushman } 359168754Sbushman 360168754Sbushman if (ai == NULL) 361168754Sbushman goto errfin; 362168754Sbushman 363168754Sbushman if (!((ai->ai_family >= 0) && (ai->ai_family < AF_MAX))) 364168754Sbushman goto errfin; 365168754Sbushman 366168754Sbushman if ((ai->ai_socktype != 0) && (ai->ai_socktype != SOCK_STREAM) && 367168754Sbushman (ai->ai_socktype != SOCK_DGRAM) && (ai->ai_socktype != SOCK_RAW)) 368168754Sbushman goto errfin; 369168754Sbushman 370168754Sbushman if ((ai->ai_protocol != 0) && (ai->ai_protocol != IPPROTO_UDP) && 371168754Sbushman (ai->ai_protocol != IPPROTO_TCP)) 372168754Sbushman goto errfin; 373168754Sbushman 374168754Sbushman if ((ai->ai_flags & ~(AI_CANONNAME | AI_NUMERICHOST | AI_PASSIVE)) != 0) 375168754Sbushman goto errfin; 376168754Sbushman 377168754Sbushman if ((ai->ai_addrlen != ai->ai_addr->sa_len) || 378168754Sbushman (ai->ai_family != ai->ai_addr->sa_family)) 379168754Sbushman goto errfin; 380168754Sbushman 381168754Sbushman if (debug) 382168754Sbushman printf("correct\n"); 383168754Sbushman 384168754Sbushman return (0); 385168754Sbushmanerrfin: 386168754Sbushman if (debug) 387168754Sbushman printf("incorrect\n"); 388168754Sbushman 389168754Sbushman return (-1); 390168754Sbushman} 391168754Sbushman 392168754Sbushmanstatic int 393168754Sbushmanaddrinfo_read_hostlist_func(struct addrinfo *ai, char *line) 394168754Sbushman{ 395168754Sbushman struct addrinfo *result; 396168754Sbushman int rv; 397168754Sbushman 398168754Sbushman if (debug) 399168754Sbushman printf("resolving %s: ", line); 400168754Sbushman rv = getaddrinfo(line, NULL, &hints, &result); 401168754Sbushman if (rv == 0) { 402168754Sbushman if (debug) 403168754Sbushman printf("found\n"); 404168754Sbushman 405168754Sbushman rv = addrinfo_test_correctness(result, NULL); 406168754Sbushman if (rv != 0) { 407168754Sbushman freeaddrinfo(result); 408168754Sbushman return (rv); 409168754Sbushman } 410168754Sbushman 411168754Sbushman clone_addrinfo(ai, result); 412168754Sbushman freeaddrinfo(result); 413168754Sbushman } else { 414168754Sbushman if (debug) 415168754Sbushman printf("not found\n"); 416168754Sbushman 417168754Sbushman memset(ai, 0, sizeof(struct addrinfo)); 418168754Sbushman } 419168754Sbushman return (0); 420168754Sbushman} 421168754Sbushman 422168754Sbushmanstatic void 423168754Sbushmanusage(void) 424168754Sbushman{ 425168754Sbushman (void)fprintf(stderr, 426168754Sbushman "Usage: %s [-d] [-46] [-s <file]> -f <file>\n", 427168754Sbushman getprogname()); 428168754Sbushman exit(1); 429168754Sbushman} 430168754Sbushman 431168754Sbushmanint 432168754Sbushmanmain(int argc, char **argv) 433168754Sbushman{ 434168754Sbushman struct addrinfo_test_data td, td_snap; 435168754Sbushman char *snapshot_file, *hostlist_file; 436168754Sbushman int rv; 437168754Sbushman int c; 438168754Sbushman 439168754Sbushman if (argc < 2) 440168754Sbushman usage(); 441168754Sbushman 442168754Sbushman snapshot_file = NULL; 443168754Sbushman hostlist_file = NULL; 444168754Sbushman memset(&hints, 0, sizeof(struct addrinfo)); 445168754Sbushman hints.ai_family = PF_UNSPEC; 446168754Sbushman hints.ai_flags = AI_CANONNAME; 447168754Sbushman while ((c = getopt(argc, argv, "46dns:f:")) != -1) 448168754Sbushman switch (c) { 449168754Sbushman case '4': 450168754Sbushman hints.ai_family = PF_INET; 451168754Sbushman case '6': 452168754Sbushman hints.ai_family = PF_INET6; 453168754Sbushman break; 454168754Sbushman case 'd': 455168754Sbushman debug = 1; 456168754Sbushman break; 457168754Sbushman case 's': 458168754Sbushman snapshot_file = strdup(optarg); 459168754Sbushman method = TEST_BUILD_SNAPSHOT; 460168754Sbushman break; 461168754Sbushman case 'f': 462168754Sbushman hostlist_file = strdup(optarg); 463168754Sbushman break; 464168754Sbushman default: 465168754Sbushman usage(); 466168754Sbushman } 467168754Sbushman 468168754Sbushman TEST_DATA_INIT(addrinfo, &td, clone_addrinfo, free_addrinfo); 469168754Sbushman TEST_DATA_INIT(addrinfo, &td_snap, clone_addrinfo, free_addrinfo); 470168754Sbushman 471168754Sbushman if (hostlist_file == NULL) 472168754Sbushman usage(); 473168754Sbushman 474168754Sbushman if (access(hostlist_file, R_OK) != 0) { 475168754Sbushman if (debug) 476168754Sbushman printf("can't access the hostlist file %s\n", 477168754Sbushman hostlist_file); 478168754Sbushman 479168754Sbushman usage(); 480168754Sbushman } 481168754Sbushman 482168754Sbushman if (debug) 483168754Sbushman printf("building host lists from %s\n", hostlist_file); 484168754Sbushman 485168754Sbushman rv = TEST_SNAPSHOT_FILE_READ(addrinfo, hostlist_file, &td, 486168754Sbushman addrinfo_read_hostlist_func); 487168754Sbushman if (rv != 0) 488168754Sbushman goto fin; 489168754Sbushman 490168754Sbushman if (snapshot_file != NULL) { 491168754Sbushman if (access(snapshot_file, W_OK | R_OK) != 0) { 492168754Sbushman if (errno == ENOENT) 493168754Sbushman method = TEST_BUILD_SNAPSHOT; 494168754Sbushman else { 495168754Sbushman if (debug) 496168754Sbushman printf("can't access the snapshot file %s\n", 497168754Sbushman snapshot_file); 498168754Sbushman 499168754Sbushman rv = -1; 500168754Sbushman goto fin; 501168754Sbushman } 502168754Sbushman } else { 503168754Sbushman rv = TEST_SNAPSHOT_FILE_READ(addrinfo, snapshot_file, 504168754Sbushman &td_snap, addrinfo_read_snapshot_func); 505168754Sbushman if (rv != 0) { 506168754Sbushman if (debug) 507168754Sbushman printf("error reading snapshot file\n"); 508168754Sbushman goto fin; 509168754Sbushman } 510168754Sbushman } 511168754Sbushman } 512168754Sbushman 513168754Sbushman switch (method) { 514168754Sbushman case TEST_GETADDRINFO: 515168754Sbushman if (snapshot_file != NULL) 516168754Sbushman rv = DO_2PASS_TEST(addrinfo, &td, &td_snap, 517168754Sbushman compare_addrinfo, NULL); 518168754Sbushman break; 519168754Sbushman case TEST_BUILD_SNAPSHOT: 520168754Sbushman if (snapshot_file != NULL) { 521168754Sbushman rv = TEST_SNAPSHOT_FILE_WRITE(addrinfo, snapshot_file, &td, 522168754Sbushman sdump_addrinfo); 523168754Sbushman } 524168754Sbushman break; 525168754Sbushman default: 526168754Sbushman rv = 0; 527168754Sbushman break; 528168754Sbushman }; 529168754Sbushman 530168754Sbushmanfin: 531168754Sbushman TEST_DATA_DESTROY(addrinfo, &td_snap); 532168754Sbushman TEST_DATA_DESTROY(addrinfo, &td); 533168754Sbushman free(hostlist_file); 534168754Sbushman free(snapshot_file); 535168754Sbushman return (rv); 536168754Sbushman 537168754Sbushman} 538168754Sbushman 539