source: rtems/cpukit/libnetworking/libc/gethostbydns.c @ cb2f320

4.104.114.84.95
Last change on this file since cb2f320 was cb2f320, checked in by Joel Sherrill <joel.sherrill@…>, on 03/05/04 at 18:02:41

2004-03-05 Joel Sherrill <joel@…>

  • libblock/src/bdbuf.c, libblock/src/ramdisk.c, libcsupport/src/newlibc.c, libcsupport/src/sync.c, libmisc/cpuuse/cpuuse.c, libmisc/monitor/mon-symbols.c, libmisc/shell/cmds.c, libmisc/shell/shell.c, libnetworking/kern/kern_sysctl.c, libnetworking/lib/ftpfs.c, libnetworking/lib/tftpDriver.c, libnetworking/libc/gethostbydns.c, libnetworking/libc/gethostbyht.c, libnetworking/libc/gethostnamadr.c, libnetworking/libc/getnetbyht.c, libnetworking/libc/getnetnamadr.c, libnetworking/libc/inet_addr.c, libnetworking/libc/linkaddr.c, libnetworking/libc/map_v4v6.c, libnetworking/libc/ns_print.c, libnetworking/libc/ns_ttl.c, libnetworking/libc/nsap_addr.c, libnetworking/libc/rcmd.c, libnetworking/libc/res_debug.c, libnetworking/libc/res_mkupdate.c, libnetworking/libc/res_query.c, libnetworking/libc/res_send.c, libnetworking/libc/res_update.c, libnetworking/net/radix.c, libnetworking/rtems/mkrootfs.c, librpc/src/rpc/clnt_perror.c, librpc/src/rpc/svc.c, score/macros/rtems/score/chain.inl, score/src/objectidtoname.c: Too much was accidentally committed -- revert.
  • Property mode set to 100644
