1 /* 2 * ++Copyright++ 1985, 1988, 1993 3 * - 4 * Copyright (c) 1985, 1988, 1993 5 * The Regents of the University of California. All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 3. All advertising materials mentioning features or use of this software 16 * must display the following acknowledgement: 17 * This product includes software developed by the University of 18 * California, Berkeley and its contributors. 19 * 4. Neither the name of the University nor the names of its contributors 20 * may be used to endorse or promote products derived from this software 21 * without specific prior written permission. 22 * 23 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 26 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 33 * SUCH DAMAGE. 34 * - 35 * Portions Copyright (c) 1993 by Digital Equipment Corporation. 36 * 37 * Permission to use, copy, modify, and distribute this software for any 38 * purpose with or without fee is hereby granted, provided that the above 39 * copyright notice and this permission notice appear in all copies, and that 40 * the name of Digital Equipment Corporation not be used in advertising or 41 * publicity pertaining to distribution of the document or software without 42 * specific, written prior permission. 43 * 44 * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL 45 * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES 46 * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT 47 * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL 48 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR 49 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS 50 * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS 51 * SOFTWARE. 52 * - 53 * --Copyright-- 54 */ 55 56 /* 57 * Portions copyright (c) 1999, 2000 58 * Intel Corporation. 59 * All rights reserved. 60 * 61 * Redistribution and use in source and binary forms, with or without 62 * modification, are permitted provided that the following conditions 63 * are met: 64 * 65 * 1. Redistributions of source code must retain the above copyright 66 * notice, this list of conditions and the following disclaimer. 67 * 68 * 2. Redistributions in binary form must reproduce the above copyright 69 * notice, this list of conditions and the following disclaimer in the 70 * documentation and/or other materials provided with the distribution. 71 * 72 * 3. All advertising materials mentioning features or use of this software 73 * must display the following acknowledgement: 74 * 75 * This product includes software developed by Intel Corporation and 76 * its contributors. 77 * 78 * 4. Neither the name of Intel Corporation or its contributors may be 79 * used to endorse or promote products derived from this software 80 * without specific prior written permission. 81 * 82 * THIS SOFTWARE IS PROVIDED BY INTEL CORPORATION AND CONTRIBUTORS ``AS IS'' 83 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 84 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 85 * ARE DISCLAIMED. IN NO EVENT SHALL INTEL CORPORATION OR CONTRIBUTORS BE 86 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 87 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 88 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 89 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 90 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 91 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 92 * THE POSSIBILITY OF SUCH DAMAGE. 93 * 94 */ 95 96 #if defined(LIBC_SCCS) && !defined(lint) 97 static char sccsid[] = "@(#)gethostnamadr.c 8.1 (Berkeley) 6/4/93"; 98 static char fromrcsid[] = "From: Id: gethnamaddr.c,v 8.23 1998/04/07 04:59:46 vixie Exp $"; 99 static char rcsid[] = "$Id: gethostbydns.c,v 1.1.1.1 2003/11/19 01:51:27 kyu3 Exp $"; 100 #endif /* LIBC_SCCS and not lint */ 101 102 #include <sys/types.h> 103 #include <sys/param.h> 104 #include <sys/socket.h> 105 #include <netinet/in.h> 106 #include <arpa/inet.h> 107 #include <arpa/nameser.h> 108 109 #include <stdio.h> 110 #include <unistd.h> 111 #include <string.h> 112 #include <netdb.h> 113 #include <resolv.h> 114 #include <ctype.h> 115 #include <errno.h> 116 #ifdef _ORG_FREEBSD_ 117 #include <syslog.h> 118 #else 119 #include <stdlib.h> 120 u_int32_t _getlong(const u_char *src); 121 u_int16_t _getshort(const u_char *src); 122 #endif 123 124 #include "res_config.h" 125 #include "Socklib_internals.h" 126 127 #define SPRINTF(x) ((size_t)sprintf x) 128 129 #define MAXALIASES 35 130 #define MAXADDRS 35 131 132 static const char AskedForGot[] = 133 "gethostby*.gethostanswer: asked for \"%s\", got \"%s\""; 134 135 static char *h_addr_ptrs[MAXADDRS + 1]; 136 137 static struct hostent host; 138 static char *host_aliases[MAXALIASES]; 139 static char hostbuf[8*1024]; 140 static u_char host_addr[16]; /* IPv4 or IPv6 */ 141 142 #ifdef RESOLVSORT 143 static void addrsort(char **, int); 144 #endif 145 146 #if PACKETSZ > 1024 147 #define MAXPACKET PACKETSZ 148 #else 149 #define MAXPACKET 1024 150 #endif 151 152 typedef union { 153 HEADER hdr; 154 u_char buf[MAXPACKET]; 155 } querybuf; 156 157 typedef union { 158 int32_t al; 159 char ac; 160 } align; 161 162 extern int h_errno; 163 int _dns_ttl_; 164 165 #ifdef DEBUG_RES 166 static void 167 dprintf(char *msg, int num) 168 { 169 if (_res.options & RES_DEBUG) { 170 int save = errno; 171 172 printf(msg, num); 173 errno = save; 174 } 175 } 176 #else 177 # define dprintf(msg, num) /*nada*/ 178 #endif 179 180 #define BOUNDED_INCR(x) \ 181 do { \ 182 cp += x; \ 183 if (cp > eom) { \ 184 h_errno = NO_RECOVERY; \ 185 return (NULL); \ 186 } \ 187 } while (0) 188 189 #define BOUNDS_CHECK(ptr, count) \ 190 do { \ 191 if ((ptr) + (count) > eom) { \ 192 h_errno = NO_RECOVERY; \ 193 return (NULL); \ 194 } \ 195 } while (0) 196 197 static struct hostent * 198 gethostanswer(const querybuf *answer, int anslen, const char *qname, int qtype) 199 { 200 register const HEADER *hp; 201 register const u_char *cp; 202 register int n; 203 const u_char *eom, *erdata; 204 char *bp, **ap, **hap; 205 int type, class, buflen, ancount, qdcount; 206 int haveanswer, had_error; 207 int toobig = 0; 208 char tbuf[MAXDNAME]; 209 const char *tname; 210 int (*name_ok)(const char *); 211 212 tname = qname; 213 host.h_name = NULL; 214 eom = answer->buf + anslen; 215 switch (qtype) { 216 case T_A: 217 case T_AAAA: 218 name_ok = res_hnok; 219 break; 220 case T_PTR: 221 name_ok = res_dnok; 222 break; 223 default: 224 h_errno = NO_RECOVERY; 225 return (NULL); /* XXX should be abort(); */ 226 } 227 /* 228 * find first satisfactory answer 229 */ 230 hp = &answer->hdr; 231 ancount = ntohs(hp->ancount); 232 qdcount = ntohs(hp->qdcount); 233 bp = hostbuf; 234 buflen = sizeof hostbuf; 235 cp = answer->buf; 236 BOUNDED_INCR(HFIXEDSZ); 237 if (qdcount != 1) { 238 h_errno = NO_RECOVERY; 239 return (NULL); 240 } 241 n = dn_expand(answer->buf, eom, cp, bp, buflen); 242 if ((n < 0) || !(*name_ok)(bp)) { 243 h_errno = NO_RECOVERY; 244 return (NULL); 245 } 246 BOUNDED_INCR(n + QFIXEDSZ); 247 if (qtype == T_A || qtype == T_AAAA) { 248 /* res_send() has already verified that the query name is the 249 * same as the one we sent; this just gets the expanded name 250 * (i.e., with the succeeding search-domain tacked on). 251 */ 252 n = (int)strlen(bp) + 1; /* for the \0 */ 253 if (n >= MAXHOSTNAMELEN) { 254 h_errno = NO_RECOVERY; 255 return (NULL); 256 } 257 host.h_name = bp; 258 bp += n; 259 buflen -= n; 260 /* The qname can be abbreviated, but h_name is now absolute. */ 261 qname = host.h_name; 262 } 263 ap = host_aliases; 264 *ap = NULL; 265 host.h_aliases = host_aliases; 266 hap = h_addr_ptrs; 267 *hap = NULL; 268 host.h_addr_list = h_addr_ptrs; 269 haveanswer = 0; 270 had_error = 0; 271 _dns_ttl_ = -1; 272 while (ancount-- > 0 && cp < eom && !had_error) { 273 n = dn_expand(answer->buf, eom, cp, bp, buflen); 274 if ((n < 0) || !(*name_ok)(bp)) { 275 had_error++; 276 continue; 277 } 278 cp += n; /* name */ 279 BOUNDS_CHECK(cp, 3 * INT16SZ + INT32SZ); 280 type = _getshort(cp); 281 cp += INT16SZ; /* type */ 282 class = _getshort(cp); 283 cp += INT16SZ; /* class */ 284 if (qtype == T_A && type == T_A) 285 _dns_ttl_ = _getlong(cp); 286 cp += INT32SZ; /* TTL */ 287 n = _getshort(cp); 288 cp += INT16SZ; /* len */ 289 BOUNDS_CHECK(cp, n); 290 erdata = cp + n; 291 if (class != C_IN) { 292 /* XXX - debug? syslog? */ 293 cp += n; 294 continue; /* XXX - had_error++ ? */ 295 } 296 if ((qtype == T_A || qtype == T_AAAA) && type == T_CNAME) { 297 if (ap >= &host_aliases[MAXALIASES-1]) 298 continue; 299 n = dn_expand(answer->buf, eom, cp, tbuf, sizeof tbuf); 300 if ((n < 0) || !(*name_ok)(tbuf)) { 301 had_error++; 302 continue; 303 } 304 cp += n; 305 if (cp != erdata) { 306 h_errno = NO_RECOVERY; 307 return (NULL); 308 } 309 /* Store alias. */ 310 *ap++ = bp; 311 n = (int)strlen(bp) + 1; /* for the \0 */ 312 if (n >= MAXHOSTNAMELEN) { 313 had_error++; 314 continue; 315 } 316 bp += n; 317 buflen -= n; 318 /* Get canonical name. */ 319 n = (int)strlen(tbuf) + 1; /* for the \0 */ 320 if (n > buflen || n >= MAXHOSTNAMELEN) { 321 had_error++; 322 continue; 323 } 324 strcpy(bp, tbuf); 325 host.h_name = bp; 326 bp += n; 327 buflen -= n; 328 continue; 329 } 330 if (qtype == T_PTR && type == T_CNAME) { 331 n = dn_expand(answer->buf, eom, cp, tbuf, sizeof tbuf); 332 if (n < 0 || !res_dnok(tbuf)) { 333 had_error++; 334 continue; 335 } 336 cp += n; 337 if (cp != erdata) { 338 h_errno = NO_RECOVERY; 339 return (NULL); 340 } 341 /* Get canonical name. */ 342 n = (int)strlen(tbuf) + 1; /* for the \0 */ 343 if (n > buflen || n >= MAXHOSTNAMELEN) { 344 had_error++; 345 continue; 346 } 347 strcpy(bp, tbuf); 348 tname = bp; 349 bp += n; 350 buflen -= n; 351 continue; 352 } 353 if (type != qtype) { 354 #ifdef _ORG_FREEBSD_ 355 syslog(LOG_NOTICE|LOG_AUTH, 356 "gethostby*.gethostanswer: asked for \"%s %s %s\", got type \"%s\"", 357 qname, p_class(C_IN), p_type(qtype), 358 p_type(type)); 359 #endif 360 cp += n; 361 continue; /* XXX - had_error++ ? */ 362 } 363 switch (type) { 364 case T_PTR: 365 if (strcasecmp(tname, bp) != 0) { 366 #ifdef _ORG_FREEBSD_ 367 syslog(LOG_NOTICE|LOG_AUTH, 368 AskedForGot, qname, bp); 369 #endif 370 cp += n; 371 continue; /* XXX - had_error++ ? */ 372 } 373 n = dn_expand(answer->buf, eom, cp, bp, buflen); 374 if ((n < 0) || !res_hnok(bp)) { 375 had_error++; 376 break; 377 } 378 #if MULTI_PTRS_ARE_ALIASES 379 cp += n; 380 if (cp != erdata) { 381 h_errno = NO_RECOVERY; 382 return (NULL); 383 } 384 if (!haveanswer) 385 host.h_name = bp; 386 else if (ap < &host_aliases[MAXALIASES-1]) 387 *ap++ = bp; 388 else 389 n = -1; 390 if (n != -1) { 391 n = (int)strlen(bp) + 1; /* for the \0 */ 392 if (n >= MAXHOSTNAMELEN) { 393 had_error++; 394 break; 395 } 396 bp += n; 397 buflen -= n; 398 } 399 break; 400 #else 401 host.h_name = bp; 402 if (_res.options & RES_USE_INET6) { 403 n = strlen(bp) + 1; /* for the \0 */ 404 if (n >= MAXHOSTNAMELEN) { 405 had_error++; 406 break; 407 } 408 bp += n; 409 buflen -= n; 410 _map_v4v6_hostent(&host, &bp, &buflen); 411 } 412 h_errno = NETDB_SUCCESS; 413 return (&host); 414 #endif 415 case T_A: 416 case T_AAAA: 417 if (strcasecmp(host.h_name, bp) != 0) { 418 #ifdef _ORG_FREEBSD_ 419 syslog(LOG_NOTICE|LOG_AUTH, 420 AskedForGot, host.h_name, bp); 421 #endif 422 cp += n; 423 continue; /* XXX - had_error++ ? */ 424 } 425 if (n != host.h_length) { 426 cp += n; 427 continue; 428 } 429 if (!haveanswer) { 430 register int nn; 431 432 host.h_name = bp; 433 nn = (int)strlen(bp) + 1; /* for the \0 */ 434 bp += nn; 435 buflen -= nn; 436 } 437 438 bp += sizeof(align) - ((size_t)bp % sizeof(align)); 439 440 if (bp + n >= &hostbuf[sizeof hostbuf]) { 441 dprintf("size (%d) too big\n", n); 442 had_error++; 443 continue; 444 } 445 if (hap >= &h_addr_ptrs[MAXADDRS-1]) { 446 if (!toobig++) 447 dprintf("Too many addresses (%d)\n", 448 MAXADDRS); 449 cp += n; 450 continue; 451 } 452 *hap++ = bp; 453 bcopy(cp, bp, n); 454 bp += n; 455 buflen -= n; 456 cp += n; 457 if (cp != erdata) { 458 h_errno = NO_RECOVERY; 459 return (NULL); 460 } 461 break; 462 default: 463 dprintf("Impossible condition (type=%d)\n", type); 464 h_errno = NO_RECOVERY; 465 return (NULL); 466 /* BIND has abort() here, too risky on bad data */ 467 } 468 if (!had_error) 469 haveanswer++; 470 } 471 if (haveanswer) { 472 *ap = NULL; 473 *hap = NULL; 474 # if defined(RESOLVSORT) 475 /* 476 * Note: we sort even if host can take only one address 477 * in its return structures - should give it the "best" 478 * address in that case, not some random one 479 */ 480 if (_res.nsort && haveanswer > 1 && qtype == T_A) 481 addrsort(h_addr_ptrs, haveanswer); 482 # endif /*RESOLVSORT*/ 483 if (!host.h_name) { 484 n = (int)strlen(qname) + 1; /* for the \0 */ 485 if (n > buflen || n >= MAXHOSTNAMELEN) 486 goto no_recovery; 487 strcpy(bp, qname); 488 host.h_name = bp; 489 bp += n; 490 buflen -= n; 491 } 492 if (_res.options & RES_USE_INET6) 493 _map_v4v6_hostent(&host, &bp, &buflen); 494 h_errno = NETDB_SUCCESS; 495 return (&host); 496 } 497 no_recovery: 498 h_errno = NO_RECOVERY; 499 return (NULL); 500 } 501 502 struct hostent * 503 __dns_getanswer(const char *answer, int anslen, const char *qname, int qtype) 504 { 505 switch(qtype) { 506 case T_AAAA: 507 host.h_addrtype = AF_INET6; 508 host.h_length = IN6ADDRSZ; 509 break; 510 case T_A: 511 default: 512 host.h_addrtype = AF_INET; 513 host.h_length = INADDRSZ; 514 break; 515 } 516 517 return(gethostanswer((const querybuf *)answer, anslen, qname, qtype)); 518 } 519 520 struct hostent * 521 _gethostbydnsname(const char *name, int af) 522 { 523 querybuf buf; 524 register const char *cp; 525 char *bp; 526 int n, size, type, len; 527 528 if ((_res.options & RES_INIT) == 0 && res_init() == -1) { 529 h_errno = NETDB_INTERNAL; 530 return (NULL); 531 } 532 533 switch (af) { 534 case AF_INET: 535 size = INADDRSZ; 536 type = T_A; 537 break; 538 case AF_INET6: 539 size = IN6ADDRSZ; 540 type = T_AAAA; 541 break; 542 default: 543 h_errno = NETDB_INTERNAL; 544 errno = EAFNOSUPPORT; 545 return (NULL); 546 } 547 548 host.h_addrtype = af; 549 host.h_length = size; 550 551 /* 552 * if there aren't any dots, it could be a user-level alias. 553 * this is also done in res_query() since we are not the only 554 * function that looks up host names. 555 */ 556 if (!strchr(name, '.') && ( NULL != (cp = __hostalias(name)))) 557 name = cp; 558 559 /* 560 * disallow names consisting only of digits/dots, unless 561 * they end in a dot. 562 */ 563 if (isdigit(name[0])) 564 for (cp = name;; ++cp) { 565 if (!*cp) { 566 if (*--cp == '.') 567 break; 568 /* 569 * All-numeric, no dot at the end. 570 * Fake up a hostent as if we'd actually 571 * done a lookup. 572 */ 573 if (inet_pton(af, name, host_addr) <= 0) { 574 h_errno = HOST_NOT_FOUND; 575 return (NULL); 576 } 577 strncpy(hostbuf, name, MAXDNAME); 578 hostbuf[MAXDNAME] = '\0'; 579 bp = hostbuf + MAXDNAME; 580 len = sizeof hostbuf - MAXDNAME; 581 host.h_name = hostbuf; 582 host.h_aliases = host_aliases; 583 host_aliases[0] = NULL; 584 h_addr_ptrs[0] = (char *)host_addr; 585 h_addr_ptrs[1] = NULL; 586 host.h_addr_list = h_addr_ptrs; 587 if (_res.options & RES_USE_INET6) 588 _map_v4v6_hostent(&host, &bp, &len); 589 h_errno = NETDB_SUCCESS; 590 return (&host); 591 } 592 if (!isdigit(*cp) && *cp != '.') 593 break; 594 } 595 if ((isxdigit(name[0]) && strchr(name, ':') != NULL) || 596 name[0] == ':') 597 for (cp = name;; ++cp) { 598 if (!*cp) { 599 if (*--cp == '.') 600 break; 601 /* 602 * All-IPv6-legal, no dot at the end. 603 * Fake up a hostent as if we'd actually 604 * done a lookup. 605 */ 606 if (inet_pton(af, name, host_addr) <= 0) { 607 h_errno = HOST_NOT_FOUND; 608 return (NULL); 609 } 610 strncpy(hostbuf, name, MAXDNAME); 611 hostbuf[MAXDNAME] = '\0'; 612 bp = hostbuf + MAXDNAME; 613 len = sizeof hostbuf - MAXDNAME; 614 host.h_name = hostbuf; 615 host.h_aliases = host_aliases; 616 host_aliases[0] = NULL; 617 h_addr_ptrs[0] = (char *)host_addr; 618 h_addr_ptrs[1] = NULL; 619 host.h_addr_list = h_addr_ptrs; 620 h_errno = NETDB_SUCCESS; 621 return (&host); 622 } 623 if (!isxdigit(*cp) && *cp != ':' && *cp != '.') 624 break; 625 } 626 627 if ((n = res_search(name, C_IN, type, buf.buf, sizeof(buf))) < 0) { 628 dprintf("res_search failed (%d)\n", n); 629 return (NULL); 630 } 631 return (gethostanswer(&buf, n, name, type)); 632 } 633 634 struct hostent * 635 _gethostbydnsaddr(const char *addr, int len, int af) 636 { 637 const u_char *uaddr = (const u_char *)addr; 638 static const u_char mapped[] = { 0,0, 0,0, 0,0, 0,0, 0,0, 0xff,0xff }; 639 static const u_char tunnelled[] = { 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 }; 640 int n, size; 641 querybuf buf; 642 register struct hostent *hp; 643 char qbuf[MAXDNAME+1], *qp; 644 #ifdef SUNSECURITY 645 register struct hostent *rhp; 646 char **haddr; 647 u_long old_options; 648 char hname2[MAXDNAME+1]; 649 #endif /*SUNSECURITY*/ 650 651 if ((_res.options & RES_INIT) == 0 && res_init() == -1) { 652 h_errno = NETDB_INTERNAL; 653 return (NULL); 654 } 655 if (af == AF_INET6 && len == IN6ADDRSZ && 656 (!bcmp(uaddr, mapped, sizeof mapped) || 657 !bcmp(uaddr, tunnelled, sizeof tunnelled))) { 658 /* Unmap. */ 659 addr += sizeof mapped; 660 uaddr += sizeof mapped; 661 af = AF_INET; 662 len = INADDRSZ; 663 } 664 switch (af) { 665 case AF_INET: 666 size = INADDRSZ; 667 break; 668 case AF_INET6: 669 size = IN6ADDRSZ; 670 break; 671 default: 672 errno = EAFNOSUPPORT; 673 h_errno = NETDB_INTERNAL; 674 return (NULL); 675 } 676 if (size != len) { 677 errno = EINVAL; 678 h_errno = NETDB_INTERNAL; 679 return (NULL); 680 } 681 switch (af) { 682 case AF_INET: 683 (void) sprintf(qbuf, "%u.%u.%u.%u.in-addr.arpa", 684 (uaddr[3] & 0xff), 685 (uaddr[2] & 0xff), 686 (uaddr[1] & 0xff), 687 (uaddr[0] & 0xff)); 688 break; 689 case AF_INET6: 690 qp = qbuf; 691 for (n = IN6ADDRSZ - 1; n >= 0; n--) { 692 qp += SPRINTF((qp, "%x.%x.", 693 uaddr[n] & 0xf, 694 (uaddr[n] >> 4) & 0xf)); 695 } 696 strcpy(qp, "ip6.int"); 697 break; 698 default: 699 abort(); 700 } 701 n = res_query(qbuf, C_IN, T_PTR, (u_char *)buf.buf, sizeof buf.buf); 702 if (n < 0) { 703 dprintf("res_query failed (%d)\n", n); 704 return (NULL); 705 } 706 if ( NULL == (hp = gethostanswer(&buf, n, qbuf, T_PTR))) 707 return (NULL); /* h_errno was set by gethostanswer() */ 708 #ifdef SUNSECURITY 709 if (af == AF_INET) { 710 /* 711 * turn off search as the name should be absolute, 712 * 'localhost' should be matched by defnames 713 */ 714 strncpy(hname2, hp->h_name, MAXDNAME); 715 hname2[MAXDNAME] = '\0'; 716 old_options = _res.options; 717 _res.options &= ~RES_DNSRCH; 718 _res.options |= RES_DEFNAMES; 719 if (!(rhp = gethostbyname(hname2))) { 720 #ifdef _ORG_FREEBSD_ 721 syslog(LOG_NOTICE|LOG_AUTH, 722 "gethostbyaddr: No A record for %s (verifying [%s])", 723 hname2, inet_ntoa(*((struct in_addr *)addr))); 724 #endif 725 _res.options = old_options; 726 h_errno = HOST_NOT_FOUND; 727 return (NULL); 728 } 729 _res.options = old_options; 730 for (haddr = rhp->h_addr_list; *haddr; haddr++) 731 if (!memcmp(*haddr, addr, INADDRSZ)) 732 break; 733 if (!*haddr) { 734 #ifdef _ORG_FREEBSD_ 735 syslog(LOG_NOTICE|LOG_AUTH, 736 "gethostbyaddr: A record of %s != PTR record [%s]", 737 hname2, inet_ntoa(*((struct in_addr *)addr))); 738 #endif 739 h_errno = HOST_NOT_FOUND; 740 return (NULL); 741 } 742 } 743 #endif /*SUNSECURITY*/ 744 hp->h_addrtype = af; 745 hp->h_length = len; 746 bcopy(addr, host_addr, len); 747 h_addr_ptrs[0] = (char *)host_addr; 748 h_addr_ptrs[1] = NULL; 749 if (af == AF_INET && (_res.options & RES_USE_INET6)) { 750 _map_v4v6_address((char*)host_addr, (char*)host_addr); 751 hp->h_addrtype = AF_INET6; 752 hp->h_length = IN6ADDRSZ; 753 } 754 h_errno = NETDB_SUCCESS; 755 return (hp); 756 } 757 758 #ifdef RESOLVSORT 759 static void 760 addrsort(char **ap, int num) 761 { 762 short i, j; 763 char **p; 764 short aval[MAXADDRS]; 765 short needsort = 0; 766 767 p = ap; 768 for (i = 0; i < num; i++, p++) { 769 for (j = 0 ; (unsigned)j < _res.nsort; j++) 770 if (_res.sort_list[j].addr.s_addr == 771 (((struct in_addr *)(*p))->s_addr & _res.sort_list[j].mask)) 772 break; 773 aval[i] = j; 774 if (needsort == 0 && i > 0 && j < aval[i-1]) 775 needsort = i; 776 } 777 if (!needsort) 778 return; 779 780 while (needsort < num) { 781 for (j = needsort - 1; j >= 0; j--) { 782 if (aval[j] > aval[j+1]) { 783 char *hp; 784 785 i = aval[j]; 786 aval[j] = aval[j+1]; 787 aval[j+1] = i; 788 789 hp = ap[j]; 790 ap[j] = ap[j+1]; 791 ap[j+1] = hp; 792 793 } else 794 break; 795 } 796 needsort++; 797 } 798 } 799 #endif 800 void 801 _sethostdnsent(int stayopen) 802 { 803 if ((_res.options & RES_INIT) == 0 && res_init() == -1) 804 return; 805 if (stayopen) 806 _res.options |= RES_STAYOPEN | RES_USEVC; 807 } 808 809 void 810 _endhostdnsent() 811 { 812 _res.options &= ~(RES_STAYOPEN | RES_USEVC); 813 res_close(); 814 } 815