xref: /freebsd/lib/libc/net/gethostbydns.c (revision dc36d6f9)
18a16b7a1SPedro F. Giffuni /*-
28a16b7a1SPedro F. Giffuni  * SPDX-License-Identifier: BSD-3-Clause
38a16b7a1SPedro F. Giffuni  *
4ca785773SPeter Wemm  * ++Copyright++ 1985, 1988, 1993
5ca785773SPeter Wemm  * -
61363f04cSPaul Traina  * Copyright (c) 1985, 1988, 1993
71363f04cSPaul Traina  *	The Regents of the University of California.  All rights reserved.
81363f04cSPaul Traina  *
91363f04cSPaul Traina  * Redistribution and use in source and binary forms, with or without
101363f04cSPaul Traina  * modification, are permitted provided that the following conditions
111363f04cSPaul Traina  * are met:
121363f04cSPaul Traina  * 1. Redistributions of source code must retain the above copyright
131363f04cSPaul Traina  *    notice, this list of conditions and the following disclaimer.
141363f04cSPaul Traina  * 2. Redistributions in binary form must reproduce the above copyright
151363f04cSPaul Traina  *    notice, this list of conditions and the following disclaimer in the
161363f04cSPaul Traina  *    documentation and/or other materials provided with the distribution.
17fbbd9655SWarner Losh  * 3. Neither the name of the University nor the names of its contributors
181363f04cSPaul Traina  *    may be used to endorse or promote products derived from this software
191363f04cSPaul Traina  *    without specific prior written permission.
201363f04cSPaul Traina  *
211363f04cSPaul Traina  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
221363f04cSPaul Traina  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
231363f04cSPaul Traina  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
241363f04cSPaul Traina  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
251363f04cSPaul Traina  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
261363f04cSPaul Traina  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
271363f04cSPaul Traina  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
281363f04cSPaul Traina  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
291363f04cSPaul Traina  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
301363f04cSPaul Traina  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
311363f04cSPaul Traina  * SUCH DAMAGE.
321363f04cSPaul Traina  * -
331363f04cSPaul Traina  * Portions Copyright (c) 1993 by Digital Equipment Corporation.
341363f04cSPaul Traina  *
351363f04cSPaul Traina  * Permission to use, copy, modify, and distribute this software for any
361363f04cSPaul Traina  * purpose with or without fee is hereby granted, provided that the above
371363f04cSPaul Traina  * copyright notice and this permission notice appear in all copies, and that
381363f04cSPaul Traina  * the name of Digital Equipment Corporation not be used in advertising or
391363f04cSPaul Traina  * publicity pertaining to distribution of the document or software without
401363f04cSPaul Traina  * specific, written prior permission.
411363f04cSPaul Traina  *
421363f04cSPaul Traina  * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
431363f04cSPaul Traina  * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
441363f04cSPaul Traina  * OF MERCHANTABILITY AND FITNESS.   IN NO EVENT SHALL DIGITAL EQUIPMENT
451363f04cSPaul Traina  * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
461363f04cSPaul Traina  * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
471363f04cSPaul Traina  * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
481363f04cSPaul Traina  * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
491363f04cSPaul Traina  * SOFTWARE.
501363f04cSPaul Traina  * -
511363f04cSPaul Traina  * --Copyright--
521363f04cSPaul Traina  */
531363f04cSPaul Traina 
541363f04cSPaul Traina #include <sys/param.h>
551363f04cSPaul Traina #include <sys/socket.h>
561363f04cSPaul Traina #include <netinet/in.h>
571363f04cSPaul Traina #include <arpa/inet.h>
581363f04cSPaul Traina #include <arpa/nameser.h>
59e5ad4f87SPeter Wemm 
60e5ad4f87SPeter Wemm #include <stdio.h>
61a52b6b83SHajimu UMEMOTO #include <stdlib.h>
62fce61be7SPoul-Henning Kamp #include <unistd.h>
63e5ad4f87SPeter Wemm #include <string.h>
641363f04cSPaul Traina #include <netdb.h>
651363f04cSPaul Traina #include <resolv.h>
661363f04cSPaul Traina #include <ctype.h>
671363f04cSPaul Traina #include <errno.h>
681363f04cSPaul Traina #include <syslog.h>
69248aee62SJacques Vidrine #include <stdarg.h>
70248aee62SJacques Vidrine #include <nsswitch.h>
711363f04cSPaul Traina 
72bcb131aaSHajimu UMEMOTO #include "netdb_private.h"
73e6507d61SBruce Evans #include "res_config.h"
741363f04cSPaul Traina 
755ce1c533SPeter Wemm #define SPRINTF(x) ((size_t)sprintf x)
765ce1c533SPeter Wemm 
771363f04cSPaul Traina static const char AskedForGot[] =
781363f04cSPaul Traina 		"gethostby*.gethostanswer: asked for \"%s\", got \"%s\"";
791363f04cSPaul Traina 
804faad310SPeter Wemm #ifdef RESOLVSORT
815342d17fSHajimu UMEMOTO static void addrsort(char **, int, res_state);
824faad310SPeter Wemm #endif
834faad310SPeter Wemm 
846dac8ac9SKris Kennaway #ifdef DEBUG
8532fefb24SBaptiste Daroussin static void dbg_printf(char *, int, res_state) __printflike(1, 0);
866dac8ac9SKris Kennaway #endif
876dac8ac9SKris Kennaway 
88a52b6b83SHajimu UMEMOTO #define MAXPACKET	(64*1024)
891363f04cSPaul Traina 
901363f04cSPaul Traina typedef union {
911363f04cSPaul Traina     HEADER hdr;
921363f04cSPaul Traina     u_char buf[MAXPACKET];
931363f04cSPaul Traina } querybuf;
941363f04cSPaul Traina 
951363f04cSPaul Traina typedef union {
961363f04cSPaul Traina     int32_t al;
971363f04cSPaul Traina     char ac;
981363f04cSPaul Traina } align;
991363f04cSPaul Traina 
100df9c30afSPeter Wemm int _dns_ttl_;
1011363f04cSPaul Traina 
102e5ad4f87SPeter Wemm #ifdef DEBUG
103e5ad4f87SPeter Wemm static void
dbg_printf(char * msg,int num,res_state res)10432fefb24SBaptiste Daroussin dbg_printf(char *msg, int num, res_state res)
105e5ad4f87SPeter Wemm {
1065342d17fSHajimu UMEMOTO 	if (res->options & RES_DEBUG) {
107e5ad4f87SPeter Wemm 		int save = errno;
108e5ad4f87SPeter Wemm 
109e5ad4f87SPeter Wemm 		printf(msg, num);
110e5ad4f87SPeter Wemm 		errno = save;
111e5ad4f87SPeter Wemm 	}
112e5ad4f87SPeter Wemm }
113e5ad4f87SPeter Wemm #else
11432fefb24SBaptiste Daroussin # define dbg_printf(msg, num, res) /*nada*/
115e5ad4f87SPeter Wemm #endif
116e5ad4f87SPeter Wemm 
117c8d2fd6dSPeter Wemm #define BOUNDED_INCR(x) \
118c8d2fd6dSPeter Wemm 	do { \
119c8d2fd6dSPeter Wemm 		cp += x; \
120c8d2fd6dSPeter Wemm 		if (cp > eom) { \
121d3ac2b30SHajimu UMEMOTO 			RES_SET_H_ERRNO(statp, NO_RECOVERY); \
122d3ac2b30SHajimu UMEMOTO 			return (-1); \
123c8d2fd6dSPeter Wemm 		} \
124c8d2fd6dSPeter Wemm 	} while (0)
125c8d2fd6dSPeter Wemm 
126c8d2fd6dSPeter Wemm #define BOUNDS_CHECK(ptr, count) \
127c8d2fd6dSPeter Wemm 	do { \
128c8d2fd6dSPeter Wemm 		if ((ptr) + (count) > eom) { \
129d3ac2b30SHajimu UMEMOTO 			RES_SET_H_ERRNO(statp, NO_RECOVERY); \
130d3ac2b30SHajimu UMEMOTO 			return (-1); \
131c8d2fd6dSPeter Wemm 		} \
132c8d2fd6dSPeter Wemm 	} while (0)
133c8d2fd6dSPeter Wemm 
134aa2f4ec7SHajimu UMEMOTO static int
gethostanswer(const querybuf * answer,int anslen,const char * qname,int qtype,struct hostent * he,struct hostent_data * hed,res_state statp)135aa2f4ec7SHajimu UMEMOTO gethostanswer(const querybuf *answer, int anslen, const char *qname, int qtype,
136d3ac2b30SHajimu UMEMOTO     struct hostent *he, struct hostent_data *hed, res_state statp)
1371363f04cSPaul Traina {
1388fb3f3f6SDavid E. O'Brien 	const HEADER *hp;
1398fb3f3f6SDavid E. O'Brien 	const u_char *cp;
1408fb3f3f6SDavid E. O'Brien 	int n;
141c8d2fd6dSPeter Wemm 	const u_char *eom, *erdata;
142d6af58f5SWarner Losh 	char *bp, *ep, **ap, **hap;
143d6af58f5SWarner Losh 	int type, class, ancount, qdcount;
1441363f04cSPaul Traina 	int haveanswer, had_error;
1451363f04cSPaul Traina 	int toobig = 0;
146ca785773SPeter Wemm 	char tbuf[MAXDNAME];
1474faad310SPeter Wemm 	const char *tname;
148c05ac53bSDavid E. O'Brien 	int (*name_ok)(const char *);
1491363f04cSPaul Traina 
1504faad310SPeter Wemm 	tname = qname;
151aa2f4ec7SHajimu UMEMOTO 	he->h_name = NULL;
1521363f04cSPaul Traina 	eom = answer->buf + anslen;
1535ce1c533SPeter Wemm 	switch (qtype) {
1545ce1c533SPeter Wemm 	case T_A:
1555ce1c533SPeter Wemm 	case T_AAAA:
1565ce1c533SPeter Wemm 		name_ok = res_hnok;
1575ce1c533SPeter Wemm 		break;
1585ce1c533SPeter Wemm 	case T_PTR:
1595ce1c533SPeter Wemm 		name_ok = res_dnok;
1605ce1c533SPeter Wemm 		break;
1615ce1c533SPeter Wemm 	default:
162d3ac2b30SHajimu UMEMOTO 		RES_SET_H_ERRNO(statp, NO_RECOVERY);
163d3ac2b30SHajimu UMEMOTO 		return (-1);	/* XXX should be abort(); */
1645ce1c533SPeter Wemm 	}
1651363f04cSPaul Traina 	/*
1661363f04cSPaul Traina 	 * find first satisfactory answer
1671363f04cSPaul Traina 	 */
1681363f04cSPaul Traina 	hp = &answer->hdr;
1691363f04cSPaul Traina 	ancount = ntohs(hp->ancount);
1701363f04cSPaul Traina 	qdcount = ntohs(hp->qdcount);
171aa2f4ec7SHajimu UMEMOTO 	bp = hed->hostbuf;
172aa2f4ec7SHajimu UMEMOTO 	ep = hed->hostbuf + sizeof hed->hostbuf;
173c8d2fd6dSPeter Wemm 	cp = answer->buf;
174c8d2fd6dSPeter Wemm 	BOUNDED_INCR(HFIXEDSZ);
1751363f04cSPaul Traina 	if (qdcount != 1) {
176d3ac2b30SHajimu UMEMOTO 		RES_SET_H_ERRNO(statp, NO_RECOVERY);
177d3ac2b30SHajimu UMEMOTO 		return (-1);
1781363f04cSPaul Traina 	}
179d6af58f5SWarner Losh 	n = dn_expand(answer->buf, eom, cp, bp, ep - bp);
1805ce1c533SPeter Wemm 	if ((n < 0) || !(*name_ok)(bp)) {
181d3ac2b30SHajimu UMEMOTO 		RES_SET_H_ERRNO(statp, NO_RECOVERY);
182d3ac2b30SHajimu UMEMOTO 		return (-1);
1831363f04cSPaul Traina 	}
184c8d2fd6dSPeter Wemm 	BOUNDED_INCR(n + QFIXEDSZ);
1855ce1c533SPeter Wemm 	if (qtype == T_A || qtype == T_AAAA) {
1861363f04cSPaul Traina 		/* res_send() has already verified that the query name is the
1871363f04cSPaul Traina 		 * same as the one we sent; this just gets the expanded name
1881363f04cSPaul Traina 		 * (i.e., with the succeeding search-domain tacked on).
1891363f04cSPaul Traina 		 */
1901363f04cSPaul Traina 		n = strlen(bp) + 1;		/* for the \0 */
1916c5aff80SPeter Wemm 		if (n >= MAXHOSTNAMELEN) {
192d3ac2b30SHajimu UMEMOTO 			RES_SET_H_ERRNO(statp, NO_RECOVERY);
193d3ac2b30SHajimu UMEMOTO 			return (-1);
1946c5aff80SPeter Wemm 		}
195aa2f4ec7SHajimu UMEMOTO 		he->h_name = bp;
1961363f04cSPaul Traina 		bp += n;
1971363f04cSPaul Traina 		/* The qname can be abbreviated, but h_name is now absolute. */
198aa2f4ec7SHajimu UMEMOTO 		qname = he->h_name;
1991363f04cSPaul Traina 	}
200aa2f4ec7SHajimu UMEMOTO 	ap = hed->host_aliases;
2011363f04cSPaul Traina 	*ap = NULL;
202aa2f4ec7SHajimu UMEMOTO 	he->h_aliases = hed->host_aliases;
203aa2f4ec7SHajimu UMEMOTO 	hap = hed->h_addr_ptrs;
2041363f04cSPaul Traina 	*hap = NULL;
205aa2f4ec7SHajimu UMEMOTO 	he->h_addr_list = hed->h_addr_ptrs;
2061363f04cSPaul Traina 	haveanswer = 0;
2071363f04cSPaul Traina 	had_error = 0;
208df9c30afSPeter Wemm 	_dns_ttl_ = -1;
2091363f04cSPaul Traina 	while (ancount-- > 0 && cp < eom && !had_error) {
210d6af58f5SWarner Losh 		n = dn_expand(answer->buf, eom, cp, bp, ep - bp);
2115ce1c533SPeter Wemm 		if ((n < 0) || !(*name_ok)(bp)) {
2121363f04cSPaul Traina 			had_error++;
2131363f04cSPaul Traina 			continue;
2141363f04cSPaul Traina 		}
2151363f04cSPaul Traina 		cp += n;			/* name */
216c8d2fd6dSPeter Wemm 		BOUNDS_CHECK(cp, 3 * INT16SZ + INT32SZ);
2171363f04cSPaul Traina 		type = _getshort(cp);
2181363f04cSPaul Traina  		cp += INT16SZ;			/* type */
2191363f04cSPaul Traina 		class = _getshort(cp);
220df9c30afSPeter Wemm  		cp += INT16SZ;			/* class */
221df9c30afSPeter Wemm 		if (qtype == T_A  && type == T_A)
222df9c30afSPeter Wemm 			_dns_ttl_ = _getlong(cp);
223df9c30afSPeter Wemm 		cp += INT32SZ;			/* TTL */
2241363f04cSPaul Traina 		n = _getshort(cp);
2251363f04cSPaul Traina 		cp += INT16SZ;			/* len */
226c8d2fd6dSPeter Wemm 		BOUNDS_CHECK(cp, n);
227c8d2fd6dSPeter Wemm 		erdata = cp + n;
2285ce1c533SPeter Wemm 		if (class != C_IN) {
2291363f04cSPaul Traina 			/* XXX - debug? syslog? */
2301363f04cSPaul Traina 			cp += n;
2311363f04cSPaul Traina 			continue;		/* XXX - had_error++ ? */
2321363f04cSPaul Traina 		}
2335ce1c533SPeter Wemm 		if ((qtype == T_A || qtype == T_AAAA) && type == T_CNAME) {
234aa2f4ec7SHajimu UMEMOTO 			if (ap >= &hed->host_aliases[_MAXALIASES-1])
2351363f04cSPaul Traina 				continue;
2361363f04cSPaul Traina 			n = dn_expand(answer->buf, eom, cp, tbuf, sizeof tbuf);
2375ce1c533SPeter Wemm 			if ((n < 0) || !(*name_ok)(tbuf)) {
2381363f04cSPaul Traina 				had_error++;
2391363f04cSPaul Traina 				continue;
2401363f04cSPaul Traina 			}
2411363f04cSPaul Traina 			cp += n;
242c8d2fd6dSPeter Wemm 			if (cp != erdata) {
243d3ac2b30SHajimu UMEMOTO 				RES_SET_H_ERRNO(statp, NO_RECOVERY);
244d3ac2b30SHajimu UMEMOTO 				return (-1);
245c8d2fd6dSPeter Wemm 			}
2461363f04cSPaul Traina 			/* Store alias. */
2471363f04cSPaul Traina 			*ap++ = bp;
2481363f04cSPaul Traina 			n = strlen(bp) + 1;	/* for the \0 */
2496c5aff80SPeter Wemm 			if (n >= MAXHOSTNAMELEN) {
2506c5aff80SPeter Wemm 				had_error++;
2516c5aff80SPeter Wemm 				continue;
2526c5aff80SPeter Wemm 			}
2531363f04cSPaul Traina 			bp += n;
2541363f04cSPaul Traina 			/* Get canonical name. */
2551363f04cSPaul Traina 			n = strlen(tbuf) + 1;	/* for the \0 */
256d6af58f5SWarner Losh 			if (n > ep - bp || n >= MAXHOSTNAMELEN) {
2571363f04cSPaul Traina 				had_error++;
2581363f04cSPaul Traina 				continue;
2591363f04cSPaul Traina 			}
2601363f04cSPaul Traina 			strcpy(bp, tbuf);
261aa2f4ec7SHajimu UMEMOTO 			he->h_name = bp;
2621363f04cSPaul Traina 			bp += n;
2631363f04cSPaul Traina 			continue;
2641363f04cSPaul Traina 		}
2654faad310SPeter Wemm 		if (qtype == T_PTR && type == T_CNAME) {
2664faad310SPeter Wemm 			n = dn_expand(answer->buf, eom, cp, tbuf, sizeof tbuf);
2676c5aff80SPeter Wemm 			if (n < 0 || !res_dnok(tbuf)) {
2684faad310SPeter Wemm 				had_error++;
2694faad310SPeter Wemm 				continue;
2704faad310SPeter Wemm 			}
2714faad310SPeter Wemm 			cp += n;
272c8d2fd6dSPeter Wemm 			if (cp != erdata) {
273d3ac2b30SHajimu UMEMOTO 				RES_SET_H_ERRNO(statp, NO_RECOVERY);
274d3ac2b30SHajimu UMEMOTO 				return (-1);
275c8d2fd6dSPeter Wemm 			}
2764faad310SPeter Wemm 			/* Get canonical name. */
2774faad310SPeter Wemm 			n = strlen(tbuf) + 1;	/* for the \0 */
278d6af58f5SWarner Losh 			if (n > ep - bp || n >= MAXHOSTNAMELEN) {
2794faad310SPeter Wemm 				had_error++;
2804faad310SPeter Wemm 				continue;
2814faad310SPeter Wemm 			}
2824faad310SPeter Wemm 			strcpy(bp, tbuf);
2834faad310SPeter Wemm 			tname = bp;
2844faad310SPeter Wemm 			bp += n;
2854faad310SPeter Wemm 			continue;
2864faad310SPeter Wemm 		}
2871363f04cSPaul Traina 		if (type != qtype) {
288817f1f30SDag-Erling Smørgrav #ifdef DEBUG
289817f1f30SDag-Erling Smørgrav 			if (type != T_KEY && type != T_SIG &&
290817f1f30SDag-Erling Smørgrav 			    type != T_DNAME && type != T_RRSIG)
2911363f04cSPaul Traina 				syslog(LOG_NOTICE|LOG_AUTH,
292e5ad4f87SPeter Wemm 	"gethostby*.gethostanswer: asked for \"%s %s %s\", got type \"%s\"",
2935ce1c533SPeter Wemm 				       qname, p_class(C_IN), p_type(qtype),
294e5ad4f87SPeter Wemm 				       p_type(type));
295817f1f30SDag-Erling Smørgrav #endif
2961363f04cSPaul Traina 			cp += n;
2971363f04cSPaul Traina 			continue;		/* XXX - had_error++ ? */
2981363f04cSPaul Traina 		}
2991363f04cSPaul Traina 		switch (type) {
3001363f04cSPaul Traina 		case T_PTR:
3014faad310SPeter Wemm 			if (strcasecmp(tname, bp) != 0) {
3021363f04cSPaul Traina 				syslog(LOG_NOTICE|LOG_AUTH,
3031363f04cSPaul Traina 				       AskedForGot, qname, bp);
3041363f04cSPaul Traina 				cp += n;
3051363f04cSPaul Traina 				continue;	/* XXX - had_error++ ? */
3061363f04cSPaul Traina 			}
307d6af58f5SWarner Losh 			n = dn_expand(answer->buf, eom, cp, bp, ep - bp);
3085ce1c533SPeter Wemm 			if ((n < 0) || !res_hnok(bp)) {
3091363f04cSPaul Traina 				had_error++;
3101363f04cSPaul Traina 				break;
3111363f04cSPaul Traina 			}
3125ce1c533SPeter Wemm #if MULTI_PTRS_ARE_ALIASES
3131363f04cSPaul Traina 			cp += n;
314c8d2fd6dSPeter Wemm 			if (cp != erdata) {
315d3ac2b30SHajimu UMEMOTO 				RES_SET_H_ERRNO(statp, NO_RECOVERY);
316d3ac2b30SHajimu UMEMOTO 				return (-1);
317c8d2fd6dSPeter Wemm 			}
3181363f04cSPaul Traina 			if (!haveanswer)
319aa2f4ec7SHajimu UMEMOTO 				he->h_name = bp;
320aa2f4ec7SHajimu UMEMOTO 			else if (ap < &hed->host_aliases[_MAXALIASES-1])
3211363f04cSPaul Traina 				*ap++ = bp;
3221363f04cSPaul Traina 			else
3231363f04cSPaul Traina 				n = -1;
3241363f04cSPaul Traina 			if (n != -1) {
3251363f04cSPaul Traina 				n = strlen(bp) + 1;	/* for the \0 */
3266c5aff80SPeter Wemm 				if (n >= MAXHOSTNAMELEN) {
3276c5aff80SPeter Wemm 					had_error++;
3286c5aff80SPeter Wemm 					break;
3296c5aff80SPeter Wemm 				}
3301363f04cSPaul Traina 				bp += n;
3311363f04cSPaul Traina 			}
3321363f04cSPaul Traina 			break;
3331363f04cSPaul Traina #else
334aa2f4ec7SHajimu UMEMOTO 			he->h_name = bp;
335d3ac2b30SHajimu UMEMOTO 			if (statp->options & RES_USE_INET6) {
3365ce1c533SPeter Wemm 				n = strlen(bp) + 1;	/* for the \0 */
3376c5aff80SPeter Wemm 				if (n >= MAXHOSTNAMELEN) {
3386c5aff80SPeter Wemm 					had_error++;
3396c5aff80SPeter Wemm 					break;
3406c5aff80SPeter Wemm 				}
3415ce1c533SPeter Wemm 				bp += n;
342850bc9afSHajimu UMEMOTO 				_map_v4v6_hostent(he, &bp, ep);
3435ce1c533SPeter Wemm 			}
344d3ac2b30SHajimu UMEMOTO 			RES_SET_H_ERRNO(statp, NETDB_SUCCESS);
345d3ac2b30SHajimu UMEMOTO 			return (0);
3461363f04cSPaul Traina #endif
3471363f04cSPaul Traina 		case T_A:
3485ce1c533SPeter Wemm 		case T_AAAA:
349aa2f4ec7SHajimu UMEMOTO 			if (strcasecmp(he->h_name, bp) != 0) {
3501363f04cSPaul Traina 				syslog(LOG_NOTICE|LOG_AUTH,
351aa2f4ec7SHajimu UMEMOTO 				       AskedForGot, he->h_name, bp);
3521363f04cSPaul Traina 				cp += n;
3531363f04cSPaul Traina 				continue;	/* XXX - had_error++ ? */
3541363f04cSPaul Traina 			}
355aa2f4ec7SHajimu UMEMOTO 			if (n != he->h_length) {
3561363f04cSPaul Traina 				cp += n;
3571363f04cSPaul Traina 				continue;
3581363f04cSPaul Traina 			}
359beddb20cSPaul Traina 			if (!haveanswer) {
3608fb3f3f6SDavid E. O'Brien 				int nn;
3611363f04cSPaul Traina 
362aa2f4ec7SHajimu UMEMOTO 				he->h_name = bp;
3631363f04cSPaul Traina 				nn = strlen(bp) + 1;	/* for the \0 */
3641363f04cSPaul Traina 				bp += nn;
3651363f04cSPaul Traina 			}
3661363f04cSPaul Traina 
367fda83111SWarner Losh 			bp += sizeof(align) - ((u_long)bp % sizeof(align));
3681363f04cSPaul Traina 
369d6af58f5SWarner Losh 			if (bp + n >= ep) {
37032fefb24SBaptiste Daroussin 				dbg_printf("size (%d) too big\n", n, statp);
3711363f04cSPaul Traina 				had_error++;
3721363f04cSPaul Traina 				continue;
3731363f04cSPaul Traina 			}
374aa2f4ec7SHajimu UMEMOTO 			if (hap >= &hed->h_addr_ptrs[_MAXADDRS-1]) {
375e5ad4f87SPeter Wemm 				if (!toobig++)
37632fefb24SBaptiste Daroussin 					dbg_printf("Too many addresses (%d)\n",
377d3ac2b30SHajimu UMEMOTO 						_MAXADDRS, statp);
3781363f04cSPaul Traina 				cp += n;
3791363f04cSPaul Traina 				continue;
3801363f04cSPaul Traina 			}
3812c08ac2bSHajimu UMEMOTO 			memcpy(*hap++ = bp, cp, n);
3821363f04cSPaul Traina 			bp += n;
3831363f04cSPaul Traina 			cp += n;
384c8d2fd6dSPeter Wemm 			if (cp != erdata) {
385d3ac2b30SHajimu UMEMOTO 				RES_SET_H_ERRNO(statp, NO_RECOVERY);
386d3ac2b30SHajimu UMEMOTO 				return (-1);
387c8d2fd6dSPeter Wemm 			}
3881363f04cSPaul Traina 			break;
3891363f04cSPaul Traina 		default:
39032fefb24SBaptiste Daroussin 			dbg_printf("Impossible condition (type=%d)\n", type,
391d3ac2b30SHajimu UMEMOTO 			    statp);
392d3ac2b30SHajimu UMEMOTO 			RES_SET_H_ERRNO(statp, NO_RECOVERY);
393d3ac2b30SHajimu UMEMOTO 			return (-1);
394ca785773SPeter Wemm 			/* BIND has abort() here, too risky on bad data */
395ca785773SPeter Wemm 		}
3961363f04cSPaul Traina 		if (!had_error)
3971363f04cSPaul Traina 			haveanswer++;
398ca785773SPeter Wemm 	}
3991363f04cSPaul Traina 	if (haveanswer) {
4001363f04cSPaul Traina 		*ap = NULL;
4011363f04cSPaul Traina 		*hap = NULL;
4021363f04cSPaul Traina # if defined(RESOLVSORT)
4031363f04cSPaul Traina 		/*
4041363f04cSPaul Traina 		 * Note: we sort even if host can take only one address
4051363f04cSPaul Traina 		 * in its return structures - should give it the "best"
4061363f04cSPaul Traina 		 * address in that case, not some random one
4071363f04cSPaul Traina 		 */
408d3ac2b30SHajimu UMEMOTO 		if (statp->nsort && haveanswer > 1 && qtype == T_A)
409d3ac2b30SHajimu UMEMOTO 			addrsort(hed->h_addr_ptrs, haveanswer, statp);
4101363f04cSPaul Traina # endif /*RESOLVSORT*/
411aa2f4ec7SHajimu UMEMOTO 		if (!he->h_name) {
4121363f04cSPaul Traina 			n = strlen(qname) + 1;	/* for the \0 */
413d6af58f5SWarner Losh 			if (n > ep - bp || n >= MAXHOSTNAMELEN)
4146c5aff80SPeter Wemm 				goto no_recovery;
4151363f04cSPaul Traina 			strcpy(bp, qname);
416aa2f4ec7SHajimu UMEMOTO 			he->h_name = bp;
4175ce1c533SPeter Wemm 			bp += n;
4181363f04cSPaul Traina 		}
419d3ac2b30SHajimu UMEMOTO 		if (statp->options & RES_USE_INET6)
420850bc9afSHajimu UMEMOTO 			_map_v4v6_hostent(he, &bp, ep);
421d3ac2b30SHajimu UMEMOTO 		RES_SET_H_ERRNO(statp, NETDB_SUCCESS);
422d3ac2b30SHajimu UMEMOTO 		return (0);
4235ce1c533SPeter Wemm 	}
4246c5aff80SPeter Wemm  no_recovery:
425d3ac2b30SHajimu UMEMOTO 	RES_SET_H_ERRNO(statp, NO_RECOVERY);
426d3ac2b30SHajimu UMEMOTO 	return (-1);
4271363f04cSPaul Traina }
4281363f04cSPaul Traina 
429aa2f4ec7SHajimu UMEMOTO /* XXX: for async DNS resolver in ypserv */
4301363f04cSPaul Traina struct hostent *
__dns_getanswer(const char * answer,int anslen,const char * qname,int qtype)431aa2f4ec7SHajimu UMEMOTO __dns_getanswer(const char *answer, int anslen, const char *qname, int qtype)
432ce8bac1eSBill Paul {
433d3ac2b30SHajimu UMEMOTO 	struct hostent *he;
434d3ac2b30SHajimu UMEMOTO 	struct hostent_data *hed;
435aa2f4ec7SHajimu UMEMOTO 	int error;
4365342d17fSHajimu UMEMOTO 	res_state statp;
437aa2f4ec7SHajimu UMEMOTO 
4385342d17fSHajimu UMEMOTO 	statp = __res_state();
439d3ac2b30SHajimu UMEMOTO 	if ((he = __hostent_init()) == NULL ||
440d3ac2b30SHajimu UMEMOTO 	    (hed = __hostent_data_init()) == NULL) {
4415342d17fSHajimu UMEMOTO 		RES_SET_H_ERRNO(statp, NETDB_INTERNAL);
442d3ac2b30SHajimu UMEMOTO 		return (NULL);
443aa2f4ec7SHajimu UMEMOTO 	}
4446b73680dSBill Paul 	switch (qtype) {
4456b73680dSBill Paul 	case T_AAAA:
446d3ac2b30SHajimu UMEMOTO 		he->h_addrtype = AF_INET6;
447d3ac2b30SHajimu UMEMOTO 		he->h_length = NS_IN6ADDRSZ;
4486b73680dSBill Paul 		break;
4496b73680dSBill Paul 	case T_A:
4506b73680dSBill Paul 	default:
451d3ac2b30SHajimu UMEMOTO 		he->h_addrtype = AF_INET;
452d3ac2b30SHajimu UMEMOTO 		he->h_length = NS_INADDRSZ;
4536b73680dSBill Paul 		break;
4546b73680dSBill Paul 	}
4556b73680dSBill Paul 
456aa2f4ec7SHajimu UMEMOTO 	error = gethostanswer((const querybuf *)answer, anslen, qname, qtype,
457d3ac2b30SHajimu UMEMOTO 	    he, hed, statp);
458d3ac2b30SHajimu UMEMOTO 	return (error == 0) ? he : NULL;
459ce8bac1eSBill Paul }
460ce8bac1eSBill Paul 
461248aee62SJacques Vidrine int
_dns_gethostbyname(void * rval,void * cb_data,va_list ap)462248aee62SJacques Vidrine _dns_gethostbyname(void *rval, void *cb_data, va_list ap)
463248aee62SJacques Vidrine {
4641363f04cSPaul Traina 	const char *name;
4655ce1c533SPeter Wemm 	int af;
466d3ac2b30SHajimu UMEMOTO 	char *buffer;
467d3ac2b30SHajimu UMEMOTO 	size_t buflen;
468d3ac2b30SHajimu UMEMOTO 	int *errnop, *h_errnop;
469d3ac2b30SHajimu UMEMOTO 	struct hostent *hptr, he;
470aa2f4ec7SHajimu UMEMOTO 	struct hostent_data *hed;
471a52b6b83SHajimu UMEMOTO 	querybuf *buf;
472d3ac2b30SHajimu UMEMOTO 	int n, type, error;
473d3ac2b30SHajimu UMEMOTO 	res_state statp;
4741363f04cSPaul Traina 
475248aee62SJacques Vidrine 	name = va_arg(ap, const char *);
476248aee62SJacques Vidrine 	af = va_arg(ap, int);
477d3ac2b30SHajimu UMEMOTO 	hptr = va_arg(ap, struct hostent *);
478d3ac2b30SHajimu UMEMOTO 	buffer = va_arg(ap, char *);
479d3ac2b30SHajimu UMEMOTO 	buflen = va_arg(ap, size_t);
480d3ac2b30SHajimu UMEMOTO 	errnop = va_arg(ap, int *);
481d3ac2b30SHajimu UMEMOTO 	h_errnop = va_arg(ap, int *);
482248aee62SJacques Vidrine 
483d3ac2b30SHajimu UMEMOTO 	*((struct hostent **)rval) = NULL;
484d3ac2b30SHajimu UMEMOTO 
485d3ac2b30SHajimu UMEMOTO 	statp = __res_state();
486d3ac2b30SHajimu UMEMOTO 	if ((hed = __hostent_data_init()) == NULL) {
487d3ac2b30SHajimu UMEMOTO 		RES_SET_H_ERRNO(statp, NETDB_INTERNAL);
488d3ac2b30SHajimu UMEMOTO 		*h_errnop = statp->res_h_errno;
489d3ac2b30SHajimu UMEMOTO 		return (NS_NOTFOUND);
490d3ac2b30SHajimu UMEMOTO 	}
491d3ac2b30SHajimu UMEMOTO 
492d3ac2b30SHajimu UMEMOTO 	he.h_addrtype = af;
4935ce1c533SPeter Wemm 	switch (af) {
4945ce1c533SPeter Wemm 	case AF_INET:
495d3ac2b30SHajimu UMEMOTO 		he.h_length = NS_INADDRSZ;
4965ce1c533SPeter Wemm 		type = T_A;
4975ce1c533SPeter Wemm 		break;
4985ce1c533SPeter Wemm 	case AF_INET6:
499d3ac2b30SHajimu UMEMOTO 		he.h_length = NS_IN6ADDRSZ;
5005ce1c533SPeter Wemm 		type = T_AAAA;
5015ce1c533SPeter Wemm 		break;
5025ce1c533SPeter Wemm 	default:
503d3ac2b30SHajimu UMEMOTO 		RES_SET_H_ERRNO(statp, NETDB_INTERNAL);
504d3ac2b30SHajimu UMEMOTO 		*h_errnop = statp->res_h_errno;
5055ce1c533SPeter Wemm 		errno = EAFNOSUPPORT;
506d3ac2b30SHajimu UMEMOTO 		return (NS_UNAVAIL);
5075ce1c533SPeter Wemm 	}
5085ce1c533SPeter Wemm 
509a52b6b83SHajimu UMEMOTO 	if ((buf = malloc(sizeof(*buf))) == NULL) {
510d3ac2b30SHajimu UMEMOTO 		RES_SET_H_ERRNO(statp, NETDB_INTERNAL);
511d3ac2b30SHajimu UMEMOTO 		*h_errnop = statp->res_h_errno;
512d3ac2b30SHajimu UMEMOTO 		return (NS_NOTFOUND);
513a52b6b83SHajimu UMEMOTO 	}
514d3ac2b30SHajimu UMEMOTO 	n = res_nsearch(statp, name, C_IN, type, buf->buf, sizeof(buf->buf));
51554384cf3SJacques Vidrine 	if (n < 0) {
516a52b6b83SHajimu UMEMOTO 		free(buf);
51732fefb24SBaptiste Daroussin 		dbg_printf("res_nsearch failed (%d)\n", n, statp);
518d3ac2b30SHajimu UMEMOTO 		*h_errnop = statp->res_h_errno;
5192db99256SHajimu UMEMOTO 		return (NS_NOTFOUND);
520a52b6b83SHajimu UMEMOTO 	} else if (n > sizeof(buf->buf)) {
521a52b6b83SHajimu UMEMOTO 		free(buf);
52232fefb24SBaptiste Daroussin 		dbg_printf("static buffer is too small (%d)\n", n, statp);
523d3ac2b30SHajimu UMEMOTO 		*h_errnop = statp->res_h_errno;
5242db99256SHajimu UMEMOTO 		return (NS_UNAVAIL);
5251363f04cSPaul Traina 	}
526d3ac2b30SHajimu UMEMOTO 	error = gethostanswer(buf, n, name, type, &he, hed, statp);
527a52b6b83SHajimu UMEMOTO 	free(buf);
528d3ac2b30SHajimu UMEMOTO 	if (error != 0) {
529d3ac2b30SHajimu UMEMOTO 		*h_errnop = statp->res_h_errno;
5302db99256SHajimu UMEMOTO 		switch (statp->res_h_errno) {
5312db99256SHajimu UMEMOTO 		case HOST_NOT_FOUND:
532d3ac2b30SHajimu UMEMOTO 			return (NS_NOTFOUND);
5332db99256SHajimu UMEMOTO 		case TRY_AGAIN:
5342db99256SHajimu UMEMOTO 			return (NS_TRYAGAIN);
5352db99256SHajimu UMEMOTO 		default:
5362db99256SHajimu UMEMOTO 			return (NS_UNAVAIL);
5372db99256SHajimu UMEMOTO 		}
5382db99256SHajimu UMEMOTO 		/*NOTREACHED*/
539d3ac2b30SHajimu UMEMOTO 	}
540d3ac2b30SHajimu UMEMOTO 	if (__copy_hostent(&he, hptr, buffer, buflen) != 0) {
541225edeacSHajimu UMEMOTO 		*errnop = errno;
542225edeacSHajimu UMEMOTO 		RES_SET_H_ERRNO(statp, NETDB_INTERNAL);
543d3ac2b30SHajimu UMEMOTO 		*h_errnop = statp->res_h_errno;
544225edeacSHajimu UMEMOTO 		return (NS_RETURN);
545d3ac2b30SHajimu UMEMOTO 	}
546225edeacSHajimu UMEMOTO 	RES_SET_H_ERRNO(statp, NETDB_SUCCESS);
547d3ac2b30SHajimu UMEMOTO 	*((struct hostent **)rval) = hptr;
548d3ac2b30SHajimu UMEMOTO 	return (NS_SUCCESS);
5491363f04cSPaul Traina }
5501363f04cSPaul Traina 
551248aee62SJacques Vidrine int
_dns_gethostbyaddr(void * rval,void * cb_data,va_list ap)552248aee62SJacques Vidrine _dns_gethostbyaddr(void *rval, void *cb_data, va_list ap)
553248aee62SJacques Vidrine {
5543da59cd0SHajimu UMEMOTO 	const void *addr;
5553da59cd0SHajimu UMEMOTO 	socklen_t len;
5563da59cd0SHajimu UMEMOTO 	int af;
557d3ac2b30SHajimu UMEMOTO 	char *buffer;
558d3ac2b30SHajimu UMEMOTO 	size_t buflen;
559d3ac2b30SHajimu UMEMOTO 	int *errnop, *h_errnop;
5603da59cd0SHajimu UMEMOTO 	const u_char *uaddr;
561d3ac2b30SHajimu UMEMOTO 	struct hostent *hptr, he;
562aa2f4ec7SHajimu UMEMOTO 	struct hostent_data *hed;
563d3ac2b30SHajimu UMEMOTO 	int n;
564a52b6b83SHajimu UMEMOTO 	querybuf *buf;
5655ce1c533SPeter Wemm 	char qbuf[MAXDNAME+1], *qp;
566d3ac2b30SHajimu UMEMOTO 	res_state statp;
567e5ad4f87SPeter Wemm #ifdef SUNSECURITY
568aa2f4ec7SHajimu UMEMOTO 	struct hostdata rhd;
569aa2f4ec7SHajimu UMEMOTO 	struct hostent *rhe;
570e5ad4f87SPeter Wemm 	char **haddr;
571e5ad4f87SPeter Wemm 	u_long old_options;
5720d389e72SHajimu UMEMOTO 	char hname2[MAXDNAME+1], numaddr[46];
573d3ac2b30SHajimu UMEMOTO 	int ret_h_error;
574e5ad4f87SPeter Wemm #endif /*SUNSECURITY*/
5751363f04cSPaul Traina 
5763da59cd0SHajimu UMEMOTO 	addr = va_arg(ap, const void *);
5773da59cd0SHajimu UMEMOTO 	len = va_arg(ap, socklen_t);
578248aee62SJacques Vidrine 	af = va_arg(ap, int);
579d3ac2b30SHajimu UMEMOTO 	hptr = va_arg(ap, struct hostent *);
580d3ac2b30SHajimu UMEMOTO 	buffer = va_arg(ap, char *);
581d3ac2b30SHajimu UMEMOTO 	buflen = va_arg(ap, size_t);
582d3ac2b30SHajimu UMEMOTO 	errnop = va_arg(ap, int *);
583d3ac2b30SHajimu UMEMOTO 	h_errnop = va_arg(ap, int *);
5843da59cd0SHajimu UMEMOTO 	uaddr = (const u_char *)addr;
585d3ac2b30SHajimu UMEMOTO 
586d3ac2b30SHajimu UMEMOTO 	*((struct hostent **)rval) = NULL;
587d3ac2b30SHajimu UMEMOTO 
588d3ac2b30SHajimu UMEMOTO 	statp = __res_state();
589d3ac2b30SHajimu UMEMOTO 	if ((hed = __hostent_data_init()) == NULL) {
590d3ac2b30SHajimu UMEMOTO 		RES_SET_H_ERRNO(statp, NETDB_INTERNAL);
591d3ac2b30SHajimu UMEMOTO 		*h_errnop = statp->res_h_errno;
592d3ac2b30SHajimu UMEMOTO 		return (NS_NOTFOUND);
593d3ac2b30SHajimu UMEMOTO 	}
594248aee62SJacques Vidrine 
5955ce1c533SPeter Wemm 	switch (af) {
5965ce1c533SPeter Wemm 	case AF_INET:
5971363f04cSPaul Traina 		(void) sprintf(qbuf, "%u.%u.%u.%u.in-addr.arpa",
5985ce1c533SPeter Wemm 			       (uaddr[3] & 0xff),
5995ce1c533SPeter Wemm 			       (uaddr[2] & 0xff),
6005ce1c533SPeter Wemm 			       (uaddr[1] & 0xff),
6015ce1c533SPeter Wemm 			       (uaddr[0] & 0xff));
6025ce1c533SPeter Wemm 		break;
6035ce1c533SPeter Wemm 	case AF_INET6:
6045ce1c533SPeter Wemm 		qp = qbuf;
605d3ac2b30SHajimu UMEMOTO 		for (n = NS_IN6ADDRSZ - 1; n >= 0; n--) {
6065ce1c533SPeter Wemm 			qp += SPRINTF((qp, "%x.%x.",
6075ce1c533SPeter Wemm 				       uaddr[n] & 0xf,
6085ce1c533SPeter Wemm 				       (uaddr[n] >> 4) & 0xf));
6095ce1c533SPeter Wemm 		}
610d0509082SJacques Vidrine 		strlcat(qbuf, "ip6.arpa", sizeof(qbuf));
6115ce1c533SPeter Wemm 		break;
6125ce1c533SPeter Wemm 	default:
6135ce1c533SPeter Wemm 		abort();
6145ce1c533SPeter Wemm 	}
615a52b6b83SHajimu UMEMOTO 	if ((buf = malloc(sizeof(*buf))) == NULL) {
616d3ac2b30SHajimu UMEMOTO 		RES_SET_H_ERRNO(statp, NETDB_INTERNAL);
617d3ac2b30SHajimu UMEMOTO 		*h_errnop = statp->res_h_errno;
618a52b6b83SHajimu UMEMOTO 		return NS_NOTFOUND;
619a52b6b83SHajimu UMEMOTO 	}
620d3ac2b30SHajimu UMEMOTO 	n = res_nquery(statp, qbuf, C_IN, T_PTR, (u_char *)buf->buf,
6215342d17fSHajimu UMEMOTO 	    sizeof buf->buf);
6221363f04cSPaul Traina 	if (n < 0) {
623a52b6b83SHajimu UMEMOTO 		free(buf);
62432fefb24SBaptiste Daroussin 		dbg_printf("res_nquery failed (%d)\n", n, statp);
625d3ac2b30SHajimu UMEMOTO 		*h_errnop = statp->res_h_errno;
626d3ac2b30SHajimu UMEMOTO 		return (NS_UNAVAIL);
6271363f04cSPaul Traina 	}
628a52b6b83SHajimu UMEMOTO 	if (n > sizeof buf->buf) {
629a52b6b83SHajimu UMEMOTO 		free(buf);
63032fefb24SBaptiste Daroussin 		dbg_printf("static buffer is too small (%d)\n", n, statp);
631d3ac2b30SHajimu UMEMOTO 		*h_errnop = statp->res_h_errno;
632d3ac2b30SHajimu UMEMOTO 		return (NS_UNAVAIL);
633686d0736SBill Fenner 	}
634d3ac2b30SHajimu UMEMOTO 	if (gethostanswer(buf, n, qbuf, T_PTR, &he, hed, statp) != 0) {
635a52b6b83SHajimu UMEMOTO 		free(buf);
636d3ac2b30SHajimu UMEMOTO 		*h_errnop = statp->res_h_errno;
6372db99256SHajimu UMEMOTO 		switch (statp->res_h_errno) {
6382db99256SHajimu UMEMOTO 		case HOST_NOT_FOUND:
6392db99256SHajimu UMEMOTO 			return (NS_NOTFOUND);
6402db99256SHajimu UMEMOTO 		case TRY_AGAIN:
6412db99256SHajimu UMEMOTO 			return (NS_TRYAGAIN);
6422db99256SHajimu UMEMOTO 		default:
6432db99256SHajimu UMEMOTO 			return (NS_UNAVAIL);
6442db99256SHajimu UMEMOTO 		}
6452db99256SHajimu UMEMOTO 		/*NOTREACHED*/
646a52b6b83SHajimu UMEMOTO 	}
647a52b6b83SHajimu UMEMOTO 	free(buf);
648e5ad4f87SPeter Wemm #ifdef SUNSECURITY
6495ce1c533SPeter Wemm 	if (af == AF_INET) {
650e5ad4f87SPeter Wemm 	    /*
651e5ad4f87SPeter Wemm 	     * turn off search as the name should be absolute,
652e5ad4f87SPeter Wemm 	     * 'localhost' should be matched by defnames
653e5ad4f87SPeter Wemm 	     */
654d3ac2b30SHajimu UMEMOTO 	    strncpy(hname2, he.h_name, MAXDNAME);
655e5ad4f87SPeter Wemm 	    hname2[MAXDNAME] = '\0';
656d3ac2b30SHajimu UMEMOTO 	    old_options = statp->options;
657d3ac2b30SHajimu UMEMOTO 	    statp->options &= ~RES_DNSRCH;
658d3ac2b30SHajimu UMEMOTO 	    statp->options |= RES_DEFNAMES;
659aa2f4ec7SHajimu UMEMOTO 	    memset(&rhd, 0, sizeof rhd);
660d3ac2b30SHajimu UMEMOTO 	    rhe = gethostbyname_r(hname2, &rhd.host, &rhd.data,
661d3ac2b30SHajimu UMEMOTO 	        sizeof(rhd.data), &ret_h_error);
662d3ac2b30SHajimu UMEMOTO 	    if (rhe == NULL) {
6630d389e72SHajimu UMEMOTO 		if (inet_ntop(af, addr, numaddr, sizeof(numaddr)) == NULL)
6640d389e72SHajimu UMEMOTO 		    strlcpy(numaddr, "UNKNOWN", sizeof(numaddr));
665e5ad4f87SPeter Wemm 		syslog(LOG_NOTICE|LOG_AUTH,
666e5ad4f87SPeter Wemm 		       "gethostbyaddr: No A record for %s (verifying [%s])",
6670d389e72SHajimu UMEMOTO 		       hname2, numaddr);
668d3ac2b30SHajimu UMEMOTO 		statp->options = old_options;
669d3ac2b30SHajimu UMEMOTO 		RES_SET_H_ERRNO(statp, HOST_NOT_FOUND);
670d3ac2b30SHajimu UMEMOTO 		*h_errnop = statp->res_h_errno;
671d3ac2b30SHajimu UMEMOTO 		return (NS_NOTFOUND);
672e5ad4f87SPeter Wemm 	    }
673d3ac2b30SHajimu UMEMOTO 	    statp->options = old_options;
674aa2f4ec7SHajimu UMEMOTO 	    for (haddr = rhe->h_addr_list; *haddr; haddr++)
675d3ac2b30SHajimu UMEMOTO 		if (!memcmp(*haddr, addr, NS_INADDRSZ))
676e5ad4f87SPeter Wemm 			break;
677e5ad4f87SPeter Wemm 	    if (!*haddr) {
6780d389e72SHajimu UMEMOTO 		if (inet_ntop(af, addr, numaddr, sizeof(numaddr)) == NULL)
6790d389e72SHajimu UMEMOTO 		    strlcpy(numaddr, "UNKNOWN", sizeof(numaddr));
680e5ad4f87SPeter Wemm 		syslog(LOG_NOTICE|LOG_AUTH,
681e5ad4f87SPeter Wemm 		       "gethostbyaddr: A record of %s != PTR record [%s]",
6820d389e72SHajimu UMEMOTO 		       hname2, numaddr);
683d3ac2b30SHajimu UMEMOTO 		RES_SET_H_ERRNO(statp, HOST_NOT_FOUND);
684d3ac2b30SHajimu UMEMOTO 		*h_errnop = statp->res_h_errno;
685d3ac2b30SHajimu UMEMOTO 		return (NS_NOTFOUND);
686e5ad4f87SPeter Wemm 	    }
6875ce1c533SPeter Wemm 	}
688e5ad4f87SPeter Wemm #endif /*SUNSECURITY*/
689d3ac2b30SHajimu UMEMOTO 	he.h_addrtype = af;
690d3ac2b30SHajimu UMEMOTO 	he.h_length = len;
6912c08ac2bSHajimu UMEMOTO 	memcpy(hed->host_addr, uaddr, len);
692aa2f4ec7SHajimu UMEMOTO 	hed->h_addr_ptrs[0] = (char *)hed->host_addr;
693aa2f4ec7SHajimu UMEMOTO 	hed->h_addr_ptrs[1] = NULL;
694d3ac2b30SHajimu UMEMOTO 	if (af == AF_INET && (statp->options & RES_USE_INET6)) {
695aa2f4ec7SHajimu UMEMOTO 		_map_v4v6_address((char*)hed->host_addr, (char*)hed->host_addr);
696d3ac2b30SHajimu UMEMOTO 		he.h_addrtype = AF_INET6;
697d3ac2b30SHajimu UMEMOTO 		he.h_length = NS_IN6ADDRSZ;
6985ce1c533SPeter Wemm 	}
699d3ac2b30SHajimu UMEMOTO 	if (__copy_hostent(&he, hptr, buffer, buflen) != 0) {
700225edeacSHajimu UMEMOTO 		*errnop = errno;
701225edeacSHajimu UMEMOTO 		RES_SET_H_ERRNO(statp, NETDB_INTERNAL);
702d3ac2b30SHajimu UMEMOTO 		*h_errnop = statp->res_h_errno;
703225edeacSHajimu UMEMOTO 		return (NS_RETURN);
704d3ac2b30SHajimu UMEMOTO 	}
705225edeacSHajimu UMEMOTO 	RES_SET_H_ERRNO(statp, NETDB_SUCCESS);
706d3ac2b30SHajimu UMEMOTO 	*((struct hostent **)rval) = hptr;
707d3ac2b30SHajimu UMEMOTO 	return (NS_SUCCESS);
7081363f04cSPaul Traina }
7091363f04cSPaul Traina 
7104faad310SPeter Wemm #ifdef RESOLVSORT
7114faad310SPeter Wemm static void
addrsort(char ** ap,int num,res_state res)712d3ac2b30SHajimu UMEMOTO addrsort(char **ap, int num, res_state res)
7134faad310SPeter Wemm {
7144faad310SPeter Wemm 	int i, j;
7154faad310SPeter Wemm 	char **p;
716aa2f4ec7SHajimu UMEMOTO 	short aval[_MAXADDRS];
7174faad310SPeter Wemm 	int needsort = 0;
7184faad310SPeter Wemm 
7194faad310SPeter Wemm 	p = ap;
7204faad310SPeter Wemm 	for (i = 0; i < num; i++, p++) {
7215342d17fSHajimu UMEMOTO 	    for (j = 0 ; (unsigned)j < res->nsort; j++)
7225342d17fSHajimu UMEMOTO 		if (res->sort_list[j].addr.s_addr ==
7235342d17fSHajimu UMEMOTO 		    (((struct in_addr *)(*p))->s_addr & res->sort_list[j].mask))
7244faad310SPeter Wemm 			break;
7254faad310SPeter Wemm 	    aval[i] = j;
7264faad310SPeter Wemm 	    if (needsort == 0 && i > 0 && j < aval[i-1])
7274faad310SPeter Wemm 		needsort = i;
7284faad310SPeter Wemm 	}
7294faad310SPeter Wemm 	if (!needsort)
7304faad310SPeter Wemm 	    return;
7314faad310SPeter Wemm 
7324faad310SPeter Wemm 	while (needsort < num) {
7334faad310SPeter Wemm 	    for (j = needsort - 1; j >= 0; j--) {
7344faad310SPeter Wemm 		if (aval[j] > aval[j+1]) {
7354faad310SPeter Wemm 		    char *hp;
7364faad310SPeter Wemm 
7374faad310SPeter Wemm 		    i = aval[j];
7384faad310SPeter Wemm 		    aval[j] = aval[j+1];
7394faad310SPeter Wemm 		    aval[j+1] = i;
7404faad310SPeter Wemm 
7414faad310SPeter Wemm 		    hp = ap[j];
7424faad310SPeter Wemm 		    ap[j] = ap[j+1];
7434faad310SPeter Wemm 		    ap[j+1] = hp;
7444faad310SPeter Wemm 
7454faad310SPeter Wemm 		} else
7464faad310SPeter Wemm 		    break;
7474faad310SPeter Wemm 	    }
7484faad310SPeter Wemm 	    needsort++;
7494faad310SPeter Wemm 	}
7504faad310SPeter Wemm }
7514faad310SPeter Wemm #endif
7525342d17fSHajimu UMEMOTO 
7531363f04cSPaul Traina void
_sethostdnsent(int stayopen)754d3ac2b30SHajimu UMEMOTO _sethostdnsent(int stayopen)
7551363f04cSPaul Traina {
7565342d17fSHajimu UMEMOTO 	res_state statp;
7575342d17fSHajimu UMEMOTO 
7585342d17fSHajimu UMEMOTO 	statp = __res_state();
7595342d17fSHajimu UMEMOTO 	if ((statp->options & RES_INIT) == 0 && res_ninit(statp) == -1)
7604faad310SPeter Wemm 		return;
7611363f04cSPaul Traina 	if (stayopen)
7625342d17fSHajimu UMEMOTO 		statp->options |= RES_STAYOPEN | RES_USEVC;
7631363f04cSPaul Traina }
7641363f04cSPaul Traina 
7651363f04cSPaul Traina void
_endhostdnsent(void)766626c9d74SCraig Rodrigues _endhostdnsent(void)
7671363f04cSPaul Traina {
7685342d17fSHajimu UMEMOTO 	res_state statp;
7695342d17fSHajimu UMEMOTO 
7705342d17fSHajimu UMEMOTO 	statp = __res_state();
7715342d17fSHajimu UMEMOTO 	statp->options &= ~(RES_STAYOPEN | RES_USEVC);
7725342d17fSHajimu UMEMOTO 	res_nclose(statp);
7731363f04cSPaul Traina }
774