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 46168754Sbushman#ifndef min 47168754Sbushman#define min(a,b) (((a)<(b))?(a):(b)) 48168754Sbushman#endif 49168754Sbushman 50168754Sbushmanenum test_methods { 51168754Sbushman TEST_GETHOSTBYNAME2, 52168754Sbushman TEST_GETHOSTBYADDR, 53168754Sbushman TEST_GETHOSTBYNAME2_GETADDRINFO, 54168754Sbushman TEST_GETHOSTBYADDR_GETNAMEINFO, 55168754Sbushman TEST_BUILD_SNAPSHOT, 56168754Sbushman TEST_BUILD_ADDR_SNAPSHOT 57168754Sbushman}; 58168754Sbushman 59168754Sbushmanstatic int use_ipnode_functions = 0; 60168754Sbushmanstatic int use_ipv6_mapping = 0; 61171016Sbushmanstatic int ipnode_flags = 0; 62168754Sbushmanstatic int debug = 0; 63168754Sbushmanstatic int af_type = AF_INET; 64168754Sbushmanstatic enum test_methods method = TEST_BUILD_SNAPSHOT; 65168754Sbushman 66168754SbushmanDECLARE_TEST_DATA(hostent) 67168754SbushmanDECLARE_TEST_FILE_SNAPSHOT(hostent) 68168754SbushmanDECLARE_1PASS_TEST(hostent) 69168754SbushmanDECLARE_2PASS_TEST(hostent) 70168754Sbushman 71168754Sbushman/* These stubs will use gethostby***() or getipnodeby***() functions, 72168754Sbushman * depending on the use_ipnode_functions global variable value */ 73168754Sbushmanstatic struct hostent *__gethostbyname2(const char *, int); 74168754Sbushmanstatic struct hostent *__gethostbyaddr(const void *, socklen_t, int); 75168754Sbushmanstatic void __freehostent(struct hostent *); 76168754Sbushman 77168754Sbushmanstatic void clone_hostent(struct hostent *, struct hostent const *); 78168754Sbushmanstatic int compare_hostent(struct hostent *, struct hostent *, void *); 79168754Sbushmanstatic void dump_hostent(struct hostent *); 80168754Sbushmanstatic void free_hostent(struct hostent *); 81168754Sbushman 82168754Sbushmanstatic int is_hostent_equal(struct hostent *, struct addrinfo *); 83168754Sbushman 84168754Sbushmanstatic void sdump_hostent(struct hostent *, char *, size_t); 85168754Sbushmanstatic int hostent_read_hostlist_func(struct hostent *, char *); 86168754Sbushmanstatic int hostent_read_snapshot_addr(char *, unsigned char *, size_t); 87168754Sbushmanstatic int hostent_read_snapshot_func(struct hostent *, char *); 88168754Sbushman 89168754Sbushmanstatic int hostent_test_correctness(struct hostent *, void *); 90168754Sbushmanstatic int hostent_test_gethostbyaddr(struct hostent *, void *); 91168754Sbushmanstatic int hostent_test_getaddrinfo_eq(struct hostent *, void *); 92168754Sbushmanstatic int hostent_test_getnameinfo_eq(struct hostent *, void *); 93168754Sbushman 94168754Sbushmanstatic void usage(void) __attribute__((__noreturn__)); 95168754Sbushman 96168754SbushmanIMPLEMENT_TEST_DATA(hostent) 97168754SbushmanIMPLEMENT_TEST_FILE_SNAPSHOT(hostent) 98168754SbushmanIMPLEMENT_1PASS_TEST(hostent) 99168754SbushmanIMPLEMENT_2PASS_TEST(hostent) 100168754Sbushman 101168754Sbushmanstatic struct hostent * 102168754Sbushman__gethostbyname2(const char *name, int af) 103168754Sbushman{ 104168754Sbushman struct hostent *he; 105168754Sbushman int error; 106168754Sbushman 107171016Sbushman if (use_ipnode_functions == 0) 108168754Sbushman he = gethostbyname2(name, af); 109171016Sbushman else { 110168754Sbushman error = 0; 111171016Sbushman he = getipnodebyname(name, af, ipnode_flags, &error); 112168754Sbushman if (he == NULL); 113168754Sbushman errno = error; 114168754Sbushman } 115168754Sbushman 116168754Sbushman return (he); 117168754Sbushman} 118168754Sbushman 119168754Sbushmanstatic struct hostent * 120168754Sbushman__gethostbyaddr(const void *addr, socklen_t len, int af) 121168754Sbushman{ 122168754Sbushman struct hostent *he; 123168754Sbushman int error; 124168754Sbushman 125171016Sbushman if (use_ipnode_functions == 0) 126168754Sbushman he = gethostbyaddr(addr, len, af); 127171016Sbushman else { 128168754Sbushman error = 0; 129171016Sbushman he = getipnodebyaddr(addr, len, af, &error); 130168754Sbushman if (he == NULL) 131168754Sbushman errno = error; 132168754Sbushman } 133168754Sbushman 134168754Sbushman return (he); 135168754Sbushman} 136168754Sbushman 137168754Sbushmanstatic void 138168754Sbushman__freehostent(struct hostent *he) 139168754Sbushman{ 140168754Sbushman /* NOTE: checking for he != NULL - just in case */ 141168754Sbushman if ((use_ipnode_functions != 0) && (he != NULL)) 142168754Sbushman freehostent(he); 143168754Sbushman} 144168754Sbushman 145168754Sbushmanstatic void 146168754Sbushmanclone_hostent(struct hostent *dest, struct hostent const *src) 147168754Sbushman{ 148168754Sbushman assert(dest != NULL); 149168754Sbushman assert(src != NULL); 150168754Sbushman 151168754Sbushman char **cp; 152168754Sbushman int aliases_num; 153168754Sbushman int addrs_num; 154168754Sbushman size_t offset; 155168754Sbushman 156168754Sbushman memset(dest, 0, sizeof(struct hostent)); 157168754Sbushman 158168754Sbushman if (src->h_name != NULL) { 159168754Sbushman dest->h_name = strdup(src->h_name); 160168754Sbushman assert(dest->h_name != NULL); 161168754Sbushman } 162168754Sbushman 163168754Sbushman dest->h_addrtype = src->h_addrtype; 164168754Sbushman dest->h_length = src->h_length; 165168754Sbushman 166168754Sbushman if (src->h_aliases != NULL) { 167168754Sbushman aliases_num = 0; 168168754Sbushman for (cp = src->h_aliases; *cp; ++cp) 169168754Sbushman ++aliases_num; 170168754Sbushman 171168754Sbushman dest->h_aliases = (char **)malloc((aliases_num + 1) * 172168754Sbushman (sizeof(char *))); 173168754Sbushman assert(dest->h_aliases != NULL); 174168754Sbushman memset(dest->h_aliases, 0, (aliases_num + 1) * 175168754Sbushman (sizeof(char *))); 176168754Sbushman 177168754Sbushman for (cp = src->h_aliases; *cp; ++cp) { 178168754Sbushman dest->h_aliases[cp - src->h_aliases] = strdup(*cp); 179168754Sbushman assert(dest->h_aliases[cp - src->h_aliases] != NULL); 180168754Sbushman } 181168754Sbushman } 182168754Sbushman 183168754Sbushman if (src->h_addr_list != NULL) { 184168754Sbushman addrs_num = 0; 185168754Sbushman for (cp = src->h_addr_list; *cp; ++cp) 186168754Sbushman ++addrs_num; 187168754Sbushman 188168754Sbushman dest->h_addr_list = (char **)malloc((addrs_num + 1) * 189168754Sbushman (sizeof(char *))); 190168754Sbushman assert(dest->h_addr_list != NULL); 191168754Sbushman memset(dest->h_addr_list, 0, (addrs_num + 1) * 192168754Sbushman (sizeof(char *))); 193168754Sbushman 194168754Sbushman for (cp = src->h_addr_list; *cp; ++cp) { 195168754Sbushman offset = cp - src->h_addr_list; 196168754Sbushman dest->h_addr_list[offset] = 197168754Sbushman (char *)malloc(src->h_length); 198168754Sbushman assert(dest->h_addr_list[offset] != NULL); 199168754Sbushman memcpy(dest->h_addr_list[offset], 200168754Sbushman src->h_addr_list[offset], src->h_length); 201168754Sbushman } 202168754Sbushman } 203168754Sbushman} 204168754Sbushman 205168754Sbushmanstatic void 206168754Sbushmanfree_hostent(struct hostent *ht) 207168754Sbushman{ 208168754Sbushman char **cp; 209168754Sbushman 210168754Sbushman assert(ht != NULL); 211168754Sbushman 212168754Sbushman free(ht->h_name); 213168754Sbushman 214168754Sbushman if (ht->h_aliases != NULL) { 215168754Sbushman for (cp = ht->h_aliases; *cp; ++cp) 216168754Sbushman free(*cp); 217168754Sbushman free(ht->h_aliases); 218168754Sbushman } 219168754Sbushman 220168754Sbushman if (ht->h_addr_list != NULL) { 221168754Sbushman for (cp = ht->h_addr_list; *cp; ++cp) 222168754Sbushman free(*cp); 223168754Sbushman free(ht->h_addr_list); 224168754Sbushman } 225168754Sbushman} 226168754Sbushman 227168754Sbushmanstatic int 228168754Sbushmancompare_hostent(struct hostent *ht1, struct hostent *ht2, void *mdata) 229168754Sbushman{ 230171016Sbushman char **c1, **c2, **ct, **cb; 231171016Sbushman int b; 232168754Sbushman 233168754Sbushman if (ht1 == ht2) 234168754Sbushman return 0; 235168754Sbushman 236168754Sbushman if ((ht1 == NULL) || (ht2 == NULL)) 237168754Sbushman goto errfin; 238168754Sbushman 239168754Sbushman if ((ht1->h_name == NULL) || (ht2->h_name == NULL)) 240168754Sbushman goto errfin; 241168754Sbushman 242168754Sbushman if ((ht1->h_addrtype != ht2->h_addrtype) || 243168754Sbushman (ht1->h_length != ht2->h_length) || 244168754Sbushman (strcmp(ht1->h_name, ht2->h_name) != 0)) 245168754Sbushman goto errfin; 246168754Sbushman 247168754Sbushman c1 = ht1->h_aliases; 248168754Sbushman c2 = ht2->h_aliases; 249168754Sbushman 250168754Sbushman if (((ht1->h_aliases == NULL) || (ht2->h_aliases == NULL)) && 251168754Sbushman (ht1->h_aliases != ht2->h_aliases)) 252168754Sbushman goto errfin; 253168754Sbushman 254168754Sbushman if ((c1 != NULL) && (c2 != NULL)) { 255171016Sbushman cb = c1; 256171016Sbushman for (;*c1; ++c1) { 257171016Sbushman b = 0; 258171016Sbushman for (ct = c2; *ct; ++ct) { 259171016Sbushman if (strcmp(*c1, *ct) == 0) { 260171016Sbushman b = 1; 261171016Sbushman break; 262171016Sbushman } 263171016Sbushman } 264171016Sbushman if (b == 0) { 265171016Sbushman if (debug) 266171016Sbushman printf("h1 aliases item can't be "\ 267171016Sbushman "found in h2 aliases\n"); 268168754Sbushman goto errfin; 269171016Sbushman } 270171016Sbushman } 271171016Sbushman 272171016Sbushman c1 = cb; 273171016Sbushman for (;*c2; ++c2) { 274171016Sbushman b = 0; 275171016Sbushman for (ct = c1; *ct; ++ct) { 276171016Sbushman if (strcmp(*c2, *ct) == 0) { 277171016Sbushman b = 1; 278171016Sbushman break; 279171016Sbushman } 280171016Sbushman } 281171016Sbushman if (b == 0) { 282171016Sbushman if (debug) 283171016Sbushman printf("h2 aliases item can't be "\ 284171016Sbushman " found in h1 aliases\n"); 285171016Sbushman goto errfin; 286171016Sbushman } 287171016Sbushman } 288168754Sbushman } 289168754Sbushman 290168754Sbushman c1 = ht1->h_addr_list; 291168754Sbushman c2 = ht2->h_addr_list; 292168754Sbushman 293168754Sbushman if (((ht1->h_addr_list == NULL) || (ht2->h_addr_list== NULL)) && 294168754Sbushman (ht1->h_addr_list != ht2->h_addr_list)) 295168754Sbushman goto errfin; 296168754Sbushman 297168754Sbushman if ((c1 != NULL) && (c2 != NULL)) { 298171016Sbushman cb = c1; 299171016Sbushman for (;*c1; ++c1) { 300171016Sbushman b = 0; 301171016Sbushman for (ct = c2; *ct; ++ct) { 302171016Sbushman if (memcmp(*c1, *ct, ht1->h_length) == 0) { 303171016Sbushman b = 1; 304171016Sbushman break; 305171016Sbushman } 306171016Sbushman } 307171016Sbushman if (b == 0) { 308171016Sbushman if (debug) 309171016Sbushman printf("h1 addresses item can't be "\ 310171016Sbushman "found in h2 addresses\n"); 311168754Sbushman goto errfin; 312171016Sbushman } 313171016Sbushman } 314171016Sbushman 315171016Sbushman c1 = cb; 316171016Sbushman for (;*c2; ++c2) { 317171016Sbushman b = 0; 318171016Sbushman for (ct = c1; *ct; ++ct) { 319171016Sbushman if (memcmp(*c2, *ct, ht1->h_length) == 0) { 320171016Sbushman b = 1; 321171016Sbushman break; 322171016Sbushman } 323171016Sbushman } 324171016Sbushman if (b == 0) { 325171016Sbushman if (debug) 326171016Sbushman printf("h2 addresses item can't be "\ 327171016Sbushman "found in h1 addresses\n"); 328171016Sbushman goto errfin; 329171016Sbushman } 330171016Sbushman } 331168754Sbushman } 332168754Sbushman 333168754Sbushman return 0; 334168754Sbushman 335168754Sbushmanerrfin: 336168754Sbushman if ((debug) && (mdata == NULL)) { 337168754Sbushman printf("following structures are not equal:\n"); 338168754Sbushman dump_hostent(ht1); 339168754Sbushman dump_hostent(ht2); 340168754Sbushman } 341168754Sbushman 342168754Sbushman return (-1); 343168754Sbushman} 344168754Sbushman 345168754Sbushmanstatic int 346168754Sbushmancheck_addrinfo_for_name(struct addrinfo *ai, char const *name) 347168754Sbushman{ 348168754Sbushman struct addrinfo *ai2; 349168754Sbushman 350168754Sbushman for (ai2 = ai; ai2 != NULL; ai2 = ai2->ai_next) { 351168754Sbushman if (strcmp(ai2->ai_canonname, name) == 0) 352168754Sbushman return (0); 353168754Sbushman } 354168754Sbushman 355168754Sbushman return (-1); 356168754Sbushman} 357168754Sbushman 358168754Sbushmanstatic int 359168754Sbushmancheck_addrinfo_for_addr(struct addrinfo *ai, char const *addr, 360168754Sbushman socklen_t addrlen, int af) 361168754Sbushman{ 362168754Sbushman struct addrinfo *ai2; 363168754Sbushman 364168754Sbushman for (ai2 = ai; ai2 != NULL; ai2 = ai2->ai_next) { 365168754Sbushman if (af != ai2->ai_family) 366168754Sbushman continue; 367168754Sbushman 368168754Sbushman switch (af) { 369168754Sbushman case AF_INET: 370168754Sbushman if (memcmp(addr, 371168754Sbushman (void *)&((struct sockaddr_in *)ai2->ai_addr)->sin_addr, 372168754Sbushman min(addrlen, ai2->ai_addrlen)) == 0) 373168754Sbushman return (0); 374168754Sbushman break; 375168754Sbushman case AF_INET6: 376168754Sbushman if (memcmp(addr, 377168754Sbushman (void *)&((struct sockaddr_in6 *)ai2->ai_addr)->sin6_addr, 378168754Sbushman min(addrlen, ai2->ai_addrlen)) == 0) 379168754Sbushman return (0); 380168754Sbushman break; 381168754Sbushman default: 382168754Sbushman break; 383168754Sbushman } 384168754Sbushman } 385168754Sbushman 386168754Sbushman return (-1); 387168754Sbushman} 388168754Sbushman 389168754Sbushmanstatic int 390168754Sbushmanis_hostent_equal(struct hostent *he, struct addrinfo *ai) 391168754Sbushman{ 392168754Sbushman char **cp; 393168754Sbushman int rv; 394168754Sbushman 395168754Sbushman if (debug) 396168754Sbushman printf("checking equality of he and ai\n"); 397168754Sbushman 398168754Sbushman rv = check_addrinfo_for_name(ai, he->h_name); 399168754Sbushman if (rv != 0) { 400168754Sbushman if (debug) 401168754Sbushman printf("not equal - he->h_name couldn't be found\n"); 402168754Sbushman 403168754Sbushman return (rv); 404168754Sbushman } 405168754Sbushman 406168754Sbushman for (cp = he->h_addr_list; *cp; ++cp) { 407168754Sbushman rv = check_addrinfo_for_addr(ai, *cp, he->h_length, 408168754Sbushman he->h_addrtype); 409168754Sbushman if (rv != 0) { 410168754Sbushman if (debug) 411168754Sbushman printf("not equal - one of he->h_addr_list couldn't be found\n"); 412168754Sbushman 413168754Sbushman return (rv); 414168754Sbushman } 415168754Sbushman } 416168754Sbushman 417168754Sbushman if (debug) 418168754Sbushman printf("equal\n"); 419168754Sbushman 420168754Sbushman return (0); 421168754Sbushman} 422168754Sbushman 423168754Sbushmanstatic void 424168754Sbushmansdump_hostent(struct hostent *ht, char *buffer, size_t buflen) 425168754Sbushman{ 426168754Sbushman char **cp; 427168754Sbushman size_t i; 428168754Sbushman int written; 429168754Sbushman 430168754Sbushman written = snprintf(buffer, buflen, "%s %d %d", 431168754Sbushman ht->h_name, ht->h_addrtype, ht->h_length); 432168754Sbushman buffer += written; 433168754Sbushman if (written > buflen) 434168754Sbushman return; 435168754Sbushman buflen -= written; 436168754Sbushman 437168754Sbushman if (ht->h_aliases != NULL) { 438168754Sbushman if (*(ht->h_aliases) != NULL) { 439168754Sbushman for (cp = ht->h_aliases; *cp; ++cp) { 440168754Sbushman written = snprintf(buffer, buflen, " %s",*cp); 441168754Sbushman buffer += written; 442168754Sbushman if (written > buflen) 443168754Sbushman return; 444168754Sbushman buflen -= written; 445168754Sbushman 446168754Sbushman if (buflen == 0) 447168754Sbushman return; 448168754Sbushman } 449168754Sbushman } else { 450168754Sbushman written = snprintf(buffer, buflen, " noaliases"); 451168754Sbushman buffer += written; 452168754Sbushman if (written > buflen) 453168754Sbushman return; 454168754Sbushman buflen -= written; 455168754Sbushman } 456168754Sbushman } else { 457168754Sbushman written = snprintf(buffer, buflen, " (null)"); 458168754Sbushman buffer += written; 459168754Sbushman if (written > buflen) 460168754Sbushman return; 461168754Sbushman buflen -= written; 462168754Sbushman } 463168754Sbushman 464168754Sbushman written = snprintf(buffer, buflen, " : "); 465168754Sbushman buffer += written; 466168754Sbushman if (written > buflen) 467168754Sbushman return; 468168754Sbushman buflen -= written; 469168754Sbushman 470168754Sbushman if (ht->h_addr_list != NULL) { 471168754Sbushman if (*(ht->h_addr_list) != NULL) { 472168754Sbushman for (cp = ht->h_addr_list; *cp; ++cp) { 473168754Sbushman for (i = 0; i < ht->h_length; ++i ) { 474168754Sbushman written = snprintf(buffer, buflen, 475168754Sbushman i + 1 != ht->h_length ? "%d." : "%d", 476168754Sbushman (unsigned char)(*cp)[i]); 477168754Sbushman buffer += written; 478168754Sbushman if (written > buflen) 479168754Sbushman return; 480168754Sbushman buflen -= written; 481168754Sbushman 482168754Sbushman if (buflen == 0) 483168754Sbushman return; 484168754Sbushman } 485168754Sbushman 486168754Sbushman if (*(cp + 1) ) { 487168754Sbushman written = snprintf(buffer, buflen, " "); 488168754Sbushman buffer += written; 489168754Sbushman if (written > buflen) 490168754Sbushman return; 491168754Sbushman buflen -= written; 492168754Sbushman } 493168754Sbushman } 494168754Sbushman } else { 495168754Sbushman written = snprintf(buffer, buflen, " noaddrs"); 496168754Sbushman buffer += written; 497168754Sbushman if (written > buflen) 498168754Sbushman return; 499168754Sbushman buflen -= written; 500168754Sbushman } 501168754Sbushman } else { 502168754Sbushman written = snprintf(buffer, buflen, " (null)"); 503168754Sbushman buffer += written; 504168754Sbushman if (written > buflen) 505168754Sbushman return; 506168754Sbushman buflen -= written; 507168754Sbushman } 508168754Sbushman} 509168754Sbushman 510168754Sbushmanstatic int 511168754Sbushmanhostent_read_hostlist_func(struct hostent *he, char *line) 512168754Sbushman{ 513168754Sbushman struct hostent *result; 514168754Sbushman int rv; 515168754Sbushman 516168754Sbushman if (debug) 517168754Sbushman printf("resolving %s: ", line); 518168754Sbushman result = __gethostbyname2(line, af_type); 519168754Sbushman if (result != NULL) { 520168754Sbushman if (debug) 521168754Sbushman printf("found\n"); 522168754Sbushman 523168754Sbushman rv = hostent_test_correctness(result, NULL); 524168754Sbushman if (rv != 0) { 525168754Sbushman __freehostent(result); 526168754Sbushman return (rv); 527168754Sbushman } 528168754Sbushman 529168754Sbushman clone_hostent(he, result); 530168754Sbushman __freehostent(result); 531168754Sbushman } else { 532168754Sbushman if (debug) 533168754Sbushman printf("not found\n"); 534168754Sbushman 535168754Sbushman memset(he, 0, sizeof(struct hostent)); 536168754Sbushman he->h_name = strdup(line); 537168754Sbushman assert(he->h_name != NULL); 538168754Sbushman } 539168754Sbushman return (0); 540168754Sbushman} 541168754Sbushman 542168754Sbushmanstatic int 543168754Sbushmanhostent_read_snapshot_addr(char *addr, unsigned char *result, size_t len) 544168754Sbushman{ 545168754Sbushman char *s, *ps, *ts; 546168754Sbushman 547168754Sbushman ps = addr; 548168754Sbushman while ( (s = strsep(&ps, ".")) != NULL) { 549168754Sbushman if (len == 0) 550168754Sbushman return (-1); 551168754Sbushman 552168754Sbushman *result = (unsigned char)strtol(s, &ts, 10); 553168754Sbushman ++result; 554168754Sbushman if (*ts != '\0') 555168754Sbushman return (-1); 556168754Sbushman 557168754Sbushman --len; 558168754Sbushman } 559168754Sbushman if (len != 0) 560168754Sbushman return (-1); 561168754Sbushman else 562168754Sbushman return (0); 563168754Sbushman} 564168754Sbushman 565168754Sbushmanstatic int 566168754Sbushmanhostent_read_snapshot_func(struct hostent *ht, char *line) 567168754Sbushman{ 568241844Seadler StringList *sl1, *sl2; 569168754Sbushman char *s, *ps, *ts; 570168754Sbushman int i, rv; 571168754Sbushman 572168754Sbushman if (debug) 573168754Sbushman printf("1 line read from snapshot:\n%s\n", line); 574168754Sbushman 575168754Sbushman rv = 0; 576168754Sbushman i = 0; 577168754Sbushman sl1 = sl2 = NULL; 578168754Sbushman ps = line; 579168754Sbushman memset(ht, 0, sizeof(struct hostent)); 580168754Sbushman while ( (s = strsep(&ps, " ")) != NULL) { 581168754Sbushman switch (i) { 582168754Sbushman case 0: 583168754Sbushman ht->h_name = strdup(s); 584168754Sbushman assert(ht->h_name != NULL); 585168754Sbushman break; 586168754Sbushman 587168754Sbushman case 1: 588168754Sbushman ht->h_addrtype = (int)strtol(s, &ts, 10); 589168754Sbushman if (*ts != '\0') 590168754Sbushman goto fin; 591168754Sbushman break; 592168754Sbushman 593168754Sbushman case 2: 594168754Sbushman ht->h_length = (int)strtol(s, &ts, 10); 595168754Sbushman if (*ts != '\0') 596168754Sbushman goto fin; 597168754Sbushman break; 598168754Sbushman 599168754Sbushman case 3: 600168754Sbushman if (sl1 == NULL) { 601168754Sbushman if (strcmp(s, "(null)") == 0) 602168754Sbushman return (0); 603168754Sbushman 604168754Sbushman sl1 = sl_init(); 605168754Sbushman assert(sl1 != NULL); 606168754Sbushman 607168754Sbushman if (strcmp(s, "noaliases") != 0) { 608168754Sbushman ts = strdup(s); 609168754Sbushman assert(ts != NULL); 610168754Sbushman sl_add(sl1, ts); 611168754Sbushman } 612168754Sbushman } else { 613168754Sbushman if (strcmp(s, ":") == 0) 614168754Sbushman ++i; 615168754Sbushman else { 616168754Sbushman ts = strdup(s); 617168754Sbushman assert(ts != NULL); 618168754Sbushman sl_add(sl1, ts); 619168754Sbushman } 620168754Sbushman } 621168754Sbushman break; 622168754Sbushman 623168754Sbushman case 4: 624168754Sbushman if (sl2 == NULL) { 625168754Sbushman if (strcmp(s, "(null)") == 0) 626168754Sbushman return (0); 627168754Sbushman 628168754Sbushman sl2 = sl_init(); 629168754Sbushman assert(sl2 != NULL); 630168754Sbushman 631168754Sbushman if (strcmp(s, "noaddrs") != 0) { 632168754Sbushman ts = (char *)malloc(ht->h_length); 633168754Sbushman assert(ts != NULL); 634168754Sbushman memset(ts, 0, ht->h_length); 635171016Sbushman rv = hostent_read_snapshot_addr(s,\ 636171016Sbushman (unsigned char *)ts, ht->h_length); 637168754Sbushman sl_add(sl2, ts); 638168754Sbushman if (rv != 0) 639168754Sbushman goto fin; 640168754Sbushman } 641168754Sbushman } else { 642168754Sbushman ts = (char *)malloc(ht->h_length); 643168754Sbushman assert(ts != NULL); 644168754Sbushman memset(ts, 0, ht->h_length); 645171016Sbushman rv = hostent_read_snapshot_addr(s,\ 646171016Sbushman (unsigned char *)ts, ht->h_length); 647168754Sbushman sl_add(sl2, ts); 648168754Sbushman if (rv != 0) 649168754Sbushman goto fin; 650168754Sbushman } 651168754Sbushman break; 652168754Sbushman default: 653168754Sbushman break; 654168754Sbushman }; 655168754Sbushman 656168754Sbushman if ((i != 3) && (i != 4)) 657168754Sbushman ++i; 658168754Sbushman } 659168754Sbushman 660168754Sbushmanfin: 661168754Sbushman if (sl1 != NULL) { 662168754Sbushman sl_add(sl1, NULL); 663168754Sbushman ht->h_aliases = sl1->sl_str; 664168754Sbushman } 665168754Sbushman if (sl2 != NULL) { 666168754Sbushman sl_add(sl2, NULL); 667168754Sbushman ht->h_addr_list = sl2->sl_str; 668168754Sbushman } 669168754Sbushman 670168754Sbushman if ((i != 4) || (rv != 0)) { 671168754Sbushman free_hostent(ht); 672168754Sbushman memset(ht, 0, sizeof(struct hostent)); 673168754Sbushman return (-1); 674168754Sbushman } 675168754Sbushman 676168754Sbushman /* NOTE: is it a dirty hack or not? */ 677168754Sbushman free(sl1); 678168754Sbushman free(sl2); 679168754Sbushman return (0); 680168754Sbushman} 681168754Sbushman 682168754Sbushmanstatic void 683168754Sbushmandump_hostent(struct hostent *result) 684168754Sbushman{ 685168754Sbushman if (result != NULL) { 686168754Sbushman char buffer[1024]; 687168754Sbushman sdump_hostent(result, buffer, sizeof(buffer)); 688168754Sbushman printf("%s\n", buffer); 689168754Sbushman } else 690168754Sbushman printf("(null)\n"); 691168754Sbushman} 692168754Sbushman 693168754Sbushmanstatic int 694168754Sbushmanhostent_test_correctness(struct hostent *ht, void *mdata) 695168754Sbushman{ 696168754Sbushman if (debug) { 697168754Sbushman printf("testing correctness with the following data:\n"); 698168754Sbushman dump_hostent(ht); 699168754Sbushman } 700168754Sbushman 701168754Sbushman if (ht == NULL) 702168754Sbushman goto errfin; 703168754Sbushman 704168754Sbushman if (ht->h_name == NULL) 705168754Sbushman goto errfin; 706168754Sbushman 707168754Sbushman if (!((ht->h_addrtype >= 0) && (ht->h_addrtype < AF_MAX))) 708168754Sbushman goto errfin; 709168754Sbushman 710168754Sbushman if ((ht->h_length != sizeof(struct in_addr)) && 711168754Sbushman (ht->h_length != sizeof(struct in6_addr))) 712168754Sbushman goto errfin; 713168754Sbushman 714168754Sbushman if (ht->h_aliases == NULL) 715168754Sbushman goto errfin; 716168754Sbushman 717168754Sbushman if (ht->h_addr_list == NULL) 718168754Sbushman goto errfin; 719168754Sbushman 720168754Sbushman if (debug) 721168754Sbushman printf("correct\n"); 722168754Sbushman 723168754Sbushman return (0); 724168754Sbushmanerrfin: 725168754Sbushman if (debug) 726168754Sbushman printf("incorrect\n"); 727168754Sbushman 728168754Sbushman return (-1); 729168754Sbushman} 730168754Sbushman 731168754Sbushmanstatic int 732168754Sbushmanhostent_test_gethostbyaddr(struct hostent *he, void *mdata) 733168754Sbushman{ 734168754Sbushman struct hostent *result; 735168754Sbushman struct hostent_test_data *addr_test_data; 736168754Sbushman int rv; 737168754Sbushman 738168754Sbushman addr_test_data = (struct hostent_test_data *)mdata; 739168754Sbushman 740168754Sbushman /* We should omit unresolved hostents */ 741168754Sbushman if (he->h_addr_list != NULL) { 742168754Sbushman char **cp; 743168754Sbushman for (cp = he->h_addr_list; *cp; ++cp) { 744168754Sbushman if (debug) 745168754Sbushman printf("doing reverse lookup for %s\n", he->h_name); 746168754Sbushman 747168754Sbushman result = __gethostbyaddr(*cp, he->h_length, 748168754Sbushman he->h_addrtype); 749168754Sbushman if (result == NULL) { 750168754Sbushman if (debug) 751168754Sbushman printf("warning: reverse lookup failed\n"); 752168754Sbushman 753168754Sbushman continue; 754168754Sbushman } 755168754Sbushman rv = hostent_test_correctness(result, NULL); 756168754Sbushman if (rv != 0) { 757168754Sbushman __freehostent(result); 758168754Sbushman return (rv); 759168754Sbushman } 760168754Sbushman 761168754Sbushman if (addr_test_data != NULL) 762168754Sbushman TEST_DATA_APPEND(hostent, addr_test_data, result); 763168754Sbushman 764168754Sbushman __freehostent(result); 765168754Sbushman } 766168754Sbushman } 767168754Sbushman 768168754Sbushman return (0); 769168754Sbushman} 770168754Sbushman 771168754Sbushmanstatic int 772168754Sbushmanhostent_test_getaddrinfo_eq(struct hostent *he, void *mdata) 773168754Sbushman{ 774168754Sbushman struct addrinfo *ai, hints; 775168754Sbushman int rv; 776168754Sbushman 777168754Sbushman ai = NULL; 778168754Sbushman memset(&hints, 0, sizeof(struct addrinfo)); 779168754Sbushman hints.ai_family = af_type; 780168754Sbushman hints.ai_flags = AI_CANONNAME; 781168754Sbushman 782168754Sbushman if (debug) 783168754Sbushman printf("using getaddrinfo() to resolve %s\n", he->h_name); 784168754Sbushman 785168754Sbushman /* struct hostent *he was not resolved */ 786168754Sbushman if (he->h_addr_list == NULL) { 787168754Sbushman /* We can be sure that he->h_name is not NULL */ 788168754Sbushman rv = getaddrinfo(he->h_name, NULL, &hints, &ai); 789168754Sbushman if (rv == 0) { 790168754Sbushman if (debug) 791168754Sbushman printf("not ok - shouldn't have been resolved\n"); 792168754Sbushman return (-1); 793168754Sbushman } 794168754Sbushman } else { 795168754Sbushman rv = getaddrinfo(he->h_name, NULL, &hints, &ai); 796168754Sbushman if (rv != 0) { 797168754Sbushman if (debug) 798168754Sbushman printf("not ok - should have beed resolved\n"); 799168754Sbushman return (-1); 800168754Sbushman } 801168754Sbushman 802168754Sbushman rv = is_hostent_equal(he, ai); 803168754Sbushman if (rv != 0) { 804168754Sbushman if (debug) 805168754Sbushman printf("not ok - addrinfo and hostent are not equal\n"); 806168754Sbushman return (-1); 807168754Sbushman } 808168754Sbushman 809168754Sbushman } 810168754Sbushman 811168754Sbushman return (0); 812168754Sbushman} 813168754Sbushman 814168754Sbushmanstatic int 815168754Sbushmanhostent_test_getnameinfo_eq(struct hostent *he, void *mdata) 816168754Sbushman{ 817168754Sbushman char buffer[NI_MAXHOST]; 818168754Sbushman struct sockaddr_in sin; 819168754Sbushman struct sockaddr_in6 sin6; 820168754Sbushman struct sockaddr *saddr; 821168754Sbushman struct hostent *result; 822168754Sbushman int rv; 823168754Sbushman 824168754Sbushman if (he->h_addr_list != NULL) { 825168754Sbushman char **cp; 826168754Sbushman for (cp = he->h_addr_list; *cp; ++cp) { 827168754Sbushman if (debug) 828168754Sbushman printf("doing reverse lookup for %s\n", he->h_name); 829168754Sbushman 830168754Sbushman result = __gethostbyaddr(*cp, he->h_length, 831168754Sbushman he->h_addrtype); 832168754Sbushman if (result != NULL) { 833168754Sbushman rv = hostent_test_correctness(result, NULL); 834168754Sbushman if (rv != 0) { 835168754Sbushman __freehostent(result); 836168754Sbushman return (rv); 837168754Sbushman } 838168754Sbushman } else { 839168754Sbushman if (debug) 840168754Sbushman printf("reverse lookup failed\n"); 841168754Sbushman } 842168754Sbushman 843168754Sbushman switch (he->h_addrtype) { 844168754Sbushman case AF_INET: 845168754Sbushman memset(&sin, 0, sizeof(struct sockaddr_in)); 846168754Sbushman sin.sin_len = sizeof(struct sockaddr_in); 847168754Sbushman sin.sin_family = AF_INET; 848168754Sbushman memcpy(&sin.sin_addr, *cp, he->h_length); 849168754Sbushman 850168754Sbushman saddr = (struct sockaddr *)&sin; 851168754Sbushman break; 852168754Sbushman case AF_INET6: 853168754Sbushman memset(&sin6, 0, sizeof(struct sockaddr_in6)); 854168754Sbushman sin6.sin6_len = sizeof(struct sockaddr_in6); 855168754Sbushman sin6.sin6_family = AF_INET6; 856168754Sbushman memcpy(&sin6.sin6_addr, *cp, he->h_length); 857168754Sbushman 858168754Sbushman saddr = (struct sockaddr *)&sin6; 859168754Sbushman break; 860168754Sbushman default: 861168754Sbushman if (debug) 862168754Sbushman printf("warning: %d family is unsupported\n", 863168754Sbushman he->h_addrtype); 864168754Sbushman continue; 865168754Sbushman } 866168754Sbushman 867168754Sbushman assert(saddr != NULL); 868168754Sbushman rv = getnameinfo(saddr, saddr->sa_len, buffer, 869168754Sbushman sizeof(buffer), NULL, 0, NI_NAMEREQD); 870168754Sbushman 871168754Sbushman if ((rv != 0) && (result != NULL)) { 872168754Sbushman if (debug) 873168754Sbushman printf("not ok - getnameinfo() didn't make the reverse lookup, when it should have (%s)\n", 874168754Sbushman gai_strerror(rv)); 875168754Sbushman return (rv); 876168754Sbushman } 877168754Sbushman 878168754Sbushman if ((rv == 0) && (result == NULL)) { 879168754Sbushman if (debug) 880168754Sbushman printf("not ok - getnameinfo() made the reverse lookup, when it shouldn't have\n"); 881168754Sbushman return (rv); 882168754Sbushman } 883168754Sbushman 884168754Sbushman if ((rv != 0) && (result == NULL)) { 885168754Sbushman if (debug) 886168754Sbushman printf("ok - both getnameinfo() and ***byaddr() failed\n"); 887168754Sbushman 888168754Sbushman continue; 889168754Sbushman } 890168754Sbushman 891168754Sbushman if (debug) 892168754Sbushman printf("comparing %s with %s\n", result->h_name, 893168754Sbushman buffer); 894168754Sbushman 895168754Sbushman rv = strcmp(result->h_name, buffer); 896168754Sbushman __freehostent(result); 897168754Sbushman 898168754Sbushman if (rv != 0) { 899168754Sbushman if (debug) 900168754Sbushman printf("not ok - getnameinfo() and ***byaddr() results are not equal\n"); 901168754Sbushman return (rv); 902168754Sbushman } else { 903168754Sbushman if (debug) 904168754Sbushman printf("ok - getnameinfo() and ***byaddr() results are equal\n"); 905168754Sbushman } 906168754Sbushman } 907168754Sbushman } 908168754Sbushman 909168754Sbushman return (0); 910168754Sbushman} 911168754Sbushman 912168754Sbushmanstatic void 913168754Sbushmanusage(void) 914168754Sbushman{ 915168754Sbushman (void)fprintf(stderr, 916171016Sbushman "Usage: %s -na2i [-o] [-d] [-46] [-mAcM] [-C] [-s <file>] -f <file>\n", 917168754Sbushman getprogname()); 918168754Sbushman exit(1); 919168754Sbushman} 920168754Sbushman 921168754Sbushmanint 922168754Sbushmanmain(int argc, char **argv) 923168754Sbushman{ 924168754Sbushman struct hostent_test_data td, td_addr, td_snap; 925168754Sbushman char *snapshot_file, *hostlist_file; 926168754Sbushman res_state statp; 927168754Sbushman int rv; 928168754Sbushman int c; 929168754Sbushman 930168754Sbushman if (argc < 2) 931168754Sbushman usage(); 932168754Sbushman 933168754Sbushman snapshot_file = NULL; 934168754Sbushman hostlist_file = NULL; 935171016Sbushman while ((c = getopt(argc, argv, "nad2iod46mAcMs:f:")) != -1) 936168754Sbushman switch (c) { 937168754Sbushman case '4': 938171016Sbushman af_type = AF_INET; 939171016Sbushman break; 940168754Sbushman case '6': 941171016Sbushman af_type = AF_INET6; 942171016Sbushman break; 943171016Sbushman case 'M': 944171016Sbushman af_type = AF_INET6; 945171016Sbushman use_ipv6_mapping = 1; 946171016Sbushman ipnode_flags |= AI_V4MAPPED_CFG; 947171016Sbushman break; 948168754Sbushman case 'm': 949171016Sbushman af_type = AF_INET6; 950171016Sbushman use_ipv6_mapping = 1; 951171016Sbushman ipnode_flags |= AI_V4MAPPED; 952168754Sbushman break; 953171016Sbushman case 'c': 954171016Sbushman ipnode_flags |= AI_ADDRCONFIG; 955171016Sbushman break; 956171016Sbushman case 'A': 957171016Sbushman ipnode_flags |= AI_ALL; 958171016Sbushman break; 959168754Sbushman case 'o': 960168754Sbushman use_ipnode_functions = 1; 961168754Sbushman break; 962168754Sbushman case 'd': 963168754Sbushman debug = 1; 964168754Sbushman break; 965168754Sbushman case 'n': 966168754Sbushman method = TEST_GETHOSTBYNAME2; 967168754Sbushman break; 968168754Sbushman case 'a': 969168754Sbushman method = TEST_GETHOSTBYADDR; 970168754Sbushman break; 971168754Sbushman case '2': 972168754Sbushman method = TEST_GETHOSTBYNAME2_GETADDRINFO; 973168754Sbushman break; 974168754Sbushman case 'i': 975168754Sbushman method = TEST_GETHOSTBYADDR_GETNAMEINFO; 976168754Sbushman break; 977168754Sbushman case 's': 978168754Sbushman snapshot_file = strdup(optarg); 979168754Sbushman break; 980168754Sbushman case 'f': 981168754Sbushman hostlist_file = strdup(optarg); 982168754Sbushman break; 983168754Sbushman default: 984168754Sbushman usage(); 985168754Sbushman } 986171016Sbushman 987171016Sbushman if (use_ipnode_functions == 0) { 988171016Sbushman statp = __res_state(); 989171016Sbushman if ((statp == NULL) || ((statp->options & RES_INIT) == 0 && 990171016Sbushman res_ninit(statp) == -1)) { 991171016Sbushman if (debug) 992171016Sbushman printf("error: can't init res_state\n"); 993171016Sbushman 994171016Sbushman free(snapshot_file); 995171016Sbushman free(hostlist_file); 996171016Sbushman return (-1); 997171016Sbushman } 998168754Sbushman 999171016Sbushman if (use_ipv6_mapping == 0) 1000171016Sbushman statp->options &= ~RES_USE_INET6; 1001171016Sbushman else 1002171016Sbushman statp->options |= RES_USE_INET6; 1003171016Sbushman } 1004171016Sbushman 1005168754Sbushman TEST_DATA_INIT(hostent, &td, clone_hostent, free_hostent); 1006168754Sbushman TEST_DATA_INIT(hostent, &td_addr, clone_hostent, free_hostent); 1007168754Sbushman TEST_DATA_INIT(hostent, &td_snap, clone_hostent, free_hostent); 1008168754Sbushman 1009168754Sbushman if (hostlist_file == NULL) 1010168754Sbushman usage(); 1011168754Sbushman 1012168754Sbushman if (access(hostlist_file, R_OK) != 0) { 1013168754Sbushman if (debug) 1014168754Sbushman printf("can't access the hostlist file %s\n", 1015168754Sbushman hostlist_file); 1016168754Sbushman 1017168754Sbushman usage(); 1018168754Sbushman } 1019168754Sbushman 1020168754Sbushman if (debug) 1021168754Sbushman printf("building host lists from %s\n", hostlist_file); 1022168754Sbushman 1023168754Sbushman rv = TEST_SNAPSHOT_FILE_READ(hostent, hostlist_file, &td, 1024168754Sbushman hostent_read_hostlist_func); 1025168754Sbushman if (rv != 0) 1026168754Sbushman goto fin; 1027168754Sbushman 1028168754Sbushman if (snapshot_file != NULL) { 1029168754Sbushman if (access(snapshot_file, W_OK | R_OK) != 0) { 1030168754Sbushman if (errno == ENOENT) { 1031168754Sbushman if (method != TEST_GETHOSTBYADDR) 1032168754Sbushman method = TEST_BUILD_SNAPSHOT; 1033168754Sbushman else 1034168754Sbushman method = TEST_BUILD_ADDR_SNAPSHOT; 1035168754Sbushman } else { 1036168754Sbushman if (debug) 1037168754Sbushman printf("can't access the snapshot file %s\n", 1038168754Sbushman snapshot_file); 1039168754Sbushman 1040168754Sbushman rv = -1; 1041168754Sbushman goto fin; 1042168754Sbushman } 1043168754Sbushman } else { 1044168754Sbushman rv = TEST_SNAPSHOT_FILE_READ(hostent, snapshot_file, 1045168754Sbushman &td_snap, hostent_read_snapshot_func); 1046168754Sbushman if (rv != 0) { 1047168754Sbushman if (debug) 1048168754Sbushman printf("error reading snapshot file\n"); 1049168754Sbushman goto fin; 1050168754Sbushman } 1051168754Sbushman } 1052168754Sbushman } 1053168754Sbushman 1054168754Sbushman switch (method) { 1055168754Sbushman case TEST_GETHOSTBYNAME2: 1056168754Sbushman if (snapshot_file != NULL) 1057168754Sbushman rv = DO_2PASS_TEST(hostent, &td, &td_snap, 1058168754Sbushman compare_hostent, NULL); 1059168754Sbushman break; 1060168754Sbushman case TEST_GETHOSTBYADDR: 1061168754Sbushman rv = DO_1PASS_TEST(hostent, &td, 1062168754Sbushman hostent_test_gethostbyaddr, (void *)&td_addr); 1063168754Sbushman 1064168754Sbushman if (snapshot_file != NULL) 1065168754Sbushman rv = DO_2PASS_TEST(hostent, &td_addr, &td_snap, 1066168754Sbushman compare_hostent, NULL); 1067168754Sbushman break; 1068168754Sbushman case TEST_GETHOSTBYNAME2_GETADDRINFO: 1069168754Sbushman rv = DO_1PASS_TEST(hostent, &td, 1070168754Sbushman hostent_test_getaddrinfo_eq, NULL); 1071168754Sbushman break; 1072168754Sbushman case TEST_GETHOSTBYADDR_GETNAMEINFO: 1073168754Sbushman rv = DO_1PASS_TEST(hostent, &td, 1074168754Sbushman hostent_test_getnameinfo_eq, NULL); 1075168754Sbushman break; 1076168754Sbushman case TEST_BUILD_SNAPSHOT: 1077168754Sbushman if (snapshot_file != NULL) { 1078168754Sbushman rv = TEST_SNAPSHOT_FILE_WRITE(hostent, snapshot_file, &td, 1079168754Sbushman sdump_hostent); 1080168754Sbushman } 1081168754Sbushman break; 1082168754Sbushman case TEST_BUILD_ADDR_SNAPSHOT: 1083168754Sbushman if (snapshot_file != NULL) { 1084168754Sbushman rv = DO_1PASS_TEST(hostent, &td, 1085168754Sbushman hostent_test_gethostbyaddr, (void *)&td_addr); 1086168754Sbushman 1087168754Sbushman rv = TEST_SNAPSHOT_FILE_WRITE(hostent, snapshot_file, 1088168754Sbushman &td_addr, sdump_hostent); 1089168754Sbushman } 1090168754Sbushman break; 1091168754Sbushman default: 1092168754Sbushman rv = 0; 1093168754Sbushman break; 1094168754Sbushman }; 1095168754Sbushman 1096168754Sbushmanfin: 1097168754Sbushman TEST_DATA_DESTROY(hostent, &td_snap); 1098168754Sbushman TEST_DATA_DESTROY(hostent, &td_addr); 1099168754Sbushman TEST_DATA_DESTROY(hostent, &td); 1100168754Sbushman free(hostlist_file); 1101168754Sbushman free(snapshot_file); 1102171016Sbushman 1103168754Sbushman return (rv); 1104168754Sbushman} 1105171016Sbushman 1106