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