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