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)
19174226Sumestatic const char rcsid[] = "$Id: res_data.c,v 1.3.18.2 2007/09/14 05:35:47 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/types.h>
27156952Sume#include <sys/param.h>
28156952Sume#include <sys/socket.h>
29156952Sume#include <sys/time.h>
30156952Sume
31156952Sume#include <netinet/in.h>
32156952Sume#include <arpa/inet.h>
33156952Sume#include <arpa/nameser.h>
34156952Sume
35156952Sume#include <ctype.h>
36156952Sume#include <netdb.h>
37156952Sume#include <resolv.h>
38156952Sume#include <res_update.h>
39156952Sume#include <stdio.h>
40156952Sume#include <stdlib.h>
41156952Sume#include <string.h>
42156952Sume#include <unistd.h>
43156952Sume
44156952Sume#include "port_after.h"
45156952Sume
46156952Sumeconst char *_res_opcodes[] = {
47156952Sume	"QUERY",
48156952Sume	"IQUERY",
49156952Sume	"CQUERYM",
50170244Sume	"CQUERYU",	/*%< experimental */
51170244Sume	"NOTIFY",	/*%< experimental */
52156952Sume	"UPDATE",
53156952Sume	"6",
54156952Sume	"7",
55156952Sume	"8",
56156952Sume	"9",
57156952Sume	"10",
58156952Sume	"11",
59156952Sume	"12",
60156952Sume	"13",
61156952Sume	"ZONEINIT",
62156952Sume	"ZONEREF",
63156952Sume};
64156952Sume
65156952Sume#ifdef BIND_UPDATE
66156952Sumeconst char *_res_sectioncodes[] = {
67156952Sume	"ZONE",
68156952Sume	"PREREQUISITES",
69156952Sume	"UPDATE",
70156952Sume	"ADDITIONAL",
71156952Sume};
72156952Sume#endif
73156952Sume
74156952Sume#ifndef __BIND_NOSTATIC
75156952Sume
76156952Sume/* Proto. */
77156952Sume
78156952Sumeint  res_ourserver_p(const res_state, const struct sockaddr_in *);
79156952Sume
80156952Sumeint
81156952Sumeres_init(void) {
82156952Sume	extern int __res_vinit(res_state, int);
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	 */
103156952Sume	if (!_res.retrans)
104156952Sume		_res.retrans = RES_TIMEOUT;
105156952Sume	if (!_res.retry)
106156956Sume		_res.retry = RES_DFLRETRY;
107156952Sume	if (!(_res.options & RES_INIT))
108156952Sume		_res.options = RES_DEFAULT;
109156952Sume
110156952Sume	/*
111156952Sume	 * This one used to initialize implicitly to zero, so unless the app
112156952Sume	 * has set it to something in particular, we can randomize it now.
113156952Sume	 */
114156952Sume	if (!_res.id)
115156952Sume		_res.id = res_randomid();
116156952Sume
117156952Sume	return (__res_vinit(&_res, 1));
118156952Sume}
119156952Sume
120156952Sumevoid
121156952Sumep_query(const u_char *msg) {
122156952Sume	fp_query(msg, stdout);
123156952Sume}
124156952Sume
125156952Sumevoid
126156952Sumefp_query(const u_char *msg, FILE *file) {
127156952Sume	fp_nquery(msg, PACKETSZ, file);
128156952Sume}
129156952Sume
130156952Sumevoid
131156952Sumefp_nquery(const u_char *msg, int len, FILE *file) {
132156952Sume	if ((_res.options & RES_INIT) == 0U && res_init() == -1)
133156952Sume		return;
134156952Sume
135156952Sume	res_pquery(&_res, msg, len, file);
136156952Sume}
137156952Sume
138156952Sumeint
139170244Sumeres_mkquery(int op,			/*!< opcode of query  */
140170244Sume	    const char *dname,		/*!< domain name  */
141170244Sume	    int class, int type,	/*!< class and type of query  */
142170244Sume	    const u_char *data,		/*!< resource record data  */
143170244Sume	    int datalen,		/*!< length of data  */
144170244Sume	    const u_char *newrr_in,	/*!< new rr for modify or append  */
145170244Sume	    u_char *buf,		/*!< buffer to put query  */
146170244Sume	    int buflen)			/*!< size of buffer  */
147156952Sume{
148156952Sume	if ((_res.options & RES_INIT) == 0U && res_init() == -1) {
149156952Sume		RES_SET_H_ERRNO(&_res, NETDB_INTERNAL);
150156952Sume		return (-1);
151156952Sume	}
152156952Sume	return (res_nmkquery(&_res, op, dname, class, type,
153156952Sume			     data, datalen,
154156952Sume			     newrr_in, buf, buflen));
155156952Sume}
156156952Sume
157156952Sumeint
158156952Sumeres_mkupdate(ns_updrec *rrecp_in, u_char *buf, int buflen) {
159156952Sume	if ((_res.options & RES_INIT) == 0U && res_init() == -1) {
160156952Sume		RES_SET_H_ERRNO(&_res, NETDB_INTERNAL);
161156952Sume		return (-1);
162156952Sume	}
163156952Sume
164156952Sume	return (res_nmkupdate(&_res, rrecp_in, buf, buflen));
165156952Sume}
166156952Sume
167156952Sumeint
168170244Sumeres_query(const char *name,	/*!< domain name  */
169170244Sume	  int class, int type,	/*!< class and type of query  */
170170244Sume	  u_char *answer,	/*!< buffer to put answer  */
171170244Sume	  int anslen)		/*!< size of answer buffer  */
172156952Sume{
173156952Sume	if ((_res.options & RES_INIT) == 0U && res_init() == -1) {
174156952Sume		RES_SET_H_ERRNO(&_res, NETDB_INTERNAL);
175156952Sume		return (-1);
176156952Sume	}
177156952Sume	return (res_nquery(&_res, name, class, type, answer, anslen));
178156952Sume}
179156952Sume
180156956Sume#ifndef _LIBC
181156952Sumevoid
182156952Sumeres_send_setqhook(res_send_qhook hook) {
183156952Sume	_res.qhook = hook;
184156952Sume}
185156952Sume
186156952Sumevoid
187156952Sumeres_send_setrhook(res_send_rhook hook) {
188156952Sume	_res.rhook = hook;
189156952Sume}
190156956Sume#endif
191156952Sume
192156952Sumeint
193156952Sumeres_isourserver(const struct sockaddr_in *inp) {
194156952Sume	return (res_ourserver_p(&_res, inp));
195156952Sume}
196156952Sume
197156952Sumeint
198156952Sumeres_send(const u_char *buf, int buflen, u_char *ans, int anssiz) {
199156952Sume	if ((_res.options & RES_INIT) == 0U && res_init() == -1) {
200156952Sume		/* errno should have been set by res_init() in this case. */
201156952Sume		return (-1);
202156952Sume	}
203156952Sume
204156952Sume	return (res_nsend(&_res, buf, buflen, ans, anssiz));
205156952Sume}
206156952Sume
207156956Sume#ifndef _LIBC
208156952Sumeint
209156952Sumeres_sendsigned(const u_char *buf, int buflen, ns_tsig_key *key,
210156952Sume	       u_char *ans, int anssiz)
211156952Sume{
212156952Sume	if ((_res.options & RES_INIT) == 0U && res_init() == -1) {
213156952Sume		/* errno should have been set by res_init() in this case. */
214156952Sume		return (-1);
215156952Sume	}
216156952Sume
217156952Sume	return (res_nsendsigned(&_res, buf, buflen, key, ans, anssiz));
218156952Sume}
219156956Sume#endif
220156952Sume
221156952Sumevoid
222156952Sumeres_close(void) {
223156952Sume	res_nclose(&_res);
224156952Sume}
225156952Sume
226156952Sumeint
227156952Sumeres_update(ns_updrec *rrecp_in) {
228156952Sume	if ((_res.options & RES_INIT) == 0U && res_init() == -1) {
229156952Sume		RES_SET_H_ERRNO(&_res, NETDB_INTERNAL);
230156952Sume		return (-1);
231156952Sume	}
232156952Sume
233156952Sume	return (res_nupdate(&_res, 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{
242156952Sume	if ((_res.options & RES_INIT) == 0U && res_init() == -1) {
243156952Sume		RES_SET_H_ERRNO(&_res, NETDB_INTERNAL);
244156952Sume		return (-1);
245156952Sume	}
246156952Sume
247156952Sume	return (res_nsearch(&_res, name, class, type, answer, anslen));
248156952Sume}
249156952Sume
250156952Sumeint
251156952Sumeres_querydomain(const char *name,
252156952Sume		const char *domain,
253170244Sume		int class, int type,	/*!< class and type of query  */
254170244Sume		u_char *answer,		/*!< buffer to put answer  */
255170244Sume		int anslen)		/*!< size of answer  */
256156952Sume{
257156952Sume	if ((_res.options & RES_INIT) == 0U && res_init() == -1) {
258156952Sume		RES_SET_H_ERRNO(&_res, NETDB_INTERNAL);
259156952Sume		return (-1);
260156952Sume	}
261156952Sume
262156952Sume	return (res_nquerydomain(&_res, name, domain,
263156952Sume				 class, type,
264156952Sume				 answer, anslen));
265156952Sume}
266156952Sume
267156956Sumeint
268156956Sumeres_opt(int n0, u_char *buf, int buflen, int anslen)
269156956Sume{
270156956Sume	return (res_nopt(&_res, n0, buf, buflen, anslen));
271156956Sume}
272156956Sume
273156952Sumeconst char *
274156952Sumehostalias(const char *name) {
275156952Sume	static char abuf[MAXDNAME];
276156952Sume
277156952Sume	return (res_hostalias(&_res, name, abuf, sizeof abuf));
278156952Sume}
279156952Sume
280156952Sume#ifdef ultrix
281156952Sumeint
282156952Sumelocal_hostname_length(const char *hostname) {
283156952Sume	int len_host, len_domain;
284156952Sume
285156952Sume	if (!*_res.defdname)
286156952Sume		res_init();
287156952Sume	len_host = strlen(hostname);
288156952Sume	len_domain = strlen(_res.defdname);
289156952Sume	if (len_host > len_domain &&
290156952Sume	    !strcasecmp(hostname + len_host - len_domain, _res.defdname) &&
291156952Sume	    hostname[len_host - len_domain - 1] == '.')
292156952Sume		return (len_host - len_domain - 1);
293156952Sume	return (0);
294156952Sume}
295156952Sume#endif /*ultrix*/
296156952Sume
297156956Sume/*
298156956Sume * Weak aliases for applications that use certain private entry points,
299156956Sume * and fail to include <resolv.h>.
300156956Sume */
301156956Sume#undef res_init
302156956Sume__weak_reference(__res_init, res_init);
303156956Sume#undef p_query
304156956Sume__weak_reference(__p_query, p_query);
305156956Sume#undef res_mkquery
306156956Sume__weak_reference(__res_mkquery, res_mkquery);
307156956Sume#undef res_query
308156956Sume__weak_reference(__res_query, res_query);
309156956Sume#undef res_send
310156956Sume__weak_reference(__res_send, res_send);
311156956Sume#undef res_close
312156956Sume__weak_reference(__res_close, _res_close);
313156956Sume#undef res_search
314156956Sume__weak_reference(__res_search, res_search);
315156956Sume#undef res_querydomain
316156956Sume__weak_reference(__res_querydomain, res_querydomain);
317156956Sume
318156952Sume#endif
319170244Sume
320170244Sume/*! \file */
321