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