10Sstevel@tonic-gate /*
2*12094SStacey.Marshall@Sun.COM * Copyright (c) 1996, 2010, Oracle and/or its affiliates. All rights reserved.
30Sstevel@tonic-gate */
40Sstevel@tonic-gate
511038SRao.Shoaib@Sun.COM
60Sstevel@tonic-gate /*
711038SRao.Shoaib@Sun.COM * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
80Sstevel@tonic-gate * Copyright (c) 1995-1999 by Internet Software Consortium.
90Sstevel@tonic-gate *
100Sstevel@tonic-gate * Permission to use, copy, modify, and distribute this software for any
110Sstevel@tonic-gate * purpose with or without fee is hereby granted, provided that the above
120Sstevel@tonic-gate * copyright notice and this permission notice appear in all copies.
130Sstevel@tonic-gate *
1411038SRao.Shoaib@Sun.COM * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
1511038SRao.Shoaib@Sun.COM * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
1611038SRao.Shoaib@Sun.COM * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR
1711038SRao.Shoaib@Sun.COM * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
1811038SRao.Shoaib@Sun.COM * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
1911038SRao.Shoaib@Sun.COM * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
2011038SRao.Shoaib@Sun.COM * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
210Sstevel@tonic-gate */
220Sstevel@tonic-gate
230Sstevel@tonic-gate #if defined(LIBC_SCCS) && !defined(lint)
2411038SRao.Shoaib@Sun.COM static const char rcsid[] = "$Id: res_data.c,v 1.7 2008/12/11 09:59:00 marka Exp $";
250Sstevel@tonic-gate #endif /* LIBC_SCCS and not lint */
260Sstevel@tonic-gate
270Sstevel@tonic-gate #include "port_before.h"
280Sstevel@tonic-gate
290Sstevel@tonic-gate #include <sys/types.h>
300Sstevel@tonic-gate #include <sys/param.h>
310Sstevel@tonic-gate #include <sys/socket.h>
320Sstevel@tonic-gate #include <sys/time.h>
330Sstevel@tonic-gate
340Sstevel@tonic-gate #include <netinet/in.h>
350Sstevel@tonic-gate #include <arpa/inet.h>
360Sstevel@tonic-gate #include <arpa/nameser.h>
370Sstevel@tonic-gate
380Sstevel@tonic-gate #include <ctype.h>
390Sstevel@tonic-gate #include <netdb.h>
400Sstevel@tonic-gate #include <resolv.h>
410Sstevel@tonic-gate #include <res_update.h>
420Sstevel@tonic-gate #include <stdio.h>
430Sstevel@tonic-gate #include <stdlib.h>
440Sstevel@tonic-gate #include <string.h>
450Sstevel@tonic-gate #include <unistd.h>
460Sstevel@tonic-gate
470Sstevel@tonic-gate #include "port_after.h"
480Sstevel@tonic-gate
4911038SRao.Shoaib@Sun.COM #ifndef ORIGINAL_ISC_CODE
500Sstevel@tonic-gate #pragma weak __fp_nquery = fp_nquery
510Sstevel@tonic-gate #pragma weak __fp_query = fp_query
520Sstevel@tonic-gate #pragma weak __p_query = p_query
530Sstevel@tonic-gate #pragma weak __hostalias = hostalias
5411038SRao.Shoaib@Sun.COM #pragma weak __res_randomid = res_randomid
550Sstevel@tonic-gate #endif
560Sstevel@tonic-gate
570Sstevel@tonic-gate const char *_res_opcodes[] = {
580Sstevel@tonic-gate "QUERY",
590Sstevel@tonic-gate "IQUERY",
600Sstevel@tonic-gate "CQUERYM",
6111038SRao.Shoaib@Sun.COM "CQUERYU", /*%< experimental */
6211038SRao.Shoaib@Sun.COM "NOTIFY", /*%< experimental */
630Sstevel@tonic-gate "UPDATE",
640Sstevel@tonic-gate "6",
650Sstevel@tonic-gate "7",
660Sstevel@tonic-gate "8",
670Sstevel@tonic-gate "9",
680Sstevel@tonic-gate "10",
690Sstevel@tonic-gate "11",
700Sstevel@tonic-gate "12",
710Sstevel@tonic-gate "13",
720Sstevel@tonic-gate "ZONEINIT",
730Sstevel@tonic-gate "ZONEREF",
740Sstevel@tonic-gate };
750Sstevel@tonic-gate
760Sstevel@tonic-gate #ifdef BIND_UPDATE
770Sstevel@tonic-gate const char *_res_sectioncodes[] = {
780Sstevel@tonic-gate "ZONE",
790Sstevel@tonic-gate "PREREQUISITES",
800Sstevel@tonic-gate "UPDATE",
810Sstevel@tonic-gate "ADDITIONAL",
820Sstevel@tonic-gate };
830Sstevel@tonic-gate #endif
840Sstevel@tonic-gate
8511038SRao.Shoaib@Sun.COM #undef _res
860Sstevel@tonic-gate #ifndef __BIND_NOSTATIC
870Sstevel@tonic-gate struct __res_state _res
880Sstevel@tonic-gate # if defined(__BIND_RES_TEXT)
8911038SRao.Shoaib@Sun.COM = { RES_TIMEOUT, } /*%< Motorola, et al. */
900Sstevel@tonic-gate # endif
910Sstevel@tonic-gate ;
920Sstevel@tonic-gate
93*12094SStacey.Marshall@Sun.COM #ifdef ORIGINAL_ISC_CODE
9411038SRao.Shoaib@Sun.COM #if defined(DO_PTHREADS) || defined(__linux)
9511038SRao.Shoaib@Sun.COM #define _res (*__res_state())
9611038SRao.Shoaib@Sun.COM #endif
97*12094SStacey.Marshall@Sun.COM #endif
9811038SRao.Shoaib@Sun.COM
990Sstevel@tonic-gate /* Proto. */
1000Sstevel@tonic-gate
1010Sstevel@tonic-gate int res_ourserver_p(const res_state, const struct sockaddr_in *);
1020Sstevel@tonic-gate
1030Sstevel@tonic-gate int
res_init(void)1040Sstevel@tonic-gate res_init(void) {
1050Sstevel@tonic-gate extern int __res_vinit(res_state, int);
1060Sstevel@tonic-gate
1070Sstevel@tonic-gate /*
1080Sstevel@tonic-gate * These three fields used to be statically initialized. This made
1090Sstevel@tonic-gate * it hard to use this code in a shared library. It is necessary,
1100Sstevel@tonic-gate * now that we're doing dynamic initialization here, that we preserve
1110Sstevel@tonic-gate * the old semantics: if an application modifies one of these three
1120Sstevel@tonic-gate * fields of _res before res_init() is called, res_init() will not
1130Sstevel@tonic-gate * alter them. Of course, if an application is setting them to
1140Sstevel@tonic-gate * _zero_ before calling res_init(), hoping to override what used
1150Sstevel@tonic-gate * to be the static default, we can't detect it and unexpected results
1160Sstevel@tonic-gate * will follow. Zero for any of these fields would make no sense,
1170Sstevel@tonic-gate * so one can safely assume that the applications were already getting
1180Sstevel@tonic-gate * unexpected results.
1190Sstevel@tonic-gate *
1200Sstevel@tonic-gate * _res.options is tricky since some apps were known to diddle the bits
1210Sstevel@tonic-gate * before res_init() was first called. We can't replicate that semantic
1220Sstevel@tonic-gate * with dynamic initialization (they may have turned bits off that are
1230Sstevel@tonic-gate * set in RES_DEFAULT). Our solution is to declare such applications
1240Sstevel@tonic-gate * "broken". They could fool us by setting RES_INIT but none do (yet).
1250Sstevel@tonic-gate */
1260Sstevel@tonic-gate if (!_res.retrans)
1270Sstevel@tonic-gate _res.retrans = RES_TIMEOUT;
1280Sstevel@tonic-gate if (!_res.retry)
1290Sstevel@tonic-gate _res.retry = 4;
1300Sstevel@tonic-gate if (!(_res.options & RES_INIT))
1310Sstevel@tonic-gate _res.options = RES_DEFAULT;
1320Sstevel@tonic-gate
1330Sstevel@tonic-gate /*
1340Sstevel@tonic-gate * This one used to initialize implicitly to zero, so unless the app
1350Sstevel@tonic-gate * has set it to something in particular, we can randomize it now.
1360Sstevel@tonic-gate */
1370Sstevel@tonic-gate if (!_res.id)
13811038SRao.Shoaib@Sun.COM _res.id = res_nrandomid(&_res);
1390Sstevel@tonic-gate
1400Sstevel@tonic-gate return (__res_vinit(&_res, 1));
1410Sstevel@tonic-gate }
1420Sstevel@tonic-gate
1430Sstevel@tonic-gate void
p_query(const u_char * msg)1440Sstevel@tonic-gate p_query(const u_char *msg) {
1450Sstevel@tonic-gate fp_query(msg, stdout);
1460Sstevel@tonic-gate }
1470Sstevel@tonic-gate
1480Sstevel@tonic-gate void
fp_query(const u_char * msg,FILE * file)1490Sstevel@tonic-gate fp_query(const u_char *msg, FILE *file) {
1500Sstevel@tonic-gate fp_nquery(msg, PACKETSZ, file);
1510Sstevel@tonic-gate }
1520Sstevel@tonic-gate
1530Sstevel@tonic-gate void
fp_nquery(const u_char * msg,int len,FILE * file)1540Sstevel@tonic-gate fp_nquery(const u_char *msg, int len, FILE *file) {
15511038SRao.Shoaib@Sun.COM if ((_res.options & RES_INIT) == 0U && res_init() == -1)
1560Sstevel@tonic-gate return;
1570Sstevel@tonic-gate
1580Sstevel@tonic-gate res_pquery(&_res, msg, len, file);
1590Sstevel@tonic-gate }
1600Sstevel@tonic-gate
1610Sstevel@tonic-gate int
res_mkquery(int op,const char * dname,int class,int type,const u_char * data,int datalen,const u_char * newrr_in,u_char * buf,int buflen)16211038SRao.Shoaib@Sun.COM res_mkquery(int op, /*!< opcode of query */
16311038SRao.Shoaib@Sun.COM const char *dname, /*!< domain name */
16411038SRao.Shoaib@Sun.COM int class, int type, /*!< class and type of query */
16511038SRao.Shoaib@Sun.COM const u_char *data, /*!< resource record data */
16611038SRao.Shoaib@Sun.COM int datalen, /*!< length of data */
16711038SRao.Shoaib@Sun.COM const u_char *newrr_in, /*!< new rr for modify or append */
16811038SRao.Shoaib@Sun.COM u_char *buf, /*!< buffer to put query */
16911038SRao.Shoaib@Sun.COM int buflen) /*!< size of buffer */
1700Sstevel@tonic-gate {
17111038SRao.Shoaib@Sun.COM if ((_res.options & RES_INIT) == 0U && res_init() == -1) {
1720Sstevel@tonic-gate RES_SET_H_ERRNO(&_res, NETDB_INTERNAL);
1730Sstevel@tonic-gate return (-1);
1740Sstevel@tonic-gate }
1750Sstevel@tonic-gate return (res_nmkquery(&_res, op, dname, class, type,
1760Sstevel@tonic-gate data, datalen,
1770Sstevel@tonic-gate newrr_in, buf, buflen));
1780Sstevel@tonic-gate }
1790Sstevel@tonic-gate
1800Sstevel@tonic-gate int
res_mkupdate(ns_updrec * rrecp_in,u_char * buf,int buflen)1810Sstevel@tonic-gate res_mkupdate(ns_updrec *rrecp_in, u_char *buf, int buflen) {
18211038SRao.Shoaib@Sun.COM if ((_res.options & RES_INIT) == 0U && res_init() == -1) {
1830Sstevel@tonic-gate RES_SET_H_ERRNO(&_res, NETDB_INTERNAL);
1840Sstevel@tonic-gate return (-1);
1850Sstevel@tonic-gate }
1860Sstevel@tonic-gate
1870Sstevel@tonic-gate return (res_nmkupdate(&_res, rrecp_in, buf, buflen));
1880Sstevel@tonic-gate }
1890Sstevel@tonic-gate
1900Sstevel@tonic-gate int
res_query(const char * name,int class,int type,u_char * answer,int anslen)19111038SRao.Shoaib@Sun.COM res_query(const char *name, /*!< domain name */
19211038SRao.Shoaib@Sun.COM int class, int type, /*!< class and type of query */
19311038SRao.Shoaib@Sun.COM u_char *answer, /*!< buffer to put answer */
19411038SRao.Shoaib@Sun.COM int anslen) /*!< size of answer buffer */
1950Sstevel@tonic-gate {
19611038SRao.Shoaib@Sun.COM if ((_res.options & RES_INIT) == 0U && res_init() == -1) {
1970Sstevel@tonic-gate RES_SET_H_ERRNO(&_res, NETDB_INTERNAL);
1980Sstevel@tonic-gate return (-1);
1990Sstevel@tonic-gate }
2000Sstevel@tonic-gate return (res_nquery(&_res, name, class, type, answer, anslen));
2010Sstevel@tonic-gate }
2020Sstevel@tonic-gate
2030Sstevel@tonic-gate void
res_send_setqhook(res_send_qhook hook)2040Sstevel@tonic-gate res_send_setqhook(res_send_qhook hook) {
2050Sstevel@tonic-gate _res.qhook = hook;
2060Sstevel@tonic-gate }
2070Sstevel@tonic-gate
2080Sstevel@tonic-gate void
res_send_setrhook(res_send_rhook hook)2090Sstevel@tonic-gate res_send_setrhook(res_send_rhook hook) {
2100Sstevel@tonic-gate _res.rhook = hook;
2110Sstevel@tonic-gate }
2120Sstevel@tonic-gate
2130Sstevel@tonic-gate int
res_isourserver(const struct sockaddr_in * inp)2140Sstevel@tonic-gate res_isourserver(const struct sockaddr_in *inp) {
2150Sstevel@tonic-gate return (res_ourserver_p(&_res, inp));
2160Sstevel@tonic-gate }
2170Sstevel@tonic-gate
2180Sstevel@tonic-gate int
res_send(const u_char * buf,int buflen,u_char * ans,int anssiz)2190Sstevel@tonic-gate res_send(const u_char *buf, int buflen, u_char *ans, int anssiz) {
22011038SRao.Shoaib@Sun.COM if ((_res.options & RES_INIT) == 0U && res_init() == -1) {
2210Sstevel@tonic-gate /* errno should have been set by res_init() in this case. */
2220Sstevel@tonic-gate return (-1);
2230Sstevel@tonic-gate }
2240Sstevel@tonic-gate
2250Sstevel@tonic-gate return (res_nsend(&_res, buf, buflen, ans, anssiz));
2260Sstevel@tonic-gate }
2270Sstevel@tonic-gate
2280Sstevel@tonic-gate int
res_sendsigned(const u_char * buf,int buflen,ns_tsig_key * key,u_char * ans,int anssiz)2290Sstevel@tonic-gate res_sendsigned(const u_char *buf, int buflen, ns_tsig_key *key,
2300Sstevel@tonic-gate u_char *ans, int anssiz)
2310Sstevel@tonic-gate {
23211038SRao.Shoaib@Sun.COM if ((_res.options & RES_INIT) == 0U && res_init() == -1) {
2330Sstevel@tonic-gate /* errno should have been set by res_init() in this case. */
2340Sstevel@tonic-gate return (-1);
2350Sstevel@tonic-gate }
2360Sstevel@tonic-gate
2370Sstevel@tonic-gate return (res_nsendsigned(&_res, buf, buflen, key, ans, anssiz));
2380Sstevel@tonic-gate }
2390Sstevel@tonic-gate
2400Sstevel@tonic-gate void
res_close(void)2410Sstevel@tonic-gate res_close(void) {
2420Sstevel@tonic-gate res_nclose(&_res);
2430Sstevel@tonic-gate }
2440Sstevel@tonic-gate
2450Sstevel@tonic-gate int
res_update(ns_updrec * rrecp_in)2460Sstevel@tonic-gate res_update(ns_updrec *rrecp_in) {
24711038SRao.Shoaib@Sun.COM if ((_res.options & RES_INIT) == 0U && res_init() == -1) {
2480Sstevel@tonic-gate RES_SET_H_ERRNO(&_res, NETDB_INTERNAL);
2490Sstevel@tonic-gate return (-1);
2500Sstevel@tonic-gate }
2510Sstevel@tonic-gate
2520Sstevel@tonic-gate return (res_nupdate(&_res, rrecp_in, NULL));
2530Sstevel@tonic-gate }
2540Sstevel@tonic-gate
2550Sstevel@tonic-gate int
res_search(const char * name,int class,int type,u_char * answer,int anslen)25611038SRao.Shoaib@Sun.COM res_search(const char *name, /*!< domain name */
25711038SRao.Shoaib@Sun.COM int class, int type, /*!< class and type of query */
25811038SRao.Shoaib@Sun.COM u_char *answer, /*!< buffer to put answer */
25911038SRao.Shoaib@Sun.COM int anslen) /*!< size of answer */
2600Sstevel@tonic-gate {
26111038SRao.Shoaib@Sun.COM if ((_res.options & RES_INIT) == 0U && res_init() == -1) {
2620Sstevel@tonic-gate RES_SET_H_ERRNO(&_res, NETDB_INTERNAL);
2630Sstevel@tonic-gate return (-1);
2640Sstevel@tonic-gate }
2650Sstevel@tonic-gate
2660Sstevel@tonic-gate return (res_nsearch(&_res, name, class, type, answer, anslen));
2670Sstevel@tonic-gate }
2680Sstevel@tonic-gate
2690Sstevel@tonic-gate int
res_querydomain(const char * name,const char * domain,int class,int type,u_char * answer,int anslen)2700Sstevel@tonic-gate res_querydomain(const char *name,
2710Sstevel@tonic-gate const char *domain,
27211038SRao.Shoaib@Sun.COM int class, int type, /*!< class and type of query */
27311038SRao.Shoaib@Sun.COM u_char *answer, /*!< buffer to put answer */
27411038SRao.Shoaib@Sun.COM int anslen) /*!< size of answer */
2750Sstevel@tonic-gate {
27611038SRao.Shoaib@Sun.COM if ((_res.options & RES_INIT) == 0U && res_init() == -1) {
2770Sstevel@tonic-gate RES_SET_H_ERRNO(&_res, NETDB_INTERNAL);
2780Sstevel@tonic-gate return (-1);
2790Sstevel@tonic-gate }
2800Sstevel@tonic-gate
2810Sstevel@tonic-gate return (res_nquerydomain(&_res, name, domain,
2820Sstevel@tonic-gate class, type,
2830Sstevel@tonic-gate answer, anslen));
2840Sstevel@tonic-gate }
2850Sstevel@tonic-gate
28611038SRao.Shoaib@Sun.COM u_int
res_randomid(void)28711038SRao.Shoaib@Sun.COM res_randomid(void) {
28811038SRao.Shoaib@Sun.COM if ((_res.options & RES_INIT) == 0U && res_init() == -1) {
28911038SRao.Shoaib@Sun.COM RES_SET_H_ERRNO(&_res, NETDB_INTERNAL);
29011038SRao.Shoaib@Sun.COM return (-1);
29111038SRao.Shoaib@Sun.COM }
29211038SRao.Shoaib@Sun.COM
29311038SRao.Shoaib@Sun.COM return (res_nrandomid(&_res));
29411038SRao.Shoaib@Sun.COM }
29511038SRao.Shoaib@Sun.COM
2960Sstevel@tonic-gate const char *
hostalias(const char * name)2970Sstevel@tonic-gate hostalias(const char *name) {
2980Sstevel@tonic-gate static char abuf[MAXDNAME];
2990Sstevel@tonic-gate
3000Sstevel@tonic-gate return (res_hostalias(&_res, name, abuf, sizeof abuf));
3010Sstevel@tonic-gate }
3020Sstevel@tonic-gate
3030Sstevel@tonic-gate #ifdef ultrix
3040Sstevel@tonic-gate int
local_hostname_length(const char * hostname)3050Sstevel@tonic-gate local_hostname_length(const char *hostname) {
3060Sstevel@tonic-gate int len_host, len_domain;
3070Sstevel@tonic-gate
3080Sstevel@tonic-gate if (!*_res.defdname)
3090Sstevel@tonic-gate res_init();
3100Sstevel@tonic-gate len_host = strlen(hostname);
3110Sstevel@tonic-gate len_domain = strlen(_res.defdname);
3120Sstevel@tonic-gate if (len_host > len_domain &&
3130Sstevel@tonic-gate !strcasecmp(hostname + len_host - len_domain, _res.defdname) &&
3140Sstevel@tonic-gate hostname[len_host - len_domain - 1] == '.')
3150Sstevel@tonic-gate return (len_host - len_domain - 1);
3160Sstevel@tonic-gate return (0);
3170Sstevel@tonic-gate }
3180Sstevel@tonic-gate #endif /*ultrix*/
3190Sstevel@tonic-gate
3200Sstevel@tonic-gate #endif
32111038SRao.Shoaib@Sun.COM
32211038SRao.Shoaib@Sun.COM /*! \file */
323