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