17c478bd9Sstevel@tonic-gate /*
2*4e567b44SStacey Marshall * Copyright (c) 1996, 2010, Oracle and/or its affiliates. All rights reserved.
37c478bd9Sstevel@tonic-gate */
47c478bd9Sstevel@tonic-gate
59525b14bSRao Shoaib
67c478bd9Sstevel@tonic-gate /*
79525b14bSRao Shoaib * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
87c478bd9Sstevel@tonic-gate * Copyright (c) 1995-1999 by Internet Software Consortium.
97c478bd9Sstevel@tonic-gate *
107c478bd9Sstevel@tonic-gate * Permission to use, copy, modify, and distribute this software for any
117c478bd9Sstevel@tonic-gate * purpose with or without fee is hereby granted, provided that the above
127c478bd9Sstevel@tonic-gate * copyright notice and this permission notice appear in all copies.
137c478bd9Sstevel@tonic-gate *
149525b14bSRao Shoaib * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
159525b14bSRao Shoaib * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
169525b14bSRao Shoaib * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR
179525b14bSRao Shoaib * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
189525b14bSRao Shoaib * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
199525b14bSRao Shoaib * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
209525b14bSRao Shoaib * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
217c478bd9Sstevel@tonic-gate */
227c478bd9Sstevel@tonic-gate
237c478bd9Sstevel@tonic-gate #include "port_before.h"
247c478bd9Sstevel@tonic-gate
257c478bd9Sstevel@tonic-gate #include <sys/types.h>
267c478bd9Sstevel@tonic-gate #include <sys/param.h>
277c478bd9Sstevel@tonic-gate #include <sys/socket.h>
287c478bd9Sstevel@tonic-gate #include <sys/time.h>
297c478bd9Sstevel@tonic-gate
307c478bd9Sstevel@tonic-gate #include <netinet/in.h>
317c478bd9Sstevel@tonic-gate #include <arpa/inet.h>
327c478bd9Sstevel@tonic-gate #include <arpa/nameser.h>
337c478bd9Sstevel@tonic-gate
347c478bd9Sstevel@tonic-gate #include <ctype.h>
357c478bd9Sstevel@tonic-gate #include <netdb.h>
367c478bd9Sstevel@tonic-gate #include <resolv.h>
377c478bd9Sstevel@tonic-gate #include <res_update.h>
387c478bd9Sstevel@tonic-gate #include <stdio.h>
397c478bd9Sstevel@tonic-gate #include <stdlib.h>
407c478bd9Sstevel@tonic-gate #include <string.h>
417c478bd9Sstevel@tonic-gate #include <unistd.h>
427c478bd9Sstevel@tonic-gate
437c478bd9Sstevel@tonic-gate #include "port_after.h"
447c478bd9Sstevel@tonic-gate
459525b14bSRao Shoaib #ifndef ORIGINAL_ISC_CODE
467c478bd9Sstevel@tonic-gate #pragma weak __fp_nquery = fp_nquery
477c478bd9Sstevel@tonic-gate #pragma weak __fp_query = fp_query
487c478bd9Sstevel@tonic-gate #pragma weak __p_query = p_query
497c478bd9Sstevel@tonic-gate #pragma weak __hostalias = hostalias
509525b14bSRao Shoaib #pragma weak __res_randomid = res_randomid
517c478bd9Sstevel@tonic-gate #endif
527c478bd9Sstevel@tonic-gate
537c478bd9Sstevel@tonic-gate const char *_res_opcodes[] = {
547c478bd9Sstevel@tonic-gate "QUERY",
557c478bd9Sstevel@tonic-gate "IQUERY",
567c478bd9Sstevel@tonic-gate "CQUERYM",
579525b14bSRao Shoaib "CQUERYU", /*%< experimental */
589525b14bSRao Shoaib "NOTIFY", /*%< experimental */
597c478bd9Sstevel@tonic-gate "UPDATE",
607c478bd9Sstevel@tonic-gate "6",
617c478bd9Sstevel@tonic-gate "7",
627c478bd9Sstevel@tonic-gate "8",
637c478bd9Sstevel@tonic-gate "9",
647c478bd9Sstevel@tonic-gate "10",
657c478bd9Sstevel@tonic-gate "11",
667c478bd9Sstevel@tonic-gate "12",
677c478bd9Sstevel@tonic-gate "13",
687c478bd9Sstevel@tonic-gate "ZONEINIT",
697c478bd9Sstevel@tonic-gate "ZONEREF",
707c478bd9Sstevel@tonic-gate };
717c478bd9Sstevel@tonic-gate
727c478bd9Sstevel@tonic-gate #ifdef BIND_UPDATE
737c478bd9Sstevel@tonic-gate const char *_res_sectioncodes[] = {
747c478bd9Sstevel@tonic-gate "ZONE",
757c478bd9Sstevel@tonic-gate "PREREQUISITES",
767c478bd9Sstevel@tonic-gate "UPDATE",
777c478bd9Sstevel@tonic-gate "ADDITIONAL",
787c478bd9Sstevel@tonic-gate };
797c478bd9Sstevel@tonic-gate #endif
807c478bd9Sstevel@tonic-gate
819525b14bSRao Shoaib #undef _res
827c478bd9Sstevel@tonic-gate #ifndef __BIND_NOSTATIC
837c478bd9Sstevel@tonic-gate struct __res_state _res
847c478bd9Sstevel@tonic-gate # if defined(__BIND_RES_TEXT)
859525b14bSRao Shoaib = { RES_TIMEOUT, } /*%< Motorola, et al. */
867c478bd9Sstevel@tonic-gate # endif
877c478bd9Sstevel@tonic-gate ;
887c478bd9Sstevel@tonic-gate
89*4e567b44SStacey Marshall #ifdef ORIGINAL_ISC_CODE
909525b14bSRao Shoaib #if defined(DO_PTHREADS) || defined(__linux)
919525b14bSRao Shoaib #define _res (*__res_state())
929525b14bSRao Shoaib #endif
93*4e567b44SStacey Marshall #endif
949525b14bSRao Shoaib
957c478bd9Sstevel@tonic-gate /* Proto. */
967c478bd9Sstevel@tonic-gate
977c478bd9Sstevel@tonic-gate int res_ourserver_p(const res_state, const struct sockaddr_in *);
987c478bd9Sstevel@tonic-gate
997c478bd9Sstevel@tonic-gate int
res_init(void)1007c478bd9Sstevel@tonic-gate res_init(void) {
1017c478bd9Sstevel@tonic-gate extern int __res_vinit(res_state, int);
1027c478bd9Sstevel@tonic-gate
1037c478bd9Sstevel@tonic-gate /*
1047c478bd9Sstevel@tonic-gate * These three fields used to be statically initialized. This made
1057c478bd9Sstevel@tonic-gate * it hard to use this code in a shared library. It is necessary,
1067c478bd9Sstevel@tonic-gate * now that we're doing dynamic initialization here, that we preserve
1077c478bd9Sstevel@tonic-gate * the old semantics: if an application modifies one of these three
1087c478bd9Sstevel@tonic-gate * fields of _res before res_init() is called, res_init() will not
1097c478bd9Sstevel@tonic-gate * alter them. Of course, if an application is setting them to
1107c478bd9Sstevel@tonic-gate * _zero_ before calling res_init(), hoping to override what used
1117c478bd9Sstevel@tonic-gate * to be the static default, we can't detect it and unexpected results
1127c478bd9Sstevel@tonic-gate * will follow. Zero for any of these fields would make no sense,
1137c478bd9Sstevel@tonic-gate * so one can safely assume that the applications were already getting
1147c478bd9Sstevel@tonic-gate * unexpected results.
1157c478bd9Sstevel@tonic-gate *
1167c478bd9Sstevel@tonic-gate * _res.options is tricky since some apps were known to diddle the bits
1177c478bd9Sstevel@tonic-gate * before res_init() was first called. We can't replicate that semantic
1187c478bd9Sstevel@tonic-gate * with dynamic initialization (they may have turned bits off that are
1197c478bd9Sstevel@tonic-gate * set in RES_DEFAULT). Our solution is to declare such applications
1207c478bd9Sstevel@tonic-gate * "broken". They could fool us by setting RES_INIT but none do (yet).
1217c478bd9Sstevel@tonic-gate */
1227c478bd9Sstevel@tonic-gate if (!_res.retrans)
1237c478bd9Sstevel@tonic-gate _res.retrans = RES_TIMEOUT;
1247c478bd9Sstevel@tonic-gate if (!_res.retry)
1257c478bd9Sstevel@tonic-gate _res.retry = 4;
1267c478bd9Sstevel@tonic-gate if (!(_res.options & RES_INIT))
1277c478bd9Sstevel@tonic-gate _res.options = RES_DEFAULT;
1287c478bd9Sstevel@tonic-gate
1297c478bd9Sstevel@tonic-gate /*
1307c478bd9Sstevel@tonic-gate * This one used to initialize implicitly to zero, so unless the app
1317c478bd9Sstevel@tonic-gate * has set it to something in particular, we can randomize it now.
1327c478bd9Sstevel@tonic-gate */
1337c478bd9Sstevel@tonic-gate if (!_res.id)
1349525b14bSRao Shoaib _res.id = res_nrandomid(&_res);
1357c478bd9Sstevel@tonic-gate
1367c478bd9Sstevel@tonic-gate return (__res_vinit(&_res, 1));
1377c478bd9Sstevel@tonic-gate }
1387c478bd9Sstevel@tonic-gate
1397c478bd9Sstevel@tonic-gate void
p_query(const u_char * msg)1407c478bd9Sstevel@tonic-gate p_query(const u_char *msg) {
1417c478bd9Sstevel@tonic-gate fp_query(msg, stdout);
1427c478bd9Sstevel@tonic-gate }
1437c478bd9Sstevel@tonic-gate
1447c478bd9Sstevel@tonic-gate void
fp_query(const u_char * msg,FILE * file)1457c478bd9Sstevel@tonic-gate fp_query(const u_char *msg, FILE *file) {
1467c478bd9Sstevel@tonic-gate fp_nquery(msg, PACKETSZ, file);
1477c478bd9Sstevel@tonic-gate }
1487c478bd9Sstevel@tonic-gate
1497c478bd9Sstevel@tonic-gate void
fp_nquery(const u_char * msg,int len,FILE * file)1507c478bd9Sstevel@tonic-gate fp_nquery(const u_char *msg, int len, FILE *file) {
1519525b14bSRao Shoaib if ((_res.options & RES_INIT) == 0U && res_init() == -1)
1527c478bd9Sstevel@tonic-gate return;
1537c478bd9Sstevel@tonic-gate
1547c478bd9Sstevel@tonic-gate res_pquery(&_res, msg, len, file);
1557c478bd9Sstevel@tonic-gate }
1567c478bd9Sstevel@tonic-gate
1577c478bd9Sstevel@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)1589525b14bSRao Shoaib res_mkquery(int op, /*!< opcode of query */
1599525b14bSRao Shoaib const char *dname, /*!< domain name */
1609525b14bSRao Shoaib int class, int type, /*!< class and type of query */
1619525b14bSRao Shoaib const u_char *data, /*!< resource record data */
1629525b14bSRao Shoaib int datalen, /*!< length of data */
1639525b14bSRao Shoaib const u_char *newrr_in, /*!< new rr for modify or append */
1649525b14bSRao Shoaib u_char *buf, /*!< buffer to put query */
1659525b14bSRao Shoaib int buflen) /*!< size of buffer */
1667c478bd9Sstevel@tonic-gate {
1679525b14bSRao Shoaib if ((_res.options & RES_INIT) == 0U && res_init() == -1) {
1687c478bd9Sstevel@tonic-gate RES_SET_H_ERRNO(&_res, NETDB_INTERNAL);
1697c478bd9Sstevel@tonic-gate return (-1);
1707c478bd9Sstevel@tonic-gate }
1717c478bd9Sstevel@tonic-gate return (res_nmkquery(&_res, op, dname, class, type,
1727c478bd9Sstevel@tonic-gate data, datalen,
1737c478bd9Sstevel@tonic-gate newrr_in, buf, buflen));
1747c478bd9Sstevel@tonic-gate }
1757c478bd9Sstevel@tonic-gate
1767c478bd9Sstevel@tonic-gate int
res_mkupdate(ns_updrec * rrecp_in,u_char * buf,int buflen)1777c478bd9Sstevel@tonic-gate res_mkupdate(ns_updrec *rrecp_in, u_char *buf, int buflen) {
1789525b14bSRao Shoaib if ((_res.options & RES_INIT) == 0U && res_init() == -1) {
1797c478bd9Sstevel@tonic-gate RES_SET_H_ERRNO(&_res, NETDB_INTERNAL);
1807c478bd9Sstevel@tonic-gate return (-1);
1817c478bd9Sstevel@tonic-gate }
1827c478bd9Sstevel@tonic-gate
1837c478bd9Sstevel@tonic-gate return (res_nmkupdate(&_res, rrecp_in, buf, buflen));
1847c478bd9Sstevel@tonic-gate }
1857c478bd9Sstevel@tonic-gate
1867c478bd9Sstevel@tonic-gate int
res_query(const char * name,int class,int type,u_char * answer,int anslen)1879525b14bSRao Shoaib res_query(const char *name, /*!< domain name */
1889525b14bSRao Shoaib int class, int type, /*!< class and type of query */
1899525b14bSRao Shoaib u_char *answer, /*!< buffer to put answer */
1909525b14bSRao Shoaib int anslen) /*!< size of answer buffer */
1917c478bd9Sstevel@tonic-gate {
1929525b14bSRao Shoaib if ((_res.options & RES_INIT) == 0U && res_init() == -1) {
1937c478bd9Sstevel@tonic-gate RES_SET_H_ERRNO(&_res, NETDB_INTERNAL);
1947c478bd9Sstevel@tonic-gate return (-1);
1957c478bd9Sstevel@tonic-gate }
1967c478bd9Sstevel@tonic-gate return (res_nquery(&_res, name, class, type, answer, anslen));
1977c478bd9Sstevel@tonic-gate }
1987c478bd9Sstevel@tonic-gate
1997c478bd9Sstevel@tonic-gate void
res_send_setqhook(res_send_qhook hook)2007c478bd9Sstevel@tonic-gate res_send_setqhook(res_send_qhook hook) {
2017c478bd9Sstevel@tonic-gate _res.qhook = hook;
2027c478bd9Sstevel@tonic-gate }
2037c478bd9Sstevel@tonic-gate
2047c478bd9Sstevel@tonic-gate void
res_send_setrhook(res_send_rhook hook)2057c478bd9Sstevel@tonic-gate res_send_setrhook(res_send_rhook hook) {
2067c478bd9Sstevel@tonic-gate _res.rhook = hook;
2077c478bd9Sstevel@tonic-gate }
2087c478bd9Sstevel@tonic-gate
2097c478bd9Sstevel@tonic-gate int
res_isourserver(const struct sockaddr_in * inp)2107c478bd9Sstevel@tonic-gate res_isourserver(const struct sockaddr_in *inp) {
2117c478bd9Sstevel@tonic-gate return (res_ourserver_p(&_res, inp));
2127c478bd9Sstevel@tonic-gate }
2137c478bd9Sstevel@tonic-gate
2147c478bd9Sstevel@tonic-gate int
res_send(const u_char * buf,int buflen,u_char * ans,int anssiz)2157c478bd9Sstevel@tonic-gate res_send(const u_char *buf, int buflen, u_char *ans, int anssiz) {
2169525b14bSRao Shoaib if ((_res.options & RES_INIT) == 0U && res_init() == -1) {
2177c478bd9Sstevel@tonic-gate /* errno should have been set by res_init() in this case. */
2187c478bd9Sstevel@tonic-gate return (-1);
2197c478bd9Sstevel@tonic-gate }
2207c478bd9Sstevel@tonic-gate
2217c478bd9Sstevel@tonic-gate return (res_nsend(&_res, buf, buflen, ans, anssiz));
2227c478bd9Sstevel@tonic-gate }
2237c478bd9Sstevel@tonic-gate
2247c478bd9Sstevel@tonic-gate int
res_sendsigned(const u_char * buf,int buflen,ns_tsig_key * key,u_char * ans,int anssiz)2257c478bd9Sstevel@tonic-gate res_sendsigned(const u_char *buf, int buflen, ns_tsig_key *key,
2267c478bd9Sstevel@tonic-gate u_char *ans, int anssiz)
2277c478bd9Sstevel@tonic-gate {
2289525b14bSRao Shoaib if ((_res.options & RES_INIT) == 0U && res_init() == -1) {
2297c478bd9Sstevel@tonic-gate /* errno should have been set by res_init() in this case. */
2307c478bd9Sstevel@tonic-gate return (-1);
2317c478bd9Sstevel@tonic-gate }
2327c478bd9Sstevel@tonic-gate
2337c478bd9Sstevel@tonic-gate return (res_nsendsigned(&_res, buf, buflen, key, ans, anssiz));
2347c478bd9Sstevel@tonic-gate }
2357c478bd9Sstevel@tonic-gate
2367c478bd9Sstevel@tonic-gate void
res_close(void)2377c478bd9Sstevel@tonic-gate res_close(void) {
2387c478bd9Sstevel@tonic-gate res_nclose(&_res);
2397c478bd9Sstevel@tonic-gate }
2407c478bd9Sstevel@tonic-gate
2417c478bd9Sstevel@tonic-gate int
res_update(ns_updrec * rrecp_in)2427c478bd9Sstevel@tonic-gate res_update(ns_updrec *rrecp_in) {
2439525b14bSRao Shoaib if ((_res.options & RES_INIT) == 0U && res_init() == -1) {
2447c478bd9Sstevel@tonic-gate RES_SET_H_ERRNO(&_res, NETDB_INTERNAL);
2457c478bd9Sstevel@tonic-gate return (-1);
2467c478bd9Sstevel@tonic-gate }
2477c478bd9Sstevel@tonic-gate
2487c478bd9Sstevel@tonic-gate return (res_nupdate(&_res, rrecp_in, NULL));
2497c478bd9Sstevel@tonic-gate }
2507c478bd9Sstevel@tonic-gate
2517c478bd9Sstevel@tonic-gate int
res_search(const char * name,int class,int type,u_char * answer,int anslen)2529525b14bSRao Shoaib res_search(const char *name, /*!< domain name */
2539525b14bSRao Shoaib int class, int type, /*!< class and type of query */
2549525b14bSRao Shoaib u_char *answer, /*!< buffer to put answer */
2559525b14bSRao Shoaib int anslen) /*!< size of answer */
2567c478bd9Sstevel@tonic-gate {
2579525b14bSRao Shoaib if ((_res.options & RES_INIT) == 0U && res_init() == -1) {
2587c478bd9Sstevel@tonic-gate RES_SET_H_ERRNO(&_res, NETDB_INTERNAL);
2597c478bd9Sstevel@tonic-gate return (-1);
2607c478bd9Sstevel@tonic-gate }
2617c478bd9Sstevel@tonic-gate
2627c478bd9Sstevel@tonic-gate return (res_nsearch(&_res, name, class, type, answer, anslen));
2637c478bd9Sstevel@tonic-gate }
2647c478bd9Sstevel@tonic-gate
2657c478bd9Sstevel@tonic-gate int
res_querydomain(const char * name,const char * domain,int class,int type,u_char * answer,int anslen)2667c478bd9Sstevel@tonic-gate res_querydomain(const char *name,
2677c478bd9Sstevel@tonic-gate const char *domain,
2689525b14bSRao Shoaib int class, int type, /*!< class and type of query */
2699525b14bSRao Shoaib u_char *answer, /*!< buffer to put answer */
2709525b14bSRao Shoaib int anslen) /*!< size of answer */
2717c478bd9Sstevel@tonic-gate {
2729525b14bSRao Shoaib if ((_res.options & RES_INIT) == 0U && res_init() == -1) {
2737c478bd9Sstevel@tonic-gate RES_SET_H_ERRNO(&_res, NETDB_INTERNAL);
2747c478bd9Sstevel@tonic-gate return (-1);
2757c478bd9Sstevel@tonic-gate }
2767c478bd9Sstevel@tonic-gate
2777c478bd9Sstevel@tonic-gate return (res_nquerydomain(&_res, name, domain,
2787c478bd9Sstevel@tonic-gate class, type,
2797c478bd9Sstevel@tonic-gate answer, anslen));
2807c478bd9Sstevel@tonic-gate }
2817c478bd9Sstevel@tonic-gate
2829525b14bSRao Shoaib u_int
res_randomid(void)2839525b14bSRao Shoaib res_randomid(void) {
2849525b14bSRao Shoaib if ((_res.options & RES_INIT) == 0U && res_init() == -1) {
2859525b14bSRao Shoaib RES_SET_H_ERRNO(&_res, NETDB_INTERNAL);
2869525b14bSRao Shoaib return (-1);
2879525b14bSRao Shoaib }
2889525b14bSRao Shoaib
2899525b14bSRao Shoaib return (res_nrandomid(&_res));
2909525b14bSRao Shoaib }
2919525b14bSRao Shoaib
2927c478bd9Sstevel@tonic-gate const char *
hostalias(const char * name)2937c478bd9Sstevel@tonic-gate hostalias(const char *name) {
2947c478bd9Sstevel@tonic-gate static char abuf[MAXDNAME];
2957c478bd9Sstevel@tonic-gate
2967c478bd9Sstevel@tonic-gate return (res_hostalias(&_res, name, abuf, sizeof abuf));
2977c478bd9Sstevel@tonic-gate }
2987c478bd9Sstevel@tonic-gate
2997c478bd9Sstevel@tonic-gate #ifdef ultrix
3007c478bd9Sstevel@tonic-gate int
local_hostname_length(const char * hostname)3017c478bd9Sstevel@tonic-gate local_hostname_length(const char *hostname) {
3027c478bd9Sstevel@tonic-gate int len_host, len_domain;
3037c478bd9Sstevel@tonic-gate
3047c478bd9Sstevel@tonic-gate if (!*_res.defdname)
3057c478bd9Sstevel@tonic-gate res_init();
3067c478bd9Sstevel@tonic-gate len_host = strlen(hostname);
3077c478bd9Sstevel@tonic-gate len_domain = strlen(_res.defdname);
3087c478bd9Sstevel@tonic-gate if (len_host > len_domain &&
3097c478bd9Sstevel@tonic-gate !strcasecmp(hostname + len_host - len_domain, _res.defdname) &&
3107c478bd9Sstevel@tonic-gate hostname[len_host - len_domain - 1] == '.')
3117c478bd9Sstevel@tonic-gate return (len_host - len_domain - 1);
3127c478bd9Sstevel@tonic-gate return (0);
3137c478bd9Sstevel@tonic-gate }
3147c478bd9Sstevel@tonic-gate #endif /*ultrix*/
3157c478bd9Sstevel@tonic-gate
3167c478bd9Sstevel@tonic-gate #endif
3179525b14bSRao Shoaib
3189525b14bSRao Shoaib /*! \file */
319