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