xref: /freebsd/lib/libc/net/getaddrinfo.c (revision ebccf1e3a6b11b97cbf5f813dd76636e892a9035)
1 /*	$KAME: getaddrinfo.c,v 1.15 2000/07/09 04:37:24 itojun Exp $	*/
2 
3 /*
4  * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  * 3. Neither the name of the project nor the names of its contributors
16  *    may be used to endorse or promote products derived from this software
17  *    without specific prior written permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
20  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22  * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
23  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29  * SUCH DAMAGE.
30  */
31 
32 /*
33  * "#ifdef FAITH" part is local hack for supporting IPv4-v6 translator.
34  *
35  * Issues to be discussed:
36  * - Thread safe-ness must be checked.
37  * - Return values.  There are nonstandard return values defined and used
38  *   in the source code.  This is because RFC2553 is silent about which error
39  *   code must be returned for which situation.
40  * - freeaddrinfo(NULL).  RFC2553 is silent about it.  XNET 5.2 says it is
41  *   invalid.  current code - SEGV on freeaddrinfo(NULL)
42  *
43  * Note:
44  * - The code filters out AFs that are not supported by the kernel,
45  *   when globbing NULL hostname (to loopback, or wildcard).  Is it the right
46  *   thing to do?  What is the relationship with post-RFC2553 AI_ADDRCONFIG
47  *   in ai_flags?
48  * - (post-2553) semantics of AI_ADDRCONFIG itself is too vague.
49  *   (1) what should we do against numeric hostname (2) what should we do
50  *   against NULL hostname (3) what is AI_ADDRCONFIG itself.  AF not ready?
51  *   non-loopback address configured?  global address configured?
52  *
53  * OS specific notes for netbsd/openbsd/freebsd4/bsdi4:
54  * - To avoid search order issue, we have a big amount of code duplicate
55  *   from gethnamaddr.c and some other places.  The issues that there's no
56  *   lower layer function to lookup "IPv4 or IPv6" record.  Calling
57  *   gethostbyname2 from getaddrinfo will end up in wrong search order, as
58  *   presented above.
59  *
60  * OS specific notes for freebsd4:
61  * - FreeBSD supported $GAI.  The code does not.
62  * - FreeBSD allowed classful IPv4 numeric (127.1), the code does not.
63  */
64 
65 #include <sys/cdefs.h>
66 __FBSDID("$FreeBSD$");
67 
68 #include "namespace.h"
69 #include <sys/types.h>
70 #include <sys/param.h>
71 #include <sys/socket.h>
72 #include <net/if.h>
73 #include <netinet/in.h>
74 #include <sys/queue.h>
75 #ifdef INET6
76 #include <net/if_var.h>
77 #include <sys/sysctl.h>
78 #include <sys/ioctl.h>
79 #include <netinet6/in6_var.h>	/* XXX */
80 #endif
81 #include <arpa/inet.h>
82 #include <arpa/nameser.h>
83 #include <rpc/rpc.h>
84 #include <rpcsvc/yp_prot.h>
85 #include <rpcsvc/ypclnt.h>
86 #include <netdb.h>
87 #include <resolv.h>
88 #include <string.h>
89 #include <stdlib.h>
90 #include <stddef.h>
91 #include <ctype.h>
92 #include <unistd.h>
93 #include <stdio.h>
94 #include <errno.h>
95 
96 #include "res_config.h"
97 
98 #ifdef DEBUG
99 #include <syslog.h>
100 #endif
101 
102 #include <stdarg.h>
103 #include <nsswitch.h>
104 #include "un-namespace.h"
105 #include "libc_private.h"
106 
107 #if defined(__KAME__) && defined(INET6)
108 # define FAITH
109 #endif
110 
111 #define SUCCESS 0
112 #define ANY 0
113 #define YES 1
114 #define NO  0
115 
116 static const char in_addrany[] = { 0, 0, 0, 0 };
117 static const char in_loopback[] = { 127, 0, 0, 1 };
118 #ifdef INET6
119 static const char in6_addrany[] = {
120 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
121 };
122 static const char in6_loopback[] = {
123 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1
124 };
125 #endif
126 
127 struct policyqueue {
128 	TAILQ_ENTRY(policyqueue) pc_entry;
129 #ifdef INET6
130 	struct in6_addrpolicy pc_policy;
131 #endif
132 };
133 TAILQ_HEAD(policyhead, policyqueue);
134 
135 static const struct afd {
136 	int a_af;
137 	int a_addrlen;
138 	int a_socklen;
139 	int a_off;
140 	const char *a_addrany;
141 	const char *a_loopback;
142 	int a_scoped;
143 } afdl [] = {
144 #ifdef INET6
145 #define	N_INET6 0
146 	{PF_INET6, sizeof(struct in6_addr),
147 	 sizeof(struct sockaddr_in6),
148 	 offsetof(struct sockaddr_in6, sin6_addr),
149 	 in6_addrany, in6_loopback, 1},
150 #define	N_INET 1
151 #else
152 #define	N_INET 0
153 #endif
154 	{PF_INET, sizeof(struct in_addr),
155 	 sizeof(struct sockaddr_in),
156 	 offsetof(struct sockaddr_in, sin_addr),
157 	 in_addrany, in_loopback, 0},
158 	{0, 0, 0, 0, NULL, NULL, 0},
159 };
160 
161 struct explore {
162 	int e_af;
163 	int e_socktype;
164 	int e_protocol;
165 	const char *e_protostr;
166 	int e_wild;
167 #define WILD_AF(ex)		((ex)->e_wild & 0x01)
168 #define WILD_SOCKTYPE(ex)	((ex)->e_wild & 0x02)
169 #define WILD_PROTOCOL(ex)	((ex)->e_wild & 0x04)
170 };
171 
172 static const struct explore explore[] = {
173 #if 0
174 	{ PF_LOCAL, 0, ANY, ANY, NULL, 0x01 },
175 #endif
176 #ifdef INET6
177 	{ PF_INET6, SOCK_DGRAM, IPPROTO_UDP, "udp", 0x07 },
178 	{ PF_INET6, SOCK_STREAM, IPPROTO_TCP, "tcp", 0x07 },
179 	{ PF_INET6, SOCK_RAW, ANY, NULL, 0x05 },
180 #endif
181 	{ PF_INET, SOCK_DGRAM, IPPROTO_UDP, "udp", 0x07 },
182 	{ PF_INET, SOCK_STREAM, IPPROTO_TCP, "tcp", 0x07 },
183 	{ PF_INET, SOCK_RAW, ANY, NULL, 0x05 },
184 	{ PF_UNSPEC, SOCK_DGRAM, IPPROTO_UDP, "udp", 0x07 },
185 	{ PF_UNSPEC, SOCK_STREAM, IPPROTO_TCP, "tcp", 0x07 },
186 	{ PF_UNSPEC, SOCK_RAW, ANY, NULL, 0x05 },
187 	{ -1, 0, 0, NULL, 0 },
188 };
189 
190 #ifdef INET6
191 #define PTON_MAX	16
192 #else
193 #define PTON_MAX	4
194 #endif
195 
196 #define AIO_SRCFLAG_DEPRECATED	0x1
197 
198 struct ai_order {
199 	union {
200 		struct sockaddr_storage aiou_ss;
201 		struct sockaddr aiou_sa;
202 	} aio_src_un;
203 #define aio_srcsa aio_src_un.aiou_sa
204 	u_int32_t aio_srcflag;
205 	int aio_srcscope;
206 	int aio_dstscope;
207 	struct policyqueue *aio_srcpolicy;
208 	struct policyqueue *aio_dstpolicy;
209 	struct addrinfo *aio_ai;
210 	int aio_matchlen;
211 };
212 
213 static const ns_src default_dns_files[] = {
214 	{ NSSRC_FILES, 	NS_SUCCESS },
215 	{ NSSRC_DNS, 	NS_SUCCESS },
216 	{ 0 }
217 };
218 
219 struct res_target {
220 	struct res_target *next;
221 	const char *name;	/* domain name */
222 	int qclass, qtype;	/* class and type of query */
223 	u_char *answer;		/* buffer to put answer */
224 	int anslen;		/* size of answer buffer */
225 	int n;			/* result length */
226 };
227 
228 #define MAXPACKET	(64*1024)
229 
230 typedef union {
231 	HEADER hdr;
232 	u_char buf[MAXPACKET];
233 } querybuf;
234 
235 static int str2number(const char *);
236 static int explore_null(const struct addrinfo *,
237 	const char *, struct addrinfo **);
238 static int explore_numeric(const struct addrinfo *, const char *,
239 	const char *, struct addrinfo **, const char *);
240 static int explore_numeric_scope(const struct addrinfo *, const char *,
241 	const char *, struct addrinfo **);
242 static int get_canonname(const struct addrinfo *,
243 	struct addrinfo *, const char *);
244 static struct addrinfo *get_ai(const struct addrinfo *,
245 	const struct afd *, const char *);
246 static int get_portmatch(const struct addrinfo *, const char *);
247 static int get_port(struct addrinfo *, const char *, int);
248 static const struct afd *find_afd(int);
249 static int addrconfig(struct addrinfo *);
250 static void set_source(struct ai_order *, struct policyhead *);
251 static int comp_dst(const void *, const void *);
252 #ifdef INET6
253 static int ip6_str2scopeid(char *, struct sockaddr_in6 *, u_int32_t *);
254 #endif
255 static int gai_addr2scopetype(struct sockaddr *);
256 
257 static int explore_fqdn(const struct addrinfo *, const char *,
258 	const char *, struct addrinfo **);
259 
260 static int reorder(struct addrinfo *);
261 static int get_addrselectpolicy(struct policyhead *);
262 static void free_addrselectpolicy(struct policyhead *);
263 static struct policyqueue *match_addrselectpolicy(struct sockaddr *,
264 	struct policyhead *);
265 static int matchlen(struct sockaddr *, struct sockaddr *);
266 
267 static struct addrinfo *getanswer(const querybuf *, int, const char *, int,
268 	const struct addrinfo *);
269 #if defined(RESOLVSORT)
270 static int addr4sort(struct addrinfo *);
271 #endif
272 static int _dns_getaddrinfo(void *, void *, va_list);
273 static void _sethtent(FILE **);
274 static void _endhtent(FILE **);
275 static struct addrinfo *_gethtent(FILE **, const char *,
276 	const struct addrinfo *);
277 static int _files_getaddrinfo(void *, void *, va_list);
278 #ifdef YP
279 static struct addrinfo *_yphostent(char *, const struct addrinfo *);
280 static int _yp_getaddrinfo(void *, void *, va_list);
281 #endif
282 
283 static int res_queryN(const char *, struct res_target *);
284 static int res_searchN(const char *, struct res_target *);
285 static int res_querydomainN(const char *, const char *,
286 	struct res_target *);
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 void
330 freeaddrinfo(ai)
331 	struct addrinfo *ai;
332 {
333 	struct addrinfo *next;
334 
335 	do {
336 		next = ai->ai_next;
337 		if (ai->ai_canonname)
338 			free(ai->ai_canonname);
339 		/* no need to free(ai->ai_addr) */
340 		free(ai);
341 		ai = next;
342 	} while (ai);
343 }
344 
345 static int
346 str2number(p)
347 	const char *p;
348 {
349 	char *ep;
350 	unsigned long v;
351 
352 	if (*p == '\0')
353 		return -1;
354 	ep = NULL;
355 	errno = 0;
356 	v = strtoul(p, &ep, 10);
357 	if (errno == 0 && ep && *ep == '\0' && v <= UINT_MAX)
358 		return v;
359 	else
360 		return -1;
361 }
362 
363 int
364 getaddrinfo(hostname, servname, hints, res)
365 	const char *hostname, *servname;
366 	const struct addrinfo *hints;
367 	struct addrinfo **res;
368 {
369 	struct addrinfo sentinel;
370 	struct addrinfo *cur;
371 	int error = 0;
372 	struct addrinfo ai;
373 	struct addrinfo ai0;
374 	struct addrinfo *pai;
375 	const struct explore *ex;
376 	int numeric = 0;
377 
378 	memset(&sentinel, 0, sizeof(sentinel));
379 	cur = &sentinel;
380 	pai = &ai;
381 	pai->ai_flags = 0;
382 	pai->ai_family = PF_UNSPEC;
383 	pai->ai_socktype = ANY;
384 	pai->ai_protocol = ANY;
385 	pai->ai_addrlen = 0;
386 	pai->ai_canonname = NULL;
387 	pai->ai_addr = NULL;
388 	pai->ai_next = NULL;
389 
390 	if (hostname == NULL && servname == NULL)
391 		return EAI_NONAME;
392 	if (hints) {
393 		/* error check for hints */
394 		if (hints->ai_addrlen || hints->ai_canonname ||
395 		    hints->ai_addr || hints->ai_next)
396 			ERR(EAI_BADHINTS); /* xxx */
397 		if (hints->ai_flags & ~AI_MASK)
398 			ERR(EAI_BADFLAGS);
399 		switch (hints->ai_family) {
400 		case PF_UNSPEC:
401 		case PF_INET:
402 #ifdef INET6
403 		case PF_INET6:
404 #endif
405 			break;
406 		default:
407 			ERR(EAI_FAMILY);
408 		}
409 		memcpy(pai, hints, sizeof(*pai));
410 
411 		/*
412 		 * if both socktype/protocol are specified, check if they
413 		 * are meaningful combination.
414 		 */
415 		if (pai->ai_socktype != ANY && pai->ai_protocol != ANY) {
416 			for (ex = explore; ex->e_af >= 0; ex++) {
417 				if (pai->ai_family != ex->e_af)
418 					continue;
419 				if (ex->e_socktype == ANY)
420 					continue;
421 				if (ex->e_protocol == ANY)
422 					continue;
423 				if (pai->ai_socktype == ex->e_socktype &&
424 				    pai->ai_protocol != ex->e_protocol) {
425 					ERR(EAI_BADHINTS);
426 				}
427 			}
428 		}
429 	}
430 
431 	/*
432 	 * post-2553: AI_ALL and AI_V4MAPPED are effective only against
433 	 * AF_INET6 query.  They need to be ignored if specified in other
434 	 * occassions.
435 	 */
436 	switch (pai->ai_flags & (AI_ALL | AI_V4MAPPED)) {
437 	case AI_V4MAPPED:
438 	case AI_ALL | AI_V4MAPPED:
439 		if (pai->ai_family != AF_INET6)
440 			pai->ai_flags &= ~(AI_ALL | AI_V4MAPPED);
441 		break;
442 	case AI_ALL:
443 #if 1
444 		/* illegal */
445 		ERR(EAI_BADFLAGS);
446 #else
447 		pai->ai_flags &= ~(AI_ALL | AI_V4MAPPED);
448 #endif
449 		break;
450 	}
451 
452 	/*
453 	 * check for special cases.  (1) numeric servname is disallowed if
454 	 * socktype/protocol are left unspecified. (2) servname is disallowed
455 	 * for raw and other inet{,6} sockets.
456 	 */
457 	if (MATCH_FAMILY(pai->ai_family, PF_INET, 1)
458 #ifdef PF_INET6
459 	    || MATCH_FAMILY(pai->ai_family, PF_INET6, 1)
460 #endif
461 	    ) {
462 		ai0 = *pai;	/* backup *pai */
463 
464 		if (pai->ai_family == PF_UNSPEC) {
465 #ifdef PF_INET6
466 			pai->ai_family = PF_INET6;
467 #else
468 			pai->ai_family = PF_INET;
469 #endif
470 		}
471 		error = get_portmatch(pai, servname);
472 		if (error)
473 			ERR(error);
474 
475 		*pai = ai0;
476 	}
477 
478 	ai0 = *pai;
479 
480 	/* NULL hostname, or numeric hostname */
481 	for (ex = explore; ex->e_af >= 0; ex++) {
482 		*pai = ai0;
483 
484 		/* PF_UNSPEC entries are prepared for DNS queries only */
485 		if (ex->e_af == PF_UNSPEC)
486 			continue;
487 
488 		if (!MATCH_FAMILY(pai->ai_family, ex->e_af, WILD_AF(ex)))
489 			continue;
490 		if (!MATCH(pai->ai_socktype, ex->e_socktype, WILD_SOCKTYPE(ex)))
491 			continue;
492 		if (!MATCH(pai->ai_protocol, ex->e_protocol, WILD_PROTOCOL(ex)))
493 			continue;
494 
495 		if (pai->ai_family == PF_UNSPEC)
496 			pai->ai_family = ex->e_af;
497 		if (pai->ai_socktype == ANY && ex->e_socktype != ANY)
498 			pai->ai_socktype = ex->e_socktype;
499 		if (pai->ai_protocol == ANY && ex->e_protocol != ANY)
500 			pai->ai_protocol = ex->e_protocol;
501 
502 		if (hostname == NULL)
503 			error = explore_null(pai, servname, &cur->ai_next);
504 		else
505 			error = explore_numeric_scope(pai, hostname, servname,
506 			    &cur->ai_next);
507 
508 		if (error)
509 			goto free;
510 
511 		while (cur && cur->ai_next)
512 			cur = cur->ai_next;
513 	}
514 
515 	/*
516 	 * XXX
517 	 * If numreic representation of AF1 can be interpreted as FQDN
518 	 * representation of AF2, we need to think again about the code below.
519 	 */
520 	if (sentinel.ai_next) {
521 		numeric = 1;
522 		goto good;
523 	}
524 
525 	if (hostname == NULL)
526 		ERR(EAI_NONAME);	/* used to be EAI_NODATA */
527 	if (pai->ai_flags & AI_NUMERICHOST)
528 		ERR(EAI_NONAME);
529 
530 	if ((pai->ai_flags & AI_ADDRCONFIG) != 0 && !addrconfig(&ai0))
531 		ERR(EAI_FAIL);
532 
533 	/*
534 	 * hostname as alphabetical name.
535 	 * we would like to prefer AF_INET6 than AF_INET, so we'll make a
536 	 * outer loop by AFs.
537 	 */
538 	for (ex = explore; ex->e_af >= 0; ex++) {
539 		*pai = ai0;
540 
541 		/* require exact match for family field */
542 		if (pai->ai_family != ex->e_af)
543 			continue;
544 
545 		if (!MATCH(pai->ai_socktype, ex->e_socktype,
546 				WILD_SOCKTYPE(ex))) {
547 			continue;
548 		}
549 		if (!MATCH(pai->ai_protocol, ex->e_protocol,
550 				WILD_PROTOCOL(ex))) {
551 			continue;
552 		}
553 
554 		if (pai->ai_socktype == ANY && ex->e_socktype != ANY)
555 			pai->ai_socktype = ex->e_socktype;
556 		if (pai->ai_protocol == ANY && ex->e_protocol != ANY)
557 			pai->ai_protocol = ex->e_protocol;
558 
559 		error = explore_fqdn(pai, hostname, servname,
560 			&cur->ai_next);
561 
562 		while (cur && cur->ai_next)
563 			cur = cur->ai_next;
564 	}
565 
566 	/* XXX inhibit errors if we have the result */
567 	if (sentinel.ai_next)
568 		error = 0;
569 
570 good:
571 	/*
572 	 * ensure we return either:
573 	 * - error == 0, non-NULL *res
574 	 * - error != 0, NULL *res
575 	 */
576 	if (error == 0) {
577 		if (sentinel.ai_next) {
578 			/*
579 			 * If the returned entry is for an active connection,
580 			 * and the given name is not numeric, reorder the
581 			 * list, so that the application would try the list
582 			 * in the most efficient order.
583 			 */
584 			if (hints == NULL || !(hints->ai_flags & AI_PASSIVE)) {
585 				if (!numeric)
586 					(void)reorder(&sentinel);
587 			}
588 			*res = sentinel.ai_next;
589 			return SUCCESS;
590 		} else
591 			error = EAI_FAIL;
592 	}
593 free:
594 bad:
595 	if (sentinel.ai_next)
596 		freeaddrinfo(sentinel.ai_next);
597 	*res = NULL;
598 	return error;
599 }
600 
601 static int
602 reorder(sentinel)
603 	struct addrinfo *sentinel;
604 {
605 	struct addrinfo *ai, **aip;
606 	struct ai_order *aio;
607 	int i, n;
608 	struct policyhead policyhead;
609 
610 	/* count the number of addrinfo elements for sorting. */
611 	for (n = 0, ai = sentinel->ai_next; ai != NULL; ai = ai->ai_next, n++)
612 		;
613 
614 	/*
615 	 * If the number is small enough, we can skip the reordering process.
616 	 */
617 	if (n <= 1)
618 		return(n);
619 
620 	/* allocate a temporary array for sort and initialization of it. */
621 	if ((aio = malloc(sizeof(*aio) * n)) == NULL)
622 		return(n);	/* give up reordering */
623 	memset(aio, 0, sizeof(*aio) * n);
624 
625 	/* retrieve address selection policy from the kernel */
626 	TAILQ_INIT(&policyhead);
627 	if (!get_addrselectpolicy(&policyhead)) {
628 		/* no policy is installed into kernel, we don't sort. */
629 		free(aio);
630 		return (n);
631 	}
632 
633 	for (i = 0, ai = sentinel->ai_next; i < n; ai = ai->ai_next, i++) {
634 		aio[i].aio_ai = ai;
635 		aio[i].aio_dstscope = gai_addr2scopetype(ai->ai_addr);
636 		aio[i].aio_dstpolicy = match_addrselectpolicy(ai->ai_addr,
637 							      &policyhead);
638 		set_source(&aio[i], &policyhead);
639 	}
640 
641 	/* perform sorting. */
642 	qsort(aio, n, sizeof(*aio), comp_dst);
643 
644 	/* reorder the addrinfo chain. */
645 	for (i = 0, aip = &sentinel->ai_next; i < n; i++) {
646 		*aip = aio[i].aio_ai;
647 		aip = &aio[i].aio_ai->ai_next;
648 	}
649 	*aip = NULL;
650 
651 	/* cleanup and return */
652 	free(aio);
653 	free_addrselectpolicy(&policyhead);
654 	return(n);
655 }
656 
657 static int
658 get_addrselectpolicy(head)
659 	struct policyhead *head;
660 {
661 #ifdef INET6
662 	int mib[] = { CTL_NET, PF_INET6, IPPROTO_IPV6, IPV6CTL_ADDRCTLPOLICY };
663 	size_t l;
664 	char *buf;
665 	struct in6_addrpolicy *pol, *ep;
666 
667 	if (sysctl(mib, sizeof(mib) / sizeof(mib[0]), NULL, &l, NULL, 0) < 0)
668 		return (0);
669 	if ((buf = malloc(l)) == NULL)
670 		return (0);
671 	if (sysctl(mib, sizeof(mib) / sizeof(mib[0]), buf, &l, NULL, 0) < 0) {
672 		free(buf);
673 		return (0);
674 	}
675 
676 	ep = (struct in6_addrpolicy *)(buf + l);
677 	for (pol = (struct in6_addrpolicy *)buf; pol + 1 <= ep; pol++) {
678 		struct policyqueue *new;
679 
680 		if ((new = malloc(sizeof(*new))) == NULL) {
681 			free_addrselectpolicy(head); /* make the list empty */
682 			break;
683 		}
684 		new->pc_policy = *pol;
685 		TAILQ_INSERT_TAIL(head, new, pc_entry);
686 	}
687 
688 	free(buf);
689 	return (1);
690 #else
691 	return (0);
692 #endif
693 }
694 
695 static void
696 free_addrselectpolicy(head)
697 	struct policyhead *head;
698 {
699 	struct policyqueue *ent, *nent;
700 
701 	for (ent = TAILQ_FIRST(head); ent; ent = nent) {
702 		nent = TAILQ_NEXT(ent, pc_entry);
703 		TAILQ_REMOVE(head, ent, pc_entry);
704 		free(ent);
705 	}
706 }
707 
708 static struct policyqueue *
709 match_addrselectpolicy(addr, head)
710 	struct sockaddr *addr;
711 	struct policyhead *head;
712 {
713 #ifdef INET6
714 	struct policyqueue *ent, *bestent = NULL;
715 	struct in6_addrpolicy *pol;
716 	int matchlen, bestmatchlen = -1;
717 	u_char *mp, *ep, *k, *p, m;
718 	struct sockaddr_in6 key;
719 
720 	switch(addr->sa_family) {
721 	case AF_INET6:
722 		key = *(struct sockaddr_in6 *)addr;
723 		break;
724 	case AF_INET:
725 		/* convert the address into IPv4-mapped IPv6 address. */
726 		memset(&key, 0, sizeof(key));
727 		key.sin6_family = AF_INET6;
728 		key.sin6_len = sizeof(key);
729 		key.sin6_addr.s6_addr[10] = 0xff;
730 		key.sin6_addr.s6_addr[11] = 0xff;
731 		memcpy(&key.sin6_addr.s6_addr[12],
732 		       &((struct sockaddr_in *)addr)->sin_addr, 4);
733 		break;
734 	default:
735 		return(NULL);
736 	}
737 
738 	for (ent = TAILQ_FIRST(head); ent; ent = TAILQ_NEXT(ent, pc_entry)) {
739 		pol = &ent->pc_policy;
740 		matchlen = 0;
741 
742 		mp = (u_char *)&pol->addrmask.sin6_addr;
743 		ep = mp + 16;	/* XXX: scope field? */
744 		k = (u_char *)&key.sin6_addr;
745 		p = (u_char *)&pol->addr.sin6_addr;
746 		for (; mp < ep && *mp; mp++, k++, p++) {
747 			m = *mp;
748 			if ((*k & m) != *p)
749 				goto next; /* not match */
750 			if (m == 0xff) /* short cut for a typical case */
751 				matchlen += 8;
752 			else {
753 				while (m >= 0x80) {
754 					matchlen++;
755 					m <<= 1;
756 				}
757 			}
758 		}
759 
760 		/* matched.  check if this is better than the current best. */
761 		if (matchlen > bestmatchlen) {
762 			bestent = ent;
763 			bestmatchlen = matchlen;
764 		}
765 
766 	  next:
767 		continue;
768 	}
769 
770 	return(bestent);
771 #else
772 	return(NULL);
773 #endif
774 
775 }
776 
777 static void
778 set_source(aio, ph)
779 	struct ai_order *aio;
780 	struct policyhead *ph;
781 {
782 	struct addrinfo ai = *aio->aio_ai;
783 	struct sockaddr_storage ss;
784 	int s, srclen;
785 
786 	/* set unspec ("no source is available"), just in case */
787 	aio->aio_srcsa.sa_family = AF_UNSPEC;
788 	aio->aio_srcscope = -1;
789 
790 	switch(ai.ai_family) {
791 	case AF_INET:
792 #ifdef INET6
793 	case AF_INET6:
794 #endif
795 		break;
796 	default:		/* ignore unsupported AFs explicitly */
797 		return;
798 	}
799 
800 	/* XXX: make a dummy addrinfo to call connect() */
801 	ai.ai_socktype = SOCK_DGRAM;
802 	ai.ai_protocol = IPPROTO_UDP; /* is UDP too specific? */
803 	ai.ai_next = NULL;
804 	memset(&ss, 0, sizeof(ss));
805 	memcpy(&ss, ai.ai_addr, ai.ai_addrlen);
806 	ai.ai_addr = (struct sockaddr *)&ss;
807 	get_port(&ai, "1", 0);
808 
809 	/* open a socket to get the source address for the given dst */
810 	if ((s = _socket(ai.ai_family, ai.ai_socktype, ai.ai_protocol)) < 0)
811 		return;		/* give up */
812 	if (_connect(s, ai.ai_addr, ai.ai_addrlen) < 0)
813 		goto cleanup;
814 	srclen = ai.ai_addrlen;
815 	if (_getsockname(s, &aio->aio_srcsa, &srclen) < 0) {
816 		aio->aio_srcsa.sa_family = AF_UNSPEC;
817 		goto cleanup;
818 	}
819 	aio->aio_srcscope = gai_addr2scopetype(&aio->aio_srcsa);
820 	aio->aio_srcpolicy = match_addrselectpolicy(&aio->aio_srcsa, ph);
821 	aio->aio_matchlen = matchlen(&aio->aio_srcsa, aio->aio_ai->ai_addr);
822 #ifdef INET6
823 	if (ai.ai_family == AF_INET6) {
824 		struct in6_ifreq ifr6;
825 		u_int32_t flags6;
826 
827 		/* XXX: interface name should not be hardcoded */
828 		strncpy(ifr6.ifr_name, "lo0", sizeof(ifr6.ifr_name));
829 		memset(&ifr6, 0, sizeof(ifr6));
830 		memcpy(&ifr6.ifr_addr, ai.ai_addr, ai.ai_addrlen);
831 		if (_ioctl(s, SIOCGIFAFLAG_IN6, &ifr6) == 0) {
832 			flags6 = ifr6.ifr_ifru.ifru_flags6;
833 			if ((flags6 & IN6_IFF_DEPRECATED))
834 				aio->aio_srcflag |= AIO_SRCFLAG_DEPRECATED;
835 		}
836 	}
837 #endif
838 
839   cleanup:
840 	_close(s);
841 	return;
842 }
843 
844 static int
845 matchlen(src, dst)
846 	struct sockaddr *src, *dst;
847 {
848 	int match = 0;
849 	u_char *s, *d;
850 	u_char *lim, r;
851 	int addrlen;
852 
853 	switch (src->sa_family) {
854 #ifdef INET6
855 	case AF_INET6:
856 		s = (u_char *)&((struct sockaddr_in6 *)src)->sin6_addr;
857 		d = (u_char *)&((struct sockaddr_in6 *)dst)->sin6_addr;
858 		addrlen = sizeof(struct in6_addr);
859 		lim = s + addrlen;
860 		break;
861 #endif
862 	case AF_INET:
863 		s = (u_char *)&((struct sockaddr_in6 *)src)->sin6_addr;
864 		d = (u_char *)&((struct sockaddr_in6 *)dst)->sin6_addr;
865 		addrlen = sizeof(struct in_addr);
866 		lim = s + addrlen;
867 		break;
868 	default:
869 		return(0);
870 	}
871 
872 	while (s < lim)
873 		if ((r = (*d++ ^ *s++)) != 0) {
874 			while (r < addrlen * 8) {
875 				match++;
876 				r <<= 1;
877 			}
878 			break;
879 		} else
880 			match += 8;
881 	return(match);
882 }
883 
884 static int
885 comp_dst(arg1, arg2)
886 	const void *arg1, *arg2;
887 {
888 	const struct ai_order *dst1 = arg1, *dst2 = arg2;
889 
890 	/*
891 	 * Rule 1: Avoid unusable destinations.
892 	 * XXX: we currently do not consider if an appropriate route exists.
893 	 */
894 	if (dst1->aio_srcsa.sa_family != AF_UNSPEC &&
895 	    dst2->aio_srcsa.sa_family == AF_UNSPEC) {
896 		return(-1);
897 	}
898 	if (dst1->aio_srcsa.sa_family == AF_UNSPEC &&
899 	    dst2->aio_srcsa.sa_family != AF_UNSPEC) {
900 		return(1);
901 	}
902 
903 	/* Rule 2: Prefer matching scope. */
904 	if (dst1->aio_dstscope == dst1->aio_srcscope &&
905 	    dst2->aio_dstscope != dst2->aio_srcscope) {
906 		return(-1);
907 	}
908 	if (dst1->aio_dstscope != dst1->aio_srcscope &&
909 	    dst2->aio_dstscope == dst2->aio_srcscope) {
910 		return(1);
911 	}
912 
913 	/* Rule 3: Avoid deprecated addresses. */
914 	if (dst1->aio_srcsa.sa_family != AF_UNSPEC &&
915 	    dst2->aio_srcsa.sa_family != AF_UNSPEC) {
916 		if (!(dst1->aio_srcflag & AIO_SRCFLAG_DEPRECATED) &&
917 		    (dst2->aio_srcflag & AIO_SRCFLAG_DEPRECATED)) {
918 			return(-1);
919 		}
920 		if ((dst1->aio_srcflag & AIO_SRCFLAG_DEPRECATED) &&
921 		    !(dst2->aio_srcflag & AIO_SRCFLAG_DEPRECATED)) {
922 			return(1);
923 		}
924 	}
925 
926 	/* Rule 4: Prefer home addresses. */
927 	/* XXX: not implemented yet */
928 
929 	/* Rule 5: Prefer matching label. */
930 #ifdef INET6
931 	if (dst1->aio_srcpolicy && dst1->aio_dstpolicy &&
932 	    dst1->aio_srcpolicy->pc_policy.label ==
933 	    dst1->aio_dstpolicy->pc_policy.label &&
934 	    (dst2->aio_srcpolicy == NULL || dst2->aio_dstpolicy == NULL ||
935 	     dst2->aio_srcpolicy->pc_policy.label !=
936 	     dst2->aio_dstpolicy->pc_policy.label)) {
937 		return(-1);
938 	}
939 	if (dst2->aio_srcpolicy && dst2->aio_dstpolicy &&
940 	    dst2->aio_srcpolicy->pc_policy.label ==
941 	    dst2->aio_dstpolicy->pc_policy.label &&
942 	    (dst1->aio_srcpolicy == NULL || dst1->aio_dstpolicy == NULL ||
943 	     dst1->aio_srcpolicy->pc_policy.label !=
944 	     dst1->aio_dstpolicy->pc_policy.label)) {
945 		return(1);
946 	}
947 #endif
948 
949 	/* Rule 6: Prefer higher precedence. */
950 #ifdef INET6
951 	if (dst1->aio_dstpolicy &&
952 	    (dst2->aio_dstpolicy == NULL ||
953 	     dst1->aio_dstpolicy->pc_policy.preced >
954 	     dst2->aio_dstpolicy->pc_policy.preced)) {
955 		return(-1);
956 	}
957 	if (dst2->aio_dstpolicy &&
958 	    (dst1->aio_dstpolicy == NULL ||
959 	     dst2->aio_dstpolicy->pc_policy.preced >
960 	     dst1->aio_dstpolicy->pc_policy.preced)) {
961 		return(1);
962 	}
963 #endif
964 
965 	/* Rule 7: Prefer native transport. */
966 	/* XXX: not implemented yet */
967 
968 	/* Rule 8: Prefer smaller scope. */
969 	if (dst1->aio_dstscope >= 0 &&
970 	    dst1->aio_dstscope < dst2->aio_dstscope) {
971 		return(-1);
972 	}
973 	if (dst2->aio_dstscope >= 0 &&
974 	    dst2->aio_dstscope < dst1->aio_dstscope) {
975 		return(1);
976 	}
977 
978 	/*
979 	 * Rule 9: Use longest matching prefix.
980 	 * We compare the match length in a same AF only.
981 	 */
982 	if (dst1->aio_ai->ai_addr->sa_family ==
983 	    dst2->aio_ai->ai_addr->sa_family) {
984 		if (dst1->aio_matchlen > dst2->aio_matchlen) {
985 			return(-1);
986 		}
987 		if (dst1->aio_matchlen < dst2->aio_matchlen) {
988 			return(1);
989 		}
990 	}
991 
992 	/* Rule 10: Otherwise, leave the order unchanged. */
993 	return(-1);
994 }
995 
996 /*
997  * Copy from scope.c.
998  * XXX: we should standardize the functions and link them as standard
999  * library.
1000  */
1001 static int
1002 gai_addr2scopetype(sa)
1003 	struct sockaddr *sa;
1004 {
1005 #ifdef INET6
1006 	struct sockaddr_in6 *sa6;
1007 #endif
1008 	struct sockaddr_in *sa4;
1009 
1010 	switch(sa->sa_family) {
1011 #ifdef INET6
1012 	case AF_INET6:
1013 		sa6 = (struct sockaddr_in6 *)sa;
1014 		if (IN6_IS_ADDR_MULTICAST(&sa6->sin6_addr)) {
1015 			/* just use the scope field of the multicast address */
1016 			return(sa6->sin6_addr.s6_addr[2] & 0x0f);
1017 		}
1018 		/*
1019 		 * Unicast addresses: map scope type to corresponding scope
1020 		 * value defined for multcast addresses.
1021 		 * XXX: hardcoded scope type values are bad...
1022 		 */
1023 		if (IN6_IS_ADDR_LOOPBACK(&sa6->sin6_addr))
1024 			return(1); /* node local scope */
1025 		if (IN6_IS_ADDR_LINKLOCAL(&sa6->sin6_addr))
1026 			return(2); /* link-local scope */
1027 		if (IN6_IS_ADDR_SITELOCAL(&sa6->sin6_addr))
1028 			return(5); /* site-local scope */
1029 		return(14);	/* global scope */
1030 		break;
1031 #endif
1032 	case AF_INET:
1033 		/*
1034 		 * IPv4 pseudo scoping according to RFC 3484.
1035 		 */
1036 		sa4 = (struct sockaddr_in *)sa;
1037 		/* IPv4 autoconfiguration addresses have link-local scope. */
1038 		if (((u_char *)&sa4->sin_addr)[0] == 169 &&
1039 		    ((u_char *)&sa4->sin_addr)[1] == 254)
1040 			return(2);
1041 		/* Private addresses have site-local scope. */
1042 		if (((u_char *)&sa4->sin_addr)[0] == 10 ||
1043 		    (((u_char *)&sa4->sin_addr)[0] == 172 &&
1044 		     (((u_char *)&sa4->sin_addr)[1] & 0xf0) == 16) ||
1045 		    (((u_char *)&sa4->sin_addr)[0] == 192 &&
1046 		     ((u_char *)&sa4->sin_addr)[1] == 168))
1047 			return(14);	/* XXX: It should be 5 unless NAT */
1048 		/* Loopback addresses have link-local scope. */
1049 		if (((u_char *)&sa4->sin_addr)[0] == 127)
1050 			return(2);
1051 		return(14);
1052 		break;
1053 	default:
1054 		errno = EAFNOSUPPORT; /* is this a good error? */
1055 		return(-1);
1056 	}
1057 }
1058 
1059 /*
1060  * hostname == NULL.
1061  * passive socket -> anyaddr (0.0.0.0 or ::)
1062  * non-passive socket -> localhost (127.0.0.1 or ::1)
1063  */
1064 static int
1065 explore_null(pai, servname, res)
1066 	const struct addrinfo *pai;
1067 	const char *servname;
1068 	struct addrinfo **res;
1069 {
1070 	int s;
1071 	const struct afd *afd;
1072 	struct addrinfo *cur;
1073 	struct addrinfo sentinel;
1074 	int error;
1075 
1076 	*res = NULL;
1077 	sentinel.ai_next = NULL;
1078 	cur = &sentinel;
1079 
1080 	/*
1081 	 * filter out AFs that are not supported by the kernel
1082 	 * XXX errno?
1083 	 */
1084 	s = _socket(pai->ai_family, SOCK_DGRAM, 0);
1085 	if (s < 0) {
1086 		if (errno != EMFILE)
1087 			return 0;
1088 	} else
1089 		_close(s);
1090 
1091 	/*
1092 	 * if the servname does not match socktype/protocol, ignore it.
1093 	 */
1094 	if (get_portmatch(pai, servname) != 0)
1095 		return 0;
1096 
1097 	afd = find_afd(pai->ai_family);
1098 	if (afd == NULL)
1099 		return 0;
1100 
1101 	if (pai->ai_flags & AI_PASSIVE) {
1102 		GET_AI(cur->ai_next, afd, afd->a_addrany);
1103 		/* xxx meaningless?
1104 		 * GET_CANONNAME(cur->ai_next, "anyaddr");
1105 		 */
1106 		GET_PORT(cur->ai_next, servname);
1107 	} else {
1108 		GET_AI(cur->ai_next, afd, afd->a_loopback);
1109 		/* xxx meaningless?
1110 		 * GET_CANONNAME(cur->ai_next, "localhost");
1111 		 */
1112 		GET_PORT(cur->ai_next, servname);
1113 	}
1114 	cur = cur->ai_next;
1115 
1116 	*res = sentinel.ai_next;
1117 	return 0;
1118 
1119 free:
1120 	if (sentinel.ai_next)
1121 		freeaddrinfo(sentinel.ai_next);
1122 	return error;
1123 }
1124 
1125 /*
1126  * numeric hostname
1127  */
1128 static int
1129 explore_numeric(pai, hostname, servname, res, canonname)
1130 	const struct addrinfo *pai;
1131 	const char *hostname;
1132 	const char *servname;
1133 	struct addrinfo **res;
1134 	const char *canonname;
1135 {
1136 	const struct afd *afd;
1137 	struct addrinfo *cur;
1138 	struct addrinfo sentinel;
1139 	int error;
1140 	char pton[PTON_MAX];
1141 
1142 	*res = NULL;
1143 	sentinel.ai_next = NULL;
1144 	cur = &sentinel;
1145 
1146 	/*
1147 	 * if the servname does not match socktype/protocol, ignore it.
1148 	 */
1149 	if (get_portmatch(pai, servname) != 0)
1150 		return 0;
1151 
1152 	afd = find_afd(pai->ai_family);
1153 	if (afd == NULL)
1154 		return 0;
1155 
1156 	switch (afd->a_af) {
1157 #if 1 /*X/Open spec*/
1158 	case AF_INET:
1159 		if (inet_aton(hostname, (struct in_addr *)pton) == 1) {
1160 			if (pai->ai_family == afd->a_af ||
1161 			    pai->ai_family == PF_UNSPEC /*?*/) {
1162 				GET_AI(cur->ai_next, afd, pton);
1163 				GET_PORT(cur->ai_next, servname);
1164 				if ((pai->ai_flags & AI_CANONNAME)) {
1165 					/*
1166 					 * Set the numeric address itself as
1167 					 * the canonical name, based on a
1168 					 * clarification in rfc3493.
1169 					 */
1170 					GET_CANONNAME(cur->ai_next, canonname);
1171 				}
1172 				while (cur && cur->ai_next)
1173 					cur = cur->ai_next;
1174 			} else
1175 				ERR(EAI_FAMILY);	/*xxx*/
1176 		}
1177 		break;
1178 #endif
1179 	default:
1180 		if (inet_pton(afd->a_af, hostname, pton) == 1) {
1181 			if (pai->ai_family == afd->a_af ||
1182 			    pai->ai_family == PF_UNSPEC /*?*/) {
1183 				GET_AI(cur->ai_next, afd, pton);
1184 				GET_PORT(cur->ai_next, servname);
1185 				if ((pai->ai_flags & AI_CANONNAME)) {
1186 					/*
1187 					 * Set the numeric address itself as
1188 					 * the canonical name, based on a
1189 					 * clarification in rfc3493.
1190 					 */
1191 					GET_CANONNAME(cur->ai_next, canonname);
1192 				}
1193 				while (cur && cur->ai_next)
1194 					cur = cur->ai_next;
1195 			} else
1196 				ERR(EAI_FAMILY);	/* XXX */
1197 		}
1198 		break;
1199 	}
1200 
1201 	*res = sentinel.ai_next;
1202 	return 0;
1203 
1204 free:
1205 bad:
1206 	if (sentinel.ai_next)
1207 		freeaddrinfo(sentinel.ai_next);
1208 	return error;
1209 }
1210 
1211 /*
1212  * numeric hostname with scope
1213  */
1214 static int
1215 explore_numeric_scope(pai, hostname, servname, res)
1216 	const struct addrinfo *pai;
1217 	const char *hostname;
1218 	const char *servname;
1219 	struct addrinfo **res;
1220 {
1221 #if !defined(SCOPE_DELIMITER) || !defined(INET6)
1222 	return explore_numeric(pai, hostname, servname, res, hostname);
1223 #else
1224 	const struct afd *afd;
1225 	struct addrinfo *cur;
1226 	int error;
1227 	char *cp, *hostname2 = NULL, *scope, *addr;
1228 	struct sockaddr_in6 *sin6;
1229 
1230 	/*
1231 	 * if the servname does not match socktype/protocol, ignore it.
1232 	 */
1233 	if (get_portmatch(pai, servname) != 0)
1234 		return 0;
1235 
1236 	afd = find_afd(pai->ai_family);
1237 	if (afd == NULL)
1238 		return 0;
1239 
1240 	if (!afd->a_scoped)
1241 		return explore_numeric(pai, hostname, servname, res, hostname);
1242 
1243 	cp = strchr(hostname, SCOPE_DELIMITER);
1244 	if (cp == NULL)
1245 		return explore_numeric(pai, hostname, servname, res, hostname);
1246 
1247 	/*
1248 	 * Handle special case of <scoped_address><delimiter><scope id>
1249 	 */
1250 	hostname2 = strdup(hostname);
1251 	if (hostname2 == NULL)
1252 		return EAI_MEMORY;
1253 	/* terminate at the delimiter */
1254 	hostname2[cp - hostname] = '\0';
1255 	addr = hostname2;
1256 	scope = cp + 1;
1257 
1258 	error = explore_numeric(pai, addr, servname, res, hostname);
1259 	if (error == 0) {
1260 		u_int32_t scopeid;
1261 
1262 		for (cur = *res; cur; cur = cur->ai_next) {
1263 			if (cur->ai_family != AF_INET6)
1264 				continue;
1265 			sin6 = (struct sockaddr_in6 *)(void *)cur->ai_addr;
1266 			if (ip6_str2scopeid(scope, sin6, &scopeid) == -1) {
1267 				free(hostname2);
1268 				return(EAI_NONAME); /* XXX: is return OK? */
1269 			}
1270 			sin6->sin6_scope_id = scopeid;
1271 		}
1272 	}
1273 
1274 	free(hostname2);
1275 
1276 	return error;
1277 #endif
1278 }
1279 
1280 static int
1281 get_canonname(pai, ai, str)
1282 	const struct addrinfo *pai;
1283 	struct addrinfo *ai;
1284 	const char *str;
1285 {
1286 	if ((pai->ai_flags & AI_CANONNAME) != 0) {
1287 		ai->ai_canonname = strdup(str);
1288 		if (ai->ai_canonname == NULL)
1289 			return EAI_MEMORY;
1290 	}
1291 	return 0;
1292 }
1293 
1294 static struct addrinfo *
1295 get_ai(pai, afd, addr)
1296 	const struct addrinfo *pai;
1297 	const struct afd *afd;
1298 	const char *addr;
1299 {
1300 	char *p;
1301 	struct addrinfo *ai;
1302 #ifdef FAITH
1303 	struct in6_addr faith_prefix;
1304 	char *fp_str;
1305 	int translate = 0;
1306 #endif
1307 
1308 #ifdef FAITH
1309 	/*
1310 	 * Transfrom an IPv4 addr into a special IPv6 addr format for
1311 	 * IPv6->IPv4 translation gateway. (only TCP is supported now)
1312 	 *
1313 	 * +-----------------------------------+------------+
1314 	 * | faith prefix part (12 bytes)      | embedded   |
1315 	 * |                                   | IPv4 addr part (4 bytes)
1316 	 * +-----------------------------------+------------+
1317 	 *
1318 	 * faith prefix part is specified as ascii IPv6 addr format
1319 	 * in environmental variable GAI.
1320 	 * For FAITH to work correctly, routing to faith prefix must be
1321 	 * setup toward a machine where a FAITH daemon operates.
1322 	 * Also, the machine must enable some mechanizm
1323 	 * (e.g. faith interface hack) to divert those packet with
1324 	 * faith prefixed destination addr to user-land FAITH daemon.
1325 	 */
1326 	fp_str = getenv("GAI");
1327 	if (fp_str && inet_pton(AF_INET6, fp_str, &faith_prefix) == 1 &&
1328 	    afd->a_af == AF_INET && pai->ai_socktype == SOCK_STREAM) {
1329 		u_int32_t v4a;
1330 		u_int8_t v4a_top;
1331 
1332 		memcpy(&v4a, addr, sizeof v4a);
1333 		v4a_top = v4a >> IN_CLASSA_NSHIFT;
1334 		if (!IN_MULTICAST(v4a) && !IN_EXPERIMENTAL(v4a) &&
1335 		    v4a_top != 0 && v4a != IN_LOOPBACKNET) {
1336 			afd = &afdl[N_INET6];
1337 			memcpy(&faith_prefix.s6_addr[12], addr,
1338 			       sizeof(struct in_addr));
1339 			translate = 1;
1340 		}
1341 	}
1342 #endif
1343 
1344 	ai = (struct addrinfo *)malloc(sizeof(struct addrinfo)
1345 		+ (afd->a_socklen));
1346 	if (ai == NULL)
1347 		return NULL;
1348 
1349 	memcpy(ai, pai, sizeof(struct addrinfo));
1350 	ai->ai_addr = (struct sockaddr *)(void *)(ai + 1);
1351 	memset(ai->ai_addr, 0, (size_t)afd->a_socklen);
1352 	ai->ai_addr->sa_len = afd->a_socklen;
1353 	ai->ai_addrlen = afd->a_socklen;
1354 	ai->ai_addr->sa_family = ai->ai_family = afd->a_af;
1355 	p = (char *)(void *)(ai->ai_addr);
1356 #ifdef FAITH
1357 	if (translate == 1)
1358 		memcpy(p + afd->a_off, &faith_prefix, (size_t)afd->a_addrlen);
1359 	else
1360 #endif
1361 	memcpy(p + afd->a_off, addr, (size_t)afd->a_addrlen);
1362 	return ai;
1363 }
1364 
1365 static int
1366 get_portmatch(ai, servname)
1367 	const struct addrinfo *ai;
1368 	const char *servname;
1369 {
1370 
1371 	/* get_port does not touch first argument when matchonly == 1. */
1372 	/* LINTED const cast */
1373 	return get_port((struct addrinfo *)ai, servname, 1);
1374 }
1375 
1376 static int
1377 get_port(ai, servname, matchonly)
1378 	struct addrinfo *ai;
1379 	const char *servname;
1380 	int matchonly;
1381 {
1382 	const char *proto;
1383 	struct servent *sp;
1384 	int port;
1385 	int allownumeric;
1386 
1387 	if (servname == NULL)
1388 		return 0;
1389 	switch (ai->ai_family) {
1390 	case AF_INET:
1391 #ifdef AF_INET6
1392 	case AF_INET6:
1393 #endif
1394 		break;
1395 	default:
1396 		return 0;
1397 	}
1398 
1399 	switch (ai->ai_socktype) {
1400 	case SOCK_RAW:
1401 		return EAI_SERVICE;
1402 	case SOCK_DGRAM:
1403 	case SOCK_STREAM:
1404 		allownumeric = 1;
1405 		break;
1406 	case ANY:
1407 		allownumeric = 0;
1408 		break;
1409 	default:
1410 		return EAI_SOCKTYPE;
1411 	}
1412 
1413 	port = str2number(servname);
1414 	if (port >= 0) {
1415 		if (!allownumeric)
1416 			return EAI_SERVICE;
1417 		if (port < 0 || port > 65535)
1418 			return EAI_SERVICE;
1419 		port = htons(port);
1420 	} else {
1421 		if (ai->ai_flags & AI_NUMERICSERV)
1422 			return EAI_NONAME;
1423 		switch (ai->ai_socktype) {
1424 		case SOCK_DGRAM:
1425 			proto = "udp";
1426 			break;
1427 		case SOCK_STREAM:
1428 			proto = "tcp";
1429 			break;
1430 		default:
1431 			proto = NULL;
1432 			break;
1433 		}
1434 
1435 		if ((sp = getservbyname(servname, proto)) == NULL)
1436 			return EAI_SERVICE;
1437 		port = sp->s_port;
1438 	}
1439 
1440 	if (!matchonly) {
1441 		switch (ai->ai_family) {
1442 		case AF_INET:
1443 			((struct sockaddr_in *)(void *)
1444 			    ai->ai_addr)->sin_port = port;
1445 			break;
1446 #ifdef INET6
1447 		case AF_INET6:
1448 			((struct sockaddr_in6 *)(void *)
1449 			    ai->ai_addr)->sin6_port = port;
1450 			break;
1451 #endif
1452 		}
1453 	}
1454 
1455 	return 0;
1456 }
1457 
1458 static const struct afd *
1459 find_afd(af)
1460 	int af;
1461 {
1462 	const struct afd *afd;
1463 
1464 	if (af == PF_UNSPEC)
1465 		return NULL;
1466 	for (afd = afdl; afd->a_af; afd++) {
1467 		if (afd->a_af == af)
1468 			return afd;
1469 	}
1470 	return NULL;
1471 }
1472 
1473 /*
1474  * post-2553: AI_ADDRCONFIG check.  if we use getipnodeby* as backend, backend
1475  * will take care of it.
1476  * the semantics of AI_ADDRCONFIG is not defined well.  we are not sure
1477  * if the code is right or not.
1478  *
1479  * XXX PF_UNSPEC -> PF_INET6 + PF_INET mapping needs to be in sync with
1480  * _dns_getaddrinfo.
1481  */
1482 static int
1483 addrconfig(pai)
1484 	struct addrinfo *pai;
1485 {
1486 	int s, af;
1487 
1488 	/*
1489 	 * TODO:
1490 	 * Note that implementation dependent test for address
1491 	 * configuration should be done everytime called
1492 	 * (or apropriate interval),
1493 	 * because addresses will be dynamically assigned or deleted.
1494 	 */
1495 	af = pai->ai_family;
1496 	if (af == AF_UNSPEC) {
1497 		if ((s = _socket(AF_INET6, SOCK_DGRAM, 0)) < 0)
1498 			af = AF_INET;
1499 		else {
1500 			_close(s);
1501 			if ((s = _socket(AF_INET, SOCK_DGRAM, 0)) < 0)
1502 				af = AF_INET6;
1503 			else
1504 				_close(s);
1505 		}
1506 	}
1507 	if (af != AF_UNSPEC) {
1508 		if ((s = _socket(af, SOCK_DGRAM, 0)) < 0)
1509 			return 0;
1510 		_close(s);
1511 	}
1512 	pai->ai_family = af;
1513 	return 1;
1514 }
1515 
1516 #ifdef INET6
1517 /* convert a string to a scope identifier. XXX: IPv6 specific */
1518 static int
1519 ip6_str2scopeid(scope, sin6, scopeid)
1520 	char *scope;
1521 	struct sockaddr_in6 *sin6;
1522 	u_int32_t *scopeid;
1523 {
1524 	u_long lscopeid;
1525 	struct in6_addr *a6;
1526 	char *ep;
1527 
1528 	a6 = &sin6->sin6_addr;
1529 
1530 	/* empty scopeid portion is invalid */
1531 	if (*scope == '\0')
1532 		return -1;
1533 
1534 	if (IN6_IS_ADDR_LINKLOCAL(a6) || IN6_IS_ADDR_MC_LINKLOCAL(a6)) {
1535 		/*
1536 		 * We currently assume a one-to-one mapping between links
1537 		 * and interfaces, so we simply use interface indices for
1538 		 * like-local scopes.
1539 		 */
1540 		*scopeid = if_nametoindex(scope);
1541 		if (*scopeid == 0)
1542 			goto trynumeric;
1543 		return 0;
1544 	}
1545 
1546 	/* still unclear about literal, allow numeric only - placeholder */
1547 	if (IN6_IS_ADDR_SITELOCAL(a6) || IN6_IS_ADDR_MC_SITELOCAL(a6))
1548 		goto trynumeric;
1549 	if (IN6_IS_ADDR_MC_ORGLOCAL(a6))
1550 		goto trynumeric;
1551 	else
1552 		goto trynumeric;	/* global */
1553 
1554 	/* try to convert to a numeric id as a last resort */
1555   trynumeric:
1556 	errno = 0;
1557 	lscopeid = strtoul(scope, &ep, 10);
1558 	*scopeid = (u_int32_t)(lscopeid & 0xffffffffUL);
1559 	if (errno == 0 && ep && *ep == '\0' && *scopeid == lscopeid)
1560 		return 0;
1561 	else
1562 		return -1;
1563 }
1564 #endif
1565 
1566 /*
1567  * FQDN hostname, DNS lookup
1568  */
1569 static int
1570 explore_fqdn(pai, hostname, servname, res)
1571 	const struct addrinfo *pai;
1572 	const char *hostname;
1573 	const char *servname;
1574 	struct addrinfo **res;
1575 {
1576 	struct addrinfo *result;
1577 	struct addrinfo *cur;
1578 	int error = 0;
1579 	static const ns_dtab dtab[] = {
1580 		NS_FILES_CB(_files_getaddrinfo, NULL)
1581 		{ NSSRC_DNS, _dns_getaddrinfo, NULL },	/* force -DHESIOD */
1582 		NS_NIS_CB(_yp_getaddrinfo, NULL)
1583 		{ 0 }
1584 	};
1585 
1586 	result = NULL;
1587 
1588 	/*
1589 	 * if the servname does not match socktype/protocol, ignore it.
1590 	 */
1591 	if (get_portmatch(pai, servname) != 0)
1592 		return 0;
1593 
1594 	switch (_nsdispatch(&result, dtab, NSDB_HOSTS, "getaddrinfo",
1595 			default_dns_files, hostname, pai)) {
1596 	case NS_TRYAGAIN:
1597 		error = EAI_AGAIN;
1598 		goto free;
1599 	case NS_UNAVAIL:
1600 		error = EAI_FAIL;
1601 		goto free;
1602 	case NS_NOTFOUND:
1603 		error = EAI_NONAME;
1604 		goto free;
1605 	case NS_SUCCESS:
1606 		error = 0;
1607 		for (cur = result; cur; cur = cur->ai_next) {
1608 			GET_PORT(cur, servname);
1609 			/* canonname should be filled already */
1610 		}
1611 		break;
1612 	}
1613 
1614 	*res = result;
1615 
1616 	return 0;
1617 
1618 free:
1619 	if (result)
1620 		freeaddrinfo(result);
1621 	return error;
1622 }
1623 
1624 #ifdef DEBUG
1625 static const char AskedForGot[] =
1626 	"gethostby*.getanswer: asked for \"%s\", got \"%s\"";
1627 #endif
1628 
1629 static struct addrinfo *
1630 getanswer(answer, anslen, qname, qtype, pai)
1631 	const querybuf *answer;
1632 	int anslen;
1633 	const char *qname;
1634 	int qtype;
1635 	const struct addrinfo *pai;
1636 {
1637 	struct addrinfo sentinel, *cur;
1638 	struct addrinfo ai;
1639 	const struct afd *afd;
1640 	char *canonname;
1641 	const HEADER *hp;
1642 	const u_char *cp;
1643 	int n;
1644 	const u_char *eom;
1645 	char *bp, *ep;
1646 	int type, class, ancount, qdcount;
1647 	int haveanswer, had_error;
1648 	char tbuf[MAXDNAME];
1649 	int (*name_ok)(const char *);
1650 	char hostbuf[8*1024];
1651 
1652 	memset(&sentinel, 0, sizeof(sentinel));
1653 	cur = &sentinel;
1654 
1655 	canonname = NULL;
1656 	eom = answer->buf + anslen;
1657 	switch (qtype) {
1658 	case T_A:
1659 	case T_AAAA:
1660 	case T_ANY:	/*use T_ANY only for T_A/T_AAAA lookup*/
1661 		name_ok = res_hnok;
1662 		break;
1663 	default:
1664 		return (NULL);	/* XXX should be abort(); */
1665 	}
1666 	/*
1667 	 * find first satisfactory answer
1668 	 */
1669 	hp = &answer->hdr;
1670 	ancount = ntohs(hp->ancount);
1671 	qdcount = ntohs(hp->qdcount);
1672 	bp = hostbuf;
1673 	ep = hostbuf + sizeof hostbuf;
1674 	cp = answer->buf + HFIXEDSZ;
1675 	if (qdcount != 1) {
1676 		h_errno = NO_RECOVERY;
1677 		return (NULL);
1678 	}
1679 	n = dn_expand(answer->buf, eom, cp, bp, ep - bp);
1680 	if ((n < 0) || !(*name_ok)(bp)) {
1681 		h_errno = NO_RECOVERY;
1682 		return (NULL);
1683 	}
1684 	cp += n + QFIXEDSZ;
1685 	if (qtype == T_A || qtype == T_AAAA || qtype == T_ANY) {
1686 		/* res_send() has already verified that the query name is the
1687 		 * same as the one we sent; this just gets the expanded name
1688 		 * (i.e., with the succeeding search-domain tacked on).
1689 		 */
1690 		n = strlen(bp) + 1;		/* for the \0 */
1691 		if (n >= MAXHOSTNAMELEN) {
1692 			h_errno = NO_RECOVERY;
1693 			return (NULL);
1694 		}
1695 		canonname = bp;
1696 		bp += n;
1697 		/* The qname can be abbreviated, but h_name is now absolute. */
1698 		qname = canonname;
1699 	}
1700 	haveanswer = 0;
1701 	had_error = 0;
1702 	while (ancount-- > 0 && cp < eom && !had_error) {
1703 		n = dn_expand(answer->buf, eom, cp, bp, ep - bp);
1704 		if ((n < 0) || !(*name_ok)(bp)) {
1705 			had_error++;
1706 			continue;
1707 		}
1708 		cp += n;			/* name */
1709 		type = _getshort(cp);
1710  		cp += INT16SZ;			/* type */
1711 		class = _getshort(cp);
1712  		cp += INT16SZ + INT32SZ;	/* class, TTL */
1713 		n = _getshort(cp);
1714 		cp += INT16SZ;			/* len */
1715 		if (class != C_IN) {
1716 			/* XXX - debug? syslog? */
1717 			cp += n;
1718 			continue;		/* XXX - had_error++ ? */
1719 		}
1720 		if ((qtype == T_A || qtype == T_AAAA || qtype == T_ANY) &&
1721 		    type == T_CNAME) {
1722 			n = dn_expand(answer->buf, eom, cp, tbuf, sizeof tbuf);
1723 			if ((n < 0) || !(*name_ok)(tbuf)) {
1724 				had_error++;
1725 				continue;
1726 			}
1727 			cp += n;
1728 			/* Get canonical name. */
1729 			n = strlen(tbuf) + 1;	/* for the \0 */
1730 			if (n > ep - bp || n >= MAXHOSTNAMELEN) {
1731 				had_error++;
1732 				continue;
1733 			}
1734 			strlcpy(bp, tbuf, ep - bp);
1735 			canonname = bp;
1736 			bp += n;
1737 			continue;
1738 		}
1739 		if (qtype == T_ANY) {
1740 			if (!(type == T_A || type == T_AAAA)) {
1741 				cp += n;
1742 				continue;
1743 			}
1744 		} else if (type != qtype) {
1745 #ifdef DEBUG
1746 			if (type != T_KEY && type != T_SIG)
1747 				syslog(LOG_NOTICE|LOG_AUTH,
1748 	       "gethostby*.getanswer: asked for \"%s %s %s\", got type \"%s\"",
1749 				       qname, p_class(C_IN), p_type(qtype),
1750 				       p_type(type));
1751 #endif
1752 			cp += n;
1753 			continue;		/* XXX - had_error++ ? */
1754 		}
1755 		switch (type) {
1756 		case T_A:
1757 		case T_AAAA:
1758 			if (strcasecmp(canonname, bp) != 0) {
1759 #ifdef DEBUG
1760 				syslog(LOG_NOTICE|LOG_AUTH,
1761 				       AskedForGot, canonname, bp);
1762 #endif
1763 				cp += n;
1764 				continue;	/* XXX - had_error++ ? */
1765 			}
1766 			if (type == T_A && n != INADDRSZ) {
1767 				cp += n;
1768 				continue;
1769 			}
1770 			if (type == T_AAAA && n != IN6ADDRSZ) {
1771 				cp += n;
1772 				continue;
1773 			}
1774 #ifdef FILTER_V4MAPPED
1775 			if (type == T_AAAA) {
1776 				struct in6_addr in6;
1777 				memcpy(&in6, cp, sizeof(in6));
1778 				if (IN6_IS_ADDR_V4MAPPED(&in6)) {
1779 					cp += n;
1780 					continue;
1781 				}
1782 			}
1783 #endif
1784 			if (!haveanswer) {
1785 				int nn;
1786 
1787 				canonname = bp;
1788 				nn = strlen(bp) + 1;	/* for the \0 */
1789 				bp += nn;
1790 			}
1791 
1792 			/* don't overwrite pai */
1793 			ai = *pai;
1794 			ai.ai_family = (type == T_A) ? AF_INET : AF_INET6;
1795 			afd = find_afd(ai.ai_family);
1796 			if (afd == NULL) {
1797 				cp += n;
1798 				continue;
1799 			}
1800 			cur->ai_next = get_ai(&ai, afd, (const char *)cp);
1801 			if (cur->ai_next == NULL)
1802 				had_error++;
1803 			while (cur && cur->ai_next)
1804 				cur = cur->ai_next;
1805 			cp += n;
1806 			break;
1807 		default:
1808 			abort();
1809 		}
1810 		if (!had_error)
1811 			haveanswer++;
1812 	}
1813 	if (haveanswer) {
1814 #if defined(RESOLVSORT)
1815 		/*
1816 		 * We support only IPv4 address for backward
1817 		 * compatibility against gethostbyname(3).
1818 		 */
1819 		if (_res.nsort && qtype == T_A) {
1820 			if (addr4sort(&sentinel) < 0) {
1821 				freeaddrinfo(sentinel.ai_next);
1822 				h_errno = NO_RECOVERY;
1823 				return NULL;
1824 			}
1825 		}
1826 #endif /*RESOLVSORT*/
1827 		if (!canonname)
1828 			(void)get_canonname(pai, sentinel.ai_next, qname);
1829 		else
1830 			(void)get_canonname(pai, sentinel.ai_next, canonname);
1831 		h_errno = NETDB_SUCCESS;
1832 		return sentinel.ai_next;
1833 	}
1834 
1835 	h_errno = NO_RECOVERY;
1836 	return NULL;
1837 }
1838 
1839 #ifdef RESOLVSORT
1840 struct addr_ptr {
1841 	struct addrinfo *ai;
1842 	int aval;
1843 };
1844 
1845 static int
1846 addr4sort(struct addrinfo *sentinel)
1847 {
1848 	struct addrinfo *ai;
1849 	struct addr_ptr *addrs, addr;
1850 	struct sockaddr_in *sin;
1851 	int naddrs, i, j;
1852 	int needsort = 0;
1853 
1854 	if (!sentinel)
1855 		return -1;
1856 	naddrs = 0;
1857 	for (ai = sentinel->ai_next; ai; ai = ai->ai_next)
1858 		naddrs++;
1859 	if (naddrs < 2)
1860 		return 0;		/* We don't need sorting. */
1861 	if ((addrs = malloc(sizeof(struct addr_ptr) * naddrs)) == NULL)
1862 		return -1;
1863 	i = 0;
1864 	for (ai = sentinel->ai_next; ai; ai = ai->ai_next) {
1865 		sin = (struct sockaddr_in *)ai->ai_addr;
1866 		for (j = 0; (unsigned)j < _res.nsort; j++) {
1867 			if (_res.sort_list[j].addr.s_addr ==
1868 			    (sin->sin_addr.s_addr & _res.sort_list[j].mask))
1869 				break;
1870 		}
1871 		addrs[i].ai = ai;
1872 		addrs[i].aval = j;
1873 		if (needsort == 0 && i > 0 && j < addrs[i - 1].aval)
1874 			needsort = i;
1875 		i++;
1876 	}
1877 	if (!needsort) {
1878 		free(addrs);
1879 		return 0;
1880 	}
1881 
1882 	while (needsort < naddrs) {
1883 	    for (j = needsort - 1; j >= 0; j--) {
1884 		if (addrs[j].aval > addrs[j+1].aval) {
1885 		    addr = addrs[j];
1886 		    addrs[j] = addrs[j + 1];
1887 		    addrs[j + 1] = addr;
1888 		} else
1889 		    break;
1890 	    }
1891 	    needsort++;
1892 	}
1893 
1894 	ai = sentinel;
1895 	for (i = 0; i < naddrs; ++i) {
1896 		ai->ai_next = addrs[i].ai;
1897 		ai = ai->ai_next;
1898 	}
1899 	ai->ai_next = NULL;
1900 	free(addrs);
1901 	return 0;
1902 }
1903 #endif /*RESOLVSORT*/
1904 
1905 /*ARGSUSED*/
1906 static int
1907 _dns_getaddrinfo(rv, cb_data, ap)
1908 	void	*rv;
1909 	void	*cb_data;
1910 	va_list	 ap;
1911 {
1912 	struct addrinfo *ai;
1913 	querybuf *buf, *buf2;
1914 	const char *hostname;
1915 	const struct addrinfo *pai;
1916 	struct addrinfo sentinel, *cur;
1917 	struct res_target q, q2;
1918 
1919 	hostname = va_arg(ap, char *);
1920 	pai = va_arg(ap, const struct addrinfo *);
1921 
1922 	memset(&q, 0, sizeof(q2));
1923 	memset(&q2, 0, sizeof(q2));
1924 	memset(&sentinel, 0, sizeof(sentinel));
1925 	cur = &sentinel;
1926 
1927 	buf = malloc(sizeof(*buf));
1928 	if (!buf) {
1929 		h_errno = NETDB_INTERNAL;
1930 		return NS_NOTFOUND;
1931 	}
1932 	buf2 = malloc(sizeof(*buf2));
1933 	if (!buf2) {
1934 		free(buf);
1935 		h_errno = NETDB_INTERNAL;
1936 		return NS_NOTFOUND;
1937 	}
1938 
1939 	switch (pai->ai_family) {
1940 	case AF_UNSPEC:
1941 		q.name = hostname;
1942 		q.qclass = C_IN;
1943 		q.qtype = T_A;
1944 		q.answer = buf->buf;
1945 		q.anslen = sizeof(buf->buf);
1946 		q.next = &q2;
1947 		q2.name = hostname;
1948 		q2.qclass = C_IN;
1949 		q2.qtype = T_AAAA;
1950 		q2.answer = buf2->buf;
1951 		q2.anslen = sizeof(buf2->buf);
1952 		break;
1953 	case AF_INET:
1954 		q.name = hostname;
1955 		q.qclass = C_IN;
1956 		q.qtype = T_A;
1957 		q.answer = buf->buf;
1958 		q.anslen = sizeof(buf->buf);
1959 		break;
1960 	case AF_INET6:
1961 		q.name = hostname;
1962 		q.qclass = C_IN;
1963 		q.qtype = T_AAAA;
1964 		q.answer = buf->buf;
1965 		q.anslen = sizeof(buf->buf);
1966 		break;
1967 	default:
1968 		free(buf);
1969 		free(buf2);
1970 		return NS_UNAVAIL;
1971 	}
1972 	if (res_searchN(hostname, &q) < 0) {
1973 		free(buf);
1974 		free(buf2);
1975 		return NS_NOTFOUND;
1976 	}
1977 	/* prefer IPv6 */
1978 	if (q.next) {
1979 		ai = getanswer(buf2, q2.n, q2.name, q2.qtype, pai);
1980 		if (ai) {
1981 			cur->ai_next = ai;
1982 			while (cur && cur->ai_next)
1983 				cur = cur->ai_next;
1984 		}
1985 	}
1986 	ai = getanswer(buf, q.n, q.name, q.qtype, pai);
1987 	if (ai)
1988 		cur->ai_next = ai;
1989 	free(buf);
1990 	free(buf2);
1991 	if (sentinel.ai_next == NULL)
1992 		switch (h_errno) {
1993 		case HOST_NOT_FOUND:
1994 			return NS_NOTFOUND;
1995 		case TRY_AGAIN:
1996 			return NS_TRYAGAIN;
1997 		default:
1998 			return NS_UNAVAIL;
1999 		}
2000 	*((struct addrinfo **)rv) = sentinel.ai_next;
2001 	return NS_SUCCESS;
2002 }
2003 
2004 static void
2005 _sethtent(FILE **hostf)
2006 {
2007 	if (!*hostf)
2008 		*hostf = fopen(_PATH_HOSTS, "r");
2009 	else
2010 		rewind(*hostf);
2011 }
2012 
2013 static void
2014 _endhtent(FILE **hostf)
2015 {
2016 	if (*hostf) {
2017 		(void) fclose(*hostf);
2018 		*hostf = NULL;
2019 	}
2020 }
2021 
2022 static struct addrinfo *
2023 _gethtent(FILE **hostf, const char *name, const struct addrinfo *pai)
2024 {
2025 	char *p;
2026 	char *cp, *tname, *cname;
2027 	struct addrinfo hints, *res0, *res;
2028 	int error;
2029 	const char *addr;
2030 	char hostbuf[8*1024];
2031 
2032 	if (!*hostf && !(*hostf = fopen(_PATH_HOSTS, "r")))
2033 		return (NULL);
2034 again:
2035 	if (!(p = fgets(hostbuf, sizeof hostbuf, *hostf)))
2036 		return (NULL);
2037 	if (*p == '#')
2038 		goto again;
2039 	cp = strpbrk(p, "#\n");
2040 	if (cp != NULL)
2041 		*cp = '\0';
2042 	if (!(cp = strpbrk(p, " \t")))
2043 		goto again;
2044 	*cp++ = '\0';
2045 	addr = p;
2046 	cname = NULL;
2047 	/* if this is not something we're looking for, skip it. */
2048 	while (cp && *cp) {
2049 		if (*cp == ' ' || *cp == '\t') {
2050 			cp++;
2051 			continue;
2052 		}
2053 		tname = cp;
2054 		if (cname == NULL)
2055 			cname = cp;
2056 		if ((cp = strpbrk(cp, " \t")) != NULL)
2057 			*cp++ = '\0';
2058 		if (strcasecmp(name, tname) == 0)
2059 			goto found;
2060 	}
2061 	goto again;
2062 
2063 found:
2064 	/* we should not glob socktype/protocol here */
2065 	memset(&hints, 0, sizeof(hints));
2066 	hints.ai_family = pai->ai_family;
2067 	hints.ai_socktype = SOCK_DGRAM;
2068 	hints.ai_protocol = 0;
2069 	hints.ai_flags = AI_NUMERICHOST;
2070 	error = getaddrinfo(addr, "0", &hints, &res0);
2071 	if (error)
2072 		goto again;
2073 #ifdef FILTER_V4MAPPED
2074 	/* XXX should check all items in the chain */
2075 	if (res0->ai_family == AF_INET6 &&
2076 	    IN6_IS_ADDR_V4MAPPED(&((struct sockaddr_in6 *)res0->ai_addr)->sin6_addr)) {
2077 		freeaddrinfo(res0);
2078 		goto again;
2079 	}
2080 #endif
2081 	for (res = res0; res; res = res->ai_next) {
2082 		/* cover it up */
2083 		res->ai_flags = pai->ai_flags;
2084 		res->ai_socktype = pai->ai_socktype;
2085 		res->ai_protocol = pai->ai_protocol;
2086 
2087 		if (pai->ai_flags & AI_CANONNAME) {
2088 			if (get_canonname(pai, res, cname) != 0) {
2089 				freeaddrinfo(res0);
2090 				goto again;
2091 			}
2092 		}
2093 	}
2094 	return res0;
2095 }
2096 
2097 /*ARGSUSED*/
2098 static int
2099 _files_getaddrinfo(rv, cb_data, ap)
2100 	void	*rv;
2101 	void	*cb_data;
2102 	va_list	 ap;
2103 {
2104 	const char *name;
2105 	const struct addrinfo *pai;
2106 	struct addrinfo sentinel, *cur;
2107 	struct addrinfo *p;
2108 	FILE *hostf = NULL;
2109 
2110 	name = va_arg(ap, char *);
2111 	pai = va_arg(ap, struct addrinfo *);
2112 
2113 	memset(&sentinel, 0, sizeof(sentinel));
2114 	cur = &sentinel;
2115 
2116 	_sethtent(&hostf);
2117 	while ((p = _gethtent(&hostf, name, pai)) != NULL) {
2118 		cur->ai_next = p;
2119 		while (cur && cur->ai_next)
2120 			cur = cur->ai_next;
2121 	}
2122 	_endhtent(&hostf);
2123 
2124 	*((struct addrinfo **)rv) = sentinel.ai_next;
2125 	if (sentinel.ai_next == NULL)
2126 		return NS_NOTFOUND;
2127 	return NS_SUCCESS;
2128 }
2129 
2130 #ifdef YP
2131 /*ARGSUSED*/
2132 static struct addrinfo *
2133 _yphostent(line, pai)
2134 	char *line;
2135 	const struct addrinfo *pai;
2136 {
2137 	struct addrinfo sentinel, *cur;
2138 	struct addrinfo hints, *res, *res0;
2139 	int error;
2140 	char *p = line;
2141 	const char *addr, *canonname;
2142 	char *nextline;
2143 	char *cp;
2144 
2145 	addr = canonname = NULL;
2146 
2147 	memset(&sentinel, 0, sizeof(sentinel));
2148 	cur = &sentinel;
2149 
2150 nextline:
2151 	/* terminate line */
2152 	cp = strchr(p, '\n');
2153 	if (cp) {
2154 		*cp++ = '\0';
2155 		nextline = cp;
2156 	} else
2157 		nextline = NULL;
2158 
2159 	cp = strpbrk(p, " \t");
2160 	if (cp == NULL) {
2161 		if (canonname == NULL)
2162 			return (NULL);
2163 		else
2164 			goto done;
2165 	}
2166 	*cp++ = '\0';
2167 
2168 	addr = p;
2169 
2170 	while (cp && *cp) {
2171 		if (*cp == ' ' || *cp == '\t') {
2172 			cp++;
2173 			continue;
2174 		}
2175 		if (!canonname)
2176 			canonname = cp;
2177 		if ((cp = strpbrk(cp, " \t")) != NULL)
2178 			*cp++ = '\0';
2179 	}
2180 
2181 	hints = *pai;
2182 	hints.ai_flags = AI_NUMERICHOST;
2183 	error = getaddrinfo(addr, NULL, &hints, &res0);
2184 	if (error == 0) {
2185 		for (res = res0; res; res = res->ai_next) {
2186 			/* cover it up */
2187 			res->ai_flags = pai->ai_flags;
2188 
2189 			if (pai->ai_flags & AI_CANONNAME)
2190 				(void)get_canonname(pai, res, canonname);
2191 		}
2192 	} else
2193 		res0 = NULL;
2194 	if (res0) {
2195 		cur->ai_next = res0;
2196 		while (cur && cur->ai_next)
2197 			cur = cur->ai_next;
2198 	}
2199 
2200 	if (nextline) {
2201 		p = nextline;
2202 		goto nextline;
2203 	}
2204 
2205 done:
2206 	return sentinel.ai_next;
2207 }
2208 
2209 /*ARGSUSED*/
2210 static int
2211 _yp_getaddrinfo(rv, cb_data, ap)
2212 	void	*rv;
2213 	void	*cb_data;
2214 	va_list	 ap;
2215 {
2216 	struct addrinfo sentinel, *cur;
2217 	struct addrinfo *ai = NULL;
2218 	char *ypbuf;
2219 	int ypbuflen, r;
2220 	const char *name;
2221 	const struct addrinfo *pai;
2222 	char *ypdomain;
2223 
2224 	if (_yp_check(&ypdomain) == 0)
2225 		return NS_UNAVAIL;
2226 
2227 	name = va_arg(ap, char *);
2228 	pai = va_arg(ap, const struct addrinfo *);
2229 
2230 	memset(&sentinel, 0, sizeof(sentinel));
2231 	cur = &sentinel;
2232 
2233 	/* hosts.byname is only for IPv4 (Solaris8) */
2234 	if (pai->ai_family == PF_UNSPEC || pai->ai_family == PF_INET) {
2235 		r = yp_match(ypdomain, "hosts.byname", name,
2236 			(int)strlen(name), &ypbuf, &ypbuflen);
2237 		if (r == 0) {
2238 			struct addrinfo ai4;
2239 
2240 			ai4 = *pai;
2241 			ai4.ai_family = AF_INET;
2242 			ai = _yphostent(ypbuf, &ai4);
2243 			if (ai) {
2244 				cur->ai_next = ai;
2245 				while (cur && cur->ai_next)
2246 					cur = cur->ai_next;
2247 			}
2248 		}
2249 		free(ypbuf);
2250 	}
2251 
2252 	/* ipnodes.byname can hold both IPv4/v6 */
2253 	r = yp_match(ypdomain, "ipnodes.byname", name,
2254 		(int)strlen(name), &ypbuf, &ypbuflen);
2255 	if (r == 0) {
2256 		ai = _yphostent(ypbuf, pai);
2257 		if (ai)
2258 			cur->ai_next = ai;
2259 		free(ypbuf);
2260 	}
2261 
2262 	if (sentinel.ai_next == NULL) {
2263 		h_errno = HOST_NOT_FOUND;
2264 		return NS_NOTFOUND;
2265 	}
2266 	*((struct addrinfo **)rv) = sentinel.ai_next;
2267 	return NS_SUCCESS;
2268 }
2269 #endif
2270 
2271 /* resolver logic */
2272 
2273 extern const char *_res_hostalias(const char *, char *, size_t);
2274 
2275 /*
2276  * Formulate a normal query, send, and await answer.
2277  * Returned answer is placed in supplied buffer "answer".
2278  * Perform preliminary check of answer, returning success only
2279  * if no error is indicated and the answer count is nonzero.
2280  * Return the size of the response on success, -1 on error.
2281  * Error number is left in h_errno.
2282  *
2283  * Caller must parse answer and determine whether it answers the question.
2284  */
2285 static int
2286 res_queryN(name, target)
2287 	const char *name;	/* domain name */
2288 	struct res_target *target;
2289 {
2290 	u_char *buf;
2291 	HEADER *hp;
2292 	int n;
2293 	struct res_target *t;
2294 	int rcode;
2295 	int ancount;
2296 
2297 	rcode = NOERROR;
2298 	ancount = 0;
2299 
2300 	buf = malloc(MAXPACKET);
2301 	if (!buf) {
2302 		h_errno = NETDB_INTERNAL;
2303 		return -1;
2304 	}
2305 
2306 	for (t = target; t; t = t->next) {
2307 		int class, type;
2308 		u_char *answer;
2309 		int anslen;
2310 
2311 		hp = (HEADER *)(void *)t->answer;
2312 		hp->rcode = NOERROR;	/* default */
2313 
2314 		/* make it easier... */
2315 		class = t->qclass;
2316 		type = t->qtype;
2317 		answer = t->answer;
2318 		anslen = t->anslen;
2319 #ifdef DEBUG
2320 		if (_res.options & RES_DEBUG)
2321 			printf(";; res_query(%s, %d, %d)\n", name, class, type);
2322 #endif
2323 
2324 		n = res_mkquery(QUERY, name, class, type, NULL, 0, NULL,
2325 		    buf, MAXPACKET);
2326 		if (n > 0 && (_res.options & RES_USE_EDNS0) != 0)
2327 			n = res_opt(n, buf, MAXPACKET, anslen);
2328 		if (n <= 0) {
2329 #ifdef DEBUG
2330 			if (_res.options & RES_DEBUG)
2331 				printf(";; res_query: mkquery failed\n");
2332 #endif
2333 			free(buf);
2334 			h_errno = NO_RECOVERY;
2335 			return (n);
2336 		}
2337 		n = res_send(buf, n, answer, anslen);
2338 #if 0
2339 		if (n < 0) {
2340 #ifdef DEBUG
2341 			if (_res.options & RES_DEBUG)
2342 				printf(";; res_query: send error\n");
2343 #endif
2344 			free(buf);
2345 			h_errno = TRY_AGAIN;
2346 			return (n);
2347 		}
2348 #endif
2349 
2350 		if (n < 0 || n > anslen)
2351 			hp->rcode = FORMERR; /* XXX not very informative */
2352 		if (hp->rcode != NOERROR || ntohs(hp->ancount) == 0) {
2353 			rcode = hp->rcode;	/* record most recent error */
2354 #ifdef DEBUG
2355 			if (_res.options & RES_DEBUG)
2356 				printf(";; rcode = %u, ancount=%u\n", hp->rcode,
2357 				    ntohs(hp->ancount));
2358 #endif
2359 			continue;
2360 		}
2361 
2362 		ancount += ntohs(hp->ancount);
2363 
2364 		t->n = n;
2365 	}
2366 
2367 	free(buf);
2368 
2369 	if (ancount == 0) {
2370 		switch (rcode) {
2371 		case NXDOMAIN:
2372 			h_errno = HOST_NOT_FOUND;
2373 			break;
2374 		case SERVFAIL:
2375 			h_errno = TRY_AGAIN;
2376 			break;
2377 		case NOERROR:
2378 			h_errno = NO_DATA;
2379 			break;
2380 		case FORMERR:
2381 		case NOTIMP:
2382 		case REFUSED:
2383 		default:
2384 			h_errno = NO_RECOVERY;
2385 			break;
2386 		}
2387 		return (-1);
2388 	}
2389 	return (ancount);
2390 }
2391 
2392 /*
2393  * Formulate a normal query, send, and retrieve answer in supplied buffer.
2394  * Return the size of the response on success, -1 on error.
2395  * If enabled, implement search rules until answer or unrecoverable failure
2396  * is detected.  Error code, if any, is left in h_errno.
2397  */
2398 static int
2399 res_searchN(name, target)
2400 	const char *name;	/* domain name */
2401 	struct res_target *target;
2402 {
2403 	const char *cp, * const *domain;
2404 	HEADER *hp = (HEADER *)(void *)target->answer;	/*XXX*/
2405 	u_int dots;
2406 	int trailing_dot, ret, saved_herrno;
2407 	int got_nodata = 0, got_servfail = 0, tried_as_is = 0;
2408 	char abuf[MAXDNAME];
2409 
2410 	if ((_res.options & RES_INIT) == 0 && res_init() == -1) {
2411 		h_errno = NETDB_INTERNAL;
2412 		return (-1);
2413 	}
2414 
2415 	errno = 0;
2416 	h_errno = HOST_NOT_FOUND;	/* default, if we never query */
2417 	dots = 0;
2418 	for (cp = name; *cp; cp++)
2419 		dots += (*cp == '.');
2420 	trailing_dot = 0;
2421 	if (cp > name && *--cp == '.')
2422 		trailing_dot++;
2423 
2424 	/*
2425 	 * if there aren't any dots, it could be a user-level alias
2426 	 */
2427 	if (!dots && (cp = _res_hostalias(name, abuf, sizeof(abuf))) != NULL)
2428 		return (res_queryN(cp, target));
2429 
2430 	/*
2431 	 * If there are dots in the name already, let's just give it a try
2432 	 * 'as is'.  The threshold can be set with the "ndots" option.
2433 	 */
2434 	saved_herrno = -1;
2435 	if (dots >= _res.ndots) {
2436 		ret = res_querydomainN(name, NULL, target);
2437 		if (ret > 0)
2438 			return (ret);
2439 		saved_herrno = h_errno;
2440 		tried_as_is++;
2441 	}
2442 
2443 	/*
2444 	 * We do at least one level of search if
2445 	 *	- there is no dot and RES_DEFNAME is set, or
2446 	 *	- there is at least one dot, there is no trailing dot,
2447 	 *	  and RES_DNSRCH is set.
2448 	 */
2449 	if ((!dots && (_res.options & RES_DEFNAMES)) ||
2450 	    (dots && !trailing_dot && (_res.options & RES_DNSRCH))) {
2451 		int done = 0;
2452 
2453 		for (domain = (const char * const *)_res.dnsrch;
2454 		   *domain && !done;
2455 		   domain++) {
2456 
2457 			ret = res_querydomainN(name, *domain, target);
2458 			if (ret > 0)
2459 				return (ret);
2460 
2461 			/*
2462 			 * If no server present, give up.
2463 			 * If name isn't found in this domain,
2464 			 * keep trying higher domains in the search list
2465 			 * (if that's enabled).
2466 			 * On a NO_DATA error, keep trying, otherwise
2467 			 * a wildcard entry of another type could keep us
2468 			 * from finding this entry higher in the domain.
2469 			 * If we get some other error (negative answer or
2470 			 * server failure), then stop searching up,
2471 			 * but try the input name below in case it's
2472 			 * fully-qualified.
2473 			 */
2474 			if (errno == ECONNREFUSED) {
2475 				h_errno = TRY_AGAIN;
2476 				return (-1);
2477 			}
2478 
2479 			switch (h_errno) {
2480 			case NO_DATA:
2481 				got_nodata++;
2482 				/* FALLTHROUGH */
2483 			case HOST_NOT_FOUND:
2484 				/* keep trying */
2485 				break;
2486 			case TRY_AGAIN:
2487 				if (hp->rcode == SERVFAIL) {
2488 					/* try next search element, if any */
2489 					got_servfail++;
2490 					break;
2491 				}
2492 				/* FALLTHROUGH */
2493 			default:
2494 				/* anything else implies that we're done */
2495 				done++;
2496 			}
2497 			/*
2498 			 * if we got here for some reason other than DNSRCH,
2499 			 * we only wanted one iteration of the loop, so stop.
2500 			 */
2501 			if (!(_res.options & RES_DNSRCH))
2502 			        done++;
2503 		}
2504 	}
2505 
2506 	/*
2507 	 * if we have not already tried the name "as is", do that now.
2508 	 * note that we do this regardless of how many dots were in the
2509 	 * name or whether it ends with a dot.
2510 	 */
2511 	if (!tried_as_is && (dots || !(_res.options & RES_NOTLDQUERY))) {
2512 		ret = res_querydomainN(name, NULL, target);
2513 		if (ret > 0)
2514 			return (ret);
2515 	}
2516 
2517 	/*
2518 	 * if we got here, we didn't satisfy the search.
2519 	 * if we did an initial full query, return that query's h_errno
2520 	 * (note that we wouldn't be here if that query had succeeded).
2521 	 * else if we ever got a nodata, send that back as the reason.
2522 	 * else send back meaningless h_errno, that being the one from
2523 	 * the last DNSRCH we did.
2524 	 */
2525 	if (saved_herrno != -1)
2526 		h_errno = saved_herrno;
2527 	else if (got_nodata)
2528 		h_errno = NO_DATA;
2529 	else if (got_servfail)
2530 		h_errno = TRY_AGAIN;
2531 	return (-1);
2532 }
2533 
2534 /*
2535  * Perform a call on res_query on the concatenation of name and domain,
2536  * removing a trailing dot from name if domain is NULL.
2537  */
2538 static int
2539 res_querydomainN(name, domain, target)
2540 	const char *name, *domain;
2541 	struct res_target *target;
2542 {
2543 	char nbuf[MAXDNAME];
2544 	const char *longname = nbuf;
2545 	size_t n, d;
2546 
2547 #ifdef DEBUG
2548 	if (_res.options & RES_DEBUG)
2549 		printf(";; res_querydomain(%s, %s)\n",
2550 			name, domain?domain:"<Nil>");
2551 #endif
2552 	if (domain == NULL) {
2553 		/*
2554 		 * Check for trailing '.';
2555 		 * copy without '.' if present.
2556 		 */
2557 		n = strlen(name);
2558 		if (n >= MAXDNAME) {
2559 			h_errno = NO_RECOVERY;
2560 			return (-1);
2561 		}
2562 		if (n > 0 && name[--n] == '.') {
2563 			strncpy(nbuf, name, n);
2564 			nbuf[n] = '\0';
2565 		} else
2566 			longname = name;
2567 	} else {
2568 		n = strlen(name);
2569 		d = strlen(domain);
2570 		if (n + d + 1 >= MAXDNAME) {
2571 			h_errno = NO_RECOVERY;
2572 			return (-1);
2573 		}
2574 		snprintf(nbuf, sizeof(nbuf), "%s.%s", name, domain);
2575 	}
2576 	return (res_queryN(longname, target));
2577 }
2578