gethostbydns.c revision 11661
13070Spst/*-
23070Spst * Copyright (c) 1985, 1988, 1993
33070Spst *	The Regents of the University of California.  All rights reserved.
43070Spst *
53070Spst * Redistribution and use in source and binary forms, with or without
63070Spst * modification, are permitted provided that the following conditions
73070Spst * are met:
83070Spst * 1. Redistributions of source code must retain the above copyright
93070Spst *    notice, this list of conditions and the following disclaimer.
103070Spst * 2. Redistributions in binary form must reproduce the above copyright
113070Spst *    notice, this list of conditions and the following disclaimer in the
123070Spst *    documentation and/or other materials provided with the distribution.
133070Spst * 3. All advertising materials mentioning features or use of this software
143070Spst *    must display the following acknowledgement:
153070Spst *	This product includes software developed by the University of
163070Spst *	California, Berkeley and its contributors.
173070Spst * 4. Neither the name of the University nor the names of its contributors
183070Spst *    may be used to endorse or promote products derived from this software
193070Spst *    without specific prior written permission.
203070Spst *
213070Spst * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
223070Spst * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
233070Spst * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
243070Spst * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
253070Spst * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
263070Spst * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
273070Spst * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
283070Spst * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
293070Spst * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
303070Spst * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
313070Spst * SUCH DAMAGE.
323070Spst * -
333070Spst * Portions Copyright (c) 1993 by Digital Equipment Corporation.
348870Srgrimes *
353070Spst * Permission to use, copy, modify, and distribute this software for any
363070Spst * purpose with or without fee is hereby granted, provided that the above
373070Spst * copyright notice and this permission notice appear in all copies, and that
383070Spst * the name of Digital Equipment Corporation not be used in advertising or
393070Spst * publicity pertaining to distribution of the document or software without
403070Spst * specific, written prior permission.
418870Srgrimes *
423070Spst * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
433070Spst * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
443070Spst * OF MERCHANTABILITY AND FITNESS.   IN NO EVENT SHALL DIGITAL EQUIPMENT
453070Spst * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
463070Spst * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
473070Spst * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
483070Spst * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
493070Spst * SOFTWARE.
503070Spst * -
513070Spst * --Copyright--
523070Spst */
533070Spst
543070Spst#if defined(LIBC_SCCS) && !defined(lint)
553070Spststatic char sccsid[] = "@(#)gethostnamadr.c	8.1 (Berkeley) 6/4/93";
5611661Sphkstatic char rcsid[] = "$Id: gethostbydns.c,v 1.6 1995/08/21 09:15:32 bde Exp $";
573070Spst#endif /* LIBC_SCCS and not lint */
583070Spst
593070Spst#include <sys/param.h>
603070Spst#include <sys/socket.h>
613070Spst#include <netinet/in.h>
623070Spst#include <arpa/inet.h>
633070Spst#include <arpa/nameser.h>
6410133Speter
6510133Speter#include <stdio.h>
6611661Sphk#include <unistd.h>
6710133Speter#include <string.h>
683070Spst#include <netdb.h>
693070Spst#include <resolv.h>
703070Spst#include <ctype.h>
713070Spst#include <errno.h>
723070Spst#include <syslog.h>
733070Spst
7410150Sbde#include "res_config.h"
753070Spst
763070Spst#define	MAXALIASES	35
773070Spst#define	MAXADDRS	35
783070Spst
793070Spst#define	MULTI_PTRS_ARE_ALIASES 1	/* XXX - experimental */
803070Spst
813070Spststatic const char AskedForGot[] =
8210133Speter		  "gethostby*.gethostanswer: asked for \"%s\", got \"%s\"";
833070Spst
843070Spststatic char *h_addr_ptrs[MAXADDRS + 1];
853070Spst
863070Spststatic struct hostent host;
873070Spststatic char *host_aliases[MAXALIASES];
883070Spststatic char hostbuf[8*1024];
893070Spststatic struct in_addr host_addr;
903070Spststatic FILE *hostf = NULL;
913070Spststatic int stayopen = 0;
923070Spst
933070Spst#if PACKETSZ > 1024
943070Spst#define	MAXPACKET	PACKETSZ
953070Spst#else
963070Spst#define	MAXPACKET	1024
973070Spst#endif
983070Spst
993070Spsttypedef union {
1003070Spst    HEADER hdr;
1013070Spst    u_char buf[MAXPACKET];
1023070Spst} querybuf;
1033070Spst
1043070Spsttypedef union {
1053070Spst    int32_t al;
1063070Spst    char ac;
1073070Spst} align;
1083070Spst
1093070Spstextern int h_errno;
1103070Spst
11110133Speter#ifdef DEBUG
11210133Speterstatic void
11310133Speterdprintf(msg, num)
11410133Speter	char *msg;
11510133Speter	int num;
11610133Speter{
11710133Speter	if (_res.options & RES_DEBUG) {
11810133Speter		int save = errno;
11910133Speter
12010133Speter		printf(msg, num);
12110133Speter		errno = save;
12210133Speter	}
12310133Speter}
12410133Speter#else
12510133Speter# define dprintf(msg, num) /*nada*/
12610133Speter#endif
12710133Speter
12810133Speter
1293070Spst#ifdef RESOLVSORT
1303070Spststatic void
1313070Spstaddrsort(ap, num)
1323070Spst	char **ap;
1333070Spst	int num;
1343070Spst{
1353070Spst	int i, j;
1363070Spst	char **p;
1373070Spst	short aval[MAXADDRS];
1383070Spst	int needsort = 0;
1393070Spst
1403070Spst	p = ap;
1413070Spst	for (i = 0; i < num; i++, p++) {
14210133Speter	    for (j = 0 ; (unsigned)j < _res.nsort; j++)
1438870Srgrimes		if (_res.sort_list[j].addr.s_addr ==
1443070Spst		    (((struct in_addr *)(*p))->s_addr & _res.sort_list[j].mask))
1453070Spst			break;
1463070Spst	    aval[i] = j;
1473070Spst	    if (needsort == 0 && i > 0 && j < aval[i-1])
1483070Spst		needsort = i;
1493070Spst	}
1503070Spst	if (!needsort)
1513070Spst	    return;
1523070Spst
1533070Spst	while (needsort < num) {
1543070Spst	    for (j = needsort - 1; j >= 0; j--) {
1553070Spst		if (aval[j] > aval[j+1]) {
1563070Spst		    char *hp;
1573070Spst
1583070Spst		    i = aval[j];
1593070Spst		    aval[j] = aval[j+1];
1603070Spst		    aval[j+1] = i;
1613070Spst
1623070Spst		    hp = ap[j];
1633070Spst		    ap[j] = ap[j+1];
1643070Spst		    ap[j+1] = hp;
1653070Spst
1663070Spst		} else
1673070Spst		    break;
1683070Spst	    }
1693070Spst	    needsort++;
1703070Spst	}
1713070Spst}
1723070Spst#endif
1733070Spst
1743070Spststatic struct hostent *
1753070Spstgethostanswer(answer, anslen, qname, qclass, qtype)
1763070Spst	const querybuf *answer;
1773070Spst	int anslen;
1783070Spst	const char *qname;
1793070Spst	int qclass, qtype;
1803070Spst{
1813070Spst	register const HEADER *hp;
1823070Spst	register const u_char *cp;
1833070Spst	register int n;
1843070Spst	const u_char *eom;
1853070Spst	char *bp, **ap, **hap;
1863070Spst	int type, class, buflen, ancount, qdcount;
1873070Spst	int haveanswer, had_error;
1883070Spst	int toobig = 0;
1893070Spst	char tbuf[MAXDNAME+1];
1903070Spst
1913070Spst	host.h_name = NULL;
1923070Spst	eom = answer->buf + anslen;
1933070Spst	/*
1943070Spst	 * find first satisfactory answer
1953070Spst	 */
1963070Spst	hp = &answer->hdr;
1973070Spst	ancount = ntohs(hp->ancount);
1983070Spst	qdcount = ntohs(hp->qdcount);
1993070Spst	bp = hostbuf;
2003070Spst	buflen = sizeof hostbuf;
2013070Spst	cp = answer->buf + HFIXEDSZ;
2023070Spst	if (qdcount != 1) {
2033070Spst		h_errno = NO_RECOVERY;
2043070Spst		return (NULL);
2053070Spst	}
2063070Spst	if ((n = dn_expand(answer->buf, eom, cp, bp, buflen)) < 0) {
2073070Spst		h_errno = NO_RECOVERY;
2083070Spst		return (NULL);
2093070Spst	}
2103070Spst	cp += n + QFIXEDSZ;
2113070Spst	if (qtype == T_A) {
2123070Spst		/* res_send() has already verified that the query name is the
2133070Spst		 * same as the one we sent; this just gets the expanded name
2143070Spst		 * (i.e., with the succeeding search-domain tacked on).
2153070Spst		 */
2163070Spst		n = strlen(bp) + 1;		/* for the \0 */
2173070Spst		host.h_name = bp;
2183070Spst		bp += n;
2193070Spst		buflen -= n;
2203070Spst		/* The qname can be abbreviated, but h_name is now absolute. */
2213070Spst		qname = host.h_name;
2223070Spst	}
2233070Spst	ap = host_aliases;
2243070Spst	*ap = NULL;
2253070Spst	host.h_aliases = host_aliases;
2263070Spst	hap = h_addr_ptrs;
2273070Spst	*hap = NULL;
2283070Spst	host.h_addr_list = h_addr_ptrs;
2293070Spst	haveanswer = 0;
2303070Spst	had_error = 0;
2313070Spst	while (ancount-- > 0 && cp < eom && !had_error) {
2323070Spst		n = dn_expand(answer->buf, eom, cp, bp, buflen);
2333070Spst		if (n < 0) {
2343070Spst			had_error++;
2353070Spst			continue;
2363070Spst		}
2373070Spst		cp += n;			/* name */
2383070Spst		type = _getshort(cp);
2393070Spst 		cp += INT16SZ;			/* type */
2403070Spst		class = _getshort(cp);
2413070Spst 		cp += INT16SZ + INT32SZ;	/* class, TTL */
2423070Spst		n = _getshort(cp);
2433070Spst		cp += INT16SZ;			/* len */
2443070Spst		if (class != qclass) {
2453070Spst			/* XXX - debug? syslog? */
2463070Spst			cp += n;
2473070Spst			continue;		/* XXX - had_error++ ? */
2483070Spst		}
2493070Spst		if (qtype == T_A && type == T_CNAME) {
2503070Spst			if (ap >= &host_aliases[MAXALIASES-1])
2513070Spst				continue;
2523070Spst			n = dn_expand(answer->buf, eom, cp, tbuf, sizeof tbuf);
2533070Spst			if (n < 0) {
2543070Spst				had_error++;
2553070Spst				continue;
2563070Spst			}
2573070Spst			cp += n;
2583070Spst			if (host.h_name && strcasecmp(host.h_name, bp) != 0) {
2593070Spst				syslog(LOG_NOTICE|LOG_AUTH,
26010133Speter		"gethostby*.gethostanswer: asked for \"%s\", got CNAME for \"%s\"",
2613070Spst				       host.h_name, bp);
2623070Spst				continue;	/* XXX - had_error++ ? */
2633070Spst			}
2643070Spst			/* Store alias. */
2653070Spst			*ap++ = bp;
2663070Spst			n = strlen(bp) + 1;	/* for the \0 */
2673070Spst			bp += n;
2683070Spst			buflen -= n;
2693070Spst			/* Get canonical name. */
2703070Spst			n = strlen(tbuf) + 1;	/* for the \0 */
2713070Spst			if (n > buflen) {
2723070Spst				had_error++;
2733070Spst				continue;
2743070Spst			}
2753070Spst			strcpy(bp, tbuf);
2763070Spst			host.h_name = bp;
2773070Spst			bp += n;
2783070Spst			buflen -= n;
2793070Spst			continue;
2803070Spst		}
2813070Spst		if (type != qtype) {
28210133Speter			/* CNAME->PTR should not cause a log message. */
28310133Speter			if (!(qtype == T_PTR && type == T_CNAME))
2843070Spst			syslog(LOG_NOTICE|LOG_AUTH,
28510133Speter	       "gethostby*.gethostanswer: asked for \"%s %s %s\", got type \"%s\"",
28610133Speter				       qname, p_class(qclass), p_type(qtype),
28710133Speter				       p_type(type));
2883070Spst			cp += n;
2893070Spst			continue;		/* XXX - had_error++ ? */
2903070Spst		}
2913070Spst		switch (type) {
2923070Spst		case T_PTR:
2933070Spst			if (strcasecmp(qname, bp) != 0) {
2943070Spst				syslog(LOG_NOTICE|LOG_AUTH,
2953070Spst				       AskedForGot, qname, bp);
2963070Spst				cp += n;
2973070Spst				continue;	/* XXX - had_error++ ? */
2983070Spst			}
2993070Spst			n = dn_expand(answer->buf, eom, cp, bp, buflen);
3003070Spst			if (n < 0) {
3013070Spst				had_error++;
3023070Spst				break;
3033070Spst			}
3043070Spst#if MULTI_PTRS_ARE_ALIASES
3053070Spst			cp += n;
3063070Spst			if (!haveanswer)
3073070Spst				host.h_name = bp;
3083070Spst			else if (ap < &host_aliases[MAXALIASES-1])
3093070Spst				*ap++ = bp;
3103070Spst			else
3113070Spst				n = -1;
3123070Spst			if (n != -1) {
3133070Spst				n = strlen(bp) + 1;	/* for the \0 */
3143070Spst				bp += n;
3153070Spst				buflen -= n;
3163070Spst			}
3173070Spst			break;
3183070Spst#else
3193070Spst			host.h_name = bp;
32010133Speter			h_errno = NETDB_SUCCESS;
3213070Spst			return (&host);
3223070Spst#endif
3233070Spst		case T_A:
3243070Spst			if (strcasecmp(host.h_name, bp) != 0) {
3253070Spst				syslog(LOG_NOTICE|LOG_AUTH,
3263070Spst				       AskedForGot, host.h_name, bp);
3273070Spst				cp += n;
3283070Spst				continue;	/* XXX - had_error++ ? */
3293070Spst			}
3303070Spst			if (haveanswer) {
3313070Spst				if (n != host.h_length) {
3323070Spst					cp += n;
3333070Spst					continue;
3343070Spst				}
3353070Spst			} else {
3363070Spst				register int nn;
3373070Spst
3383070Spst				host.h_length = n;
3393070Spst				host.h_addrtype = (class == C_IN)
3403070Spst						  ? AF_INET
3413070Spst						  : AF_UNSPEC;
3423070Spst				host.h_name = bp;
3433070Spst				nn = strlen(bp) + 1;	/* for the \0 */
3443070Spst				bp += nn;
3453070Spst				buflen -= nn;
3463070Spst			}
3473070Spst
3483070Spst			bp += sizeof(align) - ((u_long)bp % sizeof(align));
3493070Spst
3503070Spst			if (bp + n >= &hostbuf[sizeof hostbuf]) {
35110133Speter				dprintf("size (%d) too big\n", n);
3523070Spst				had_error++;
3533070Spst				continue;
3543070Spst			}
3553070Spst			if (hap >= &h_addr_ptrs[MAXADDRS-1]) {
35610133Speter				if (!toobig++)
35710133Speter					dprintf("Too many addresses (%d)\n",
3583070Spst					       MAXADDRS);
3593070Spst				cp += n;
3603070Spst				continue;
3613070Spst			}
3623070Spst			bcopy(cp, *hap++ = bp, n);
3633070Spst			bp += n;
3643070Spst			cp += n;
3653070Spst			break;
3663070Spst		default:
36710133Speter			dprintf("Impossible condition (type=%d)\n", type);
36810133Speter			h_errno = NO_RECOVERY;
36910133Speter			return (NULL);
3703070Spst		} /*switch*/
3713070Spst		if (!had_error)
3723070Spst			haveanswer++;
3733070Spst	} /*while*/
3743070Spst	if (haveanswer) {
3753070Spst		*ap = NULL;
3763070Spst		*hap = NULL;
3773070Spst# if defined(RESOLVSORT)
3783070Spst		/*
3793070Spst		 * Note: we sort even if host can take only one address
3803070Spst		 * in its return structures - should give it the "best"
3813070Spst		 * address in that case, not some random one
3823070Spst		 */
3833070Spst		if (_res.nsort && haveanswer > 1 &&
3843070Spst		    qclass == C_IN && qtype == T_A)
3853070Spst			addrsort(h_addr_ptrs, haveanswer);
3863070Spst# endif /*RESOLVSORT*/
3873070Spst		if (!host.h_name) {
3883070Spst			n = strlen(qname) + 1;	/* for the \0 */
3893070Spst			strcpy(bp, qname);
3903070Spst			host.h_name = bp;
3913070Spst		}
39210133Speter		h_errno = NETDB_SUCCESS;
3933070Spst		return (&host);
3943070Spst	} else {
3953070Spst		h_errno = TRY_AGAIN;
3963070Spst		return (NULL);
3973070Spst	}
3983070Spst}
3993070Spst
4003070Spststruct hostent *
4013070Spst_gethostbydnsname(name)
4023070Spst	const char *name;
4033070Spst{
4043070Spst	querybuf buf;
4053070Spst	register const char *cp;
4063070Spst	int n;
4073070Spst
40810133Speter	if ((_res.options & RES_INIT) == 0 && res_init() == -1) {
40910133Speter		h_errno = NETDB_INTERNAL;
41010133Speter		return (NULL);
41110133Speter	}
41210133Speter
4133070Spst	/*
41410133Speter	 * if there aren't any dots, it could be a user-level alias.
41510133Speter	 * this is also done in res_query() since we are not the only
41610133Speter	 * function that looks up host names.
41710133Speter	 */
41810133Speter	if (!strchr(name, '.') && (cp = __hostalias(name)))
41910133Speter		name = cp;
42010133Speter
42110133Speter	/*
4223070Spst	 * disallow names consisting only of digits/dots, unless
4233070Spst	 * they end in a dot.
4243070Spst	 */
4253070Spst	if (isdigit(name[0]))
4263070Spst		for (cp = name;; ++cp) {
4273070Spst			if (!*cp) {
4283070Spst				if (*--cp == '.')
4293070Spst					break;
4303070Spst				/*
4313070Spst				 * All-numeric, no dot at the end.
4323070Spst				 * Fake up a hostent as if we'd actually
4333070Spst				 * done a lookup.
4343070Spst				 */
4353070Spst				if (!inet_aton(name, &host_addr)) {
4363070Spst					h_errno = HOST_NOT_FOUND;
4373070Spst					return (NULL);
4383070Spst				}
43910133Speter				strncpy(hostbuf, name, MAXDNAME);
44010133Speter				hostbuf[MAXDNAME] = '\0';
44110133Speter				host.h_name = hostbuf;
4423070Spst				host.h_aliases = host_aliases;
4433070Spst				host_aliases[0] = NULL;
4443070Spst				host.h_addrtype = AF_INET;
4453070Spst				host.h_length = INT32SZ;
4463070Spst				h_addr_ptrs[0] = (char *)&host_addr;
4473070Spst				h_addr_ptrs[1] = NULL;
4483070Spst				host.h_addr_list = h_addr_ptrs;
4493070Spst				return (&host);
4503070Spst			}
4518870Srgrimes			if (!isdigit(*cp) && *cp != '.')
4523070Spst				break;
4533070Spst		}
4543070Spst
4553070Spst	if ((n = res_search(name, C_IN, T_A, buf.buf, sizeof(buf))) < 0) {
45610133Speter		dprintf("res_search failed (%d)\n", n);
4573070Spst		return (NULL);
4583070Spst	}
4593070Spst	return (gethostanswer(&buf, n, name, C_IN, T_A));
4603070Spst}
4613070Spst
4623070Spststruct hostent *
4633070Spst_gethostbydnsaddr(addr, len, type)
4643070Spst	const char *addr;
4653070Spst	int len, type;
4663070Spst{
4673070Spst	int n;
4683070Spst	querybuf buf;
4693070Spst	register struct hostent *hp;
4703070Spst	char qbuf[MAXDNAME+1];
47110133Speter#ifdef SUNSECURITY
47210133Speter	register struct hostent *rhp;
47310133Speter	char **haddr;
47410133Speter	u_long old_options;
47510133Speter	char hname2[MAXDNAME+1];
47610133Speter#endif /*SUNSECURITY*/
4778870Srgrimes
47810133Speter	if ((_res.options & RES_INIT) == 0 && res_init() == -1) {
47910133Speter		h_errno = NETDB_INTERNAL;
4803070Spst		return (NULL);
48110133Speter	}
48210133Speter	if (type != AF_INET) {
48310133Speter		errno = EAFNOSUPPORT;
48410133Speter		h_errno = NETDB_INTERNAL;
48510133Speter		return (NULL);
48610133Speter	}
4873070Spst	(void)sprintf(qbuf, "%u.%u.%u.%u.in-addr.arpa",
4883070Spst		((unsigned)addr[3] & 0xff),
4893070Spst		((unsigned)addr[2] & 0xff),
4903070Spst		((unsigned)addr[1] & 0xff),
4913070Spst		((unsigned)addr[0] & 0xff));
4923070Spst	n = res_query(qbuf, C_IN, T_PTR, (u_char *)buf.buf, sizeof buf.buf);
4933070Spst	if (n < 0) {
49410133Speter		dprintf("res_query failed (%d)\n", n);
4953070Spst		return (NULL);
4963070Spst	}
4973070Spst	if (!(hp = gethostanswer(&buf, n, qbuf, C_IN, T_PTR)))
49810133Speter		return (NULL);	/* h_errno was set by gethostanswer() */
49910133Speter#ifdef SUNSECURITY
50010133Speter	/*
50110133Speter	 * turn off search as the name should be absolute,
50210133Speter	 * 'localhost' should be matched by defnames
50310133Speter	 */
50410133Speter	strncpy(hname2, hp->h_name, MAXDNAME);
50510133Speter	hname2[MAXDNAME] = '\0';
50610133Speter	old_options = _res.options;
50710133Speter	_res.options &= ~RES_DNSRCH;
50810133Speter	_res.options |= RES_DEFNAMES;
50910133Speter	if (!(rhp = gethostbyname(hname2))) {
51010133Speter		syslog(LOG_NOTICE|LOG_AUTH,
51110133Speter		       "gethostbyaddr: No A record for %s (verifying [%s])",
51210133Speter		       hname2, inet_ntoa(*((struct in_addr *)addr)));
51310133Speter		_res.options = old_options;
51410133Speter		h_errno = HOST_NOT_FOUND;
5153070Spst		return (NULL);
51610133Speter	}
51710133Speter	_res.options = old_options;
51810133Speter	for (haddr = rhp->h_addr_list; *haddr; haddr++)
51910133Speter		if (!memcmp(*haddr, addr, INADDRSZ))
52010133Speter			break;
52110133Speter	if (!*haddr) {
52210133Speter		syslog(LOG_NOTICE|LOG_AUTH,
52310133Speter		       "gethostbyaddr: A record of %s != PTR record [%s]",
52410133Speter		       hname2, inet_ntoa(*((struct in_addr *)addr)));
52510133Speter		h_errno = HOST_NOT_FOUND;
52610133Speter		return (NULL);
52710133Speter	}
52810133Speter#endif /*SUNSECURITY*/
5293070Spst	hp->h_addrtype = type;
5303070Spst	hp->h_length = len;
5313070Spst	h_addr_ptrs[0] = (char *)&host_addr;
5323070Spst	h_addr_ptrs[1] = NULL;
5333070Spst	host_addr = *(struct in_addr *)addr;
53410133Speter	h_errno = NETDB_SUCCESS;
5353070Spst	return (hp);
5363070Spst}
5373070Spst
5383070Spstvoid
5393070Spst_sethostdnsent(stayopen)
5403070Spst	int stayopen;
5413070Spst{
5423070Spst	if (stayopen)
5433070Spst		_res.options |= RES_STAYOPEN | RES_USEVC;
5443070Spst}
5453070Spst
5463070Spstvoid
5473070Spst_endhostdnsent()
5483070Spst{
5493070Spst	_res.options &= ~(RES_STAYOPEN | RES_USEVC);
5503070Spst	_res_close();
5513070Spst}
552