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.2 2003/11/15 23:24:06 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 255char * 256gai_strerror(ecode) 257 int ecode; 258{ 259 if (ecode < 0 || ecode > EAI_MAX) 260 ecode = EAI_MAX; 261 return ai_errlist[ecode]; 262} 263 264void 265freeaddrinfo(ai) 266 struct addrinfo *ai; 267{ 268 struct addrinfo *next; 269 270 do { 271 next = ai->ai_next; 272 if (ai->ai_canonname) 273 free(ai->ai_canonname); 274 /* no need to free(ai->ai_addr) */ 275 free(ai); 276 } while ((ai = next) != NULL); 277} 278 279static int 280str_isnumber(p) 281 const char *p; 282{ 283 char *q = (char *)p; 284 while (*q) { 285 if (! isdigit(*q)) 286 return NO; 287 q++; 288 } 289 return YES; 290} 291 292int 293getaddrinfo(hostname, servname, hints, res) 294 const char *hostname, *servname; 295 const struct addrinfo *hints; 296 struct addrinfo **res; 297{ 298 struct addrinfo sentinel; 299 struct addrinfo *cur; 300 int error = 0; 301 struct addrinfo ai; 302 struct addrinfo ai0; 303 struct addrinfo *pai; 304 const struct afd *afd; 305 const struct explore *ex; 306 307#ifdef FAITH 308 static int firsttime = 1; 309 310 if (firsttime) { 311 /* translator hack */ 312 char *q = getenv("GAI"); 313 if (q && inet_pton(AF_INET6, q, &faith_prefix) == 1) 314 translate = YES; 315 firsttime = 0; 316 } 317#endif 318 319 sentinel.ai_next = NULL; 320 cur = &sentinel; 321 pai = &ai; 322 pai->ai_flags = 0; 323 pai->ai_family = PF_UNSPEC; 324 pai->ai_socktype = ANY; 325 pai->ai_protocol = ANY; 326 pai->ai_addrlen = 0; 327 pai->ai_canonname = NULL; 328 pai->ai_addr = NULL; 329 pai->ai_next = NULL; 330 331 if (hostname == NULL && servname == NULL) 332 return EAI_NONAME; 333 if (hints) { 334 /* error check for hints */ 335 if (hints->ai_addrlen || hints->ai_canonname || 336 hints->ai_addr || hints->ai_next) 337 ERR(EAI_BADHINTS); /* xxx */ 338 if (hints->ai_flags & ~AI_MASK) 339 ERR(EAI_BADFLAGS); 340 switch (hints->ai_family) { 341 case PF_UNSPEC: 342 case PF_INET: 343#ifdef INET6 344 case PF_INET6: 345#endif 346 break; 347 default: 348 ERR(EAI_FAMILY); 349 } 350 memcpy(pai, hints, sizeof(*pai)); 351 352 /* 353 * if both socktype/protocol are specified, check if they 354 * are meaningful combination. 355 */ 356 if (pai->ai_socktype != ANY && pai->ai_protocol != ANY) { 357 for (ex = explore; ex->e_af >= 0; ex++) { 358 if (pai->ai_family != ex->e_af) 359 continue; 360 if (ex->e_socktype == ANY) 361 continue; 362 if (ex->e_protocol == ANY) 363 continue; 364 if (pai->ai_socktype == ex->e_socktype 365 && pai->ai_protocol != ex->e_protocol) { 366 ERR(EAI_BADHINTS); 367 } 368 } 369 } 370 } 371 372 /* 373 * check for special cases. (1) numeric servname is disallowed if 374 * socktype/protocol are left unspecified. (2) servname is disallowed 375 * for raw and other inet{,6} sockets. 376 */ 377 if (MATCH_FAMILY(pai->ai_family, PF_INET, 1) 378#ifdef PF_INET6 379 || MATCH_FAMILY(pai->ai_family, PF_INET6, 1) 380#endif 381 ) { 382 ai0 = *pai; 383 384 if (pai->ai_family == PF_UNSPEC) { 385#ifdef PF_INET6 386 pai->ai_family = PF_INET6; 387#else 388 pai->ai_family = PF_INET; 389#endif 390 } 391 error = get_portmatch(pai, servname); 392 if (error) 393 ERR(error); 394 395 *pai = ai0; 396 } 397 398 ai0 = *pai; 399 400 /* NULL hostname, or numeric hostname */ 401 for (ex = explore; ex->e_af >= 0; ex++) { 402 *pai = ai0; 403 404 if (!MATCH_FAMILY(pai->ai_family, ex->e_af, WILD_AF(ex))) 405 continue; 406 if (!MATCH(pai->ai_socktype, ex->e_socktype, WILD_SOCKTYPE(ex))) 407 continue; 408 if (!MATCH(pai->ai_protocol, ex->e_protocol, WILD_PROTOCOL(ex))) 409 continue; 410 411 if (pai->ai_family == PF_UNSPEC) 412 pai->ai_family = ex->e_af; 413 if (pai->ai_socktype == ANY && ex->e_socktype != ANY) 414 pai->ai_socktype = ex->e_socktype; 415 if (pai->ai_protocol == ANY && ex->e_protocol != ANY) 416 pai->ai_protocol = ex->e_protocol; 417 418 if (hostname == NULL) 419 error = explore_null(pai, hostname, servname, &cur->ai_next); 420 else 421 error = explore_numeric_scope(pai, hostname, servname, &cur->ai_next); 422 423 if (error) 424 goto free; 425 426 while (cur && cur->ai_next) 427 cur = cur->ai_next; 428 } 429 430 /* 431 * XXX 432 * If numreic representation of AF1 can be interpreted as FQDN 433 * representation of AF2, we need to think again about the code below. 434 */ 435 if (sentinel.ai_next) 436 goto good; 437 438 if (pai->ai_flags & AI_NUMERICHOST) 439 ERR(EAI_NONAME); 440 if (hostname == NULL) 441 ERR(EAI_NONAME); 442 443 /* 444 * hostname as alphabetical name. 445 * we would like to prefer AF_INET6 than AF_INET, so we'll make a 446 * outer loop by AFs. 447 */ 448 for (afd = afdl; afd->a_af; afd++) { 449 *pai = ai0; 450 451 if (!MATCH_FAMILY(pai->ai_family, afd->a_af, 1)) 452 continue; 453 454 for (ex = explore; ex->e_af >= 0; ex++) { 455 *pai = ai0; 456 457 if (pai->ai_family == PF_UNSPEC) 458 pai->ai_family = afd->a_af; 459 460 if (!MATCH_FAMILY(pai->ai_family, ex->e_af, WILD_AF(ex))) 461 continue; 462 if (!MATCH(pai->ai_socktype, ex->e_socktype, 463 WILD_SOCKTYPE(ex))) { 464 continue; 465 } 466 if (!MATCH(pai->ai_protocol, ex->e_protocol, 467 WILD_PROTOCOL(ex))) { 468 continue; 469 } 470 471 if (pai->ai_family == PF_UNSPEC) 472 pai->ai_family = ex->e_af; 473 if (pai->ai_socktype == ANY && ex->e_socktype != ANY) 474 pai->ai_socktype = ex->e_socktype; 475 if (pai->ai_protocol == ANY && ex->e_protocol != ANY) 476 pai->ai_protocol = ex->e_protocol; 477 478 error = explore_fqdn(pai, hostname, servname, 479 &cur->ai_next); 480 481 while (cur && cur->ai_next) 482 cur = cur->ai_next; 483 } 484 } 485 486 /* XXX */ 487 if (sentinel.ai_next) 488 error = 0; 489 490 if (error) 491 goto free; 492 if (error == 0) { 493 if (sentinel.ai_next) { 494 good: 495 *res = sentinel.ai_next; 496 return SUCCESS; 497 } else 498 error = EAI_FAIL; 499 } 500 free: 501 bad: 502 if (sentinel.ai_next) 503 freeaddrinfo(sentinel.ai_next); 504 *res = NULL; 505 return error; 506} 507 508/* 509 * FQDN hostname, DNS lookup 510 */ 511static int 512explore_fqdn(pai, hostname, servname, res) 513 const struct addrinfo *pai; 514 const char *hostname; 515 const char *servname; 516 struct addrinfo **res; 517{ 518 struct hostent *hp; 519 int h_error; 520 int af; 521 char **aplist = NULL, *apbuf = NULL; 522 char *ap; 523 struct addrinfo sentinel, *cur; 524 int i; 525#ifndef USE_GETIPNODEBY 526 int naddrs; 527#endif 528 const struct afd *afd; 529 int error; 530 531 *res = NULL; 532 sentinel.ai_next = NULL; 533 cur = &sentinel; 534 535 /* 536 * Do not filter unsupported AFs here. We need to honor content of 537 * databases (/etc/hosts, DNS and others). Otherwise we cannot 538 * replace gethostbyname() by getaddrinfo(). 539 */ 540 541 /* 542 * if the servname does not match socktype/protocol, ignore it. 543 */ 544 if (get_portmatch(pai, servname) != 0) 545 return 0; 546 547 afd = find_afd(pai->ai_family); 548 549 /* 550 * post-RFC2553: should look at (pai->ai_flags & AI_ADDRCONFIG) 551 * rather than hardcoding it. we may need to add AI_ADDRCONFIG 552 * handling code by ourselves in case we don't have getipnodebyname(). 553 */ 554#ifdef USE_GETIPNODEBY 555 hp = getipnodebyname(hostname, pai->ai_family, AI_ADDRCONFIG, &h_error); 556#else 557#ifdef HAVE_GETHOSTBYNAME2 558 hp = gethostbyname2(hostname, pai->ai_family); 559#else 560 if (pai->ai_family != AF_INET) 561 return 0; 562 hp = gethostbyname(hostname); 563#ifdef HAVE_H_ERRNO 564 h_error = h_errno; 565#else 566 h_error = EINVAL; 567#endif 568#endif /*HAVE_GETHOSTBYNAME2*/ 569#endif /*USE_GETIPNODEBY*/ 570 571 if (hp == NULL) { 572 switch (h_error) { 573 case HOST_NOT_FOUND: 574 case NO_DATA: 575 error = EAI_NODATA; 576 break; 577 case TRY_AGAIN: 578 error = EAI_AGAIN; 579 break; 580 case NO_RECOVERY: 581 case NETDB_INTERNAL: 582 default: 583 error = EAI_FAIL; 584 break; 585 } 586 } else if ((hp->h_name == NULL) || (hp->h_name[0] == 0) 587 || (hp->h_addr_list[0] == NULL)) { 588#ifdef USE_GETIPNODEBY 589 freehostent(hp); 590#endif 591 hp = NULL; 592 error = EAI_FAIL; 593 } 594 595 if (hp == NULL) 596 goto free; 597 598#ifdef USE_GETIPNODEBY 599 aplist = hp->h_addr_list; 600#else 601 /* 602 * hp will be overwritten if we use gethostbyname2(). 603 * always deep copy for simplification. 604 */ 605 for (naddrs = 0; hp->h_addr_list[naddrs] != NULL; naddrs++) 606 ; 607 naddrs++; 608 aplist = (char **)malloc(sizeof(aplist[0]) * naddrs); 609 apbuf = (char *)malloc(hp->h_length * naddrs); 610 if (aplist == NULL || apbuf == NULL) { 611 error = EAI_MEMORY; 612 goto free; 613 } 614 memset(aplist, 0, sizeof(aplist[0]) * naddrs); 615 for (i = 0; i < naddrs; i++) { 616 if (hp->h_addr_list[i] == NULL) { 617 aplist[i] = NULL; 618 continue; 619 } 620 memcpy(&apbuf[i * hp->h_length], hp->h_addr_list[i], 621 hp->h_length); 622 aplist[i] = &apbuf[i * hp->h_length]; 623 } 624#endif 625 626 for (i = 0; aplist[i] != NULL; i++) { 627 af = hp->h_addrtype; 628 ap = aplist[i]; 629#ifdef AF_INET6 630 if (af == AF_INET6 631 && IN6_IS_ADDR_V4MAPPED((struct in6_addr *)ap)) { 632 af = AF_INET; 633 ap = ap + sizeof(struct in6_addr) 634 - sizeof(struct in_addr); 635 } 636#endif 637 638 if (af != pai->ai_family) 639 continue; 640 641 if ((pai->ai_flags & AI_CANONNAME) == 0) { 642 GET_AI(cur->ai_next, afd, ap); 643 GET_PORT(cur->ai_next, servname); 644 } else { 645 /* 646 * if AI_CANONNAME and if reverse lookup 647 * fail, return ai anyway to pacify 648 * calling application. 649 * 650 * XXX getaddrinfo() is a name->address 651 * translation function, and it looks 652 * strange that we do addr->name 653 * translation here. 654 */ 655 get_name(ap, afd, &cur->ai_next, 656 ap, pai, servname); 657 } 658 659 while (cur && cur->ai_next) 660 cur = cur->ai_next; 661 } 662 663 *res = sentinel.ai_next; 664 return 0; 665 666free: 667#ifdef USE_GETIPNODEBY 668 if (hp) 669 freehostent(hp); 670#endif 671 if (aplist) 672 free(aplist); 673 if (apbuf) 674 free(apbuf); 675 if (sentinel.ai_next) 676 freeaddrinfo(sentinel.ai_next); 677 return error; 678} 679 680/* 681 * hostname == NULL. 682 * passive socket -> anyaddr (0.0.0.0 or ::) 683 * non-passive socket -> localhost (127.0.0.1 or ::1) 684 */ 685static int 686explore_null(pai, hostname, servname, res) 687 const struct addrinfo *pai; 688 const char *hostname; 689 const char *servname; 690 struct addrinfo **res; 691{ 692 int s; 693 const struct afd *afd; 694 struct addrinfo *cur; 695 struct addrinfo sentinel; 696 int error; 697 698 *res = NULL; 699 sentinel.ai_next = NULL; 700 cur = &sentinel; 701 702 /* 703 * filter out AFs that are not supported by the kernel 704 * XXX errno? 705 */ 706 s = socket(pai->ai_family, SOCK_DGRAM, 0); 707 if (s < 0) { 708 if (errno != EMFILE) 709 return 0; 710 } else 711 close(s); 712 713 /* 714 * if the servname does not match socktype/protocol, ignore it. 715 */ 716 if (get_portmatch(pai, servname) != 0) 717 return 0; 718 719 afd = find_afd(pai->ai_family); 720 721 if (pai->ai_flags & AI_PASSIVE) { 722 GET_AI(cur->ai_next, afd, afd->a_addrany); 723 /* xxx meaningless? 724 * GET_CANONNAME(cur->ai_next, "anyaddr"); 725 */ 726 GET_PORT(cur->ai_next, servname); 727 } else { 728 GET_AI(cur->ai_next, afd, afd->a_loopback); 729 /* xxx meaningless? 730 * GET_CANONNAME(cur->ai_next, "localhost"); 731 */ 732 GET_PORT(cur->ai_next, servname); 733 } 734 cur = cur->ai_next; 735 736 *res = sentinel.ai_next; 737 return 0; 738 739free: 740 if (sentinel.ai_next) 741 freeaddrinfo(sentinel.ai_next); 742 return error; 743} 744 745/* 746 * numeric hostname 747 */ 748static int 749explore_numeric(pai, hostname, servname, res) 750 const struct addrinfo *pai; 751 const char *hostname; 752 const char *servname; 753 struct addrinfo **res; 754{ 755 const struct afd *afd; 756 struct addrinfo *cur; 757 struct addrinfo sentinel; 758 int error; 759 char pton[PTON_MAX]; 760 int flags; 761 762 *res = NULL; 763 sentinel.ai_next = NULL; 764 cur = &sentinel; 765 766 /* 767 * if the servname does not match socktype/protocol, ignore it. 768 */ 769 if (get_portmatch(pai, servname) != 0) 770 return 0; 771 772 afd = find_afd(pai->ai_family); 773 flags = pai->ai_flags; 774 775 if (inet_pton(afd->a_af, hostname, pton) == 1) { 776 u_int32_t v4a; 777#ifdef INET6 778 u_char pfx; 779#endif 780 781 switch (afd->a_af) { 782 case AF_INET: 783 v4a = (u_int32_t)ntohl(((struct in_addr *)pton)->s_addr); 784 if (IN_MULTICAST(v4a) || IN_EXPERIMENTAL(v4a)) 785 flags &= ~AI_CANONNAME; 786 v4a >>= IN_CLASSA_NSHIFT; 787 if (v4a == 0 || v4a == IN_LOOPBACKNET) 788 flags &= ~AI_CANONNAME; 789 break; 790#ifdef INET6 791 case AF_INET6: 792 pfx = ((struct in6_addr *)pton)->s6_addr[0]; 793 if (pfx == 0 || pfx == 0xfe || pfx == 0xff) 794 flags &= ~AI_CANONNAME; 795 break; 796#endif 797 } 798 799 if (pai->ai_family == afd->a_af || 800 pai->ai_family == PF_UNSPEC /*?*/) { 801 if ((flags & AI_CANONNAME) == 0) { 802 GET_AI(cur->ai_next, afd, pton); 803 GET_PORT(cur->ai_next, servname); 804 } else { 805 /* 806 * if AI_CANONNAME and if reverse lookup 807 * fail, return ai anyway to pacify 808 * calling application. 809 * 810 * XXX getaddrinfo() is a name->address 811 * translation function, and it looks 812 * strange that we do addr->name 813 * translation here. 814 */ 815 get_name(pton, afd, &cur->ai_next, 816 pton, pai, servname); 817 } 818 while (cur && cur->ai_next) 819 cur = cur->ai_next; 820 } else 821 ERR(EAI_FAMILY); /*xxx*/ 822 } 823 824 *res = sentinel.ai_next; 825 return 0; 826 827free: 828bad: 829 if (sentinel.ai_next) 830 freeaddrinfo(sentinel.ai_next); 831 return error; 832} 833 834/* 835 * numeric hostname with scope 836 */ 837static int 838explore_numeric_scope(pai, hostname, servname, res) 839 const struct addrinfo *pai; 840 const char *hostname; 841 const char *servname; 842 struct addrinfo **res; 843{ 844#ifndef SCOPE_DELIMITER 845 return explore_numeric(pai, hostname, servname, res); 846#else 847 const struct afd *afd; 848 struct addrinfo *cur; 849 int error; 850 char *cp, *hostname2 = NULL; 851 int scope; 852 struct sockaddr_in6 *sin6; 853 854 /* 855 * if the servname does not match socktype/protocol, ignore it. 856 */ 857 if (get_portmatch(pai, servname) != 0) 858 return 0; 859 860 afd = find_afd(pai->ai_family); 861 if (!afd->a_scoped) 862 return explore_numeric(pai, hostname, servname, res); 863 864 cp = strchr(hostname, SCOPE_DELIMITER); 865 if (cp == NULL) 866 return explore_numeric(pai, hostname, servname, res); 867 868 /* 869 * Handle special case of <scoped_address><delimiter><scope id> 870 */ 871 hostname2 = strdup(hostname); 872 if (hostname2 == NULL) 873 return EAI_MEMORY; 874 /* terminate at the delimiter */ 875 hostname2[cp - hostname] = '\0'; 876 877 cp++; 878 switch (pai->ai_family) { 879#ifdef INET6 880 case AF_INET6: 881 scope = if_nametoindex(cp); 882 if (scope == 0) { 883 free(hostname2); 884 return (EAI_NONAME); 885 } 886 break; 887#endif 888 } 889 890 error = explore_numeric(pai, hostname2, servname, res); 891 if (error == 0) { 892 for (cur = *res; cur; cur = cur->ai_next) { 893 if (cur->ai_family != AF_INET6) 894 continue; 895 sin6 = (struct sockaddr_in6 *)cur->ai_addr; 896 if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr) || 897 IN6_IS_ADDR_MC_LINKLOCAL(&sin6->sin6_addr)) 898 sin6->sin6_scope_id = scope; 899 } 900 } 901 902 free(hostname2); 903 904 return error; 905#endif 906} 907 908static int 909get_name(addr, afd, res, numaddr, pai, servname) 910 const char *addr; 911 const struct afd *afd; 912 struct addrinfo **res; 913 char *numaddr; 914 const struct addrinfo *pai; 915 const char *servname; 916{ 917 struct hostent *hp = NULL; 918 struct addrinfo *cur = NULL; 919 int error = 0; 920 char *ap = NULL, *cn = NULL; 921#ifdef USE_GETIPNODEBY 922 int h_error; 923 924 hp = getipnodebyaddr(addr, afd->a_addrlen, afd->a_af, &h_error); 925#else 926 hp = gethostbyaddr(addr, afd->a_addrlen, afd->a_af); 927#endif 928 if (hp && hp->h_name && hp->h_name[0] && hp->h_addr_list[0]) { 929#ifdef USE_GETIPNODEBY 930 GET_AI(cur, afd, hp->h_addr_list[0]); 931 GET_PORT(cur, servname); 932 GET_CANONNAME(cur, hp->h_name); 933#else 934 /* hp will be damaged if we use gethostbyaddr() */ 935 if ((ap = (char *)malloc(hp->h_length)) == NULL) { 936 error = EAI_MEMORY; 937 goto free; 938 } 939 memcpy(ap, hp->h_addr_list[0], hp->h_length); 940 if ((cn = strdup(hp->h_name)) == NULL) { 941 error = EAI_MEMORY; 942 goto free; 943 } 944 945 GET_AI(cur, afd, ap); 946 GET_PORT(cur, servname); 947 GET_CANONNAME(cur, cn); 948 free(ap); ap = NULL; 949 free(cn); cn = NULL; 950#endif 951 } else { 952 GET_AI(cur, afd, numaddr); 953 GET_PORT(cur, servname); 954 } 955 956#ifdef USE_GETIPNODEBY 957 if (hp) 958 freehostent(hp); 959#endif 960 *res = cur; 961 return SUCCESS; 962 free: 963 if (cur) 964 freeaddrinfo(cur); 965 if (ap) 966 free(ap); 967 if (cn) 968 free(cn); 969#ifdef USE_GETIPNODEBY 970 if (hp) 971 freehostent(hp); 972#endif 973 *res = NULL; 974 return error; 975} 976 977static int 978get_canonname(pai, ai, str) 979 const struct addrinfo *pai; 980 struct addrinfo *ai; 981 const char *str; 982{ 983 if ((pai->ai_flags & AI_CANONNAME) != 0) { 984 ai->ai_canonname = (char *)malloc(strlen(str) + 1); 985 if (ai->ai_canonname == NULL) 986 return EAI_MEMORY; 987 strcpy(ai->ai_canonname, str); 988 } 989 return 0; 990} 991 992static struct addrinfo * 993get_ai(pai, afd, addr) 994 const struct addrinfo *pai; 995 const struct afd *afd; 996 const char *addr; 997{ 998 char *p; 999 struct addrinfo *ai; 1000 1001 ai = (struct addrinfo *)malloc(sizeof(struct addrinfo) 1002 + (afd->a_socklen)); 1003 if (ai == NULL) 1004 return NULL; 1005 1006 memcpy(ai, pai, sizeof(struct addrinfo)); 1007 ai->ai_addr = (struct sockaddr *)(ai + 1); 1008 memset(ai->ai_addr, 0, afd->a_socklen); 1009#ifdef HAVE_SOCKADDR_SA_LEN 1010 ai->ai_addr->sa_len = afd->a_socklen; 1011#endif 1012 ai->ai_addrlen = afd->a_socklen; 1013 ai->ai_addr->sa_family = ai->ai_family = afd->a_af; 1014 p = (char *)(ai->ai_addr); 1015 memcpy(p + afd->a_off, addr, afd->a_addrlen); 1016 return ai; 1017} 1018 1019static int 1020get_portmatch(ai, servname) 1021 const struct addrinfo *ai; 1022 const char *servname; 1023{ 1024 1025 /* get_port does not touch first argument. when matchonly == 1. */ 1026 return get_port((struct addrinfo *)ai, servname, 1); 1027} 1028 1029static int 1030get_port(ai, servname, matchonly) 1031 struct addrinfo *ai; 1032 const char *servname; 1033 int matchonly; 1034{ 1035 const char *proto; 1036 struct servent *sp; 1037 int port; 1038 int allownumeric; 1039 1040 if (servname == NULL) 1041 return 0; 1042 switch (ai->ai_family) { 1043 case AF_INET: 1044#ifdef AF_INET6 1045 case AF_INET6: 1046#endif 1047 break; 1048 default: 1049 return 0; 1050 } 1051 1052 switch (ai->ai_socktype) { 1053 case SOCK_RAW: 1054 return EAI_SERVICE; 1055 case SOCK_DGRAM: 1056 case SOCK_STREAM: 1057 allownumeric = 1; 1058 break; 1059 case ANY: 1060 allownumeric = 0; 1061 break; 1062 default: 1063 return EAI_SOCKTYPE; 1064 } 1065 1066 if (str_isnumber(servname)) { 1067 if (!allownumeric) 1068 return EAI_SERVICE; 1069 port = htons(atoi(servname)); 1070 if (port < 0 || port > 65535) 1071 return EAI_SERVICE; 1072 } else { 1073 switch (ai->ai_socktype) { 1074 case SOCK_DGRAM: 1075 proto = "udp"; 1076 break; 1077 case SOCK_STREAM: 1078 proto = "tcp"; 1079 break; 1080 default: 1081 proto = NULL; 1082 break; 1083 } 1084 1085 if ((sp = getservbyname(servname, proto)) == NULL) 1086 return EAI_SERVICE; 1087 port = sp->s_port; 1088 } 1089 1090 if (!matchonly) { 1091 switch (ai->ai_family) { 1092 case AF_INET: 1093 ((struct sockaddr_in *)ai->ai_addr)->sin_port = port; 1094 break; 1095#ifdef INET6 1096 case AF_INET6: 1097 ((struct sockaddr_in6 *)ai->ai_addr)->sin6_port = port; 1098 break; 1099#endif 1100 } 1101 } 1102 1103 return 0; 1104} 1105 1106static const struct afd * 1107find_afd(af) 1108 int af; 1109{ 1110 const struct afd *afd; 1111 1112 if (af == PF_UNSPEC) 1113 return NULL; 1114 for (afd = afdl; afd->a_af; afd++) { 1115 if (afd->a_af == af) 1116 return afd; 1117 } 1118 return NULL; 1119} 1120