xref: /dflybsd-src/lib/libc/net/getaddrinfo.c (revision ce0e08e21d42c06c0014fae6b9d27144aa5109b0)
1 /*	$FreeBSD: src/lib/libc/net/getaddrinfo.c,v 1.9.2.14 2002/11/08 17:49:31 ume Exp $	*/
2 /*	$DragonFly: src/lib/libc/net/getaddrinfo.c,v 1.9 2008/10/04 22:38:42 swildner Exp $	*/
3 /*	$KAME: getaddrinfo.c,v 1.15 2000/07/09 04:37:24 itojun Exp $	*/
4 
5 /*
6  * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
7  * All rights reserved.
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions
11  * are met:
12  * 1. Redistributions of source code must retain the above copyright
13  *    notice, this list of conditions and the following disclaimer.
14  * 2. Redistributions in binary form must reproduce the above copyright
15  *    notice, this list of conditions and the following disclaimer in the
16  *    documentation and/or other materials provided with the distribution.
17  * 3. Neither the name of the project nor the names of its contributors
18  *    may be used to endorse or promote products derived from this software
19  *    without specific prior written permission.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
22  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24  * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
25  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31  * SUCH DAMAGE.
32  */
33 
34 /*
35  * "#ifdef FAITH" part is local hack for supporting IPv4-v6 translator.
36  *
37  * Issues to be discussed:
38  * - Thread safe-ness must be checked.
39  * - Return values.  There are nonstandard return values defined and used
40  *   in the source code.  This is because RFC2553 is silent about which error
41  *   code must be returned for which situation.
42  * - freeaddrinfo(NULL).  RFC2553 is silent about it.  XNET 5.2 says it is
43  *   invalid.  current code - SEGV on freeaddrinfo(NULL)
44  *
45  * Note:
46  * - The code filters out AFs that are not supported by the kernel,
47  *   when globbing NULL hostname (to loopback, or wildcard).  Is it the right
48  *   thing to do?  What is the relationship with post-RFC2553 AI_ADDRCONFIG
49  *   in ai_flags?
50  * - (post-2553) semantics of AI_ADDRCONFIG itself is too vague.
51  *   (1) what should we do against numeric hostname (2) what should we do
52  *   against NULL hostname (3) what is AI_ADDRCONFIG itself.  AF not ready?
53  *   non-loopback address configured?  global address configured?
54  *
55  * OS specific notes for netbsd/openbsd/freebsd4/bsdi4:
56  * - To avoid search order issue, we have a big amount of code duplicate
57  *   from gethnamaddr.c and some other places.  The issues that there's no
58  *   lower layer function to lookup "IPv4 or IPv6" record.  Calling
59  *   gethostbyname2 from getaddrinfo will end up in wrong search order, as
60  *   presented above.
61  *
62  * OS specific notes for freebsd4:
63  * - FreeBSD supported $GAI.  The code does not.
64  * - FreeBSD allowed classful IPv4 numeric (127.1), the code does not.
65  */
66 
67 #include "namespace.h"
68 #include <sys/types.h>
69 #include <sys/param.h>
70 #include <sys/socket.h>
71 #include <net/if.h>
72 #include <netinet/in.h>
73 #include <arpa/inet.h>
74 #include <arpa/nameser.h>
75 #include <netdb.h>
76 #include <resolv.h>
77 #include <string.h>
78 #include <stdlib.h>
79 #include <stddef.h>
80 #include <ctype.h>
81 #include <unistd.h>
82 #include <stdio.h>
83 #include <errno.h>
84 #include "un-namespace.h"
85 
86 #include "res_config.h"
87 
88 #ifdef DEBUG
89 #include <syslog.h>
90 #endif
91 
92 #if defined(__KAME__) && defined(INET6)
93 # define FAITH
94 #endif
95 
96 #define SUCCESS 0
97 #define ANY 0
98 #define YES 1
99 #define NO  0
100 
101 static const char in_addrany[] = { 0, 0, 0, 0 };
102 static const char in_loopback[] = { 127, 0, 0, 1 };
103 #ifdef INET6
104 static const char in6_addrany[] = {
105 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
106 };
107 static const char in6_loopback[] = {
108 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1
109 };
110 #endif
111 
112 static const struct afd {
113 	int a_af;
114 	int a_addrlen;
115 	int a_socklen;
116 	int a_off;
117 	const char *a_addrany;
118 	const char *a_loopback;
119 	int a_scoped;
120 } afdl [] = {
121 #ifdef INET6
122 #define	N_INET6 0
123 	{PF_INET6, sizeof(struct in6_addr),
124 	 sizeof(struct sockaddr_in6),
125 	 offsetof(struct sockaddr_in6, sin6_addr),
126 	 in6_addrany, in6_loopback, 1},
127 #define	N_INET 1
128 #else
129 #define	N_INET 0
130 #endif
131 	{PF_INET, sizeof(struct in_addr),
132 	 sizeof(struct sockaddr_in),
133 	 offsetof(struct sockaddr_in, sin_addr),
134 	 in_addrany, in_loopback, 0},
135 	{0, 0, 0, 0, NULL, NULL, 0},
136 };
137 
138 struct explore {
139 	int e_af;
140 	int e_socktype;
141 	int e_protocol;
142 	const char *e_protostr;
143 	int e_wild;
144 #define WILD_AF(ex)		((ex)->e_wild & 0x01)
145 #define WILD_SOCKTYPE(ex)	((ex)->e_wild & 0x02)
146 #define WILD_PROTOCOL(ex)	((ex)->e_wild & 0x04)
147 };
148 
149 static const struct explore explore[] = {
150 #if 0
151 	{ PF_LOCAL, 0, ANY, ANY, NULL, 0x01 },
152 #endif
153 #ifdef INET6
154 	{ PF_INET6, SOCK_DGRAM, IPPROTO_UDP, "udp", 0x07 },
155 	{ PF_INET6, SOCK_STREAM, IPPROTO_TCP, "tcp", 0x07 },
156 	{ PF_INET6, SOCK_RAW, ANY, NULL, 0x05 },
157 #endif
158 	{ PF_INET, SOCK_DGRAM, IPPROTO_UDP, "udp", 0x07 },
159 	{ PF_INET, SOCK_STREAM, IPPROTO_TCP, "tcp", 0x07 },
160 	{ PF_INET, SOCK_RAW, ANY, NULL, 0x05 },
161 	{ PF_UNSPEC, SOCK_DGRAM, IPPROTO_UDP, "udp", 0x07 },
162 	{ PF_UNSPEC, SOCK_STREAM, IPPROTO_TCP, "tcp", 0x07 },
163 	{ PF_UNSPEC, SOCK_RAW, ANY, NULL, 0x05 },
164 	{ -1, 0, 0, NULL, 0 },
165 };
166 
167 #ifdef INET6
168 #define PTON_MAX	16
169 #else
170 #define PTON_MAX	4
171 #endif
172 
173 #define MAXPACKET	(64*1024)
174 
175 typedef union {
176 	HEADER hdr;
177 	u_char buf[MAXPACKET];
178 } querybuf;
179 
180 struct res_target {
181 	struct res_target *next;
182 	const char *name;	/* domain name */
183 	int qclass, qtype;	/* class and type of query */
184 	u_char *answer;		/* buffer to put answer */
185 	int anslen;		/* size of answer buffer */
186 	int n;			/* result length */
187 };
188 
189 static int str2number (const char *);
190 static int explore_fqdn (const struct addrinfo *, const char *,
191 	const char *, struct addrinfo **);
192 static int explore_null (const struct addrinfo *,
193 	const char *, struct addrinfo **);
194 static int explore_numeric (const struct addrinfo *, const char *,
195 	const char *, struct addrinfo **);
196 static int explore_numeric_scope (const struct addrinfo *, const char *,
197 	const char *, struct addrinfo **);
198 static int get_canonname (const struct addrinfo *,
199 	struct addrinfo *, const char *);
200 static struct addrinfo *get_ai (const struct addrinfo *,
201 	const struct afd *, const char *);
202 static int get_portmatch (const struct addrinfo *, const char *);
203 static int get_port (struct addrinfo *, const char *, int);
204 static const struct afd *find_afd (int);
205 static int addrconfig (struct addrinfo *);
206 #ifdef INET6
207 static int ip6_str2scopeid (char *, struct sockaddr_in6 *, u_int32_t *);
208 #endif
209 
210 static struct addrinfo *getanswer (const querybuf *, int, const char *,
211 	int, const struct addrinfo *);
212 static int _dns_getaddrinfo (const struct addrinfo *, const char *,
213 	struct addrinfo **);
214 static struct addrinfo *_gethtent (FILE *fp, const char *,
215 	const struct addrinfo *);
216 static int _files_getaddrinfo (const struct addrinfo *, const char *,
217 	struct addrinfo **);
218 #ifdef YP
219 static int _nis_getaddrinfo (const struct addrinfo *, const char *,
220 	struct addrinfo **);
221 #endif
222 
223 static int res_queryN (const char *, struct res_target *);
224 static int res_searchN (const char *, struct res_target *);
225 static int res_querydomainN (const char *, const char *,
226 	struct res_target *);
227 
228 static const char *ai_errlist[] = {
229 	"Success",
230 	"Address family for hostname not supported",	/* EAI_ADDRFAMILY */
231 	"Temporary failure in name resolution",		/* EAI_AGAIN      */
232 	"Invalid value for ai_flags",		       	/* EAI_BADFLAGS   */
233 	"Non-recoverable failure in name resolution", 	/* EAI_FAIL       */
234 	"ai_family not supported",			/* EAI_FAMILY     */
235 	"Memory allocation failure", 			/* EAI_MEMORY     */
236 	"No address associated with hostname", 		/* EAI_NODATA     */
237 	"hostname nor servname provided, or not known",	/* EAI_NONAME     */
238 	"servname not supported for ai_socktype",	/* EAI_SERVICE    */
239 	"ai_socktype not supported", 			/* EAI_SOCKTYPE   */
240 	"System error returned in errno", 		/* EAI_SYSTEM     */
241 	"Invalid value for hints",			/* EAI_BADHINTS	  */
242 	"Resolved protocol is unknown",			/* EAI_PROTOCOL   */
243 	"Argument buffer overflow",			/* EAI_OVERFLOW   */
244 	"Unknown error", 				/* EAI_MAX        */
245 };
246 
247 /*
248  * Select order host function.
249  */
250 #define	MAXHOSTCONF	4
251 
252 #ifndef HOSTCONF
253 #  define	HOSTCONF	"/etc/host.conf"
254 #endif /* !HOSTCONF */
255 
256 struct _hostconf {
257 	int (*byname)(const struct addrinfo *, const char *,
258 		      struct addrinfo **);
259 };
260 
261 /* default order */
262 static struct _hostconf _hostconf[MAXHOSTCONF] = {
263 	_dns_getaddrinfo,
264 	_files_getaddrinfo,
265 #ifdef ICMPNL
266 	NULL,
267 #endif /* ICMPNL */
268 };
269 
270 static int	_hostconf_init_done;
271 static void	_hostconf_init(void);
272 
273 /* Make getaddrinfo() thread-safe in libc for use with kernel threads. */
274 #include "libc_private.h"
275 #include "spinlock.h"
276 /*
277  * XXX: Our res_*() is not thread-safe.  So, we share lock between
278  * getaddrinfo() and getipnodeby*().  Still, we cannot use
279  * getaddrinfo() and getipnodeby*() in conjunction with other
280  * functions which call res_*().
281  */
282 spinlock_t __getaddrinfo_thread_lock = _SPINLOCK_INITIALIZER;
283 #define THREAD_LOCK() \
284 	if (__isthreaded) _SPINLOCK(&__getaddrinfo_thread_lock);
285 #define THREAD_UNLOCK() \
286 	if (__isthreaded) _SPINUNLOCK(&__getaddrinfo_thread_lock);
287 
288 /* XXX macros that make external reference is BAD. */
289 
290 #define GET_AI(ai, afd, addr) \
291 do { \
292 	/* external reference: pai, error, and label free */ \
293 	(ai) = get_ai(pai, (afd), (addr)); \
294 	if ((ai) == NULL) { \
295 		error = EAI_MEMORY; \
296 		goto free; \
297 	} \
298 } while (/*CONSTCOND*/0)
299 
300 #define GET_PORT(ai, serv) \
301 do { \
302 	/* external reference: error and label free */ \
303 	error = get_port((ai), (serv), 0); \
304 	if (error != 0) \
305 		goto free; \
306 } while (/*CONSTCOND*/0)
307 
308 #define GET_CANONNAME(ai, str) \
309 do { \
310 	/* external reference: pai, error and label free */ \
311 	error = get_canonname(pai, (ai), (str)); \
312 	if (error != 0) \
313 		goto free; \
314 } while (/*CONSTCOND*/0)
315 
316 #define ERR(err) \
317 do { \
318 	/* external reference: error, and label bad */ \
319 	error = (err); \
320 	goto bad; \
321 	/*NOTREACHED*/ \
322 } while (/*CONSTCOND*/0)
323 
324 #define MATCH_FAMILY(x, y, w) \
325 	((x) == (y) || (/*CONSTCOND*/(w) && ((x) == PF_UNSPEC || (y) == PF_UNSPEC)))
326 #define MATCH(x, y, w) \
327 	((x) == (y) || (/*CONSTCOND*/(w) && ((x) == ANY || (y) == ANY)))
328 
329 const char *
330 gai_strerror(int ecode)
331 {
332 	if (ecode < 0 || ecode > EAI_MAX)
333 		ecode = EAI_MAX;
334 	return ai_errlist[ecode];
335 }
336 
337 void
338 freeaddrinfo(struct addrinfo *ai)
339 {
340 	struct addrinfo *next;
341 
342 	do {
343 		next = ai->ai_next;
344 		if (ai->ai_canonname)
345 			free(ai->ai_canonname);
346 		/* no need to free(ai->ai_addr) */
347 		free(ai);
348 		ai = next;
349 	} while (ai);
350 }
351 
352 static int
353 str2number(const char *p)
354 {
355 	char *ep;
356 	unsigned long v;
357 
358 	if (*p == '\0')
359 		return -1;
360 	ep = NULL;
361 	errno = 0;
362 	v = strtoul(p, &ep, 10);
363 	if (errno == 0 && ep && *ep == '\0' && v <= UINT_MAX)
364 		return v;
365 	else
366 		return -1;
367 }
368 
369 int
370 getaddrinfo(const char *hostname, const char *servname,
371 	    const struct addrinfo *hints, struct addrinfo **res)
372 {
373 	struct addrinfo sentinel;
374 	struct addrinfo *cur;
375 	int error = 0;
376 	struct addrinfo ai;
377 	struct addrinfo ai0;
378 	struct addrinfo *pai;
379 	const struct explore *ex;
380 
381 	memset(&sentinel, 0, sizeof(sentinel));
382 	cur = &sentinel;
383 	pai = &ai;
384 	pai->ai_flags = 0;
385 	pai->ai_family = PF_UNSPEC;
386 	pai->ai_socktype = ANY;
387 	pai->ai_protocol = ANY;
388 	pai->ai_addrlen = 0;
389 	pai->ai_canonname = NULL;
390 	pai->ai_addr = NULL;
391 	pai->ai_next = NULL;
392 
393 	if (hostname == NULL && servname == NULL)
394 		return EAI_NONAME;
395 	if (hints) {
396 		/* error check for hints */
397 		if (hints->ai_addrlen || hints->ai_canonname ||
398 		    hints->ai_addr || hints->ai_next)
399 			ERR(EAI_BADHINTS); /* xxx */
400 		if (hints->ai_flags & ~AI_MASK)
401 			ERR(EAI_BADFLAGS);
402 		switch (hints->ai_family) {
403 		case PF_UNSPEC:
404 		case PF_INET:
405 #ifdef INET6
406 		case PF_INET6:
407 #endif
408 			break;
409 		default:
410 			ERR(EAI_FAMILY);
411 		}
412 		memcpy(pai, hints, sizeof(*pai));
413 
414 		/*
415 		 * if both socktype/protocol are specified, check if they
416 		 * are meaningful combination.
417 		 */
418 		if (pai->ai_socktype != ANY && pai->ai_protocol != ANY) {
419 			for (ex = explore; ex->e_af >= 0; ex++) {
420 				if (pai->ai_family != ex->e_af)
421 					continue;
422 				if (ex->e_socktype == ANY)
423 					continue;
424 				if (ex->e_protocol == ANY)
425 					continue;
426 				if (pai->ai_socktype == ex->e_socktype &&
427 				    pai->ai_protocol != ex->e_protocol) {
428 					ERR(EAI_BADHINTS);
429 				}
430 			}
431 		}
432 	}
433 
434 	/*
435 	 * post-2553: AI_ALL and AI_V4MAPPED are effective only against
436 	 * AF_INET6 query.  They need to be ignored if specified in other
437 	 * occassions.
438 	 */
439 	switch (pai->ai_flags & (AI_ALL | AI_V4MAPPED)) {
440 	case AI_V4MAPPED:
441 	case AI_ALL | AI_V4MAPPED:
442 		if (pai->ai_family != AF_INET6)
443 			pai->ai_flags &= ~(AI_ALL | AI_V4MAPPED);
444 		break;
445 	case AI_ALL:
446 #if 1
447 		/* illegal */
448 		ERR(EAI_BADFLAGS);
449 #else
450 		pai->ai_flags &= ~(AI_ALL | AI_V4MAPPED);
451 #endif
452 		break;
453 	}
454 
455 	/*
456 	 * check for special cases.  (1) numeric servname is disallowed if
457 	 * socktype/protocol are left unspecified. (2) servname is disallowed
458 	 * for raw and other inet{,6} sockets.
459 	 */
460 	if (MATCH_FAMILY(pai->ai_family, PF_INET, 1)
461 #ifdef PF_INET6
462 	    || MATCH_FAMILY(pai->ai_family, PF_INET6, 1)
463 #endif
464 	    ) {
465 		ai0 = *pai;	/* backup *pai */
466 
467 		if (pai->ai_family == PF_UNSPEC) {
468 #ifdef PF_INET6
469 			pai->ai_family = PF_INET6;
470 #else
471 			pai->ai_family = PF_INET;
472 #endif
473 		}
474 		error = get_portmatch(pai, servname);
475 		if (error)
476 			ERR(error);
477 
478 		*pai = ai0;
479 	}
480 
481 	ai0 = *pai;
482 
483 	/* NULL hostname, or numeric hostname */
484 	for (ex = explore; ex->e_af >= 0; ex++) {
485 		*pai = ai0;
486 
487 		/* PF_UNSPEC entries are prepared for DNS queries only */
488 		if (ex->e_af == PF_UNSPEC)
489 			continue;
490 
491 		if (!MATCH_FAMILY(pai->ai_family, ex->e_af, WILD_AF(ex)))
492 			continue;
493 		if (!MATCH(pai->ai_socktype, ex->e_socktype,
494 			   WILD_SOCKTYPE(ex)))
495 			continue;
496 		if (!MATCH(pai->ai_protocol, ex->e_protocol,
497 			   WILD_PROTOCOL(ex)))
498 			continue;
499 
500 		if (pai->ai_family == PF_UNSPEC)
501 			pai->ai_family = ex->e_af;
502 		if (pai->ai_socktype == ANY && ex->e_socktype != ANY)
503 			pai->ai_socktype = ex->e_socktype;
504 		if (pai->ai_protocol == ANY && ex->e_protocol != ANY)
505 			pai->ai_protocol = ex->e_protocol;
506 
507 		if (hostname == NULL)
508 			error = explore_null(pai, servname, &cur->ai_next);
509 		else
510 			error = explore_numeric_scope(pai, hostname, servname,
511 						      &cur->ai_next);
512 
513 		if (error)
514 			goto free;
515 
516 		while (cur && cur->ai_next)
517 			cur = cur->ai_next;
518 	}
519 
520 	/*
521 	 * XXX
522 	 * If numreic representation of AF1 can be interpreted as FQDN
523 	 * representation of AF2, we need to think again about the code below.
524 	 */
525 	if (sentinel.ai_next)
526 		goto good;
527 
528 	if (pai->ai_flags & AI_NUMERICHOST)
529 		ERR(EAI_NONAME);
530 	if (hostname == NULL)
531 		ERR(EAI_NODATA);
532 
533 	if ((pai->ai_flags & AI_ADDRCONFIG) != 0 && !addrconfig(&ai0))
534 		ERR(EAI_FAIL);
535 
536 	/*
537 	 * hostname as alphabetical name.
538 	 * we would like to prefer AF_INET6 than AF_INET, so we'll make a
539 	 * outer loop by AFs.
540 	 */
541 	for (ex = explore; ex->e_af >= 0; ex++) {
542 		*pai = ai0;
543 
544 		/* require exact match for family field */
545 		if (pai->ai_family != ex->e_af)
546 			continue;
547 
548 		if (!MATCH(pai->ai_socktype, ex->e_socktype, WILD_SOCKTYPE(ex))) {
549 			continue;
550 		}
551 		if (!MATCH(pai->ai_protocol, ex->e_protocol, WILD_PROTOCOL(ex))) {
552 			continue;
553 		}
554 
555 		if (pai->ai_socktype == ANY && ex->e_socktype != ANY)
556 			pai->ai_socktype = ex->e_socktype;
557 		if (pai->ai_protocol == ANY && ex->e_protocol != ANY)
558 			pai->ai_protocol = ex->e_protocol;
559 
560 		error = explore_fqdn(pai, hostname, servname, &cur->ai_next);
561 
562 		while (cur && cur->ai_next)
563 			cur = cur->ai_next;
564 	}
565 
566 	/* XXX */
567 	if (sentinel.ai_next)
568 		error = 0;
569 
570 	if (error)
571 		goto free;
572 	if (error == 0) {
573 		if (sentinel.ai_next) {
574  good:
575 			*res = sentinel.ai_next;
576 			return SUCCESS;
577 		} else
578 			error = EAI_FAIL;
579 	}
580  free:
581  bad:
582 	if (sentinel.ai_next)
583 		freeaddrinfo(sentinel.ai_next);
584 	*res = NULL;
585 	return error;
586 }
587 
588 static char *
589 _hgetword(char **pp)
590 {
591 	char c, *p, *ret;
592 	const char *sp;
593 	static const char sep[] = "# \t\n";
594 
595 	ret = NULL;
596 	for (p = *pp; (c = *p) != '\0'; p++) {
597 		for (sp = sep; *sp != '\0'; sp++) {
598 			if (c == *sp)
599 				break;
600 		}
601 		if (c == '#')
602 			p[1] = '\0';	/* ignore rest of line */
603 		if (ret == NULL) {
604 			if (*sp == '\0')
605 				ret = p;
606 		} else {
607 			if (*sp != '\0') {
608 				*p++ = '\0';
609 				break;
610 			}
611 		}
612 	}
613 	*pp = p;
614 	if (ret == NULL || *ret == '\0')
615 		return NULL;
616 	return ret;
617 }
618 
619 /*
620  * Initialize hostconf structure.
621  */
622 
623 static void
624 _hostconf_init(void)
625 {
626 	FILE *fp;
627 	int n;
628 	char *p, *line;
629 	char buf[BUFSIZ];
630 
631 	_hostconf_init_done = 1;
632 	n = 0;
633 	p = HOSTCONF;
634 	if ((fp = fopen(p, "r")) == NULL)
635 		return;
636 	while (n < MAXHOSTCONF && fgets(buf, sizeof(buf), fp)) {
637 		line = buf;
638 		if ((p = _hgetword(&line)) == NULL)
639 			continue;
640 		do {
641 			if (strcmp(p, "hosts") == 0
642 			||  strcmp(p, "local") == 0
643 			||  strcmp(p, "file") == 0
644 			||  strcmp(p, "files") == 0)
645 				_hostconf[n++].byname = _files_getaddrinfo;
646 			else if (strcmp(p, "dns") == 0
647 			     ||  strcmp(p, "bind") == 0)
648 				_hostconf[n++].byname = _dns_getaddrinfo;
649 #ifdef YP
650 			else if (strcmp(p, "nis") == 0)
651 				_hostconf[n++].byname = _nis_getaddrinfo;
652 #endif
653 		} while ((p = _hgetword(&line)) != NULL);
654 	}
655 	fclose(fp);
656 	if (n < 0) {
657 		/* no keyword found. do not change default configuration */
658 		return;
659 	}
660 	for (; n < MAXHOSTCONF; n++)
661 		_hostconf[n].byname = NULL;
662 }
663 
664 /*
665  * FQDN hostname, DNS lookup
666  */
667 static int
668 explore_fqdn(const struct addrinfo *pai, const char *hostname,
669 	     const char *servname, struct addrinfo **res)
670 {
671 	struct addrinfo *result;
672 	struct addrinfo *cur;
673 	int error = 0, i;
674 
675 	result = NULL;
676 	*res = NULL;
677 
678 	THREAD_LOCK();
679 
680 	/*
681 	 * if the servname does not match socktype/protocol, ignore it.
682 	 */
683 	if (get_portmatch(pai, servname) != 0) {
684 		THREAD_UNLOCK();
685 		return 0;
686 	}
687 
688 	if (!_hostconf_init_done)
689 		_hostconf_init();
690 
691 	for (i = 0; i < MAXHOSTCONF; i++) {
692 		if (!_hostconf[i].byname)
693 			continue;
694 		error = (*_hostconf[i].byname)(pai, hostname, &result);
695 		if (error != 0)
696 			continue;
697 		for (cur = result; cur; cur = cur->ai_next) {
698 			GET_PORT(cur, servname);
699 			/* canonname should be filled already */
700 		}
701 		THREAD_UNLOCK();
702 		*res = result;
703 		return 0;
704 	}
705 
706 free:
707 	THREAD_UNLOCK();
708 	if (result)
709 		freeaddrinfo(result);
710 	return error;
711 }
712 
713 /*
714  * hostname == NULL.
715  * passive socket -> anyaddr (0.0.0.0 or ::)
716  * non-passive socket -> localhost (127.0.0.1 or ::1)
717  */
718 static int
719 explore_null(const struct addrinfo *pai, const char *servname,
720 	     struct addrinfo **res)
721 {
722 	int s;
723 	const struct afd *afd;
724 	struct addrinfo *cur;
725 	struct addrinfo sentinel;
726 	int error;
727 
728 	*res = NULL;
729 	sentinel.ai_next = NULL;
730 	cur = &sentinel;
731 
732 	/*
733 	 * filter out AFs that are not supported by the kernel
734 	 * XXX errno?
735 	 */
736 	s = _socket(pai->ai_family, SOCK_DGRAM, 0);
737 	if (s < 0) {
738 		if (errno != EMFILE)
739 			return 0;
740 	} else
741 		_close(s);
742 
743 	/*
744 	 * if the servname does not match socktype/protocol, ignore it.
745 	 */
746 	if (get_portmatch(pai, servname) != 0)
747 		return 0;
748 
749 	afd = find_afd(pai->ai_family);
750 	if (afd == NULL)
751 		return 0;
752 
753 	if (pai->ai_flags & AI_PASSIVE) {
754 		GET_AI(cur->ai_next, afd, afd->a_addrany);
755 		/* xxx meaningless?
756 		 * GET_CANONNAME(cur->ai_next, "anyaddr");
757 		 */
758 		GET_PORT(cur->ai_next, servname);
759 	} else {
760 		GET_AI(cur->ai_next, afd, afd->a_loopback);
761 		/* xxx meaningless?
762 		 * GET_CANONNAME(cur->ai_next, "localhost");
763 		 */
764 		GET_PORT(cur->ai_next, servname);
765 	}
766 	cur = cur->ai_next;
767 
768 	*res = sentinel.ai_next;
769 	return 0;
770 
771 free:
772 	if (sentinel.ai_next)
773 		freeaddrinfo(sentinel.ai_next);
774 	return error;
775 }
776 
777 /*
778  * numeric hostname
779  */
780 static int
781 explore_numeric(const struct addrinfo *pai, const char *hostname,
782 		const char *servname, struct addrinfo **res)
783 {
784 	const struct afd *afd;
785 	struct addrinfo *cur;
786 	struct addrinfo sentinel;
787 	int error;
788 	char pton[PTON_MAX];
789 
790 	*res = NULL;
791 	sentinel.ai_next = NULL;
792 	cur = &sentinel;
793 
794 	/*
795 	 * if the servname does not match socktype/protocol, ignore it.
796 	 */
797 	if (get_portmatch(pai, servname) != 0)
798 		return 0;
799 
800 	afd = find_afd(pai->ai_family);
801 	if (afd == NULL)
802 		return 0;
803 
804 	switch (afd->a_af) {
805 #if 1 /*X/Open spec*/
806 	case AF_INET:
807 		if (inet_aton(hostname, (struct in_addr *)pton) == 1) {
808 			if (pai->ai_family == afd->a_af ||
809 			    pai->ai_family == PF_UNSPEC /*?*/) {
810 				GET_AI(cur->ai_next, afd, pton);
811 				GET_PORT(cur->ai_next, servname);
812 				while (cur && cur->ai_next)
813 					cur = cur->ai_next;
814 			} else
815 				ERR(EAI_FAMILY);	/*xxx*/
816 		}
817 		break;
818 #endif
819 	default:
820 		if (inet_pton(afd->a_af, hostname, pton) == 1) {
821 			if (pai->ai_family == afd->a_af ||
822 			    pai->ai_family == PF_UNSPEC /*?*/) {
823 				GET_AI(cur->ai_next, afd, pton);
824 				GET_PORT(cur->ai_next, servname);
825 				while (cur && cur->ai_next)
826 					cur = cur->ai_next;
827 			} else
828 				ERR(EAI_FAMILY);	/* XXX */
829 		}
830 		break;
831 	}
832 
833 	*res = sentinel.ai_next;
834 	return 0;
835 
836 free:
837 bad:
838 	if (sentinel.ai_next)
839 		freeaddrinfo(sentinel.ai_next);
840 	return error;
841 }
842 
843 /*
844  * numeric hostname with scope
845  */
846 static int
847 explore_numeric_scope(const struct addrinfo *pai, const char *hostname,
848 		      const char *servname, struct addrinfo **res)
849 {
850 #if !defined(SCOPE_DELIMITER) || !defined(INET6)
851 	return explore_numeric(pai, hostname, servname, res);
852 #else
853 	const struct afd *afd;
854 	struct addrinfo *cur;
855 	int error;
856 	char *cp, *hostname2 = NULL, *scope, *addr;
857 	struct sockaddr_in6 *sin6;
858 
859 	/*
860 	 * if the servname does not match socktype/protocol, ignore it.
861 	 */
862 	if (get_portmatch(pai, servname) != 0)
863 		return 0;
864 
865 	afd = find_afd(pai->ai_family);
866 	if (afd == NULL)
867 		return 0;
868 	if (!afd->a_scoped)
869 		return explore_numeric(pai, hostname, servname, res);
870 
871 	cp = strchr(hostname, SCOPE_DELIMITER);
872 	if (cp == NULL)
873 		return explore_numeric(pai, hostname, servname, res);
874 
875 	/*
876 	 * Handle special case of <scoped_address><delimiter><scope id>
877 	 */
878 	hostname2 = strdup(hostname);
879 	if (hostname2 == NULL)
880 		return EAI_MEMORY;
881 	/* terminate at the delimiter */
882 	hostname2[cp - hostname] = '\0';
883 	addr = hostname2;
884 	scope = cp + 1;
885 
886 	error = explore_numeric(pai, addr, servname, res);
887 	if (error == 0) {
888 		u_int32_t scopeid;
889 
890 		for (cur = *res; cur; cur = cur->ai_next) {
891 			if (cur->ai_family != AF_INET6)
892 				continue;
893 			sin6 = (struct sockaddr_in6 *)(void *)cur->ai_addr;
894 			if (ip6_str2scopeid(scope, sin6, &scopeid) == -1) {
895 				free(hostname2);
896 				return(EAI_NODATA); /* XXX: is return OK? */
897 			}
898 			sin6->sin6_scope_id = scopeid;
899 		}
900 	}
901 
902 	free(hostname2);
903 
904 	return error;
905 #endif
906 }
907 
908 static int
909 get_canonname(const struct addrinfo *pai, struct addrinfo *ai, const char *str)
910 {
911 	if ((pai->ai_flags & AI_CANONNAME) != 0) {
912 		ai->ai_canonname = (char *)malloc(strlen(str) + 1);
913 		if (ai->ai_canonname == NULL)
914 			return EAI_MEMORY;
915 		strlcpy(ai->ai_canonname, str, strlen(str) + 1);
916 	}
917 	return 0;
918 }
919 
920 static struct addrinfo *
921 get_ai(const struct addrinfo *pai, const struct afd *afd, const char *addr)
922 {
923 	char *p;
924 	struct addrinfo *ai;
925 #ifdef FAITH
926 	struct in6_addr faith_prefix;
927 	char *fp_str;
928 	int translate = 0;
929 #endif
930 
931 #ifdef FAITH
932 	/*
933 	 * Transfrom an IPv4 addr into a special IPv6 addr format for
934 	 * IPv6->IPv4 translation gateway. (only TCP is supported now)
935 	 *
936 	 * +-----------------------------------+------------+
937 	 * | faith prefix part (12 bytes)      | embedded   |
938 	 * |                                   | IPv4 addr part (4 bytes)
939 	 * +-----------------------------------+------------+
940 	 *
941 	 * faith prefix part is specified as ascii IPv6 addr format
942 	 * in environmental variable GAI.
943 	 * For FAITH to work correctly, routing to faith prefix must be
944 	 * setup toward a machine where a FAITH daemon operates.
945 	 * Also, the machine must enable some mechanizm
946 	 * (e.g. faith interface hack) to divert those packet with
947 	 * faith prefixed destination addr to user-land FAITH daemon.
948 	 */
949 	fp_str = getenv("GAI");
950 	if (fp_str && inet_pton(AF_INET6, fp_str, &faith_prefix) == 1 &&
951 	    afd->a_af == AF_INET && pai->ai_socktype == SOCK_STREAM) {
952 		u_int32_t v4a;
953 		u_int8_t v4a_top;
954 
955 		memcpy(&v4a, addr, sizeof v4a);
956 		v4a_top = v4a >> IN_CLASSA_NSHIFT;
957 		if (!IN_MULTICAST(v4a) && !IN_EXPERIMENTAL(v4a) &&
958 		    v4a_top != 0 && v4a != IN_LOOPBACKNET) {
959 			afd = &afdl[N_INET6];
960 			memcpy(&faith_prefix.s6_addr[12], addr,
961 			       sizeof(struct in_addr));
962 			translate = 1;
963 		}
964 	}
965 #endif
966 
967 	ai = (struct addrinfo *)malloc(sizeof(struct addrinfo)
968 		+ (afd->a_socklen));
969 	if (ai == NULL)
970 		return NULL;
971 
972 	memcpy(ai, pai, sizeof(struct addrinfo));
973 	ai->ai_addr = (struct sockaddr *)(void *)(ai + 1);
974 	memset(ai->ai_addr, 0, (size_t)afd->a_socklen);
975 	ai->ai_addr->sa_len = afd->a_socklen;
976 	ai->ai_addrlen = afd->a_socklen;
977 	ai->ai_addr->sa_family = ai->ai_family = afd->a_af;
978 	p = (char *)(ai->ai_addr);
979 #ifdef FAITH
980 	if (translate == 1)
981 		memcpy(p + afd->a_off, &faith_prefix, afd->a_addrlen);
982 	else
983 #endif
984 	memcpy(p + afd->a_off, addr, afd->a_addrlen);
985 
986 	return ai;
987 }
988 
989 static int
990 get_portmatch(const struct addrinfo *ai, const char *servname)
991 {
992 
993 	/* get_port does not touch first argument. when matchonly == 1. */
994 	/* LINTED const cast */
995 	return get_port((struct addrinfo *)ai, servname, 1);
996 }
997 
998 static int
999 get_port(struct addrinfo *ai, const char *servname, int matchonly)
1000 {
1001 	const char *proto;
1002 	struct servent *sp;
1003 	int port;
1004 	int allownumeric;
1005 
1006 	if (servname == NULL)
1007 		return 0;
1008 	switch (ai->ai_family) {
1009 	case AF_INET:
1010 #ifdef AF_INET6
1011 	case AF_INET6:
1012 #endif
1013 		break;
1014 	default:
1015 		return 0;
1016 	}
1017 
1018 	switch (ai->ai_socktype) {
1019 	case SOCK_RAW:
1020 		return EAI_SERVICE;
1021 	case SOCK_DGRAM:
1022 	case SOCK_STREAM:
1023 		allownumeric = 1;
1024 		break;
1025 	case ANY:
1026 		allownumeric = 0;
1027 		break;
1028 	default:
1029 		return EAI_SOCKTYPE;
1030 	}
1031 
1032 	port = str2number(servname);
1033 	if (port >= 0) {
1034 		if (!allownumeric)
1035 			return EAI_SERVICE;
1036 		if (port < 0 || port > 65535)
1037 			return EAI_SERVICE;
1038 		port = htons(port);
1039 	} else {
1040 		if (ai->ai_flags & AI_NUMERICSERV)
1041 			return EAI_NONAME;
1042 		switch (ai->ai_socktype) {
1043 		case SOCK_DGRAM:
1044 			proto = "udp";
1045 			break;
1046 		case SOCK_STREAM:
1047 			proto = "tcp";
1048 			break;
1049 		default:
1050 			proto = NULL;
1051 			break;
1052 		}
1053 
1054 		if ((sp = getservbyname(servname, proto)) == NULL)
1055 			return EAI_SERVICE;
1056 		port = sp->s_port;
1057 	}
1058 
1059 	if (!matchonly) {
1060 		switch (ai->ai_family) {
1061 		case AF_INET:
1062 			((struct sockaddr_in *)(void *)
1063 			    ai->ai_addr)->sin_port = port;
1064 			break;
1065 #ifdef INET6
1066 		case AF_INET6:
1067 			((struct sockaddr_in6 *)(void *)
1068 			    ai->ai_addr)->sin6_port = port;
1069 			break;
1070 #endif
1071 		}
1072 	}
1073 
1074 	return 0;
1075 }
1076 
1077 static const struct afd *
1078 find_afd(int af)
1079 {
1080 	const struct afd *afd;
1081 
1082 	if (af == PF_UNSPEC)
1083 		return NULL;
1084 	for (afd = afdl; afd->a_af; afd++) {
1085 		if (afd->a_af == af)
1086 			return afd;
1087 	}
1088 	return NULL;
1089 }
1090 
1091 /*
1092  * post-2553: AI_ADDRCONFIG check.  if we use getipnodeby* as backend, backend
1093  * will take care of it.
1094  * the semantics of AI_ADDRCONFIG is not defined well.  we are not sure
1095  * if the code is right or not.
1096  *
1097  * XXX PF_UNSPEC -> PF_INET6 + PF_INET mapping needs to be in sync with
1098  * _dns_getaddrinfo.
1099  */
1100 static int
1101 addrconfig(struct addrinfo *pai)
1102 {
1103 	int s, af;
1104 
1105 	/*
1106 	 * TODO:
1107 	 * Note that implementation dependent test for address
1108 	 * configuration should be done everytime called
1109 	 * (or apropriate interval),
1110 	 * because addresses will be dynamically assigned or deleted.
1111 	 */
1112 	af = pai->ai_family;
1113 	if (af == AF_UNSPEC) {
1114 		if ((s = _socket(AF_INET6, SOCK_DGRAM, 0)) < 0)
1115 			af = AF_INET;
1116 		else {
1117 			_close(s);
1118 			if ((s = _socket(AF_INET, SOCK_DGRAM, 0)) < 0)
1119 				af = AF_INET6;
1120 			else
1121 				_close(s);
1122 		}
1123 
1124 	}
1125 	if (af != AF_UNSPEC) {
1126 		if ((s = _socket(af, SOCK_DGRAM, 0)) < 0)
1127 			return 0;
1128 		_close(s);
1129 	}
1130 	pai->ai_family = af;
1131 	return 1;
1132 }
1133 
1134 #ifdef INET6
1135 /* convert a string to a scope identifier. XXX: IPv6 specific */
1136 static int
1137 ip6_str2scopeid(char *scope, struct sockaddr_in6 *sin6, u_int32_t *scopeid)
1138 {
1139 	u_long lscopeid;
1140 	struct in6_addr *a6;
1141 	char *ep;
1142 
1143 	a6 = &sin6->sin6_addr;
1144 
1145 	/* empty scopeid portion is invalid */
1146 	if (*scope == '\0')
1147 		return -1;
1148 
1149 	if (IN6_IS_ADDR_LINKLOCAL(a6) || IN6_IS_ADDR_MC_LINKLOCAL(a6)) {
1150 		/*
1151 		 * We currently assume a one-to-one mapping between links
1152 		 * and interfaces, so we simply use interface indices for
1153 		 * like-local scopes.
1154 		 */
1155 		*scopeid = if_nametoindex(scope);
1156 		if (*scopeid == 0)
1157 			goto trynumeric;
1158 		return 0;
1159 	}
1160 
1161 	/* still unclear about literal, allow numeric only - placeholder */
1162 	if (IN6_IS_ADDR_SITELOCAL(a6) || IN6_IS_ADDR_MC_SITELOCAL(a6))
1163 		goto trynumeric;
1164 	if (IN6_IS_ADDR_MC_ORGLOCAL(a6))
1165 		goto trynumeric;
1166 	else
1167 		goto trynumeric;	/* global */
1168 
1169 	/* try to convert to a numeric id as a last resort */
1170   trynumeric:
1171 	errno = 0;
1172 	lscopeid = strtoul(scope, &ep, 10);
1173 	*scopeid = (u_int32_t)(lscopeid & 0xffffffffUL);
1174 	if (errno == 0 && ep && *ep == '\0' && *scopeid == lscopeid)
1175 		return 0;
1176 	else
1177 		return -1;
1178 }
1179 #endif
1180 
1181 #ifdef RESOLVSORT
1182 struct addr_ptr {
1183 	struct addrinfo *ai;
1184 	int aval;
1185 };
1186 
1187 static int
1188 addr4sort(struct addrinfo *sentinel)
1189 {
1190 	struct addrinfo *ai;
1191 	struct addr_ptr *addrs, addr;
1192 	struct sockaddr_in *sin;
1193 	int naddrs, i, j;
1194 	int needsort = 0;
1195 
1196 	if (!sentinel)
1197 		return -1;
1198 	naddrs = 0;
1199 	for (ai = sentinel->ai_next; ai; ai = ai->ai_next)
1200 		naddrs++;
1201 	if (naddrs < 2)
1202 		return 0;		/* We don't need sorting. */
1203 	if ((addrs = malloc(sizeof(struct addr_ptr) * naddrs)) == NULL)
1204 		return -1;
1205 	i = 0;
1206 	for (ai = sentinel->ai_next; ai; ai = ai->ai_next) {
1207 		sin = (struct sockaddr_in *)ai->ai_addr;
1208 		for (j = 0; (unsigned)j < _res.nsort; j++) {
1209 			if (_res.sort_list[j].addr.s_addr ==
1210 			    (sin->sin_addr.s_addr & _res.sort_list[j].mask))
1211 				break;
1212 		}
1213 		addrs[i].ai = ai;
1214 		addrs[i].aval = j;
1215 		if (needsort == 0 && i > 0 && j < addrs[i - 1].aval)
1216 			needsort = i;
1217 		i++;
1218 	}
1219 	if (!needsort) {
1220 		free(addrs);
1221 		return 0;
1222 	}
1223 
1224 	while (needsort < naddrs) {
1225 	    for (j = needsort - 1; j >= 0; j--) {
1226 		if (addrs[j].aval > addrs[j+1].aval) {
1227 		    addr = addrs[j];
1228 		    addrs[j] = addrs[j + 1];
1229 		    addrs[j + 1] = addr;
1230 		} else
1231 		    break;
1232 	    }
1233 	    needsort++;
1234 	}
1235 
1236 	ai = sentinel;
1237 	for (i = 0; i < naddrs; ++i) {
1238 		ai->ai_next = addrs[i].ai;
1239 		ai = ai->ai_next;
1240 	}
1241 	ai->ai_next = NULL;
1242 	free(addrs);
1243 	return 0;
1244 }
1245 #endif /*RESOLVSORT*/
1246 
1247 #ifdef DEBUG
1248 static const char AskedForGot[] =
1249 	"gethostby*.getanswer: asked for \"%s\", got \"%s\"";
1250 #endif
1251 
1252 static struct addrinfo *
1253 getanswer(const querybuf *answer, int anslen, const char *qname, int qtype,
1254 	  const struct addrinfo *pai)
1255 {
1256 	struct addrinfo sentinel, *cur;
1257 	struct addrinfo ai;
1258 	const struct afd *afd;
1259 	char *canonname;
1260 	const HEADER *hp;
1261 	const u_char *cp;
1262 	int n;
1263 	const u_char *eom;
1264 	char *bp, *ep;
1265 	int type, class, ancount, qdcount;
1266 	int haveanswer, had_error;
1267 	char tbuf[MAXDNAME];
1268 	int (*name_ok) (const char *);
1269 	char hostbuf[8*1024];
1270 
1271 	memset(&sentinel, 0, sizeof(sentinel));
1272 	cur = &sentinel;
1273 
1274 	canonname = NULL;
1275 	eom = answer->buf + anslen;
1276 	switch (qtype) {
1277 	case T_A:
1278 	case T_AAAA:
1279 	case T_ANY:	/*use T_ANY only for T_A/T_AAAA lookup*/
1280 		name_ok = res_hnok;
1281 		break;
1282 	default:
1283 		return (NULL);	/* XXX should be abort(); */
1284 	}
1285 	/*
1286 	 * find first satisfactory answer
1287 	 */
1288 	hp = &answer->hdr;
1289 	ancount = ntohs(hp->ancount);
1290 	qdcount = ntohs(hp->qdcount);
1291 	bp = hostbuf;
1292 	ep = hostbuf + sizeof hostbuf;
1293 	cp = answer->buf + HFIXEDSZ;
1294 	if (qdcount != 1) {
1295 		h_errno = NO_RECOVERY;
1296 		return (NULL);
1297 	}
1298 	n = dn_expand(answer->buf, eom, cp, bp, ep - bp);
1299 	if ((n < 0) || !(*name_ok)(bp)) {
1300 		h_errno = NO_RECOVERY;
1301 		return (NULL);
1302 	}
1303 	cp += n + QFIXEDSZ;
1304 	if (qtype == T_A || qtype == T_AAAA || qtype == T_ANY) {
1305 		/* res_send() has already verified that the query name is the
1306 		 * same as the one we sent; this just gets the expanded name
1307 		 * (i.e., with the succeeding search-domain tacked on).
1308 		 */
1309 		n = strlen(bp) + 1;		/* for the \0 */
1310 		if (n >= MAXHOSTNAMELEN) {
1311 			h_errno = NO_RECOVERY;
1312 			return (NULL);
1313 		}
1314 		canonname = bp;
1315 		bp += n;
1316 		/* The qname can be abbreviated, but h_name is now absolute. */
1317 		qname = canonname;
1318 	}
1319 	haveanswer = 0;
1320 	had_error = 0;
1321 	while (ancount-- > 0 && cp < eom && !had_error) {
1322 		n = dn_expand(answer->buf, eom, cp, bp, ep - bp);
1323 		if ((n < 0) || !(*name_ok)(bp)) {
1324 			had_error++;
1325 			continue;
1326 		}
1327 		cp += n;			/* name */
1328 		type = _getshort(cp);
1329  		cp += INT16SZ;			/* type */
1330 		class = _getshort(cp);
1331  		cp += INT16SZ + INT32SZ;	/* class, TTL */
1332 		n = _getshort(cp);
1333 		cp += INT16SZ;			/* len */
1334 		if (class != C_IN) {
1335 			/* XXX - debug? syslog? */
1336 			cp += n;
1337 			continue;		/* XXX - had_error++ ? */
1338 		}
1339 		if ((qtype == T_A || qtype == T_AAAA || qtype == T_ANY) &&
1340 		    type == T_CNAME) {
1341 			n = dn_expand(answer->buf, eom, cp, tbuf, sizeof tbuf);
1342 			if ((n < 0) || !(*name_ok)(tbuf)) {
1343 				had_error++;
1344 				continue;
1345 			}
1346 			cp += n;
1347 			/* Get canonical name. */
1348 			n = strlen(tbuf) + 1;	/* for the \0 */
1349 			if (n > ep - bp || n >= MAXHOSTNAMELEN) {
1350 				had_error++;
1351 				continue;
1352 			}
1353 			strlcpy(bp, tbuf, ep - bp);
1354 			canonname = bp;
1355 			bp += n;
1356 			continue;
1357 		}
1358 		if (qtype == T_ANY) {
1359 			if (!(type == T_A || type == T_AAAA)) {
1360 				cp += n;
1361 				continue;
1362 			}
1363 		} else if (type != qtype) {
1364 #ifdef DEBUG
1365 			if (type != T_KEY && type != T_SIG)
1366 				syslog(LOG_NOTICE|LOG_AUTH,
1367 	       "gethostby*.getanswer: asked for \"%s %s %s\", got type \"%s\"",
1368 				       qname, p_class(C_IN), p_type(qtype),
1369 				       p_type(type));
1370 #endif
1371 			cp += n;
1372 			continue;		/* XXX - had_error++ ? */
1373 		}
1374 		switch (type) {
1375 		case T_A:
1376 		case T_AAAA:
1377 			if (strcasecmp(canonname, bp) != 0) {
1378 #ifdef DEBUG
1379 				syslog(LOG_NOTICE|LOG_AUTH,
1380 				       AskedForGot, canonname, bp);
1381 #endif
1382 				cp += n;
1383 				continue;	/* XXX - had_error++ ? */
1384 			}
1385 			if (type == T_A && n != INADDRSZ) {
1386 				cp += n;
1387 				continue;
1388 			}
1389 			if (type == T_AAAA && n != IN6ADDRSZ) {
1390 				cp += n;
1391 				continue;
1392 			}
1393 #ifdef FILTER_V4MAPPED
1394 			if (type == T_AAAA) {
1395 				struct in6_addr in6;
1396 				memcpy(&in6, cp, sizeof(in6));
1397 				if (IN6_IS_ADDR_V4MAPPED(&in6)) {
1398 					cp += n;
1399 					continue;
1400 				}
1401 			}
1402 #endif
1403 			if (!haveanswer) {
1404 				int nn;
1405 
1406 				canonname = bp;
1407 				nn = strlen(bp) + 1;	/* for the \0 */
1408 				bp += nn;
1409 			}
1410 
1411 			/* don't overwrite pai */
1412 			ai = *pai;
1413 			ai.ai_family = (type == T_A) ? AF_INET : AF_INET6;
1414 			afd = find_afd(ai.ai_family);
1415 			if (afd == NULL) {
1416 				cp += n;
1417 				continue;
1418 			}
1419 			cur->ai_next = get_ai(&ai, afd, (const char *)cp);
1420 			if (cur->ai_next == NULL)
1421 				had_error++;
1422 			while (cur && cur->ai_next)
1423 				cur = cur->ai_next;
1424 			cp += n;
1425 			break;
1426 		default:
1427 			abort();
1428 		}
1429 		if (!had_error)
1430 			haveanswer++;
1431 	}
1432 	if (haveanswer) {
1433 #if defined(RESOLVSORT)
1434 		/*
1435 		 * We support only IPv4 address for backward
1436 		 * compatibility against gethostbyname(3).
1437 		 */
1438 		if (_res.nsort && qtype == T_A) {
1439 			if (addr4sort(&sentinel) < 0) {
1440 				freeaddrinfo(sentinel.ai_next);
1441 				h_errno = NO_RECOVERY;
1442 				return NULL;
1443 			}
1444 		}
1445 #endif /*RESOLVSORT*/
1446 		if (!canonname)
1447 			get_canonname(pai, sentinel.ai_next, qname);
1448 		else
1449 			get_canonname(pai, sentinel.ai_next, canonname);
1450 		h_errno = NETDB_SUCCESS;
1451 		return sentinel.ai_next;
1452 	}
1453 
1454 	h_errno = NO_RECOVERY;
1455 	return NULL;
1456 }
1457 
1458 /*ARGSUSED*/
1459 static int
1460 _dns_getaddrinfo(const struct addrinfo *pai, const char *hostname,
1461 		 struct addrinfo **res)
1462 {
1463 	struct addrinfo *ai;
1464 	querybuf *buf, *buf2;
1465 	const char *name;
1466 	struct addrinfo sentinel, *cur;
1467 	struct res_target q, q2;
1468 
1469 	memset(&q, 0, sizeof(q2));
1470 	memset(&q2, 0, sizeof(q2));
1471 	memset(&sentinel, 0, sizeof(sentinel));
1472 	cur = &sentinel;
1473 
1474 	buf = malloc(sizeof(*buf));
1475 	if (!buf) {
1476 		h_errno = NETDB_INTERNAL;
1477 		return EAI_MEMORY;
1478 	}
1479 	buf2 = malloc(sizeof(*buf2));
1480 	if (!buf2) {
1481 		free(buf);
1482 		h_errno = NETDB_INTERNAL;
1483 		return EAI_MEMORY;
1484 	}
1485 
1486 	switch (pai->ai_family) {
1487 	case AF_UNSPEC:
1488 		q.name = name;
1489 		q.qclass = C_IN;
1490 		q.qtype = T_A;
1491 		q.answer = buf->buf;
1492 		q.anslen = sizeof(buf->buf);
1493 		q.next = &q2;
1494 		q2.name = name;
1495 		q2.qclass = C_IN;
1496 		q2.qtype = T_AAAA;
1497 		q2.answer = buf2->buf;
1498 		q2.anslen = sizeof(buf2->buf);
1499 		break;
1500 	case AF_INET:
1501 		q.name = name;
1502 		q.qclass = C_IN;
1503 		q.qtype = T_A;
1504 		q.answer = buf->buf;
1505 		q.anslen = sizeof(buf->buf);
1506 		break;
1507 	case AF_INET6:
1508 		q.name = name;
1509 		q.qclass = C_IN;
1510 		q.qtype = T_AAAA;
1511 		q.answer = buf->buf;
1512 		q.anslen = sizeof(buf->buf);
1513 		break;
1514 	default:
1515 		free(buf);
1516 		free(buf2);
1517 		return EAI_FAIL;
1518 	}
1519 	if (res_searchN(hostname, &q) < 0) {
1520 		free(buf);
1521 		free(buf2);
1522 		return EAI_NODATA;
1523 	}
1524 	/* prefer IPv6 */
1525 	if (q.next) {
1526 		ai = getanswer(buf2, q2.n, q2.name, q2.qtype, pai);
1527 		if (ai) {
1528 			cur->ai_next = ai;
1529 			while (cur && cur->ai_next)
1530 				cur = cur->ai_next;
1531 		}
1532 	}
1533 
1534 	ai = getanswer(buf, q.n, q.name, q.qtype, pai);
1535 	if (ai)
1536 		cur->ai_next = ai;
1537 	free(buf);
1538 	free(buf2);
1539 	if (sentinel.ai_next == NULL)
1540 		switch (h_errno) {
1541 		case HOST_NOT_FOUND:
1542 			return EAI_NODATA;
1543 		case TRY_AGAIN:
1544 			return EAI_AGAIN;
1545 		default:
1546 			return EAI_FAIL;
1547 		}
1548 	*res = sentinel.ai_next;
1549 	return 0;
1550 }
1551 
1552 static struct addrinfo *
1553 _gethtent(FILE *hostf, const char *name, const struct addrinfo *pai)
1554 {
1555 	char *p;
1556 	char *cp, *tname, *cname;
1557 	struct addrinfo hints, *res0, *res;
1558 	int error;
1559 	const char *addr;
1560 	char hostbuf[8*1024];
1561 
1562 again:
1563 	if (!(p = fgets(hostbuf, sizeof hostbuf, hostf)))
1564 		return (NULL);
1565 	if (*p == '#')
1566 		goto again;
1567 	if (!(cp = strpbrk(p, "#\n")))
1568 		goto again;
1569 	*cp = '\0';
1570 	if (!(cp = strpbrk(p, " \t")))
1571 		goto again;
1572 	*cp++ = '\0';
1573 	addr = p;
1574 	cname = NULL;
1575 	/* if this is not something we're looking for, skip it. */
1576 	while (cp && *cp) {
1577 		if (*cp == ' ' || *cp == '\t') {
1578 			cp++;
1579 			continue;
1580 		}
1581 		tname = cp;
1582 		if (cname == NULL)
1583 			cname = cp;
1584 		if ((cp = strpbrk(cp, " \t")) != NULL)
1585 			*cp++ = '\0';
1586 		if (strcasecmp(name, tname) == 0)
1587 			goto found;
1588 	}
1589 	goto again;
1590 
1591 found:
1592 	/* we should not glob socktype/protocol here */
1593 	memset(&hints, 0, sizeof(hints));
1594 	hints.ai_family = pai->ai_family;
1595 	hints.ai_socktype = SOCK_DGRAM;
1596 	hints.ai_protocol = 0;
1597 	hints.ai_flags = AI_NUMERICHOST;
1598 	error = getaddrinfo(addr, "0", &hints, &res0);
1599 	if (error)
1600 		goto again;
1601 #ifdef FILTER_V4MAPPED
1602 	/* XXX should check all items in the chain */
1603 	if (res0->ai_family == AF_INET6 &&
1604 	    IN6_IS_ADDR_V4MAPPED(&((struct sockaddr_in6 *)res0->ai_addr)->sin6_addr)) {
1605 		freeaddrinfo(res0);
1606 		goto again;
1607 	}
1608 #endif
1609 	for (res = res0; res; res = res->ai_next) {
1610 		/* cover it up */
1611 		res->ai_flags = pai->ai_flags;
1612 		res->ai_socktype = pai->ai_socktype;
1613 		res->ai_protocol = pai->ai_protocol;
1614 
1615 		if (pai->ai_flags & AI_CANONNAME) {
1616 			if (get_canonname(pai, res, cname) != 0) {
1617 				freeaddrinfo(res0);
1618 				goto again;
1619 			}
1620 		}
1621 	}
1622 	return res0;
1623 }
1624 
1625 /*ARGSUSED*/
1626 static int
1627 _files_getaddrinfo(const struct addrinfo *pai, const char *hostname,
1628 		   struct addrinfo **res)
1629 {
1630 	FILE *hostf;
1631 	struct addrinfo sentinel, *cur;
1632 	struct addrinfo *p;
1633 
1634 	sentinel.ai_next = NULL;
1635 	cur = &sentinel;
1636 
1637 	if ((hostf = fopen(_PATH_HOSTS, "r")) == NULL)
1638 		return EAI_FAIL;
1639 	while ((p = _gethtent(hostf, hostname, pai)) != NULL) {
1640 		cur->ai_next = p;
1641 		while (cur && cur->ai_next)
1642 			cur = cur->ai_next;
1643 	}
1644 	fclose(hostf);
1645 
1646 	if (!sentinel.ai_next)
1647 		return EAI_NODATA;
1648 
1649 	*res = sentinel.ai_next;
1650 	return 0;
1651 }
1652 
1653 #ifdef YP
1654 /*ARGSUSED*/
1655 static int
1656 _nis_getaddrinfo(const struct addrinfo *pai, const char *hostname,
1657 		 struct addrinfo **res)
1658 {
1659 	struct hostent *hp;
1660 	int af;
1661 	struct addrinfo sentinel, *cur;
1662 	int i;
1663 	const struct afd *afd;
1664 	int error;
1665 
1666 	sentinel.ai_next = NULL;
1667 	cur = &sentinel;
1668 
1669 	af = (pai->ai_family == AF_UNSPEC) ? AF_INET : pai->ai_family;
1670 	if (af != AF_INET)
1671 		return (EAI_ADDRFAMILY);
1672 
1673 	if ((hp = _gethostbynisname(hostname, af)) == NULL) {
1674 		switch (errno) {
1675 		/* XXX: should be filled in */
1676 		default:
1677 			error = EAI_FAIL;
1678 			break;
1679 		}
1680 	} else if (hp->h_name == NULL ||
1681 		   hp->h_name[0] == 0 || hp->h_addr_list[0] == NULL) {
1682 		hp = NULL;
1683 		error = EAI_FAIL;
1684 	}
1685 
1686 	if (hp == NULL)
1687 		return error;
1688 
1689 	for (i = 0; hp->h_addr_list[i] != NULL; i++) {
1690 		if (hp->h_addrtype != af)
1691 			continue;
1692 
1693 		afd = find_afd(hp->h_addrtype);
1694 		if (afd == NULL)
1695 			continue;
1696 
1697 		GET_AI(cur->ai_next, afd, hp->h_addr_list[i]);
1698 		if ((pai->ai_flags & AI_CANONNAME) != 0) {
1699 			/*
1700 			 * RFC2553 says that ai_canonname will be set only for
1701 			 * the first element.  we do it for all the elements,
1702 			 * just for convenience.
1703 			 */
1704 			GET_CANONNAME(cur->ai_next, hp->h_name);
1705 		}
1706 
1707 		while (cur && cur->ai_next)
1708 			cur = cur->ai_next;
1709 	}
1710 
1711 	*res = sentinel.ai_next;
1712 	return 0;
1713 
1714 free:
1715 	if (sentinel.ai_next)
1716 		freeaddrinfo(sentinel.ai_next);
1717 	return error;
1718 }
1719 #endif
1720 
1721 /* resolver logic */
1722 
1723 extern const char *__hostalias (const char *);
1724 extern int h_errno;
1725 
1726 /*
1727  * Formulate a normal query, send, and await answer.
1728  * Returned answer is placed in supplied buffer "answer".
1729  * Perform preliminary check of answer, returning success only
1730  * if no error is indicated and the answer count is nonzero.
1731  * Return the size of the response on success, -1 on error.
1732  * Error number is left in h_errno.
1733  *
1734  * Caller must parse answer and determine whether it answers the question.
1735  */
1736 static int
1737 res_queryN(const char *name,		/* domain name */
1738 	   struct res_target *target)
1739 {
1740 	u_char *buf;
1741 	HEADER *hp;
1742 	int n;
1743 	struct res_target *t;
1744 	int rcode;
1745 	int ancount;
1746 
1747 	rcode = NOERROR;
1748 	ancount = 0;
1749 
1750 	if ((_res.options & RES_INIT) == 0 && res_init() == -1) {
1751 		h_errno = NETDB_INTERNAL;
1752 		return (-1);
1753 	}
1754 
1755 	buf = malloc(MAXPACKET);
1756 	if (!buf) {
1757 		h_errno = NETDB_INTERNAL;
1758 		return (-1);
1759 	}
1760 
1761 	for (t = target; t; t = t->next) {
1762 		int class, type;
1763 		u_char *answer;
1764 		int anslen;
1765 
1766 		hp = (HEADER *)(void *)t->answer;
1767 		hp->rcode = NOERROR;	/* default */
1768 
1769 		/* make it easier... */
1770 		class = t->qclass;
1771 		type = t->qtype;
1772 		answer = t->answer;
1773 		anslen = t->anslen;
1774 #ifdef DEBUG
1775 		if (_res.options & RES_DEBUG)
1776 			printf(";; res_query(%s, %d, %d)\n", name, class, type);
1777 #endif
1778 
1779 		n = res_mkquery(QUERY, name, class, type, NULL, 0, NULL,
1780 		    buf, MAXPACKET);
1781 		if (n > 0 && (_res.options & RES_USE_EDNS0) != 0)
1782 			n = res_opt(n, buf, MAXPACKET, anslen);
1783 		if (n <= 0) {
1784 #ifdef DEBUG
1785 			if (_res.options & RES_DEBUG)
1786 				printf(";; res_query: mkquery failed\n");
1787 #endif
1788 			free(buf);
1789 			h_errno = NO_RECOVERY;
1790 			return (n);
1791 		}
1792 		n = res_send(buf, n, answer, anslen);
1793 #if 0
1794 		if (n < 0) {
1795 #ifdef DEBUG
1796 			if (_res.options & RES_DEBUG)
1797 				printf(";; res_query: send error\n");
1798 #endif
1799 			free(buf);
1800 			h_errno = TRY_AGAIN;
1801 			return (n);
1802 		}
1803 #endif
1804 
1805 		if (n < 0 || n > anslen)
1806 			hp->rcode = FORMERR; /* XXX not very informative */
1807 		if (hp->rcode != NOERROR || ntohs(hp->ancount) == 0) {
1808 			rcode = hp->rcode;	/* record most recent error */
1809 #ifdef DEBUG
1810 			if (_res.options & RES_DEBUG)
1811 				printf(";; rcode = %u, ancount=%u\n", hp->rcode,
1812 				    ntohs(hp->ancount));
1813 #endif
1814 			continue;
1815 		}
1816 
1817 		ancount += ntohs(hp->ancount);
1818 
1819 		t->n = n;
1820 	}
1821 
1822 	free(buf);
1823 
1824 	if (ancount == 0) {
1825 		switch (rcode) {
1826 		case NXDOMAIN:
1827 			h_errno = HOST_NOT_FOUND;
1828 			break;
1829 		case SERVFAIL:
1830 			h_errno = TRY_AGAIN;
1831 			break;
1832 		case NOERROR:
1833 			h_errno = NO_DATA;
1834 			break;
1835 		case FORMERR:
1836 		case NOTIMP:
1837 		case REFUSED:
1838 		default:
1839 			h_errno = NO_RECOVERY;
1840 			break;
1841 		}
1842 		return (-1);
1843 	}
1844 	return (ancount);
1845 }
1846 
1847 /*
1848  * Formulate a normal query, send, and retrieve answer in supplied buffer.
1849  * Return the size of the response on success, -1 on error.
1850  * If enabled, implement search rules until answer or unrecoverable failure
1851  * is detected.  Error code, if any, is left in h_errno.
1852  */
1853 static int
1854 res_searchN(const char *name,		/* domain name */
1855 	    struct res_target *target)
1856 {
1857 	const char *cp, * const *domain;
1858 	HEADER *hp = (HEADER *)(void *)target->answer;	/*XXX*/
1859 	u_int dots;
1860 	int trailing_dot, ret, saved_herrno;
1861 	int got_nodata = 0, got_servfail = 0, tried_as_is = 0;
1862 
1863 	if ((_res.options & RES_INIT) == 0 && res_init() == -1) {
1864 		h_errno = NETDB_INTERNAL;
1865 		return (-1);
1866 	}
1867 
1868 	errno = 0;
1869 	h_errno = HOST_NOT_FOUND;	/* default, if we never query */
1870 	dots = 0;
1871 	for (cp = name; *cp; cp++)
1872 		dots += (*cp == '.');
1873 	trailing_dot = 0;
1874 	if (cp > name && *--cp == '.')
1875 		trailing_dot++;
1876 
1877 	/*
1878 	 * if there aren't any dots, it could be a user-level alias
1879 	 */
1880 	if (!dots && (cp = __hostalias(name)) != NULL)
1881 		return (res_queryN(cp, target));
1882 
1883 	/*
1884 	 * If there are dots in the name already, let's just give it a try
1885 	 * 'as is'.  The threshold can be set with the "ndots" option.
1886 	 */
1887 	saved_herrno = -1;
1888 	if (dots >= _res.ndots) {
1889 		ret = res_querydomainN(name, NULL, target);
1890 		if (ret > 0)
1891 			return (ret);
1892 		saved_herrno = h_errno;
1893 		tried_as_is++;
1894 	}
1895 
1896 	/*
1897 	 * We do at least one level of search if
1898 	 *	- there is no dot and RES_DEFNAME is set, or
1899 	 *	- there is at least one dot, there is no trailing dot,
1900 	 *	  and RES_DNSRCH is set.
1901 	 */
1902 	if ((!dots && (_res.options & RES_DEFNAMES)) ||
1903 	    (dots && !trailing_dot && (_res.options & RES_DNSRCH))) {
1904 		int done = 0;
1905 
1906 		for (domain = (const char * const *)_res.dnsrch;
1907 		   *domain && !done;
1908 		   domain++) {
1909 
1910 			ret = res_querydomainN(name, *domain, target);
1911 			if (ret > 0)
1912 				return (ret);
1913 
1914 			/*
1915 			 * If no server present, give up.
1916 			 * If name isn't found in this domain,
1917 			 * keep trying higher domains in the search list
1918 			 * (if that's enabled).
1919 			 * On a NO_DATA error, keep trying, otherwise
1920 			 * a wildcard entry of another type could keep us
1921 			 * from finding this entry higher in the domain.
1922 			 * If we get some other error (negative answer or
1923 			 * server failure), then stop searching up,
1924 			 * but try the input name below in case it's
1925 			 * fully-qualified.
1926 			 */
1927 			if (errno == ECONNREFUSED) {
1928 				h_errno = TRY_AGAIN;
1929 				return (-1);
1930 			}
1931 
1932 			switch (h_errno) {
1933 			case NO_DATA:
1934 				got_nodata++;
1935 				/* FALLTHROUGH */
1936 			case HOST_NOT_FOUND:
1937 				/* keep trying */
1938 				break;
1939 			case TRY_AGAIN:
1940 				if (hp->rcode == SERVFAIL) {
1941 					/* try next search element, if any */
1942 					got_servfail++;
1943 					break;
1944 				}
1945 				/* FALLTHROUGH */
1946 			default:
1947 				/* anything else implies that we're done */
1948 				done++;
1949 			}
1950 			/*
1951 			 * if we got here for some reason other than DNSRCH,
1952 			 * we only wanted one iteration of the loop, so stop.
1953 			 */
1954 			if (!(_res.options & RES_DNSRCH))
1955 			        done++;
1956 		}
1957 	}
1958 
1959 	/*
1960 	 * if we have not already tried the name "as is", do that now.
1961 	 * note that we do this regardless of how many dots were in the
1962 	 * name or whether it ends with a dot.
1963 	 */
1964 	if (!tried_as_is && (dots || !(_res.options & RES_NOTLDQUERY))) {
1965 		ret = res_querydomainN(name, NULL, target);
1966 		if (ret > 0)
1967 			return (ret);
1968 	}
1969 
1970 	/*
1971 	 * if we got here, we didn't satisfy the search.
1972 	 * if we did an initial full query, return that query's h_errno
1973 	 * (note that we wouldn't be here if that query had succeeded).
1974 	 * else if we ever got a nodata, send that back as the reason.
1975 	 * else send back meaningless h_errno, that being the one from
1976 	 * the last DNSRCH we did.
1977 	 */
1978 	if (saved_herrno != -1)
1979 		h_errno = saved_herrno;
1980 	else if (got_nodata)
1981 		h_errno = NO_DATA;
1982 	else if (got_servfail)
1983 		h_errno = TRY_AGAIN;
1984 	return (-1);
1985 }
1986 
1987 /*
1988  * Perform a call on res_query on the concatenation of name and domain,
1989  * removing a trailing dot from name if domain is NULL.
1990  */
1991 static int
1992 res_querydomainN(const char *name, const char *domain,
1993 		 struct res_target *target)
1994 {
1995 	char nbuf[MAXDNAME];
1996 	const char *longname = nbuf;
1997 	size_t n, d;
1998 
1999 	if ((_res.options & RES_INIT) == 0 && res_init() == -1) {
2000 		h_errno = NETDB_INTERNAL;
2001 		return (-1);
2002 	}
2003 #ifdef DEBUG
2004 	if (_res.options & RES_DEBUG)
2005 		printf(";; res_querydomain(%s, %s)\n",
2006 			name, domain?domain:"<Nil>");
2007 #endif
2008 	if (domain == NULL) {
2009 		/*
2010 		 * Check for trailing '.';
2011 		 * copy without '.' if present.
2012 		 */
2013 		n = strlen(name);
2014 		if (n >= MAXDNAME) {
2015 			h_errno = NO_RECOVERY;
2016 			return (-1);
2017 		}
2018 		if (n > 0 && name[--n] == '.') {
2019 			strncpy(nbuf, name, n);
2020 			nbuf[n] = '\0';
2021 		} else
2022 			longname = name;
2023 	} else {
2024 		n = strlen(name);
2025 		d = strlen(domain);
2026 		if (n + d + 1 >= MAXDNAME) {
2027 			h_errno = NO_RECOVERY;
2028 			return (-1);
2029 		}
2030 		snprintf(nbuf, sizeof(nbuf), "%s.%s", name, domain);
2031 	}
2032 	return (res_queryN(longname, target));
2033 }
2034