17257d1b4Sraf /*
2*bd0e95e6SGary Mills  * Copyright 2015 Gary Mills
3d67944fbSScott Rotondo  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
47257d1b4Sraf  * Use is subject to license terms.
57257d1b4Sraf  */
67257d1b4Sraf 
77c478bd9Sstevel@tonic-gate /*
87c478bd9Sstevel@tonic-gate  * Copyright (c) 1985, 1988 Regents of the University of California.
97c478bd9Sstevel@tonic-gate  * All rights reserved.
107c478bd9Sstevel@tonic-gate  *
117c478bd9Sstevel@tonic-gate  * Redistribution and use in source and binary forms are permitted
127c478bd9Sstevel@tonic-gate  * provided that this notice is preserved and that due credit is given
137c478bd9Sstevel@tonic-gate  * to the University of California at Berkeley. The name of the University
147c478bd9Sstevel@tonic-gate  * may not be used to endorse or promote products derived from this
157c478bd9Sstevel@tonic-gate  * software without specific prior written permission. This software
167c478bd9Sstevel@tonic-gate  * is provided ``as is'' without express or implied warranty.
177c478bd9Sstevel@tonic-gate  *
187c478bd9Sstevel@tonic-gate  */
197c478bd9Sstevel@tonic-gate 
207c478bd9Sstevel@tonic-gate #include <sys/param.h>
217c478bd9Sstevel@tonic-gate #include <sys/socket.h>
227c478bd9Sstevel@tonic-gate #include <netinet/in.h>
237c478bd9Sstevel@tonic-gate #include <ctype.h>
247c478bd9Sstevel@tonic-gate #include <netdb.h>
257c478bd9Sstevel@tonic-gate #include <stdio.h>
267c478bd9Sstevel@tonic-gate #include <errno.h>
27*bd0e95e6SGary Mills #include <string.h>
287c478bd9Sstevel@tonic-gate #include <arpa/inet.h>
297c478bd9Sstevel@tonic-gate #include <arpa/nameser.h>
307c478bd9Sstevel@tonic-gate #include <resolv.h>
317c478bd9Sstevel@tonic-gate #include <syslog.h>
32*bd0e95e6SGary Mills #include "crossl.h"
337c478bd9Sstevel@tonic-gate 
347c478bd9Sstevel@tonic-gate /*
357c478bd9Sstevel@tonic-gate  * When the name service switch calls libresolv, it doesn't want fallback
367c478bd9Sstevel@tonic-gate  * to /etc/hosts, so we provide a method to turn it off.
377c478bd9Sstevel@tonic-gate  */
387c478bd9Sstevel@tonic-gate static int	no_hosts_fallback = 0;
397c478bd9Sstevel@tonic-gate 
407c478bd9Sstevel@tonic-gate void
__res_set_no_hosts_fallback(void)417c478bd9Sstevel@tonic-gate __res_set_no_hosts_fallback(void) {
427c478bd9Sstevel@tonic-gate 	no_hosts_fallback = 1;
437c478bd9Sstevel@tonic-gate }
447c478bd9Sstevel@tonic-gate 
457c478bd9Sstevel@tonic-gate static int
__res_no_hosts_fallback(void)467c478bd9Sstevel@tonic-gate __res_no_hosts_fallback(void) {
477c478bd9Sstevel@tonic-gate 	return(no_hosts_fallback);
487c478bd9Sstevel@tonic-gate }
497c478bd9Sstevel@tonic-gate 
507c478bd9Sstevel@tonic-gate static char *h_addr_ptrs[MAXADDRS + 1];
517c478bd9Sstevel@tonic-gate 
527c478bd9Sstevel@tonic-gate static struct hostent host;
537c478bd9Sstevel@tonic-gate static char *host_aliases[MAXALIASES];
547c478bd9Sstevel@tonic-gate static char hostbuf[BUFSIZ+1];
557c478bd9Sstevel@tonic-gate static struct in_addr host_addr;
567c478bd9Sstevel@tonic-gate static char HOSTDB[] = "/etc/hosts";
577c478bd9Sstevel@tonic-gate static FILE *hostf = NULL;
587c478bd9Sstevel@tonic-gate static char hostaddr[MAXADDRS];
597c478bd9Sstevel@tonic-gate static char *host_addrs[2];
607c478bd9Sstevel@tonic-gate static int stayopen = 0;
617c478bd9Sstevel@tonic-gate static char *any();
627c478bd9Sstevel@tonic-gate 
637c478bd9Sstevel@tonic-gate #if PACKETSZ > 1024
647c478bd9Sstevel@tonic-gate #define	MAXPACKET	PACKETSZ
657c478bd9Sstevel@tonic-gate #else
667c478bd9Sstevel@tonic-gate #define	MAXPACKET	1024
677c478bd9Sstevel@tonic-gate #endif
687c478bd9Sstevel@tonic-gate 
697c478bd9Sstevel@tonic-gate typedef union {
707c478bd9Sstevel@tonic-gate 	HEADER hdr;
717c478bd9Sstevel@tonic-gate 	u_char buf[MAXPACKET];
727c478bd9Sstevel@tonic-gate } querybuf;
737c478bd9Sstevel@tonic-gate 
747c478bd9Sstevel@tonic-gate static union {
757c478bd9Sstevel@tonic-gate 	long al;
767c478bd9Sstevel@tonic-gate 	char ac;
777c478bd9Sstevel@tonic-gate } align;
787c478bd9Sstevel@tonic-gate 
797c478bd9Sstevel@tonic-gate 
807c478bd9Sstevel@tonic-gate int h_errno;
817c478bd9Sstevel@tonic-gate 
827c478bd9Sstevel@tonic-gate static struct hostent *
getanswer(answer,anslen,iquery)837c478bd9Sstevel@tonic-gate getanswer(answer, anslen, iquery)
847c478bd9Sstevel@tonic-gate 	querybuf *answer;
857c478bd9Sstevel@tonic-gate 	int anslen;
867c478bd9Sstevel@tonic-gate 	int iquery;
877c478bd9Sstevel@tonic-gate {
887c478bd9Sstevel@tonic-gate 	register HEADER *hp;
897c478bd9Sstevel@tonic-gate 	register u_char *cp;
907c478bd9Sstevel@tonic-gate 	register int n;
917c478bd9Sstevel@tonic-gate 	u_char *eom;
927c478bd9Sstevel@tonic-gate 	char *bp, **ap;
937c478bd9Sstevel@tonic-gate 	int type, class, buflen, ancount, qdcount;
947c478bd9Sstevel@tonic-gate 	int haveanswer, getclass = C_ANY;
957c478bd9Sstevel@tonic-gate 	char **hap;
967c478bd9Sstevel@tonic-gate 
977c478bd9Sstevel@tonic-gate 	eom = answer->buf + anslen;
987c478bd9Sstevel@tonic-gate 	/*
997c478bd9Sstevel@tonic-gate 	 * find first satisfactory answer
1007c478bd9Sstevel@tonic-gate 	 */
1017c478bd9Sstevel@tonic-gate 	hp = &answer->hdr;
1027c478bd9Sstevel@tonic-gate 	ancount = ntohs(hp->ancount);
1037c478bd9Sstevel@tonic-gate 	qdcount = ntohs(hp->qdcount);
1047c478bd9Sstevel@tonic-gate 	bp = hostbuf;
1057c478bd9Sstevel@tonic-gate 	buflen = sizeof (hostbuf);
1067c478bd9Sstevel@tonic-gate 	cp = answer->buf + sizeof (HEADER);
1077c478bd9Sstevel@tonic-gate 	if (qdcount) {
1087c478bd9Sstevel@tonic-gate 		if (iquery) {
109*bd0e95e6SGary Mills 			if ((n = dn_expand(answer->buf, eom,
110*bd0e95e6SGary Mills 			    cp, (u_char *)bp, buflen)) < 0) {
1117c478bd9Sstevel@tonic-gate 				h_errno = NO_RECOVERY;
1127c478bd9Sstevel@tonic-gate 				return ((struct hostent *) NULL);
1137c478bd9Sstevel@tonic-gate 			}
1147c478bd9Sstevel@tonic-gate 			cp += n + QFIXEDSZ;
1157c478bd9Sstevel@tonic-gate 			host.h_name = bp;
1167c478bd9Sstevel@tonic-gate 			n = strlen(bp) + 1;
1177c478bd9Sstevel@tonic-gate 			bp += n;
1187c478bd9Sstevel@tonic-gate 			buflen -= n;
1197c478bd9Sstevel@tonic-gate 		} else
1207c478bd9Sstevel@tonic-gate 			cp += dn_skipname(cp, eom) + QFIXEDSZ;
1217c478bd9Sstevel@tonic-gate 		while (--qdcount > 0)
1227c478bd9Sstevel@tonic-gate 			cp += dn_skipname(cp, eom) + QFIXEDSZ;
1237c478bd9Sstevel@tonic-gate 	} else if (iquery) {
1247c478bd9Sstevel@tonic-gate 		if (hp->aa)
1257c478bd9Sstevel@tonic-gate 			h_errno = HOST_NOT_FOUND;
1267c478bd9Sstevel@tonic-gate 		else
1277c478bd9Sstevel@tonic-gate 			h_errno = TRY_AGAIN;
1287c478bd9Sstevel@tonic-gate 		return ((struct hostent *) NULL);
1297c478bd9Sstevel@tonic-gate 	}
1307c478bd9Sstevel@tonic-gate 	ap = host_aliases;
1317c478bd9Sstevel@tonic-gate 	host.h_aliases = host_aliases;
1327c478bd9Sstevel@tonic-gate 	hap = h_addr_ptrs;
1337c478bd9Sstevel@tonic-gate #if BSD >= 43 || defined(h_addr)	/* new-style hostent structure */
1347c478bd9Sstevel@tonic-gate 	host.h_addr_list = h_addr_ptrs;
1357c478bd9Sstevel@tonic-gate #endif
1367c478bd9Sstevel@tonic-gate 	haveanswer = 0;
1377c478bd9Sstevel@tonic-gate 	while (--ancount >= 0 && cp < eom && haveanswer < MAXADDRS) {
138*bd0e95e6SGary Mills 		if ((n = dn_expand(answer->buf, eom,
139*bd0e95e6SGary Mills 		    cp, (u_char *)bp, buflen)) < 0)
1407c478bd9Sstevel@tonic-gate 			break;
1417c478bd9Sstevel@tonic-gate 		cp += n;
1427c478bd9Sstevel@tonic-gate 		type = _getshort(cp);
1437c478bd9Sstevel@tonic-gate 		cp += sizeof (u_short);
1447c478bd9Sstevel@tonic-gate 		class = _getshort(cp);
1457c478bd9Sstevel@tonic-gate 		cp += sizeof (u_short) + sizeof (u_long);
1467c478bd9Sstevel@tonic-gate 		n = _getshort(cp);
1477c478bd9Sstevel@tonic-gate 		cp += sizeof (u_short);
1487c478bd9Sstevel@tonic-gate 		if (type == T_CNAME) {
1497c478bd9Sstevel@tonic-gate 			cp += n;
1507c478bd9Sstevel@tonic-gate 			if (ap >= &host_aliases[MAXALIASES-1])
1517c478bd9Sstevel@tonic-gate 				continue;
1527c478bd9Sstevel@tonic-gate 			*ap++ = bp;
1537c478bd9Sstevel@tonic-gate 			n = strlen(bp) + 1;
1547c478bd9Sstevel@tonic-gate 			bp += n;
1557c478bd9Sstevel@tonic-gate 			buflen -= n;
1567c478bd9Sstevel@tonic-gate 			continue;
1577c478bd9Sstevel@tonic-gate 		}
1587c478bd9Sstevel@tonic-gate 		if (iquery && type == T_PTR) {
159*bd0e95e6SGary Mills 			if ((n = dn_expand(answer->buf, eom,
160*bd0e95e6SGary Mills 			    cp, (u_char *)bp, buflen)) < 0) {
1617c478bd9Sstevel@tonic-gate 				cp += n;
1627c478bd9Sstevel@tonic-gate 				continue;
1637c478bd9Sstevel@tonic-gate 			}
1647c478bd9Sstevel@tonic-gate 			cp += n;
1657c478bd9Sstevel@tonic-gate 			host.h_name = bp;
1667c478bd9Sstevel@tonic-gate 			return (&host);
1677c478bd9Sstevel@tonic-gate 		}
1687c478bd9Sstevel@tonic-gate 		if (iquery || type != T_A) {
1697c478bd9Sstevel@tonic-gate #ifdef DEBUG
1707c478bd9Sstevel@tonic-gate 			if (_res.options & RES_DEBUG)
1717c478bd9Sstevel@tonic-gate 				printf("unexpected answer type %d, size %d\n",
1727c478bd9Sstevel@tonic-gate 					type, n);
1737c478bd9Sstevel@tonic-gate #endif
1747c478bd9Sstevel@tonic-gate 			cp += n;
1757c478bd9Sstevel@tonic-gate 			continue;
1767c478bd9Sstevel@tonic-gate 		}
1777c478bd9Sstevel@tonic-gate 		if (haveanswer) {
1787c478bd9Sstevel@tonic-gate 			if (n != host.h_length) {
1797c478bd9Sstevel@tonic-gate 				cp += n;
1807c478bd9Sstevel@tonic-gate 				continue;
1817c478bd9Sstevel@tonic-gate 			}
1827c478bd9Sstevel@tonic-gate 			if (class != getclass) {
1837c478bd9Sstevel@tonic-gate 				cp += n;
1847c478bd9Sstevel@tonic-gate 				continue;
1857c478bd9Sstevel@tonic-gate 			}
1867c478bd9Sstevel@tonic-gate 		} else {
1877c478bd9Sstevel@tonic-gate 			host.h_length = n;
1887c478bd9Sstevel@tonic-gate 			getclass = class;
1897c478bd9Sstevel@tonic-gate 			host.h_addrtype = (class == C_IN) ? AF_INET : AF_UNSPEC;
1907c478bd9Sstevel@tonic-gate 			if (!iquery) {
1917c478bd9Sstevel@tonic-gate 				host.h_name = bp;
1927c478bd9Sstevel@tonic-gate 				bp += strlen(bp) + 1;
1937c478bd9Sstevel@tonic-gate 			}
1947c478bd9Sstevel@tonic-gate 		}
1957c478bd9Sstevel@tonic-gate 
1967c478bd9Sstevel@tonic-gate 		bp += sizeof (align) - ((u_long)bp % sizeof (align));
1977c478bd9Sstevel@tonic-gate 
1987c478bd9Sstevel@tonic-gate 		if (bp + n >= &hostbuf[sizeof (hostbuf)]) {
1997c478bd9Sstevel@tonic-gate #ifdef DEBUG
2007c478bd9Sstevel@tonic-gate 			if (_res.options & RES_DEBUG)
2017c478bd9Sstevel@tonic-gate 				printf("size (%d) too big\n", n);
2027c478bd9Sstevel@tonic-gate #endif
2037c478bd9Sstevel@tonic-gate 			break;
2047c478bd9Sstevel@tonic-gate 		}
2057c478bd9Sstevel@tonic-gate #ifdef SYSV
2067c478bd9Sstevel@tonic-gate 		memcpy((void *)(*hap++ = bp), (void *)cp, n);
2077c478bd9Sstevel@tonic-gate #else
2087c478bd9Sstevel@tonic-gate 		bcopy(cp, *hap++ = bp, n);
2097c478bd9Sstevel@tonic-gate #endif
2107c478bd9Sstevel@tonic-gate 		bp += n;
2117c478bd9Sstevel@tonic-gate 		cp += n;
2127c478bd9Sstevel@tonic-gate 		haveanswer++;
2137c478bd9Sstevel@tonic-gate 	}
2147c478bd9Sstevel@tonic-gate 	if (haveanswer) {
2157c478bd9Sstevel@tonic-gate 		*ap = NULL;
2167c478bd9Sstevel@tonic-gate #if BSD >= 43 || defined(h_addr)	/* new-style hostent structure */
2177c478bd9Sstevel@tonic-gate 		*hap = NULL;
2187c478bd9Sstevel@tonic-gate #else
2197c478bd9Sstevel@tonic-gate 		host.h_addr = h_addr_ptrs[0];
2207c478bd9Sstevel@tonic-gate #endif
2217c478bd9Sstevel@tonic-gate 		return (&host);
2227c478bd9Sstevel@tonic-gate 	} else {
2237c478bd9Sstevel@tonic-gate 		h_errno = TRY_AGAIN;
2247c478bd9Sstevel@tonic-gate 		return ((struct hostent *) NULL);
2257c478bd9Sstevel@tonic-gate 	}
2267c478bd9Sstevel@tonic-gate }
2277c478bd9Sstevel@tonic-gate 
228d67944fbSScott Rotondo static struct hostent *_gethtbyname();
229d67944fbSScott Rotondo 
2307c478bd9Sstevel@tonic-gate struct hostent *
res_gethostbyname(name)2317c478bd9Sstevel@tonic-gate res_gethostbyname(name)
2327c478bd9Sstevel@tonic-gate 	char *name;
2337c478bd9Sstevel@tonic-gate {
2347c478bd9Sstevel@tonic-gate 	querybuf buf;
2357c478bd9Sstevel@tonic-gate 	register char *cp;
2367c478bd9Sstevel@tonic-gate 	int n;
2377c478bd9Sstevel@tonic-gate 
2387c478bd9Sstevel@tonic-gate 	/*
2397c478bd9Sstevel@tonic-gate 	 * disallow names consisting only of digits/dots, unless
2407c478bd9Sstevel@tonic-gate 	 * they end in a dot.
2417c478bd9Sstevel@tonic-gate 	 */
2427c478bd9Sstevel@tonic-gate 	if (isdigit(name[0]))
2437c478bd9Sstevel@tonic-gate 		for (cp = name; /*EMPTY*/; ++cp) {
2447c478bd9Sstevel@tonic-gate 			if (!*cp) {
2457c478bd9Sstevel@tonic-gate 				if (*--cp == '.')
2467c478bd9Sstevel@tonic-gate 					break;
2477c478bd9Sstevel@tonic-gate 				h_errno = HOST_NOT_FOUND;
2487c478bd9Sstevel@tonic-gate 				return ((struct hostent *) NULL);
2497c478bd9Sstevel@tonic-gate 			}
2507c478bd9Sstevel@tonic-gate 			if (!isdigit(*cp) && *cp != '.')
2517c478bd9Sstevel@tonic-gate 				break;
2527c478bd9Sstevel@tonic-gate 		}
2537c478bd9Sstevel@tonic-gate 
2547c478bd9Sstevel@tonic-gate 	if ((n = res_search(name, C_IN, T_A, buf.buf, sizeof (buf))) < 0) {
2557c478bd9Sstevel@tonic-gate #ifdef DEBUG
2567c478bd9Sstevel@tonic-gate 		if (_res.options & RES_DEBUG)
2577c478bd9Sstevel@tonic-gate 			printf("res_search failed\n");
2587c478bd9Sstevel@tonic-gate #endif
2597c478bd9Sstevel@tonic-gate 		if (errno == ECONNREFUSED)
2607c478bd9Sstevel@tonic-gate 			return (_gethtbyname(name));
2617c478bd9Sstevel@tonic-gate 		else
2627c478bd9Sstevel@tonic-gate 			return ((struct hostent *) NULL);
2637c478bd9Sstevel@tonic-gate 	}
2647c478bd9Sstevel@tonic-gate 	return (getanswer(&buf, n, 0));
2657c478bd9Sstevel@tonic-gate }
2667c478bd9Sstevel@tonic-gate 
267d67944fbSScott Rotondo static struct hostent *_gethtbyaddr();
268d67944fbSScott Rotondo 
2697c478bd9Sstevel@tonic-gate static struct hostent *
_getrhbyaddr(addr,len,type)2707c478bd9Sstevel@tonic-gate _getrhbyaddr(addr, len, type)
2717c478bd9Sstevel@tonic-gate 	char *addr;
2727c478bd9Sstevel@tonic-gate 	int len, type;
2737c478bd9Sstevel@tonic-gate {
2747c478bd9Sstevel@tonic-gate 	int n;
2757c478bd9Sstevel@tonic-gate 	querybuf buf;
2767c478bd9Sstevel@tonic-gate 	register struct hostent *hp;
2777c478bd9Sstevel@tonic-gate 	char qbuf[MAXDNAME];
2787c478bd9Sstevel@tonic-gate 
2797c478bd9Sstevel@tonic-gate 	if (type != AF_INET)
2807c478bd9Sstevel@tonic-gate 		return ((struct hostent *) NULL);
2817c478bd9Sstevel@tonic-gate 	(void) sprintf(qbuf, "%d.%d.%d.%d.in-addr.arpa",
2827c478bd9Sstevel@tonic-gate 		((unsigned)addr[3] & 0xff),
2837c478bd9Sstevel@tonic-gate 		((unsigned)addr[2] & 0xff),
2847c478bd9Sstevel@tonic-gate 		((unsigned)addr[1] & 0xff),
2857c478bd9Sstevel@tonic-gate 		((unsigned)addr[0] & 0xff));
286*bd0e95e6SGary Mills 	n = res_query(qbuf, C_IN, T_PTR, (u_char *)&buf, sizeof (buf));
2877c478bd9Sstevel@tonic-gate 	if (n < 0) {
2887c478bd9Sstevel@tonic-gate #ifdef DEBUG
2897c478bd9Sstevel@tonic-gate 		if (_res.options & RES_DEBUG)
2907c478bd9Sstevel@tonic-gate 			printf("res_query failed\n");
2917c478bd9Sstevel@tonic-gate #endif
2927c478bd9Sstevel@tonic-gate 		if (errno == ECONNREFUSED)
2937c478bd9Sstevel@tonic-gate 			return (_gethtbyaddr(addr, len, type));
2947c478bd9Sstevel@tonic-gate 		return ((struct hostent *) NULL);
2957c478bd9Sstevel@tonic-gate 	}
2967c478bd9Sstevel@tonic-gate 	hp = getanswer(&buf, n, 1);
2977c478bd9Sstevel@tonic-gate 	if (hp == NULL)
2987c478bd9Sstevel@tonic-gate 		return ((struct hostent *) NULL);
2997c478bd9Sstevel@tonic-gate 	hp->h_addrtype = type;
3007c478bd9Sstevel@tonic-gate 	hp->h_length = len;
3017c478bd9Sstevel@tonic-gate 	h_addr_ptrs[0] = (char *)&host_addr;
3027c478bd9Sstevel@tonic-gate 	h_addr_ptrs[1] = (char *)0;
3037c478bd9Sstevel@tonic-gate 	host_addr = *(struct in_addr *)addr;
3047c478bd9Sstevel@tonic-gate 	return (hp);
3057c478bd9Sstevel@tonic-gate }
3067c478bd9Sstevel@tonic-gate 
3077c478bd9Sstevel@tonic-gate /*
3087c478bd9Sstevel@tonic-gate  * First we get what the PTR record says, but do an extra call
3097c478bd9Sstevel@tonic-gate  * to gethostbyname() to make sure that someone is not trying to
3107c478bd9Sstevel@tonic-gate  * spoof us.  Hopefully this is not done that often, so good
3117c478bd9Sstevel@tonic-gate  * performance is not really an issue.
3127c478bd9Sstevel@tonic-gate  */
3137c478bd9Sstevel@tonic-gate struct hostent *
res_gethostbyaddr(addr,len,type)3147c478bd9Sstevel@tonic-gate res_gethostbyaddr(addr, len, type)
3157c478bd9Sstevel@tonic-gate 	char	*addr;
3167c478bd9Sstevel@tonic-gate 	int	len;
3177c478bd9Sstevel@tonic-gate 	int	type;
3187c478bd9Sstevel@tonic-gate {
3197c478bd9Sstevel@tonic-gate 	char		**a, hbuf[MAXHOSTNAMELEN];
3207c478bd9Sstevel@tonic-gate 	struct hostent	*hp, *hp2;
3217c478bd9Sstevel@tonic-gate 
3227c478bd9Sstevel@tonic-gate 	if ((hp = _getrhbyaddr(addr, len, type)) == (struct hostent *)NULL)
3237c478bd9Sstevel@tonic-gate 		return ((struct hostent *)NULL);
3247c478bd9Sstevel@tonic-gate 
3257c478bd9Sstevel@tonic-gate 	/* hang on to what we got as an answer */
3267c478bd9Sstevel@tonic-gate 	(void) strcpy(hbuf, hp->h_name);
3277c478bd9Sstevel@tonic-gate 
3287c478bd9Sstevel@tonic-gate 	/* check to make sure by doing a forward query */
3297c478bd9Sstevel@tonic-gate 	if ((hp2 = res_gethostbyname(hbuf)) != (struct hostent *)NULL)
3307c478bd9Sstevel@tonic-gate 		for (a = hp2->h_addr_list; *a; a++)
3317c478bd9Sstevel@tonic-gate #ifdef SYSV
3327c478bd9Sstevel@tonic-gate 			if (memcmp(*a, addr, hp2->h_length) == 0)
3337c478bd9Sstevel@tonic-gate #else
3347c478bd9Sstevel@tonic-gate 			if (bcmp(*a, addr, hp2->h_length) == 0)
3357c478bd9Sstevel@tonic-gate #endif
3367c478bd9Sstevel@tonic-gate 				return (hp2);
3377c478bd9Sstevel@tonic-gate 
3387c478bd9Sstevel@tonic-gate 	/*
3397c478bd9Sstevel@tonic-gate 	 * we've been spoofed, make sure to log it.
3407c478bd9Sstevel@tonic-gate 	 * XXX - syslog needs a security priority level.
3417c478bd9Sstevel@tonic-gate 	 */
3427c478bd9Sstevel@tonic-gate 	syslog(LOG_NOTICE, "gethostbyaddr: %s != %s", hbuf,
3437c478bd9Sstevel@tonic-gate 		inet_ntoa(*(struct in_addr *)addr));
3447c478bd9Sstevel@tonic-gate 	return ((struct hostent *)NULL);
3457c478bd9Sstevel@tonic-gate }
3467c478bd9Sstevel@tonic-gate 
3476a1c6faaSanay static void
_sethtent(int f)3486a1c6faaSanay _sethtent(int f)
3497c478bd9Sstevel@tonic-gate {
3506a1c6faaSanay 	if (__res_no_hosts_fallback()) return;
3517c478bd9Sstevel@tonic-gate 
3527c478bd9Sstevel@tonic-gate 	if (hostf == NULL)
3537c478bd9Sstevel@tonic-gate 		hostf = fopen(HOSTDB, "r");
3547c478bd9Sstevel@tonic-gate 	else
3557c478bd9Sstevel@tonic-gate 		rewind(hostf);
3567c478bd9Sstevel@tonic-gate 	stayopen |= f;
3577c478bd9Sstevel@tonic-gate }
3587c478bd9Sstevel@tonic-gate 
3596a1c6faaSanay static void
_endhtent(void)3606a1c6faaSanay _endhtent(void)
3617c478bd9Sstevel@tonic-gate {
3626a1c6faaSanay 	if (__res_no_hosts_fallback()) return;
3637c478bd9Sstevel@tonic-gate 
3647c478bd9Sstevel@tonic-gate 	if (hostf && !stayopen) {
3657c478bd9Sstevel@tonic-gate 		(void) fclose(hostf);
3667c478bd9Sstevel@tonic-gate 		hostf = NULL;
3677c478bd9Sstevel@tonic-gate 	}
3687c478bd9Sstevel@tonic-gate }
3697c478bd9Sstevel@tonic-gate 
3707c478bd9Sstevel@tonic-gate static struct hostent *
_gethtent()3717c478bd9Sstevel@tonic-gate _gethtent()
3727c478bd9Sstevel@tonic-gate {
3737c478bd9Sstevel@tonic-gate 	char *p;
3747c478bd9Sstevel@tonic-gate 	register char *cp, **q;
3757c478bd9Sstevel@tonic-gate 
3767c478bd9Sstevel@tonic-gate 	if (__res_no_hosts_fallback()) return(NULL);
3777c478bd9Sstevel@tonic-gate 
3787c478bd9Sstevel@tonic-gate 	if (hostf == NULL && (hostf = fopen(HOSTDB, "r")) == NULL)
3797c478bd9Sstevel@tonic-gate 		return (NULL);
3807c478bd9Sstevel@tonic-gate again:
3817c478bd9Sstevel@tonic-gate 	if ((p = fgets(hostbuf, BUFSIZ, hostf)) == NULL)
3827c478bd9Sstevel@tonic-gate 		return (NULL);
3837c478bd9Sstevel@tonic-gate 	if (*p == '#')
3847c478bd9Sstevel@tonic-gate 		goto again;
3857c478bd9Sstevel@tonic-gate 	cp = any(p, "#\n");
3867c478bd9Sstevel@tonic-gate 	if (cp == NULL)
3877c478bd9Sstevel@tonic-gate 		goto again;
3887c478bd9Sstevel@tonic-gate 	*cp = '\0';
3897c478bd9Sstevel@tonic-gate 	cp = any(p, " \t");
3907c478bd9Sstevel@tonic-gate 	if (cp == NULL)
3917c478bd9Sstevel@tonic-gate 		goto again;
3927c478bd9Sstevel@tonic-gate 	*cp++ = '\0';
3937c478bd9Sstevel@tonic-gate 	/* THIS STUFF IS INTERNET SPECIFIC */
3947c478bd9Sstevel@tonic-gate #if BSD >= 43 || defined(h_addr)	/* new-style hostent structure */
3957c478bd9Sstevel@tonic-gate 	host.h_addr_list = host_addrs;
3967c478bd9Sstevel@tonic-gate #endif
3977c478bd9Sstevel@tonic-gate 	host.h_addr = hostaddr;
3987c478bd9Sstevel@tonic-gate 	*((u_long *)host.h_addr) = inet_addr(p);
3997c478bd9Sstevel@tonic-gate 	host.h_length = sizeof (u_long);
4007c478bd9Sstevel@tonic-gate 	host.h_addrtype = AF_INET;
4017c478bd9Sstevel@tonic-gate 	while (*cp == ' ' || *cp == '\t')
4027c478bd9Sstevel@tonic-gate 		cp++;
4037c478bd9Sstevel@tonic-gate 	host.h_name = cp;
4047c478bd9Sstevel@tonic-gate 	q = host.h_aliases = host_aliases;
4057c478bd9Sstevel@tonic-gate 	cp = any(cp, " \t");
4067c478bd9Sstevel@tonic-gate 	if (cp != NULL)
4077c478bd9Sstevel@tonic-gate 		*cp++ = '\0';
4087c478bd9Sstevel@tonic-gate 	while (cp && *cp) {
4097c478bd9Sstevel@tonic-gate 		if (*cp == ' ' || *cp == '\t') {
4107c478bd9Sstevel@tonic-gate 			cp++;
4117c478bd9Sstevel@tonic-gate 			continue;
4127c478bd9Sstevel@tonic-gate 		}
4137c478bd9Sstevel@tonic-gate 		if (q < &host_aliases[MAXALIASES - 1])
4147c478bd9Sstevel@tonic-gate 			*q++ = cp;
4157c478bd9Sstevel@tonic-gate 		cp = any(cp, " \t");
4167c478bd9Sstevel@tonic-gate 		if (cp != NULL)
4177c478bd9Sstevel@tonic-gate 			*cp++ = '\0';
4187c478bd9Sstevel@tonic-gate 	}
4197c478bd9Sstevel@tonic-gate 	*q = NULL;
4207c478bd9Sstevel@tonic-gate 	return (&host);
4217c478bd9Sstevel@tonic-gate }
4227c478bd9Sstevel@tonic-gate 
4237c478bd9Sstevel@tonic-gate static char *
any(cp,match)4247c478bd9Sstevel@tonic-gate any(cp, match)
4257c478bd9Sstevel@tonic-gate 	register char *cp;
4267c478bd9Sstevel@tonic-gate 	char *match;
4277c478bd9Sstevel@tonic-gate {
4287c478bd9Sstevel@tonic-gate 	register char *mp, c;
4297c478bd9Sstevel@tonic-gate 
4307c478bd9Sstevel@tonic-gate 	while (c = *cp) {
4317c478bd9Sstevel@tonic-gate 		for (mp = match; *mp; mp++)
4327c478bd9Sstevel@tonic-gate 			if (*mp == c)
4337c478bd9Sstevel@tonic-gate 				return (cp);
4347c478bd9Sstevel@tonic-gate 		cp++;
4357c478bd9Sstevel@tonic-gate 	}
4367c478bd9Sstevel@tonic-gate 	return ((char *)0);
4377c478bd9Sstevel@tonic-gate }
4387c478bd9Sstevel@tonic-gate 
4397c478bd9Sstevel@tonic-gate static struct hostent *
_gethtbyname(name)4407c478bd9Sstevel@tonic-gate _gethtbyname(name)
4417c478bd9Sstevel@tonic-gate 	char *name;
4427c478bd9Sstevel@tonic-gate {
4437c478bd9Sstevel@tonic-gate 	register struct hostent *p;
4447c478bd9Sstevel@tonic-gate 	register char **cp;
4457c478bd9Sstevel@tonic-gate 
4467c478bd9Sstevel@tonic-gate 	_sethtent(0);
4477c478bd9Sstevel@tonic-gate 	while (p = _gethtent()) {
4487c478bd9Sstevel@tonic-gate 		if (strcasecmp(p->h_name, name) == 0)
4497c478bd9Sstevel@tonic-gate 			break;
4507c478bd9Sstevel@tonic-gate 		for (cp = p->h_aliases; *cp != 0; cp++)
4517c478bd9Sstevel@tonic-gate 			if (strcasecmp(*cp, name) == 0)
4527c478bd9Sstevel@tonic-gate 				goto found;
4537c478bd9Sstevel@tonic-gate 	}
4547c478bd9Sstevel@tonic-gate found:
4557c478bd9Sstevel@tonic-gate 	_endhtent();
4567c478bd9Sstevel@tonic-gate 	return (p);
4577c478bd9Sstevel@tonic-gate }
4587c478bd9Sstevel@tonic-gate 
4597c478bd9Sstevel@tonic-gate static struct hostent *
_gethtbyaddr(addr,len,type)4607c478bd9Sstevel@tonic-gate _gethtbyaddr(addr, len, type)
4617c478bd9Sstevel@tonic-gate 	char *addr;
4627c478bd9Sstevel@tonic-gate 	int len, type;
4637c478bd9Sstevel@tonic-gate {
4647c478bd9Sstevel@tonic-gate 	register struct hostent *p;
4657c478bd9Sstevel@tonic-gate 
4667c478bd9Sstevel@tonic-gate 	_sethtent(0);
4677c478bd9Sstevel@tonic-gate 	while (p = _gethtent())
4687c478bd9Sstevel@tonic-gate #ifdef SYSV
4697c478bd9Sstevel@tonic-gate 		if (p->h_addrtype == type && !memcmp(p->h_addr, addr, len))
4707c478bd9Sstevel@tonic-gate #else
4717c478bd9Sstevel@tonic-gate 		if (p->h_addrtype == type && !bcmp(p->h_addr, addr, len))
4727c478bd9Sstevel@tonic-gate #endif
4737c478bd9Sstevel@tonic-gate 			break;
4747c478bd9Sstevel@tonic-gate 	_endhtent();
4757c478bd9Sstevel@tonic-gate 	return (p);
4767c478bd9Sstevel@tonic-gate }
477