10Sstevel@tonic-gate /* 20Sstevel@tonic-gate * Copyright (c) 1985, 1988, 1993 30Sstevel@tonic-gate * The Regents of the University of California. All rights reserved. 40Sstevel@tonic-gate * 50Sstevel@tonic-gate * Redistribution and use in source and binary forms, with or without 60Sstevel@tonic-gate * modification, are permitted provided that the following conditions 70Sstevel@tonic-gate * are met: 80Sstevel@tonic-gate * 1. Redistributions of source code must retain the above copyright 90Sstevel@tonic-gate * notice, this list of conditions and the following disclaimer. 100Sstevel@tonic-gate * 2. Redistributions in binary form must reproduce the above copyright 110Sstevel@tonic-gate * notice, this list of conditions and the following disclaimer in the 120Sstevel@tonic-gate * documentation and/or other materials provided with the distribution. 130Sstevel@tonic-gate * 3. All advertising materials mentioning features or use of this software 140Sstevel@tonic-gate * must display the following acknowledgement: 150Sstevel@tonic-gate * This product includes software developed by the University of 160Sstevel@tonic-gate * California, Berkeley and its contributors. 170Sstevel@tonic-gate * 4. Neither the name of the University nor the names of its contributors 180Sstevel@tonic-gate * may be used to endorse or promote products derived from this software 190Sstevel@tonic-gate * without specific prior written permission. 200Sstevel@tonic-gate * 210Sstevel@tonic-gate * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 220Sstevel@tonic-gate * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 230Sstevel@tonic-gate * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 240Sstevel@tonic-gate * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 250Sstevel@tonic-gate * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 260Sstevel@tonic-gate * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 270Sstevel@tonic-gate * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 280Sstevel@tonic-gate * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 290Sstevel@tonic-gate * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 300Sstevel@tonic-gate * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 310Sstevel@tonic-gate * SUCH DAMAGE. 320Sstevel@tonic-gate */ 330Sstevel@tonic-gate 340Sstevel@tonic-gate /* 35*11038SRao.Shoaib@Sun.COM * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC") 360Sstevel@tonic-gate * Portions Copyright (c) 1996-1999 by Internet Software Consortium. 370Sstevel@tonic-gate * 380Sstevel@tonic-gate * Permission to use, copy, modify, and distribute this software for any 390Sstevel@tonic-gate * purpose with or without fee is hereby granted, provided that the above 400Sstevel@tonic-gate * copyright notice and this permission notice appear in all copies. 410Sstevel@tonic-gate * 42*11038SRao.Shoaib@Sun.COM * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES 43*11038SRao.Shoaib@Sun.COM * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 44*11038SRao.Shoaib@Sun.COM * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR 45*11038SRao.Shoaib@Sun.COM * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 46*11038SRao.Shoaib@Sun.COM * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 47*11038SRao.Shoaib@Sun.COM * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT 48*11038SRao.Shoaib@Sun.COM * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 490Sstevel@tonic-gate */ 500Sstevel@tonic-gate 510Sstevel@tonic-gate /* from gethostnamadr.c 8.1 (Berkeley) 6/4/93 */ 520Sstevel@tonic-gate /* BIND Id: gethnamaddr.c,v 8.15 1996/05/22 04:56:30 vixie Exp $ */ 530Sstevel@tonic-gate 540Sstevel@tonic-gate #if defined(LIBC_SCCS) && !defined(lint) 55*11038SRao.Shoaib@Sun.COM static const char rcsid[] = "$Id: lcl_ho.c,v 1.5 2006/03/09 23:57:56 marka Exp $"; 560Sstevel@tonic-gate #endif /* LIBC_SCCS and not lint */ 570Sstevel@tonic-gate 580Sstevel@tonic-gate /* Imports. */ 590Sstevel@tonic-gate 600Sstevel@tonic-gate #include "port_before.h" 610Sstevel@tonic-gate 620Sstevel@tonic-gate #include <sys/types.h> 630Sstevel@tonic-gate #include <sys/param.h> 640Sstevel@tonic-gate #include <sys/socket.h> 650Sstevel@tonic-gate 660Sstevel@tonic-gate #include <netinet/in.h> 670Sstevel@tonic-gate #include <arpa/inet.h> 680Sstevel@tonic-gate #include <arpa/nameser.h> 690Sstevel@tonic-gate 700Sstevel@tonic-gate #include <ctype.h> 710Sstevel@tonic-gate #include <errno.h> 720Sstevel@tonic-gate #include <fcntl.h> 730Sstevel@tonic-gate #include <netdb.h> 740Sstevel@tonic-gate #include <resolv.h> 750Sstevel@tonic-gate #include <stdio.h> 760Sstevel@tonic-gate #include <stdlib.h> 770Sstevel@tonic-gate #include <string.h> 780Sstevel@tonic-gate 790Sstevel@tonic-gate #include <irs.h> 800Sstevel@tonic-gate #include <isc/memcluster.h> 810Sstevel@tonic-gate 820Sstevel@tonic-gate #include "port_after.h" 830Sstevel@tonic-gate 840Sstevel@tonic-gate #include "irs_p.h" 850Sstevel@tonic-gate #include "dns_p.h" 860Sstevel@tonic-gate #include "lcl_p.h" 870Sstevel@tonic-gate 880Sstevel@tonic-gate #ifdef SPRINTF_CHAR 890Sstevel@tonic-gate # define SPRINTF(x) strlen(sprintf/**/x) 900Sstevel@tonic-gate #else 910Sstevel@tonic-gate # define SPRINTF(x) sprintf x 920Sstevel@tonic-gate #endif 930Sstevel@tonic-gate 940Sstevel@tonic-gate /* Definitions. */ 950Sstevel@tonic-gate 960Sstevel@tonic-gate #define MAXALIASES 35 970Sstevel@tonic-gate #define MAXADDRS 35 980Sstevel@tonic-gate #define Max(a,b) ((a) > (b) ? (a) : (b)) 990Sstevel@tonic-gate 1000Sstevel@tonic-gate #if PACKETSZ > 1024 1010Sstevel@tonic-gate #define MAXPACKET PACKETSZ 1020Sstevel@tonic-gate #else 1030Sstevel@tonic-gate #define MAXPACKET 1024 1040Sstevel@tonic-gate #endif 1050Sstevel@tonic-gate 1060Sstevel@tonic-gate struct pvt { 1070Sstevel@tonic-gate FILE * fp; 1080Sstevel@tonic-gate struct hostent host; 1090Sstevel@tonic-gate char * h_addr_ptrs[MAXADDRS + 1]; 1100Sstevel@tonic-gate char * host_aliases[MAXALIASES]; 1110Sstevel@tonic-gate char hostbuf[8*1024]; 112*11038SRao.Shoaib@Sun.COM u_char host_addr[16]; /*%< IPv4 or IPv6 */ 1130Sstevel@tonic-gate struct __res_state *res; 1140Sstevel@tonic-gate void (*free_res)(void *); 1150Sstevel@tonic-gate }; 1160Sstevel@tonic-gate 1170Sstevel@tonic-gate typedef union { 1180Sstevel@tonic-gate int32_t al; 1190Sstevel@tonic-gate char ac; 1200Sstevel@tonic-gate } align; 1210Sstevel@tonic-gate 1220Sstevel@tonic-gate static const u_char mapped[] = { 0,0, 0,0, 0,0, 0,0, 0,0, 0xff,0xff }; 1230Sstevel@tonic-gate static const u_char tunnelled[] = { 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 }; 1240Sstevel@tonic-gate 1250Sstevel@tonic-gate /* Forward. */ 1260Sstevel@tonic-gate 1270Sstevel@tonic-gate static void ho_close(struct irs_ho *this); 1280Sstevel@tonic-gate static struct hostent * ho_byname(struct irs_ho *this, const char *name); 1290Sstevel@tonic-gate static struct hostent * ho_byname2(struct irs_ho *this, const char *name, 1300Sstevel@tonic-gate int af); 1310Sstevel@tonic-gate static struct hostent * ho_byaddr(struct irs_ho *this, const void *addr, 1320Sstevel@tonic-gate int len, int af); 1330Sstevel@tonic-gate static struct hostent * ho_next(struct irs_ho *this); 1340Sstevel@tonic-gate static void ho_rewind(struct irs_ho *this); 1350Sstevel@tonic-gate static void ho_minimize(struct irs_ho *this); 1360Sstevel@tonic-gate static struct __res_state * ho_res_get(struct irs_ho *this); 1370Sstevel@tonic-gate static void ho_res_set(struct irs_ho *this, 1380Sstevel@tonic-gate struct __res_state *res, 1390Sstevel@tonic-gate void (*free_res)(void *)); 1400Sstevel@tonic-gate static struct addrinfo * ho_addrinfo(struct irs_ho *this, const char *name, 1410Sstevel@tonic-gate const struct addrinfo *pai); 1420Sstevel@tonic-gate 1430Sstevel@tonic-gate static size_t ns_namelen(const char *); 1440Sstevel@tonic-gate static int init(struct irs_ho *this); 1450Sstevel@tonic-gate 1460Sstevel@tonic-gate /* Portability. */ 1470Sstevel@tonic-gate 1480Sstevel@tonic-gate #ifndef SEEK_SET 1490Sstevel@tonic-gate # define SEEK_SET 0 1500Sstevel@tonic-gate #endif 1510Sstevel@tonic-gate 1520Sstevel@tonic-gate /* Public. */ 1530Sstevel@tonic-gate 1540Sstevel@tonic-gate struct irs_ho * 1550Sstevel@tonic-gate irs_lcl_ho(struct irs_acc *this) { 1560Sstevel@tonic-gate struct irs_ho *ho; 1570Sstevel@tonic-gate struct pvt *pvt; 1580Sstevel@tonic-gate 1590Sstevel@tonic-gate UNUSED(this); 1600Sstevel@tonic-gate 1610Sstevel@tonic-gate if (!(pvt = memget(sizeof *pvt))) { 1620Sstevel@tonic-gate errno = ENOMEM; 1630Sstevel@tonic-gate return (NULL); 1640Sstevel@tonic-gate } 1650Sstevel@tonic-gate memset(pvt, 0, sizeof *pvt); 1660Sstevel@tonic-gate if (!(ho = memget(sizeof *ho))) { 1670Sstevel@tonic-gate memput(pvt, sizeof *pvt); 1680Sstevel@tonic-gate errno = ENOMEM; 1690Sstevel@tonic-gate return (NULL); 1700Sstevel@tonic-gate } 1710Sstevel@tonic-gate memset(ho, 0x5e, sizeof *ho); 1720Sstevel@tonic-gate ho->private = pvt; 1730Sstevel@tonic-gate ho->close = ho_close; 1740Sstevel@tonic-gate ho->byname = ho_byname; 1750Sstevel@tonic-gate ho->byname2 = ho_byname2; 1760Sstevel@tonic-gate ho->byaddr = ho_byaddr; 1770Sstevel@tonic-gate ho->next = ho_next; 1780Sstevel@tonic-gate ho->rewind = ho_rewind; 1790Sstevel@tonic-gate ho->minimize = ho_minimize; 1800Sstevel@tonic-gate ho->res_get = ho_res_get; 1810Sstevel@tonic-gate ho->res_set = ho_res_set; 1820Sstevel@tonic-gate ho->addrinfo = ho_addrinfo; 1830Sstevel@tonic-gate return (ho); 1840Sstevel@tonic-gate } 1850Sstevel@tonic-gate 1860Sstevel@tonic-gate /* Methods. */ 1870Sstevel@tonic-gate 1880Sstevel@tonic-gate static void 1890Sstevel@tonic-gate ho_close(struct irs_ho *this) { 1900Sstevel@tonic-gate struct pvt *pvt = (struct pvt *)this->private; 1910Sstevel@tonic-gate 1920Sstevel@tonic-gate ho_minimize(this); 1930Sstevel@tonic-gate if (pvt->fp) 1940Sstevel@tonic-gate (void) fclose(pvt->fp); 1950Sstevel@tonic-gate if (pvt->res && pvt->free_res) 1960Sstevel@tonic-gate (*pvt->free_res)(pvt->res); 1970Sstevel@tonic-gate memput(pvt, sizeof *pvt); 1980Sstevel@tonic-gate memput(this, sizeof *this); 1990Sstevel@tonic-gate } 2000Sstevel@tonic-gate 2010Sstevel@tonic-gate static struct hostent * 2020Sstevel@tonic-gate ho_byname(struct irs_ho *this, const char *name) { 2030Sstevel@tonic-gate struct pvt *pvt = (struct pvt *)this->private; 2040Sstevel@tonic-gate struct hostent *hp; 2050Sstevel@tonic-gate 2060Sstevel@tonic-gate if (init(this) == -1) 2070Sstevel@tonic-gate return (NULL); 2080Sstevel@tonic-gate 2090Sstevel@tonic-gate if (pvt->res->options & RES_USE_INET6) { 2100Sstevel@tonic-gate hp = ho_byname2(this, name, AF_INET6); 2110Sstevel@tonic-gate if (hp) 2120Sstevel@tonic-gate return (hp); 2130Sstevel@tonic-gate } 2140Sstevel@tonic-gate return (ho_byname2(this, name, AF_INET)); 2150Sstevel@tonic-gate } 2160Sstevel@tonic-gate 2170Sstevel@tonic-gate static struct hostent * 2180Sstevel@tonic-gate ho_byname2(struct irs_ho *this, const char *name, int af) { 2190Sstevel@tonic-gate struct pvt *pvt = (struct pvt *)this->private; 2200Sstevel@tonic-gate struct hostent *hp; 2210Sstevel@tonic-gate char **hap; 2220Sstevel@tonic-gate size_t n; 2230Sstevel@tonic-gate 2240Sstevel@tonic-gate if (init(this) == -1) 2250Sstevel@tonic-gate return (NULL); 2260Sstevel@tonic-gate 2270Sstevel@tonic-gate ho_rewind(this); 2280Sstevel@tonic-gate n = ns_namelen(name); 2290Sstevel@tonic-gate while ((hp = ho_next(this)) != NULL) { 2300Sstevel@tonic-gate size_t nn; 2310Sstevel@tonic-gate 2320Sstevel@tonic-gate if (hp->h_addrtype != af) 2330Sstevel@tonic-gate continue; 2340Sstevel@tonic-gate nn = ns_namelen(hp->h_name); 2350Sstevel@tonic-gate if (strncasecmp(hp->h_name, name, Max(n, nn)) == 0) 2360Sstevel@tonic-gate goto found; 2370Sstevel@tonic-gate for (hap = hp->h_aliases; *hap; hap++) { 2380Sstevel@tonic-gate nn = ns_namelen(*hap); 2390Sstevel@tonic-gate if (strncasecmp(*hap, name, Max(n, nn)) == 0) 2400Sstevel@tonic-gate goto found; 2410Sstevel@tonic-gate } 2420Sstevel@tonic-gate } 2430Sstevel@tonic-gate found: 2440Sstevel@tonic-gate if (!hp) { 2450Sstevel@tonic-gate RES_SET_H_ERRNO(pvt->res, HOST_NOT_FOUND); 2460Sstevel@tonic-gate return (NULL); 2470Sstevel@tonic-gate } 2480Sstevel@tonic-gate RES_SET_H_ERRNO(pvt->res, NETDB_SUCCESS); 2490Sstevel@tonic-gate return (hp); 2500Sstevel@tonic-gate } 2510Sstevel@tonic-gate 2520Sstevel@tonic-gate static struct hostent * 2530Sstevel@tonic-gate ho_byaddr(struct irs_ho *this, const void *addr, int len, int af) { 2540Sstevel@tonic-gate struct pvt *pvt = (struct pvt *)this->private; 2550Sstevel@tonic-gate const u_char *uaddr = addr; 2560Sstevel@tonic-gate struct hostent *hp; 2570Sstevel@tonic-gate int size; 2580Sstevel@tonic-gate 2590Sstevel@tonic-gate if (init(this) == -1) 2600Sstevel@tonic-gate return (NULL); 2610Sstevel@tonic-gate 2620Sstevel@tonic-gate if (af == AF_INET6 && len == IN6ADDRSZ && 2630Sstevel@tonic-gate (!memcmp(uaddr, mapped, sizeof mapped) || 2640Sstevel@tonic-gate !memcmp(uaddr, tunnelled, sizeof tunnelled))) { 2650Sstevel@tonic-gate /* Unmap. */ 2660Sstevel@tonic-gate addr = (const u_char *)addr + sizeof mapped; 2670Sstevel@tonic-gate uaddr += sizeof mapped; 2680Sstevel@tonic-gate af = AF_INET; 2690Sstevel@tonic-gate len = INADDRSZ; 2700Sstevel@tonic-gate } 2710Sstevel@tonic-gate switch (af) { 2720Sstevel@tonic-gate case AF_INET: 2730Sstevel@tonic-gate size = INADDRSZ; 2740Sstevel@tonic-gate break; 2750Sstevel@tonic-gate case AF_INET6: 2760Sstevel@tonic-gate size = IN6ADDRSZ; 2770Sstevel@tonic-gate break; 2780Sstevel@tonic-gate default: 2790Sstevel@tonic-gate errno = EAFNOSUPPORT; 2800Sstevel@tonic-gate RES_SET_H_ERRNO(pvt->res, NETDB_INTERNAL); 2810Sstevel@tonic-gate return (NULL); 2820Sstevel@tonic-gate } 2830Sstevel@tonic-gate if (size > len) { 2840Sstevel@tonic-gate errno = EINVAL; 2850Sstevel@tonic-gate RES_SET_H_ERRNO(pvt->res, NETDB_INTERNAL); 2860Sstevel@tonic-gate return (NULL); 2870Sstevel@tonic-gate } 2880Sstevel@tonic-gate 2890Sstevel@tonic-gate /* 2900Sstevel@tonic-gate * Do the search. 2910Sstevel@tonic-gate */ 2920Sstevel@tonic-gate ho_rewind(this); 2930Sstevel@tonic-gate while ((hp = ho_next(this)) != NULL) { 2940Sstevel@tonic-gate char **hap; 2950Sstevel@tonic-gate 2960Sstevel@tonic-gate for (hap = hp->h_addr_list; *hap; hap++) { 2970Sstevel@tonic-gate const u_char *taddr = (const u_char *)*hap; 2980Sstevel@tonic-gate int taf = hp->h_addrtype; 2990Sstevel@tonic-gate int tlen = hp->h_length; 3000Sstevel@tonic-gate 3010Sstevel@tonic-gate if (taf == AF_INET6 && tlen == IN6ADDRSZ && 3020Sstevel@tonic-gate (!memcmp(taddr, mapped, sizeof mapped) || 3030Sstevel@tonic-gate !memcmp(taddr, tunnelled, sizeof tunnelled))) { 3040Sstevel@tonic-gate /* Unmap. */ 3050Sstevel@tonic-gate taddr += sizeof mapped; 3060Sstevel@tonic-gate taf = AF_INET; 3070Sstevel@tonic-gate tlen = INADDRSZ; 3080Sstevel@tonic-gate } 3090Sstevel@tonic-gate if (taf == af && tlen == len && 3100Sstevel@tonic-gate !memcmp(taddr, uaddr, tlen)) 3110Sstevel@tonic-gate goto found; 3120Sstevel@tonic-gate } 3130Sstevel@tonic-gate } 3140Sstevel@tonic-gate found: 3150Sstevel@tonic-gate if (!hp) { 3160Sstevel@tonic-gate RES_SET_H_ERRNO(pvt->res, HOST_NOT_FOUND); 3170Sstevel@tonic-gate return (NULL); 3180Sstevel@tonic-gate } 3190Sstevel@tonic-gate RES_SET_H_ERRNO(pvt->res, NETDB_SUCCESS); 3200Sstevel@tonic-gate return (hp); 3210Sstevel@tonic-gate } 3220Sstevel@tonic-gate 3230Sstevel@tonic-gate static struct hostent * 3240Sstevel@tonic-gate ho_next(struct irs_ho *this) { 3250Sstevel@tonic-gate struct pvt *pvt = (struct pvt *)this->private; 3260Sstevel@tonic-gate char *cp, **q, *p; 3270Sstevel@tonic-gate char *bufp, *ndbuf, *dbuf = NULL; 3280Sstevel@tonic-gate int c, af, len, bufsiz, offset; 3290Sstevel@tonic-gate 3300Sstevel@tonic-gate if (init(this) == -1) 3310Sstevel@tonic-gate return (NULL); 3320Sstevel@tonic-gate 3330Sstevel@tonic-gate if (!pvt->fp) 3340Sstevel@tonic-gate ho_rewind(this); 3350Sstevel@tonic-gate if (!pvt->fp) { 3360Sstevel@tonic-gate RES_SET_H_ERRNO(pvt->res, NETDB_INTERNAL); 3370Sstevel@tonic-gate return (NULL); 3380Sstevel@tonic-gate } 3390Sstevel@tonic-gate bufp = pvt->hostbuf; 3400Sstevel@tonic-gate bufsiz = sizeof pvt->hostbuf; 3410Sstevel@tonic-gate offset = 0; 3420Sstevel@tonic-gate again: 3430Sstevel@tonic-gate if (!(p = fgets(bufp + offset, bufsiz - offset, pvt->fp))) { 3440Sstevel@tonic-gate RES_SET_H_ERRNO(pvt->res, HOST_NOT_FOUND); 3450Sstevel@tonic-gate if (dbuf) 3460Sstevel@tonic-gate free(dbuf); 3470Sstevel@tonic-gate return (NULL); 3480Sstevel@tonic-gate } 3490Sstevel@tonic-gate if (!strchr(p, '\n') && !feof(pvt->fp)) { 3500Sstevel@tonic-gate #define GROWBUF 1024 3510Sstevel@tonic-gate /* allocate space for longer line */ 3520Sstevel@tonic-gate if (dbuf == NULL) { 3530Sstevel@tonic-gate if ((ndbuf = malloc(bufsiz + GROWBUF)) != NULL) 3540Sstevel@tonic-gate strcpy(ndbuf, bufp); 3550Sstevel@tonic-gate } else 3560Sstevel@tonic-gate ndbuf = realloc(dbuf, bufsiz + GROWBUF); 3570Sstevel@tonic-gate if (ndbuf) { 3580Sstevel@tonic-gate dbuf = ndbuf; 3590Sstevel@tonic-gate bufp = dbuf; 3600Sstevel@tonic-gate bufsiz += GROWBUF; 3610Sstevel@tonic-gate offset = strlen(dbuf); 3620Sstevel@tonic-gate } else { 3630Sstevel@tonic-gate /* allocation failed; skip this long line */ 3640Sstevel@tonic-gate while ((c = getc(pvt->fp)) != EOF) 3650Sstevel@tonic-gate if (c == '\n') 3660Sstevel@tonic-gate break; 3670Sstevel@tonic-gate if (c != EOF) 3680Sstevel@tonic-gate ungetc(c, pvt->fp); 3690Sstevel@tonic-gate } 3700Sstevel@tonic-gate goto again; 3710Sstevel@tonic-gate } 3720Sstevel@tonic-gate 3730Sstevel@tonic-gate p -= offset; 3740Sstevel@tonic-gate offset = 0; 3750Sstevel@tonic-gate 3760Sstevel@tonic-gate if (*p == '#') 3770Sstevel@tonic-gate goto again; 3780Sstevel@tonic-gate if ((cp = strpbrk(p, "#\n")) != NULL) 3790Sstevel@tonic-gate *cp = '\0'; 3800Sstevel@tonic-gate if (!(cp = strpbrk(p, " \t"))) 3810Sstevel@tonic-gate goto again; 3820Sstevel@tonic-gate *cp++ = '\0'; 3830Sstevel@tonic-gate if (inet_pton(AF_INET6, p, pvt->host_addr) > 0) { 3840Sstevel@tonic-gate af = AF_INET6; 3850Sstevel@tonic-gate len = IN6ADDRSZ; 3860Sstevel@tonic-gate } else if (inet_aton(p, (struct in_addr *)pvt->host_addr) > 0) { 3870Sstevel@tonic-gate if (pvt->res->options & RES_USE_INET6) { 3880Sstevel@tonic-gate map_v4v6_address((char*)pvt->host_addr, 3890Sstevel@tonic-gate (char*)pvt->host_addr); 3900Sstevel@tonic-gate af = AF_INET6; 3910Sstevel@tonic-gate len = IN6ADDRSZ; 3920Sstevel@tonic-gate } else { 3930Sstevel@tonic-gate af = AF_INET; 3940Sstevel@tonic-gate len = INADDRSZ; 3950Sstevel@tonic-gate } 3960Sstevel@tonic-gate } else { 3970Sstevel@tonic-gate goto again; 3980Sstevel@tonic-gate } 3990Sstevel@tonic-gate pvt->h_addr_ptrs[0] = (char *)pvt->host_addr; 4000Sstevel@tonic-gate pvt->h_addr_ptrs[1] = NULL; 4010Sstevel@tonic-gate pvt->host.h_addr_list = pvt->h_addr_ptrs; 4020Sstevel@tonic-gate pvt->host.h_length = len; 4030Sstevel@tonic-gate pvt->host.h_addrtype = af; 4040Sstevel@tonic-gate while (*cp == ' ' || *cp == '\t') 4050Sstevel@tonic-gate cp++; 4060Sstevel@tonic-gate pvt->host.h_name = cp; 4070Sstevel@tonic-gate q = pvt->host.h_aliases = pvt->host_aliases; 4080Sstevel@tonic-gate if ((cp = strpbrk(cp, " \t")) != NULL) 4090Sstevel@tonic-gate *cp++ = '\0'; 4100Sstevel@tonic-gate while (cp && *cp) { 4110Sstevel@tonic-gate if (*cp == ' ' || *cp == '\t') { 4120Sstevel@tonic-gate cp++; 4130Sstevel@tonic-gate continue; 4140Sstevel@tonic-gate } 4150Sstevel@tonic-gate if (q < &pvt->host_aliases[MAXALIASES - 1]) 4160Sstevel@tonic-gate *q++ = cp; 4170Sstevel@tonic-gate if ((cp = strpbrk(cp, " \t")) != NULL) 4180Sstevel@tonic-gate *cp++ = '\0'; 4190Sstevel@tonic-gate } 4200Sstevel@tonic-gate *q = NULL; 4210Sstevel@tonic-gate if (dbuf) 4220Sstevel@tonic-gate free(dbuf); 4230Sstevel@tonic-gate RES_SET_H_ERRNO(pvt->res, NETDB_SUCCESS); 4240Sstevel@tonic-gate return (&pvt->host); 4250Sstevel@tonic-gate } 4260Sstevel@tonic-gate 4270Sstevel@tonic-gate static void 4280Sstevel@tonic-gate ho_rewind(struct irs_ho *this) { 4290Sstevel@tonic-gate struct pvt *pvt = (struct pvt *)this->private; 4300Sstevel@tonic-gate 4310Sstevel@tonic-gate if (pvt->fp) { 4320Sstevel@tonic-gate if (fseek(pvt->fp, 0L, SEEK_SET) == 0) 4330Sstevel@tonic-gate return; 4340Sstevel@tonic-gate (void)fclose(pvt->fp); 4350Sstevel@tonic-gate } 4360Sstevel@tonic-gate if (!(pvt->fp = fopen(_PATH_HOSTS, "r"))) 4370Sstevel@tonic-gate return; 4380Sstevel@tonic-gate if (fcntl(fileno(pvt->fp), F_SETFD, 1) < 0) { 4390Sstevel@tonic-gate (void)fclose(pvt->fp); 4400Sstevel@tonic-gate pvt->fp = NULL; 4410Sstevel@tonic-gate } 4420Sstevel@tonic-gate } 4430Sstevel@tonic-gate 4440Sstevel@tonic-gate static void 4450Sstevel@tonic-gate ho_minimize(struct irs_ho *this) { 4460Sstevel@tonic-gate struct pvt *pvt = (struct pvt *)this->private; 4470Sstevel@tonic-gate 4480Sstevel@tonic-gate if (pvt->fp != NULL) { 4490Sstevel@tonic-gate (void)fclose(pvt->fp); 4500Sstevel@tonic-gate pvt->fp = NULL; 4510Sstevel@tonic-gate } 4520Sstevel@tonic-gate if (pvt->res) 4530Sstevel@tonic-gate res_nclose(pvt->res); 4540Sstevel@tonic-gate } 4550Sstevel@tonic-gate 4560Sstevel@tonic-gate static struct __res_state * 4570Sstevel@tonic-gate ho_res_get(struct irs_ho *this) { 4580Sstevel@tonic-gate struct pvt *pvt = (struct pvt *)this->private; 4590Sstevel@tonic-gate 4600Sstevel@tonic-gate if (!pvt->res) { 4610Sstevel@tonic-gate struct __res_state *res; 4620Sstevel@tonic-gate res = (struct __res_state *)malloc(sizeof *res); 4630Sstevel@tonic-gate if (!res) { 4640Sstevel@tonic-gate errno = ENOMEM; 4650Sstevel@tonic-gate return (NULL); 4660Sstevel@tonic-gate } 4670Sstevel@tonic-gate memset(res, 0, sizeof *res); 4680Sstevel@tonic-gate ho_res_set(this, res, free); 4690Sstevel@tonic-gate } 4700Sstevel@tonic-gate 4710Sstevel@tonic-gate return (pvt->res); 4720Sstevel@tonic-gate } 4730Sstevel@tonic-gate 4740Sstevel@tonic-gate static void 4750Sstevel@tonic-gate ho_res_set(struct irs_ho *this, struct __res_state *res, 4760Sstevel@tonic-gate void (*free_res)(void *)) { 4770Sstevel@tonic-gate struct pvt *pvt = (struct pvt *)this->private; 4780Sstevel@tonic-gate 4790Sstevel@tonic-gate if (pvt->res && pvt->free_res) { 4800Sstevel@tonic-gate res_nclose(pvt->res); 4810Sstevel@tonic-gate (*pvt->free_res)(pvt->res); 4820Sstevel@tonic-gate } 4830Sstevel@tonic-gate 4840Sstevel@tonic-gate pvt->res = res; 4850Sstevel@tonic-gate pvt->free_res = free_res; 4860Sstevel@tonic-gate } 4870Sstevel@tonic-gate 4880Sstevel@tonic-gate struct lcl_res_target { 4890Sstevel@tonic-gate struct lcl_res_target *next; 4900Sstevel@tonic-gate int family; 4910Sstevel@tonic-gate }; 4920Sstevel@tonic-gate 4930Sstevel@tonic-gate /* XXX */ 4940Sstevel@tonic-gate extern struct addrinfo *hostent2addrinfo __P((struct hostent *, 4950Sstevel@tonic-gate const struct addrinfo *pai)); 4960Sstevel@tonic-gate 4970Sstevel@tonic-gate static struct addrinfo * 4980Sstevel@tonic-gate ho_addrinfo(struct irs_ho *this, const char *name, const struct addrinfo *pai) 4990Sstevel@tonic-gate { 5000Sstevel@tonic-gate struct pvt *pvt = (struct pvt *)this->private; 5010Sstevel@tonic-gate struct hostent *hp; 5020Sstevel@tonic-gate struct lcl_res_target q, q2, *p; 5030Sstevel@tonic-gate struct addrinfo sentinel, *cur; 5040Sstevel@tonic-gate 5050Sstevel@tonic-gate memset(&q, 0, sizeof(q2)); 5060Sstevel@tonic-gate memset(&q2, 0, sizeof(q2)); 5070Sstevel@tonic-gate memset(&sentinel, 0, sizeof(sentinel)); 5080Sstevel@tonic-gate cur = &sentinel; 5090Sstevel@tonic-gate 5100Sstevel@tonic-gate switch(pai->ai_family) { 511*11038SRao.Shoaib@Sun.COM case AF_UNSPEC: /*%< INET6 then INET4 */ 5120Sstevel@tonic-gate q.family = AF_INET6; 5130Sstevel@tonic-gate q.next = &q2; 5140Sstevel@tonic-gate q2.family = AF_INET; 5150Sstevel@tonic-gate break; 5160Sstevel@tonic-gate case AF_INET6: 5170Sstevel@tonic-gate q.family = AF_INET6; 5180Sstevel@tonic-gate break; 5190Sstevel@tonic-gate case AF_INET: 5200Sstevel@tonic-gate q.family = AF_INET; 5210Sstevel@tonic-gate break; 5220Sstevel@tonic-gate default: 523*11038SRao.Shoaib@Sun.COM RES_SET_H_ERRNO(pvt->res, NO_RECOVERY); /*%< ??? */ 5240Sstevel@tonic-gate return(NULL); 5250Sstevel@tonic-gate } 5260Sstevel@tonic-gate 5270Sstevel@tonic-gate for (p = &q; p; p = p->next) { 5280Sstevel@tonic-gate struct addrinfo *ai; 5290Sstevel@tonic-gate 5300Sstevel@tonic-gate hp = (*this->byname2)(this, name, p->family); 5310Sstevel@tonic-gate if (hp == NULL) { 5320Sstevel@tonic-gate /* byname2 should've set an appropriate error */ 5330Sstevel@tonic-gate continue; 5340Sstevel@tonic-gate } 5350Sstevel@tonic-gate if ((hp->h_name == NULL) || (hp->h_name[0] == 0) || 5360Sstevel@tonic-gate (hp->h_addr_list[0] == NULL)) { 5370Sstevel@tonic-gate RES_SET_H_ERRNO(pvt->res, NO_RECOVERY); 5380Sstevel@tonic-gate continue; 5390Sstevel@tonic-gate } 5400Sstevel@tonic-gate 5410Sstevel@tonic-gate ai = hostent2addrinfo(hp, pai); 5420Sstevel@tonic-gate if (ai) { 5430Sstevel@tonic-gate cur->ai_next = ai; 544*11038SRao.Shoaib@Sun.COM while (cur->ai_next) 5450Sstevel@tonic-gate cur = cur->ai_next; 5460Sstevel@tonic-gate } 5470Sstevel@tonic-gate } 5480Sstevel@tonic-gate 5490Sstevel@tonic-gate if (sentinel.ai_next == NULL) 5500Sstevel@tonic-gate RES_SET_H_ERRNO(pvt->res, HOST_NOT_FOUND); 5510Sstevel@tonic-gate 5520Sstevel@tonic-gate return(sentinel.ai_next); 5530Sstevel@tonic-gate } 5540Sstevel@tonic-gate 5550Sstevel@tonic-gate /* Private. */ 5560Sstevel@tonic-gate 5570Sstevel@tonic-gate static size_t 5580Sstevel@tonic-gate ns_namelen(const char *s) { 5590Sstevel@tonic-gate int i; 5600Sstevel@tonic-gate 5610Sstevel@tonic-gate for (i = strlen(s); i > 0 && s[i-1] == '.'; i--) 5620Sstevel@tonic-gate (void)NULL; 5630Sstevel@tonic-gate return ((size_t) i); 5640Sstevel@tonic-gate } 5650Sstevel@tonic-gate 5660Sstevel@tonic-gate static int 5670Sstevel@tonic-gate init(struct irs_ho *this) { 5680Sstevel@tonic-gate struct pvt *pvt = (struct pvt *)this->private; 5690Sstevel@tonic-gate 5700Sstevel@tonic-gate if (!pvt->res && !ho_res_get(this)) 5710Sstevel@tonic-gate return (-1); 572*11038SRao.Shoaib@Sun.COM if (((pvt->res->options & RES_INIT) == 0U) && 5730Sstevel@tonic-gate res_ninit(pvt->res) == -1) 5740Sstevel@tonic-gate return (-1); 5750Sstevel@tonic-gate return (0); 5760Sstevel@tonic-gate } 577*11038SRao.Shoaib@Sun.COM 578*11038SRao.Shoaib@Sun.COM /*! \file */ 579