File size: 18.5 KB
Line 
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#if defined(LIBC_SCCS) && !defined(lint)
57static char sccsid[] = "@(#)gethostnamadr.c     8.1 (Berkeley) 6/4/93";
58static char fromrcsid[] = "From: Id: gethnamaddr.c,v 8.23 1998/04/07 04:59:46 vixie Exp $";
59static char rcsid[] = "$Id$";
60#endif /* LIBC_SCCS and not lint */
61
62#include <sys/types.h>
63#include <sys/param.h>
64#include <sys/socket.h>
65#include <netinet/in.h>
66#include <arpa/inet.h>
67#include <arpa/nameser.h>
68
69#include <stdio.h>
70#include <unistd.h>
71#include <string.h>
72#include <netdb.h>
73#include <resolv.h>
74#include <ctype.h>
75#include <errno.h>
76#include <syslog.h>
77
78#include "res_config.h"
79
80void abort(void); /* to avoid warning */
81
82#define SPRINTF(x) ((size_t)sprintf x)
83
84#define MAXALIASES      35
85#define MAXADDRS        35
86
87static const char AskedForGot[] =
88                "gethostby*.gethostanswer: asked for \"%s\", got \"%s\"";
89
90static char *h_addr_ptrs[MAXADDRS + 1];
91
92static struct hostent host;
93static char *host_aliases[MAXALIASES];
94static char hostbuf[8*1024];
95static u_char host_addr[16];    /* IPv4 or IPv6 */
96
97#ifdef RESOLVSORT
98static void addrsort __P((char **, int));
99#endif
100
101#if PACKETSZ > 1024
102#define MAXPACKET       PACKETSZ
103#else
104#define MAXPACKET       1024
105#endif
106
107typedef union {
108    HEADER hdr;
109    u_char buf[MAXPACKET];
110} querybuf;
111
112typedef union {
113    int32_t al;
114    char ac;
115} align;
116
117extern int h_errno;
118int _dns_ttl_;
119
120#ifdef DEBUG
121static void
122dprintf(msg, num)
123        char *msg;
124        int num;
125{
126        if (_res.options & RES_DEBUG) {
127                int save = errno;
128
129                printf(msg, num);
130                errno = save;
131        }
132}
133#else
134# define dprintf(msg, num) /*nada*/
135#endif
136
137#define BOUNDED_INCR(x) \
138        do { \
139                cp += x; \
140                if (cp > eom) { \
141                        h_errno = NO_RECOVERY; \
142                        return (NULL); \
143                } \
144        } while (0)
145
146#define BOUNDS_CHECK(ptr, count) \
147        do { \
148                if ((ptr) + (count) > eom) { \
149                        h_errno = NO_RECOVERY; \
150                        return (NULL); \
151                } \
152        } while (0)
153
154static struct hostent *
155gethostanswer(answer, anslen, qname, qtype)
156        const querybuf *answer;
157        int anslen;
158        const char *qname;
159        int qtype;
160{
161        register const HEADER *hp;
162        register const u_char *cp;
163        register int n;
164        const u_char *eom, *erdata;
165        char *bp, **ap, **hap;
166        int type, class, buflen, ancount, qdcount;
167        int haveanswer, had_error;
168        int toobig = 0;
169        char tbuf[MAXDNAME];
170        const char *tname;
171        int (*name_ok) __P((const char *));
172
173        tname = qname;
174        host.h_name = NULL;
175        eom = answer->buf + anslen;
176        switch (qtype) {
177        case T_A:
178        case T_AAAA:
179                name_ok = res_hnok;
180                break;
181        case T_PTR:
182                name_ok = res_dnok;
183                break;
184        default:
185                h_errno = NO_RECOVERY;
186                return (NULL);  /* XXX should be abort(); */
187        }
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;
197        BOUNDED_INCR(HFIXEDSZ);
198        if (qdcount != 1) {
199                h_errno = NO_RECOVERY;
200                return (NULL);
201        }
202        n = dn_expand(answer->buf, eom, cp, bp, buflen);
203        if ((n < 0) || !(*name_ok)(bp)) {
204                h_errno = NO_RECOVERY;
205                return (NULL);
206        }
207        BOUNDED_INCR(n + QFIXEDSZ);
208        if (qtype == T_A || qtype == T_AAAA) {
209                /* res_send() has already verified that the query name is the
210                 * same as the one we sent; this just gets the expanded name
211                 * (i.e., with the succeeding search-domain tacked on).
212                 */
213                n = strlen(bp) + 1;             /* for the \0 */
214                if (n >= MAXHOSTNAMELEN) {
215                        h_errno = NO_RECOVERY;
216                        return (NULL);
217                }
218                host.h_name = bp;
219                bp += n;
220                buflen -= n;
221                /* The qname can be abbreviated, but h_name is now absolute. */
222                qname = host.h_name;
223        }
224        ap = host_aliases;
225        *ap = NULL;
226        host.h_aliases = host_aliases;
227        hap = h_addr_ptrs;
228        *hap = NULL;
229        host.h_addr_list = h_addr_ptrs;
230        haveanswer = 0;
231        had_error = 0;
232        _dns_ttl_ = -1;
233        while (ancount-- > 0 && cp < eom && !had_error) {
234                n = dn_expand(answer->buf, eom, cp, bp, buflen);
235                if ((n < 0) || !(*name_ok)(bp)) {
236                        had_error++;
237                        continue;
238                }
239                cp += n;                        /* name */
240                BOUNDS_CHECK(cp, 3 * INT16SZ + INT32SZ);
241                type = _getshort(cp);
242                cp += INT16SZ;                  /* type */
243                class = _getshort(cp);
244                cp += INT16SZ;                  /* class */
245                if (qtype == T_A  && type == T_A)
246                        _dns_ttl_ = _getlong(cp);
247                cp += INT32SZ;                  /* TTL */
248                n = _getshort(cp);
249                cp += INT16SZ;                  /* len */
250                BOUNDS_CHECK(cp, n);
251                erdata = cp + n;
252                if (class != C_IN) {
253                        /* XXX - debug? syslog? */
254                        cp += n;
255                        continue;               /* XXX - had_error++ ? */
256                }
257                if ((qtype == T_A || qtype == T_AAAA) && type == T_CNAME) {
258                        if (ap >= &host_aliases[MAXALIASES-1])
259                                continue;
260                        n = dn_expand(answer->buf, eom, cp, tbuf, sizeof tbuf);
261                        if ((n < 0) || !(*name_ok)(tbuf)) {
262                                had_error++;
263                                continue;
264                        }
265                        cp += n;
266                        if (cp != erdata) {
267                                h_errno = NO_RECOVERY;
268                                return (NULL);
269                        }
270                        /* Store alias. */
271                        *ap++ = bp;
272                        n = strlen(bp) + 1;     /* for the \0 */
273                        if (n >= MAXHOSTNAMELEN) {
274                                had_error++;
275                                continue;
276                        }
277                        bp += n;
278                        buflen -= n;
279                        /* Get canonical name. */
280                        n = strlen(tbuf) + 1;   /* for the \0 */
281                        if (n > buflen || n >= MAXHOSTNAMELEN) {
282                                had_error++;
283                                continue;
284                        }
285                        strcpy(bp, tbuf);
286                        host.h_name = bp;
287                        bp += n;
288                        buflen -= n;
289                        continue;
290                }
291                if (qtype == T_PTR && type == T_CNAME) {
292                        n = dn_expand(answer->buf, eom, cp, tbuf, sizeof tbuf);
293                        if (n < 0 || !res_dnok(tbuf)) {
294                                had_error++;
295                                continue;
296                        }
297                        cp += n;
298                        if (cp != erdata) {
299                                h_errno = NO_RECOVERY;
300                                return (NULL);
301                        }
302                        /* Get canonical name. */
303                        n = strlen(tbuf) + 1;   /* for the \0 */
304                        if (n > buflen || n >= MAXHOSTNAMELEN) {
305                                had_error++;
306                                continue;
307                        }
308                        strcpy(bp, tbuf);
309                        tname = bp;
310                        bp += n;
311                        buflen -= n;
312                        continue;
313                }
314                if (type != qtype) {
315                        syslog(LOG_NOTICE|LOG_AUTH,
316        "gethostby*.gethostanswer: asked for \"%s %s %s\", got type \"%s\"",
317                               qname, p_class(C_IN), p_type(qtype),
318                               p_type(type));
319                        cp += n;
320                        continue;               /* XXX - had_error++ ? */
321                }
322                switch (type) {
323                case T_PTR:
324                        if (strcasecmp(tname, bp) != 0) {
325                                syslog(LOG_NOTICE|LOG_AUTH,
326                                       AskedForGot, qname, bp);
327                                cp += n;
328                                continue;       /* XXX - had_error++ ? */
329                        }
330                        n = dn_expand(answer->buf, eom, cp, bp, buflen);
331                        if ((n < 0) || !res_hnok(bp)) {
332                                had_error++;
333                                break;
334                        }
335#if MULTI_PTRS_ARE_ALIASES
336                        cp += n;
337                        if (cp != erdata) {
338                                h_errno = NO_RECOVERY;
339                                return (NULL);
340                        }
341                        if (!haveanswer)
342                                host.h_name = bp;
343                        else if (ap < &host_aliases[MAXALIASES-1])
344                                *ap++ = bp;
345                        else
346                                n = -1;
347                        if (n != -1) {
348                                n = strlen(bp) + 1;     /* for the \0 */
349                                if (n >= MAXHOSTNAMELEN) {
350                                        had_error++;
351                                        break;
352                                }
353                                bp += n;
354                                buflen -= n;
355                        }
356                        break;
357#else
358                        host.h_name = bp;
359                        if (_res.options & RES_USE_INET6) {
360                                n = strlen(bp) + 1;     /* for the \0 */
361                                if (n >= MAXHOSTNAMELEN) {
362                                        had_error++;
363                                        break;
364                                }
365                                bp += n;
366                                buflen -= n;
367                                _map_v4v6_hostent(&host, &bp, &buflen);
368                        }
369                        h_errno = NETDB_SUCCESS;
370                        return (&host);
371#endif
372                case T_A:
373                case T_AAAA:
374                        if (strcasecmp(host.h_name, bp) != 0) {
375                                syslog(LOG_NOTICE|LOG_AUTH,
376                                       AskedForGot, host.h_name, bp);
377                                cp += n;
378                                continue;       /* XXX - had_error++ ? */
379                        }
380                        if (n != host.h_length) {
381                                cp += n;
382                                continue;
383                        }
384                        if (!haveanswer) {
385                                register int nn;
386
387                                host.h_name = bp;
388                                nn = strlen(bp) + 1;    /* for the \0 */
389                                bp += nn;
390                                buflen -= nn;
391                        }
392
393                        bp += sizeof(align) - ((u_long)bp % sizeof(align));
394
395                        if (bp + n >= &hostbuf[sizeof hostbuf]) {
396                                dprintf("size (%d) too big\n", n);
397                                had_error++;
398                                continue;
399                        }
400                        if (hap >= &h_addr_ptrs[MAXADDRS-1]) {
401                                if (!toobig++)
402                                        dprintf("Too many addresses (%d)\n",
403                                                MAXADDRS);
404                                cp += n;
405                                continue;
406                        }
407                        bcopy(cp, *hap++ = bp, n);
408                        bp += n;
409                        buflen -= n;
410                        cp += n;
411                        if (cp != erdata) {
412                                h_errno = NO_RECOVERY;
413                                return (NULL);
414                        }
415                        break;
416                default:
417                        dprintf("Impossible condition (type=%d)\n", type);
418                        h_errno = NO_RECOVERY;
419                        return (NULL);
420                        /* BIND has abort() here, too risky on bad data */
421                }
422                if (!had_error)
423                        haveanswer++;
424        }
425        if (haveanswer) {
426                *ap = NULL;
427                *hap = NULL;
428# if defined(RESOLVSORT)
429                /*
430                 * Note: we sort even if host can take only one address
431                 * in its return structures - should give it the "best"
432                 * address in that case, not some random one
433                 */
434                if (_res.nsort && haveanswer > 1 && qtype == T_A)
435                        addrsort(h_addr_ptrs, haveanswer);
436# endif /*RESOLVSORT*/
437                if (!host.h_name) {
438                        n = strlen(qname) + 1;  /* for the \0 */
439                        if (n > buflen || n >= MAXHOSTNAMELEN)
440                                goto no_recovery;
441                        strcpy(bp, qname);
442                        host.h_name = bp;
443                        bp += n;
444                        buflen -= n;
445                }
446                if (_res.options & RES_USE_INET6)
447                        _map_v4v6_hostent(&host, &bp, &buflen);
448                h_errno = NETDB_SUCCESS;
449                return (&host);
450        }
451 no_recovery:
452        h_errno = NO_RECOVERY;
453        return (NULL);
454}
455
456struct hostent *
457__dns_getanswer(answer, anslen, qname, qtype)
458        const char *answer;
459        int anslen;
460        const char *qname;
461        int qtype;
462{
463        switch(qtype) {
464        case T_AAAA:
465                host.h_addrtype = AF_INET6;
466                host.h_length = IN6ADDRSZ;
467                break;
468        case T_A:
469        default:
470                host.h_addrtype = AF_INET;
471                host.h_length = INADDRSZ;
472                break;
473        }
474
475        return(gethostanswer((const querybuf *)answer, anslen, qname, qtype));
476}
477
478struct hostent *
479_gethostbydnsname(name, af)
480        const char *name;
481        int af;
482{
483        querybuf buf;
484        register const char *cp;
485        char *bp;
486        int n, size, type, len;
487
488        if ((_res.options & RES_INIT) == 0 && res_init() == -1) {
489                h_errno = NETDB_INTERNAL;
490                return (NULL);
491        }
492
493        switch (af) {
494        case AF_INET:
495                size = INADDRSZ;
496                type = T_A;
497                break;
498        case AF_INET6:
499                size = IN6ADDRSZ;
500                type = T_AAAA;
501                break;
502        default:
503                h_errno = NETDB_INTERNAL;
504                errno = EAFNOSUPPORT;
505                return (NULL);
506        }
507
508        host.h_addrtype = af;
509        host.h_length = size;
510
511        /*
512         * if there aren't any dots, it could be a user-level alias.
513         * this is also done in res_query() since we are not the only
514         * function that looks up host names.
515         */
516        if (!strchr(name, '.') && (cp = __hostalias(name)))
517                name = cp;
518
519        /*
520         * disallow names consisting only of digits/dots, unless
521         * they end in a dot.
522         */
523        if (isdigit((int)name[0]))
524                for (cp = name;; ++cp) {
525                        if (!*cp) {
526                                if (*--cp == '.')
527                                        break;
528                                /*
529                                 * All-numeric, no dot at the end.
530                                 * Fake up a hostent as if we'd actually
531                                 * done a lookup.
532                                 */
533                                if (inet_pton(af, name, host_addr) <= 0) {
534                                        h_errno = HOST_NOT_FOUND;
535                                        return (NULL);
536                                }
537                                strncpy(hostbuf, name, MAXDNAME);
538                                hostbuf[MAXDNAME] = '\0';
539                                bp = hostbuf + MAXDNAME;
540                                len = sizeof hostbuf - MAXDNAME;
541                                host.h_name = hostbuf;
542                                host.h_aliases = host_aliases;
543                                host_aliases[0] = NULL;
544                                h_addr_ptrs[0] = (char *)host_addr;
545                                h_addr_ptrs[1] = NULL;
546                                host.h_addr_list = h_addr_ptrs;
547                                if (_res.options & RES_USE_INET6)
548                                        _map_v4v6_hostent(&host, &bp, &len);
549                                h_errno = NETDB_SUCCESS;
550                                return (&host);
551                        }
552                        if (!isdigit((int)*cp) && *cp != '.')
553                                break;
554                }
555        if ((isxdigit((int)name[0]) && strchr(name, ':') != NULL) ||
556            name[0] == ':')
557                for (cp = name;; ++cp) {
558                        if (!*cp) {
559                                if (*--cp == '.')
560                                        break;
561                                /*
562                                 * All-IPv6-legal, no dot at the end.
563                                 * Fake up a hostent as if we'd actually
564                                 * done a lookup.
565                                 */
566                                if (inet_pton(af, name, host_addr) <= 0) {
567                                        h_errno = HOST_NOT_FOUND;
568                                        return (NULL);
569                                }
570                                strncpy(hostbuf, name, MAXDNAME);
571                                hostbuf[MAXDNAME] = '\0';
572                                bp = hostbuf + MAXDNAME;
573                                len = sizeof hostbuf - MAXDNAME;
574                                host.h_name = hostbuf;
575                                host.h_aliases = host_aliases;
576                                host_aliases[0] = NULL;
577                                h_addr_ptrs[0] = (char *)host_addr;
578                                h_addr_ptrs[1] = NULL;
579                                host.h_addr_list = h_addr_ptrs;
580                                h_errno = NETDB_SUCCESS;
581                                return (&host);
582                        }
583                        if (!isxdigit((int)*cp) && *cp != ':' && *cp != '.')
584                                break;
585                }
586
587        if ((n = res_search(name, C_IN, type, buf.buf, sizeof(buf))) < 0) {
588                dprintf("res_search failed (%d)\n", n);
589                return (NULL);
590        }
591        return (gethostanswer(&buf, n, name, type));
592}
593
594struct hostent *
595_gethostbydnsaddr(addr, len, af)
596        const char *addr;       /* XXX should have been def'd as u_char! */
597        int len, af;
598{
599        const u_char *uaddr = (const u_char *)addr;
600        static const u_char mapped[] = { 0,0, 0,0, 0,0, 0,0, 0,0, 0xff,0xff };
601        static const u_char tunnelled[] = { 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 };
602        int n, size;
603        querybuf buf;
604        register struct hostent *hp;
605        char qbuf[MAXDNAME+1], *qp;
606#ifdef SUNSECURITY
607        register struct hostent *rhp;
608        char **haddr;
609        u_long old_options;
610        char hname2[MAXDNAME+1];
611#endif /*SUNSECURITY*/
612       
613        if ((_res.options & RES_INIT) == 0 && res_init() == -1) {
614                h_errno = NETDB_INTERNAL;
615                return (NULL);
616        }
617        if (af == AF_INET6 && len == IN6ADDRSZ &&
618            (!bcmp(uaddr, mapped, sizeof mapped) ||
619             !bcmp(uaddr, tunnelled, sizeof tunnelled))) {
620                /* Unmap. */
621                addr += sizeof mapped;
622                uaddr += sizeof mapped;
623                af = AF_INET;
624                len = INADDRSZ;
625        }
626        switch (af) {
627        case AF_INET:
628                size = INADDRSZ;
629                break;
630        case AF_INET6:
631                size = IN6ADDRSZ;
632                break;
633        default:
634                errno = EAFNOSUPPORT;
635                h_errno = NETDB_INTERNAL;
636                return (NULL);
637        }
638        if (size != len) {
639                errno = EINVAL;
640                h_errno = NETDB_INTERNAL;
641                return (NULL);
642        }
643        switch (af) {
644        case AF_INET:
645                (void) sprintf(qbuf, "%u.%u.%u.%u.in-addr.arpa",
646                               (uaddr[3] & 0xff),
647                               (uaddr[2] & 0xff),
648                               (uaddr[1] & 0xff),
649                               (uaddr[0] & 0xff));
650                break;
651        case AF_INET6:
652                qp = qbuf;
653                for (n = IN6ADDRSZ - 1; n >= 0; n--) {
654                        qp += SPRINTF((qp, "%x.%x.",
655                                       uaddr[n] & 0xf,
656                                       (uaddr[n] >> 4) & 0xf));
657                }
658                strcpy(qp, "ip6.int");
659                break;
660        default:
661                abort();
662        }
663        n = res_query(qbuf, C_IN, T_PTR, (u_char *)buf.buf, sizeof buf.buf);
664        if (n < 0) {
665                dprintf("res_query failed (%d)\n", n);
666                return (NULL);
667        }
668        if (!(hp = gethostanswer(&buf, n, qbuf, T_PTR)))
669                return (NULL);  /* h_errno was set by gethostanswer() */
670#ifdef SUNSECURITY
671        if (af == AF_INET) {
672            /*
673             * turn off search as the name should be absolute,
674             * 'localhost' should be matched by defnames
675             */
676            strncpy(hname2, hp->h_name, MAXDNAME);
677            hname2[MAXDNAME] = '\0';
678            old_options = _res.options;
679            _res.options &= ~RES_DNSRCH;
680            _res.options |= RES_DEFNAMES;
681            if (!(rhp = gethostbyname(hname2))) {
682                syslog(LOG_NOTICE|LOG_AUTH,
683                       "gethostbyaddr: No A record for %s (verifying [%s])",
684                       hname2, inet_ntoa(*((struct in_addr *)addr)));
685                _res.options = old_options;
686                h_errno = HOST_NOT_FOUND;
687                return (NULL);
688            }
689            _res.options = old_options;
690            for (haddr = rhp->h_addr_list; *haddr; haddr++)
691                if (!memcmp(*haddr, addr, INADDRSZ))
692                        break;
693            if (!*haddr) {
694                syslog(LOG_NOTICE|LOG_AUTH,
695                       "gethostbyaddr: A record of %s != PTR record [%s]",
696                       hname2, inet_ntoa(*((struct in_addr *)addr)));
697                h_errno = HOST_NOT_FOUND;
698                return (NULL);
699            }
700        }
701#endif /*SUNSECURITY*/
702        hp->h_addrtype = af;
703        hp->h_length = len;
704        bcopy(addr, host_addr, len);
705        h_addr_ptrs[0] = (char *)host_addr;
706        h_addr_ptrs[1] = NULL;
707        if (af == AF_INET && (_res.options & RES_USE_INET6)) {
708                _map_v4v6_address((char*)host_addr, (char*)host_addr);
709                hp->h_addrtype = AF_INET6;
710                hp->h_length = IN6ADDRSZ;
711        }
712        h_errno = NETDB_SUCCESS;
713        return (hp);
714}
715
716#ifdef RESOLVSORT
717static void
718addrsort(ap, num)
719        char **ap;
720        int num;
721{
722        int i, j;
723        char **p;
724        short aval[MAXADDRS];
725        int needsort = 0;
726
727        p = ap;
728        for (i = 0; i < num; i++, p++) {
729            for (j = 0 ; (unsigned)j < _res.nsort; j++)
730                if (_res.sort_list[j].addr.s_addr ==
731                    (((struct in_addr *)(*p))->s_addr & _res.sort_list[j].mask))
732                        break;
733            aval[i] = j;
734            if (needsort == 0 && i > 0 && j < aval[i-1])
735                needsort = i;
736        }
737        if (!needsort)
738            return;
739
740        while (needsort < num) {
741            for (j = needsort - 1; j >= 0; j--) {
742                if (aval[j] > aval[j+1]) {
743                    char *hp;
744
745                    i = aval[j];
746                    aval[j] = aval[j+1];
747                    aval[j+1] = i;
748
749                    hp = ap[j];
750                    ap[j] = ap[j+1];
751                    ap[j+1] = hp;
752
753                } else
754                    break;
755            }
756            needsort++;
757        }
758}
759#endif
760void
761_sethostdnsent(stayopen)
762        int stayopen;
763{
764        if ((_res.options & RES_INIT) == 0 && res_init() == -1)
765                return;
766        if (stayopen)
767                _res.options |= RES_STAYOPEN | RES_USEVC;
768}
769
770void
771_endhostdnsent()
772{
773        _res.options &= ~(RES_STAYOPEN | RES_USEVC);
774        res_close();
775}
Note: See TracBrowser for help on using the repository browser.