1156952Sume/* 2156952Sume * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC") 3156952Sume * Copyright (c) 1995-1999 by Internet Software Consortium. 4156952Sume * 5156952Sume * Permission to use, copy, modify, and distribute this software for any 6156952Sume * purpose with or without fee is hereby granted, provided that the above 7156952Sume * copyright notice and this permission notice appear in all copies. 8156952Sume * 9156952Sume * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES 10156952Sume * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 11156952Sume * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR 12156952Sume * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 13156952Sume * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 14156952Sume * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT 15156952Sume * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 16156952Sume */ 17156952Sume 18156952Sume#if defined(LIBC_SCCS) && !defined(lint) 19269867Sumestatic const char rcsid[] = "$Id: res_data.c,v 1.7 2008/12/11 09:59:00 marka Exp $"; 20156952Sume#endif /* LIBC_SCCS and not lint */ 21156956Sume#include <sys/cdefs.h> 22156956Sume__FBSDID("$FreeBSD$"); 23156952Sume 24156952Sume#include "port_before.h" 25156952Sume 26156952Sume#include <sys/param.h> 27156952Sume#include <sys/socket.h> 28156952Sume#include <sys/time.h> 29156952Sume 30156952Sume#include <netinet/in.h> 31156952Sume#include <arpa/inet.h> 32156952Sume#include <arpa/nameser.h> 33156952Sume 34156952Sume#include <ctype.h> 35156952Sume#include <netdb.h> 36156952Sume#include <resolv.h> 37156952Sume#include <res_update.h> 38156952Sume#include <stdio.h> 39156952Sume#include <stdlib.h> 40156952Sume#include <string.h> 41156952Sume#include <unistd.h> 42156952Sume 43156952Sume#include "port_after.h" 44156952Sume 45156952Sumeconst char *_res_opcodes[] = { 46156952Sume "QUERY", 47156952Sume "IQUERY", 48156952Sume "CQUERYM", 49170244Sume "CQUERYU", /*%< experimental */ 50170244Sume "NOTIFY", /*%< experimental */ 51156952Sume "UPDATE", 52156952Sume "6", 53156952Sume "7", 54156952Sume "8", 55156952Sume "9", 56156952Sume "10", 57156952Sume "11", 58156952Sume "12", 59156952Sume "13", 60156952Sume "ZONEINIT", 61156952Sume "ZONEREF", 62156952Sume}; 63156952Sume 64156952Sume#ifdef BIND_UPDATE 65156952Sumeconst char *_res_sectioncodes[] = { 66156952Sume "ZONE", 67156952Sume "PREREQUISITES", 68156952Sume "UPDATE", 69156952Sume "ADDITIONAL", 70156952Sume}; 71156952Sume#endif 72156952Sume 73156952Sume#ifndef __BIND_NOSTATIC 74156952Sume 75156952Sume/* Proto. */ 76156952Sume 77156952Sumeint res_ourserver_p(const res_state, const struct sockaddr_in *); 78156952Sume 79289837Svangyzen__noinline int 80156952Sumeres_init(void) { 81156952Sume extern int __res_vinit(res_state, int); 82289837Svangyzen res_state statp = &_res; 83156952Sume 84156952Sume /* 85156952Sume * These three fields used to be statically initialized. This made 86156952Sume * it hard to use this code in a shared library. It is necessary, 87156952Sume * now that we're doing dynamic initialization here, that we preserve 88156952Sume * the old semantics: if an application modifies one of these three 89156952Sume * fields of _res before res_init() is called, res_init() will not 90156952Sume * alter them. Of course, if an application is setting them to 91156952Sume * _zero_ before calling res_init(), hoping to override what used 92156952Sume * to be the static default, we can't detect it and unexpected results 93156952Sume * will follow. Zero for any of these fields would make no sense, 94156952Sume * so one can safely assume that the applications were already getting 95156952Sume * unexpected results. 96156952Sume * 97156952Sume * _res.options is tricky since some apps were known to diddle the bits 98156952Sume * before res_init() was first called. We can't replicate that semantic 99156952Sume * with dynamic initialization (they may have turned bits off that are 100156952Sume * set in RES_DEFAULT). Our solution is to declare such applications 101156952Sume * "broken". They could fool us by setting RES_INIT but none do (yet). 102156952Sume */ 103289837Svangyzen if (!statp->retrans) 104289837Svangyzen statp->retrans = RES_TIMEOUT; 105289837Svangyzen if (!statp->retry) 106289837Svangyzen statp->retry = RES_DFLRETRY; 107289837Svangyzen if (!(statp->options & RES_INIT)) 108289837Svangyzen statp->options = RES_DEFAULT; 109156952Sume 110289837Svangyzen return (__res_vinit(statp, 1)); 111156952Sume} 112156952Sume 113156952Sumevoid 114156952Sumep_query(const u_char *msg) { 115156952Sume fp_query(msg, stdout); 116156952Sume} 117156952Sume 118156952Sumevoid 119156952Sumefp_query(const u_char *msg, FILE *file) { 120156952Sume fp_nquery(msg, PACKETSZ, file); 121156952Sume} 122156952Sume 123156952Sumevoid 124156952Sumefp_nquery(const u_char *msg, int len, FILE *file) { 125289837Svangyzen res_state statp = &_res; 126289837Svangyzen if ((statp->options & RES_INIT) == 0U && res_init() == -1) 127156952Sume return; 128156952Sume 129289837Svangyzen res_pquery(statp, msg, len, file); 130156952Sume} 131156952Sume 132156952Sumeint 133170244Sumeres_mkquery(int op, /*!< opcode of query */ 134170244Sume const char *dname, /*!< domain name */ 135170244Sume int class, int type, /*!< class and type of query */ 136170244Sume const u_char *data, /*!< resource record data */ 137170244Sume int datalen, /*!< length of data */ 138170244Sume const u_char *newrr_in, /*!< new rr for modify or append */ 139170244Sume u_char *buf, /*!< buffer to put query */ 140170244Sume int buflen) /*!< size of buffer */ 141156952Sume{ 142289837Svangyzen res_state statp = &_res; 143289837Svangyzen if ((statp->options & RES_INIT) == 0U && res_init() == -1) { 144289837Svangyzen RES_SET_H_ERRNO(statp, NETDB_INTERNAL); 145156952Sume return (-1); 146156952Sume } 147289837Svangyzen return (res_nmkquery(statp, op, dname, class, type, 148156952Sume data, datalen, 149156952Sume newrr_in, buf, buflen)); 150156952Sume} 151156952Sume 152156952Sumeint 153156952Sumeres_mkupdate(ns_updrec *rrecp_in, u_char *buf, int buflen) { 154289837Svangyzen res_state statp = &_res; 155289837Svangyzen if ((statp->options & RES_INIT) == 0U && res_init() == -1) { 156289837Svangyzen RES_SET_H_ERRNO(statp, NETDB_INTERNAL); 157156952Sume return (-1); 158156952Sume } 159156952Sume 160289837Svangyzen return (res_nmkupdate(statp, rrecp_in, buf, buflen)); 161156952Sume} 162156952Sume 163156952Sumeint 164170244Sumeres_query(const char *name, /*!< domain name */ 165170244Sume int class, int type, /*!< class and type of query */ 166170244Sume u_char *answer, /*!< buffer to put answer */ 167170244Sume int anslen) /*!< size of answer buffer */ 168156952Sume{ 169289837Svangyzen res_state statp = &_res; 170289837Svangyzen if ((statp->options & RES_INIT) == 0U && res_init() == -1) { 171289837Svangyzen RES_SET_H_ERRNO(statp, NETDB_INTERNAL); 172156952Sume return (-1); 173156952Sume } 174289837Svangyzen return (res_nquery(statp, name, class, type, answer, anslen)); 175156952Sume} 176156952Sume 177156956Sume#ifndef _LIBC 178156952Sumevoid 179156952Sumeres_send_setqhook(res_send_qhook hook) { 180156952Sume _res.qhook = hook; 181156952Sume} 182156952Sume 183156952Sumevoid 184156952Sumeres_send_setrhook(res_send_rhook hook) { 185156952Sume _res.rhook = hook; 186156952Sume} 187156956Sume#endif 188156952Sume 189156952Sumeint 190156952Sumeres_isourserver(const struct sockaddr_in *inp) { 191156952Sume return (res_ourserver_p(&_res, inp)); 192156952Sume} 193156952Sume 194156952Sumeint 195156952Sumeres_send(const u_char *buf, int buflen, u_char *ans, int anssiz) { 196289837Svangyzen res_state statp = &_res; 197289837Svangyzen if ((statp->options & RES_INIT) == 0U && res_init() == -1) { 198156952Sume /* errno should have been set by res_init() in this case. */ 199156952Sume return (-1); 200156952Sume } 201156952Sume 202289837Svangyzen return (res_nsend(statp, buf, buflen, ans, anssiz)); 203156952Sume} 204156952Sume 205156956Sume#ifndef _LIBC 206156952Sumeint 207156952Sumeres_sendsigned(const u_char *buf, int buflen, ns_tsig_key *key, 208156952Sume u_char *ans, int anssiz) 209156952Sume{ 210289837Svangyzen res_state statp = &_res; 211289837Svangyzen if ((statp->options & RES_INIT) == 0U && res_init() == -1) { 212156952Sume /* errno should have been set by res_init() in this case. */ 213156952Sume return (-1); 214156952Sume } 215156952Sume 216289837Svangyzen return (res_nsendsigned(statp, buf, buflen, key, ans, anssiz)); 217156952Sume} 218156956Sume#endif 219156952Sume 220156952Sumevoid 221156952Sumeres_close(void) { 222156952Sume res_nclose(&_res); 223156952Sume} 224156952Sume 225156952Sumeint 226156952Sumeres_update(ns_updrec *rrecp_in) { 227289837Svangyzen res_state statp = &_res; 228289837Svangyzen if ((statp->options & RES_INIT) == 0U && res_init() == -1) { 229289837Svangyzen RES_SET_H_ERRNO(statp, NETDB_INTERNAL); 230156952Sume return (-1); 231156952Sume } 232156952Sume 233289837Svangyzen return (res_nupdate(statp, rrecp_in, NULL)); 234156952Sume} 235156952Sume 236156952Sumeint 237170244Sumeres_search(const char *name, /*!< domain name */ 238170244Sume int class, int type, /*!< class and type of query */ 239170244Sume u_char *answer, /*!< buffer to put answer */ 240170244Sume int anslen) /*!< size of answer */ 241156952Sume{ 242289837Svangyzen res_state statp = &_res; 243289837Svangyzen if ((statp->options & RES_INIT) == 0U && res_init() == -1) { 244289837Svangyzen RES_SET_H_ERRNO(statp, NETDB_INTERNAL); 245156952Sume return (-1); 246156952Sume } 247156952Sume 248289837Svangyzen return (res_nsearch(statp, name, class, type, answer, anslen)); 249156952Sume} 250156952Sume 251156952Sumeint 252156952Sumeres_querydomain(const char *name, 253156952Sume const char *domain, 254170244Sume int class, int type, /*!< class and type of query */ 255170244Sume u_char *answer, /*!< buffer to put answer */ 256170244Sume int anslen) /*!< size of answer */ 257156952Sume{ 258289837Svangyzen res_state statp = &_res; 259289837Svangyzen if ((statp->options & RES_INIT) == 0U && res_init() == -1) { 260289837Svangyzen RES_SET_H_ERRNO(statp, NETDB_INTERNAL); 261156952Sume return (-1); 262156952Sume } 263156952Sume 264289837Svangyzen return (res_nquerydomain(statp, name, domain, 265156952Sume class, type, 266156952Sume answer, anslen)); 267156952Sume} 268156952Sume 269269867Sumeu_int 270269867Sumeres_randomid(void) { 271289837Svangyzen res_state statp = &_res; 272289837Svangyzen if ((statp->options & RES_INIT) == 0U && res_init() == -1) { 273289837Svangyzen RES_SET_H_ERRNO(statp, NETDB_INTERNAL); 274269867Sume return (-1); 275269867Sume } 276269867Sume 277289837Svangyzen return (res_nrandomid(statp)); 278269867Sume} 279269867Sume 280156956Sumeint 281156956Sumeres_opt(int n0, u_char *buf, int buflen, int anslen) 282156956Sume{ 283156956Sume return (res_nopt(&_res, n0, buf, buflen, anslen)); 284156956Sume} 285156956Sume 286156952Sumeconst char * 287156952Sumehostalias(const char *name) { 288156952Sume static char abuf[MAXDNAME]; 289156952Sume 290156952Sume return (res_hostalias(&_res, name, abuf, sizeof abuf)); 291156952Sume} 292156952Sume 293156952Sume#ifdef ultrix 294156952Sumeint 295156952Sumelocal_hostname_length(const char *hostname) { 296156952Sume int len_host, len_domain; 297289837Svangyzen res_state statp; 298156952Sume 299289837Svangyzen statp = &_res; 300289837Svangyzen if (!*statp->defdname) 301156952Sume res_init(); 302156952Sume len_host = strlen(hostname); 303289837Svangyzen len_domain = strlen(statp->defdname); 304156952Sume if (len_host > len_domain && 305289837Svangyzen !strcasecmp(hostname + len_host - len_domain, statp->defdname) && 306156952Sume hostname[len_host - len_domain - 1] == '.') 307156952Sume return (len_host - len_domain - 1); 308156952Sume return (0); 309156952Sume} 310156952Sume#endif /*ultrix*/ 311156952Sume 312156956Sume/* 313156956Sume * Weak aliases for applications that use certain private entry points, 314156956Sume * and fail to include <resolv.h>. 315156956Sume */ 316156956Sume#undef res_init 317156956Sume__weak_reference(__res_init, res_init); 318156956Sume#undef p_query 319156956Sume__weak_reference(__p_query, p_query); 320156956Sume#undef res_mkquery 321156956Sume__weak_reference(__res_mkquery, res_mkquery); 322156956Sume#undef res_query 323156956Sume__weak_reference(__res_query, res_query); 324156956Sume#undef res_send 325156956Sume__weak_reference(__res_send, res_send); 326156956Sume#undef res_close 327156956Sume__weak_reference(__res_close, _res_close); 328156956Sume#undef res_search 329156956Sume__weak_reference(__res_search, res_search); 330156956Sume#undef res_querydomain 331156956Sume__weak_reference(__res_querydomain, res_querydomain); 332156956Sume 333156952Sume#endif 334170244Sume 335170244Sume/*! \file */ 336