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 
30 /*
31  * "#ifdef FAITH" part is local hack for supporting IPv4-v6 translator.
32  *
33  * Issues to be discussed:
34  * - Thread safe-ness must be checked.
35  * - 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  * Note:
39  * - We use getipnodebyname() just for thread-safeness.  There's no intent
40  *   to let it do PF_UNSPEC (actually we never pass PF_UNSPEC to
41  *   getipnodebyname().
42  * - The code filters out AFs that are not supported by the kernel,
43  *   when globbing NULL hostname (to loopback, or wildcard).  Is it the right
44  *   thing to do?  What is the relationship with post-RFC2553 AI_ADDRCONFIG
45  *   in ai_flags?
46  */
47 
48 /*
49  * Mingw64 has its own implementation of getaddrinfo, mingw32 no
50  */
51 #ifndef __MINGW64__
52 
53 
54 #ifdef HAVE_CONFIG_H
55 #include <config.h>
56 #endif
57 
58 #ifndef lint
59 static const char rcsid[] _U_ =
60      "@(#) $Header: /tcpdump/master/libpcap/Win32/Src/getaddrinfo.c,v 1.3 2008-09-15 23:37:51 guy Exp $";
61 #endif
62 
63 #include <pcap-stdinc.h>
64 #if 0
65 #include <sys/sysctl.h>
66 #endif
67 #ifndef __MINGW32__
68 #include <arpa/nameser.h>
69 #endif
70 #include <string.h>
71 #include <stdlib.h>
72 #include <stddef.h>
73 #include <ctype.h>
74 #include <stdio.h>
75 #include <errno.h>
76 
77 #ifndef HAVE_PORTABLE_PROTOTYPE
78 #include "cdecl_ext.h"
79 #endif
80 
81 #ifndef HAVE_U_INT32_T
82 #include "bittypes.h"
83 #endif
84 
85 #ifndef HAVE_SOCKADDR_STORAGE
86 #ifndef __MINGW32__
87 #include "sockstorage.h"
88 #endif
89 #endif
90 
91 #ifdef NEED_ADDRINFO_H
92 #include "addrinfo.h"
93 #ifdef WIN32
94 #include "ip6_misc.h"
95 #endif
96 #endif
97 
98 
99 #if defined(__KAME__) && defined(INET6)
100 # define FAITH
101 #endif
102 
103 #define SUCCESS 0
104 #define ANY 0
105 #define YES 1
106 #define NO  0
107 
108 #ifdef FAITH
109 static int translate = NO;
110 static struct in6_addr faith_prefix = IN6ADDR_ANY_INIT;
111 #endif
112 
113 static const char in_addrany[] = { 0, 0, 0, 0 };
114 static const char in6_addrany[] = {
115 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
116 };
117 static const char in_loopback[] = { 127, 0, 0, 1 };
118 static const char in6_loopback[] = {
119 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1
120 };
121 
122 struct sockinet {
123 	u_char	si_len;
124 	u_char	si_family;
125 	u_short	si_port;
126 	u_int32_t si_scope_id;
127 };
128 
129 static const struct afd {
130 	int a_af;
131 	int a_addrlen;
132 	int 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 	{PF_INET6, sizeof(struct in6_addr),
140 	 sizeof(struct sockaddr_in6),
141 	 offsetof(struct sockaddr_in6, sin6_addr),
142 	 in6_addrany, in6_loopback, 1},
143 #endif
144 	{PF_INET, sizeof(struct in_addr),
145 	 sizeof(struct sockaddr_in),
146 	 offsetof(struct sockaddr_in, sin_addr),
147 	 in_addrany, in_loopback, 0},
148 	{0, 0, 0, 0, NULL, NULL, 0},
149 };
150 
151 struct explore {
152 	int e_af;
153 	int e_socktype;
154 	int e_protocol;
155 	const char *e_protostr;
156 	int e_wild;
157 #define WILD_AF(ex)		((ex)->e_wild & 0x01)
158 #define WILD_SOCKTYPE(ex)	((ex)->e_wild & 0x02)
159 #define WILD_PROTOCOL(ex)	((ex)->e_wild & 0x04)
160 };
161 
162 static const struct explore explore[] = {
163 #if 0
164 	{ PF_LOCAL, 0, ANY, ANY, NULL, 0x01 },
165 #endif
166 #ifdef INET6
167 	{ PF_INET6, SOCK_DGRAM, IPPROTO_UDP, "udp", 0x07 },
168 	{ PF_INET6, SOCK_STREAM, IPPROTO_TCP, "tcp", 0x07 },
169 	{ PF_INET6, SOCK_RAW, ANY, NULL, 0x05 },
170 #endif
171 	{ PF_INET, SOCK_DGRAM, IPPROTO_UDP, "udp", 0x07 },
172 	{ PF_INET, SOCK_STREAM, IPPROTO_TCP, "tcp", 0x07 },
173 	{ PF_INET, SOCK_RAW, ANY, NULL, 0x05 },
174 	{ -1, 0, 0, NULL, 0 },
175 };
176 
177 #ifdef INET6
178 #define PTON_MAX	16
179 #else
180 #define PTON_MAX	4
181 #endif
182 
183 
184 static int str_isnumber __P((const char *));
185 static int explore_fqdn __P((const struct addrinfo *, const char *,
186 	const char *, struct addrinfo **));
187 static int explore_null __P((const struct addrinfo *, const char *,
188 	const char *, struct addrinfo **));
189 static int explore_numeric __P((const struct addrinfo *, const char *,
190 	const char *, struct addrinfo **));
191 static int explore_numeric_scope __P((const struct addrinfo *, const char *,
192 	const char *, struct addrinfo **));
193 static int get_name __P((const char *, const struct afd *, struct addrinfo **,
194 	char *, const struct addrinfo *, const char *));
195 static int get_canonname __P((const struct addrinfo *,
196 	struct addrinfo *, const char *));
197 static struct addrinfo *get_ai __P((const struct addrinfo *,
198 	const struct afd *, const char *));
199 static int get_portmatch __P((const struct addrinfo *, const char *));
200 static int get_port __P((struct addrinfo *, const char *, int));
201 static const struct afd *find_afd __P((int));
202 
203 static char *ai_errlist[] = {
204 	"Success",
205 	"Address family for hostname not supported",	/* EAI_ADDRFAMILY */
206 	"Temporary failure in name resolution",		/* EAI_AGAIN      */
207 	"Invalid value for ai_flags",		       	/* EAI_BADFLAGS   */
208 	"Non-recoverable failure in name resolution", 	/* EAI_FAIL       */
209 	"ai_family not supported",			/* EAI_FAMILY     */
210 	"Memory allocation failure", 			/* EAI_MEMORY     */
211 	"No address associated with hostname", 		/* EAI_NODATA     */
212 	"hostname nor servname provided, or not known",	/* EAI_NONAME     */
213 	"servname not supported for ai_socktype",	/* EAI_SERVICE    */
214 	"ai_socktype not supported", 			/* EAI_SOCKTYPE   */
215 	"System error returned in errno", 		/* EAI_SYSTEM     */
216 	"Invalid value for hints",			/* EAI_BADHINTS	  */
217 	"Resolved protocol is unknown",			/* EAI_PROTOCOL   */
218 	"Unknown error", 				/* EAI_MAX        */
219 };
220 
221 /* XXX macros that make external reference is BAD. */
222 
223 #define GET_AI(ai, afd, addr) \
224 do { \
225 	/* external reference: pai, error, and label free */ \
226 	(ai) = get_ai(pai, (afd), (addr)); \
227 	if ((ai) == NULL) { \
228 		error = EAI_MEMORY; \
229 		goto free; \
230 	} \
231 } while (0)
232 
233 #define GET_PORT(ai, serv) \
234 do { \
235 	/* external reference: error and label free */ \
236 	error = get_port((ai), (serv), 0); \
237 	if (error != 0) \
238 		goto free; \
239 } while (0)
240 
241 #define GET_CANONNAME(ai, str) \
242 do { \
243 	/* external reference: pai, error and label free */ \
244 	error = get_canonname(pai, (ai), (str)); \
245 	if (error != 0) \
246 		goto free; \
247 } while (0)
248 
249 #define ERR(err) \
250 do { \
251 	/* external reference: error, and label bad */ \
252 	error = (err); \
253 	goto bad; \
254 } while (0)
255 
256 #define MATCH_FAMILY(x, y, w) \
257 	((x) == (y) || ((w) && ((x) == PF_UNSPEC || (y) == PF_UNSPEC)))
258 #define MATCH(x, y, w) \
259 	((x) == (y) || ((w) && ((x) == ANY || (y) == ANY)))
260 
261 #if  defined(DEFINE_ADDITIONAL_IPV6_STUFF)
262 char *
gai_strerror(ecode)263 gai_strerror(ecode)
264 	int ecode;
265 {
266 	if (ecode < 0 || ecode > EAI_MAX)
267 		ecode = EAI_MAX;
268 	return ai_errlist[ecode];
269 }
270 #endif
271 
272 void
freeaddrinfo(ai)273 freeaddrinfo(ai)
274 	struct addrinfo *ai;
275 {
276 	struct addrinfo *next;
277 
278 	do {
279 		next = ai->ai_next;
280 		if (ai->ai_canonname)
281 			free(ai->ai_canonname);
282 		/* no need to free(ai->ai_addr) */
283 		free(ai);
284 	} while ((ai = next) != NULL);
285 }
286 
287 static int
str_isnumber(p)288 str_isnumber(p)
289 	const char *p;
290 {
291 	char *q = (char *)p;
292 	while (*q) {
293 		if (! isdigit(*q))
294 			return NO;
295 		q++;
296 	}
297 	return YES;
298 }
299 
300 int
getaddrinfo(hostname,servname,hints,res)301 getaddrinfo(hostname, servname, hints, res)
302 	const char *hostname, *servname;
303 	const struct addrinfo *hints;
304 	struct addrinfo **res;
305 {
306 	struct addrinfo sentinel;
307 	struct addrinfo *cur;
308 	int error = 0;
309 	struct addrinfo ai;
310 	struct addrinfo ai0;
311 	struct addrinfo *pai;
312 	const struct afd *afd;
313 	const struct explore *ex;
314 
315 #ifdef FAITH
316 	static int firsttime = 1;
317 
318 	if (firsttime) {
319 		/* translator hack */
320 		char *q = getenv("GAI");
321 		if (q && inet_pton(AF_INET6, q, &faith_prefix) == 1)
322 			translate = YES;
323 		firsttime = 0;
324 	}
325 #endif
326 
327 	sentinel.ai_next = NULL;
328 	cur = &sentinel;
329 	pai = &ai;
330 	pai->ai_flags = 0;
331 	pai->ai_family = PF_UNSPEC;
332 	pai->ai_socktype = ANY;
333 	pai->ai_protocol = ANY;
334 	pai->ai_addrlen = 0;
335 	pai->ai_canonname = NULL;
336 	pai->ai_addr = NULL;
337 	pai->ai_next = NULL;
338 
339 	if (hostname == NULL && servname == NULL)
340 		return EAI_NONAME;
341 	if (hints) {
342 		/* error check for hints */
343 		if (hints->ai_addrlen || hints->ai_canonname ||
344 		    hints->ai_addr || hints->ai_next)
345 			ERR(EAI_BADHINTS); /* xxx */
346 		if (hints->ai_flags & ~AI_MASK)
347 			ERR(EAI_BADFLAGS);
348 		switch (hints->ai_family) {
349 		case PF_UNSPEC:
350 		case PF_INET:
351 #ifdef INET6
352 		case PF_INET6:
353 #endif
354 			break;
355 		default:
356 			ERR(EAI_FAMILY);
357 		}
358 		memcpy(pai, hints, sizeof(*pai));
359 
360 		/*
361 		 * if both socktype/protocol are specified, check if they
362 		 * are meaningful combination.
363 		 */
364 		if (pai->ai_socktype != ANY && pai->ai_protocol != ANY) {
365 			for (ex = explore; ex->e_af >= 0; ex++) {
366 				if (pai->ai_family != ex->e_af)
367 					continue;
368 				if (ex->e_socktype == ANY)
369 					continue;
370 				if (ex->e_protocol == ANY)
371 					continue;
372 				if (pai->ai_socktype == ex->e_socktype
373 				 && pai->ai_protocol != ex->e_protocol) {
374 					ERR(EAI_BADHINTS);
375 				}
376 			}
377 		}
378 	}
379 
380 	/*
381 	 * check for special cases.  (1) numeric servname is disallowed if
382 	 * socktype/protocol are left unspecified. (2) servname is disallowed
383 	 * for raw and other inet{,6} sockets.
384 	 */
385 	if (MATCH_FAMILY(pai->ai_family, PF_INET, 1)
386 #ifdef PF_INET6
387 	 || MATCH_FAMILY(pai->ai_family, PF_INET6, 1)
388 #endif
389 	    ) {
390 		ai0 = *pai;
391 
392 		if (pai->ai_family == PF_UNSPEC) {
393 #ifdef PF_INET6
394 			pai->ai_family = PF_INET6;
395 #else
396 			pai->ai_family = PF_INET;
397 #endif
398 		}
399 		error = get_portmatch(pai, servname);
400 		if (error)
401 			ERR(error);
402 
403 		*pai = ai0;
404 	}
405 
406 	ai0 = *pai;
407 
408 	/* NULL hostname, or numeric hostname */
409 	for (ex = explore; ex->e_af >= 0; ex++) {
410 		*pai = ai0;
411 
412 		if (!MATCH_FAMILY(pai->ai_family, ex->e_af, WILD_AF(ex)))
413 			continue;
414 		if (!MATCH(pai->ai_socktype, ex->e_socktype, WILD_SOCKTYPE(ex)))
415 			continue;
416 		if (!MATCH(pai->ai_protocol, ex->e_protocol, WILD_PROTOCOL(ex)))
417 			continue;
418 
419 		if (pai->ai_family == PF_UNSPEC)
420 			pai->ai_family = ex->e_af;
421 		if (pai->ai_socktype == ANY && ex->e_socktype != ANY)
422 			pai->ai_socktype = ex->e_socktype;
423 		if (pai->ai_protocol == ANY && ex->e_protocol != ANY)
424 			pai->ai_protocol = ex->e_protocol;
425 
426 		if (hostname == NULL)
427 			error = explore_null(pai, hostname, servname, &cur->ai_next);
428 		else
429 			error = explore_numeric_scope(pai, hostname, servname, &cur->ai_next);
430 
431 		if (error)
432 			goto free;
433 
434 		while (cur && cur->ai_next)
435 			cur = cur->ai_next;
436 	}
437 
438 	/*
439 	 * XXX
440 	 * If numreic representation of AF1 can be interpreted as FQDN
441 	 * representation of AF2, we need to think again about the code below.
442 	 */
443 	if (sentinel.ai_next)
444 		goto good;
445 
446 	if (pai->ai_flags & AI_NUMERICHOST)
447 		ERR(EAI_NONAME);
448 	if (hostname == NULL)
449 		ERR(EAI_NONAME);
450 
451 	/*
452 	 * hostname as alphabetical name.
453 	 * we would like to prefer AF_INET6 than AF_INET, so we'll make a
454 	 * outer loop by AFs.
455 	 */
456 	for (afd = afdl; afd->a_af; afd++) {
457 		*pai = ai0;
458 
459 		if (!MATCH_FAMILY(pai->ai_family, afd->a_af, 1))
460 			continue;
461 
462 		for (ex = explore; ex->e_af >= 0; ex++) {
463 			*pai = ai0;
464 
465 			if (pai->ai_family == PF_UNSPEC)
466 				pai->ai_family = afd->a_af;
467 
468 			if (!MATCH_FAMILY(pai->ai_family, ex->e_af, WILD_AF(ex)))
469 				continue;
470 			if (!MATCH(pai->ai_socktype, ex->e_socktype,
471 					WILD_SOCKTYPE(ex))) {
472 				continue;
473 			}
474 			if (!MATCH(pai->ai_protocol, ex->e_protocol,
475 					WILD_PROTOCOL(ex))) {
476 				continue;
477 			}
478 
479 			if (pai->ai_family == PF_UNSPEC)
480 				pai->ai_family = ex->e_af;
481 			if (pai->ai_socktype == ANY && ex->e_socktype != ANY)
482 				pai->ai_socktype = ex->e_socktype;
483 			if (pai->ai_protocol == ANY && ex->e_protocol != ANY)
484 				pai->ai_protocol = ex->e_protocol;
485 
486 			error = explore_fqdn(pai, hostname, servname,
487 				&cur->ai_next);
488 
489 			while (cur && cur->ai_next)
490 				cur = cur->ai_next;
491 		}
492 	}
493 
494 	/* XXX */
495 	if (sentinel.ai_next)
496 		error = 0;
497 
498 	if (error)
499 		goto free;
500 	if (error == 0) {
501 		if (sentinel.ai_next) {
502  good:
503 			*res = sentinel.ai_next;
504 			return SUCCESS;
505 		} else
506 			error = EAI_FAIL;
507 	}
508  free:
509  bad:
510 	if (sentinel.ai_next)
511 		freeaddrinfo(sentinel.ai_next);
512 	*res = NULL;
513 	return error;
514 }
515 
516 /*
517  * FQDN hostname, DNS lookup
518  */
519 static int
explore_fqdn(pai,hostname,servname,res)520 explore_fqdn(pai, hostname, servname, res)
521 	const struct addrinfo *pai;
522 	const char *hostname;
523 	const char *servname;
524 	struct addrinfo **res;
525 {
526 	struct hostent *hp;
527 	int h_error;
528 	int af;
529 	char **aplist = NULL, *apbuf = NULL;
530 	char *ap;
531 	struct addrinfo sentinel, *cur;
532 	int i;
533 #ifndef USE_GETIPNODEBY
534 	int naddrs;
535 #endif
536 	const struct afd *afd;
537 	int error;
538 
539 	*res = NULL;
540 	sentinel.ai_next = NULL;
541 	cur = &sentinel;
542 
543 	/*
544 	 * Do not filter unsupported AFs here.  We need to honor content of
545 	 * databases (/etc/hosts, DNS and others).  Otherwise we cannot
546 	 * replace gethostbyname() by getaddrinfo().
547 	 */
548 
549 	/*
550 	 * if the servname does not match socktype/protocol, ignore it.
551 	 */
552 	if (get_portmatch(pai, servname) != 0)
553 		return 0;
554 
555 	afd = find_afd(pai->ai_family);
556 
557 	/*
558 	 * post-RFC2553: should look at (pai->ai_flags & AI_ADDRCONFIG)
559 	 * rather than hardcoding it.  we may need to add AI_ADDRCONFIG
560 	 * handling code by ourselves in case we don't have getipnodebyname().
561 	 */
562 #ifdef USE_GETIPNODEBY
563 	hp = getipnodebyname(hostname, pai->ai_family, AI_ADDRCONFIG, &h_error);
564 #else
565 #ifdef HAVE_GETHOSTBYNAME2
566 	hp = gethostbyname2(hostname, pai->ai_family);
567 #else
568 	if (pai->ai_family != AF_INET)
569 		return 0;
570 	hp = gethostbyname(hostname);
571 #ifdef HAVE_H_ERRNO
572 	h_error = h_errno;
573 #else
574 	h_error = EINVAL;
575 #endif
576 #endif /*HAVE_GETHOSTBYNAME2*/
577 #endif /*USE_GETIPNODEBY*/
578 
579 	if (hp == NULL) {
580 		switch (h_error) {
581 		case HOST_NOT_FOUND:
582 		case NO_DATA:
583 			error = EAI_NODATA;
584 			break;
585 		case TRY_AGAIN:
586 			error = EAI_AGAIN;
587 			break;
588 		case NO_RECOVERY:
589 		case NETDB_INTERNAL:
590 		default:
591 			error = EAI_FAIL;
592 			break;
593 		}
594 	} else if ((hp->h_name == NULL) || (hp->h_name[0] == 0)
595 			|| (hp->h_addr_list[0] == NULL)) {
596 #ifdef USE_GETIPNODEBY
597 		freehostent(hp);
598 #endif
599 		hp = NULL;
600 		error = EAI_FAIL;
601 	}
602 
603 	if (hp == NULL)
604 		goto free;
605 
606 #ifdef USE_GETIPNODEBY
607 	aplist = hp->h_addr_list;
608 #else
609 	/*
610 	 * hp will be overwritten if we use gethostbyname2().
611 	 * always deep copy for simplification.
612 	 */
613 	for (naddrs = 0; hp->h_addr_list[naddrs] != NULL; naddrs++)
614 		;
615 	naddrs++;
616 	aplist = (char **)malloc(sizeof(aplist[0]) * naddrs);
617 	apbuf = (char *)malloc(hp->h_length * naddrs);
618 	if (aplist == NULL || apbuf == NULL) {
619 		error = EAI_MEMORY;
620 		goto free;
621 	}
622 	memset(aplist, 0, sizeof(aplist[0]) * naddrs);
623 	for (i = 0; i < naddrs; i++) {
624 		if (hp->h_addr_list[i] == NULL) {
625 			aplist[i] = NULL;
626 			continue;
627 		}
628 		memcpy(&apbuf[i * hp->h_length], hp->h_addr_list[i],
629 			hp->h_length);
630 		aplist[i] = &apbuf[i * hp->h_length];
631 	}
632 #endif
633 
634 	for (i = 0; aplist[i] != NULL; i++) {
635 		af = hp->h_addrtype;
636 		ap = aplist[i];
637 #ifdef AF_INET6
638 		if (af == AF_INET6
639 		 && IN6_IS_ADDR_V4MAPPED((struct in6_addr *)ap)) {
640 			af = AF_INET;
641 			ap = ap + sizeof(struct in6_addr)
642 				- sizeof(struct in_addr);
643 		}
644 #endif
645 
646 		if (af != pai->ai_family)
647 			continue;
648 
649 		if ((pai->ai_flags & AI_CANONNAME) == 0) {
650 			GET_AI(cur->ai_next, afd, ap);
651 			GET_PORT(cur->ai_next, servname);
652 		} else {
653 			/*
654 			 * if AI_CANONNAME and if reverse lookup
655 			 * fail, return ai anyway to pacify
656 			 * calling application.
657 			 *
658 			 * XXX getaddrinfo() is a name->address
659 			 * translation function, and it looks
660 			 * strange that we do addr->name
661 			 * translation here.
662 			 */
663 			get_name(ap, afd, &cur->ai_next,
664 				ap, pai, servname);
665 		}
666 
667 		while (cur && cur->ai_next)
668 			cur = cur->ai_next;
669 	}
670 
671 	*res = sentinel.ai_next;
672 	return 0;
673 
674 free:
675 #ifdef USE_GETIPNODEBY
676 	if (hp)
677 		freehostent(hp);
678 #endif
679 	if (aplist)
680 		free(aplist);
681 	if (apbuf)
682 		free(apbuf);
683 	if (sentinel.ai_next)
684 		freeaddrinfo(sentinel.ai_next);
685 	return error;
686 }
687 
688 /*
689  * hostname == NULL.
690  * passive socket -> anyaddr (0.0.0.0 or ::)
691  * non-passive socket -> localhost (127.0.0.1 or ::1)
692  */
693 static int
explore_null(pai,hostname,servname,res)694 explore_null(pai, hostname, servname, res)
695 	const struct addrinfo *pai;
696 	const char *hostname;
697 	const char *servname;
698 	struct addrinfo **res;
699 {
700 	int s;
701 	const struct afd *afd;
702 	struct addrinfo *cur;
703 	struct addrinfo sentinel;
704 	int error;
705 
706 	*res = NULL;
707 	sentinel.ai_next = NULL;
708 	cur = &sentinel;
709 
710 	/*
711 	 * filter out AFs that are not supported by the kernel
712 	 * XXX errno?
713 	 */
714 	s = socket(pai->ai_family, SOCK_DGRAM, 0);
715 	if (s < 0) {
716 		if (errno != EMFILE)
717 			return 0;
718 	} else
719 		close(s);
720 
721 	/*
722 	 * if the servname does not match socktype/protocol, ignore it.
723 	 */
724 	if (get_portmatch(pai, servname) != 0)
725 		return 0;
726 
727 	afd = find_afd(pai->ai_family);
728 
729 	if (pai->ai_flags & AI_PASSIVE) {
730 		GET_AI(cur->ai_next, afd, afd->a_addrany);
731 		/* xxx meaningless?
732 		 * GET_CANONNAME(cur->ai_next, "anyaddr");
733 		 */
734 		GET_PORT(cur->ai_next, servname);
735 	} else {
736 		GET_AI(cur->ai_next, afd, afd->a_loopback);
737 		/* xxx meaningless?
738 		 * GET_CANONNAME(cur->ai_next, "localhost");
739 		 */
740 		GET_PORT(cur->ai_next, servname);
741 	}
742 	cur = cur->ai_next;
743 
744 	*res = sentinel.ai_next;
745 	return 0;
746 
747 free:
748 	if (sentinel.ai_next)
749 		freeaddrinfo(sentinel.ai_next);
750 	return error;
751 }
752 
753 /*
754  * numeric hostname
755  */
756 static int
explore_numeric(pai,hostname,servname,res)757 explore_numeric(pai, hostname, servname, res)
758 	const struct addrinfo *pai;
759 	const char *hostname;
760 	const char *servname;
761 	struct addrinfo **res;
762 {
763 	const struct afd *afd;
764 	struct addrinfo *cur;
765 	struct addrinfo sentinel;
766 	int error;
767 	char pton[PTON_MAX];
768 	int flags;
769 
770 	*res = NULL;
771 	sentinel.ai_next = NULL;
772 	cur = &sentinel;
773 
774 	/*
775 	 * if the servname does not match socktype/protocol, ignore it.
776 	 */
777 	if (get_portmatch(pai, servname) != 0)
778 		return 0;
779 
780 	afd = find_afd(pai->ai_family);
781 	flags = pai->ai_flags;
782 
783 	if (inet_pton(afd->a_af, hostname, pton) == 1) {
784 		u_int32_t v4a;
785 #ifdef INET6
786 		u_char pfx;
787 #endif
788 
789 		switch (afd->a_af) {
790 		case AF_INET:
791 			v4a = (u_int32_t)ntohl(((struct in_addr *)pton)->s_addr);
792 			if (IN_MULTICAST(v4a) || IN_EXPERIMENTAL(v4a))
793 				flags &= ~AI_CANONNAME;
794 			v4a >>= IN_CLASSA_NSHIFT;
795 			if (v4a == 0 || v4a == IN_LOOPBACKNET)
796 				flags &= ~AI_CANONNAME;
797 			break;
798 #ifdef INET6
799 		case AF_INET6:
800 			pfx = ((struct in6_addr *)pton)->s6_addr[0];
801 			if (pfx == 0 || pfx == 0xfe || pfx == 0xff)
802 				flags &= ~AI_CANONNAME;
803 			break;
804 #endif
805 		}
806 
807 		if (pai->ai_family == afd->a_af ||
808 		    pai->ai_family == PF_UNSPEC /*?*/) {
809 			if ((flags & AI_CANONNAME) == 0) {
810 				GET_AI(cur->ai_next, afd, pton);
811 				GET_PORT(cur->ai_next, servname);
812 			} else {
813 				/*
814 				 * if AI_CANONNAME and if reverse lookup
815 				 * fail, return ai anyway to pacify
816 				 * calling application.
817 				 *
818 				 * XXX getaddrinfo() is a name->address
819 				 * translation function, and it looks
820 				 * strange that we do addr->name
821 				 * translation here.
822 				 */
823 				get_name(pton, afd, &cur->ai_next,
824 					pton, pai, servname);
825 			}
826 			while (cur && cur->ai_next)
827 				cur = cur->ai_next;
828 		} else
829 			ERR(EAI_FAMILY);	/*xxx*/
830 	}
831 
832 	*res = sentinel.ai_next;
833 	return 0;
834 
835 free:
836 bad:
837 	if (sentinel.ai_next)
838 		freeaddrinfo(sentinel.ai_next);
839 	return error;
840 }
841 
842 /*
843  * numeric hostname with scope
844  */
845 static int
explore_numeric_scope(pai,hostname,servname,res)846 explore_numeric_scope(pai, hostname, servname, res)
847 	const struct addrinfo *pai;
848 	const char *hostname;
849 	const char *servname;
850 	struct addrinfo **res;
851 {
852 #ifndef SCOPE_DELIMITER
853 	return explore_numeric(pai, hostname, servname, res);
854 #else
855 	const struct afd *afd;
856 	struct addrinfo *cur;
857 	int error;
858 	char *cp, *hostname2 = NULL;
859 	int scope;
860 	struct sockaddr_in6 *sin6;
861 
862 	/*
863 	 * if the servname does not match socktype/protocol, ignore it.
864 	 */
865 	if (get_portmatch(pai, servname) != 0)
866 		return 0;
867 
868 	afd = find_afd(pai->ai_family);
869 	if (!afd->a_scoped)
870 		return explore_numeric(pai, hostname, servname, res);
871 
872 	cp = strchr(hostname, SCOPE_DELIMITER);
873 	if (cp == NULL)
874 		return explore_numeric(pai, hostname, servname, res);
875 
876 	/*
877 	 * Handle special case of <scoped_address><delimiter><scope id>
878 	 */
879 	hostname2 = strdup(hostname);
880 	if (hostname2 == NULL)
881 		return EAI_MEMORY;
882 	/* terminate at the delimiter */
883 	hostname2[cp - hostname] = '\0';
884 
885 	cp++;
886 	switch (pai->ai_family) {
887 #ifdef INET6
888 	case AF_INET6:
889 		scope = if_nametoindex(cp);
890 		if (scope == 0) {
891 			free(hostname2);
892 			return (EAI_NONAME);
893 		}
894 		break;
895 #endif
896 	}
897 
898 	error = explore_numeric(pai, hostname2, servname, res);
899 	if (error == 0) {
900 		for (cur = *res; cur; cur = cur->ai_next) {
901 			if (cur->ai_family != AF_INET6)
902 				continue;
903 			sin6 = (struct sockaddr_in6 *)cur->ai_addr;
904 			if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr) ||
905 			    IN6_IS_ADDR_MC_LINKLOCAL(&sin6->sin6_addr))
906 				sin6->sin6_scope_id = scope;
907 		}
908 	}
909 
910 	free(hostname2);
911 
912 	return error;
913 #endif
914 }
915 
916 static int
get_name(addr,afd,res,numaddr,pai,servname)917 get_name(addr, afd, res, numaddr, pai, servname)
918 	const char *addr;
919 	const struct afd *afd;
920 	struct addrinfo **res;
921 	char *numaddr;
922 	const struct addrinfo *pai;
923 	const char *servname;
924 {
925 	struct hostent *hp = NULL;
926 	struct addrinfo *cur = NULL;
927 	int error = 0;
928 	char *ap = NULL, *cn = NULL;
929 #ifdef USE_GETIPNODEBY
930 	int h_error;
931 
932 	hp = getipnodebyaddr(addr, afd->a_addrlen, afd->a_af, &h_error);
933 #else
934 	hp = gethostbyaddr(addr, afd->a_addrlen, afd->a_af);
935 #endif
936 	if (hp && hp->h_name && hp->h_name[0] && hp->h_addr_list[0]) {
937 #ifdef USE_GETIPNODEBY
938 		GET_AI(cur, afd, hp->h_addr_list[0]);
939 		GET_PORT(cur, servname);
940 		GET_CANONNAME(cur, hp->h_name);
941 #else
942 		/* hp will be damaged if we use gethostbyaddr() */
943 		if ((ap = (char *)malloc(hp->h_length)) == NULL) {
944 			error = EAI_MEMORY;
945 			goto free;
946 		}
947 		memcpy(ap, hp->h_addr_list[0], hp->h_length);
948 		if ((cn = strdup(hp->h_name)) == NULL) {
949 			error = EAI_MEMORY;
950 			goto free;
951 		}
952 
953 		GET_AI(cur, afd, ap);
954 		GET_PORT(cur, servname);
955 		GET_CANONNAME(cur, cn);
956 		free(ap); ap = NULL;
957 		free(cn); cn = NULL;
958 #endif
959 	} else {
960 		GET_AI(cur, afd, numaddr);
961 		GET_PORT(cur, servname);
962 	}
963 
964 #ifdef USE_GETIPNODEBY
965 	if (hp)
966 		freehostent(hp);
967 #endif
968 	*res = cur;
969 	return SUCCESS;
970  free:
971 	if (cur)
972 		freeaddrinfo(cur);
973 	if (ap)
974 		free(ap);
975 	if (cn)
976 		free(cn);
977 #ifdef USE_GETIPNODEBY
978 	if (hp)
979 		freehostent(hp);
980 #endif
981 	*res = NULL;
982 	return error;
983 }
984 
985 static int
get_canonname(pai,ai,str)986 get_canonname(pai, ai, str)
987 	const struct addrinfo *pai;
988 	struct addrinfo *ai;
989 	const char *str;
990 {
991 	if ((pai->ai_flags & AI_CANONNAME) != 0) {
992 		ai->ai_canonname = strdup(str);
993 		if (ai->ai_canonname == NULL)
994 			return EAI_MEMORY;
995 	}
996 	return 0;
997 }
998 
999 static struct addrinfo *
get_ai(pai,afd,addr)1000 get_ai(pai, afd, addr)
1001 	const struct addrinfo *pai;
1002 	const struct afd *afd;
1003 	const char *addr;
1004 {
1005 	char *p;
1006 	struct addrinfo *ai;
1007 
1008 	ai = (struct addrinfo *)malloc(sizeof(struct addrinfo)
1009 		+ (afd->a_socklen));
1010 	if (ai == NULL)
1011 		return NULL;
1012 
1013 	memcpy(ai, pai, sizeof(struct addrinfo));
1014 	ai->ai_addr = (struct sockaddr *)(ai + 1);
1015 	memset(ai->ai_addr, 0, afd->a_socklen);
1016 #ifdef HAVE_SOCKADDR_SA_LEN
1017 	ai->ai_addr->sa_len = afd->a_socklen;
1018 #endif
1019 	ai->ai_addrlen = afd->a_socklen;
1020 	ai->ai_addr->sa_family = ai->ai_family = afd->a_af;
1021 	p = (char *)(ai->ai_addr);
1022 	memcpy(p + afd->a_off, addr, afd->a_addrlen);
1023 	return ai;
1024 }
1025 
1026 static int
get_portmatch(ai,servname)1027 get_portmatch(ai, servname)
1028 	const struct addrinfo *ai;
1029 	const char *servname;
1030 {
1031 
1032 	/* get_port does not touch first argument. when matchonly == 1. */
1033 	return get_port((struct addrinfo *)ai, servname, 1);
1034 }
1035 
1036 static int
get_port(ai,servname,matchonly)1037 get_port(ai, servname, matchonly)
1038 	struct addrinfo *ai;
1039 	const char *servname;
1040 	int matchonly;
1041 {
1042 	const char *proto;
1043 	struct servent *sp;
1044 	int port;
1045 	int allownumeric;
1046 
1047 	if (servname == NULL)
1048 		return 0;
1049 	switch (ai->ai_family) {
1050 	case AF_INET:
1051 #ifdef AF_INET6
1052 	case AF_INET6:
1053 #endif
1054 		break;
1055 	default:
1056 		return 0;
1057 	}
1058 
1059 	switch (ai->ai_socktype) {
1060 	case SOCK_RAW:
1061 		return EAI_SERVICE;
1062 	case SOCK_DGRAM:
1063 	case SOCK_STREAM:
1064 		allownumeric = 1;
1065 		break;
1066 	case ANY:
1067 		allownumeric = 0;
1068 		break;
1069 	default:
1070 		return EAI_SOCKTYPE;
1071 	}
1072 
1073 	if (str_isnumber(servname)) {
1074 		if (!allownumeric)
1075 			return EAI_SERVICE;
1076 		port = htons(atoi(servname));
1077 		if (port < 0 || port > 65535)
1078 			return EAI_SERVICE;
1079 	} else {
1080 		switch (ai->ai_socktype) {
1081 		case SOCK_DGRAM:
1082 			proto = "udp";
1083 			break;
1084 		case SOCK_STREAM:
1085 			proto = "tcp";
1086 			break;
1087 		default:
1088 			proto = NULL;
1089 			break;
1090 		}
1091 
1092 		if ((sp = getservbyname(servname, proto)) == NULL)
1093 			return EAI_SERVICE;
1094 		port = sp->s_port;
1095 	}
1096 
1097 	if (!matchonly) {
1098 		switch (ai->ai_family) {
1099 		case AF_INET:
1100 			((struct sockaddr_in *)ai->ai_addr)->sin_port = port;
1101 			break;
1102 #ifdef INET6
1103 		case AF_INET6:
1104 			((struct sockaddr_in6 *)ai->ai_addr)->sin6_port = port;
1105 			break;
1106 #endif
1107 		}
1108 	}
1109 
1110 	return 0;
1111 }
1112 
1113 static const struct afd *
find_afd(af)1114 find_afd(af)
1115 	int af;
1116 {
1117 	const struct afd *afd;
1118 
1119 	if (af == PF_UNSPEC)
1120 		return NULL;
1121 	for (afd = afdl; afd->a_af; afd++) {
1122 		if (afd->a_af == af)
1123 			return afd;
1124 	}
1125 	return NULL;
1126 }
1127 
1128 
1129 #endif /*__MING64__*/
1130