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