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