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