[BACK]Return to res_data.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / lib / libc / resolv

Annotation of src/lib/libc/resolv/res_data.c, Revision 1.12

1.12    ! christos    1: /*     $NetBSD: res_data.c,v 1.1.1.4 2009/04/12 16:35:47 christos Exp $        */
1.1       christos    2:
                      3: /*
                      4:  * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
                      5:  * Copyright (c) 1995-1999 by Internet Software Consortium.
                      6:  *
                      7:  * Permission to use, copy, modify, and distribute this software for any
                      8:  * purpose with or without fee is hereby granted, provided that the above
                      9:  * copyright notice and this permission notice appear in all copies.
                     10:  *
                     11:  * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
                     12:  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
                     13:  * MERCHANTABILITY AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR
                     14:  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
                     15:  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
                     16:  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
                     17:  * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
                     18:  */
                     19:
1.4       christos   20: #include <sys/cdefs.h>
1.1       christos   21: #if defined(LIBC_SCCS) && !defined(lint)
1.4       christos   22: #ifdef notdef
1.12    ! christos   23: static const char rcsid[] = "Id: res_data.c,v 1.7 2008/12/11 09:59:00 marka Exp";
1.4       christos   24: #else
1.12    ! christos   25: __RCSID("$NetBSD: res_data.c,v 1.11 2008/06/21 20:41:48 christos Exp $");
1.4       christos   26: #endif
1.1       christos   27: #endif /* LIBC_SCCS and not lint */
                     28:
                     29: #include "port_before.h"
                     30:
1.5       christos   31: #include "namespace.h"
1.1       christos   32: #include <sys/types.h>
                     33: #include <sys/param.h>
                     34: #include <sys/socket.h>
                     35: #include <sys/time.h>
                     36:
                     37: #include <netinet/in.h>
                     38: #include <arpa/inet.h>
                     39: #include <arpa/nameser.h>
                     40:
                     41: #include <ctype.h>
                     42: #include <netdb.h>
                     43: #include <resolv.h>
                     44: #include <res_update.h>
                     45: #include <stdio.h>
                     46: #include <stdlib.h>
                     47: #include <string.h>
                     48: #include <unistd.h>
                     49:
                     50: #include "port_after.h"
1.5       christos   51:
                     52: #ifdef __weak_alias
                     53: __weak_alias(res_init,_res_init)
                     54: __weak_alias(res_mkquery,_res_mkquery)
1.7       christos   55: __weak_alias(res_query,_res_query)
                     56: __weak_alias(res_search,_res_search)
                     57: __weak_alias(res_send,__res_send)
                     58: __weak_alias(res_close,__res_close)
                     59: /* XXX: these leaked in the old bind8 libc */
                     60: __weak_alias(res_querydomain,__res_querydomain)
1.5       christos   61: __weak_alias(res_send_setqhook,__res_send_setqhook)
                     62: __weak_alias(res_send_setrhook,__res_send_setrhook)
1.7       christos   63: #if 0
                     64: __weak_alias(p_query,__p_query)
                     65: __weak_alias(fp_query,__fp_query)
                     66: __weak_alias(fp_nquery,__fp_nquery)
1.5       christos   67: __weak_alias(res_isourserver,__res_isourserver)
                     68: __weak_alias(res_opt,_res_opt)
                     69: __weak_alias(hostalias,__hostalias)
                     70: #endif
1.6       christos   71: #endif
1.5       christos   72:
1.1       christos   73: const char *_res_opcodes[] = {
                     74:        "QUERY",
                     75:        "IQUERY",
                     76:        "CQUERYM",
1.9       christos   77:        "CQUERYU",      /*%< experimental */
                     78:        "NOTIFY",       /*%< experimental */
1.1       christos   79:        "UPDATE",
                     80:        "6",
                     81:        "7",
                     82:        "8",
                     83:        "9",
                     84:        "10",
                     85:        "11",
                     86:        "12",
                     87:        "13",
                     88:        "ZONEINIT",
                     89:        "ZONEREF",
                     90: };
                     91:
                     92: #ifdef BIND_UPDATE
                     93: const char *_res_sectioncodes[] = {
                     94:        "ZONE",
                     95:        "PREREQUISITES",
                     96:        "UPDATE",
                     97:        "ADDITIONAL",
                     98: };
                     99: #endif
                    100:
