res_data.c revision 156956
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)
19156952Sumestatic const char rcsid[] = "$Id: res_data.c,v 1.1.206.2 2004/03/16 12:34:18 marka Exp $";
20156952Sume#endif /* LIBC_SCCS and not lint */
21156956Sume#include <sys/cdefs.h>
22156956Sume__FBSDID("$FreeBSD: head/lib/libc/resolv/res_data.c 156956 2006-03-21 15:37:16Z ume $");
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>
38156956Sume#ifndef _LIBC
39156952Sume#include <res_update.h>
40156956Sume#endif
41156952Sume#include <stdio.h>
42156952Sume#include <stdlib.h>
43156952Sume#include <string.h>
44156952Sume#include <unistd.h>
45156952Sume
46156952Sume#include "port_after.h"
47156952Sume
48156952Sumeconst char *_res_opcodes[] = {
49156952Sume	"QUERY",
50156952Sume	"IQUERY",
51156952Sume	"CQUERYM",
52156952Sume	"CQUERYU",	/* experimental */
53156952Sume	"NOTIFY",	/* experimental */
54156952Sume	"UPDATE",
55156952Sume	"6",
56156952Sume	"7",
57156952Sume	"8",
58156952Sume	"9",
59156952Sume	"10",
60156952Sume	"11",
61156952Sume	"12",
62156952Sume	"13",
63156952Sume	"ZONEINIT",
64156952Sume	"ZONEREF",
65156952Sume};
66156952Sume
67156952Sume#ifdef BIND_UPDATE
68156952Sumeconst char *_res_sectioncodes[] = {
69156952Sume	"ZONE",
70156952Sume	"PREREQUISITES",
71156952Sume	"UPDATE",
72156952Sume	"ADDITIONAL",
73156952Sume};
74156952Sume#endif
75156952Sume
76156952Sume#ifndef __BIND_NOSTATIC
77156952Sume
78156952Sume/* Proto. */
79156952Sume
80156952Sumeint  res_ourserver_p(const res_state, const struct sockaddr_in *);
81156952Sume
82156952Sumeint
83156952Sumeres_init(void) {
84156952Sume	extern int __res_vinit(res_state, int);
85156952Sume
86156952Sume	/*
87156952Sume	 * These three fields used to be statically initialized.  This made
88156952Sume	 * it hard to use this code in a shared library.  It is necessary,
89156952Sume	 * now that we're doing dynamic initialization here, that we preserve
90156952Sume	 * the old semantics: if an application modifies one of these three
91156952Sume	 * fields of _res before res_init() is called, res_init() will not
92156952Sume	 * alter them.  Of course, if an application is setting them to
93156952Sume	 * _zero_ before calling res_init(), hoping to override what used
94156952Sume	 * to be the static default, we can't detect it and unexpected results
95156952Sume	 * will follow.  Zero for any of these fields would make no sense,
96156952Sume	 * so one can safely assume that the applications were already getting
97156952Sume	 * unexpected results.
98156952Sume	 *
99156952Sume	 * _res.options is tricky since some apps were known to diddle the bits
100156952Sume	 * before res_init() was first called. We can't replicate that semantic
101156952Sume	 * with dynamic initialization (they may have turned bits off that are
102156952Sume	 * set in RES_DEFAULT).  Our solution is to declare such applications
103156952Sume	 * "broken".  They could fool us by setting RES_INIT but none do (yet).
104156952Sume	 */
105156952Sume	if (!_res.retrans)
106156952Sume		_res.retrans = RES_TIMEOUT;
107156952Sume	if (!_res.retry)
108156956Sume		_res.retry = RES_DFLRETRY;
109156952Sume	if (!(_res.options & RES_INIT))
110156952Sume		_res.options = RES_DEFAULT;
111156952Sume
112156952Sume	/*
113156952Sume	 * This one used to initialize implicitly to zero, so unless the app
114156952Sume	 * has set it to something in particular, we can randomize it now.
115156952Sume	 */
116156952Sume	if (!_res.id)
117156952Sume		_res.id = res_randomid();
118156952Sume
119156952Sume	return (__res_vinit(&_res, 1));
120156952Sume}
121156952Sume
122156952Sumevoid
123156952Sumep_query(const u_char *msg) {
124156952Sume	fp_query(msg, stdout);
125156952Sume}
126156952Sume
127156952Sumevoid
128156952Sumefp_query(const u_char *msg, FILE *file) {
129156952Sume	fp_nquery(msg, PACKETSZ, file);
130156952Sume}
131156952Sume
132156952Sumevoid
133156952Sumefp_nquery(const u_char *msg, int len, FILE *file) {
134156952Sume	if ((_res.options & RES_INIT) == 0U && res_init() == -1)
135156952Sume		return;
136156952Sume
137156952Sume	res_pquery(&_res, msg, len, file);
138156952Sume}
139156952Sume
140156952Sumeint
141156952Sumeres_mkquery(int op,			/* opcode of query */
142156952Sume	    const char *dname,		/* domain name */
143156952Sume	    int class, int type,	/* class and type of query */
144156952Sume	    const u_char *data,		/* resource record data */
145156952Sume	    int datalen,		/* length of data */
146156952Sume	    const u_char *newrr_in,	/* new rr for modify or append */
147156952Sume	    u_char *buf,		/* buffer to put query */
148156952Sume	    int buflen)			/* size of buffer */
149156952Sume{
150156952Sume	if ((_res.options & RES_INIT) == 0U && res_init() == -1) {
151156952Sume		RES_SET_H_ERRNO(&_res, NETDB_INTERNAL);
152156952Sume		return (-1);
153156952Sume	}
154156952Sume	return (res_nmkquery(&_res, op, dname, class, type,
155156952Sume			     data, datalen,
156156952Sume			     newrr_in, buf, buflen));
157156952Sume}
158156952Sume
159156956Sume#ifndef _LIBC
160156952Sumeint
161156952Sumeres_mkupdate(ns_updrec *rrecp_in, u_char *buf, int buflen) {
162156952Sume	if ((_res.options & RES_INIT) == 0U && res_init() == -1) {
163156952Sume		RES_SET_H_ERRNO(&_res, NETDB_INTERNAL);
164156952Sume		return (-1);
165156952Sume	}
166156952Sume
167156952Sume	return (res_nmkupdate(&_res, rrecp_in, buf, buflen));
168156952Sume}
169156956Sume#endif
170156952Sume
171156952Sumeint
172156952Sumeres_query(const char *name,	/* domain name */
173156952Sume	  int class, int type,	/* class and type of query */
174156952Sume	  u_char *answer,	/* buffer to put answer */
175156952Sume	  int anslen)		/* size of answer buffer */
176156952Sume{
177156952Sume	if ((_res.options & RES_INIT) == 0U && res_init() == -1) {
178156952Sume		RES_SET_H_ERRNO(&_res, NETDB_INTERNAL);
179156952Sume		return (-1);
180156952Sume	}
181156952Sume	return (res_nquery(&_res, name, class, type, answer, anslen));
182156952Sume}
183156952Sume
184156956Sume#ifndef _LIBC
185156952Sumevoid
186156952Sumeres_send_setqhook(res_send_qhook hook) {
187156952Sume	_res.qhook = hook;
188156952Sume}
189156952Sume
190156952Sumevoid
191156952Sumeres_send_setrhook(res_send_rhook hook) {
192156952Sume	_res.rhook = hook;
193156952Sume}
194156956Sume#endif
195156952Sume
196156952Sumeint
197156952Sumeres_isourserver(const struct sockaddr_in *inp) {
198156952Sume	return (res_ourserver_p(&_res, inp));
199156952Sume}
200156952Sume
201156952Sumeint
202156952Sumeres_send(const u_char *buf, int buflen, u_char *ans, int anssiz) {
203156952Sume	if ((_res.options & RES_INIT) == 0U && res_init() == -1) {
204156952Sume		/* errno should have been set by res_init() in this case. */
205156952Sume		return (-1);
206156952Sume	}
207156952Sume
208156952Sume	return (res_nsend(&_res, buf, buflen, ans, anssiz));
209156952Sume}
210156952Sume
211156956Sume#ifndef _LIBC
212156952Sumeint
213156952Sumeres_sendsigned(const u_char *buf, int buflen, ns_tsig_key *key,
214156952Sume	       u_char *ans, int anssiz)
215156952Sume{
216156952Sume	if ((_res.options & RES_INIT) == 0U && res_init() == -1) {
217156952Sume		/* errno should have been set by res_init() in this case. */
218156952Sume		return (-1);
219156952Sume	}
220156952Sume
221156952Sume	return (res_nsendsigned(&_res, buf, buflen, key, ans, anssiz));
222156952Sume}
223156956Sume#endif
224156952Sume
225156952Sumevoid
226156952Sumeres_close(void) {
227156952Sume	res_nclose(&_res);
228156952Sume}
229156952Sume
230156956Sume#ifndef _LIBC
231156952Sumeint
232156952Sumeres_update(ns_updrec *rrecp_in) {
233156952Sume	if ((_res.options & RES_INIT) == 0U && res_init() == -1) {
234156952Sume		RES_SET_H_ERRNO(&_res, NETDB_INTERNAL);
235156952Sume		return (-1);
236156952Sume	}
237156952Sume
238156952Sume	return (res_nupdate(&_res, rrecp_in, NULL));
239156952Sume}
240156956Sume#endif
241156952Sume
242156952Sumeint
243156952Sumeres_search(const char *name,	/* domain name */
244156952Sume	   int class, int type,	/* class and type of query */
245156952Sume	   u_char *answer,	/* buffer to put answer */
246156952Sume	   int anslen)		/* size of answer */
247156952Sume{
248156952Sume	if ((_res.options & RES_INIT) == 0U && res_init() == -1) {
249156952Sume		RES_SET_H_ERRNO(&_res, NETDB_INTERNAL);
250156952Sume		return (-1);
251156952Sume	}
252156952Sume
253156952Sume	return (res_nsearch(&_res, name, class, type, answer, anslen));
254156952Sume}
255156952Sume
256156952Sumeint
257156952Sumeres_querydomain(const char *name,
258156952Sume		const char *domain,
259156952Sume		int class, int type,	/* class and type of query */
260156952Sume		u_char *answer,		/* buffer to put answer */
261156952Sume		int anslen)		/* size of answer */
262156952Sume{
263156952Sume	if ((_res.options & RES_INIT) == 0U && res_init() == -1) {
264156952Sume		RES_SET_H_ERRNO(&_res, NETDB_INTERNAL);
265156952Sume		return (-1);
266156952Sume	}
267156952Sume
268156952Sume	return (res_nquerydomain(&_res, name, domain,
269156952Sume				 class, type,
270156952Sume				 answer, anslen));
271156952Sume}
272156952Sume
273156956Sumeint
274156956Sumeres_opt(int n0, u_char *buf, int buflen, int anslen)
275156956Sume{
276156956Sume	return (res_nopt(&_res, n0, buf, buflen, anslen));
277156956Sume}
278156956Sume
279156952Sumeconst char *
280156952Sumehostalias(const char *name) {
281156952Sume	static char abuf[MAXDNAME];
282156952Sume
283156952Sume	return (res_hostalias(&_res, name, abuf, sizeof abuf));
284156952Sume}
285156952Sume
286156952Sume#ifdef ultrix
287156952Sumeint
288156952Sumelocal_hostname_length(const char *hostname) {
289156952Sume	int len_host, len_domain;
290156952Sume
291156952Sume	if (!*_res.defdname)
292156952Sume		res_init();
293156952Sume	len_host = strlen(hostname);
294156952Sume	len_domain = strlen(_res.defdname);
295156952Sume	if (len_host > len_domain &&
296156952Sume	    !strcasecmp(hostname + len_host - len_domain, _res.defdname) &&
297156952Sume	    hostname[len_host - len_domain - 1] == '.')
298156952Sume		return (len_host - len_domain - 1);
299156952Sume	return (0);
300156952Sume}
301156952Sume#endif /*ultrix*/
302156952Sume
303156956Sume/*
304156956Sume * Weak aliases for applications that use certain private entry points,
305156956Sume * and fail to include <resolv.h>.
306156956Sume */
307156956Sume#undef res_init
308156956Sume__weak_reference(__res_init, res_init);
309156956Sume#undef p_query
310156956Sume__weak_reference(__p_query, p_query);
311156956Sume#undef res_mkquery
312156956Sume__weak_reference(__res_mkquery, res_mkquery);
313156956Sume#undef res_query
314156956Sume__weak_reference(__res_query, res_query);
315156956Sume#undef res_send
316156956Sume__weak_reference(__res_send, res_send);
317156956Sume#undef res_close
318156956Sume__weak_reference(__res_close, _res_close);
319156956Sume#undef res_search
320156956Sume__weak_reference(__res_search, res_search);
321156956Sume#undef res_querydomain
322156956Sume__weak_reference(__res_querydomain, res_querydomain);
323156956Sume
324156952Sume#endif
325