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 * $FreeBSD$ 30 */ 31 32 /* 33 * "#ifdef FAITH" part is local hack for supporting IPv4-v6 translator. 34 * 35 * Issues to be discussed: 36 * - Thread safe-ness must be checked. 37 * - Return values. There are nonstandard return values defined and used 38 * in the source code. This is because RFC2553 is silent about which error 39 * code must be returned for which situation. 40 * Note: 41 * - We use getipnodebyname() just for thread-safeness. There's no intent 42 * to let it do PF_UNSPEC (actually we never pass PF_UNSPEC to 43 * getipnodebyname(). 44 * - The code filters out AFs that are not supported by the kernel, 45 * when globbing NULL hostname (to loopback, or wildcard). Is it the right 46 * thing to do? What is the relationship with post-RFC2553 AI_ADDRCONFIG 47 * in ai_flags? 48 */ 49 50 #include <sys/types.h> 51 #include <sys/param.h> 52 #include <sys/socket.h> 53 #include <net/if.h> 54 #include <netinet/in.h> 55 #include <arpa/inet.h> 56 #include <arpa/nameser.h> 57 #include <netdb.h> 58 #include <resolv.h> 59 #include <string.h> 60 #include <stdlib.h> 61 #include <stddef.h> 62 #include <ctype.h> 63 #include <unistd.h> 64 #include <stdio.h> 65 66 #if defined(__KAME__) && defined(INET6) 67 # define FAITH 68 #endif 69 70 #define SUCCESS 0 71 #define ANY 0 72 #define YES 1 73 #define NO 0 74 75 static const char in_addrany[] = { 0, 0, 0, 0 }; 76 static const char in6_addrany[] = { 77 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 78 }; 79 static const char in_loopback[] = { 127, 0, 0, 1 }; 80 static const char in6_loopback[] = { 81 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 82 }; 83 84 static const struct afd { 85 int a_af; 86 int a_addrlen; 87 int a_socklen; 88 int a_off; 89 const char *a_addrany; 90 const char *a_loopback; 91 int a_scoped; 92 } afdl [] = { 93 #ifdef INET6 94 #define N_INET6 0 95 {PF_INET6, sizeof(struct in6_addr), 96 sizeof(struct sockaddr_in6), 97 offsetof(struct sockaddr_in6, sin6_addr), 98 in6_addrany, in6_loopback, 1}, 99 #define N_INET 1 100 #else 101 #define N_INET 0 102 #endif 103 {PF_INET, sizeof(struct in_addr), 104 sizeof(struct sockaddr_in), 105 offsetof(struct sockaddr_in, sin_addr), 106 in_addrany, in_loopback, 0}, 107 {0, 0, 0, 0, NULL, NULL, 0}, 108 }; 109 110 struct explore { 111 int e_af; 112 int e_socktype; 113 int e_protocol; 114 const char *e_protostr; 115 int e_wild; 116 #define WILD_AF(ex) ((ex)->e_wild & 0x01) 117 #define WILD_SOCKTYPE(ex) ((ex)->e_wild & 0x02) 118 #define WILD_PROTOCOL(ex) ((ex)->e_wild & 0x04) 119 }; 120 121 static const struct explore explore[] = { 122 #ifdef INET6 123 { PF_INET6, SOCK_DGRAM, IPPROTO_UDP, "udp", 0x07 }, 124 { PF_INET6, SOCK_STREAM, IPPROTO_TCP, "tcp", 0x07 }, 125 { PF_INET6, SOCK_RAW, ANY, NULL, 0x05 }, 126 #endif 127 { PF_INET, SOCK_DGRAM, IPPROTO_UDP, "udp", 0x07 }, 128 { PF_INET, SOCK_STREAM, IPPROTO_TCP, "tcp", 0x07 }, 129 { PF_INET, SOCK_RAW, ANY, NULL, 0x05 }, 130 { -1, 0, 0, NULL, 0 }, 131 }; 132 133 #ifdef INET6 134 #define PTON_MAX 16 135 #else 136 #define PTON_MAX 4 137 #endif 138 139 140 static int str_isnumber __P((const char *)); 141 static int explore_fqdn __P((const struct addrinfo *, const char *, 142 const char *, struct addrinfo **)); 143 static int explore_null __P((const struct addrinfo *, const char *, 144 const char *, struct addrinfo **)); 145 static int explore_numeric __P((const struct addrinfo *, const char *, 146 const char *, struct addrinfo **)); 147 static int explore_numeric_scope __P((const struct addrinfo *, const char *, 148 const char *, struct addrinfo **)); 149 static int get_canonname __P((const struct addrinfo *, 150 struct addrinfo *, const char *)); 151 static struct addrinfo *get_ai __P((const struct addrinfo *, 152 const struct afd *, const char *)); 153 static int get_portmatch __P((const struct addrinfo *, const char *)); 154 static int get_port __P((struct addrinfo *, const char *, int)); 155 static const struct afd *find_afd __P((int)); 156 157 static char *ai_errlist[] = { 158 "Success", 159 "Address family for hostname not supported", /* EAI_ADDRFAMILY */ 160 "Temporary failure in name resolution", /* EAI_AGAIN */ 161 "Invalid value for ai_flags", /* EAI_BADFLAGS */ 162 "Non-recoverable failure in name resolution", /* EAI_FAIL */ 163 "ai_family not supported", /* EAI_FAMILY */ 164 "Memory allocation failure", /* EAI_MEMORY */ 165 "No address associated with hostname", /* EAI_NODATA */ 166 "hostname nor servname provided, or not known", /* EAI_NONAME */ 167 "servname not supported for ai_socktype", /* EAI_SERVICE */ 168 "ai_socktype not supported", /* EAI_SOCKTYPE */ 169 "System error returned in errno", /* EAI_SYSTEM */ 170 "Invalid value for hints", /* EAI_BADHINTS */ 171 "Resolved protocol is unknown", /* EAI_PROTOCOL */ 172 "Argument res is NULL", /* EAI_RESNULL */ 173 "Unknown error", /* EAI_MAX */ 174 }; 175 176 /* XXX macros that make external reference is BAD. */ 177 178 #define GET_AI(ai, afd, addr) \ 179 do { \ 180 /* external reference: pai, error, and label free */ \ 181 (ai) = get_ai(pai, (afd), (addr)); \ 182 if ((ai) == NULL) { \ 183 error = EAI_MEMORY; \ 184 goto free; \ 185 } \ 186 } while (0) 187 188 #define GET_PORT(ai, serv) \ 189 do { \ 190 /* external reference: error and label free */ \ 191 error = get_port((ai), (serv), 0); \ 192 if (error != 0) \ 193 goto free; \ 194 } while (0) 195 196 #define GET_CANONNAME(ai, str) \ 197 do { \ 198 /* external reference: pai, error and label free */ \ 199 error = get_canonname(pai, (ai), (str)); \ 200 if (error != 0) \ 201 goto free; \ 202 } while (0) 203 204 #define ERR(err) \ 205 do { \ 206 /* external reference: error, and label bad */ \ 207 error = (err); \ 208 goto bad; \ 209 } while (0) 210 211 #define MATCH_FAMILY(x, y, w) \ 212 ((x) == (y) || ((w) && ((x) == PF_UNSPEC || (y) == PF_UNSPEC))) 213 #define MATCH(x, y, w) \ 214 ((x) == (y) || ((w) && ((x) == ANY || (y) == ANY))) 215 216 char * 217 gai_strerror(ecode) 218 int ecode; 219 { 220 if (ecode < 0 || ecode > EAI_MAX) 221 ecode = EAI_MAX; 222 return ai_errlist[ecode]; 223 } 224 225 void 226 freeaddrinfo(ai) 227 struct addrinfo *ai; 228 { 229 struct addrinfo *next; 230 231 do { 232 next = ai->ai_next; 233 if (ai->ai_canonname) 234 free(ai->ai_canonname); 235 /* no need to free(ai->ai_addr) */ 236 free(ai); 237 } while ((ai = next) != NULL); 238 } 239 240 static int 241 str_isnumber(p) 242 const char *p; 243 { 244 char *q = (char *)p; 245 while (*q) { 246 if (! isdigit(*q)) 247 return NO; 248 q++; 249 } 250 return YES; 251 } 252 253 int 254 getaddrinfo(hostname, servname, hints, res) 255 const char *hostname, *servname; 256 const struct addrinfo *hints; 257 struct addrinfo **res; 258 { 259 struct addrinfo sentinel; 260 struct addrinfo *cur; 261 int error = 0; 262 struct addrinfo ai; 263 struct addrinfo ai0; 264 struct addrinfo *pai; 265 const struct afd *afd; 266 const struct explore *ex; 267 268 sentinel.ai_next = NULL; 269 cur = &sentinel; 270 pai = &ai; 271 pai->ai_flags = 0; 272 pai->ai_family = PF_UNSPEC; 273 pai->ai_socktype = ANY; 274 pai->ai_protocol = ANY; 275 pai->ai_addrlen = 0; 276 pai->ai_canonname = NULL; 277 pai->ai_addr = NULL; 278 pai->ai_next = NULL; 279 280 if (hostname == NULL && servname == NULL) 281 return EAI_NONAME; 282 if (res == NULL) 283 return EAI_RESNULL; /* xxx */ 284 if (hints) { 285 /* error check for hints */ 286 if (hints->ai_addrlen || hints->ai_canonname || 287 hints->ai_addr || hints->ai_next) 288 ERR(EAI_BADHINTS); /* xxx */ 289 if (hints->ai_flags & ~AI_MASK) 290 ERR(EAI_BADFLAGS); 291 switch (hints->ai_family) { 292 case PF_UNSPEC: 293 case PF_INET: 294 #ifdef INET6 295 case PF_INET6: 296 #endif 297 break; 298 default: 299 ERR(EAI_FAMILY); 300 } 301 memcpy(pai, hints, sizeof(*pai)); 302 303 /* 304 * if both socktype/protocol are specified, check if they 305 * are meaningful combination. 306 */ 307 if (pai->ai_socktype != ANY && pai->ai_protocol != ANY) { 308 int matched = 0; 309 310 for (ex = explore; ex->e_af >= 0; ex++) { 311 if (pai->ai_family != ex->e_af) 312 continue; 313 if (ex->e_socktype == ANY) 314 continue; 315 if (ex->e_protocol == ANY) 316 continue; 317 if (pai->ai_socktype == ex->e_socktype 318 && pai->ai_protocol == ex->e_protocol) 319 matched = 1; 320 else 321 continue; 322 if (matched == 0) 323 ERR(EAI_BADHINTS); 324 } 325 } 326 } 327 328 /* backup original pai contents */ 329 ai0 = *pai; 330 331 /* 332 * special cases check for inet and inet6 sockets. 333 * (1) servname is disallowed for raw sockets. 334 * (2) numeric servname is disallowed if socktype/protocol is left 335 * unspecified. 336 */ 337 if (MATCH_FAMILY(pai->ai_family, PF_INET, 1) 338 #ifdef INET6 339 || MATCH_FAMILY(pai->ai_family, PF_INET6, 1) 340 #endif 341 ) { 342 *pai = ai0; 343 344 if (pai->ai_family == PF_UNSPEC) 345 #ifdef INET6 346 pai->ai_family = PF_INET6; 347 #else 348 pai->ai_family = PF_INET; 349 #endif 350 error = get_portmatch(pai, servname); 351 if (error) 352 ERR(error); 353 } 354 355 /* NULL hostname, or numeric hostname */ 356 for (ex = explore; ex->e_af >= 0; ex++) { 357 *pai = ai0; 358 359 if (!MATCH_FAMILY(pai->ai_family, ex->e_af, WILD_AF(ex))) 360 continue; 361 if (!MATCH(pai->ai_socktype, ex->e_socktype, WILD_SOCKTYPE(ex))) 362 continue; 363 if (!MATCH(pai->ai_protocol, ex->e_protocol, WILD_PROTOCOL(ex))) 364 continue; 365 366 if (pai->ai_family == PF_UNSPEC) 367 pai->ai_family = ex->e_af; 368 if (pai->ai_socktype == ANY && ex->e_socktype != ANY) 369 pai->ai_socktype = ex->e_socktype; 370 if (pai->ai_protocol == ANY && ex->e_protocol != ANY) 371 pai->ai_protocol = ex->e_protocol; 372 373 if (hostname == NULL) 374 error = explore_null(pai, hostname, servname, &cur->ai_next); 375 else 376 error = explore_numeric_scope(pai, hostname, servname, &cur->ai_next); 377 378 if (error) 379 goto free; 380 381 while (cur && cur->ai_next) 382 cur = cur->ai_next; 383 } 384 385 /* 386 * XXX 387 * If numreic representation of AF1 can be interpreted as FQDN 388 * representation of AF2, we need to think again about the code below. 389 */ 390 if (sentinel.ai_next) 391 goto good; 392 393 if (pai->ai_flags & AI_NUMERICHOST) 394 ERR(EAI_NONAME); 395 if (hostname == NULL) 396 ERR(EAI_NONAME); 397 398 /* 399 * hostname as alphabetical name. 400 * we would like to prefer AF_INET6 than AF_INET, so we'll make a 401 * outer loop by AFs. 402 */ 403 for (afd = afdl; afd->a_af; afd++) { 404 *pai = ai0; 405 406 if (!MATCH_FAMILY(pai->ai_family, afd->a_af, 1)) 407 continue; 408 409 for (ex = explore; ex->e_af >= 0; ex++) { 410 *pai = ai0; 411 412 if (pai->ai_family == PF_UNSPEC) 413 pai->ai_family = afd->a_af; 414 415 if (!MATCH_FAMILY(pai->ai_family, ex->e_af, 416 WILD_AF(ex))) 417 continue; 418 if (!MATCH(pai->ai_socktype, ex->e_socktype, 419 WILD_SOCKTYPE(ex))) { 420 continue; 421 } 422 if (!MATCH(pai->ai_protocol, ex->e_protocol, 423 WILD_PROTOCOL(ex))) { 424 continue; 425 } 426 427 if (pai->ai_family == PF_UNSPEC) 428 pai->ai_family = ex->e_af; 429 if (pai->ai_socktype == ANY && ex->e_socktype != ANY) 430 pai->ai_socktype = ex->e_socktype; 431 if (pai->ai_protocol == ANY && ex->e_protocol != ANY) 432 pai->ai_protocol = ex->e_protocol; 433 434 error = explore_fqdn(pai, hostname, servname, 435 &cur->ai_next); 436 437 while (cur && cur->ai_next) 438 cur = cur->ai_next; 439 } 440 } 441 442 /* XXX: if any addrinfo found, SUCCESS return even if (error != 0) */ 443 if (sentinel.ai_next) { 444 good: 445 *res = sentinel.ai_next; 446 return SUCCESS; 447 } 448 /* else, failed */ 449 free: 450 bad: 451 if (error == 0) 452 error = EAI_FAIL; 453 if (sentinel.ai_next) 454 freeaddrinfo(sentinel.ai_next); 455 *res = NULL; 456 return error; 457 } 458 459 /* 460 * FQDN hostname, DNS lookup 461 */ 462 static int 463 explore_fqdn(pai, hostname, servname, res) 464 const struct addrinfo *pai; 465 const char *hostname; 466 const char *servname; 467 struct addrinfo **res; 468 { 469 struct hostent *hp; 470 int h_error; 471 int af; 472 char *ap; 473 struct addrinfo sentinel, *cur; 474 int i; 475 const struct afd *afd; 476 int error; 477 478 *res = NULL; 479 sentinel.ai_next = NULL; 480 cur = &sentinel; 481 482 /* 483 * if the servname does not match socktype/protocol, ignore it. 484 */ 485 if (get_portmatch(pai, servname) != 0) 486 return 0; 487 488 afd = find_afd(pai->ai_family); 489 if (afd == NULL) 490 return 0; 491 492 hp = getipnodebyname(hostname, pai->ai_family, AI_ADDRCONFIG, 493 &h_error); 494 if (hp == NULL) { 495 switch (h_error) { 496 case HOST_NOT_FOUND: 497 case NO_DATA: 498 error = EAI_NODATA; 499 break; 500 case TRY_AGAIN: 501 error = EAI_AGAIN; 502 break; 503 case NO_RECOVERY: 504 case NETDB_INTERNAL: 505 default: 506 error = EAI_FAIL; 507 break; 508 } 509 } else if ((hp->h_name == NULL) || (hp->h_name[0] == 0) 510 || (hp->h_addr_list[0] == NULL)) { 511 freehostent(hp); 512 hp = NULL; 513 error = EAI_FAIL; 514 } 515 516 if (hp == NULL) 517 goto free; 518 519 for (i = 0; hp->h_addr_list[i] != NULL; i++) { 520 af = hp->h_addrtype; 521 ap = hp->h_addr_list[i]; 522 523 if (af != pai->ai_family) 524 continue; 525 526 GET_AI(cur->ai_next, afd, ap); 527 GET_PORT(cur->ai_next, servname); 528 if ((pai->ai_flags & AI_CANONNAME) != 0) { 529 /* 530 * RFC2553 says that ai_canonname will be set only for 531 * the first element. we do it for all the elements, 532 * just for convenience. 533 */ 534 GET_CANONNAME(cur->ai_next, hp->h_name); 535 } 536 537 while (cur && cur->ai_next) 538 cur = cur->ai_next; 539 } 540 541 *res = sentinel.ai_next; 542 return 0; 543 544 free: 545 if (hp) 546 freehostent(hp); 547 if (sentinel.ai_next) 548 freeaddrinfo(sentinel.ai_next); 549 return error; 550 } 551 552 /* 553 * hostname == NULL. 554 * passive socket -> anyaddr (0.0.0.0 or ::) 555 * non-passive socket -> localhost (127.0.0.1 or ::1) 556 */ 557 static int 558 explore_null(pai, hostname, servname, res) 559 const struct addrinfo *pai; 560 const char *hostname; 561 const char *servname; 562 struct addrinfo **res; 563 { 564 int s; 565 const struct afd *afd; 566 struct addrinfo *cur; 567 struct addrinfo sentinel; 568 int error; 569 570 *res = NULL; 571 sentinel.ai_next = NULL; 572 cur = &sentinel; 573 574 /* 575 * filter out AFs that are not supported by the kernel 576 * XXX errno? 577 */ 578 s = socket(pai->ai_family, SOCK_DGRAM, 0); 579 if (s < 0) 580 return 0; 581 _close(s); 582 afd = find_afd(pai->ai_family); 583 if (afd == NULL) 584 return 0; 585 586 GET_AI(cur->ai_next, afd, 587 (pai->ai_flags & AI_PASSIVE) ? afd->a_addrany : afd->a_loopback 588 ); 589 /* xxx meaningless? 590 * GET_CANONNAME(cur->ai_next, "anyaddr"); 591 * or 592 * GET_CANONNAME(cur->ai_next, "localhost"); 593 */ 594 /* if the servname does not match socktype/protocol, ignored */ 595 GET_PORT(cur->ai_next, servname); 596 597 *res = sentinel.ai_next; 598 return 0; 599 600 free: 601 if (sentinel.ai_next) 602 freeaddrinfo(sentinel.ai_next); 603 return error; 604 } 605 606 /* 607 * numeric hostname 608 */ 609 static int 610 explore_numeric(pai, hostname, servname, res) 611 const struct addrinfo *pai; 612 const char *hostname; 613 const char *servname; 614 struct addrinfo **res; 615 { 616 const struct afd *afd; 617 struct addrinfo *cur; 618 struct addrinfo sentinel; 619 int error; 620 char pton[PTON_MAX]; 621 int flags; 622 623 *res = NULL; 624 sentinel.ai_next = NULL; 625 cur = &sentinel; 626 627 /* 628 * if the servname does not match socktype/protocol, ignore it. 629 */ 630 if (get_portmatch(pai, servname) != 0) 631 return 0; 632 633 afd = find_afd(pai->ai_family); 634 if (afd == NULL) 635 return 0; 636 flags = pai->ai_flags; 637 638 if ((afd->a_af == AF_INET 639 ? inet_aton(hostname, (struct in_addr *)pton) 640 : inet_pton(afd->a_af, hostname, pton)) == 1) { 641 if (pai->ai_family == afd->a_af || 642 pai->ai_family == PF_UNSPEC /*?*/) { 643 GET_AI(cur->ai_next, afd, pton); 644 GET_PORT(cur->ai_next, servname); 645 while (cur && cur->ai_next) 646 cur = cur->ai_next; 647 } else 648 ERR(EAI_FAMILY); /*xxx*/ 649 } 650 651 *res = sentinel.ai_next; 652 return 0; 653 654 free: 655 bad: 656 if (sentinel.ai_next) 657 freeaddrinfo(sentinel.ai_next); 658 return error; 659 } 660 661 /* 662 * numeric hostname with scope 663 */ 664 static int 665 explore_numeric_scope(pai, hostname, servname, res) 666 const struct addrinfo *pai; 667 const char *hostname; 668 const char *servname; 669 struct addrinfo **res; 670 { 671 #ifndef SCOPE_DELIMITER 672 return explore_numeric(pai, hostname, servname, res); 673 #else 674 const struct afd *afd; 675 struct addrinfo *cur; 676 int error; 677 char *cp, *hostname2 = NULL; 678 int scope; 679 #ifdef INET6 680 struct sockaddr_in6 *sin6; 681 #endif 682 683 /* 684 * if the servname does not match socktype/protocol, ignore it. 685 */ 686 if (get_portmatch(pai, servname) != 0) 687 return 0; 688 689 afd = find_afd(pai->ai_family); 690 if (afd == NULL) 691 return 0; 692 if (!afd->a_scoped) 693 return explore_numeric(pai, hostname, servname, res); 694 695 cp = strchr(hostname, SCOPE_DELIMITER); 696 if (cp == NULL) 697 return explore_numeric(pai, hostname, servname, res); 698 699 /* 700 * Handle special case of <scoped_address><delimiter><scope id> 701 */ 702 hostname2 = strdup(hostname); 703 if (hostname2 == NULL) 704 return EAI_MEMORY; 705 /* terminate at the delimiter */ 706 hostname2[cp - hostname] = '\0'; 707 708 cp++; 709 switch (pai->ai_family) { 710 #ifdef INET6 711 case AF_INET6: 712 scope = if_nametoindex(cp); 713 if (scope == 0) { 714 error = EAI_SYSTEM; 715 goto free; 716 } 717 break; 718 #endif 719 } 720 721 error = explore_numeric(pai, hostname2, servname, res); 722 if (error == 0) { 723 for (cur = *res; cur; cur = cur->ai_next) { 724 #ifdef INET6 725 if (cur->ai_family != AF_INET6) 726 continue; 727 sin6 = (struct sockaddr_in6 *)cur->ai_addr; 728 if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr) || 729 IN6_IS_ADDR_MC_LINKLOCAL(&sin6->sin6_addr)) 730 sin6->sin6_scope_id = scope; 731 #endif 732 } 733 } 734 735 #ifdef INET6 736 free: 737 #endif 738 free(hostname2); 739 740 return error; 741 #endif 742 } 743 744 static int 745 get_canonname(pai, ai, str) 746 const struct addrinfo *pai; 747 struct addrinfo *ai; 748 const char *str; 749 { 750 if ((pai->ai_flags & AI_CANONNAME) != 0) { 751 ai->ai_canonname = (char *)malloc(strlen(str) + 1); 752 if (ai->ai_canonname == NULL) 753 return EAI_MEMORY; 754 strcpy(ai->ai_canonname, str); 755 } 756 return 0; 757 } 758 759 static struct addrinfo * 760 get_ai(pai, afd, addr) 761 const struct addrinfo *pai; 762 const struct afd *afd; 763 const char *addr; 764 { 765 char *p; 766 struct addrinfo *ai; 767 #ifdef FAITH 768 struct in6_addr faith_prefix; 769 char *fp_str; 770 int translate = 0; 771 #endif 772 773 #ifdef FAITH 774 /* 775 * Transfrom an IPv4 addr into a special IPv6 addr format for 776 * IPv6->IPv4 translation gateway. (only TCP is supported now) 777 * 778 * +-----------------------------------+------------+ 779 * | faith prefix part (12 bytes) | embedded | 780 * | | IPv4 addr part (4 bytes) 781 * +-----------------------------------+------------+ 782 * 783 * faith prefix part is specified as ascii IPv6 addr format 784 * in environmental variable GAI. 785 * For FAITH to work correctly, routing to faith prefix must be 786 * setup toward a machine where a FAITH daemon operates. 787 * Also, the machine must enable some mechanizm 788 * (e.g. faith interface hack) to divert those packet with 789 * faith prefixed destination addr to user-land FAITH daemon. 790 */ 791 fp_str = getenv("GAI"); 792 if (fp_str && inet_pton(AF_INET6, fp_str, &faith_prefix) == 1 && 793 afd->a_af == AF_INET && pai->ai_socktype == SOCK_STREAM) { 794 u_int32_t v4a; 795 u_int8_t v4a_top; 796 797 memcpy(&v4a, addr, sizeof v4a); 798 v4a_top = v4a >> IN_CLASSA_NSHIFT; 799 if (!IN_MULTICAST(v4a) && !IN_EXPERIMENTAL(v4a) && 800 v4a_top != 0 && v4a != IN_LOOPBACKNET) { 801 afd = &afdl[N_INET6]; 802 memcpy(&faith_prefix.s6_addr[12], addr, 803 sizeof(struct in_addr)); 804 translate = 1; 805 } 806 } 807 #endif 808 809 ai = (struct addrinfo *)malloc(sizeof(struct addrinfo) 810 + (afd->a_socklen)); 811 if (ai == NULL) 812 return NULL; 813 814 memcpy(ai, pai, sizeof(struct addrinfo)); 815 ai->ai_addr = (struct sockaddr *)(ai + 1); 816 memset(ai->ai_addr, 0, afd->a_socklen); 817 ai->ai_addr->sa_len = afd->a_socklen; 818 ai->ai_addrlen = afd->a_socklen; 819 ai->ai_addr->sa_family = ai->ai_family = afd->a_af; 820 p = (char *)(ai->ai_addr); 821 #ifdef FAITH 822 if (translate == 1) 823 memcpy(p + afd->a_off, &faith_prefix, afd->a_addrlen); 824 else 825 #endif 826 memcpy(p + afd->a_off, addr, afd->a_addrlen); 827 828 return ai; 829 } 830 831 static int 832 get_portmatch(ai, servname) 833 const struct addrinfo *ai; 834 const char *servname; 835 { 836 /* get_port does not touch first argument. when matchonly == 1. */ 837 return get_port((struct addrinfo *)ai, servname, 1); 838 } 839 840 static int 841 get_port(ai, servname, matchonly) 842 struct addrinfo *ai; 843 const char *servname; 844 int matchonly; 845 { 846 const char *proto; 847 struct servent *sp; 848 int port; 849 int allownumeric; 850 851 if (servname == NULL) 852 return 0; 853 if (ai->ai_family != AF_INET 854 #ifdef INET6 855 && ai->ai_family != AF_INET6 856 #endif 857 ) 858 return 0; 859 860 switch (ai->ai_socktype) { 861 case SOCK_RAW: 862 return EAI_SERVICE; 863 case SOCK_DGRAM: 864 case SOCK_STREAM: 865 allownumeric = 1; 866 break; 867 case ANY: 868 allownumeric = 0; 869 break; 870 default: 871 return EAI_SOCKTYPE; 872 } 873 874 if (str_isnumber(servname)) { 875 if (!allownumeric) 876 return EAI_SERVICE; 877 port = htons(atoi(servname)); 878 if (port < 0 || port > 65535) 879 return EAI_SERVICE; 880 } else { 881 switch (ai->ai_socktype) { 882 case SOCK_DGRAM: 883 proto = "udp"; 884 break; 885 case SOCK_STREAM: 886 proto = "tcp"; 887 break; 888 default: 889 proto = NULL; 890 break; 891 } 892 893 if ((sp = getservbyname(servname, proto)) == NULL) 894 return EAI_SERVICE; 895 port = sp->s_port; 896 } 897 898 if (!matchonly) { 899 switch (ai->ai_family) { 900 case AF_INET: 901 ((struct sockaddr_in *)ai->ai_addr)->sin_port = port; 902 break; 903 #ifdef INET6 904 case AF_INET6: 905 ((struct sockaddr_in6 *)ai->ai_addr)->sin6_port = port; 906 break; 907 #endif 908 } 909 } 910 911 return 0; 912 } 913 914 static const struct afd * 915 find_afd(af) 916 int af; 917 { 918 const struct afd *afd; 919 920 if (af == PF_UNSPEC) 921 return NULL; 922 for (afd = afdl; afd->a_af; afd++) { 923 if (afd->a_af == af) 924 return afd; 925 } 926 return NULL; 927 } 928