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