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