1.8       christos  101: #ifndef __BIND_NOSTATIC
                    102: extern struct __res_state _nres;
1.1       christos  103:
                    104: /* Proto. */
                    105:
1.2       christos  106: int  res_ourserver_p(const res_state, const struct sockaddr *);
1.1       christos  107:
                    108: int
                    109: res_init(void) {
1.8       christos  110:        int rv;
1.1       christos  111:        extern int __res_vinit(res_state, int);
1.8       christos  112: #ifdef COMPAT__RES
                    113:        /*
                    114:         * Compatibility with program that were accessing _res directly
                    115:         * to set options. We keep another struct res that is the same
                    116:         * size as the original res structure, and then copy fields to
                    117:         * it so that we achieve the same initialization
                    118:         */
                    119:        extern void *__res_get_old_state(void);
                    120:        extern void __res_put_old_state(void *);
                    121:        res_state ores = __res_get_old_state();
                    122:
                    123:        if (ores->options != 0)
                    124:                _nres.options = ores->options;
                    125:        if (ores->retrans != 0)
                    126:                _nres.retrans = ores->retrans;
                    127:        if (ores->retry != 0)
                    128:                _nres.retry = ores->retry;
                    129: #endif
1.1       christos  130:
                    131:        /*
                    132:         * These three fields used to be statically initialized.  This made
                    133:         * it hard to use this code in a shared library.  It is necessary,
                    134:         * now that we're doing dynamic initialization here, that we preserve
                    135:         * the old semantics: if an application modifies one of these three
                    136:         * fields of _res before res_init() is called, res_init() will not
                    137:         * alter them.  Of course, if an application is setting them to
                    138:         * _zero_ before calling res_init(), hoping to override what used
                    139:         * to be the static default, we can't detect it and unexpected results
                    140:         * will follow.  Zero for any of these fields would make no sense,
                    141:         * so one can safely assume that the applications were already getting
                    142:         * unexpected results.
                    143:         *
1.8       christos  144:         * _nres.options is tricky since some apps were known to diddle the bits
1.1       christos  145:         * before res_init() was first called. We can't replicate that semantic
                    146:         * with dynamic initialization (they may have turned bits off that are
                    147:         * set in RES_DEFAULT).  Our solution is to declare such applications
                    148:         * "broken".  They could fool us by setting RES_INIT but none do (yet).
                    149:         */
1.8       christos  150:        if (!_nres.retrans)
                    151:                _nres.retrans = RES_TIMEOUT;
                    152:        if (!_nres.retry)
                    153:                _nres.retry = 4;
                    154:        if (!(_nres.options & RES_INIT))
                    155:                _nres.options = RES_DEFAULT;
1.1       christos  156:
                    157:        /*
                    158:         * This one used to initialize implicitly to zero, so unless the app
                    159:         * has set it to something in particular, we can randomize it now.
                    160:         */
1.8       christos  161:        if (!_nres.id)
1.12    ! christos  162:                _nres.id = res_nrandomid(&_nres);
1.1       christos  163:
1.8       christos  164:        rv = __res_vinit(&_nres, 1);
                    165: #ifdef COMPAT__RES
                    166:        __res_put_old_state(&_nres);
                    167: #endif
                    168:        return rv;
1.1       christos  169: }
                    170:
                    171: void
                    172: p_query(const u_char *msg) {
                    173:        fp_query(msg, stdout);
                    174: }
                    175:
                    176: void
                    177: fp_query(const u_char *msg, FILE *file) {
                    178:        fp_nquery(msg, PACKETSZ, file);
                    179: }
                    180:
                    181: void
                    182: fp_nquery(const u_char *msg, int len, FILE *file) {
1.8       christos  183:        if ((_nres.options & RES_INIT) == 0U && res_init() == -1)
1.1       christos  184:                return;
                    185:
1.8       christos  186:        res_pquery(&_nres, msg, len, file);
1.1       christos  187: }
                    188:
                    189: int
