xref: /dragonfly/lib/libc/net/getaddrinfo.c (revision 0cfebe3d)
1 /*	$FreeBSD: src/lib/libc/net/getaddrinfo.c,v 1.9.2.14 2002/11/08 17:49:31 ume Exp $	*/
2 /*	$DragonFly: src/lib/libc/net/getaddrinfo.c,v 1.6 2005/11/13 02:04:47 swildner Exp $	*/
3 /*	$KAME: getaddrinfo.c,v 1.15 2000/07/09 04:37:24 itojun Exp $	*/
4 
5 /*
6  * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
7  * All rights reserved.
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions
11  * are met:
12  * 1. Redistributions of source code must retain the above copyright
13  *    notice, this list of conditions and the following disclaimer.
14  * 2. Redistributions in binary form must reproduce the above copyright
15  *    notice, this list of conditions and the following disclaimer in the
16  *    documentation and/or other materials provided with the distribution.
17  * 3. Neither the name of the project nor the names of its contributors
18  *    may be used to endorse or promote products derived from this software
19  *    without specific prior written permission.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
22  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24  * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
25  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31  * SUCH DAMAGE.
32  */
33 
34 /*
35  * "#ifdef FAITH" part is local hack for supporting IPv4-v6 translator.
36  *
37  * Issues to be discussed:
38  * - Thread safe-ness must be checked.
39  * - Return values.  There are nonstandard return values defined and used
40  *   in the source code.  This is because RFC2553 is silent about which error
41  *   code must be returned for which situation.
42  * - freeaddrinfo(NULL).  RFC2553 is silent about it.  XNET 5.2 says it is
43  *   invalid.  current code - SEGV on freeaddrinfo(NULL)
44  *
45  * Note:
46  * - The code filters out AFs that are not supported by the kernel,
47  *   when globbing NULL hostname (to loopback, or wildcard).  Is it the right
48  *   thing to do?  What is the relationship with post-RFC2553 AI_ADDRCONFIG
49  *   in ai_flags?
50  * - (post-2553) semantics of AI_ADDRCONFIG itself is too vague.
51  *   (1) what should we do against numeric hostname (2) what should we do
52  *   against NULL hostname (3) what is AI_ADDRCONFIG itself.  AF not ready?
53  *   non-loopback address configured?  global address configured?
54  *
55  * OS specific notes for netbsd/openbsd/freebsd4/bsdi4:
56  * - To avoid search order issue, we have a big amount of code duplicate
57  *   from gethnamaddr.c and some other places.  The issues that there's no
58  *   lower layer function to lookup "IPv4 or IPv6" record.  Calling
59  *   gethostbyname2 from getaddrinfo will end up in wrong search order, as
60  *   presented above.
61  *
62  * OS specific notes for freebsd4:
63  * - FreeBSD supported $GAI.  The code does not.
64  * - FreeBSD allowed classful IPv4 numeric (127.1), the code does not.
65  */
66 
67 #include "namespace.h"
68 #include <sys/types.h>
69 #include <sys/param.h>
70 #include <sys/socket.h>
71 #include <net/if.h>
72 #include <netinet/in.h>
73 #include <arpa/inet.h>
74 #include <arpa/nameser.h>
75 #include <netdb.h>
76 #include <resolv.h>
77 #include <string.h>
78 #include <stdlib.h>
79 #include <stddef.h>
80 #include <ctype.h>
81 #include <unistd.h>
82 #include <stdio.h>
83 #include <errno.h>
84 #include "un-namespace.h"
85 
86 #include "res_config.h"
87 
88 #ifdef DEBUG
89 #include <syslog.h>
90 #endif
91 
92 #if defined(__KAME__) && defined(INET6)
93 # define FAITH
94 #endif
95 
96 #define SUCCESS 0
97 #define ANY 0
98 #define YES 1
99 #define NO  0
100 
101 static const char in_addrany[] = { 0, 0, 0, 0 };
102 static const char in_loopback[] = { 127, 0, 0, 1 };
103 #ifdef INET6
104 static const char in6_addrany[] = {
105 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
106 };
107 static const char in6_loopback[] = {
108 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1
109 };
110 #endif
111 
112 static const struct afd {
113 	int a_af;
114 	int a_addrlen;
115 	int a_socklen;
116 	int a_off;
117 	const char *a_addrany;
118 	const char *a_loopback;
119 	int a_scoped;
120 } afdl [] = {
121 #ifdef INET6
122 #define	N_INET6 0
123 	{PF_INET6, sizeof(struct in6_addr),
124 	 sizeof(struct sockaddr_in6),
125 	 offsetof(struct sockaddr_in6, sin6_addr),
126 	 in6_addrany, in6_loopback, 1},
127 #define	N_INET 1
128 #else
129 #define	N_INET 0
130 #endif
131 	{PF_INET, sizeof(struct in_addr),
132 	 sizeof(struct sockaddr_in),
133 	 offsetof(struct sockaddr_in, sin_addr),
134 	 in_addrany, in_loopback, 0},
135 	{0, 0, 0, 0, NULL, NULL, 0},
136 };
137 
138 struct explore {
139 	int e_af;
140 	int e_socktype;
141 	int e_protocol;
142 	const char *e_protostr;
143 	int e_wild;
144 #define WILD_AF(ex)		((ex)->e_wild & 0x01)
145 #define WILD_SOCKTYPE(ex)	((ex)->e_wild & 0x02)
146 #define WILD_PROTOCOL(ex)	((ex)->e_wild & 0x04)
147 };
148 
149 static const struct explore explore[] = {
150 #if 0
151 	{ PF_LOCAL, 0, ANY, ANY, NULL, 0x01 },
152 #endif
153 #ifdef INET6
154 	{ PF_INET6, SOCK_DGRAM, IPPROTO_UDP, "udp", 0x07 },
155 	{ PF_INET6, SOCK_STREAM, IPPROTO_TCP, "tcp", 0x07 },
156 	{ PF_INET6, SOCK_RAW, ANY, NULL, 0x05 },
157 #endif
158 	{ PF_INET, SOCK_DGRAM, IPPROTO_UDP, "udp", 0x07 },
159 	{ PF_INET, SOCK_STREAM, IPPROTO_TCP, "tcp", 0x07 },
160 	{ PF_INET, SOCK_RAW, ANY, NULL, 0x05 },
161 	{ PF_UNSPEC, SOCK_DGRAM, IPPROTO_UDP, "udp", 0x07 },
162 	{ PF_UNSPEC, SOCK_STREAM, IPPROTO_TCP, "tcp", 0x07 },
163 	{ PF_UNSPEC, SOCK_RAW, ANY, NULL, 0x05 },
164 	{ -1, 0, 0, NULL, 0 },
165 };
166 
167 #ifdef INET6
168 #define PTON_MAX	16
169 #else
170 #define PTON_MAX	4
171 #endif
172 
173 #define MAXPACKET	(64*1024)
174 
175 typedef union {
176 	HEADER hdr;
177 	u_char buf[MAXPACKET];
178 } querybuf;
179 
180 struct res_target {
181 	struct res_target *next;
182 	const char *name;	/* domain name */
183 	int qclass, qtype;	/* class and type of query */
184 	u_char *answer;		/* buffer to put answer */
185 	int anslen;		/* size of answer buffer */
186 	int n;			/* result length */
187 };
188 
189 static int str_isnumber (const char *);
190 static int explore_fqdn (const struct addrinfo *, const char *,
191 	const char *, struct addrinfo **);
192 static int explore_null (const struct addrinfo *,
193 	const char *, struct addrinfo **);
194 static int explore_numeric (const struct addrinfo *, const char *,
195 	const char *, struct addrinfo **);
196 static int explore_numeric_scope (const struct addrinfo *, const char *,
197 	const char *, struct addrinfo **);
198 static int get_canonname (const struct addrinfo *,
199 	struct addrinfo *, const char *);
200 static struct addrinfo *get_ai (const struct addrinfo *,
201 	const struct afd *, const char *);
202 static int get_portmatch (const struct addrinfo *, const char *);
203 static int get_port (struct addrinfo *, const char *, int);
204 static const struct afd *find_afd (int);
205 static int addrconfig (struct addrinfo *);
206 #ifdef INET6
207 static int ip6_str2scopeid (char *, struct sockaddr_in6 *, u_int32_t *);
208 #endif
209 
210 static struct addrinfo *getanswer (const querybuf *, int, const char *,
211 	int, const struct addrinfo *);
212 static int _dns_getaddrinfo (const struct addrinfo *, const char *,
213 	struct addrinfo **);
214 static struct addrinfo *_gethtent (FILE *fp, const char *,
215 	const struct addrinfo *);
216 static int _files_getaddrinfo (const struct addrinfo *, const char *,
217 	struct addrinfo **);
218 #ifdef YP
219 static int _nis_getaddrinfo (const struct addrinfo *, const char *,
220 	struct addrinfo **);
221 #endif
222 
223 static int res_queryN (const char *, struct res_target *);
224 static int res_searchN (const char *, struct res_target *);
225 static int res_querydomainN (const char *, const char *,
226 	struct res_target *);
227 
228 static char *ai_errlist[] = {
229 	"Success",
230 	"Address family for hostname not supported",	/* EAI_ADDRFAMILY */
231 	"Temporary failure in name resolution",		/* EAI_AGAIN      */
232 	"Invalid value for ai_flags",		       	/* EAI_BADFLAGS   */
233 	"Non-recoverable failure in name resolution", 	/* EAI_FAIL       */
234 	"ai_family not supported",			/* EAI_FAMILY     */
235 	"Memory allocation failure", 			/* EAI_MEMORY     */
236 	"No address associated with hostname", 		/* EAI_NODATA     */
237 	"hostname nor servname provided, or not known",	/* EAI_NONAME     */
238 	"servname not supported for ai_socktype",	/* EAI_SERVICE    */
239 	"ai_socktype not supported", 			/* EAI_SOCKTYPE   */
240 	"System error returned in errno", 		/* EAI_SYSTEM     */
241 	"Invalid value for hints",			/* EAI_BADHINTS	  */
242 	"Resolved protocol is unknown",			/* EAI_PROTOCOL   */
243 	"Unknown error", 				/* EAI_MAX        */
244 };
245 
246 /*
247  * Select order host function.
248  */
249 #define	MAXHOSTCONF	4
250 
251 #ifndef HOSTCONF
252 #  define	HOSTCONF	"/etc/host.conf"
253 #endif /* !HOSTCONF */
254 
255 struct _hostconf {
256 	int (*byname)(const struct addrinfo *, const char *,
257 		      struct addrinfo **);
258 };
259 
260 /* default order */
261 static struct _hostconf _hostconf[MAXHOSTCONF] = {
262 	_dns_getaddrinfo,
263 	_files_getaddrinfo,
264 #ifdef ICMPNL
265 	NULL,
266 #endif /* ICMPNL */
267 };
268 
269 static int	_hostconf_init_done;
270 static void	_hostconf_init(void);
271 
272 /* Make getaddrinfo() thread-safe in libc for use with kernel threads. */
273 #include "libc_private.h"
274 #include "spinlock.h"
275 /*
276  * XXX: Our res_*() is not thread-safe.  So, we share lock between
277  * getaddrinfo() and getipnodeby*().  Still, we cannot use
278  * getaddrinfo() and getipnodeby*() in conjunction with other
279  * functions which call res_*().
280  */
281 spinlock_t __getaddrinfo_thread_lock = _SPINLOCK_INITIALIZER;
282 #define THREAD_LOCK() \
283 	if (__isthreaded) _SPINLOCK(&__getaddrinfo_thread_lock);
284 #define THREAD_UNLOCK() \
285 	if (__isthreaded) _SPINUNLOCK(&__getaddrinfo_thread_lock);
286 
287 /* XXX macros that make external reference is BAD. */
288 
289 #define GET_AI(ai, afd, addr) \
290 do { \
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) \
300 do { \
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) \
308 do { \
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) \
316 do { \
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 
328 char *
329 gai_strerror(int ecode)
330 {
331 	if (ecode < 0 || ecode > EAI_MAX)
332 		ecode = EAI_MAX;
333 	return ai_errlist[ecode];
334 }
335 
336 void
337 freeaddrinfo(struct addrinfo *ai)
338 {
339 	struct addrinfo *next;
340 
341 	do {
342 		next = ai->ai_next;
343 		if (ai->ai_canonname)
344 			free(ai->ai_canonname);
345 		/* no need to free(ai->ai_addr) */
346 		free(ai);
347 		ai = next;
348 	} while (ai);
349 }
350 
351 static int
352 str_isnumber(const char *p)
353 {
354 	char *ep;
355 
356 	if (*p == '\0')
357 		return NO;
358 	ep = NULL;
359 	errno = 0;
360 	strtoul(p, &ep, 10);
361 	if (errno == 0 && ep && *ep == '\0')
362 		return YES;
363 	else
364 		return NO;
365 }
366 
367 int
368 getaddrinfo(const char *hostname, const char *servname,
369 	    const struct addrinfo *hints, struct addrinfo **res)
370 {
371 	struct addrinfo sentinel;
372 	struct addrinfo *cur;
373 	int error = 0;
374 	struct addrinfo ai;
375 	struct addrinfo ai0;
376 	struct addrinfo *pai;
377 	const struct explore *ex;
378 
379 	memset(&sentinel, 0, sizeof(sentinel));
380 	cur = &sentinel;
381 	pai = &ai;
382 	pai->ai_flags = 0;
383 	pai->ai_family = PF_UNSPEC;
384 	pai->ai_socktype = ANY;
385 	pai->ai_protocol = ANY;
386 	pai->ai_addrlen = 0;
387 	pai->ai_canonname = NULL;
388 	pai->ai_addr = NULL;
389 	pai->ai_next = NULL;
390 
391 	if (hostname == NULL && servname == NULL)
392 		return EAI_NONAME;
393 	if (hints) {
394 		/* error check for hints */
395 		if (hints->ai_addrlen || hints->ai_canonname ||
396 		    hints->ai_addr || hints->ai_next)
397 			ERR(EAI_BADHINTS); /* xxx */
398 		if (hints->ai_flags & ~AI_MASK)
399 			ERR(EAI_BADFLAGS);
400 		switch (hints->ai_family) {
401 		case PF_UNSPEC:
402 		case PF_INET:
403 #ifdef INET6
404 		case PF_INET6:
405 #endif
406 			break;
407 		default:
408 			ERR(EAI_FAMILY);
409 		}
410 		memcpy(pai, hints, sizeof(*pai));
411 
412 		/*
413 		 * if both socktype/protocol are specified, check if they
414 		 * are meaningful combination.
415 		 */
416 		if (pai->ai_socktype != ANY && pai->ai_protocol != ANY) {
417 			for (ex = explore; ex->e_af >= 0; ex++) {
418 				if (pai->ai_family != ex->e_af)
419 					continue;
420 				if (ex->e_socktype == ANY)
421 					continue;
422 				if (ex->e_protocol == ANY)
423 					continue;
424 				if (pai->ai_socktype == ex->e_socktype &&
425 				    pai->ai_protocol != ex->e_protocol) {
426 					ERR(EAI_BADHINTS);
427 				}
428 			}
429 		}
430 	}
431 
432 	/*
433 	 * post-2553: AI_ALL and AI_V4MAPPED are effective only against
434 	 * AF_INET6 query.  They need to be ignored if specified in other
435 	 * occassions.
436 	 */
437 	switch (pai->ai_flags & (AI_ALL | AI_V4MAPPED)) {
438 	case AI_V4MAPPED:
439 	case AI_ALL | AI_V4MAPPED:
440 		if (pai->ai_family != AF_INET6)
441 			pai->ai_flags &= ~(AI_ALL | AI_V4MAPPED);
442 		break;
443 	case AI_ALL:
444 #if 1
445 		/* illegal */
446 		ERR(EAI_BADFLAGS);
447 #else
448 		pai->ai_flags &= ~(AI_ALL | AI_V4MAPPED);
449 #endif
450 		break;
451 	}
452 
453 	/*
454 	 * check for special cases.  (1) numeric servname is disallowed if
455 	 * socktype/protocol are left unspecified. (2) servname is disallowed
456 	 * for raw and other inet{,6} sockets.
457 	 */
458 	if (MATCH_FAMILY(pai->ai_family, PF_INET, 1)
459 #ifdef PF_INET6
460 	    || MATCH_FAMILY(pai->ai_family, PF_INET6, 1)
461 #endif
462 	    ) {
463 		ai0 = *pai;	/* backup *pai */
464 
465 		if (pai->ai_family == PF_UNSPEC) {
466 #ifdef PF_INET6
467 			pai->ai_family = PF_INET6;
468 #else
469 			pai->ai_family = PF_INET;
470 #endif
471 		}
472 		error = get_portmatch(pai, servname);
473 		if (error)
474 			ERR(error);
475 
476 		*pai = ai0;
477 	}
478 
479 	ai0 = *pai;
480 
481 	/* NULL hostname, or numeric hostname */
482 	for (ex = explore; ex->e_af >= 0; ex++) {
483 		*pai = ai0;
484 
485 		/* PF_UNSPEC entries are prepared for DNS queries only */
486 		if (ex->e_af == PF_UNSPEC)
487 			continue;
488 
489 		if (!MATCH_FAMILY(pai->ai_family, ex->e_af, WILD_AF(ex)))
490 			continue;
491 		if (!MATCH(pai->ai_socktype, ex->e_socktype,
492 			   WILD_SOCKTYPE(ex)))
493 			continue;
494 		if (!MATCH(pai->ai_protocol, ex->e_protocol,
495 			   WILD_PROTOCOL(ex)))
496 			continue;
497 
498 		if (pai->ai_family == PF_UNSPEC)
499 			pai->ai_family = ex->e_af;
500 		if (pai->ai_socktype == ANY && ex->e_socktype != ANY)
501 			pai->ai_socktype = ex->e_socktype;
502 		if (pai->ai_protocol == ANY && ex->e_protocol != ANY)
503 			pai->ai_protocol = ex->e_protocol;
504 
505 		if (hostname == NULL)
506 			error = explore_null(pai, servname, &cur->ai_next);
507 		else
508 			error = explore_numeric_scope(pai, hostname, servname,
509 						      &cur->ai_next);
510 
511 		if (error)
512 			goto free;
513 
514 		while (cur && cur->ai_next)
515 			cur = cur->ai_next;
516 	}
517 
518 	/*
519 	 * XXX
520 	 * If numreic representation of AF1 can be interpreted as FQDN
521 	 * representation of AF2, we need to think again about the code below.
522 	 */
523 	if (sentinel.ai_next)
524 		goto good;
525 
526 	if (pai->ai_flags & AI_NUMERICHOST)
527 		ERR(EAI_NONAME);
528 	if (hostname == NULL)
529 		ERR(EAI_NODATA);
530 
531 	if ((pai->ai_flags & AI_ADDRCONFIG) != 0 && !addrconfig(&ai0))
532 		ERR(EAI_FAIL);
533 
534 	/*
535 	 * hostname as alphabetical name.
536 	 * we would like to prefer AF_INET6 than AF_INET, so we'll make a
537 	 * outer loop by AFs.
538 	 */
539 	for (ex = explore; ex->e_af >= 0; ex++) {
540 		*pai = ai0;
541 
542 		/* require exact match for family field */
543 		if (pai->ai_family != ex->e_af)
544 			continue;
545 
546 		if (!MATCH(pai->ai_socktype, ex->e_socktype, WILD_SOCKTYPE(ex))) {
547 			continue;
548 		}
549 		if (!MATCH(pai->ai_protocol, ex->e_protocol, WILD_PROTOCOL(ex))) {
550 			continue;
551 		}
552 
553 		if (pai->ai_socktype == ANY && ex->e_socktype != ANY)
554 			pai->ai_socktype = ex->e_socktype;
555 		if (pai->ai_protocol == ANY && ex->e_protocol != ANY)
556 			pai->ai_protocol = ex->e_protocol;
557 
558 		error = explore_fqdn(pai, hostname, servname, &cur->ai_next);
559 
560 		while (cur && cur->ai_next)
561 			cur = cur->ai_next;
562 	}
563 
564 	/* XXX */
565 	if (sentinel.ai_next)
566 		error = 0;
567 
568 	if (error)
569 		goto free;
570 	if (error == 0) {
571 		if (sentinel.ai_next) {
572  good:
573 			*res = sentinel.ai_next;
574 			return SUCCESS;
575 		} else
576 			error = EAI_FAIL;
577 	}
578  free:
579  bad:
580 	if (sentinel.ai_next)
581 		freeaddrinfo(sentinel.ai_next);
582 	*res = NULL;
583 	return error;
584 }
585 
586 static char *
587 _hgetword(char **pp)
588 {
589 	char c, *p, *ret;
590 	const char *sp;
591 	static const char sep[] = "# \t\n";
592 
593 	ret = NULL;
594 	for (p = *pp; (c = *p) != '\0'; p++) {
595 		for (sp = sep; *sp != '\0'; sp++) {
596 			if (c == *sp)
597 				break;
598 		}
599 		if (c == '#')
600 			p[1] = '\0';	/* ignore rest of line */
601 		if (ret == NULL) {
602 			if (*sp == '\0')
603 				ret = p;
604 		} else {
605 			if (*sp != '\0') {
606 				*p++ = '\0';
607 				break;
608 			}
609 		}
610 	}
611 	*pp = p;
612 	if (ret == NULL || *ret == '\0')
613 		return NULL;
614 	return ret;
615 }
616 
617 /*
618  * Initialize hostconf structure.
619  */
620 
621 static void
622 _hostconf_init(void)
623 {
624 	FILE *fp;
625 	int n;
626 	char *p, *line;
627 	char buf[BUFSIZ];
628 
629 	_hostconf_init_done = 1;
630 	n = 0;
631 	p = HOSTCONF;
632 	if ((fp = fopen(p, "r")) == NULL)
633 		return;
634 	while (n < MAXHOSTCONF && fgets(buf, sizeof(buf), fp)) {
635 		line = buf;
636 		if ((p = _hgetword(&line)) == NULL)
637 			continue;
638 		do {
639 			if (strcmp(p, "hosts") == 0
640 			||  strcmp(p, "local") == 0
641 			||  strcmp(p, "file") == 0
642 			||  strcmp(p, "files") == 0)
643 				_hostconf[n++].byname = _files_getaddrinfo;
644 			else if (strcmp(p, "dns") == 0
645 			     ||  strcmp(p, "bind") == 0)
646 				_hostconf[n++].byname = _dns_getaddrinfo;
647 #ifdef YP
648 			else if (strcmp(p, "nis") == 0)
649 				_hostconf[n++].byname = _nis_getaddrinfo;
650 #endif
651 		} while ((p = _hgetword(&line)) != NULL);
652 	}
653 	fclose(fp);
654 	if (n < 0) {
655 		/* no keyword found. do not change default configuration */
656 		return;
657 	}
658 	for (; n < MAXHOSTCONF; n++)
659 		_hostconf[n].byname = NULL;
660 }
661 
662 /*
663  * FQDN hostname, DNS lookup
664  */
665 static int
666 explore_fqdn(const struct addrinfo *pai, const char *hostname,
667 	     const char *servname, struct addrinfo **res)
668 {
669 	struct addrinfo *result;
670 	struct addrinfo *cur;
671 	int error = 0, i;
672 
673 	result = NULL;
674 	*res = NULL;
675 
676 	THREAD_LOCK();
677 
678 	/*
679 	 * if the servname does not match socktype/protocol, ignore it.
680 	 */
681 	if (get_portmatch(pai, servname) != 0) {
682 		THREAD_UNLOCK();
683 		return 0;
684 	}
685 
686 	if (!_hostconf_init_done)
687 		_hostconf_init();
688 
689 	for (i = 0; i < MAXHOSTCONF; i++) {
690 		if (!_hostconf[i].byname)
691 			continue;
692 		error = (*_hostconf[i].byname)(pai, hostname, &result);
693 		if (error != 0)
694 			continue;
695 		for (cur = result; cur; cur = cur->ai_next) {
696 			GET_PORT(cur, servname);
697 			/* canonname should be filled already */
698 		}
699 		THREAD_UNLOCK();
700 		*res = result;
701 		return 0;
702 	}
703 
704 free:
705 	THREAD_UNLOCK();
706 	if (result)
707 		freeaddrinfo(result);
708 	return error;
709 }
710 
711 /*
712  * hostname == NULL.
713  * passive socket -> anyaddr (0.0.0.0 or ::)
714  * non-passive socket -> localhost (127.0.0.1 or ::1)
715  */
716 static int
717 explore_null(const struct addrinfo *pai, const char *servname,
718 	     struct addrinfo **res)
719 {
720 	int s;
721 	const struct afd *afd;
722 	struct addrinfo *cur;
723 	struct addrinfo sentinel;
724 	int error;
725 
726 	*res = NULL;
727 	sentinel.ai_next = NULL;
728 	cur = &sentinel;
729 
730 	/*
731 	 * filter out AFs that are not supported by the kernel
732 	 * XXX errno?
733 	 */
734 	s = _socket(pai->ai_family, SOCK_DGRAM, 0);
735 	if (s < 0) {
736 		if (errno != EMFILE)
737 			return 0;
738 	} else
739 		_close(s);
740 
741 	/*
742 	 * if the servname does not match socktype/protocol, ignore it.
743 	 */
744 	if (get_portmatch(pai, servname) != 0)
745 		return 0;
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 
769 free:
770 	if (sentinel.ai_next)
771 		freeaddrinfo(sentinel.ai_next);
772 	return error;
773 }
774 
775 /*
776  * numeric hostname
777  */
778 static int
779 explore_numeric(const struct addrinfo *pai, const char *hostname,
780 		const char *servname, struct addrinfo **res)
781 {
782 	const struct afd *afd;
783 	struct addrinfo *cur;
784 	struct addrinfo sentinel;
785 	int error;
786 	char pton[PTON_MAX];
787 
788 	*res = NULL;
789 	sentinel.ai_next = NULL;
790 	cur = &sentinel;
791 
792 	/*
793 	 * if the servname does not match socktype/protocol, ignore it.
794 	 */
795 	if (get_portmatch(pai, servname) != 0)
796 		return 0;
797 
798 	afd = find_afd(pai->ai_family);
799 	if (afd == NULL)
800 		return 0;
801 
802 	switch (afd->a_af) {
803 #if 1 /*X/Open spec*/
804 	case AF_INET:
805 		if (inet_aton(hostname, (struct in_addr *)pton) == 1) {
806 			if (pai->ai_family == afd->a_af ||
807 			    pai->ai_family == PF_UNSPEC /*?*/) {
808 				GET_AI(cur->ai_next, afd, pton);
809 				GET_PORT(cur->ai_next, servname);
810 				while (cur && cur->ai_next)
811 					cur = cur->ai_next;
812 			} else
813 				ERR(EAI_FAMILY);	/*xxx*/
814 		}
815 		break;
816 #endif
817 	default:
818 		if (inet_pton(afd->a_af, hostname, pton) == 1) {
819 			if (pai->ai_family == afd->a_af ||
820 			    pai->ai_family == PF_UNSPEC /*?*/) {
821 				GET_AI(cur->ai_next, afd, pton);
822 				GET_PORT(cur->ai_next, servname);
823 				while (cur && cur->ai_next)
824 					cur = cur->ai_next;
825 			} else
826 				ERR(EAI_FAMILY);	/* XXX */
827 		}
828 		break;
829 	}
830 
831 	*res = sentinel.ai_next;
832 	return 0;
833 
834 free:
835 bad:
836 	if (sentinel.ai_next)
837 		freeaddrinfo(sentinel.ai_next);
838 	return error;
839 }
840 
841 /*
842  * numeric hostname with scope
843  */
844 static int
845 explore_numeric_scope(const struct addrinfo *pai, const char *hostname,
846 		      const char *servname, struct addrinfo **res)
847 {
848 #if !defined(SCOPE_DELIMITER) || !defined(INET6)
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 	/*
858 	 * if the servname does not match socktype/protocol, ignore it.
859 	 */
860 	if (get_portmatch(pai, servname) != 0)
861 		return 0;
862 
863 	afd = find_afd(pai->ai_family);
864 	if (afd == NULL)
865 		return 0;
866 	if (!afd->a_scoped)
867 		return explore_numeric(pai, hostname, servname, res);
868 
869 	cp = strchr(hostname, SCOPE_DELIMITER);
870 	if (cp == NULL)
871 		return explore_numeric(pai, hostname, servname, res);
872 
873 	/*
874 	 * Handle special case of <scoped_address><delimiter><scope id>
875 	 */
876 	hostname2 = strdup(hostname);
877 	if (hostname2 == NULL)
878 		return EAI_MEMORY;
879 	/* terminate at the delimiter */
880 	hostname2[cp - hostname] = '\0';
881 	addr = hostname2;
882 	scope = cp + 1;
883 
884 	error = explore_numeric(pai, addr, servname, res);
885 	if (error == 0) {
886 		u_int32_t scopeid;
887 
888 		for (cur = *res; cur; cur = cur->ai_next) {
889 			if (cur->ai_family != AF_INET6)
890 				continue;
891 			sin6 = (struct sockaddr_in6 *)(void *)cur->ai_addr;
892 			if (ip6_str2scopeid(scope, sin6, &scopeid) == -1) {
893 				free(hostname2);
894 				return(EAI_NODATA); /* XXX: is return OK? */
895 			}
896 			sin6->sin6_scope_id = scopeid;
897 		}
898 	}
899 
900 	free(hostname2);
901 
902 	return error;
903 #endif
904 }
905 
906 static int
907 get_canonname(const struct addrinfo *pai, struct addrinfo *ai, 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 		strlcpy(ai->ai_canonname, str, strlen(str) + 1);
914 	}
915 	return 0;
916 }
917 
918 static struct addrinfo *
919 get_ai(const struct addrinfo *pai, const struct afd *afd, const char *addr)
920 {
921 	char *p;
922 	struct addrinfo *ai;
923 #ifdef FAITH
924 	struct in6_addr faith_prefix;
925 	char *fp_str;
926 	int translate = 0;
927 #endif
928 
929 #ifdef FAITH
930 	/*
931 	 * Transfrom an IPv4 addr into a special IPv6 addr format for
932 	 * IPv6->IPv4 translation gateway. (only TCP is supported now)
933 	 *
934 	 * +-----------------------------------+------------+
935 	 * | faith prefix part (12 bytes)      | embedded   |
936 	 * |                                   | IPv4 addr part (4 bytes)
937 	 * +-----------------------------------+------------+
938 	 *
939 	 * faith prefix part is specified as ascii IPv6 addr format
940 	 * in environmental variable GAI.
941 	 * For FAITH to work correctly, routing to faith prefix must be
942 	 * setup toward a machine where a FAITH daemon operates.
943 	 * Also, the machine must enable some mechanizm
944 	 * (e.g. faith interface hack) to divert those packet with
945 	 * faith prefixed destination addr to user-land FAITH daemon.
946 	 */
947 	fp_str = getenv("GAI");
948 	if (fp_str && inet_pton(AF_INET6, fp_str, &faith_prefix) == 1 &&
949 	    afd->a_af == AF_INET && pai->ai_socktype == SOCK_STREAM) {
950 		u_int32_t v4a;
951 		u_int8_t v4a_top;
952 
953 		memcpy(&v4a, addr, sizeof v4a);
954 		v4a_top = v4a >> IN_CLASSA_NSHIFT;
955 		if (!IN_MULTICAST(v4a) && !IN_EXPERIMENTAL(v4a) &&
956 		    v4a_top != 0 && v4a != IN_LOOPBACKNET) {
957 			afd = &afdl[N_INET6];
958 			memcpy(&faith_prefix.s6_addr[12], addr,
959 			       sizeof(struct in_addr));
960 			translate = 1;
961 		}
962 	}
963 #endif
964 
965 	ai = (struct addrinfo *)malloc(sizeof(struct addrinfo)
966 		+ (afd->a_socklen));
967 	if (ai == NULL)
968 		return NULL;
969 
970 	memcpy(ai, pai, sizeof(struct addrinfo));
971 	ai->ai_addr = (struct sockaddr *)(void *)(ai + 1);
972 	memset(ai->ai_addr, 0, (size_t)afd->a_socklen);
973 	ai->ai_addr->sa_len = afd->a_socklen;
974 	ai->ai_addrlen = afd->a_socklen;
975 	ai->ai_addr->sa_family = ai->ai_family = afd->a_af;
976 	p = (char *)(ai->ai_addr);
977 #ifdef FAITH
978 	if (translate == 1)
979 		memcpy(p + afd->a_off, &faith_prefix, afd->a_addrlen);
980 	else
981 #endif
982 	memcpy(p + afd->a_off, addr, afd->a_addrlen);
983 
984 	return ai;
985 }
986 
987 static int
988 get_portmatch(const struct addrinfo *ai, const char *servname)
989 {
990 
991 	/* get_port does not touch first argument. when matchonly == 1. */
992 	/* LINTED const cast */
993 	return get_port((struct addrinfo *)ai, servname, 1);
994 }
995 
996 static int
997 get_port(struct addrinfo *ai, const char *servname, int matchonly)
998 {
999 	const char *proto;
1000 	struct servent *sp;
1001 	int port;
1002 	int allownumeric;
1003 
1004 	if (servname == NULL)
1005 		return 0;
1006 	switch (ai->ai_family) {
1007 	case AF_INET:
1008 #ifdef AF_INET6
1009 	case AF_INET6:
1010 #endif
1011 		break;
1012 	default:
1013 		return 0;
1014 	}
1015 
1016 	switch (ai->ai_socktype) {
1017 	case SOCK_RAW:
1018 		return EAI_SERVICE;
1019 	case SOCK_DGRAM:
1020 	case SOCK_STREAM:
1021 		allownumeric = 1;
1022 		break;
1023 	case ANY:
1024 		allownumeric = 0;
1025 		break;
1026 	default:
1027 		return EAI_SOCKTYPE;
1028 	}
1029 
1030 	if (str_isnumber(servname)) {
1031 		if (!allownumeric)
1032 			return EAI_SERVICE;
1033 		port = atoi(servname);
1034 		if (port < 0 || port > 65535)
1035 			return EAI_SERVICE;
1036 		port = htons(port);
1037 	} else {
1038 		switch (ai->ai_socktype) {
1039 		case SOCK_DGRAM:
1040 			proto = "udp";
1041 			break;
1042 		case SOCK_STREAM:
1043 			proto = "tcp";
1044 			break;
1045 		default:
1046 			proto = NULL;
1047 			break;
1048 		}
1049 
1050 		if ((sp = getservbyname(servname, proto)) == NULL)
1051 			return EAI_SERVICE;
1052 		port = sp->s_port;
1053 	}
1054 
1055 	if (!matchonly) {
1056 		switch (ai->ai_family) {
1057 		case AF_INET:
1058 			((struct sockaddr_in *)(void *)
1059 			    ai->ai_addr)->sin_port = port;
1060 			break;
1061 #ifdef INET6
1062 		case AF_INET6:
1063 			((struct sockaddr_in6 *)(void *)
1064 			    ai->ai_addr)->sin6_port = port;
1065 			break;
1066 #endif
1067 		}
1068 	}
1069 
1070 	return 0;
1071 }
1072 
1073 static const struct afd *
1074 find_afd(int af)
1075 {
1076 	const struct afd *afd;
1077 
1078 	if (af == PF_UNSPEC)
1079 		return NULL;
1080 	for (afd = afdl; afd->a_af; afd++) {
1081 		if (afd->a_af == af)
1082 			return afd;
1083 	}
1084 	return NULL;
1085 }
1086 
1087 /*
1088  * post-2553: AI_ADDRCONFIG check.  if we use getipnodeby* as backend, backend
1089  * will take care of it.
1090  * the semantics of AI_ADDRCONFIG is not defined well.  we are not sure
1091  * if the code is right or not.
1092  *
1093  * XXX PF_UNSPEC -> PF_INET6 + PF_INET mapping needs to be in sync with
1094  * _dns_getaddrinfo.
1095  */
1096 static int
1097 addrconfig(struct addrinfo *pai)
1098 {
1099 	int s, af;
1100 
1101 	/*
1102 	 * TODO:
1103 	 * Note that implementation dependent test for address
1104 	 * configuration should be done everytime called
1105 	 * (or apropriate interval),
1106 	 * because addresses will be dynamically assigned or deleted.
1107 	 */
1108 	af = pai->ai_family;
1109 	if (af == AF_UNSPEC) {
1110 		if ((s = _socket(AF_INET6, SOCK_DGRAM, 0)) < 0)
1111 			af = AF_INET;
1112 		else {
1113 			_close(s);
1114 			if ((s = _socket(AF_INET, SOCK_DGRAM, 0)) < 0)
1115 				af = AF_INET6;
1116 			else
1117 				_close(s);
1118 		}
1119 
1120 	}
1121 	if (af != AF_UNSPEC) {
1122 		if ((s = _socket(af, SOCK_DGRAM, 0)) < 0)
1123 			return 0;
1124 		_close(s);
1125 	}
1126 	pai->ai_family = af;
1127 	return 1;
1128 }
1129 
1130 #ifdef INET6
1131 /* convert a string to a scope identifier. XXX: IPv6 specific */
1132 static int
1133 ip6_str2scopeid(char *scope, struct sockaddr_in6 *sin6, u_int32_t *scopeid)
1134 {
1135 	u_long lscopeid;
1136 	struct in6_addr *a6;
1137 	char *ep;
1138 
1139 	a6 = &sin6->sin6_addr;
1140 
1141 	/* empty scopeid portion is invalid */
1142 	if (*scope == '\0')
1143 		return -1;
1144 
1145 	if (IN6_IS_ADDR_LINKLOCAL(a6) || IN6_IS_ADDR_MC_LINKLOCAL(a6)) {
1146 		/*
1147 		 * We currently assume a one-to-one mapping between links
1148 		 * and interfaces, so we simply use interface indices for
1149 		 * like-local scopes.
1150 		 */
1151 		*scopeid = if_nametoindex(scope);
1152 		if (*scopeid == 0)
1153 			goto trynumeric;
1154 		return 0;
1155 	}
1156 
1157 	/* still unclear about literal, allow numeric only - placeholder */
1158 	if (IN6_IS_ADDR_SITELOCAL(a6) || IN6_IS_ADDR_MC_SITELOCAL(a6))
1159 		goto trynumeric;
1160 	if (IN6_IS_ADDR_MC_ORGLOCAL(a6))
1161 		goto trynumeric;
1162 	else
1163 		goto trynumeric;	/* global */
1164 
1165 	/* try to convert to a numeric id as a last resort */
1166   trynumeric:
1167 	errno = 0;
1168 	lscopeid = strtoul(scope, &ep, 10);
1169 	*scopeid = (u_int32_t)(lscopeid & 0xffffffffUL);
1170 	if (errno == 0 && ep && *ep == '\0' && *scopeid == lscopeid)
1171 		return 0;
1172 	else
1173 		return -1;
1174 }
1175 #endif
1176 
1177 #ifdef RESOLVSORT
1178 struct addr_ptr {
1179 	struct addrinfo *ai;
1180 	int aval;
1181 };
1182 
1183 static int
1184 addr4sort(struct addrinfo *sentinel)
1185 {
1186 	struct addrinfo *ai;
1187 	struct addr_ptr *addrs, addr;
1188 	struct sockaddr_in *sin;
1189 	int naddrs, i, j;
1190 	int needsort = 0;
1191 
1192 	if (!sentinel)
1193 		return -1;
1194 	naddrs = 0;
1195 	for (ai = sentinel->ai_next; ai; ai = ai->ai_next)
1196 		naddrs++;
1197 	if (naddrs < 2)
1198 		return 0;		/* We don't need sorting. */
1199 	if ((addrs = malloc(sizeof(struct addr_ptr) * naddrs)) == NULL)
1200 		return -1;
1201 	i = 0;
1202 	for (ai = sentinel->ai_next; ai; ai = ai->ai_next) {
1203 		sin = (struct sockaddr_in *)ai->ai_addr;
1204 		for (j = 0; (unsigned)j < _res.nsort; j++) {
1205 			if (_res.sort_list[j].addr.s_addr ==
1206 			    (sin->sin_addr.s_addr & _res.sort_list[j].mask))
1207 				break;
1208 		}
1209 		addrs[i].ai = ai;
1210 		addrs[i].aval = j;
1211 		if (needsort == 0 && i > 0 && j < addrs[i - 1].aval)
1212 			needsort = i;
1213 		i++;
1214 	}
1215 	if (!needsort) {
1216 		free(addrs);
1217 		return 0;
1218 	}
1219 
1220 	while (needsort < naddrs) {
1221 	    for (j = needsort - 1; j >= 0; j--) {
1222 		if (addrs[j].aval > addrs[j+1].aval) {
1223 		    addr = addrs[j];
1224 		    addrs[j] = addrs[j + 1];
1225 		    addrs[j + 1] = addr;
1226 		} else
1227 		    break;
1228 	    }
1229 	    needsort++;
1230 	}
1231 
1232 	ai = sentinel;
1233 	for (i = 0; i < naddrs; ++i) {
1234 		ai->ai_next = addrs[i].ai;
1235 		ai = ai->ai_next;
1236 	}
1237 	ai->ai_next = NULL;
1238 	free(addrs);
1239 	return 0;
1240 }
1241 #endif /*RESOLVSORT*/
1242 
1243 #ifdef DEBUG
1244 static const char AskedForGot[] =
1245 	"gethostby*.getanswer: asked for \"%s\", got \"%s\"";
1246 #endif
1247 
1248 static struct addrinfo *
1249 getanswer(const querybuf *answer, int anslen, const char *qname, int qtype,
1250 	  const struct addrinfo *pai)
1251 {
1252 	struct addrinfo sentinel, *cur;
1253 	struct addrinfo ai;
1254 	const struct afd *afd;
1255 	char *canonname;
1256 	const HEADER *hp;
1257 	const u_char *cp;
1258 	int n;
1259 	const u_char *eom;
1260 	char *bp, *ep;
1261 	int type, class, ancount, qdcount;
1262 	int haveanswer, had_error;
1263 	char tbuf[MAXDNAME];
1264 	int (*name_ok) (const char *);
1265 	char hostbuf[8*1024];
1266 
1267 	memset(&sentinel, 0, sizeof(sentinel));
1268 	cur = &sentinel;
1269 
1270 	canonname = NULL;
1271 	eom = answer->buf + anslen;
1272 	switch (qtype) {
1273 	case T_A:
1274 	case T_AAAA:
1275 	case T_ANY:	/*use T_ANY only for T_A/T_AAAA lookup*/
1276 		name_ok = res_hnok;
1277 		break;
1278 	default:
1279 		return (NULL);	/* XXX should be abort(); */
1280 	}
1281 	/*
1282 	 * find first satisfactory answer
1283 	 */
1284 	hp = &answer->hdr;
1285 	ancount = ntohs(hp->ancount);
1286 	qdcount = ntohs(hp->qdcount);
1287 	bp = hostbuf;
1288 	ep = hostbuf + sizeof hostbuf;
1289 	cp = answer->buf + HFIXEDSZ;
1290 	if (qdcount != 1) {
1291 		h_errno = NO_RECOVERY;
1292 		return (NULL);
1293 	}
1294 	n = dn_expand(answer->buf, eom, cp, bp, ep - bp);
1295 	if ((n < 0) || !(*name_ok)(bp)) {
1296 		h_errno = NO_RECOVERY;
1297 		return (NULL);
1298 	}
1299 	cp += n + QFIXEDSZ;
1300 	if (qtype == T_A || qtype == T_AAAA || qtype == T_ANY) {
1301 		/* res_send() has already verified that the query name is the
1302 		 * same as the one we sent; this just gets the expanded name
1303 		 * (i.e., with the succeeding search-domain tacked on).
1304 		 */
1305 		n = strlen(bp) + 1;		/* for the \0 */
1306 		if (n >= MAXHOSTNAMELEN) {
1307 			h_errno = NO_RECOVERY;
1308 			return (NULL);
1309 		}
1310 		canonname = bp;
1311 		bp += n;
1312 		/* The qname can be abbreviated, but h_name is now absolute. */
1313 		qname = canonname;
1314 	}
1315 	haveanswer = 0;
1316 	had_error = 0;
1317 	while (ancount-- > 0 && cp < eom && !had_error) {
1318 		n = dn_expand(answer->buf, eom, cp, bp, ep - bp);
1319 		if ((n < 0) || !(*name_ok)(bp)) {
1320 			had_error++;
1321 			continue;
1322 		}
1323 		cp += n;			/* name */
1324 		type = _getshort(cp);
1325  		cp += INT16SZ;			/* type */
1326 		class = _getshort(cp);
1327  		cp += INT16SZ + INT32SZ;	/* class, TTL */
1328 		n = _getshort(cp);
1329 		cp += INT16SZ;			/* len */
1330 		if (class != C_IN) {
1331 			/* XXX - debug? syslog? */
1332 			cp += n;
1333 			continue;		/* XXX - had_error++ ? */
1334 		}
1335 		if ((qtype == T_A || qtype == T_AAAA || qtype == T_ANY) &&
1336 		    type == T_CNAME) {
1337 			n = dn_expand(answer->buf, eom, cp, tbuf, sizeof tbuf);
1338 			if ((n < 0) || !(*name_ok)(tbuf)) {
1339 				had_error++;
1340 				continue;
1341 			}
1342 			cp += n;
1343 			/* Get canonical name. */
1344 			n = strlen(tbuf) + 1;	/* for the \0 */
1345 			if (n > ep - bp || n >= MAXHOSTNAMELEN) {
1346 				had_error++;
1347 				continue;
1348 			}
1349 			strlcpy(bp, tbuf, ep - bp);
1350 			canonname = bp;
1351 			bp += n;
1352 			continue;
1353 		}
1354 		if (qtype == T_ANY) {
1355 			if (!(type == T_A || type == T_AAAA)) {
1356 				cp += n;
1357 				continue;
1358 			}
1359 		} else if (type != qtype) {
1360 #ifdef DEBUG
1361 			if (type != T_KEY && type != T_SIG)
1362 				syslog(LOG_NOTICE|LOG_AUTH,
1363 	       "gethostby*.getanswer: asked for \"%s %s %s\", got type \"%s\"",
1364 				       qname, p_class(C_IN), p_type(qtype),
1365 				       p_type(type));
1366 #endif
1367 			cp += n;
1368 			continue;		/* XXX - had_error++ ? */
1369 		}
1370 		switch (type) {
1371 		case T_A:
1372 		case T_AAAA:
1373 			if (strcasecmp(canonname, bp) != 0) {
1374 #ifdef DEBUG
1375 				syslog(LOG_NOTICE|LOG_AUTH,
1376 				       AskedForGot, canonname, bp);
1377 #endif
1378 				cp += n;
1379 				continue;	/* XXX - had_error++ ? */
1380 			}
1381 			if (type == T_A && n != INADDRSZ) {
1382 				cp += n;
1383 				continue;
1384 			}
1385 			if (type == T_AAAA && n != IN6ADDRSZ) {
1386 				cp += n;
1387 				continue;
1388 			}
1389 #ifdef FILTER_V4MAPPED
1390 			if (type == T_AAAA) {
1391 				struct in6_addr in6;
1392 				memcpy(&in6, cp, sizeof(in6));
1393 				if (IN6_IS_ADDR_V4MAPPED(&in6)) {
1394 					cp += n;
1395 					continue;
1396 				}
1397 			}
1398 #endif
1399 			if (!haveanswer) {
1400 				int nn;
1401 
1402 				canonname = bp;
1403 				nn = strlen(bp) + 1;	/* for the \0 */
1404 				bp += nn;
1405 			}
1406 
1407 			/* don't overwrite pai */
1408 			ai = *pai;
1409 			ai.ai_family = (type == T_A) ? AF_INET : AF_INET6;
1410 			afd = find_afd(ai.ai_family);
1411 			if (afd == NULL) {
1412 				cp += n;
1413 				continue;
1414 			}
1415 			cur->ai_next = get_ai(&ai, afd, (const char *)cp);
1416 			if (cur->ai_next == NULL)
1417 				had_error++;
1418 			while (cur && cur->ai_next)
1419 				cur = cur->ai_next;
1420 			cp += n;
1421 			break;
1422 		default:
1423 			abort();
1424 		}
1425 		if (!had_error)
1426 			haveanswer++;
1427 	}
1428 	if (haveanswer) {
1429 #if defined(RESOLVSORT)
1430 		/*
1431 		 * We support only IPv4 address for backward
1432 		 * compatibility against gethostbyname(3).
1433 		 */
1434 		if (_res.nsort && qtype == T_A) {
1435 			if (addr4sort(&sentinel) < 0) {
1436 				freeaddrinfo(sentinel.ai_next);
1437 				h_errno = NO_RECOVERY;
1438 				return NULL;
1439 			}
1440 		}
1441 #endif /*RESOLVSORT*/
1442 		if (!canonname)
1443 			get_canonname(pai, sentinel.ai_next, qname);
1444 		else
1445 			get_canonname(pai, sentinel.ai_next, canonname);
1446 		h_errno = NETDB_SUCCESS;
1447 		return sentinel.ai_next;
1448 	}
1449 
1450 	h_errno = NO_RECOVERY;
1451 	return NULL;
1452 }
1453 
1454 /*ARGSUSED*/
1455 static int
1456 _dns_getaddrinfo(const struct addrinfo *pai, const char *hostname,
1457 		 struct addrinfo **res)
1458 {
1459 	struct addrinfo *ai;
1460 	querybuf *buf, *buf2;
1461 	const char *name;
1462 	struct addrinfo sentinel, *cur;
1463 	struct res_target q, q2;
1464 
1465 	memset(&q, 0, sizeof(q2));
1466 	memset(&q2, 0, sizeof(q2));
1467 	memset(&sentinel, 0, sizeof(sentinel));
1468 	cur = &sentinel;
1469 
1470 	buf = malloc(sizeof(*buf));
1471 	if (!buf) {
1472 		h_errno = NETDB_INTERNAL;
1473 		return EAI_MEMORY;
1474 	}
1475 	buf2 = malloc(sizeof(*buf2));
1476 	if (!buf2) {
1477 		free(buf);
1478 		h_errno = NETDB_INTERNAL;
1479 		return EAI_MEMORY;
1480 	}
1481 
1482 	switch (pai->ai_family) {
1483 	case AF_UNSPEC:
1484 		q.name = name;
1485 		q.qclass = C_IN;
1486 		q.qtype = T_A;
1487 		q.answer = buf->buf;
1488 		q.anslen = sizeof(buf->buf);
1489 		q.next = &q2;
1490 		q2.name = name;
1491 		q2.qclass = C_IN;
1492 		q2.qtype = T_AAAA;
1493 		q2.answer = buf2->buf;
1494 		q2.anslen = sizeof(buf2->buf);
1495 		break;
1496 	case AF_INET:
1497 		q.name = name;
1498 		q.qclass = C_IN;
1499 		q.qtype = T_A;
1500 		q.answer = buf->buf;
1501 		q.anslen = sizeof(buf->buf);
1502 		break;
1503 	case AF_INET6:
1504 		q.name = name;
1505 		q.qclass = C_IN;
1506 		q.qtype = T_AAAA;
1507 		q.answer = buf->buf;
1508 		q.anslen = sizeof(buf->buf);
1509 		break;
1510 	default:
1511 		free(buf);
1512 		free(buf2);
1513 		return EAI_FAIL;
1514 	}
1515 	if (res_searchN(hostname, &q) < 0) {
1516 		free(buf);
1517 		free(buf2);
1518 		return EAI_NODATA;
1519 	}
1520 	/* prefer IPv6 */
1521 	if (q.next) {
1522 		ai = getanswer(buf2, q2.n, q2.name, q2.qtype, pai);
1523 		if (ai) {
1524 			cur->ai_next = ai;
1525 			while (cur && cur->ai_next)
1526 				cur = cur->ai_next;
1527 		}
1528 	}
1529 
1530 	ai = getanswer(buf, q.n, q.name, q.qtype, pai);
1531 	if (ai)
1532 		cur->ai_next = ai;
1533 	free(buf);
1534 	free(buf2);
1535 	if (sentinel.ai_next == NULL)
1536 		switch (h_errno) {
1537 		case HOST_NOT_FOUND:
1538 			return EAI_NODATA;
1539 		case TRY_AGAIN:
1540 			return EAI_AGAIN;
1541 		default:
1542 			return EAI_FAIL;
1543 		}
1544 	*res = sentinel.ai_next;
1545 	return 0;
1546 }
1547 
1548 static struct addrinfo *
1549 _gethtent(FILE *hostf, const char *name, const struct addrinfo *pai)
1550 {
1551 	char *p;
1552 	char *cp, *tname, *cname;
1553 	struct addrinfo hints, *res0, *res;
1554 	int error;
1555 	const char *addr;
1556 	char hostbuf[8*1024];
1557 
1558 again:
1559 	if (!(p = fgets(hostbuf, sizeof hostbuf, hostf)))
1560 		return (NULL);
1561 	if (*p == '#')
1562 		goto again;
1563 	if (!(cp = strpbrk(p, "#\n")))
1564 		goto again;
1565 	*cp = '\0';
1566 	if (!(cp = strpbrk(p, " \t")))
1567 		goto again;
1568 	*cp++ = '\0';
1569 	addr = p;
1570 	cname = NULL;
1571 	/* if this is not something we're looking for, skip it. */
1572 	while (cp && *cp) {
1573 		if (*cp == ' ' || *cp == '\t') {
1574 			cp++;
1575 			continue;
1576 		}
1577 		tname = cp;
1578 		if (cname == NULL)
1579 			cname = cp;
1580 		if ((cp = strpbrk(cp, " \t")) != NULL)
1581 			*cp++ = '\0';
1582 		if (strcasecmp(name, tname) == 0)
1583 			goto found;
1584 	}
1585 	goto again;
1586 
1587 found:
1588 	/* we should not glob socktype/protocol here */
1589 	memset(&hints, 0, sizeof(hints));
1590 	hints.ai_family = pai->ai_family;
1591 	hints.ai_socktype = SOCK_DGRAM;
1592 	hints.ai_protocol = 0;
1593 	hints.ai_flags = AI_NUMERICHOST;
1594 	error = getaddrinfo(addr, "0", &hints, &res0);
1595 	if (error)
1596 		goto again;
1597 #ifdef FILTER_V4MAPPED
1598 	/* XXX should check all items in the chain */
1599 	if (res0->ai_family == AF_INET6 &&
1600 	    IN6_IS_ADDR_V4MAPPED(&((struct sockaddr_in6 *)res0->ai_addr)->sin6_addr)) {
1601 		freeaddrinfo(res0);
1602 		goto again;
1603 	}
1604 #endif
1605 	for (res = res0; res; res = res->ai_next) {
1606 		/* cover it up */
1607 		res->ai_flags = pai->ai_flags;
1608 		res->ai_socktype = pai->ai_socktype;
1609 		res->ai_protocol = pai->ai_protocol;
1610 
1611 		if (pai->ai_flags & AI_CANONNAME) {
1612 			if (get_canonname(pai, res, cname) != 0) {
1613 				freeaddrinfo(res0);
1614 				goto again;
1615 			}
1616 		}
1617 	}
1618 	return res0;
1619 }
1620 
1621 /*ARGSUSED*/
1622 static int
1623 _files_getaddrinfo(const struct addrinfo *pai, const char *hostname,
1624 		   struct addrinfo **res)
1625 {
1626 	FILE *hostf;
1627 	struct addrinfo sentinel, *cur;
1628 	struct addrinfo *p;
1629 
1630 	sentinel.ai_next = NULL;
1631 	cur = &sentinel;
1632 
1633 	if ((hostf = fopen(_PATH_HOSTS, "r")) == NULL)
1634 		return EAI_FAIL;
1635 	while ((p = _gethtent(hostf, hostname, pai)) != NULL) {
1636 		cur->ai_next = p;
1637 		while (cur && cur->ai_next)
1638 			cur = cur->ai_next;
1639 	}
1640 	fclose(hostf);
1641 
1642 	if (!sentinel.ai_next)
1643 		return EAI_NODATA;
1644 
1645 	*res = sentinel.ai_next;
1646 	return 0;
1647 }
1648 
1649 #ifdef YP
1650 /*ARGSUSED*/
1651 static int
1652 _nis_getaddrinfo(const struct addrinfo *pai, const char *hostname,
1653 		 struct addrinfo **res)
1654 {
1655 	struct hostent *hp;
1656 	int af;
1657 	struct addrinfo sentinel, *cur;
1658 	int i;
1659 	const struct afd *afd;
1660 	int error;
1661 
1662 	sentinel.ai_next = NULL;
1663 	cur = &sentinel;
1664 
1665 	af = (pai->ai_family == AF_UNSPEC) ? AF_INET : pai->ai_family;
1666 	if (af != AF_INET)
1667 		return (EAI_ADDRFAMILY);
1668 
1669 	if ((hp = _gethostbynisname(hostname, af)) == NULL) {
1670 		switch (errno) {
1671 		/* XXX: should be filled in */
1672 		default:
1673 			error = EAI_FAIL;
1674 			break;
1675 		}
1676 	} else if (hp->h_name == NULL ||
1677 		   hp->h_name[0] == 0 || hp->h_addr_list[0] == NULL) {
1678 		hp = NULL;
1679 		error = EAI_FAIL;
1680 	}
1681 
1682 	if (hp == NULL)
1683 		return error;
1684 
1685 	for (i = 0; hp->h_addr_list[i] != NULL; i++) {
1686 		if (hp->h_addrtype != af)
1687 			continue;
1688 
1689 		afd = find_afd(hp->h_addrtype);
1690 		if (afd == NULL)
1691 			continue;
1692 
1693 		GET_AI(cur->ai_next, afd, hp->h_addr_list[i]);
1694 		if ((pai->ai_flags & AI_CANONNAME) != 0) {
1695 			/*
1696 			 * RFC2553 says that ai_canonname will be set only for
1697 			 * the first element.  we do it for all the elements,
1698 			 * just for convenience.
1699 			 */
1700 			GET_CANONNAME(cur->ai_next, hp->h_name);
1701 		}
1702 
1703 		while (cur && cur->ai_next)
1704 			cur = cur->ai_next;
1705 	}
1706 
1707 	*res = sentinel.ai_next;
1708 	return 0;
1709 
1710 free:
1711 	if (sentinel.ai_next)
1712 		freeaddrinfo(sentinel.ai_next);
1713 	return error;
1714 }
1715 #endif
1716 
1717 /* resolver logic */
1718 
1719 extern const char *__hostalias (const char *);
1720 extern int h_errno;
1721 
1722 /*
1723  * Formulate a normal query, send, and await answer.
1724  * Returned answer is placed in supplied buffer "answer".
1725  * Perform preliminary check of answer, returning success only
1726  * if no error is indicated and the answer count is nonzero.
1727  * Return the size of the response on success, -1 on error.
1728  * Error number is left in h_errno.
1729  *
1730  * Caller must parse answer and determine whether it answers the question.
1731  */
1732 static int
1733 res_queryN(const char *name,		/* domain name */
1734 	   struct res_target *target)
1735 {
1736 	u_char *buf;
1737 	HEADER *hp;
1738 	int n;
1739 	struct res_target *t;
1740 	int rcode;
1741 	int ancount;
1742 
1743 	rcode = NOERROR;
1744 	ancount = 0;
1745 
1746 	if ((_res.options & RES_INIT) == 0 && res_init() == -1) {
1747 		h_errno = NETDB_INTERNAL;
1748 		return (-1);
1749 	}
1750 
1751 	buf = malloc(MAXPACKET);
1752 	if (!buf) {
1753 		h_errno = NETDB_INTERNAL;
1754 		return (-1);
1755 	}
1756 
1757 	for (t = target; t; t = t->next) {
1758 		int class, type;
1759 		u_char *answer;
1760 		int anslen;
1761 
1762 		hp = (HEADER *)(void *)t->answer;
1763 		hp->rcode = NOERROR;	/* default */
1764 
1765 		/* make it easier... */
1766 		class = t->qclass;
1767 		type = t->qtype;
1768 		answer = t->answer;
1769 		anslen = t->anslen;
1770 #ifdef DEBUG
1771 		if (_res.options & RES_DEBUG)
1772 			printf(";; res_query(%s, %d, %d)\n", name, class, type);
1773 #endif
1774 
1775 		n = res_mkquery(QUERY, name, class, type, NULL, 0, NULL,
1776 		    buf, MAXPACKET);
1777 		if (n > 0 && (_res.options & RES_USE_EDNS0) != 0)
1778 			n = res_opt(n, buf, MAXPACKET, anslen);
1779 		if (n <= 0) {
1780 #ifdef DEBUG
1781 			if (_res.options & RES_DEBUG)
1782 				printf(";; res_query: mkquery failed\n");
1783 #endif
1784 			free(buf);
1785 			h_errno = NO_RECOVERY;
1786 			return (n);
1787 		}
1788 		n = res_send(buf, n, answer, anslen);
1789 #if 0
1790 		if (n < 0) {
1791 #ifdef DEBUG
1792 			if (_res.options & RES_DEBUG)
1793 				printf(";; res_query: send error\n");
1794 #endif
1795 			free(buf);
1796 			h_errno = TRY_AGAIN;
1797 			return (n);
1798 		}
1799 #endif
1800 
1801 		if (n < 0 || n > anslen)
1802 			hp->rcode = FORMERR; /* XXX not very informative */
1803 		if (hp->rcode != NOERROR || ntohs(hp->ancount) == 0) {
1804 			rcode = hp->rcode;	/* record most recent error */
1805 #ifdef DEBUG
1806 			if (_res.options & RES_DEBUG)
1807 				printf(";; rcode = %u, ancount=%u\n", hp->rcode,
1808 				    ntohs(hp->ancount));
1809 #endif
1810 			continue;
1811 		}
1812 
1813 		ancount += ntohs(hp->ancount);
1814 
1815 		t->n = n;
1816 	}
1817 
1818 	free(buf);
1819 
1820 	if (ancount == 0) {
1821 		switch (rcode) {
1822 		case NXDOMAIN:
1823 			h_errno = HOST_NOT_FOUND;
1824 			break;
1825 		case SERVFAIL:
1826 			h_errno = TRY_AGAIN;
1827 			break;
1828 		case NOERROR:
1829 			h_errno = NO_DATA;
1830 			break;
1831 		case FORMERR:
1832 		case NOTIMP:
1833 		case REFUSED:
1834 		default:
1835 			h_errno = NO_RECOVERY;
1836 			break;
1837 		}
1838 		return (-1);
1839 	}
1840 	return (ancount);
1841 }
1842 
1843 /*
1844  * Formulate a normal query, send, and retrieve answer in supplied buffer.
1845  * Return the size of the response on success, -1 on error.
1846  * If enabled, implement search rules until answer or unrecoverable failure
1847  * is detected.  Error code, if any, is left in h_errno.
1848  */
1849 static int
1850 res_searchN(const char *name,		/* domain name */
1851 	    struct res_target *target)
1852 {
1853 	const char *cp, * const *domain;
1854 	HEADER *hp = (HEADER *)(void *)target->answer;	/*XXX*/
1855 	u_int dots;
1856 	int trailing_dot, ret, saved_herrno;
1857 	int got_nodata = 0, got_servfail = 0, tried_as_is = 0;
1858 
1859 	if ((_res.options & RES_INIT) == 0 && res_init() == -1) {
1860 		h_errno = NETDB_INTERNAL;
1861 		return (-1);
1862 	}
1863 
1864 	errno = 0;
1865 	h_errno = HOST_NOT_FOUND;	/* default, if we never query */
1866 	dots = 0;
1867 	for (cp = name; *cp; cp++)
1868 		dots += (*cp == '.');
1869 	trailing_dot = 0;
1870 	if (cp > name && *--cp == '.')
1871 		trailing_dot++;
1872 
1873 	/*
1874 	 * if there aren't any dots, it could be a user-level alias
1875 	 */
1876 	if (!dots && (cp = __hostalias(name)) != NULL)
1877 		return (res_queryN(cp, target));
1878 
1879 	/*
1880 	 * If there are dots in the name already, let's just give it a try
1881 	 * 'as is'.  The threshold can be set with the "ndots" option.
1882 	 */
1883 	saved_herrno = -1;
1884 	if (dots >= _res.ndots) {
1885 		ret = res_querydomainN(name, NULL, target);
1886 		if (ret > 0)
1887 			return (ret);
1888 		saved_herrno = h_errno;
1889 		tried_as_is++;
1890 	}
1891 
1892 	/*
1893 	 * We do at least one level of search if
1894 	 *	- there is no dot and RES_DEFNAME is set, or
1895 	 *	- there is at least one dot, there is no trailing dot,
1896 	 *	  and RES_DNSRCH is set.
1897 	 */
1898 	if ((!dots && (_res.options & RES_DEFNAMES)) ||
1899 	    (dots && !trailing_dot && (_res.options & RES_DNSRCH))) {
1900 		int done = 0;
1901 
1902 		for (domain = (const char * const *)_res.dnsrch;
1903 		   *domain && !done;
1904 		   domain++) {
1905 
1906 			ret = res_querydomainN(name, *domain, target);
1907 			if (ret > 0)
1908 				return (ret);
1909 
1910 			/*
1911 			 * If no server present, give up.
1912 			 * If name isn't found in this domain,
1913 			 * keep trying higher domains in the search list
1914 			 * (if that's enabled).
1915 			 * On a NO_DATA error, keep trying, otherwise
1916 			 * a wildcard entry of another type could keep us
1917 			 * from finding this entry higher in the domain.
1918 			 * If we get some other error (negative answer or
1919 			 * server failure), then stop searching up,
1920 			 * but try the input name below in case it's
1921 			 * fully-qualified.
1922 			 */
1923 			if (errno == ECONNREFUSED) {
1924 				h_errno = TRY_AGAIN;
1925 				return (-1);
1926 			}
1927 
1928 			switch (h_errno) {
1929 			case NO_DATA:
1930 				got_nodata++;
1931 				/* FALLTHROUGH */
1932 			case HOST_NOT_FOUND:
1933 				/* keep trying */
1934 				break;
1935 			case TRY_AGAIN:
1936 				if (hp->rcode == SERVFAIL) {
1937 					/* try next search element, if any */
1938 					got_servfail++;
1939 					break;
1940 				}
1941 				/* FALLTHROUGH */
1942 			default:
1943 				/* anything else implies that we're done */
1944 				done++;
1945 			}
1946 			/*
1947 			 * if we got here for some reason other than DNSRCH,
1948 			 * we only wanted one iteration of the loop, so stop.
1949 			 */
1950 			if (!(_res.options & RES_DNSRCH))
1951 			        done++;
1952 		}
1953 	}
1954 
1955 	/*
1956 	 * if we have not already tried the name "as is", do that now.
1957 	 * note that we do this regardless of how many dots were in the
1958 	 * name or whether it ends with a dot.
1959 	 */
1960 	if (!tried_as_is && (dots || !(_res.options & RES_NOTLDQUERY))) {
1961 		ret = res_querydomainN(name, NULL, target);
1962 		if (ret > 0)
1963 			return (ret);
1964 	}
1965 
1966 	/*
1967 	 * if we got here, we didn't satisfy the search.
1968 	 * if we did an initial full query, return that query's h_errno
1969 	 * (note that we wouldn't be here if that query had succeeded).
1970 	 * else if we ever got a nodata, send that back as the reason.
1971 	 * else send back meaningless h_errno, that being the one from
1972 	 * the last DNSRCH we did.
1973 	 */
1974 	if (saved_herrno != -1)
1975 		h_errno = saved_herrno;
1976 	else if (got_nodata)
1977 		h_errno = NO_DATA;
1978 	else if (got_servfail)
1979 		h_errno = TRY_AGAIN;
1980 	return (-1);
1981 }
1982 
1983 /*
1984  * Perform a call on res_query on the concatenation of name and domain,
1985  * removing a trailing dot from name if domain is NULL.
1986  */
1987 static int
1988 res_querydomainN(const char *name, const char *domain,
1989 		 struct res_target *target)
1990 {
1991 	char nbuf[MAXDNAME];
1992 	const char *longname = nbuf;
1993 	size_t n, d;
1994 
1995 	if ((_res.options & RES_INIT) == 0 && res_init() == -1) {
1996 		h_errno = NETDB_INTERNAL;
1997 		return (-1);
1998 	}
1999 #ifdef DEBUG
2000 	if (_res.options & RES_DEBUG)
2001 		printf(";; res_querydomain(%s, %s)\n",
2002 			name, domain?domain:"<Nil>");
2003 #endif
2004 	if (domain == NULL) {
2005 		/*
2006 		 * Check for trailing '.';
2007 		 * copy without '.' if present.
2008 		 */
2009 		n = strlen(name);
2010 		if (n >= MAXDNAME) {
2011 			h_errno = NO_RECOVERY;
2012 			return (-1);
2013 		}
2014 		if (n > 0 && name[--n] == '.') {
2015 			strncpy(nbuf, name, n);
2016 			nbuf[n] = '\0';
2017 		} else
2018 			longname = name;
2019 	} else {
2020 		n = strlen(name);
2021 		d = strlen(domain);
2022 		if (n + d + 1 >= MAXDNAME) {
2023 			h_errno = NO_RECOVERY;
2024 			return (-1);
2025 		}
2026 		snprintf(nbuf, sizeof(nbuf), "%s.%s", name, domain);
2027 	}
2028 	return (res_queryN(longname, target));
2029 }
2030