source: rtems/cpukit/libnetworking/libc/gethostbydns.c @ 39f13cb

4.104.115
Last change on this file since 39f13cb was 39f13cb, checked in by Ralf Corsepius <ralf.corsepius@…>, on 03/27/10 at 04:00:53

Add HAVE_STRINGS_H for better POSIX compliance.

  • Property mode set to 100644
File size: 18.2 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 HAVE_CONFIG_H
57#include "config.h"
58#endif
59
60#include <rtems/bsd/sys/cdefs.h>
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#ifdef HAVE_STRINGS_H
73#include <strings.h>
74#endif
75#include <netdb.h>
76#include <resolv.h>
77#include <ctype.h>
78#include <errno.h>
79#include <syslog.h>
80
81#include "res_config.h"
82
83void abort(void); /* to avoid warning */
84
85#define SPRINTF(x) ((size_t)sprintf x)
86
87#define MAXALIASES      35
88#define MAXADDRS        35
89
90static const char AskedForGot[] =
91                "gethostby*.gethostanswer: asked for \"%s\", got \"%s\"";
92
93static char *h_addr_ptrs[MAXADDRS + 1];
94
95static struct hostent host;
96static char *host_aliases[MAXALIASES];
97static char hostbuf[8*1024];
98static u_char host_addr[16];    /* IPv4 or IPv6 */
99
100#ifdef RESOLVSORT
101static void addrsort(char **, int);
102#endif
103
104#if PACKETSZ > 1024
105#define MAXPACKET       PACKETSZ
106#else
107#define MAXPACKET       1024
108#endif
109
110typedef union {
111    HEADER hdr;
112    u_char buf[MAXPACKET];
113} querybuf;
114
115typedef union {
116    int32_t al;
117    char ac;
118} align;
119
120extern int h_errno;
121int _dns_ttl_;
122
123#ifdef DEBUG
124static void
125debugprintf(
126        char *msg,
127        int num)
128{
129        if (_res.options & RES_DEBUG) {
130                int save = errno;
131
132                printf(msg, num);
133                errno = save;
134        }
135}
136#else
137#define debugprintf(msg, num) /*nada*/
138#endif
139
140#define BOUNDED_INCR(x) \
141        do { \
142                cp += x; \
143                if (cp > eom) { \
144                        h_errno = NO_RECOVERY; \
145                        return (NULL); \
146                } \
147        } while (0)
148
149#define BOUNDS_CHECK(ptr, count) \
150        do { \
151                if ((ptr) + (count) > eom) { \
152                        h_errno = NO_RECOVERY; \
153                        return (NULL); \
154                } \
155        } while (0)
156
157static struct hostent *
158gethostanswer(
159        const querybuf *answer,
160        int anslen,
161        const char *qname,
162        int qtype)
163{
164        const HEADER *hp;
165        const u_char *cp;
166        int n;
167        const u_char *eom, *erdata;
168        char *bp, **ap, **hap;
169        int type, class, buflen, ancount, qdcount;
170        int haveanswer, had_error;
171        int toobig = 0;
172        char tbuf[MAXDNAME];
173        const char *tname;
174        int (*name_ok)(const char *);
175
176        tname = qname;
177        host.h_name = NULL;
178        eom = answer->buf + anslen;
179        switch (qtype) {
180        case T_A:
181        case T_AAAA:
182                name_ok = res_hnok;
183                break;
184        case T_PTR:
185                name_ok = res_dnok;
186                break;
187        default:
188                h_errno = NO_RECOVERY;
189                return (NULL);  /* XXX should be abort(); */
190        }
191        /*
192         * find first satisfactory answer
193         */
194        hp = &answer->hdr;
195        ancount = ntohs(hp->ancount);
196        qdcount = ntohs(hp->qdcount);
197        bp = hostbuf;
198        buflen = sizeof hostbuf;
199        cp = answer->buf;
200        BOUNDED_INCR(HFIXEDSZ);
201        if (qdcount != 1) {
202                h_errno = NO_RECOVERY;
203                return (NULL);
204        }
205        n = dn_expand(answer->buf, eom, cp, bp, buflen);
206        if ((n < 0) || !(*name_ok)(bp)) {
207                h_errno = NO_RECOVERY;
208                return (NULL);
209        }
210        BOUNDED_INCR(n + QFIXEDSZ);
211        if (qtype == T_A || qtype == T_AAAA) {
212                /* res_send() has already verified that the query name is the
213                 * same as the one we sent; this just gets the expanded name
214                 * (i.e., with the succeeding search-domain tacked on).
215                 */
216                n = strlen(bp) + 1;             /* for the \0 */
217                if (n >= MAXHOSTNAMELEN) {
218                        h_errno = NO_RECOVERY;
219                        return (NULL);
220                }
221                host.h_name = bp;
222                bp += n;
223                buflen -= n;
224                /* The qname can be abbreviated, but h_name is now absolute. */
225                qname = host.h_name;
226        }
227        ap = host_aliases;
228        *ap = NULL;
229        host.h_aliases = host_aliases;
230        hap = h_addr_ptrs;
231        *hap = NULL;
232        host.h_addr_list = h_addr_ptrs;
233        haveanswer = 0;
234        had_error = 0;
235        _dns_ttl_ = -1;
236        while (ancount-- > 0 && cp < eom && !had_error) {
237                n = dn_expand(answer->buf, eom, cp, bp, buflen);
238                if ((n < 0) || !(*name_ok)(bp)) {
239                        had_error++;
240                        continue;
241                }
242                cp += n;                        /* name */
243                BOUNDS_CHECK(cp, 3 * INT16SZ + INT32SZ);
244                type = _getshort(cp);
245                cp += INT16SZ;                  /* type */
246                class = _getshort(cp);
247                cp += INT16SZ;                  /* class */
248                if (qtype == T_A  && type == T_A)
249                        _dns_ttl_ = _getlong(cp);
250                cp += INT32SZ;                  /* TTL */
251                n = _getshort(cp);
252                cp += INT16SZ;                  /* len */
253                BOUNDS_CHECK(cp, n);
254                erdata = cp + n;
255                if (class != C_IN) {
256                        /* XXX - debug? syslog? */
257                        cp += n;
258                        continue;               /* XXX - had_error++ ? */
259                }
260                if ((qtype == T_A || qtype == T_AAAA) && type == T_CNAME) {
261                        if (ap >= &host_aliases[MAXALIASES-1])
262                                continue;
263                        n = dn_expand(answer->buf, eom, cp, tbuf, sizeof tbuf);
264                        if ((n < 0) || !(*name_ok)(tbuf)) {
265                                had_error++;
266                                continue;
267                        }
268                        cp += n;
269                        if (cp != erdata) {
270                                h_errno = NO_RECOVERY;
271                                return (NULL);
272                        }
273                        /* Store alias. */
274                        *ap++ = bp;
275                        n = strlen(bp) + 1;     /* for the \0 */
276                        if (n >= MAXHOSTNAMELEN) {
277                                had_error++;
278                                continue;
279                        }
280                        bp += n;
281                        buflen -= n;
282                        /* Get canonical name. */
283                        n = strlen(tbuf) + 1;   /* for the \0 */
284                        if (n > buflen || n >= MAXHOSTNAMELEN) {
285                                had_error++;
286                                continue;
287                        }
288                        strcpy(bp, tbuf);
289                        host.h_name = bp;
290                        bp += n;
291                        buflen -= n;
292                        continue;
293                }
294                if (qtype == T_PTR && type == T_CNAME) {
295                        n = dn_expand(answer->buf, eom, cp, tbuf, sizeof tbuf);
296                        if (n < 0 || !res_dnok(tbuf)) {
297                                had_error++;
298                                continue;
299                        }
300                        cp += n;
301                        if (cp != erdata) {
302                                h_errno = NO_RECOVERY;
303                                return (NULL);
304                        }
305                        /* Get canonical name. */
306                        n = strlen(tbuf) + 1;   /* for the \0 */
307                        if (n > buflen || n >= MAXHOSTNAMELEN) {
308                                had_error++;
309                                continue;
310                        }
311                        strcpy(bp, tbuf);
312                        tname = bp;
313                        bp += n;
314                        buflen -= n;
315                        continue;
316                }
317                if (type != qtype) {
318                        syslog(LOG_NOTICE|LOG_AUTH,
319        "gethostby*.gethostanswer: asked for \"%s %s %s\", got type \"%s\"",
320                               qname, p_class(C_IN), p_type(qtype),
321                               p_type(type));
322                        cp += n;
323                        continue;               /* XXX - had_error++ ? */
324                }
325                switch (type) {
326                case T_PTR:
327                        if (strcasecmp(tname, bp) != 0) {
328                                syslog(LOG_NOTICE|LOG_AUTH,
329                                       AskedForGot, qname, bp);
330                                cp += n;
331                                continue;       /* XXX - had_error++ ? */
332                        }
333                        n = dn_expand(answer->buf, eom, cp, bp, buflen);
334                        if ((n < 0) || !res_hnok(bp)) {
335                                had_error++;
336                                break;
337                        }
338#if MULTI_PTRS_ARE_ALIASES
339                        cp += n;
340                        if (cp != erdata) {
341                                h_errno = NO_RECOVERY;
342                                return (NULL);
343                        }
344                        if (!haveanswer)
345                                host.h_name = bp;
346                        else if (ap < &host_aliases[MAXALIASES-1])
347                                *ap++ = bp;
348                        else
349                                n = -1;
350                        if (n != -1) {
351                                n = strlen(bp) + 1;     /* for the \0 */
352                                if (n >= MAXHOSTNAMELEN) {
353                                        had_error++;
354                                        break;
355                                }
356                                bp += n;
357                                buflen -= n;
358                        }
359                        break;
360#else
361                        host.h_name = bp;
362                        if (_res.options & RES_USE_INET6) {
363                                n = strlen(bp) + 1;     /* for the \0 */
364                                if (n >= MAXHOSTNAMELEN) {
365                                        had_error++;
366                                        break;
367                                }
368                                bp += n;
369                                buflen -= n;
370                                _map_v4v6_hostent(&host, &bp, &buflen);
371                        }
372                        h_errno = NETDB_SUCCESS;
373                        return (&host);
374#endif
375                case T_A:
376                case T_AAAA:
377                        if (strcasecmp(host.h_name, bp) != 0) {
378                                syslog(LOG_NOTICE|LOG_AUTH,
379                                       AskedForGot, host.h_name, bp);
380                                cp += n;
381                                continue;       /* XXX - had_error++ ? */
382                        }
383                        if (n != host.h_length) {
384                                cp += n;
385                                continue;
386                        }
387                        if (!haveanswer) {
388                                register int nn;
389
390                                host.h_name = bp;
391                                nn = strlen(bp) + 1;    /* for the \0 */
392                                bp += nn;
393                                buflen -= nn;
394                        }
395
396                        bp += sizeof(align) - ((u_long)bp % sizeof(align));
397
398                        if (bp + n >= &hostbuf[sizeof hostbuf]) {
399                                debugprintf("size (%d) too big\n", n);
400                                had_error++;
401                                continue;
402                        }
403                        if (hap >= &h_addr_ptrs[MAXADDRS-1]) {
404                                if (!toobig++)
405                                        debugprintf("Too many addresses (%d)\n",
406                                                MAXADDRS);
407                                cp += n;
408                                continue;
409                        }
410                        memcpy(*hap++ = bp, cp, n);
411                        bp += n;
412                        buflen -= n;
413                        cp += n;
414                        if (cp != erdata) {
415                                h_errno = NO_RECOVERY;
416                                return (NULL);
417                        }
418                        break;
419                default:
420                        debugprintf("Impossible condition (type=%d)\n", type);
421                        h_errno = NO_RECOVERY;
422                        return (NULL);
423                        /* BIND has abort() here, too risky on bad data */
424                }
425                if (!had_error)
426                        haveanswer++;
427        }
428        if (haveanswer) {
429                *ap = NULL;
430                *hap = NULL;
431# if defined(RESOLVSORT)
432                /*
433                 * Note: we sort even if host can take only one address
434                 * in its return structures - should give it the "best"
435                 * address in that case, not some random one
436                 */
437                if (_res.nsort && haveanswer > 1 && qtype == T_A)
438                        addrsort(h_addr_ptrs, haveanswer);
439# endif /*RESOLVSORT*/
440                if (!host.h_name) {
441                        n = strlen(qname) + 1;  /* for the \0 */
442                        if (n > buflen || n >= MAXHOSTNAMELEN)
443                                goto no_recovery;
444                        strcpy(bp, qname);
445                        host.h_name = bp;
446                        bp += n;
447                        buflen -= n;
448                }
449                if (_res.options & RES_USE_INET6)
450                        _map_v4v6_hostent(&host, &bp, &buflen);
451                h_errno = NETDB_SUCCESS;
452                return (&host);
453        }
454 no_recovery:
455        h_errno = NO_RECOVERY;
456        return (NULL);
457}
458
459struct hostent *
460__dns_getanswer(const char *answer, int anslen, const char *qname, int qtype)
461{
462        switch(qtype) {
463        case T_AAAA:
464                host.h_addrtype = AF_INET6;
465                host.h_length = IN6ADDRSZ;
466                break;
467        case T_A:
468        default:
469                host.h_addrtype = AF_INET;
470                host.h_length = INADDRSZ;
471                break;
472        }
473
474        return(gethostanswer((const querybuf *)answer, anslen, qname, qtype));
475}
476
477struct hostent *
478_gethostbydnsname(
479        const char *name,
480        int af)
481{
482        querybuf buf;
483        register const char *cp;
484        char *bp;
485        int n, size, type, len;
486
487        if ((_res.options & RES_INIT) == 0 && res_init() == -1) {
488                h_errno = NETDB_INTERNAL;
489                return (NULL);
490        }
491
492        switch (af) {
493        case AF_INET:
494                size = INADDRSZ;
495                type = T_A;
496                break;
497        case AF_INET6:
498                size = IN6ADDRSZ;
499                type = T_AAAA;
500                break;
501        default:
502                h_errno = NETDB_INTERNAL;
503                errno = EAFNOSUPPORT;
504                return (NULL);
505        }
506
507        host.h_addrtype = af;
508        host.h_length = size;
509
510        /*
511         * if there aren't any dots, it could be a user-level alias.
512         * this is also done in res_query() since we are not the only
513         * function that looks up host names.
514         */
515        if (!strchr(name, '.') && (cp = __hostalias(name)))
516                name = cp;
517
518        /*
519         * disallow names consisting only of digits/dots, unless
520         * they end in a dot.
521         */
522        if (isdigit((unsigned char)name[0]))
523                for (cp = name;; ++cp) {
524                        if (!*cp) {
525                                if (*--cp == '.')
526                                        break;
527                                /*
528                                 * All-numeric, no dot at the end.
529                                 * Fake up a hostent as if we'd actually
530                                 * done a lookup.
531                                 */
532                                if (inet_pton(af, name, host_addr) <= 0) {
533                                        h_errno = HOST_NOT_FOUND;
534                                        return (NULL);
535                                }
536                                strncpy(hostbuf, name, MAXDNAME);
537                                hostbuf[MAXDNAME] = '\0';
538                                bp = hostbuf + MAXDNAME;
539                                len = sizeof hostbuf - MAXDNAME;
540                                host.h_name = hostbuf;
541                                host.h_aliases = host_aliases;
542                                host_aliases[0] = NULL;
543                                h_addr_ptrs[0] = (char *)host_addr;
544                                h_addr_ptrs[1] = NULL;
545                                host.h_addr_list = h_addr_ptrs;
546                                if (_res.options & RES_USE_INET6)
547                                        _map_v4v6_hostent(&host, &bp, &len);
548                                h_errno = NETDB_SUCCESS;
549                                return (&host);
550                        }
551                        if (!isdigit((unsigned char)*cp) && *cp != '.')
552                                break;
553                }
554        if ((isxdigit((unsigned char)name[0]) && strchr(name, ':') != NULL) ||
555            name[0] == ':')
556                for (cp = name;; ++cp) {
557                        if (!*cp) {
558                                if (*--cp == '.')
559                                        break;
560                                /*
561                                 * All-IPv6-legal, no dot at the end.
562                                 * Fake up a hostent as if we'd actually
563                                 * done a lookup.
564                                 */
565                                if (inet_pton(af, name, host_addr) <= 0) {
566                                        h_errno = HOST_NOT_FOUND;
567                                        return (NULL);
568                                }
569                                strncpy(hostbuf, name, MAXDNAME);
570                                hostbuf[MAXDNAME] = '\0';
571                                bp = hostbuf + MAXDNAME;
572                                len = sizeof hostbuf - MAXDNAME;
573                                host.h_name = hostbuf;
574                                host.h_aliases = host_aliases;
575                                host_aliases[0] = NULL;
576                                h_addr_ptrs[0] = (char *)host_addr;
577                                h_addr_ptrs[1] = NULL;
578                                host.h_addr_list = h_addr_ptrs;
579                                h_errno = NETDB_SUCCESS;
580                                return (&host);
581                        }
582                        if (!isxdigit((unsigned char)*cp) && *cp != ':' && *cp != '.')
583                                break;
584                }
585
586        if ((n = res_search(name, C_IN, type, buf.buf, sizeof(buf))) < 0) {
587                debugprintf("res_search failed (%d)\n", n);
588                return (NULL);
589        }
590        return (gethostanswer(&buf, n, name, type));
591}
592
593struct hostent *
594_gethostbydnsaddr(
595        const char *addr,       /* XXX should have been def'd as u_char! */
596        int len,
597        int 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                debugprintf("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        memcpy(host_addr, 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(
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
760
761void
762_sethostdnsent(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(void)
772{
773        _res.options &= ~(RES_STAYOPEN | RES_USEVC);
774        res_close();
775}
Note: See TracBrowser for help on using the repository browser.