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 #if defined(LIBC_SCCS) && !defined(lint) 249525b14bSRao Shoaib static const char rcsid[] = "$Id: res_data.c,v 1.7 2008/12/11 09:59:00 marka Exp $"; 257c478bd9Sstevel@tonic-gate #endif /* LIBC_SCCS and not lint */ 267c478bd9Sstevel@tonic-gate 277c478bd9Sstevel@tonic-gate #include "port_before.h" 287c478bd9Sstevel@tonic-gate 297c478bd9Sstevel@tonic-gate #include <sys/types.h> 307c478bd9Sstevel@tonic-gate #include <sys/param.h> 317c478bd9Sstevel@tonic-gate #include <sys/socket.h> 327c478bd9Sstevel@tonic-gate #include <sys/time.h> 337c478bd9Sstevel@tonic-gate 347c478bd9Sstevel@tonic-gate #include <netinet/in.h> 357c478bd9Sstevel@tonic-gate #include <arpa/inet.h> 367c478bd9Sstevel@tonic-gate #include <arpa/nameser.h> 377c478bd9Sstevel@tonic-gate 387c478bd9Sstevel@tonic-gate #include <ctype.h> 397c478bd9Sstevel@tonic-gate #include <netdb.h> 407c478bd9Sstevel@tonic-gate #include <resolv.h> 417c478bd9Sstevel@tonic-gate #include <res_update.h> 427c478bd9Sstevel@tonic-gate #include <stdio.h> 437c478bd9Sstevel@tonic-gate #include <stdlib.h> 447c478bd9Sstevel@tonic-gate #include <string.h> 457c478bd9Sstevel@tonic-gate #include <unistd.h> 467c478bd9Sstevel@tonic-gate 477c478bd9Sstevel@tonic-gate #include "port_after.h" 487c478bd9Sstevel@tonic-gate 499525b14bSRao Shoaib #ifndef ORIGINAL_ISC_CODE 507c478bd9Sstevel@tonic-gate #pragma weak __fp_nquery = fp_nquery 517c478bd9Sstevel@tonic-gate #pragma weak __fp_query = fp_query 527c478bd9Sstevel@tonic-gate #pragma weak __p_query = p_query 537c478bd9Sstevel@tonic-gate #pragma weak __hostalias = hostalias 549525b14bSRao Shoaib #pragma weak __res_randomid = res_randomid 557c478bd9Sstevel@tonic-gate #endif 567c478bd9Sstevel@tonic-gate 577c478bd9Sstevel@tonic-gate const char *_res_opcodes[] = { 587c478bd9Sstevel@tonic-gate "QUERY", 597c478bd9Sstevel@tonic-gate "IQUERY", 607c478bd9Sstevel@tonic-gate "CQUERYM", 619525b14bSRao Shoaib "CQUERYU", /*%< experimental */ 629525b14bSRao Shoaib "NOTIFY", /*%< experimental */ 637c478bd9Sstevel@tonic-gate "UPDATE", 647c478bd9Sstevel@tonic-gate "6", 657c478bd9Sstevel@tonic-gate "7", 667c478bd9Sstevel@tonic-gate "8", 677c478bd9Sstevel@tonic-gate "9", 687c478bd9Sstevel@tonic-gate "10", 697c478bd9Sstevel@tonic-gate "11", 707c478bd9Sstevel@tonic-gate "12", 717c478bd9Sstevel@tonic-gate "13", 727c478bd9Sstevel@tonic-gate "ZONEINIT", 737c478bd9Sstevel@tonic-gate "ZONEREF", 747c478bd9Sstevel@tonic-gate }; 757c478bd9Sstevel@tonic-gate 767c478bd9Sstevel@tonic-gate #ifdef BIND_UPDATE 777c478bd9Sstevel@tonic-gate const char *_res_sectioncodes[] = { 787c478bd9Sstevel@tonic-gate "ZONE", 797c478bd9Sstevel@tonic-gate "PREREQUISITES", 807c478bd9Sstevel@tonic-gate "UPDATE", 817c478bd9Sstevel@tonic-gate "ADDITIONAL", 827c478bd9Sstevel@tonic-gate }; 837c478bd9Sstevel@tonic-gate #endif 847c478bd9Sstevel@tonic-gate 859525b14bSRao Shoaib #undef _res 867c478bd9Sstevel@tonic-gate #ifndef __BIND_NOSTATIC 877c478bd9Sstevel@tonic-gate struct __res_state _res 887c478bd9Sstevel@tonic-gate # if defined(__BIND_RES_TEXT) 899525b14bSRao Shoaib = { RES_TIMEOUT, } /*%< Motorola, et al. */ 907c478bd9Sstevel@tonic-gate # endif 917c478bd9Sstevel@tonic-gate ; 927c478bd9Sstevel@tonic-gate 93*4e567b44SStacey Marshall #ifdef ORIGINAL_ISC_CODE 949525b14bSRao Shoaib #if defined(DO_PTHREADS) || defined(__linux) 959525b14bSRao Shoaib #define _res (*__res_state()) 969525b14bSRao Shoaib #endif 97*4e567b44SStacey Marshall #endif 989525b14bSRao Shoaib 997c478bd9Sstevel@tonic-gate /* Proto. */ 1007c478bd9Sstevel@tonic-gate 1017c478bd9Sstevel@tonic-gate int res_ourserver_p(const res_state, const struct sockaddr_in *); 1027c478bd9Sstevel@tonic-gate 1037c478bd9Sstevel@tonic-gate int 1047c478bd9Sstevel@tonic-gate res_init(void) { 1057c478bd9Sstevel@tonic-gate extern int __res_vinit(res_state, int); 1067c478bd9Sstevel@tonic-gate 1077c478bd9Sstevel@tonic-gate /* 1087c478bd9Sstevel@tonic-gate * These three fields used to be statically initialized. This made 1097c478bd9Sstevel@tonic-gate * it hard to use this code in a shared library. It is necessary, 1107c478bd9Sstevel@tonic-gate * now that we're doing dynamic initialization here, that we preserve 1117c478bd9Sstevel@tonic-gate * the old semantics: if an application modifies one of these three 1127c478bd9Sstevel@tonic-gate * fields of _res before res_init() is called, res_init() will not 1137c478bd9Sstevel@tonic-gate * alter them. Of course, if an application is setting them to 1147c478bd9Sstevel@tonic-gate * _zero_ before calling res_init(), hoping to override what used 1157c478bd9Sstevel@tonic-gate * to be the static default, we can't detect it and unexpected results 1167c478bd9Sstevel@tonic-gate * will follow. Zero for any of these fields would make no sense, 1177c478bd9Sstevel@tonic-gate * so one can safely assume that the applications were already getting 1187c478bd9Sstevel@tonic-gate * unexpected results. 1197c478bd9Sstevel@tonic-gate * 1207c478bd9Sstevel@tonic-gate * _res.options is tricky since some apps were known to diddle the bits 1217c478bd9Sstevel@tonic-gate * before res_init() was first called. We can't replicate that semantic 1227c478bd9Sstevel@tonic-gate * with dynamic initialization (they may have turned bits off that are 1237c478bd9Sstevel@tonic-gate * set in RES_DEFAULT). Our solution is to declare such applications 1247c478bd9Sstevel@tonic-gate * "broken". They could fool us by setting RES_INIT but none do (yet). 1257c478bd9Sstevel@tonic-gate */ 1267c478bd9Sstevel@tonic-gate if (!_res.retrans) 1277c478bd9Sstevel@tonic-gate _res.retrans = RES_TIMEOUT; 1287c478bd9Sstevel@tonic-gate if (!_res.retry) 1297c478bd9Sstevel@tonic-gate _res.retry = 4; 1307c478bd9Sstevel@tonic-gate if (!(_res.options & RES_INIT)) 1317c478bd9Sstevel@tonic-gate _res.options = RES_DEFAULT; 1327c478bd9Sstevel@tonic-gate 1337c478bd9Sstevel@tonic-gate /* 1347c478bd9Sstevel@tonic-gate * This one used to initialize implicitly to zero, so unless the app 1357c478bd9Sstevel@tonic-gate * has set it to something in particular, we can randomize it now. 1367c478bd9Sstevel@tonic-gate */ 1377c478bd9Sstevel@tonic-gate if (!_res.id) 1389525b14bSRao Shoaib _res.id = res_nrandomid(&_res); 1397c478bd9Sstevel@tonic-gate 1407c478bd9Sstevel@tonic-gate return (__res_vinit(&_res, 1)); 1417c478bd9Sstevel@tonic-gate } 1427c478bd9Sstevel@tonic-gate 1437c478bd9Sstevel@tonic-gate void 1447c478bd9Sstevel@tonic-gate p_query(const u_char *msg) { 1457c478bd9Sstevel@tonic-gate fp_query(msg, stdout); 1467c478bd9Sstevel@tonic-gate } 1477c478bd9Sstevel@tonic-gate 1487c478bd9Sstevel@tonic-gate void 1497c478bd9Sstevel@tonic-gate fp_query(const u_char *msg, FILE *file) { 1507c478bd9Sstevel@tonic-gate fp_nquery(msg, PACKETSZ, file); 1517c478bd9Sstevel@tonic-gate } 1527c478bd9Sstevel@tonic-gate 1537c478bd9Sstevel@tonic-gate void 1547c478bd9Sstevel@tonic-gate fp_nquery(const u_char *msg, int len, FILE *file) { 1559525b14bSRao Shoaib if ((_res.options & RES_INIT) == 0U && res_init() == -1) 1567c478bd9Sstevel@tonic-gate return; 1577c478bd9Sstevel@tonic-gate 1587c478bd9Sstevel@tonic-gate res_pquery(&_res, msg, len, file); 1597c478bd9Sstevel@tonic-gate } 1607c478bd9Sstevel@tonic-gate 1617c478bd9Sstevel@tonic-gate int 1629525b14bSRao Shoaib res_mkquery(int op, /*!< opcode of query */ 1639525b14bSRao Shoaib const char *dname, /*!< domain name */ 1649525b14bSRao Shoaib int class, int type, /*!< class and type of query */ 1659525b14bSRao Shoaib const u_char *data, /*!< resource record data */ 1669525b14bSRao Shoaib int datalen, /*!< length of data */ 1679525b14bSRao Shoaib const u_char *newrr_in, /*!< new rr for modify or append */ 1689525b14bSRao Shoaib u_char *buf, /*!< buffer to put query */ 1699525b14bSRao Shoaib int buflen) /*!< size of buffer */ 1707c478bd9Sstevel@tonic-gate { 1719525b14bSRao Shoaib if ((_res.options & RES_INIT) == 0U && res_init() == -1) { 1727c478bd9Sstevel@tonic-gate RES_SET_H_ERRNO(&_res, NETDB_INTERNAL); 1737c478bd9Sstevel@tonic-gate return (-1); 1747c478bd9Sstevel@tonic-gate } 1757c478bd9Sstevel@tonic-gate return (res_nmkquery(&_res, op, dname, class, type, 1767c478bd9Sstevel@tonic-gate data, datalen, 1777c478bd9Sstevel@tonic-gate newrr_in, buf, buflen)); 1787c478bd9Sstevel@tonic-gate } 1797c478bd9Sstevel@tonic-gate 1807c478bd9Sstevel@tonic-gate int 1817c478bd9Sstevel@tonic-gate res_mkupdate(ns_updrec *rrecp_in, u_char *buf, int buflen) { 1829525b14bSRao Shoaib if ((_res.options & RES_INIT) == 0U && res_init() == -1) { 1837c478bd9Sstevel@tonic-gate RES_SET_H_ERRNO(&_res, NETDB_INTERNAL); 1847c478bd9Sstevel@tonic-gate return (-1); 1857c478bd9Sstevel@tonic-gate } 1867c478bd9Sstevel@tonic-gate 1877c478bd9Sstevel@tonic-gate return (res_nmkupdate(&_res, rrecp_in, buf, buflen)); 1887c478bd9Sstevel@tonic-gate } 1897c478bd9Sstevel@tonic-gate 1907c478bd9Sstevel@tonic-gate int 1919525b14bSRao Shoaib res_query(const char *name, /*!< domain name */ 1929525b14bSRao Shoaib int class, int type, /*!< class and type of query */ 1939525b14bSRao Shoaib u_char *answer, /*!< buffer to put answer */ 1949525b14bSRao Shoaib int anslen) /*!< size of answer buffer */ 1957c478bd9Sstevel@tonic-gate { 1969525b14bSRao Shoaib if ((_res.options & RES_INIT) == 0U && res_init() == -1) { 1977c478bd9Sstevel@tonic-gate RES_SET_H_ERRNO(&_res, NETDB_INTERNAL); 1987c478bd9Sstevel@tonic-gate return (-1); 1997c478bd9Sstevel@tonic-gate } 2007c478bd9Sstevel@tonic-gate return (res_nquery(&_res, name, class, type, answer, anslen)); 2017c478bd9Sstevel@tonic-gate } 2027c478bd9Sstevel@tonic-gate 2037c478bd9Sstevel@tonic-gate void 2047c478bd9Sstevel@tonic-gate res_send_setqhook(res_send_qhook hook) { 2057c478bd9Sstevel@tonic-gate _res.qhook = hook; 2067c478bd9Sstevel@tonic-gate } 2077c478bd9Sstevel@tonic-gate 2087c478bd9Sstevel@tonic-gate void 2097c478bd9Sstevel@tonic-gate res_send_setrhook(res_send_rhook hook) { 2107c478bd9Sstevel@tonic-gate _res.rhook = hook; 2117c478bd9Sstevel@tonic-gate } 2127c478bd9Sstevel@tonic-gate 2137c478bd9Sstevel@tonic-gate int 2147c478bd9Sstevel@tonic-gate res_isourserver(const struct sockaddr_in *inp) { 2157c478bd9Sstevel@tonic-gate return (res_ourserver_p(&_res, inp)); 2167c478bd9Sstevel@tonic-gate } 2177c478bd9Sstevel@tonic-gate 2187c478bd9Sstevel@tonic-gate int 2197c478bd9Sstevel@tonic-gate res_send(const u_char *buf, int buflen, u_char *ans, int anssiz) { 2209525b14bSRao Shoaib if ((_res.options & RES_INIT) == 0U && res_init() == -1) { 2217c478bd9Sstevel@tonic-gate /* errno should have been set by res_init() in this case. */ 2227c478bd9Sstevel@tonic-gate return (-1); 2237c478bd9Sstevel@tonic-gate } 2247c478bd9Sstevel@tonic-gate 2257c478bd9Sstevel@tonic-gate return (res_nsend(&_res, buf, buflen, ans, anssiz)); 2267c478bd9Sstevel@tonic-gate } 2277c478bd9Sstevel@tonic-gate 2287c478bd9Sstevel@tonic-gate int 2297c478bd9Sstevel@tonic-gate res_sendsigned(const u_char *buf, int buflen, ns_tsig_key *key, 2307c478bd9Sstevel@tonic-gate u_char *ans, int anssiz) 2317c478bd9Sstevel@tonic-gate { 2329525b14bSRao Shoaib if ((_res.options & RES_INIT) == 0U && res_init() == -1) { 2337c478bd9Sstevel@tonic-gate /* errno should have been set by res_init() in this case. */ 2347c478bd9Sstevel@tonic-gate return (-1); 2357c478bd9Sstevel@tonic-gate } 2367c478bd9Sstevel@tonic-gate 2377c478bd9Sstevel@tonic-gate return (res_nsendsigned(&_res, buf, buflen, key, ans, anssiz)); 2387c478bd9Sstevel@tonic-gate } 2397c478bd9Sstevel@tonic-gate 2407c478bd9Sstevel@tonic-gate void 2417c478bd9Sstevel@tonic-gate res_close(void) { 2427c478bd9Sstevel@tonic-gate res_nclose(&_res); 2437c478bd9Sstevel@tonic-gate } 2447c478bd9Sstevel@tonic-gate 2457c478bd9Sstevel@tonic-gate int 2467c478bd9Sstevel@tonic-gate res_update(ns_updrec *rrecp_in) { 2479525b14bSRao Shoaib if ((_res.options & RES_INIT) == 0U && res_init() == -1) { 2487c478bd9Sstevel@tonic-gate RES_SET_H_ERRNO(&_res, NETDB_INTERNAL); 2497c478bd9Sstevel@tonic-gate return (-1); 2507c478bd9Sstevel@tonic-gate } 2517c478bd9Sstevel@tonic-gate 2527c478bd9Sstevel@tonic-gate return (res_nupdate(&_res, rrecp_in, NULL)); 2537c478bd9Sstevel@tonic-gate } 2547c478bd9Sstevel@tonic-gate 2557c478bd9Sstevel@tonic-gate int 2569525b14bSRao Shoaib res_search(const char *name, /*!< domain name */ 2579525b14bSRao Shoaib int class, int type, /*!< class and type of query */ 2589525b14bSRao Shoaib u_char *answer, /*!< buffer to put answer */ 2599525b14bSRao Shoaib int anslen) /*!< size of answer */ 2607c478bd9Sstevel@tonic-gate { 2619525b14bSRao Shoaib if ((_res.options & RES_INIT) == 0U && res_init() == -1) { 2627c478bd9Sstevel@tonic-gate RES_SET_H_ERRNO(&_res, NETDB_INTERNAL); 2637c478bd9Sstevel@tonic-gate return (-1); 2647c478bd9Sstevel@tonic-gate } 2657c478bd9Sstevel@tonic-gate 2667c478bd9Sstevel@tonic-gate return (res_nsearch(&_res, name, class, type, answer, anslen)); 2677c478bd9Sstevel@tonic-gate } 2687c478bd9Sstevel@tonic-gate 2697c478bd9Sstevel@tonic-gate int 2707c478bd9Sstevel@tonic-gate res_querydomain(const char *name, 2717c478bd9Sstevel@tonic-gate const char *domain, 2729525b14bSRao Shoaib int class, int type, /*!< class and type of query */ 2739525b14bSRao Shoaib u_char *answer, /*!< buffer to put answer */ 2749525b14bSRao Shoaib int anslen) /*!< size of answer */ 2757c478bd9Sstevel@tonic-gate { 2769525b14bSRao Shoaib if ((_res.options & RES_INIT) == 0U && res_init() == -1) { 2777c478bd9Sstevel@tonic-gate RES_SET_H_ERRNO(&_res, NETDB_INTERNAL); 2787c478bd9Sstevel@tonic-gate return (-1); 2797c478bd9Sstevel@tonic-gate } 2807c478bd9Sstevel@tonic-gate 2817c478bd9Sstevel@tonic-gate return (res_nquerydomain(&_res, name, domain, 2827c478bd9Sstevel@tonic-gate class, type, 2837c478bd9Sstevel@tonic-gate answer, anslen)); 2847c478bd9Sstevel@tonic-gate } 2857c478bd9Sstevel@tonic-gate 2869525b14bSRao Shoaib u_int 2879525b14bSRao Shoaib res_randomid(void) { 2889525b14bSRao Shoaib if ((_res.options & RES_INIT) == 0U && res_init() == -1) { 2899525b14bSRao Shoaib RES_SET_H_ERRNO(&_res, NETDB_INTERNAL); 2909525b14bSRao Shoaib return (-1); 2919525b14bSRao Shoaib } 2929525b14bSRao Shoaib 2939525b14bSRao Shoaib return (res_nrandomid(&_res)); 2949525b14bSRao Shoaib } 2959525b14bSRao Shoaib 2967c478bd9Sstevel@tonic-gate const char * 2977c478bd9Sstevel@tonic-gate hostalias(const char *name) { 2987c478bd9Sstevel@tonic-gate static char abuf[MAXDNAME]; 2997c478bd9Sstevel@tonic-gate 3007c478bd9Sstevel@tonic-gate return (res_hostalias(&_res, name, abuf, sizeof abuf)); 3017c478bd9Sstevel@tonic-gate } 3027c478bd9Sstevel@tonic-gate 3037c478bd9Sstevel@tonic-gate #ifdef ultrix 3047c478bd9Sstevel@tonic-gate int 3057c478bd9Sstevel@tonic-gate local_hostname_length(const char *hostname) { 3067c478bd9Sstevel@tonic-gate int len_host, len_domain; 3077c478bd9Sstevel@tonic-gate 3087c478bd9Sstevel@tonic-gate if (!*_res.defdname) 3097c478bd9Sstevel@tonic-gate res_init(); 3107c478bd9Sstevel@tonic-gate len_host = strlen(hostname); 3117c478bd9Sstevel@tonic-gate len_domain = strlen(_res.defdname); 3127c478bd9Sstevel@tonic-gate if (len_host > len_domain && 3137c478bd9Sstevel@tonic-gate !strcasecmp(hostname + len_host - len_domain, _res.defdname) && 3147c478bd9Sstevel@tonic-gate hostname[len_host - len_domain - 1] == '.') 3157c478bd9Sstevel@tonic-gate return (len_host - len_domain - 1); 3167c478bd9Sstevel@tonic-gate return (0); 3177c478bd9Sstevel@tonic-gate } 3187c478bd9Sstevel@tonic-gate #endif /*ultrix*/ 3197c478bd9Sstevel@tonic-gate 3207c478bd9Sstevel@tonic-gate #endif 3219525b14bSRao Shoaib 3229525b14bSRao Shoaib /*! \file */ 323