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