xref: /freebsd/lib/libc/net/getaddrinfo.c (revision 23f282aa31e9b6fceacd449020e936e98d6f2298)
1 /*
2  * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  * 3. Neither the name of the project nor the names of its contributors
14  *    may be used to endorse or promote products derived from this software
15  *    without specific prior written permission.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
18  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20  * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
21  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27  * SUCH DAMAGE.
28  *
29  * $FreeBSD$
30  */
31 
32 /*
33  * "#ifdef FAITH" part is local hack for supporting IPv4-v6 translator.
34  *
35  * Issues to be discussed:
36  * - Thread safe-ness must be checked.
37  * - Return values.  There are nonstandard return values defined and used
38  *   in the source code.  This is because RFC2553 is silent about which error
39  *   code must be returned for which situation.
40  * Note:
41  * - We use getipnodebyname() just for thread-safeness.  There's no intent
42  *   to let it do PF_UNSPEC (actually we never pass PF_UNSPEC to
43  *   getipnodebyname().
44  * - The code filters out AFs that are not supported by the kernel,
45  *   when globbing NULL hostname (to loopback, or wildcard).  Is it the right
46  *   thing to do?  What is the relationship with post-RFC2553 AI_ADDRCONFIG
47  *   in ai_flags?
48  */
49 
50 #include <sys/types.h>
51 #include <sys/param.h>
52 #include <sys/socket.h>
53 #include <net/if.h>
54 #include <netinet/in.h>
55 #include <arpa/inet.h>
56 #include <arpa/nameser.h>
57 #include <netdb.h>
58 #include <resolv.h>
59 #include <string.h>
60 #include <stdlib.h>
61 #include <stddef.h>
62 #include <ctype.h>
63 #include <unistd.h>
64 #include <stdio.h>
65 
66 #if defined(__KAME__) && defined(INET6)
67 # define FAITH
68 #endif
69 
70 #define	SUCCESS 0
71 #define	ANY 0
72 #define	YES 1
73 #define	NO  0
74 
75 static const char in_addrany[] = { 0, 0, 0, 0 };
76 static const char in6_addrany[] = {
77 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
78 };
79 static const char in_loopback[] = { 127, 0, 0, 1 };
80 static const char in6_loopback[] = {
81 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1
82 };
83 
84 static const struct afd {
85 	int a_af;
86 	int a_addrlen;
87 	int a_socklen;
88 	int a_off;
89 	const char *a_addrany;
90 	const char *a_loopback;
91 	int a_scoped;
92 } afdl [] = {
93 #ifdef INET6
94 #define	N_INET6 0
95 	{PF_INET6, sizeof(struct in6_addr),
96 	 sizeof(struct sockaddr_in6),
97 	 offsetof(struct sockaddr_in6, sin6_addr),
98 	 in6_addrany, in6_loopback, 1},
99 #define	N_INET 1
100 #else
101 #define	N_INET 0
102 #endif
103 	{PF_INET, sizeof(struct in_addr),
104 	 sizeof(struct sockaddr_in),
105 	 offsetof(struct sockaddr_in, sin_addr),
106 	 in_addrany, in_loopback, 0},
107 	{0, 0, 0, 0, NULL, NULL, 0},
108 };
109 
110 struct explore {
111 	int e_socktype;
112 	int e_protocol;
113 	const char *e_protostr;
114 	int e_wild;
115 #define	WILD_AF(ex)		((ex)->e_wild & 0x01)
116 #define	WILD_SOCKTYPE(ex)	((ex)->e_wild & 0x02)
117 #define	WILD_PROTOCOL(ex)	((ex)->e_wild & 0x04)
118 };
119 
120 static const struct explore explore[] = {
121 	{ SOCK_DGRAM, IPPROTO_UDP, "udp", 0x07 },
122 	{ SOCK_STREAM, IPPROTO_TCP, "tcp", 0x07 },
123 	{ SOCK_RAW, ANY, NULL, 0x05 },
124 	{ 0, 0, NULL, 0 },
125 };
126 
127 #ifdef INET6
128 #define	PTON_MAX	16
129 #else
130 #define	PTON_MAX	4
131 #endif
132 
133 extern struct	hostent * _getipnodebyname_multi __P((const char *name,
134 	int af, int flags, int *errp));
135 static int str_isnumber __P((const char *));
136 static int explore_fqdn __P((const struct addrinfo *, const char *,
137 	const char *, struct addrinfo **));
138 static int explore_null __P((const struct addrinfo *, const char *,
139 	const char *, struct addrinfo **));
140 static int explore_numeric __P((const struct addrinfo *, const char *,
141 	const char *, struct addrinfo **));
142 static int explore_numeric_scope __P((const struct addrinfo *, const char *,
143 	const char *, struct addrinfo **));
144 static int get_canonname __P((const struct addrinfo *,
145 	struct addrinfo *, const char *));
146 static struct addrinfo *get_ai __P((const struct addrinfo *,
147 	const struct afd *, const char *));
148 static int get_portmatch __P((const struct addrinfo *, const char *));
149 static int get_port __P((struct addrinfo *, const char *, int));
150 static const struct afd *find_afd __P((int));
151 
152 static char *ai_errlist[] = {
153 	"Success",
154 	"Address family for hostname not supported",	/* EAI_ADDRFAMILY */
155 	"Temporary failure in name resolution",		/* EAI_AGAIN      */
156 	"Invalid value for ai_flags",		       	/* EAI_BADFLAGS   */
157 	"Non-recoverable failure in name resolution", 	/* EAI_FAIL       */
158 	"ai_family not supported",			/* EAI_FAMILY     */
159 	"Memory allocation failure", 			/* EAI_MEMORY     */
160 	"No address associated with hostname", 		/* EAI_NODATA     */
161 	"hostname nor servname provided, or not known",	/* EAI_NONAME     */
162 	"servname not supported for ai_socktype",	/* EAI_SERVICE    */
163 	"ai_socktype not supported", 			/* EAI_SOCKTYPE   */
164 	"System error returned in errno", 		/* EAI_SYSTEM     */
165 	"Invalid value for hints",			/* EAI_BADHINTS	  */
166 	"Resolved protocol is unknown",			/* EAI_PROTOCOL   */
167 	"Argument res is NULL",				/* EAI_RESNULL	  */
168 	"Unknown error", 				/* EAI_MAX        */
169 };
170 
171 /* XXX macros that make external reference is BAD. */
172 
173 #define	GET_AI(ai, afd, addr) \
174 do { \
175 	/* external reference: pai, error, and label free */ \
176 	(ai) = get_ai(pai, (afd), (addr)); \
177 	if ((ai) == NULL) { \
178 		error = EAI_MEMORY; \
179 		goto free; \
180 	} \
181 } while (0)
182 
183 #define	GET_PORT(ai, serv) \
184 do { \
185 	/* external reference: error and label free */ \
186 	error = get_port((ai), (serv), 0); \
187 	if (error != 0) \
188 		goto free; \
189 } while (0)
190 
191 #define	GET_CANONNAME(ai, str) \
192 do { \
193 	/* external reference: pai, error and label free */ \
194 	error = get_canonname(pai, (ai), (str)); \
195 	if (error != 0) \
196 		goto free; \
197 } while (0)
198 
199 #define	ERR(err) \
200 do { \
201 	/* external reference: error, and label bad */ \
202 	error = (err); \
203 	goto bad; \
204 } while (0)
205 
206 #define	MATCH_FAMILY(x, y, w) \
207 	((x) == (y) || ((w) && ((x) == PF_UNSPEC || (y) == PF_UNSPEC)))
208 #define	MATCH(x, y, w) \
209 	((x) == (y) || ((w) && ((x) == ANY || (y) == ANY)))
210 
211 char *
212 gai_strerror(ecode)
213 	int ecode;
214 {
215 	if (ecode < 0 || ecode > EAI_MAX)
216 		ecode = EAI_MAX;
217 	return ai_errlist[ecode];
218 }
219 
220 void
221 freeaddrinfo(ai)
222 	struct addrinfo *ai;
223 {
224 	struct addrinfo *next;
225 
226 	do {
227 		next = ai->ai_next;
228 		if (ai->ai_canonname)
229 			free(ai->ai_canonname);
230 		/* no need to free(ai->ai_addr) */
231 		free(ai);
232 	} while ((ai = next) != NULL);
233 }
234 
235 static int
236 str_isnumber(p)
237 	const char *p;
238 {
239 	char *q = (char *)p;
240 	while (*q) {
241 		if (! isdigit(*q))
242 			return NO;
243 		q++;
244 	}
245 	return YES;
246 }
247 
248 int
249 getaddrinfo(hostname, servname, hints, res)
250 	const char *hostname, *servname;
251 	const struct addrinfo *hints;
252 	struct addrinfo **res;
253 {
254 	struct addrinfo sentinel;
255 	struct addrinfo *cur;
256 	int error = 0;
257 	struct addrinfo ai;
258 	struct addrinfo ai0;
259 	struct addrinfo *pai;
260 	const struct afd *afd;
261 	const struct explore *ex;
262 
263 	sentinel.ai_next = NULL;
264 	cur = &sentinel;
265 	pai = &ai;
266 	pai->ai_flags = 0;
267 	pai->ai_family = PF_UNSPEC;
268 	pai->ai_socktype = ANY;
269 	pai->ai_protocol = ANY;
270 	pai->ai_addrlen = 0;
271 	pai->ai_canonname = NULL;
272 	pai->ai_addr = NULL;
273 	pai->ai_next = NULL;
274 
275 	if (hostname == NULL && servname == NULL)
276 		return EAI_NONAME;
277 	if (res == NULL)
278 		return EAI_RESNULL; /* xxx */
279 	if (hints) {
280 		/* error check for hints */
281 		if (hints->ai_addrlen || hints->ai_canonname ||
282 		    hints->ai_addr || hints->ai_next)
283 			ERR(EAI_BADHINTS); /* xxx */
284 		if (hints->ai_flags & ~AI_MASK)
285 			ERR(EAI_BADFLAGS);
286 		switch (hints->ai_family) {
287 		case PF_UNSPEC:
288 		case PF_INET:
289 #ifdef INET6
290 		case PF_INET6:
291 #endif
292 			break;
293 		default:
294 			ERR(EAI_FAMILY);
295 		}
296 		memcpy(pai, hints, sizeof(*pai));
297 
298 		/*
299 		 * if both socktype/protocol are specified, check if they
300 		 * are meaningful combination.
301 		 */
302 		if (pai->ai_socktype != ANY && pai->ai_protocol != ANY) {
303 			int matched = 0;
304 
305 			for (ex = explore; ex->e_socktype; ex++) {
306 				if (ex->e_socktype == ANY)
307 					continue;
308 				if (ex->e_protocol == ANY)
309 					continue;
310 				if (pai->ai_socktype == ex->e_socktype
311 				 && pai->ai_protocol == ex->e_protocol)
312 					matched = 1;
313 				else
314 					continue;
315 				if (matched == 0)
316 					ERR(EAI_BADHINTS);
317 			}
318 		}
319 	}
320 
321 	/* backup original pai contents */
322 	ai0 = *pai;
323 
324 	/*
325 	 * special cases check for inet and inet6 sockets.
326 	 * (1) servname is disallowed for raw sockets.
327 	 * (2) numeric servname is disallowed if socktype/protocol is left
328 	 *     unspecified.
329 	 */
330 	if (MATCH_FAMILY(pai->ai_family, PF_INET, 1)
331 #ifdef INET6
332 	    || MATCH_FAMILY(pai->ai_family, PF_INET6, 1)
333 #endif
334 	    ) {
335 		*pai = ai0;
336 
337 		if (pai->ai_family == PF_UNSPEC)
338 #ifdef INET6
339 			pai->ai_family = PF_INET6;
340 #else
341 			pai->ai_family = PF_INET;
342 #endif
343 		error = get_portmatch(pai, servname);
344 		if (error)
345 			ERR(error);
346 	}
347 
348 	/* NULL hostname, or numeric hostname */
349 	for (afd = afdl; afd->a_af; afd++)
350       {
351 	for (ex = explore; ex->e_socktype; ex++) {
352 		*pai = ai0;
353 
354 		if (!MATCH_FAMILY(pai->ai_family, afd->a_af, WILD_AF(ex)))
355 			continue;
356 		if (!MATCH(pai->ai_socktype, ex->e_socktype, WILD_SOCKTYPE(ex)))
357 			continue;
358 		if (!MATCH(pai->ai_protocol, ex->e_protocol, WILD_PROTOCOL(ex)))
359 			continue;
360 
361 		if (pai->ai_family == PF_UNSPEC)
362 			pai->ai_family = afd->a_af;
363 		if (pai->ai_socktype == ANY && ex->e_socktype != ANY)
364 			pai->ai_socktype = ex->e_socktype;
365 		if (pai->ai_protocol == ANY && ex->e_protocol != ANY)
366 			pai->ai_protocol = ex->e_protocol;
367 
368 		if (hostname == NULL)
369 			error = explore_null(pai, hostname, servname, &cur->ai_next);
370 		else
371 			error = explore_numeric_scope(pai, hostname, servname, &cur->ai_next);
372 
373 		if (error)
374 			goto free;
375 
376 		while (cur && cur->ai_next)
377 			cur = cur->ai_next;
378 	}
379       }
380 
381 	/*
382 	 * XXX
383 	 * If numreic representation of AF1 can be interpreted as FQDN
384 	 * representation of AF2, we need to think again about the code below.
385 	 */
386 	if (sentinel.ai_next)
387 		goto good;
388 
389 	if (pai->ai_flags & AI_NUMERICHOST)
390 		ERR(EAI_NONAME);
391 	if (hostname == NULL)
392 		ERR(EAI_NONAME);
393 
394 	/* hostname as alphabetical name. */
395 	{
396 		for (ex = explore; ex->e_socktype; ex++) {
397 			*pai = ai0;
398 
399 			if (!MATCH(pai->ai_socktype, ex->e_socktype,
400 					WILD_SOCKTYPE(ex))) {
401 				continue;
402 			}
403 			if (!MATCH(pai->ai_protocol, ex->e_protocol,
404 					WILD_PROTOCOL(ex))) {
405 				continue;
406 			}
407 
408 			if (pai->ai_socktype == ANY && ex->e_socktype != ANY)
409 				pai->ai_socktype = ex->e_socktype;
410 			if (pai->ai_protocol == ANY && ex->e_protocol != ANY)
411 				pai->ai_protocol = ex->e_protocol;
412 
413 			error = explore_fqdn(pai, hostname, servname,
414 				&cur->ai_next);
415 
416 			while (cur && cur->ai_next)
417 				cur = cur->ai_next;
418 		}
419 	}
420 
421 	/* XXX: if any addrinfo found, SUCCESS return even if (error != 0) */
422 	if (sentinel.ai_next) {
423  good:
424 		*res = sentinel.ai_next;
425 		return SUCCESS;
426 	}
427 	/* else, failed */
428  free:
429  bad:
430 	if (error == 0)
431 		error = EAI_FAIL;
432 	if (sentinel.ai_next)
433 		freeaddrinfo(sentinel.ai_next);
434 	*res = NULL;
435 	return error;
436 }
437 
438 /*
439  * FQDN hostname, DNS lookup
440  */
441 static int
442 explore_fqdn(pai, hostname, servname, res)
443 	const struct addrinfo *pai;
444 	const char *hostname;
445 	const char *servname;
446 	struct addrinfo **res;
447 {
448 	struct hostent *hp;
449 	int h_error;
450 	int af;
451 	char *ap;
452 	struct addrinfo sentinel, *cur;
453 	int i;
454 	const struct afd *afd;
455 	int error;
456 
457 	*res = NULL;
458 	sentinel.ai_next = NULL;
459 	cur = &sentinel;
460 
461 	/*
462 	 * if the servname does not match socktype/protocol, ignore it.
463 	 */
464 	if (get_portmatch(pai, servname) != 0)
465 		return 0;
466 
467 	hp = _getipnodebyname_multi(hostname, pai->ai_family, AI_ADDRCONFIG,
468 				       &h_error);
469 	if (hp == NULL) {
470 		switch (h_error) {
471 		case HOST_NOT_FOUND:
472 		case NO_DATA:
473 			error = EAI_NODATA;
474 			break;
475 		case TRY_AGAIN:
476 			error = EAI_AGAIN;
477 			break;
478 		case NO_RECOVERY:
479 		case NETDB_INTERNAL:
480 		default:
481 			error = EAI_FAIL;
482 			break;
483 		}
484 	} else if ((hp->h_name == NULL) || (hp->h_name[0] == 0)
485 			|| (hp->h_addr_list[0] == NULL)) {
486 		freehostent(hp);
487 		hp = NULL;
488 		error = EAI_FAIL;
489 	}
490 
491 	if (hp == NULL)
492 		goto free;
493 
494 	for (i = 0; hp->h_addr_list[i] != NULL; i++) {
495 		af = hp->h_addrtype;
496 		ap = hp->h_addr_list[i];
497 
498 		if (pai->ai_family != AF_UNSPEC && af != pai->ai_family)
499 			continue;
500 
501 		afd = find_afd(af);
502 		if (afd == NULL)
503 			continue;
504 
505 		GET_AI(cur->ai_next, afd, ap);
506 		GET_PORT(cur->ai_next, servname);
507 		if ((pai->ai_flags & AI_CANONNAME) != 0) {
508 			/*
509 			 * RFC2553 says that ai_canonname will be set only for
510 			 * the first element.  we do it for all the elements,
511 			 * just for convenience.
512 			 */
513 			GET_CANONNAME(cur->ai_next, hp->h_name);
514 		}
515 
516 		while (cur && cur->ai_next)
517 			cur = cur->ai_next;
518 	}
519 
520 	*res = sentinel.ai_next;
521 	return 0;
522 
523 free:
524 	if (hp)
525 		freehostent(hp);
526 	if (sentinel.ai_next)
527 		freeaddrinfo(sentinel.ai_next);
528 	return error;
529 }
530 
531 /*
532  * hostname == NULL.
533  * passive socket -> anyaddr (0.0.0.0 or ::)
534  * non-passive socket -> localhost (127.0.0.1 or ::1)
535  */
536 static int
537 explore_null(pai, hostname, servname, res)
538 	const struct addrinfo *pai;
539 	const char *hostname;
540 	const char *servname;
541 	struct addrinfo **res;
542 {
543 	int s;
544 	const struct afd *afd;
545 	struct addrinfo *cur;
546 	struct addrinfo sentinel;
547 	int error;
548 
549 	*res = NULL;
550 	sentinel.ai_next = NULL;
551 	cur = &sentinel;
552 
553 	/*
554 	 * filter out AFs that are not supported by the kernel
555 	 * XXX errno?
556 	 */
557 	s = socket(pai->ai_family, SOCK_DGRAM, 0);
558 	if (s < 0)
559 		return 0;
560 	_close(s);
561 	afd = find_afd(pai->ai_family);
562 	if (afd == NULL)
563 		return 0;
564 
565 	GET_AI(cur->ai_next, afd,
566 	       (pai->ai_flags & AI_PASSIVE) ? afd->a_addrany : afd->a_loopback
567 	       );
568 	/* xxx meaningless?
569 	 * GET_CANONNAME(cur->ai_next, "anyaddr");
570 	 * or
571 	 * GET_CANONNAME(cur->ai_next, "localhost");
572 	 */
573 	/* if the servname does not match socktype/protocol, ignored */
574 	GET_PORT(cur->ai_next, servname);
575 
576 	*res = sentinel.ai_next;
577 	return 0;
578 
579 free:
580 	if (sentinel.ai_next)
581 		freeaddrinfo(sentinel.ai_next);
582 	return error;
583 }
584 
585 /*
586  * numeric hostname
587  */
588 static int
589 explore_numeric(pai, hostname, servname, res)
590 	const struct addrinfo *pai;
591 	const char *hostname;
592 	const char *servname;
593 	struct addrinfo **res;
594 {
595 	const struct afd *afd;
596 	struct addrinfo *cur;
597 	struct addrinfo sentinel;
598 	int error;
599 	char pton[PTON_MAX];
600 	int flags;
601 
602 	*res = NULL;
603 	sentinel.ai_next = NULL;
604 	cur = &sentinel;
605 
606 	/*
607 	 * if the servname does not match socktype/protocol, ignore it.
608 	 */
609 	if (get_portmatch(pai, servname) != 0)
610 		return 0;
611 
612 	afd = find_afd(pai->ai_family);
613 	if (afd == NULL)
614 		return 0;
615 	flags = pai->ai_flags;
616 
617 	if ((afd->a_af == AF_INET
618 	     ? inet_aton(hostname, (struct in_addr *)pton)
619 	     : inet_pton(afd->a_af, hostname, pton)) == 1) {
620 		if (pai->ai_family == afd->a_af ||
621 		    pai->ai_family == PF_UNSPEC /*?*/) {
622 			GET_AI(cur->ai_next, afd, pton);
623 			GET_PORT(cur->ai_next, servname);
624 			while (cur && cur->ai_next)
625 				cur = cur->ai_next;
626 		} else
627 			ERR(EAI_FAMILY);	/*xxx*/
628 	}
629 
630 	*res = sentinel.ai_next;
631 	return 0;
632 
633 free:
634 bad:
635 	if (sentinel.ai_next)
636 		freeaddrinfo(sentinel.ai_next);
637 	return error;
638 }
639 
640 /*
641  * numeric hostname with scope
642  */
643 static int
644 explore_numeric_scope(pai, hostname, servname, res)
645 	const struct addrinfo *pai;
646 	const char *hostname;
647 	const char *servname;
648 	struct addrinfo **res;
649 {
650 #ifndef SCOPE_DELIMITER
651 	return explore_numeric(pai, hostname, servname, res);
652 #else
653 	const struct afd *afd;
654 	struct addrinfo *cur;
655 	int error;
656 	char *cp, *hostname2 = NULL;
657 	int scope;
658 #ifdef INET6
659 	struct sockaddr_in6 *sin6;
660 #endif
661 
662 	/*
663 	 * if the servname does not match socktype/protocol, ignore it.
664 	 */
665 	if (get_portmatch(pai, servname) != 0)
666 		return 0;
667 
668 	afd = find_afd(pai->ai_family);
669 	if (afd == NULL)
670 		return 0;
671 	if (!afd->a_scoped)
672 		return explore_numeric(pai, hostname, servname, res);
673 
674 	cp = strchr(hostname, SCOPE_DELIMITER);
675 	if (cp == NULL)
676 		return explore_numeric(pai, hostname, servname, res);
677 
678 	/*
679 	 * Handle special case of <scoped_address><delimiter><scope id>
680 	 */
681 	hostname2 = strdup(hostname);
682 	if (hostname2 == NULL)
683 		return EAI_MEMORY;
684 	/* terminate at the delimiter */
685 	hostname2[cp - hostname] = '\0';
686 
687 	cp++;
688 	switch (pai->ai_family) {
689 #ifdef INET6
690 	case AF_INET6:
691 		scope = if_nametoindex(cp);
692 		if (scope == 0) {
693 			error = EAI_SYSTEM;
694 			goto free;
695 		}
696 		break;
697 #endif
698 	}
699 
700 	error = explore_numeric(pai, hostname2, servname, res);
701 	if (error == 0) {
702 		for (cur = *res; cur; cur = cur->ai_next) {
703 #ifdef INET6
704 			if (cur->ai_family != AF_INET6)
705 				continue;
706 			sin6 = (struct sockaddr_in6 *)cur->ai_addr;
707 			if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr) ||
708 			    IN6_IS_ADDR_MC_LINKLOCAL(&sin6->sin6_addr))
709 				sin6->sin6_scope_id = scope;
710 #endif
711 		}
712 	}
713 
714 #ifdef INET6
715 free:
716 #endif
717 	free(hostname2);
718 
719 	return error;
720 #endif
721 }
722 
723 static int
724 get_canonname(pai, ai, str)
725 	const struct addrinfo *pai;
726 	struct addrinfo *ai;
727 	const char *str;
728 {
729 	if ((pai->ai_flags & AI_CANONNAME) != 0) {
730 		ai->ai_canonname = (char *)malloc(strlen(str) + 1);
731 		if (ai->ai_canonname == NULL)
732 			return EAI_MEMORY;
733 		strcpy(ai->ai_canonname, str);
734 	}
735 	return 0;
736 }
737 
738 static struct addrinfo *
739 get_ai(pai, afd, addr)
740 	const struct addrinfo *pai;
741 	const struct afd *afd;
742 	const char *addr;
743 {
744 	char *p;
745 	struct addrinfo *ai;
746 #ifdef FAITH
747 	struct in6_addr faith_prefix;
748 	char *fp_str;
749 	int translate = 0;
750 #endif
751 
752 #ifdef FAITH
753 	/*
754 	 * Transfrom an IPv4 addr into a special IPv6 addr format for
755 	 * IPv6->IPv4 translation gateway. (only TCP is supported now)
756 	 *
757 	 * +-----------------------------------+------------+
758 	 * | faith prefix part (12 bytes)      | embedded   |
759 	 * |                                   | IPv4 addr part (4 bytes)
760 	 * +-----------------------------------+------------+
761 	 *
762 	 * faith prefix part is specified as ascii IPv6 addr format
763 	 * in environmental variable GAI.
764 	 * For FAITH to work correctly, routing to faith prefix must be
765 	 * setup toward a machine where a FAITH daemon operates.
766 	 * Also, the machine must enable some mechanizm
767 	 * (e.g. faith interface hack) to divert those packet with
768 	 * faith prefixed destination addr to user-land FAITH daemon.
769 	 */
770 	fp_str = getenv("GAI");
771 	if (fp_str && inet_pton(AF_INET6, fp_str, &faith_prefix) == 1 &&
772 	    afd->a_af == AF_INET && pai->ai_socktype == SOCK_STREAM) {
773 		u_int32_t v4a;
774 		u_int8_t v4a_top;
775 
776 		memcpy(&v4a, addr, sizeof v4a);
777 		v4a_top = v4a >> IN_CLASSA_NSHIFT;
778 		if (!IN_MULTICAST(v4a) && !IN_EXPERIMENTAL(v4a) &&
779 		    v4a_top != 0 && v4a != IN_LOOPBACKNET) {
780 			afd = &afdl[N_INET6];
781 			memcpy(&faith_prefix.s6_addr[12], addr,
782 			       sizeof(struct in_addr));
783 			translate = 1;
784 		}
785 	}
786 #endif
787 
788 	ai = (struct addrinfo *)malloc(sizeof(struct addrinfo)
789 		+ (afd->a_socklen));
790 	if (ai == NULL)
791 		return NULL;
792 
793 	memcpy(ai, pai, sizeof(struct addrinfo));
794 	ai->ai_addr = (struct sockaddr *)(ai + 1);
795 	memset(ai->ai_addr, 0, afd->a_socklen);
796 	ai->ai_addr->sa_len = afd->a_socklen;
797 	ai->ai_addrlen = afd->a_socklen;
798 	ai->ai_addr->sa_family = ai->ai_family = afd->a_af;
799 	p = (char *)(ai->ai_addr);
800 #ifdef FAITH
801 	if (translate == 1)
802 		memcpy(p + afd->a_off, &faith_prefix, afd->a_addrlen);
803 	else
804 #endif
805 	memcpy(p + afd->a_off, addr, afd->a_addrlen);
806 
807 	return ai;
808 }
809 
810 static int
811 get_portmatch(ai, servname)
812 	const struct addrinfo *ai;
813 	const char *servname;
814 {
815 	/* get_port does not touch first argument. when matchonly == 1. */
816 	return get_port((struct addrinfo *)ai, servname, 1);
817 }
818 
819 static int
820 get_port(ai, servname, matchonly)
821 	struct addrinfo *ai;
822 	const char *servname;
823 	int matchonly;
824 {
825 	const char *proto;
826 	struct servent *sp;
827 	int port;
828 	int allownumeric;
829 
830 	if (servname == NULL)
831 		return 0;
832 	if (ai->ai_family != AF_INET
833 #ifdef INET6
834 	    && ai->ai_family != AF_INET6
835 #endif
836 	    )
837 		return 0;
838 
839 	switch (ai->ai_socktype) {
840 	case SOCK_RAW:
841 		return EAI_SERVICE;
842 	case SOCK_DGRAM:
843 	case SOCK_STREAM:
844 		allownumeric = 1;
845 		break;
846 	case ANY:
847 		allownumeric = 0;
848 		break;
849 	default:
850 		return EAI_SOCKTYPE;
851 	}
852 
853 	if (str_isnumber(servname)) {
854 		if (!allownumeric)
855 			return EAI_SERVICE;
856 		port = htons(atoi(servname));
857 		if (port < 0 || port > 65535)
858 			return EAI_SERVICE;
859 	} else {
860 		switch (ai->ai_socktype) {
861 		case SOCK_DGRAM:
862 			proto = "udp";
863 			break;
864 		case SOCK_STREAM:
865 			proto = "tcp";
866 			break;
867 		default:
868 			proto = NULL;
869 			break;
870 		}
871 
872 		if ((sp = getservbyname(servname, proto)) == NULL)
873 			return EAI_SERVICE;
874 		port = sp->s_port;
875 	}
876 
877 	if (!matchonly) {
878 		switch (ai->ai_family) {
879 		case AF_INET:
880 			((struct sockaddr_in *)ai->ai_addr)->sin_port = port;
881 			break;
882 #ifdef INET6
883 		case AF_INET6:
884 			((struct sockaddr_in6 *)ai->ai_addr)->sin6_port = port;
885 			break;
886 #endif
887 		}
888 	}
889 
890 	return 0;
891 }
892 
893 static const struct afd *
894 find_afd(af)
895 	int af;
896 {
897 	const struct afd *afd;
898 
899 	if (af == PF_UNSPEC)
900 		return NULL;
901 	for (afd = afdl; afd->a_af; afd++) {
902 		if (afd->a_af == af)
903 			return afd;
904 	}
905 	return NULL;
906 }
907