gethostnamadr.c revision 158477
11573Srgrimes/*- 23070Spst * Copyright (c) 1994, Garrett Wollman 31573Srgrimes * 41573Srgrimes * Redistribution and use in source and binary forms, with or without 51573Srgrimes * modification, are permitted provided that the following conditions 61573Srgrimes * are met: 71573Srgrimes * 1. Redistributions of source code must retain the above copyright 81573Srgrimes * notice, this list of conditions and the following disclaimer. 91573Srgrimes * 2. Redistributions in binary form must reproduce the above copyright 101573Srgrimes * notice, this list of conditions and the following disclaimer in the 111573Srgrimes * documentation and/or other materials provided with the distribution. 121573Srgrimes * 133070Spst * THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS ``AS IS'' AND 141573Srgrimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 151573Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 161573Srgrimes * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 171573Srgrimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 181573Srgrimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 191573Srgrimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 201573Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 211573Srgrimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 221573Srgrimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 231573Srgrimes * SUCH DAMAGE. 241573Srgrimes */ 251573Srgrimes 2692986Sobrien#include <sys/cdefs.h> 2792986Sobrien__FBSDID("$FreeBSD: head/lib/libc/net/gethostnamadr.c 158477 2006-05-12 15:37:23Z ume $"); 281573Srgrimes 29113977Snectar#include "namespace.h" 30145633Sume#include "reentrant.h" 311573Srgrimes#include <sys/param.h> 321573Srgrimes#include <sys/socket.h> 331573Srgrimes#include <netinet/in.h> 341573Srgrimes#include <arpa/inet.h> 351573Srgrimes#include <netdb.h> 361573Srgrimes#include <stdio.h> 371573Srgrimes#include <ctype.h> 38145512Sume#include <errno.h> 39145633Sume#include <stdlib.h> 401573Srgrimes#include <string.h> 4165532Snectar#include <stdarg.h> 4265532Snectar#include <nsswitch.h> 4317903Speter#include <arpa/nameser.h> /* XXX hack for _res */ 4417903Speter#include <resolv.h> /* XXX hack for _res */ 45113977Snectar#include "un-namespace.h" 46145602Sume#include "netdb_private.h" 47158115Sume#ifdef NS_CACHING 48158115Sume#include "nscache.h" 49158115Sume#endif 501573Srgrimes 5165532Snectarextern int _ht_gethostbyname(void *, void *, va_list); 5265532Snectarextern int _dns_gethostbyname(void *, void *, va_list); 5365532Snectarextern int _nis_gethostbyname(void *, void *, va_list); 5465532Snectarextern int _ht_gethostbyaddr(void *, void *, va_list); 5565532Snectarextern int _dns_gethostbyaddr(void *, void *, va_list); 5665532Snectarextern int _nis_gethostbyaddr(void *, void *, va_list); 571991Swollman 58157779Sumestatic int gethostbyname_internal(const char *, int, struct hostent *, char *, 59157779Sume size_t, struct hostent **, int *, res_state); 60145512Sume 6165532Snectar/* Host lookup order if nsswitch.conf is broken or nonexistant */ 62145512Sumestatic const ns_src default_src[] = { 6365532Snectar { NSSRC_FILES, NS_SUCCESS }, 6465532Snectar { NSSRC_DNS, NS_SUCCESS }, 6565532Snectar { 0 } 661991Swollman}; 67158115Sume#ifdef NS_CACHING 68158115Sumestatic int host_id_func(char *, size_t *, va_list, void *); 69158115Sumestatic int host_marshal_func(char *, size_t *, void *, va_list, void *); 70158115Sumestatic int host_unmarshal_func(char *, size_t, void *, va_list, void *); 71158115Sume#endif 721991Swollman 73157779SumeNETDB_THREAD_ALLOC(hostent) 74157779SumeNETDB_THREAD_ALLOC(hostent_data) 75157779SumeNETDB_THREAD_ALLOC(hostdata) 76145633Sume 77145633Sumestatic void 78157779Sumehostent_free(void *ptr) 791991Swollman{ 80157779Sume free(ptr); 81157779Sume} 8217903Speter 83157779Sumestatic void 84157779Sumehostent_data_free(void *ptr) 85157779Sume{ 86157779Sume struct hostent_data *hed = ptr; 87157779Sume 88157779Sume if (hed == NULL) 89145633Sume return; 90157779Sume hed->stayopen = 0; 91157779Sume _endhosthtent(hed); 92157779Sume free(hed); 93145633Sume} 94145633Sume 95145633Sumestatic void 96157779Sumehostdata_free(void *ptr) 97145633Sume{ 98157779Sume free(ptr); 99145633Sume} 100145633Sume 101157779Sumeint 102157779Sume__copy_hostent(struct hostent *he, struct hostent *hptr, char *buf, 103157779Sume size_t buflen) 104145633Sume{ 105157779Sume char *cp; 106157779Sume char **ptr; 107157779Sume int i, n; 108157779Sume int nptr, len; 109145633Sume 110157779Sume /* Find out the amount of space required to store the answer. */ 111157779Sume nptr = 2; /* NULL ptrs */ 112157779Sume len = (char *)ALIGN(buf) - buf; 113157779Sume for (i = 0; he->h_addr_list[i]; i++, nptr++) { 114157779Sume len += he->h_length; 115157779Sume } 116157779Sume for (i = 0; he->h_aliases[i]; i++, nptr++) { 117157779Sume len += strlen(he->h_aliases[i]) + 1; 118157779Sume } 119157779Sume len += strlen(he->h_name) + 1; 120157779Sume len += nptr * sizeof(char*); 121157779Sume 122157779Sume if (len > buflen) { 123157779Sume errno = ERANGE; 124157779Sume return (-1); 125157779Sume } 126157779Sume 127157779Sume /* copy address size and type */ 128157779Sume hptr->h_addrtype = he->h_addrtype; 129157779Sume n = hptr->h_length = he->h_length; 130157779Sume 131157779Sume ptr = (char **)ALIGN(buf); 132157779Sume cp = (char *)ALIGN(buf) + nptr * sizeof(char *); 133157779Sume 134157779Sume /* copy address list */ 135157779Sume hptr->h_addr_list = ptr; 136157779Sume for (i = 0; he->h_addr_list[i]; i++ , ptr++) { 137157779Sume memcpy(cp, he->h_addr_list[i], n); 138157779Sume hptr->h_addr_list[i] = cp; 139157779Sume cp += n; 140157779Sume } 141157779Sume hptr->h_addr_list[i] = NULL; 142157779Sume ptr++; 143157779Sume 144157779Sume /* copy official name */ 145157779Sume n = strlen(he->h_name) + 1; 146157779Sume strcpy(cp, he->h_name); 147157779Sume hptr->h_name = cp; 148157779Sume cp += n; 149157779Sume 150157779Sume /* copy aliases */ 151157779Sume hptr->h_aliases = ptr; 152157779Sume for (i = 0 ; he->h_aliases[i]; i++) { 153157779Sume n = strlen(he->h_aliases[i]) + 1; 154157779Sume strcpy(cp, he->h_aliases[i]); 155157779Sume hptr->h_aliases[i] = cp; 156157779Sume cp += n; 157157779Sume } 158157779Sume hptr->h_aliases[i] = NULL; 159157779Sume 160157779Sume return (0); 161145633Sume} 162145633Sume 163158115Sume#ifdef NS_CACHING 164157779Sumestatic int 165158115Sumehost_id_func(char *buffer, size_t *buffer_size, va_list ap, void *cache_mdata) 166158115Sume{ 167158115Sume res_state statp; 168158115Sume u_long res_options; 169158115Sume 170158115Sume const int op_id = 1; 171158115Sume char *str; 172158115Sume int len, type; 173158115Sume 174158115Sume size_t desired_size, size; 175158115Sume enum nss_lookup_type lookup_type; 176158115Sume char *p; 177158115Sume int res = NS_UNAVAIL; 178158115Sume 179158115Sume statp = __res_state(); 180158115Sume res_options = statp->options & (RES_RECURSE | RES_DEFNAMES | 181158115Sume RES_DNSRCH | RES_NOALIASES | RES_USE_INET6); 182158115Sume 183158115Sume lookup_type = (enum nss_lookup_type)cache_mdata; 184158115Sume switch (lookup_type) { 185158115Sume case nss_lt_name: 186158115Sume str = va_arg(ap, char *); 187158115Sume type = va_arg(ap, int); 188158115Sume 189158115Sume size = strlen(str); 190158115Sume desired_size = sizeof(res_options) + sizeof(int) + 191158115Sume sizeof(enum nss_lookup_type) + sizeof(int) + size + 1; 192158115Sume 193158115Sume if (desired_size > *buffer_size) { 194158115Sume res = NS_RETURN; 195158115Sume goto fin; 196158115Sume } 197158115Sume 198158115Sume p = buffer; 199158115Sume 200158115Sume memcpy(p, &res_options, sizeof(res_options)); 201158115Sume p += sizeof(res_options); 202158115Sume 203158115Sume memcpy(p, &op_id, sizeof(int)); 204158115Sume p += sizeof(int); 205158115Sume 206158115Sume memcpy(p, &lookup_type, sizeof(enum nss_lookup_type)); 207158115Sume p += sizeof(int); 208158115Sume 209158115Sume memcpy(p, &type, sizeof(int)); 210158115Sume p += sizeof(int); 211158115Sume 212158115Sume memcpy(p, str, size + 1); 213158115Sume 214158115Sume res = NS_SUCCESS; 215158115Sume break; 216158115Sume case nss_lt_id: 217158115Sume str = va_arg(ap, char *); 218158115Sume len = va_arg(ap, int); 219158115Sume type = va_arg(ap, int); 220158115Sume 221158115Sume desired_size = sizeof(res_options) + sizeof(int) + 222158115Sume sizeof(enum nss_lookup_type) + sizeof(int) * 2 + len; 223158115Sume 224158115Sume if (desired_size > *buffer_size) { 225158115Sume res = NS_RETURN; 226158115Sume goto fin; 227158115Sume } 228158115Sume 229158115Sume p = buffer; 230158115Sume memcpy(p, &res_options, sizeof(res_options)); 231158115Sume p += sizeof(res_options); 232158115Sume 233158115Sume memcpy(p, &op_id, sizeof(int)); 234158115Sume p += sizeof(int); 235158115Sume 236158115Sume memcpy(p, &lookup_type, sizeof(enum nss_lookup_type)); 237158115Sume p += sizeof(int); 238158115Sume 239158115Sume memcpy(p, &type, sizeof(int)); 240158115Sume p += sizeof(int); 241158115Sume 242158115Sume memcpy(p, &len, sizeof(int)); 243158115Sume p += sizeof(int); 244158115Sume 245158115Sume memcpy(p, str, len); 246158115Sume 247158115Sume res = NS_SUCCESS; 248158115Sume break; 249158115Sume default: 250158115Sume /* should be unreachable */ 251158115Sume return (NS_UNAVAIL); 252158115Sume } 253158115Sume 254158115Sumefin: 255158115Sume *buffer_size = desired_size; 256158115Sume return (res); 257158115Sume} 258158115Sume 259158115Sumestatic int 260158115Sumehost_marshal_func(char *buffer, size_t *buffer_size, void *retval, va_list ap, 261158115Sume void *cache_mdata) 262158115Sume{ 263158115Sume char *str; 264158115Sume int len, type; 265158115Sume struct hostent *ht; 266158115Sume 267158115Sume struct hostent new_ht; 268158115Sume size_t desired_size, aliases_size, addr_size, size; 269158115Sume char *p, **iter; 270158115Sume 271158115Sume switch ((enum nss_lookup_type)cache_mdata) { 272158115Sume case nss_lt_name: 273158115Sume str = va_arg(ap, char *); 274158115Sume type = va_arg(ap, int); 275158115Sume break; 276158115Sume case nss_lt_id: 277158115Sume str = va_arg(ap, char *); 278158115Sume len = va_arg(ap, int); 279158115Sume type = va_arg(ap, int); 280158115Sume break; 281158115Sume default: 282158115Sume /* should be unreachable */ 283158115Sume return (NS_UNAVAIL); 284158115Sume } 285158115Sume ht = va_arg(ap, struct hostent *); 286158115Sume 287158115Sume desired_size = _ALIGNBYTES + sizeof(struct hostent) + sizeof(char *); 288158115Sume if (ht->h_name != NULL) 289158115Sume desired_size += strlen(ht->h_name) + 1; 290158115Sume 291158115Sume if (ht->h_aliases != NULL) { 292158115Sume aliases_size = 0; 293158115Sume for (iter = ht->h_aliases; *iter; ++iter) { 294158115Sume desired_size += strlen(*iter) + 1; 295158115Sume ++aliases_size; 296158115Sume } 297158115Sume 298158115Sume desired_size += _ALIGNBYTES + 299158115Sume (aliases_size + 1) * sizeof(char *); 300158115Sume } 301158115Sume 302158115Sume if (ht->h_addr_list != NULL) { 303158115Sume addr_size = 0; 304158115Sume for (iter = ht->h_addr_list; *iter; ++iter) 305158115Sume ++addr_size; 306158115Sume 307158115Sume desired_size += addr_size * _ALIGN(ht->h_length); 308158115Sume desired_size += _ALIGNBYTES + (addr_size + 1) * sizeof(char *); 309158115Sume } 310158115Sume 311158115Sume if (desired_size > *buffer_size) { 312158115Sume /* this assignment is here for future use */ 313158115Sume *buffer_size = desired_size; 314158115Sume return (NS_RETURN); 315158115Sume } 316158115Sume 317158115Sume memcpy(&new_ht, ht, sizeof(struct hostent)); 318158115Sume memset(buffer, 0, desired_size); 319158115Sume 320158115Sume *buffer_size = desired_size; 321158115Sume p = buffer + sizeof(struct hostent) + sizeof(char *); 322158115Sume memcpy(buffer + sizeof(struct hostent), &p, sizeof(char *)); 323158115Sume p = (char *)_ALIGN(p); 324158115Sume 325158115Sume if (new_ht.h_name != NULL) { 326158115Sume size = strlen(new_ht.h_name); 327158115Sume memcpy(p, new_ht.h_name, size); 328158115Sume new_ht.h_name = p; 329158115Sume p += size + 1; 330158115Sume } 331158115Sume 332158115Sume if (new_ht.h_aliases != NULL) { 333158115Sume p = (char *)_ALIGN(p); 334158115Sume memcpy(p, new_ht.h_aliases, sizeof(char *) * aliases_size); 335158115Sume new_ht.h_aliases = (char **)p; 336158115Sume p += sizeof(char *) * (aliases_size + 1); 337158115Sume 338158115Sume for (iter = new_ht.h_aliases; *iter; ++iter) { 339158115Sume size = strlen(*iter); 340158115Sume memcpy(p, *iter, size); 341158115Sume *iter = p; 342158115Sume p += size + 1; 343158115Sume } 344158115Sume } 345158115Sume 346158115Sume if (new_ht.h_addr_list != NULL) { 347158115Sume p = (char *)_ALIGN(p); 348158115Sume memcpy(p, new_ht.h_addr_list, sizeof(char *) * addr_size); 349158115Sume new_ht.h_addr_list = (char **)p; 350158115Sume p += sizeof(char *) * (addr_size + 1); 351158115Sume 352158115Sume size = _ALIGN(new_ht.h_length); 353158115Sume for (iter = new_ht.h_addr_list; *iter; ++iter) { 354158115Sume memcpy(p, *iter, size); 355158115Sume *iter = p; 356158115Sume p += size + 1; 357158115Sume } 358158115Sume } 359158115Sume memcpy(buffer, &new_ht, sizeof(struct hostent)); 360158115Sume return (NS_SUCCESS); 361158115Sume} 362158115Sume 363158115Sumestatic int 364158115Sumehost_unmarshal_func(char *buffer, size_t buffer_size, void *retval, va_list ap, 365158115Sume void *cache_mdata) 366158115Sume{ 367158115Sume char *str; 368158115Sume int len, type; 369158115Sume struct hostent *ht; 370158115Sume 371158115Sume char *p; 372158115Sume char **iter; 373158115Sume char *orig_buf; 374158115Sume size_t orig_buf_size; 375158115Sume 376158115Sume switch ((enum nss_lookup_type)cache_mdata) { 377158115Sume case nss_lt_name: 378158115Sume str = va_arg(ap, char *); 379158115Sume type = va_arg(ap, int); 380158115Sume break; 381158115Sume case nss_lt_id: 382158115Sume str = va_arg(ap, char *); 383158115Sume len = va_arg(ap, int); 384158115Sume type = va_arg(ap, int); 385158115Sume break; 386158115Sume default: 387158115Sume /* should be unreachable */ 388158115Sume return (NS_UNAVAIL); 389158115Sume } 390158115Sume 391158115Sume ht = va_arg(ap, struct hostent *); 392158115Sume orig_buf = va_arg(ap, char *); 393158115Sume orig_buf_size = va_arg(ap, size_t); 394158115Sume 395158115Sume if (orig_buf_size < 396158115Sume buffer_size - sizeof(struct hostent) - sizeof(char *)) { 397158115Sume errno = ERANGE; 398158115Sume return (NS_RETURN); 399158115Sume } 400158115Sume 401158115Sume memcpy(ht, buffer, sizeof(struct hostent)); 402158115Sume memcpy(&p, buffer + sizeof(struct hostent), sizeof(char *)); 403158115Sume 404158115Sume orig_buf = (char *)_ALIGN(orig_buf); 405158115Sume memcpy(orig_buf, buffer + sizeof(struct hostent) + sizeof(char *) + 406158115Sume _ALIGN(p) - (size_t)p, 407158115Sume buffer_size - sizeof(struct hostent) - sizeof(char *) - 408158115Sume _ALIGN(p) + (size_t)p); 409158115Sume p = (char *)_ALIGN(p); 410158115Sume 411158115Sume NS_APPLY_OFFSET(ht->h_name, orig_buf, p, char *); 412158115Sume if (ht->h_aliases != NULL) { 413158115Sume NS_APPLY_OFFSET(ht->h_aliases, orig_buf, p, char **); 414158115Sume 415158115Sume for (iter = ht->h_aliases; *iter; ++iter) 416158115Sume NS_APPLY_OFFSET(*iter, orig_buf, p, char *); 417158115Sume } 418158115Sume 419158115Sume if (ht->h_addr_list != NULL) { 420158115Sume NS_APPLY_OFFSET(ht->h_addr_list, orig_buf, p, char **); 421158115Sume 422158115Sume for (iter = ht->h_addr_list; *iter; ++iter) 423158115Sume NS_APPLY_OFFSET(*iter, orig_buf, p, char *); 424158115Sume } 425158115Sume 426158115Sume *((struct hostent **)retval) = ht; 427158115Sume return (NS_SUCCESS); 428158115Sume} 429158115Sume#endif /* NS_CACHING */ 430158115Sume 431158115Sumestatic int 432157779Sumefakeaddr(const char *name, int af, struct hostent *hp, char *buf, 433158115Sume size_t buflen, res_state statp) 434157779Sume{ 435157779Sume struct hostent_data *hed; 436157779Sume struct hostent he; 437157779Sume 438157779Sume if ((hed = __hostent_data_init()) == NULL) { 439157779Sume errno = ENOMEM; 440157779Sume RES_SET_H_ERRNO(statp, NETDB_INTERNAL); 441157779Sume return (-1); 442157779Sume } 443157779Sume 444157779Sume if ((af != AF_INET || 445157779Sume inet_aton(name, (struct in_addr *)hed->host_addr) != 1) && 446157779Sume inet_pton(af, name, hed->host_addr) != 1) { 447157779Sume RES_SET_H_ERRNO(statp, HOST_NOT_FOUND); 448157779Sume return (-1); 449157779Sume } 450157779Sume strncpy(hed->hostbuf, name, MAXDNAME); 451157779Sume hed->hostbuf[MAXDNAME] = '\0'; 452157779Sume if (af == AF_INET && (statp->options & RES_USE_INET6) != 0U) { 453157779Sume _map_v4v6_address((char *)hed->host_addr, 454157779Sume (char *)hed->host_addr); 455157779Sume af = AF_INET6; 456157779Sume } 457157779Sume he.h_addrtype = af; 458157779Sume switch(af) { 459157779Sume case AF_INET: 460157779Sume he.h_length = NS_INADDRSZ; 461157779Sume break; 462157779Sume case AF_INET6: 463157779Sume he.h_length = NS_IN6ADDRSZ; 464157779Sume break; 465157779Sume default: 466157779Sume errno = EAFNOSUPPORT; 467157779Sume RES_SET_H_ERRNO(statp, NETDB_INTERNAL); 468157779Sume return (-1); 469157779Sume } 470157779Sume he.h_name = hed->hostbuf; 471157779Sume he.h_aliases = hed->host_aliases; 472157779Sume hed->host_aliases[0] = NULL; 473157779Sume hed->h_addr_ptrs[0] = (char *)hed->host_addr; 474157779Sume hed->h_addr_ptrs[1] = NULL; 475157779Sume he.h_addr_list = hed->h_addr_ptrs; 476157779Sume RES_SET_H_ERRNO(statp, NETDB_SUCCESS); 477157779Sume return (__copy_hostent(&he, hp, buf, buflen)); 478157779Sume} 479157779Sume 480145633Sumeint 481157779Sumegethostbyname_r(const char *name, struct hostent *he, char *buffer, 482157779Sume size_t buflen, struct hostent **result, int *h_errnop) 483145633Sume{ 484157779Sume res_state statp; 485145633Sume 486157779Sume statp = __res_state(); 487157779Sume if ((statp->options & RES_INIT) == 0 && res_ninit(statp) == -1) { 488157779Sume RES_SET_H_ERRNO(statp, NETDB_INTERNAL); 489157779Sume return (-1); 49067709Sume } 491157779Sume if (statp->options & RES_USE_INET6) { 492157779Sume if (fakeaddr(name, AF_INET, he, buffer, buflen, statp) == 0) { 493157779Sume *result = he; 494157779Sume return (0); 495157779Sume } 496157779Sume if (gethostbyname_internal(name, AF_INET6, he, buffer, buflen, 497157779Sume result, h_errnop, statp) == 0) 498157779Sume return (0); 499145512Sume } 500157779Sume return (gethostbyname_internal(name, AF_INET, he, buffer, buflen, 501157779Sume result, h_errnop, statp)); 50217903Speter} 50317903Speter 504145633Sumeint 505157779Sumegethostbyname2_r(const char *name, int af, struct hostent *he, char *buffer, 506157779Sume size_t buflen, struct hostent **result, int *h_errnop) 50717903Speter{ 508157779Sume res_state statp; 509157779Sume 510157779Sume statp = __res_state(); 511157779Sume if ((statp->options & RES_INIT) == 0 && res_ninit(statp) == -1) { 512157779Sume RES_SET_H_ERRNO(statp, NETDB_INTERNAL); 513157779Sume return (-1); 514145512Sume } 515157779Sume return (gethostbyname_internal(name, af, he, buffer, buflen, result, 516157779Sume h_errnop, statp)); 517145512Sume} 518145512Sume 519157779Sumeint 520157779Sumegethostbyname_internal(const char *name, int af, struct hostent *hp, char *buf, 521157779Sume size_t buflen, struct hostent **result, int *h_errnop, res_state statp) 522145512Sume{ 523145512Sume const char *cp; 524157779Sume int rval, ret_errno; 525145512Sume char abuf[MAXDNAME]; 5261991Swollman 527158115Sume#ifdef NS_CACHING 528158115Sume static const nss_cache_info cache_info = 529158115Sume NS_COMMON_CACHE_INFO_INITIALIZER( 530158115Sume hosts, (void *)nss_lt_name, 531158115Sume host_id_func, host_marshal_func, host_unmarshal_func); 532158115Sume#endif 53365532Snectar static const ns_dtab dtab[] = { 53465532Snectar NS_FILES_CB(_ht_gethostbyname, NULL) 53565532Snectar { NSSRC_DNS, _dns_gethostbyname, NULL }, 53665532Snectar NS_NIS_CB(_nis_gethostbyname, NULL) /* force -DHESIOD */ 537158115Sume#ifdef NS_CACHING 538158115Sume NS_CACHE_CB(&cache_info) 539158115Sume#endif 54065532Snectar { 0 } 541145512Sume }; 542145512Sume 543145512Sume switch (af) { 544145512Sume case AF_INET: 545145512Sume case AF_INET6: 546145512Sume break; 547145512Sume default: 548157779Sume RES_SET_H_ERRNO(statp, NETDB_INTERNAL); 549157779Sume *h_errnop = statp->res_h_errno; 550145512Sume errno = EAFNOSUPPORT; 551157779Sume return (-1); 552145512Sume } 553145512Sume 554145512Sume /* 555145512Sume * if there aren't any dots, it could be a user-level alias. 556145512Sume * this is also done in res_query() since we are not the only 557145512Sume * function that looks up host names. 558145512Sume */ 559145512Sume if (!strchr(name, '.') && 560157779Sume (cp = res_hostalias(statp, name, abuf, sizeof abuf))) 561145512Sume name = cp; 562145512Sume 563157779Sume if (fakeaddr(name, af, hp, buf, buflen, statp) == 0) { 564157779Sume *result = hp; 565157779Sume return (0); 566157779Sume } 567145512Sume 568157779Sume rval = _nsdispatch((void *)result, dtab, NSDB_HOSTS, 569157779Sume "gethostbyname2_r", default_src, name, af, hp, buf, buflen, 570157779Sume &ret_errno, h_errnop); 5711991Swollman 572157779Sume return ((rval == NS_SUCCESS) ? 0 : -1); 5731991Swollman} 5741991Swollman 575145633Sumeint 576158477Sumegethostbyaddr_r(const void *addr, 577158477Sume#if __LONG_BIT == 64 578158477Sume int len, 579158477Sume#else 580158477Sume socklen_t len, 581158477Sume#endif 582158477Sume int af, struct hostent *hp, char *buf, size_t buflen, 583158477Sume struct hostent **result, int *h_errnop) 5841991Swollman{ 585145687Sume const u_char *uaddr = (const u_char *)addr; 586145687Sume const struct in6_addr *addr6; 587145687Sume socklen_t size; 588157779Sume int rval, ret_errno; 589157779Sume res_state statp; 5901991Swollman 591158115Sume#ifdef NS_CACHING 592158115Sume static const nss_cache_info cache_info = 593158115Sume NS_COMMON_CACHE_INFO_INITIALIZER( 594158115Sume hosts, (void *)nss_lt_id, 595158115Sume host_id_func, host_marshal_func, host_unmarshal_func); 596158115Sume#endif 59765532Snectar static const ns_dtab dtab[] = { 59865532Snectar NS_FILES_CB(_ht_gethostbyaddr, NULL) 59965532Snectar { NSSRC_DNS, _dns_gethostbyaddr, NULL }, 60065532Snectar NS_NIS_CB(_nis_gethostbyaddr, NULL) /* force -DHESIOD */ 601158115Sume#ifdef NS_CACHING 602158115Sume NS_CACHE_CB(&cache_info) 603158115Sume#endif 60465532Snectar { 0 } 605145633Sume }; 6061991Swollman 607157779Sume statp = __res_state(); 608157779Sume if ((statp->options & RES_INIT) == 0 && res_ninit(statp) == -1) { 609157779Sume RES_SET_H_ERRNO(statp, NETDB_INTERNAL); 610157779Sume *h_errnop = statp->res_h_errno; 611157779Sume return (-1); 612145728Sume } 613145728Sume 614157779Sume if (af == AF_INET6 && len == NS_IN6ADDRSZ) { 615158477Sume addr6 = (const struct in6_addr *)addr; 616145687Sume if (IN6_IS_ADDR_LINKLOCAL(addr6)) { 617157779Sume RES_SET_H_ERRNO(statp, HOST_NOT_FOUND); 618157779Sume *h_errnop = statp->res_h_errno; 619157779Sume return (-1); 620145687Sume } 621145687Sume if (IN6_IS_ADDR_V4MAPPED(addr6) || 622145687Sume IN6_IS_ADDR_V4COMPAT(addr6)) { 623145687Sume /* Unmap. */ 624157779Sume uaddr += NS_IN6ADDRSZ - NS_INADDRSZ; 625145687Sume af = AF_INET; 626157779Sume len = NS_INADDRSZ; 627145687Sume } 628145687Sume } 629145687Sume switch (af) { 630145687Sume case AF_INET: 631157779Sume size = NS_INADDRSZ; 632145687Sume break; 633145687Sume case AF_INET6: 634157779Sume size = NS_IN6ADDRSZ; 635145687Sume break; 636145687Sume default: 637145687Sume errno = EAFNOSUPPORT; 638157779Sume RES_SET_H_ERRNO(statp, NETDB_INTERNAL); 639157779Sume *h_errnop = statp->res_h_errno; 640157779Sume return (-1); 641145687Sume } 642145687Sume if (size != len) { 643145687Sume errno = EINVAL; 644157779Sume RES_SET_H_ERRNO(statp, NETDB_INTERNAL); 645157779Sume *h_errnop = statp->res_h_errno; 646157779Sume return (-1); 647145687Sume } 648145687Sume 649157779Sume rval = _nsdispatch((void *)result, dtab, NSDB_HOSTS, 650157779Sume "gethostbyaddr_r", default_src, uaddr, len, af, hp, buf, buflen, 651157779Sume &ret_errno, h_errnop); 65265532Snectar 653157779Sume return ((rval == NS_SUCCESS) ? 0 : -1); 6541991Swollman} 6551991Swollman 656145633Sumestruct hostent * 657145633Sumegethostbyname(const char *name) 658145633Sume{ 659145633Sume struct hostdata *hd; 660157779Sume struct hostent *rval; 661157779Sume int ret_h_errno; 662145633Sume 663145633Sume if ((hd = __hostdata_init()) == NULL) 664157779Sume return (NULL); 665157779Sume if (gethostbyname_r(name, &hd->host, hd->data, sizeof(hd->data), &rval, 666157779Sume &ret_h_errno) != 0) 667157779Sume return (NULL); 668157779Sume return (rval); 669145633Sume} 670145633Sume 671145633Sumestruct hostent * 672145633Sumegethostbyname2(const char *name, int af) 673145633Sume{ 674145633Sume struct hostdata *hd; 675157779Sume struct hostent *rval; 676157779Sume int ret_h_errno; 677145633Sume 678145633Sume if ((hd = __hostdata_init()) == NULL) 679157779Sume return (NULL); 680157779Sume if (gethostbyname2_r(name, af, &hd->host, hd->data, sizeof(hd->data), 681157779Sume &rval, &ret_h_errno) != 0) 682157779Sume return (NULL); 683157779Sume return (rval); 684145633Sume} 685145633Sume 686145633Sumestruct hostent * 687158477Sume#if __LONG_BIT == 64 688158477Sumegethostbyaddr(const void *addr, int len, int af) 689158477Sume#else 690158477Sumegethostbyaddr(const void *addr, socklen_t len, int af) 691158477Sume#endif 692145633Sume{ 693145633Sume struct hostdata *hd; 694157779Sume struct hostent *rval; 695157779Sume int ret_h_errno; 696145633Sume 697145633Sume if ((hd = __hostdata_init()) == NULL) 698157779Sume return (NULL); 699157779Sume if (gethostbyaddr_r(addr, len, af, &hd->host, hd->data, 700157779Sume sizeof(hd->data), &rval, &ret_h_errno) != 0) 701157779Sume return (NULL); 702157779Sume return (rval); 703145633Sume} 704145633Sume 705145633Sumevoid 706145633Sumesethostent(int stayopen) 707145633Sume{ 708157779Sume struct hostent_data *hed; 709145633Sume 710157779Sume if ((hed = __hostent_data_init()) == NULL) 711145633Sume return; 712157779Sume _sethosthtent(stayopen, hed); 713157779Sume _sethostdnsent(stayopen); 714145633Sume} 715145633Sume 716145633Sumevoid 717145633Sumeendhostent(void) 718145633Sume{ 719157779Sume struct hostent_data *hed; 720145633Sume 721157779Sume if ((hed = __hostent_data_init()) == NULL) 722145633Sume return; 723157779Sume _endhosthtent(hed); 724157779Sume _endhostdnsent(); 725145633Sume} 726