1.9       christos  190: res_mkquery(int op,                    /*!< opcode of query  */
                    191:            const char *dname,          /*!< domain name  */
                    192:            int class, int type,        /*!< class and type of query  */
                    193:            const u_char *data,         /*!< resource record data  */
                    194:            int datalen,                /*!< length of data  */
                    195:            const u_char *newrr_in,     /*!< new rr for modify or append  */
                    196:            u_char *buf,                /*!< buffer to put query  */
                    197:            int buflen)                 /*!< size of buffer  */
1.1       christos  198: {
1.8       christos  199:        if ((_nres.options & RES_INIT) == 0U && res_init() == -1) {
                    200:                RES_SET_H_ERRNO(&_nres, NETDB_INTERNAL);
1.1       christos  201:                return (-1);
                    202:        }
1.8       christos  203:        return (res_nmkquery(&_nres, op, dname, class, type,
1.1       christos  204:                             data, datalen,
                    205:                             newrr_in, buf, buflen));
                    206: }
                    207:
1.2       christos  208: #ifdef _LIBRESOLV
1.1       christos  209: int
                    210: res_mkupdate(ns_updrec *rrecp_in, u_char *buf, int buflen) {
1.8       christos  211:        if ((_nres.options & RES_INIT) == 0U && res_init() == -1) {
                    212:                RES_SET_H_ERRNO(&_nres, NETDB_INTERNAL);
1.1       christos  213:                return (-1);
                    214:        }
                    215:
1.8       christos  216:        return (res_nmkupdate(&_nres, rrecp_in, buf, buflen));
1.1       christos  217: }
1.2       christos  218: #endif
1.1       christos  219:
                    220: int
1.9       christos  221: res_query(const char *name,    /*!< domain name  */
                    222:          int class, int type,  /*!< class and type of query  */
                    223:          u_char *answer,       /*!< buffer to put answer  */
                    224:          int anslen)           /*!< size of answer buffer  */
1.1       christos  225: {
1.8       christos  226:        if ((_nres.options & RES_INIT) == 0U && res_init() == -1) {
                    227:                RES_SET_H_ERRNO(&_nres, NETDB_INTERNAL);
1.1       christos  228:                return (-1);
                    229:        }
1.8       christos  230:        return (res_nquery(&_nres, name, class, type, answer, anslen));
1.1       christos  231: }
                    232:
                    233: void
                    234: res_send_setqhook(res_send_qhook hook) {
1.8       christos  235:        _nres.qhook = hook;
1.1       christos  236: }
                    237:
                    238: void
                    239: res_send_setrhook(res_send_rhook hook) {
1.8       christos  240:        _nres.rhook = hook;
1.1       christos  241: }
                    242:
                    243: int
                    244: res_isourserver(const struct sockaddr_in *inp) {
1.8       christos  245:        return (res_ourserver_p(&_nres, (const struct sockaddr *)(const void *)inp));
1.1       christos  246: }
                    247:
                    248: int
                    249: res_send(const u_char *buf, int buflen, u_char *ans, int anssiz) {
1.8       christos  250:        if ((_nres.options & RES_INIT) == 0U && res_init() == -1) {
1.1       christos  251:                /* errno should have been set by res_init() in this case. */
                    252:                return (-1);
                    253:        }
                    254:
1.8       christos  255:        return (res_nsend(&_nres, buf, buflen, ans, anssiz));
1.1       christos  256: }
                    257:
1.2       christos  258: #ifdef _LIBRESOLV
1.1       christos  259: int
                    260: res_sendsigned(const u_char *buf, int buflen, ns_tsig_key *key,
                    261:               u_char *ans, int anssiz)
                    262: {
1.8       christos  263:        if ((_nres.options & RES_INIT) == 0U && res_init() == -1) {
1.1       christos  264:                /* errno should have been set by res_init() in this case. */
                    265:                return (-1);
                    266:        }
                    267:
1.8       christos  268:        return (res_nsendsigned(&_nres, buf, buflen, key, ans, anssiz));
1.1       christos  269: }
1.2       christos  270: #endif
1.1       christos  271:
                    272: void
                    273: res_close(void) {
1.8       christos  274:        res_nclose(&_nres);
1.1       christos  275: }
                    276:
