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