1/*	$KAME: getaddrinfo.c,v 1.14 2001/01/06 09:41:15 jinmei 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/*! \file
33 * Issues to be discussed:
34 *\li  Thread safe-ness must be checked.
35 *\li  Return values.  There are nonstandard return values defined and used
36 *   in the source code.  This is because RFC2553 is silent about which error
37 *   code must be returned for which situation.
38 *\li  IPv4 classful (shortened) form.  RFC2553 is silent about it.  XNET 5.2
39 *   says to use inet_aton() to convert IPv4 numeric to binary (allows
40 *   classful form as a result).
41 *   current code - disallow classful form for IPv4 (due to use of inet_pton).
42 *\li  freeaddrinfo(NULL).  RFC2553 is silent about it.  XNET 5.2 says it is
43 *   invalid.
44 *   current code - SEGV on freeaddrinfo(NULL)
45 * Note:
46 *\li  We use getipnodebyname() just for thread-safeness.  There's no intent
47 *   to let it do PF_UNSPEC (actually we never pass PF_UNSPEC to
48 *   getipnodebyname().
49 *\li  The code filters out AFs that are not supported by the kernel,
50 *   when globbing NULL hostname (to loopback, or wildcard).  Is it the right
51 *   thing to do?  What is the relationship with post-RFC2553 AI_ADDRCONFIG
52 *   in ai_flags?
53 *\li  (post-2553) semantics of AI_ADDRCONFIG itself is too vague.
54 *   (1) what should we do against numeric hostname (2) what should we do
55 *   against NULL hostname (3) what is AI_ADDRCONFIG itself.  AF not ready?
56 *   non-loopback address configured?  global address configured?
57 * \par Additional Issue:
58 *  To avoid search order issue, we have a big amount of code duplicate
59 *   from gethnamaddr.c and some other places.  The issues that there's no
60 *   lower layer function to lookup "IPv4 or IPv6" record.  Calling
61 *   gethostbyname2 from getaddrinfo will end up in wrong search order, as
62 *   follows:
63 *	\li The code makes use of following calls when asked to resolver with
64 *	  ai_family  = PF_UNSPEC:
65 *\code		getipnodebyname(host, AF_INET6);
66 *		getipnodebyname(host, AF_INET);
67 *\endcode
68 *	\li  This will result in the following queries if the node is configure to
69 *	  prefer /etc/hosts than DNS:
70 *\code
71 *		lookup /etc/hosts for IPv6 address
72 *		lookup DNS for IPv6 address
73 *		lookup /etc/hosts for IPv4 address
74 *		lookup DNS for IPv4 address
75 *\endcode
76 *	  which may not meet people's requirement.
77 *	 \li The right thing to happen is to have underlying layer which does
78 *	  PF_UNSPEC lookup (lookup both) and return chain of addrinfos.
79 *	  This would result in a bit of code duplicate with _dns_ghbyname() and
80 *	  friends.
81 */
82
83#include "port_before.h"
84
85#include <sys/types.h>
86#include <sys/param.h>
87#include <sys/socket.h>
88
89#include <net/if.h>
90#include <netinet/in.h>
91
92#include <arpa/inet.h>
93#include <arpa/nameser.h>
94
95#include <netdb.h>
96#include <resolv.h>
97#include <string.h>
98#include <stdlib.h>
99#include <stddef.h>
100#include <ctype.h>
101#include <unistd.h>
102#include <stdio.h>
103#include <errno.h>
104
105#include <stdarg.h>
106
107#include <irs.h>
108#include <isc/assertions.h>
109
110#include "port_after.h"
111
112#include "irs_data.h"
113
114#define SUCCESS 0
115#define ANY 0
116#define YES 1
117#define NO  0
118
119static const char in_addrany[] = { 0, 0, 0, 0 };
120static const char in6_addrany[] = {
121	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
122};
123static const char in_loopback[] = { 127, 0, 0, 1 };
124static const char in6_loopback[] = {
125	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1
126};
127
128static const struct afd {
129	int a_af;
130	int a_addrlen;
131	int a_socklen;
132	int a_off;
133	const char *a_addrany;
134	const char *a_loopback;
135	int a_scoped;
136} afdl [] = {
137	{PF_INET6, sizeof(struct in6_addr),
138	 sizeof(struct sockaddr_in6),
139	 offsetof(struct sockaddr_in6, sin6_addr),
140	 in6_addrany, in6_loopback, 1},
141	{PF_INET, sizeof(struct in_addr),
142	 sizeof(struct sockaddr_in),
143	 offsetof(struct sockaddr_in, sin_addr),
144	 in_addrany, in_loopback, 0},
145	{0, 0, 0, 0, NULL, NULL, 0},
146};
147
148struct explore {
149	int e_af;
150	int e_socktype;
151	int e_protocol;
152	const char *e_protostr;
153	int e_wild;
154#define WILD_AF(ex)		((ex)->e_wild & 0x01)
155#define WILD_SOCKTYPE(ex)	((ex)->e_wild & 0x02)
156#define WILD_PROTOCOL(ex)	((ex)->e_wild & 0x04)
157};
158
159static const struct explore explore[] = {
160#if 0
161	{ PF_LOCAL, 0, ANY, ANY, NULL, 0x01 },
162#endif
163	{ PF_INET6, SOCK_DGRAM, IPPROTO_UDP, "udp", 0x07 },
164	{ PF_INET6, SOCK_STREAM, IPPROTO_TCP, "tcp", 0x07 },
165	{ PF_INET6, SOCK_RAW, ANY, NULL, 0x05 },
166	{ PF_INET, SOCK_DGRAM, IPPROTO_UDP, "udp", 0x07 },
167	{ PF_INET, SOCK_STREAM, IPPROTO_TCP, "tcp", 0x07 },
168	{ PF_INET, SOCK_RAW, ANY, NULL, 0x05 },
169	{ -1, 0, 0, NULL, 0 },
170};
171
172#define PTON_MAX	16
173
174static int str_isnumber __P((const char *));
175static int explore_fqdn __P((const struct addrinfo *, const char *,
176	const char *, struct addrinfo **));
177static int explore_copy __P((const struct addrinfo *, const struct addrinfo *,
178	struct addrinfo **));
179static int explore_null __P((const struct addrinfo *,
180	const char *, struct addrinfo **));
181static int explore_numeric __P((const struct addrinfo *, const char *,
182	const char *, struct addrinfo **));
183static int explore_numeric_scope __P((const struct addrinfo *, const char *,
184	const char *, struct addrinfo **));
185static int get_canonname __P((const struct addrinfo *,
186	struct addrinfo *, const char *));
187static struct addrinfo *get_ai __P((const struct addrinfo *,
188	const struct afd *, const char *));
189static struct addrinfo *copy_ai __P((const struct addrinfo *));
190static int get_portmatch __P((const struct addrinfo *, const char *));
191static int get_port __P((const struct addrinfo *, const char *, int));
192static const struct afd *find_afd __P((int));
193static int addrconfig __P((int));
194static int ip6_str2scopeid __P((char *, struct sockaddr_in6 *,
195				u_int32_t *scopeidp));
196static struct net_data *init __P((void));
197
198struct addrinfo *hostent2addrinfo __P((struct hostent *,
199				       const struct addrinfo *));
200struct addrinfo *addr2addrinfo __P((const struct addrinfo *,
201				    const char *));
202
203#if 0
204static const char *ai_errlist[] = {
205	"Success",
206	"Address family for hostname not supported",	/*%< EAI_ADDRFAMILY */
207	"Temporary failure in name resolution",		/*%< EAI_AGAIN */
208	"Invalid value for ai_flags",		       	/*%< EAI_BADFLAGS */
209	"Non-recoverable failure in name resolution", 	/*%< EAI_FAIL */
210	"ai_family not supported",			/*%< EAI_FAMILY */
211	"Memory allocation failure", 			/*%< EAI_MEMORY */
212	"No address associated with hostname", 		/*%< EAI_NODATA */
213	"hostname nor servname provided, or not known",	/*%< EAI_NONAME */
214	"servname not supported for ai_socktype",	/*%< EAI_SERVICE */
215	"ai_socktype not supported", 			/*%< EAI_SOCKTYPE */
216	"System error returned in errno", 		/*%< EAI_SYSTEM */
217	"Invalid value for hints",			/*%< EAI_BADHINTS */
218	"Resolved protocol is unknown",			/*%< EAI_PROTOCOL */
219	"Unknown error", 				/*%< EAI_MAX */
220};
221#endif
222
223/* XXX macros that make external reference is BAD. */
224
225#define GET_AI(ai, afd, addr) \
226do { \
227	/* external reference: pai, error, and label free */ \
228	(ai) = get_ai(pai, (afd), (addr)); \
229	if ((ai) == NULL) { \
230		error = EAI_MEMORY; \
231		goto free; \
232	} \
233} while (/*CONSTCOND*/0)
234
235#define GET_PORT(ai, serv) \
236do { \
237	/* external reference: error and label free */ \
238	error = get_port((ai), (serv), 0); \
239	if (error != 0) \
240		goto free; \
241} while (/*CONSTCOND*/0)
242
243#define GET_CANONNAME(ai, str) \
244do { \
245	/* external reference: pai, error and label free */ \
246	error = get_canonname(pai, (ai), (str)); \
247	if (error != 0) \
248		goto free; \
249} while (/*CONSTCOND*/0)
250
251#ifndef SOLARIS2
252#define SETERROR(err) \
253do { \
254	/* external reference: error, and label bad */ \
255	error = (err); \
256	goto bad; \
257	/*NOTREACHED*/ \
258} while (/*CONSTCOND*/0)
259#else
260#define SETERROR(err) \
261do { \
262	/* external reference: error, and label bad */ \
263	error = (err); \
264	if (error == error) \
265		goto bad; \
266} while (/*CONSTCOND*/0)
267#endif
268
269
270#define MATCH_FAMILY(x, y, w) \
271	((x) == (y) || (/*CONSTCOND*/(w) && ((x) == PF_UNSPEC || (y) == PF_UNSPEC)))
272#define MATCH(x, y, w) \
273	((x) == (y) || (/*CONSTCOND*/(w) && ((x) == ANY || (y) == ANY)))
274
275#if 0				/*%< bind8 has its own version */
276char *
277gai_strerror(ecode)
278	int ecode;
279{
280	if (ecode < 0 || ecode > EAI_MAX)
281		ecode = EAI_MAX;
282	return ai_errlist[ecode];
283}
284#endif
285
286void
287freeaddrinfo(ai)
288	struct addrinfo *ai;
289{
290	struct addrinfo *next;
291
292	do {
293		next = ai->ai_next;
294		if (ai->ai_canonname)
295			free(ai->ai_canonname);
296		/* no need to free(ai->ai_addr) */
297		free(ai);
298		ai = next;
299	} while (ai);
300}
301
302static int
303str_isnumber(p)
304	const char *p;
305{
306	char *ep;
307
308	if (*p == '\0')
309		return NO;
310	ep = NULL;
311	errno = 0;
312	(void)strtoul(p, &ep, 10);
313	if (errno == 0 && ep && *ep == '\0')
314		return YES;
315	else
316		return NO;
317}
318
319int
320getaddrinfo(hostname, servname, hints, res)
321	const char *hostname, *servname;
322	const struct addrinfo *hints;
323	struct addrinfo **res;
324{
325	struct addrinfo sentinel;
326	struct addrinfo *cur;
327	int error = 0;
328	struct addrinfo ai, ai0, *afai = NULL;
329	struct addrinfo *pai;
330	const struct explore *ex;
331
332	memset(&sentinel, 0, sizeof(sentinel));
333	cur = &sentinel;
334	pai = &ai;
335	pai->ai_flags = 0;
336	pai->ai_family = PF_UNSPEC;
337	pai->ai_socktype = ANY;
338	pai->ai_protocol = ANY;
339#if defined(sun) && defined(_SOCKLEN_T) && defined(__sparcv9)
340	/*
341	 * clear _ai_pad to preserve binary
342	 * compatibility with previously compiled 64-bit
343	 * applications in a pre-SUSv3 environment by
344	 * guaranteeing the upper 32-bits are empty.
345	 */
346	pai->_ai_pad = 0;
347#endif
348	pai->ai_addrlen = 0;
349	pai->ai_canonname = NULL;
350	pai->ai_addr = NULL;
351	pai->ai_next = NULL;
352
353	if (hostname == NULL && servname == NULL)
354		return EAI_NONAME;
355	if (hints) {
356		/* error check for hints */
357		if (hints->ai_addrlen || hints->ai_canonname ||
358		    hints->ai_addr || hints->ai_next)
359			SETERROR(EAI_BADHINTS); /*%< xxx */
360		if (hints->ai_flags & ~AI_MASK)
361			SETERROR(EAI_BADFLAGS);
362		switch (hints->ai_family) {
363		case PF_UNSPEC:
364		case PF_INET:
365		case PF_INET6:
366			break;
367		default:
368			SETERROR(EAI_FAMILY);
369		}
370		memcpy(pai, hints, sizeof(*pai));
371
372#if defined(sun) && defined(_SOCKLEN_T) && defined(__sparcv9)
373		/*
374		 * We need to clear _ai_pad to preserve binary
375		 * compatibility.  See prior comment.
376		 */
377		pai->_ai_pad = 0;
378#endif
379		/*
380		 * if both socktype/protocol are specified, check if they
381		 * are meaningful combination.
382		 */
383		if (pai->ai_socktype != ANY && pai->ai_protocol != ANY) {
384			for (ex = explore; ex->e_af >= 0; ex++) {
385				if (pai->ai_family != ex->e_af)
386					continue;
387				if (ex->e_socktype == ANY)
388					continue;
389				if (ex->e_protocol == ANY)
390					continue;
391				if (pai->ai_socktype == ex->e_socktype &&
392				    pai->ai_protocol != ex->e_protocol) {
393					SETERROR(EAI_BADHINTS);
394				}
395			}
396		}
397	}
398
399	/*
400	 * post-2553: AI_ALL and AI_V4MAPPED are effective only against
401	 * AF_INET6 query.  They needs to be ignored if specified in other
402	 * occassions.
403	 */
404	switch (pai->ai_flags & (AI_ALL | AI_V4MAPPED)) {
405	case AI_V4MAPPED:
406	case AI_ALL | AI_V4MAPPED:
407		if (pai->ai_family != AF_INET6)
408			pai->ai_flags &= ~(AI_ALL | AI_V4MAPPED);
409		break;
410	case AI_ALL:
411#if 1
412		/* illegal */
413		SETERROR(EAI_BADFLAGS);
414#else
415		pai->ai_flags &= ~(AI_ALL | AI_V4MAPPED);
416		break;
417#endif
418	}
419
420	/*
421	 * check for special cases.  (1) numeric servname is disallowed if
422	 * socktype/protocol are left unspecified. (2) servname is disallowed
423	 * for raw and other inet{,6} sockets.
424	 */
425	if (MATCH_FAMILY(pai->ai_family, PF_INET, 1)
426#ifdef PF_INET6
427	 || MATCH_FAMILY(pai->ai_family, PF_INET6, 1)
428#endif
429	    ) {
430		ai0 = *pai;	/* backup *pai */
431
432		if (pai->ai_family == PF_UNSPEC) {
433#ifdef PF_INET6
434			pai->ai_family = PF_INET6;
435#else
436			pai->ai_family = PF_INET;
437#endif
438		}
439		error = get_portmatch(pai, servname);
440		if (error)
441			SETERROR(error);
442
443		*pai = ai0;
444	}
445
446	ai0 = *pai;
447
448	/* NULL hostname, or numeric hostname */
449	for (ex = explore; ex->e_af >= 0; ex++) {
450		*pai = ai0;
451
452		if (!MATCH_FAMILY(pai->ai_family, ex->e_af, WILD_AF(ex)))
453			continue;
454		if (!MATCH(pai->ai_socktype, ex->e_socktype, WILD_SOCKTYPE(ex)))
455			continue;
456		if (!MATCH(pai->ai_protocol, ex->e_protocol, WILD_PROTOCOL(ex)))
457			continue;
458
459		if (pai->ai_family == PF_UNSPEC)
460			pai->ai_family = ex->e_af;
461		if (pai->ai_socktype == ANY && ex->e_socktype != ANY)
462			pai->ai_socktype = ex->e_socktype;
463		if (pai->ai_protocol == ANY && ex->e_protocol != ANY)
464			pai->ai_protocol = ex->e_protocol;
465
466		/*
467		 * if the servname does not match socktype/protocol, ignore it.
468		 */
469		if (get_portmatch(pai, servname) != 0)
470			continue;
471
472		if (hostname == NULL) {
473			/*
474			 * filter out AFs that are not supported by the kernel
475			 * XXX errno?
476			 */
477			if (!addrconfig(pai->ai_family))
478				continue;
479			error = explore_null(pai, servname, &cur->ai_next);
480		} else
481			error = explore_numeric_scope(pai, hostname, servname,
482			    &cur->ai_next);
483
484		if (error)
485			goto free;
486
487		while (cur && cur->ai_next)
488			cur = cur->ai_next;
489	}
490
491	/*
492	 * XXX
493	 * If numreic representation of AF1 can be interpreted as FQDN
494	 * representation of AF2, we need to think again about the code below.
495	 */
496	if (sentinel.ai_next)
497		goto good;
498
499	if (pai->ai_flags & AI_NUMERICHOST)
500		SETERROR(EAI_NONAME);
501	if (hostname == NULL)
502		SETERROR(EAI_NONAME);
503
504	/*
505	 * hostname as alphabetical name.
506	 * We'll make sure that
507	 * - if returning addrinfo list is empty, return non-zero error
508	 *   value (already known one or EAI_NONAME).
509	 * - otherwise,
510	 *   + if we haven't had any errors, return 0 (i.e. success).
511	 *   + if we've had an error, free the list and return the error.
512	 * without any assumption on the behavior of explore_fqdn().
513	 */
514
515	/* first, try to query DNS for all possible address families. */
516	*pai = ai0;
517	error = explore_fqdn(pai, hostname, servname, &afai);
518	if (error) {
519		if (afai != NULL)
520			freeaddrinfo(afai);
521		goto free;
522	}
523	if (afai == NULL) {
524		error = EAI_NONAME; /*%< we've had no errors. */
525		goto free;
526	}
527
528	/*
529	 * we would like to prefer AF_INET6 than AF_INET, so we'll make an
530	 * outer loop by AFs.
531	 */
532	for (ex = explore; ex->e_af >= 0; ex++) {
533		*pai = ai0;
534
535		if (pai->ai_family == PF_UNSPEC)
536			pai->ai_family = ex->e_af;
537
538		if (!MATCH_FAMILY(pai->ai_family, ex->e_af, WILD_AF(ex)))
539			continue;
540		if (!MATCH(pai->ai_socktype, ex->e_socktype,
541			   WILD_SOCKTYPE(ex))) {
542			continue;
543		}
544		if (!MATCH(pai->ai_protocol, ex->e_protocol,
545			   WILD_PROTOCOL(ex))) {
546			continue;
547		}
548
549#ifdef AI_ADDRCONFIG
550		/*
551		 * If AI_ADDRCONFIG is specified, check if we are
552		 * expected to return the address family or not.
553		 */
554		if ((pai->ai_flags & AI_ADDRCONFIG) != 0 &&
555		    !addrconfig(pai->ai_family))
556			continue;
557#endif
558
559		if (pai->ai_family == PF_UNSPEC)
560			pai->ai_family = ex->e_af;
561		if (pai->ai_socktype == ANY && ex->e_socktype != ANY)
562			pai->ai_socktype = ex->e_socktype;
563		if (pai->ai_protocol == ANY && ex->e_protocol != ANY)
564			pai->ai_protocol = ex->e_protocol;
565
566		/*
567		 * if the servname does not match socktype/protocol, ignore it.
568		 */
569		if (get_portmatch(pai, servname) != 0)
570			continue;
571
572		if ((error = explore_copy(pai, afai, &cur->ai_next)) != 0) {
573			freeaddrinfo(afai);
574			goto free;
575		}
576
577		while (cur && cur->ai_next)
578			cur = cur->ai_next;
579	}
580
581	freeaddrinfo(afai);	/*%< afai must not be NULL at this point. */
582
583	if (sentinel.ai_next) {
584good:
585		*res = sentinel.ai_next;
586		return(SUCCESS);
587	} else {
588		/*
589		 * All the process succeeded, but we've had an empty list.
590		 * This can happen if the given hints do not match our
591		 * candidates.
592		 */
593		error = EAI_NONAME;
594	}
595
596free:
597bad:
598	if (sentinel.ai_next)
599		freeaddrinfo(sentinel.ai_next);
600	*res = NULL;
601	return(error);
602}
603
604/*%
605 * FQDN hostname, DNS lookup
606 */
607static int
608explore_fqdn(pai, hostname, servname, res)
609	const struct addrinfo *pai;
610	const char *hostname;
611	const char *servname;
612	struct addrinfo **res;
613{
614	struct addrinfo *result;
615	struct addrinfo *cur;
616	struct net_data *net_data = init();
617	struct irs_ho *ho;
618	int error = 0;
619	char tmp[NS_MAXDNAME];
620	const char *cp;
621
622	INSIST(res != NULL && *res == NULL);
623
624	/*
625	 * if the servname does not match socktype/protocol, ignore it.
626	 */
627	if (get_portmatch(pai, servname) != 0)
628		return(0);
629
630	if (!net_data || !(ho = net_data->ho))
631		return(0);
632#if 0				/*%< XXX (notyet) */
633	if (net_data->ho_stayopen && net_data->ho_last &&
634	    net_data->ho_last->h_addrtype == af) {
635		if (ns_samename(name, net_data->ho_last->h_name) == 1)
636			return (net_data->ho_last);
637		for (hap = net_data->ho_last->h_aliases; hap && *hap; hap++)
638			if (ns_samename(name, *hap) == 1)
639				return (net_data->ho_last);
640	}
641#endif
642	if (!strchr(hostname, '.') &&
643	    (cp = res_hostalias(net_data->res, hostname,
644				tmp, sizeof(tmp))))
645		hostname = cp;
646	result = (*ho->addrinfo)(ho, hostname, pai);
647	if (!net_data->ho_stayopen) {
648		(*ho->minimize)(ho);
649	}
650	if (result == NULL) {
651		int e = h_errno;
652
653		switch(e) {
654		case NETDB_INTERNAL:
655			error = EAI_SYSTEM;
656			break;
657		case TRY_AGAIN:
658			error = EAI_AGAIN;
659			break;
660		case NO_RECOVERY:
661			error = EAI_FAIL;
662			break;
663		case HOST_NOT_FOUND:
664		case NO_DATA:
665			error = EAI_NONAME;
666			break;
667		default:
668		case NETDB_SUCCESS: /*%< should be impossible... */
669			error = EAI_NONAME;
670			break;
671		}
672		goto free;
673	}
674
675	for (cur = result; cur; cur = cur->ai_next) {
676		GET_PORT(cur, servname); /*%< XXX: redundant lookups... */
677		/* canonname should already be filled. */
678	}
679
680	*res = result;
681
682	return(0);
683
684free:
685	if (result)
686		freeaddrinfo(result);
687	return error;
688}
689
690static int
691explore_copy(pai, src0, res)
692	const struct addrinfo *pai;	/*%< seed */
693	const struct addrinfo *src0;	/*%< source */
694	struct addrinfo **res;
695{
696	int error;
697	struct addrinfo sentinel, *cur;
698	const struct addrinfo *src;
699
700	error = 0;
701	sentinel.ai_next = NULL;
702	cur = &sentinel;
703
704	for (src = src0; src != NULL; src = src->ai_next) {
705		if (src->ai_family != pai->ai_family)
706			continue;
707
708		cur->ai_next = copy_ai(src);
709		if (!cur->ai_next) {
710			error = EAI_MEMORY;
711			goto fail;
712		}
713
714		cur->ai_next->ai_socktype = pai->ai_socktype;
715		cur->ai_next->ai_protocol = pai->ai_protocol;
716		cur = cur->ai_next;
717	}
718
719	*res = sentinel.ai_next;
720	return 0;
721
722fail:
723	freeaddrinfo(sentinel.ai_next);
724	return error;
725}
726
727/*%
728 * hostname == NULL.
729 * passive socket -> anyaddr (0.0.0.0 or ::)
730 * non-passive socket -> localhost (127.0.0.1 or ::1)
731 */
732static int
733explore_null(pai, servname, res)
734	const struct addrinfo *pai;
735	const char *servname;
736	struct addrinfo **res;
737{
738	const struct afd *afd;
739	struct addrinfo *cur;
740	struct addrinfo sentinel;
741	int error;
742
743	*res = NULL;
744	sentinel.ai_next = NULL;
745	cur = &sentinel;
746
747	afd = find_afd(pai->ai_family);
748	if (afd == NULL)
749		return 0;
750
751	if (pai->ai_flags & AI_PASSIVE) {
752		GET_AI(cur->ai_next, afd, afd->a_addrany);
753		/* xxx meaningless?
754		 * GET_CANONNAME(cur->ai_next, "anyaddr");
755		 */
756		GET_PORT(cur->ai_next, servname);
757	} else {
758		GET_AI(cur->ai_next, afd, afd->a_loopback);
759		/* xxx meaningless?
760		 * GET_CANONNAME(cur->ai_next, "localhost");
761		 */
762		GET_PORT(cur->ai_next, servname);
763	}
764	cur = cur->ai_next;
765
766	*res = sentinel.ai_next;
767	return 0;
768
769free:
770	if (sentinel.ai_next)
771		freeaddrinfo(sentinel.ai_next);
772	return error;
773}
774
775/*%
776 * numeric hostname
777 */
778static int
779explore_numeric(pai, hostname, servname, res)
780	const struct addrinfo *pai;
781	const char *hostname;
782	const char *servname;
783	struct addrinfo **res;
784{
785	const struct afd *afd;
786	struct addrinfo *cur;
787	struct addrinfo sentinel;
788	int error;
789	char pton[PTON_MAX];
790
791	*res = NULL;
792	sentinel.ai_next = NULL;
793	cur = &sentinel;
794
795	afd = find_afd(pai->ai_family);
796	if (afd == NULL)
797		return 0;
798
799	switch (afd->a_af) {
800#if 0 /*X/Open spec*/
801	case AF_INET:
802		if (inet_aton(hostname, (struct in_addr *)pton) == 1) {
803			if (pai->ai_family == afd->a_af ||
804			    pai->ai_family == PF_UNSPEC /*?*/) {
805				GET_AI(cur->ai_next, afd, pton);
806				GET_PORT(cur->ai_next, servname);
807				while (cur->ai_next)
808					cur = cur->ai_next;
809			} else
810				SETERROR(EAI_FAMILY);	/*xxx*/
811		}
812		break;
813#endif
814	default:
815		if (inet_pton(afd->a_af, hostname, pton) == 1) {
816			if (pai->ai_family == afd->a_af ||
817			    pai->ai_family == PF_UNSPEC /*?*/) {
818				GET_AI(cur->ai_next, afd, pton);
819				GET_PORT(cur->ai_next, servname);
820				while (cur->ai_next)
821					cur = cur->ai_next;
822			} else
823				SETERROR(EAI_FAMILY);	/*xxx*/
824		}
825		break;
826	}
827
828	*res = sentinel.ai_next;
829	return 0;
830
831free:
832bad:
833	if (sentinel.ai_next)
834		freeaddrinfo(sentinel.ai_next);
835	return error;
836}
837
838/*%
839 * numeric hostname with scope
840 */
841static int
842explore_numeric_scope(pai, hostname, servname, res)
843	const struct addrinfo *pai;
844	const char *hostname;
845	const char *servname;
846	struct addrinfo **res;
847{
848#ifndef SCOPE_DELIMITER
849	return explore_numeric(pai, hostname, servname, res);
850#else
851	const struct afd *afd;
852	struct addrinfo *cur;
853	int error;
854	char *cp, *hostname2 = NULL, *scope, *addr;
855	struct sockaddr_in6 *sin6;
856
857	afd = find_afd(pai->ai_family);
858	if (afd == NULL)
859		return 0;
860
861	if (!afd->a_scoped)
862		return explore_numeric(pai, hostname, servname, res);
863
864	cp = strchr(hostname, SCOPE_DELIMITER);
865	if (cp == NULL)
866		return explore_numeric(pai, hostname, servname, res);
867
868	/*
869	 * Handle special case of <scoped_address><delimiter><scope id>
870	 */
871	hostname2 = strdup(hostname);
872	if (hostname2 == NULL)
873		return EAI_MEMORY;
874	/* terminate at the delimiter */
875	hostname2[cp - hostname] = '\0';
876	addr = hostname2;
877	scope = cp + 1;
878
879	error = explore_numeric(pai, addr, servname, res);
880	if (error == 0) {
881		u_int32_t scopeid = 0;
882
883		for (cur = *res; cur; cur = cur->ai_next) {
884			if (cur->ai_family != AF_INET6)
885				continue;
886			sin6 = (struct sockaddr_in6 *)(void *)cur->ai_addr;
887			if (!ip6_str2scopeid(scope, sin6, &scopeid)) {
888				free(hostname2);
889				return(EAI_NONAME); /*%< XXX: is return OK? */
890			}
891#ifdef HAVE_SIN6_SCOPE_ID
892			sin6->sin6_scope_id = scopeid;
893#endif
894		}
895	}
896
897	free(hostname2);
898
899	return error;
900#endif
901}
902
903static int
904get_canonname(pai, ai, str)
905	const struct addrinfo *pai;
906	struct addrinfo *ai;
907	const char *str;
908{
909	if ((pai->ai_flags & AI_CANONNAME) != 0) {
910		ai->ai_canonname = (char *)malloc(strlen(str) + 1);
911		if (ai->ai_canonname == NULL)
912			return EAI_MEMORY;
913		strcpy(ai->ai_canonname, str);
914	}
915	return 0;
916}
917
918static struct addrinfo *
919get_ai(pai, afd, addr)
920	const struct addrinfo *pai;
921	const struct afd *afd;
922	const char *addr;
923{
924	char *p;
925	struct addrinfo *ai;
926
927	ai = (struct addrinfo *)malloc(sizeof(struct addrinfo)
928		+ (afd->a_socklen));
929	if (ai == NULL)
930		return NULL;
931
932	memcpy(ai, pai, sizeof(struct addrinfo));
933	ai->ai_addr = (struct sockaddr *)(void *)(ai + 1);
934	memset(ai->ai_addr, 0, (size_t)afd->a_socklen);
935#ifdef HAVE_SA_LEN
936	ai->ai_addr->sa_len = afd->a_socklen;
937#endif
938	ai->ai_addrlen = afd->a_socklen;
939	ai->ai_addr->sa_family = ai->ai_family = afd->a_af;
940	p = (char *)(void *)(ai->ai_addr);
941	memcpy(p + afd->a_off, addr, (size_t)afd->a_addrlen);
942	return ai;
943}
944
945/* XXX need to malloc() the same way we do from other functions! */
946static struct addrinfo *
947copy_ai(pai)
948	const struct addrinfo *pai;
949{
950	struct addrinfo *ai;
951	size_t l;
952
953	l = sizeof(*ai) + pai->ai_addrlen;
954	if ((ai = (struct addrinfo *)malloc(l)) == NULL)
955		return NULL;
956	memset(ai, 0, l);
957	memcpy(ai, pai, sizeof(*ai));
958	ai->ai_addr = (struct sockaddr *)(void *)(ai + 1);
959	memcpy(ai->ai_addr, pai->ai_addr, pai->ai_addrlen);
960
961	if (pai->ai_canonname) {
962		l = strlen(pai->ai_canonname) + 1;
963		if ((ai->ai_canonname = malloc(l)) == NULL) {
964			free(ai);
965			return NULL;
966		}
967		strcpy(ai->ai_canonname, pai->ai_canonname);	/* (checked) */
968	} else {
969		/* just to make sure */
970		ai->ai_canonname = NULL;
971	}
972
973	ai->ai_next = NULL;
974
975	return ai;
976}
977
978static int
979get_portmatch(const struct addrinfo *ai, const char *servname) {
980
981	/* get_port does not touch first argument. when matchonly == 1. */
982	/* LINTED const cast */
983	return get_port((const struct addrinfo *)ai, servname, 1);
984}
985
986static int
987get_port(const struct addrinfo *ai, const char *servname, int matchonly) {
988	const char *proto;
989	struct servent *sp;
990	int port;
991	int allownumeric;
992
993	if (servname == NULL)
994		return 0;
995	switch (ai->ai_family) {
996	case AF_INET:
997#ifdef AF_INET6
998	case AF_INET6:
999#endif
1000		break;
1001	default:
1002		return 0;
1003	}
1004
1005	switch (ai->ai_socktype) {
1006	case SOCK_RAW:
1007		return EAI_SERVICE;
1008	case SOCK_DGRAM:
1009	case SOCK_STREAM:
1010		allownumeric = 1;
1011		break;
1012	case ANY:
1013		switch (ai->ai_family) {
1014		case AF_INET:
1015#ifdef AF_INET6
1016		case AF_INET6:
1017#endif
1018			allownumeric = 1;
1019			break;
1020		default:
1021			allownumeric = 0;
1022			break;
1023		}
1024		break;
1025	default:
1026		return EAI_SOCKTYPE;
1027	}
1028
1029	if (str_isnumber(servname)) {
1030		if (!allownumeric)
1031			return EAI_SERVICE;
1032		port = atoi(servname);
1033		if (port < 0 || port > 65535)
1034			return EAI_SERVICE;
1035		port = htons(port);
1036	} else {
1037		switch (ai->ai_socktype) {
1038		case SOCK_DGRAM:
1039			proto = "udp";
1040			break;
1041		case SOCK_STREAM:
1042			proto = "tcp";
1043			break;
1044		default:
1045			proto = NULL;
1046			break;
1047		}
1048
1049		if ((sp = getservbyname(servname, proto)) == NULL)
1050			return EAI_SERVICE;
1051		port = sp->s_port;
1052	}
1053
1054	if (!matchonly) {
1055		switch (ai->ai_family) {
1056		case AF_INET:
1057			((struct sockaddr_in *)(void *)
1058			    ai->ai_addr)->sin_port = port;
1059			break;
1060		case AF_INET6:
1061			((struct sockaddr_in6 *)(void *)
1062			    ai->ai_addr)->sin6_port = port;
1063			break;
1064		}
1065	}
1066
1067	return 0;
1068}
1069
1070static const struct afd *
1071find_afd(af)
1072	int af;
1073{
1074	const struct afd *afd;
1075
1076	if (af == PF_UNSPEC)
1077		return NULL;
1078	for (afd = afdl; afd->a_af; afd++) {
1079		if (afd->a_af == af)
1080			return afd;
1081	}
1082	return NULL;
1083}
1084
1085/*%
1086 * post-2553: AI_ADDRCONFIG check.  if we use getipnodeby* as backend, backend
1087 * will take care of it.
1088 * the semantics of AI_ADDRCONFIG is not defined well.  we are not sure
1089 * if the code is right or not.
1090 */
1091static int
1092addrconfig(af)
1093	int af;
1094{
1095	int s;
1096
1097	/* XXX errno */
1098	s = socket(af, SOCK_DGRAM, 0);
1099	if (s < 0) {
1100		if (errno != EMFILE)
1101			return 0;
1102	} else
1103		close(s);
1104	return 1;
1105}
1106
1107/* convert a string to a scope identifier. XXX: IPv6 specific */
1108static int
1109ip6_str2scopeid(char *scope, struct sockaddr_in6 *sin6,
1110		u_int32_t *scopeidp)
1111{
1112	u_int32_t scopeid;
1113	u_long lscopeid;
1114	struct in6_addr *a6 = &sin6->sin6_addr;
1115	char *ep;
1116
1117	/* empty scopeid portion is invalid */
1118	if (*scope == '\0')
1119		return (0);
1120
1121#ifdef USE_IFNAMELINKID
1122	if (IN6_IS_ADDR_LINKLOCAL(a6) || IN6_IS_ADDR_MC_LINKLOCAL(a6) ||
1123	    IN6_IS_ADDR_MC_NODELOCAL(a6)) {
1124		/*
1125		 * Using interface names as link indices can be allowed
1126		 * only when we can assume a one-to-one mappings between
1127		 * links and interfaces.  See comments in getnameinfo.c.
1128		 */
1129		scopeid = if_nametoindex(scope);
1130		if (scopeid == 0)
1131			goto trynumeric;
1132		*scopeidp = scopeid;
1133		return (1);
1134	}
1135#endif
1136
1137	/* still unclear about literal, allow numeric only - placeholder */
1138	if (IN6_IS_ADDR_SITELOCAL(a6) || IN6_IS_ADDR_MC_SITELOCAL(a6))
1139		goto trynumeric;
1140	if (IN6_IS_ADDR_MC_ORGLOCAL(a6))
1141		goto trynumeric;
1142	else
1143		goto trynumeric;	/*%< global */
1144	/* try to convert to a numeric id as a last resort */
1145trynumeric:
1146	errno = 0;
1147	lscopeid = strtoul(scope, &ep, 10);
1148	scopeid = lscopeid & 0xffffffff;
1149	if (errno == 0 && ep && *ep == '\0' && scopeid == lscopeid) {
1150		*scopeidp = scopeid;
1151		return (1);
1152	} else
1153		return (0);
1154}
1155
1156struct addrinfo *
1157hostent2addrinfo(hp, pai)
1158	struct hostent *hp;
1159	const struct addrinfo *pai;
1160{
1161	int i, af, error = 0;
1162	char **aplist = NULL, *ap;
1163	struct addrinfo sentinel, *cur;
1164	const struct afd *afd;
1165
1166	af = hp->h_addrtype;
1167	if (pai->ai_family != AF_UNSPEC && af != pai->ai_family)
1168		return(NULL);
1169
1170	afd = find_afd(af);
1171	if (afd == NULL)
1172		return(NULL);
1173
1174	aplist = hp->h_addr_list;
1175
1176	memset(&sentinel, 0, sizeof(sentinel));
1177	cur = &sentinel;
1178
1179	for (i = 0; (ap = aplist[i]) != NULL; i++) {
1180#if 0				/*%< the trick seems too much */
1181		af = hp->h_addr_list;
1182		if (af == AF_INET6 &&
1183		    IN6_IS_ADDR_V4MAPPED((struct in6_addr *)ap)) {
1184			af = AF_INET;
1185			ap = ap + sizeof(struct in6_addr)
1186				- sizeof(struct in_addr);
1187		}
1188		afd = find_afd(af);
1189		if (afd == NULL)
1190			continue;
1191#endif /* 0 */
1192
1193		GET_AI(cur->ai_next, afd, ap);
1194
1195		/* GET_PORT(cur->ai_next, servname); */
1196		if ((pai->ai_flags & AI_CANONNAME) != 0) {
1197			/*
1198			 * RFC2553 says that ai_canonname will be set only for
1199			 * the first element.  we do it for all the elements,
1200			 * just for convenience.
1201			 */
1202			GET_CANONNAME(cur->ai_next, hp->h_name);
1203		}
1204		while (cur->ai_next) /*%< no need to loop, actually. */
1205			cur = cur->ai_next;
1206		continue;
1207
1208	free:
1209		if (cur->ai_next)
1210			freeaddrinfo(cur->ai_next);
1211		cur->ai_next = NULL;
1212		/* continue, without tht pointer CUR advanced. */
1213	}
1214
1215	return(sentinel.ai_next);
1216}
1217
1218struct addrinfo *
1219addr2addrinfo(pai, cp)
1220	const struct addrinfo *pai;
1221	const char *cp;
1222{
1223	const struct afd *afd;
1224
1225	afd = find_afd(pai->ai_family);
1226	if (afd == NULL)
1227		return(NULL);
1228
1229	return(get_ai(pai, afd, cp));
1230}
1231
1232static struct net_data *
1233init()
1234{
1235	struct net_data *net_data;
1236
1237	if (!(net_data = net_data_init(NULL)))
1238		goto error;
1239	if (!net_data->ho) {
1240		net_data->ho = (*net_data->irs->ho_map)(net_data->irs);
1241		if (!net_data->ho || !net_data->res) {
1242error:
1243			errno = EIO;
1244			if (net_data && net_data->res)
1245				RES_SET_H_ERRNO(net_data->res, NETDB_INTERNAL);
1246			return (NULL);
1247		}
1248
1249		(*net_data->ho->res_set)(net_data->ho, net_data->res, NULL);
1250	}
1251
1252	return (net_data);
1253}
1254