xref: /onnv-gate/usr/src/lib/libresolv/res_gethost.c (revision 9694:78fafb281255)
16812Sraf /*
2*9694SScott.Rotondo@Sun.COM  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
36812Sraf  * Use is subject to license terms.
46812Sraf  */
56812Sraf 
60Sstevel@tonic-gate /*
70Sstevel@tonic-gate  * Copyright (c) 1985, 1988 Regents of the University of California.
80Sstevel@tonic-gate  * All rights reserved.
90Sstevel@tonic-gate  *
100Sstevel@tonic-gate  * Redistribution and use in source and binary forms are permitted
110Sstevel@tonic-gate  * provided that this notice is preserved and that due credit is given
120Sstevel@tonic-gate  * to the University of California at Berkeley. The name of the University
130Sstevel@tonic-gate  * may not be used to endorse or promote products derived from this
140Sstevel@tonic-gate  * software without specific prior written permission. This software
150Sstevel@tonic-gate  * is provided ``as is'' without express or implied warranty.
160Sstevel@tonic-gate  *
170Sstevel@tonic-gate  */
180Sstevel@tonic-gate 
190Sstevel@tonic-gate #include <sys/param.h>
200Sstevel@tonic-gate #include <sys/socket.h>
210Sstevel@tonic-gate #include <netinet/in.h>
220Sstevel@tonic-gate #include <ctype.h>
230Sstevel@tonic-gate #include <netdb.h>
240Sstevel@tonic-gate #include <stdio.h>
250Sstevel@tonic-gate #include <errno.h>
260Sstevel@tonic-gate #include <arpa/inet.h>
270Sstevel@tonic-gate #include <arpa/nameser.h>
280Sstevel@tonic-gate #include <resolv.h>
290Sstevel@tonic-gate #include <syslog.h>
300Sstevel@tonic-gate 
310Sstevel@tonic-gate /*
320Sstevel@tonic-gate  * When the name service switch calls libresolv, it doesn't want fallback
330Sstevel@tonic-gate  * to /etc/hosts, so we provide a method to turn it off.
340Sstevel@tonic-gate  */
350Sstevel@tonic-gate static int	no_hosts_fallback = 0;
360Sstevel@tonic-gate 
370Sstevel@tonic-gate void
__res_set_no_hosts_fallback(void)380Sstevel@tonic-gate __res_set_no_hosts_fallback(void) {
390Sstevel@tonic-gate 	no_hosts_fallback = 1;
400Sstevel@tonic-gate }
410Sstevel@tonic-gate 
420Sstevel@tonic-gate static int
__res_no_hosts_fallback(void)430Sstevel@tonic-gate __res_no_hosts_fallback(void) {
440Sstevel@tonic-gate 	return(no_hosts_fallback);
450Sstevel@tonic-gate }
460Sstevel@tonic-gate 
470Sstevel@tonic-gate static char *h_addr_ptrs[MAXADDRS + 1];
480Sstevel@tonic-gate 
490Sstevel@tonic-gate static struct hostent host;
500Sstevel@tonic-gate static char *host_aliases[MAXALIASES];
510Sstevel@tonic-gate static char hostbuf[BUFSIZ+1];
520Sstevel@tonic-gate static struct in_addr host_addr;
530Sstevel@tonic-gate static char HOSTDB[] = "/etc/hosts";
540Sstevel@tonic-gate static FILE *hostf = NULL;
550Sstevel@tonic-gate static char hostaddr[MAXADDRS];
560Sstevel@tonic-gate static char *host_addrs[2];
570Sstevel@tonic-gate static int stayopen = 0;
580Sstevel@tonic-gate static char *any();
590Sstevel@tonic-gate 
600Sstevel@tonic-gate #if PACKETSZ > 1024
610Sstevel@tonic-gate #define	MAXPACKET	PACKETSZ
620Sstevel@tonic-gate #else
630Sstevel@tonic-gate #define	MAXPACKET	1024
640Sstevel@tonic-gate #endif
650Sstevel@tonic-gate 
660Sstevel@tonic-gate typedef union {
670Sstevel@tonic-gate 	HEADER hdr;
680Sstevel@tonic-gate 	u_char buf[MAXPACKET];
690Sstevel@tonic-gate } querybuf;
700Sstevel@tonic-gate 
710Sstevel@tonic-gate static union {
720Sstevel@tonic-gate 	long al;
730Sstevel@tonic-gate 	char ac;
740Sstevel@tonic-gate } align;
750Sstevel@tonic-gate 
760Sstevel@tonic-gate 
770Sstevel@tonic-gate int h_errno;
780Sstevel@tonic-gate 
790Sstevel@tonic-gate static struct hostent *
getanswer(answer,anslen,iquery)800Sstevel@tonic-gate getanswer(answer, anslen, iquery)
810Sstevel@tonic-gate 	querybuf *answer;
820Sstevel@tonic-gate 	int anslen;
830Sstevel@tonic-gate 	int iquery;
840Sstevel@tonic-gate {
850Sstevel@tonic-gate 	register HEADER *hp;
860Sstevel@tonic-gate 	register u_char *cp;
870Sstevel@tonic-gate 	register int n;
880Sstevel@tonic-gate 	u_char *eom;
890Sstevel@tonic-gate 	char *bp, **ap;
900Sstevel@tonic-gate 	int type, class, buflen, ancount, qdcount;
910Sstevel@tonic-gate 	int haveanswer, getclass = C_ANY;
920Sstevel@tonic-gate 	char **hap;
930Sstevel@tonic-gate 
940Sstevel@tonic-gate 	eom = answer->buf + anslen;
950Sstevel@tonic-gate 	/*
960Sstevel@tonic-gate 	 * find first satisfactory answer
970Sstevel@tonic-gate 	 */
980Sstevel@tonic-gate 	hp = &answer->hdr;
990Sstevel@tonic-gate 	ancount = ntohs(hp->ancount);
1000Sstevel@tonic-gate 	qdcount = ntohs(hp->qdcount);
1010Sstevel@tonic-gate 	bp = hostbuf;
1020Sstevel@tonic-gate 	buflen = sizeof (hostbuf);
1030Sstevel@tonic-gate 	cp = answer->buf + sizeof (HEADER);
1040Sstevel@tonic-gate 	if (qdcount) {
1050Sstevel@tonic-gate 		if (iquery) {
1060Sstevel@tonic-gate 			if ((n = dn_expand((char *)answer->buf, eom,
1070Sstevel@tonic-gate 						cp, bp, buflen)) < 0) {
1080Sstevel@tonic-gate 				h_errno = NO_RECOVERY;
1090Sstevel@tonic-gate 				return ((struct hostent *) NULL);
1100Sstevel@tonic-gate 			}
1110Sstevel@tonic-gate 			cp += n + QFIXEDSZ;
1120Sstevel@tonic-gate 			host.h_name = bp;
1130Sstevel@tonic-gate 			n = strlen(bp) + 1;
1140Sstevel@tonic-gate 			bp += n;
1150Sstevel@tonic-gate 			buflen -= n;
1160Sstevel@tonic-gate 		} else
1170Sstevel@tonic-gate 			cp += dn_skipname(cp, eom) + QFIXEDSZ;
1180Sstevel@tonic-gate 		while (--qdcount > 0)
1190Sstevel@tonic-gate 			cp += dn_skipname(cp, eom) + QFIXEDSZ;
1200Sstevel@tonic-gate 	} else if (iquery) {
1210Sstevel@tonic-gate 		if (hp->aa)
1220Sstevel@tonic-gate 			h_errno = HOST_NOT_FOUND;
1230Sstevel@tonic-gate 		else
1240Sstevel@tonic-gate 			h_errno = TRY_AGAIN;
1250Sstevel@tonic-gate 		return ((struct hostent *) NULL);
1260Sstevel@tonic-gate 	}
1270Sstevel@tonic-gate 	ap = host_aliases;
1280Sstevel@tonic-gate 	host.h_aliases = host_aliases;
1290Sstevel@tonic-gate 	hap = h_addr_ptrs;
1300Sstevel@tonic-gate #if BSD >= 43 || defined(h_addr)	/* new-style hostent structure */
1310Sstevel@tonic-gate 	host.h_addr_list = h_addr_ptrs;
1320Sstevel@tonic-gate #endif
1330Sstevel@tonic-gate 	haveanswer = 0;
1340Sstevel@tonic-gate 	while (--ancount >= 0 && cp < eom && haveanswer < MAXADDRS) {
1350Sstevel@tonic-gate 		if ((n = dn_expand((char *)answer->buf, eom,
1360Sstevel@tonic-gate 						cp, bp, buflen)) < 0)
1370Sstevel@tonic-gate 			break;
1380Sstevel@tonic-gate 		cp += n;
1390Sstevel@tonic-gate 		type = _getshort(cp);
1400Sstevel@tonic-gate 		cp += sizeof (u_short);
1410Sstevel@tonic-gate 		class = _getshort(cp);
1420Sstevel@tonic-gate 		cp += sizeof (u_short) + sizeof (u_long);
1430Sstevel@tonic-gate 		n = _getshort(cp);
1440Sstevel@tonic-gate 		cp += sizeof (u_short);
1450Sstevel@tonic-gate 		if (type == T_CNAME) {
1460Sstevel@tonic-gate 			cp += n;
1470Sstevel@tonic-gate 			if (ap >= &host_aliases[MAXALIASES-1])
1480Sstevel@tonic-gate 				continue;
1490Sstevel@tonic-gate 			*ap++ = bp;
1500Sstevel@tonic-gate 			n = strlen(bp) + 1;
1510Sstevel@tonic-gate 			bp += n;
1520Sstevel@tonic-gate 			buflen -= n;
1530Sstevel@tonic-gate 			continue;
1540Sstevel@tonic-gate 		}
1550Sstevel@tonic-gate 		if (iquery && type == T_PTR) {
1560Sstevel@tonic-gate 			if ((n = dn_expand((char *)answer->buf, eom,
1570Sstevel@tonic-gate 					cp, bp, buflen)) < 0) {
1580Sstevel@tonic-gate 				cp += n;
1590Sstevel@tonic-gate 				continue;
1600Sstevel@tonic-gate 			}
1610Sstevel@tonic-gate 			cp += n;
1620Sstevel@tonic-gate 			host.h_name = bp;
1630Sstevel@tonic-gate 			return (&host);
1640Sstevel@tonic-gate 		}
1650Sstevel@tonic-gate 		if (iquery || type != T_A) {
1660Sstevel@tonic-gate #ifdef DEBUG
1670Sstevel@tonic-gate 			if (_res.options & RES_DEBUG)
1680Sstevel@tonic-gate 				printf("unexpected answer type %d, size %d\n",
1690Sstevel@tonic-gate 					type, n);
1700Sstevel@tonic-gate #endif
1710Sstevel@tonic-gate 			cp += n;
1720Sstevel@tonic-gate 			continue;
1730Sstevel@tonic-gate 		}
1740Sstevel@tonic-gate 		if (haveanswer) {
1750Sstevel@tonic-gate 			if (n != host.h_length) {
1760Sstevel@tonic-gate 				cp += n;
1770Sstevel@tonic-gate 				continue;
1780Sstevel@tonic-gate 			}
1790Sstevel@tonic-gate 			if (class != getclass) {
1800Sstevel@tonic-gate 				cp += n;
1810Sstevel@tonic-gate 				continue;
1820Sstevel@tonic-gate 			}
1830Sstevel@tonic-gate 		} else {
1840Sstevel@tonic-gate 			host.h_length = n;
1850Sstevel@tonic-gate 			getclass = class;
1860Sstevel@tonic-gate 			host.h_addrtype = (class == C_IN) ? AF_INET : AF_UNSPEC;
1870Sstevel@tonic-gate 			if (!iquery) {
1880Sstevel@tonic-gate 				host.h_name = bp;
1890Sstevel@tonic-gate 				bp += strlen(bp) + 1;
1900Sstevel@tonic-gate 			}
1910Sstevel@tonic-gate 		}
1920Sstevel@tonic-gate 
1930Sstevel@tonic-gate 		bp += sizeof (align) - ((u_long)bp % sizeof (align));
1940Sstevel@tonic-gate 
1950Sstevel@tonic-gate 		if (bp + n >= &hostbuf[sizeof (hostbuf)]) {
1960Sstevel@tonic-gate #ifdef DEBUG
1970Sstevel@tonic-gate 			if (_res.options & RES_DEBUG)
1980Sstevel@tonic-gate 				printf("size (%d) too big\n", n);
1990Sstevel@tonic-gate #endif
2000Sstevel@tonic-gate 			break;
2010Sstevel@tonic-gate 		}
2020Sstevel@tonic-gate #ifdef SYSV
2030Sstevel@tonic-gate 		memcpy((void *)(*hap++ = bp), (void *)cp, n);
2040Sstevel@tonic-gate #else
2050Sstevel@tonic-gate 		bcopy(cp, *hap++ = bp, n);
2060Sstevel@tonic-gate #endif
2070Sstevel@tonic-gate 		bp += n;
2080Sstevel@tonic-gate 		cp += n;
2090Sstevel@tonic-gate 		haveanswer++;
2100Sstevel@tonic-gate 	}
2110Sstevel@tonic-gate 	if (haveanswer) {
2120Sstevel@tonic-gate 		*ap = NULL;
2130Sstevel@tonic-gate #if BSD >= 43 || defined(h_addr)	/* new-style hostent structure */
2140Sstevel@tonic-gate 		*hap = NULL;
2150Sstevel@tonic-gate #else
2160Sstevel@tonic-gate 		host.h_addr = h_addr_ptrs[0];
2170Sstevel@tonic-gate #endif
2180Sstevel@tonic-gate 		return (&host);
2190Sstevel@tonic-gate 	} else {
2200Sstevel@tonic-gate 		h_errno = TRY_AGAIN;
2210Sstevel@tonic-gate 		return ((struct hostent *) NULL);
2220Sstevel@tonic-gate 	}
2230Sstevel@tonic-gate }
2240Sstevel@tonic-gate 
225*9694SScott.Rotondo@Sun.COM static struct hostent *_gethtbyname();
226*9694SScott.Rotondo@Sun.COM 
2270Sstevel@tonic-gate struct hostent *
res_gethostbyname(name)2280Sstevel@tonic-gate res_gethostbyname(name)
2290Sstevel@tonic-gate 	char *name;
2300Sstevel@tonic-gate {
2310Sstevel@tonic-gate 	querybuf buf;
2320Sstevel@tonic-gate 	register char *cp;
2330Sstevel@tonic-gate 	int n;
2340Sstevel@tonic-gate 	struct hostent *hp, *gethostdomain();
2350Sstevel@tonic-gate 
2360Sstevel@tonic-gate 	/*
2370Sstevel@tonic-gate 	 * disallow names consisting only of digits/dots, unless
2380Sstevel@tonic-gate 	 * they end in a dot.
2390Sstevel@tonic-gate 	 */
2400Sstevel@tonic-gate 	if (isdigit(name[0]))
2410Sstevel@tonic-gate 		for (cp = name; /*EMPTY*/; ++cp) {
2420Sstevel@tonic-gate 			if (!*cp) {
2430Sstevel@tonic-gate 				if (*--cp == '.')
2440Sstevel@tonic-gate 					break;
2450Sstevel@tonic-gate 				h_errno = HOST_NOT_FOUND;
2460Sstevel@tonic-gate 				return ((struct hostent *) NULL);
2470Sstevel@tonic-gate 			}
2480Sstevel@tonic-gate 			if (!isdigit(*cp) && *cp != '.')
2490Sstevel@tonic-gate 				break;
2500Sstevel@tonic-gate 		}
2510Sstevel@tonic-gate 
2520Sstevel@tonic-gate 	if ((n = res_search(name, C_IN, T_A, buf.buf, sizeof (buf))) < 0) {
2530Sstevel@tonic-gate #ifdef DEBUG
2540Sstevel@tonic-gate 		if (_res.options & RES_DEBUG)
2550Sstevel@tonic-gate 			printf("res_search failed\n");
2560Sstevel@tonic-gate #endif
2570Sstevel@tonic-gate 		if (errno == ECONNREFUSED)
2580Sstevel@tonic-gate 			return (_gethtbyname(name));
2590Sstevel@tonic-gate 		else
2600Sstevel@tonic-gate 			return ((struct hostent *) NULL);
2610Sstevel@tonic-gate 	}
2620Sstevel@tonic-gate 	return (getanswer(&buf, n, 0));
2630Sstevel@tonic-gate }
2640Sstevel@tonic-gate 
265*9694SScott.Rotondo@Sun.COM static struct hostent *_gethtbyaddr();
266*9694SScott.Rotondo@Sun.COM 
2670Sstevel@tonic-gate static struct hostent *
_getrhbyaddr(addr,len,type)2680Sstevel@tonic-gate _getrhbyaddr(addr, len, type)
2690Sstevel@tonic-gate 	char *addr;
2700Sstevel@tonic-gate 	int len, type;
2710Sstevel@tonic-gate {
2720Sstevel@tonic-gate 	int n;
2730Sstevel@tonic-gate 	querybuf buf;
2740Sstevel@tonic-gate 	register struct hostent *hp;
2750Sstevel@tonic-gate 	char qbuf[MAXDNAME];
2760Sstevel@tonic-gate 
2770Sstevel@tonic-gate 	if (type != AF_INET)
2780Sstevel@tonic-gate 		return ((struct hostent *) NULL);
2790Sstevel@tonic-gate 	(void) sprintf(qbuf, "%d.%d.%d.%d.in-addr.arpa",
2800Sstevel@tonic-gate 		((unsigned)addr[3] & 0xff),
2810Sstevel@tonic-gate 		((unsigned)addr[2] & 0xff),
2820Sstevel@tonic-gate 		((unsigned)addr[1] & 0xff),
2830Sstevel@tonic-gate 		((unsigned)addr[0] & 0xff));
2840Sstevel@tonic-gate 	n = res_query(qbuf, C_IN, T_PTR, (char *)&buf, sizeof (buf));
2850Sstevel@tonic-gate 	if (n < 0) {
2860Sstevel@tonic-gate #ifdef DEBUG
2870Sstevel@tonic-gate 		if (_res.options & RES_DEBUG)
2880Sstevel@tonic-gate 			printf("res_query failed\n");
2890Sstevel@tonic-gate #endif
2900Sstevel@tonic-gate 		if (errno == ECONNREFUSED)
2910Sstevel@tonic-gate 			return (_gethtbyaddr(addr, len, type));
2920Sstevel@tonic-gate 		return ((struct hostent *) NULL);
2930Sstevel@tonic-gate 	}
2940Sstevel@tonic-gate 	hp = getanswer(&buf, n, 1);
2950Sstevel@tonic-gate 	if (hp == NULL)
2960Sstevel@tonic-gate 		return ((struct hostent *) NULL);
2970Sstevel@tonic-gate 	hp->h_addrtype = type;
2980Sstevel@tonic-gate 	hp->h_length = len;
2990Sstevel@tonic-gate 	h_addr_ptrs[0] = (char *)&host_addr;
3000Sstevel@tonic-gate 	h_addr_ptrs[1] = (char *)0;
3010Sstevel@tonic-gate 	host_addr = *(struct in_addr *)addr;
3020Sstevel@tonic-gate 	return (hp);
3030Sstevel@tonic-gate }
3040Sstevel@tonic-gate 
3050Sstevel@tonic-gate /*
3060Sstevel@tonic-gate  * First we get what the PTR record says, but do an extra call
3070Sstevel@tonic-gate  * to gethostbyname() to make sure that someone is not trying to
3080Sstevel@tonic-gate  * spoof us.  Hopefully this is not done that often, so good
3090Sstevel@tonic-gate  * performance is not really an issue.
3100Sstevel@tonic-gate  */
3110Sstevel@tonic-gate struct hostent *
res_gethostbyaddr(addr,len,type)3120Sstevel@tonic-gate res_gethostbyaddr(addr, len, type)
3130Sstevel@tonic-gate 	char	*addr;
3140Sstevel@tonic-gate 	int	len;
3150Sstevel@tonic-gate 	int	type;
3160Sstevel@tonic-gate {
3170Sstevel@tonic-gate 	char		**a, hbuf[MAXHOSTNAMELEN];
3180Sstevel@tonic-gate 	struct hostent	*hp, *hp2;
3190Sstevel@tonic-gate 
3200Sstevel@tonic-gate 	if ((hp = _getrhbyaddr(addr, len, type)) == (struct hostent *)NULL)
3210Sstevel@tonic-gate 		return ((struct hostent *)NULL);
3220Sstevel@tonic-gate 
3230Sstevel@tonic-gate 	/* hang on to what we got as an answer */
3240Sstevel@tonic-gate 	(void) strcpy(hbuf, hp->h_name);
3250Sstevel@tonic-gate 
3260Sstevel@tonic-gate 	/* check to make sure by doing a forward query */
3270Sstevel@tonic-gate 	if ((hp2 = res_gethostbyname(hbuf)) != (struct hostent *)NULL)
3280Sstevel@tonic-gate 		for (a = hp2->h_addr_list; *a; a++)
3290Sstevel@tonic-gate #ifdef SYSV
3300Sstevel@tonic-gate 			if (memcmp(*a, addr, hp2->h_length) == 0)
3310Sstevel@tonic-gate #else
3320Sstevel@tonic-gate 			if (bcmp(*a, addr, hp2->h_length) == 0)
3330Sstevel@tonic-gate #endif
3340Sstevel@tonic-gate 				return (hp2);
3350Sstevel@tonic-gate 
3360Sstevel@tonic-gate 	/*
3370Sstevel@tonic-gate 	 * we've been spoofed, make sure to log it.
3380Sstevel@tonic-gate 	 * XXX - syslog needs a security priority level.
3390Sstevel@tonic-gate 	 */
3400Sstevel@tonic-gate 	syslog(LOG_NOTICE, "gethostbyaddr: %s != %s", hbuf,
3410Sstevel@tonic-gate 		inet_ntoa(*(struct in_addr *)addr));
3420Sstevel@tonic-gate 	return ((struct hostent *)NULL);
3430Sstevel@tonic-gate }
3440Sstevel@tonic-gate 
345237Sanay static void
_sethtent(int f)346237Sanay _sethtent(int f)
3470Sstevel@tonic-gate {
348237Sanay 	if (__res_no_hosts_fallback()) return;
3490Sstevel@tonic-gate 
3500Sstevel@tonic-gate 	if (hostf == NULL)
3510Sstevel@tonic-gate 		hostf = fopen(HOSTDB, "r");
3520Sstevel@tonic-gate 	else
3530Sstevel@tonic-gate 		rewind(hostf);
3540Sstevel@tonic-gate 	stayopen |= f;
3550Sstevel@tonic-gate }
3560Sstevel@tonic-gate 
357237Sanay static void
_endhtent(void)358237Sanay _endhtent(void)
3590Sstevel@tonic-gate {
360237Sanay 	if (__res_no_hosts_fallback()) return;
3610Sstevel@tonic-gate 
3620Sstevel@tonic-gate 	if (hostf && !stayopen) {
3630Sstevel@tonic-gate 		(void) fclose(hostf);
3640Sstevel@tonic-gate 		hostf = NULL;
3650Sstevel@tonic-gate 	}
3660Sstevel@tonic-gate }
3670Sstevel@tonic-gate 
3680Sstevel@tonic-gate static struct hostent *
_gethtent()3690Sstevel@tonic-gate _gethtent()
3700Sstevel@tonic-gate {
3710Sstevel@tonic-gate 	char *p;
3720Sstevel@tonic-gate 	register char *cp, **q;
3730Sstevel@tonic-gate 
3740Sstevel@tonic-gate 	if (__res_no_hosts_fallback()) return(NULL);
3750Sstevel@tonic-gate 
3760Sstevel@tonic-gate 	if (hostf == NULL && (hostf = fopen(HOSTDB, "r")) == NULL)
3770Sstevel@tonic-gate 		return (NULL);
3780Sstevel@tonic-gate again:
3790Sstevel@tonic-gate 	if ((p = fgets(hostbuf, BUFSIZ, hostf)) == NULL)
3800Sstevel@tonic-gate 		return (NULL);
3810Sstevel@tonic-gate 	if (*p == '#')
3820Sstevel@tonic-gate 		goto again;
3830Sstevel@tonic-gate 	cp = any(p, "#\n");
3840Sstevel@tonic-gate 	if (cp == NULL)
3850Sstevel@tonic-gate 		goto again;
3860Sstevel@tonic-gate 	*cp = '\0';
3870Sstevel@tonic-gate 	cp = any(p, " \t");
3880Sstevel@tonic-gate 	if (cp == NULL)
3890Sstevel@tonic-gate 		goto again;
3900Sstevel@tonic-gate 	*cp++ = '\0';
3910Sstevel@tonic-gate 	/* THIS STUFF IS INTERNET SPECIFIC */
3920Sstevel@tonic-gate #if BSD >= 43 || defined(h_addr)	/* new-style hostent structure */
3930Sstevel@tonic-gate 	host.h_addr_list = host_addrs;
3940Sstevel@tonic-gate #endif
3950Sstevel@tonic-gate 	host.h_addr = hostaddr;
3960Sstevel@tonic-gate 	*((u_long *)host.h_addr) = inet_addr(p);
3970Sstevel@tonic-gate 	host.h_length = sizeof (u_long);
3980Sstevel@tonic-gate 	host.h_addrtype = AF_INET;
3990Sstevel@tonic-gate 	while (*cp == ' ' || *cp == '\t')
4000Sstevel@tonic-gate 		cp++;
4010Sstevel@tonic-gate 	host.h_name = cp;
4020Sstevel@tonic-gate 	q = host.h_aliases = host_aliases;
4030Sstevel@tonic-gate 	cp = any(cp, " \t");
4040Sstevel@tonic-gate 	if (cp != NULL)
4050Sstevel@tonic-gate 		*cp++ = '\0';
4060Sstevel@tonic-gate 	while (cp && *cp) {
4070Sstevel@tonic-gate 		if (*cp == ' ' || *cp == '\t') {
4080Sstevel@tonic-gate 			cp++;
4090Sstevel@tonic-gate 			continue;
4100Sstevel@tonic-gate 		}
4110Sstevel@tonic-gate 		if (q < &host_aliases[MAXALIASES - 1])
4120Sstevel@tonic-gate 			*q++ = cp;
4130Sstevel@tonic-gate 		cp = any(cp, " \t");
4140Sstevel@tonic-gate 		if (cp != NULL)
4150Sstevel@tonic-gate 			*cp++ = '\0';
4160Sstevel@tonic-gate 	}
4170Sstevel@tonic-gate 	*q = NULL;
4180Sstevel@tonic-gate 	return (&host);
4190Sstevel@tonic-gate }
4200Sstevel@tonic-gate 
4210Sstevel@tonic-gate static char *
any(cp,match)4220Sstevel@tonic-gate any(cp, match)
4230Sstevel@tonic-gate 	register char *cp;
4240Sstevel@tonic-gate 	char *match;
4250Sstevel@tonic-gate {
4260Sstevel@tonic-gate 	register char *mp, c;
4270Sstevel@tonic-gate 
4280Sstevel@tonic-gate 	while (c = *cp) {
4290Sstevel@tonic-gate 		for (mp = match; *mp; mp++)
4300Sstevel@tonic-gate 			if (*mp == c)
4310Sstevel@tonic-gate 				return (cp);
4320Sstevel@tonic-gate 		cp++;
4330Sstevel@tonic-gate 	}
4340Sstevel@tonic-gate 	return ((char *)0);
4350Sstevel@tonic-gate }
4360Sstevel@tonic-gate 
4370Sstevel@tonic-gate static struct hostent *
_gethtbyname(name)4380Sstevel@tonic-gate _gethtbyname(name)
4390Sstevel@tonic-gate 	char *name;
4400Sstevel@tonic-gate {
4410Sstevel@tonic-gate 	register struct hostent *p;
4420Sstevel@tonic-gate 	register char **cp;
4430Sstevel@tonic-gate 
4440Sstevel@tonic-gate 	_sethtent(0);
4450Sstevel@tonic-gate 	while (p = _gethtent()) {
4460Sstevel@tonic-gate 		if (strcasecmp(p->h_name, name) == 0)
4470Sstevel@tonic-gate 			break;
4480Sstevel@tonic-gate 		for (cp = p->h_aliases; *cp != 0; cp++)
4490Sstevel@tonic-gate 			if (strcasecmp(*cp, name) == 0)
4500Sstevel@tonic-gate 				goto found;
4510Sstevel@tonic-gate 	}
4520Sstevel@tonic-gate found:
4530Sstevel@tonic-gate 	_endhtent();
4540Sstevel@tonic-gate 	return (p);
4550Sstevel@tonic-gate }
4560Sstevel@tonic-gate 
4570Sstevel@tonic-gate static struct hostent *
_gethtbyaddr(addr,len,type)4580Sstevel@tonic-gate _gethtbyaddr(addr, len, type)
4590Sstevel@tonic-gate 	char *addr;
4600Sstevel@tonic-gate 	int len, type;
4610Sstevel@tonic-gate {
4620Sstevel@tonic-gate 	register struct hostent *p;
4630Sstevel@tonic-gate 
4640Sstevel@tonic-gate 	_sethtent(0);
4650Sstevel@tonic-gate 	while (p = _gethtent())
4660Sstevel@tonic-gate #ifdef SYSV
4670Sstevel@tonic-gate 		if (p->h_addrtype == type && !memcmp(p->h_addr, addr, len))
4680Sstevel@tonic-gate #else
4690Sstevel@tonic-gate 		if (p->h_addrtype == type && !bcmp(p->h_addr, addr, len))
4700Sstevel@tonic-gate #endif
4710Sstevel@tonic-gate 			break;
4720Sstevel@tonic-gate 	_endhtent();
4730Sstevel@tonic-gate 	return (p);
4740Sstevel@tonic-gate }
475