1.2       christos  277: #ifdef _LIBRESOLV
1.1       christos  278: int
                    279: res_update(ns_updrec *rrecp_in) {
1.8       christos  280:        if ((_nres.options & RES_INIT) == 0U && res_init() == -1) {
                    281:                RES_SET_H_ERRNO(&_nres, NETDB_INTERNAL);
1.1       christos  282:                return (-1);
                    283:        }
                    284:
1.8       christos  285:        return (res_nupdate(&_nres, rrecp_in, NULL));
1.1       christos  286: }
1.2       christos  287: #endif
1.1       christos  288:
                    289: int
1.9       christos  290: res_search(const char *name,   /*!< domain name  */
                    291:           int class, int type, /*!< class and type of query  */
                    292:           u_char *answer,      /*!< buffer to put answer  */
                    293:           int anslen)          /*!< size of answer  */
1.1       christos  294: {
1.8       christos  295:        if ((_nres.options & RES_INIT) == 0U && res_init() == -1) {
                    296:                RES_SET_H_ERRNO(&_nres, NETDB_INTERNAL);
1.1       christos  297:                return (-1);
                    298:        }
                    299:
1.8       christos  300:        return (res_nsearch(&_nres, name, class, type, answer, anslen));
1.1       christos  301: }
                    302:
                    303: int
                    304: res_querydomain(const char *name,
                    305:                const char *domain,
1.9       christos  306:                int class, int type,    /*!< class and type of query  */
                    307:                u_char *answer,         /*!< buffer to put answer  */
                    308:                int anslen)             /*!< size of answer  */
1.1       christos  309: {
1.8       christos  310:        if ((_nres.options & RES_INIT) == 0U && res_init() == -1) {
                    311:                RES_SET_H_ERRNO(&_nres, NETDB_INTERNAL);
1.1       christos  312:                return (-1);
                    313:        }
                    314:
1.8       christos  315:        return (res_nquerydomain(&_nres, name, domain,
1.1       christos  316:                                 class, type,
                    317:                                 answer, anslen));
                    318: }
                    319:
1.2       christos  320: int
                    321: res_opt(int a, u_char *b, int c, int d)
                    322: {
1.8       christos  323:        return res_nopt(&_nres, a, b, c, d);
1.2       christos  324: }
                    325:
1.12    ! christos  326: u_int
        !           327: res_randomid(void) {
        !           328:        if ((_nres.options & RES_INIT) == 0U && res_init() == -1) {
        !           329:                RES_SET_H_ERRNO(&_res, NETDB_INTERNAL);
        !           330:                return (-1);
        !           331:        }
        !           332:
        !           333:        return (res_nrandomid(&_nres));
        !           334: }
        !           335:
1.1       christos  336: const char *
                    337: hostalias(const char *name) {
                    338:        static char abuf[MAXDNAME];
                    339:
1.8       christos  340:        return (res_hostalias(&_nres, name, abuf, sizeof abuf));
1.1       christos  341: }
                    342:
                    343: #ifdef ultrix
                    344: int
                    345: local_hostname_length(const char *hostname) {
                    346:        int len_host, len_domain;
                    347:
1.8       christos  348:        if (!*_nres.defdname)
1.1       christos  349:                res_init();
                    350:        len_host = strlen(hostname);
1.8       christos  351:        len_domain = strlen(_nres.defdname);
1.1       christos  352:        if (len_host > len_domain &&
1.8       christos  353:            !strcasecmp(hostname + len_host - len_domain, _nres.defdname) &&
1.1       christos  354:            hostname[len_host - len_domain - 1] == '.')
                    355:                return (len_host - len_domain - 1);
                    356:        return (0);
                    357: }
                    358: #endif /*ultrix*/
                    359:
                    360: #endif
1.9       christos  361:
                    362: /*! \file */

CVSweb <webmaster@jp.NetBSD.org>