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