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