]> git.saurik.com Git - apple/libresolv.git/blob - res_data.c
libresolv-67.40.1.tar.gz
[apple/libresolv.git] / res_data.c
1 /*
2 * Copyright (c) 1995-1999 by Internet Software Consortium.
3 *
4 * Permission to use, copy, modify, and distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
9 * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
10 * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
11 * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
12 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
13 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
14 * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
15 * SOFTWARE.
16 */
17
18 #if defined(LIBC_SCCS) && !defined(lint)
19 static const char rcsid[] = "$Id: res_data.c,v 1.1 2006/03/01 19:01:37 majka Exp $";
20 #endif /* LIBC_SCCS and not lint */
21
22 #include <sys/types.h>
23 #include <sys/param.h>
24 #include <sys/socket.h>
25 #include <sys/time.h>
26
27 #include <netinet/in.h>
28 #include <arpa/inet.h>
29 #include <arpa/nameser.h>
30
31 #include <ctype.h>
32 #include <netdb.h>
33 #include <resolv.h>
34 #include <res_update.h>
35 #include <stdio.h>
36 #include <stdlib.h>
37 #include <string.h>
38 #include <unistd.h>
39
40 #include "res_private.h"
41
42 static struct __res_state *_res_static;
43
44 #ifdef USE__RES_9
45 struct __res_9_state _res_9;
46 #endif
47
48 extern int __res_vinit(res_state, int);
49
50 __attribute__((__visibility__("hidden")))
51 const char *__res_opcodes[] = {
52 "QUERY",
53 "IQUERY",
54 "CQUERYM",
55 "CQUERYU", /* experimental */
56 "NOTIFY", /* experimental */
57 "UPDATE",
58 "6",
59 "7",
60 "8",
61 "9",
62 "10",
63 "11",
64 "12",
65 "13",
66 "ZONEINIT",
67 "ZONEREF",
68 };
69
70 void
71 __h_errno_set(struct __res_state *res, int err)
72 {
73 h_errno = res->res_h_errno = err;
74 }
75
76 void
77 res_client_close(res_state res)
78 {
79 if (res == NULL) return;
80
81 if (res->_u._ext.ext != NULL) free(res->_u._ext.ext);
82 free(res);
83 }
84
85 res_state
86 res_state_new()
87 {
88 res_state x;
89
90 x = (res_state)calloc(1, sizeof(struct __res_state));
91 if (x == NULL) return NULL;
92
93 /*
94 * We use _pad (normally unused) to hold a version number.
95 * We use it provide limited compatibility between versions.
96 */
97 x->_pad = 9;
98
99 x->_u._ext.ext = (struct __res_state_ext *)calloc(1, sizeof(struct __res_state_ext));
100 if (x->_u._ext.ext == NULL)
101 {
102 free(x);
103 return NULL;
104 }
105
106 return x;
107 }
108
109 int
110 res_init(void)
111 {
112 extern int __res_vinit(res_state, int);
113 unsigned int save_retrans, save_retry, save_options, save_id;
114 struct __res_state_ext *save_ext;
115
116 #ifdef USE__RES_9
117 _res_static = &_res_9;
118 #else
119 _res_static = &_res;
120 #endif
121
122 save_retrans = RES_TIMEOUT;
123 save_retry = RES_DFLRETRY;
124 save_options = RES_DEFAULT;
125 save_id = res_randomid();
126 save_ext = _res_static->_u._ext.ext;
127
128 if (_res_static->options & RES_INIT)
129 {
130 /* Caller wants to override default options */
131 save_options = _res_static->options;
132 if (_res_static->retrans != 0) save_retrans = _res_static->retrans;
133 if (_res_static->retry != 0) save_retry = _res_static->retry;
134 if (_res_static->id != 0) save_id = _res_static->id;
135 }
136
137 memset(_res_static, 0, sizeof(struct __res_state));
138 _res_static->_vcsock = -1;
139
140 _res_static->retrans = save_retrans;
141 _res_static->retry = save_retry;
142 _res_static->id = save_id;
143 _res_static->options = save_options;
144 _res_static->_u._ext.ext = save_ext;
145
146 _res_static->_pad = 9;
147
148 if (_res_static->_u._ext.ext == NULL) _res_static->_u._ext.ext = (struct __res_state_ext *)calloc(1, sizeof(struct __res_state_ext));
149
150 return (__res_vinit(_res_static, 1));
151 }
152
153 int
154 res_query(const char *name, int class, int type, u_char *answer, int anslen)
155 {
156 #ifdef USE__RES_9
157 _res_static = &_res_9;
158 #else
159 _res_static = &_res;
160 #endif
161
162 if (((_res_static->options & RES_INIT) == 0) && (res_init() == -1))
163 {
164 RES_SET_H_ERRNO(_res_static, NETDB_INTERNAL);
165 return -1;
166 }
167 return (res_nquery(_res_static, name, class, type, answer, anslen));
168 }
169
170 void
171 fp_nquery(const u_char *msg, int len, FILE *file)
172 {
173 #ifdef USE__RES_9
174 _res_static = &_res_9;
175 #else
176 _res_static = &_res;
177 #endif
178
179 if (((_res_static->options & RES_INIT) == 0) && (res_init() == -1)) return;
180
181 res_pquery(_res_static, msg, len, file);
182 }
183
184 void
185 fp_query(const u_char *msg, FILE *file)
186 {
187 fp_nquery(msg, NS_PACKETSZ, file);
188 }
189
190 void
191 p_query(const u_char *msg)
192 {
193 fp_query(msg, stdout);
194 }
195
196 const char *
197 hostalias(const char *name)
198 {
199 static char abuf[NS_MAXDNAME];
200
201 #ifdef USE__RES_9
202 _res_static = &_res_9;
203 #else
204 _res_static = &_res;
205 #endif
206
207 return (res_hostalias(_res_static, name, abuf, sizeof abuf));
208 }
209
210 void
211 res_close(void)
212 {
213 #ifdef USE__RES_9
214 _res_static = &_res_9;
215 #else
216 _res_static = &_res;
217 #endif
218
219 res_nclose(_res_static);
220 }
221
222 int
223 res_isourserver(const struct sockaddr_in *inp)
224 {
225 #ifdef USE__RES_9
226 _res_static = &_res_9;
227 #else
228 _res_static = &_res;
229 #endif
230
231 return (res_ourserver_p(_res_static, (const struct sockaddr *)inp));
232 }
233
234 int
235 res_nisourserver(const res_state res, const struct sockaddr_in *inp)
236 {
237 return (res_ourserver_p(res, (const struct sockaddr *)inp));
238 }
239
240 int
241 res_mkquery(int op, const char *dname, int class, int type, const u_char *data, int datalen, const u_char *newrr_in, u_char *buf, int buflen)
242 {
243 #ifdef USE__RES_9
244 _res_static = &_res_9;
245 #else
246 _res_static = &_res;
247 #endif
248
249 if (((_res_static->options & RES_INIT) == 0) && (res_init() == -1))
250 {
251 RES_SET_H_ERRNO(_res_static, NETDB_INTERNAL);
252 return -1;
253 }
254
255 return res_nmkquery(_res_static, op, dname, class, type, data, datalen, newrr_in, buf, buflen);
256 }
257
258 int
259 res_querydomain(const char *name, const char *domain, int class, int type, u_char *answer, int anslen)
260 {
261 #ifdef USE__RES_9
262 _res_static = &_res_9;
263 #else
264 _res_static = &_res;
265 #endif
266
267 if (((_res_static->options & RES_INIT) == 0) && (res_init() == -1))
268 {
269 RES_SET_H_ERRNO(_res_static, NETDB_INTERNAL);
270 return -1;
271 }
272
273 return res_nquerydomain(_res_static, name, domain, class, type, answer, anslen);
274 }
275
276 int
277 res_search(const char *name, int class, int type, u_char *answer, int anslen)
278 {
279 #ifdef USE__RES_9
280 _res_static = &_res_9;
281 #else
282 _res_static = &_res;
283 #endif
284
285 if (((_res_static->options & RES_INIT) == 0) && (res_init() == -1))
286 {
287 RES_SET_H_ERRNO(_res_static, NETDB_INTERNAL);
288 return -1;
289 }
290
291 return res_nsearch(_res_static, name, class, type, answer, anslen);
292 }
293
294 int
295 res_send(const u_char *buf, int buflen, u_char *ans, int anssiz)
296 {
297 #ifdef USE__RES_9
298 _res_static = &_res_9;
299 #else
300 _res_static = &_res;
301 #endif
302
303 if (((_res_static->options & RES_INIT) == 0) && (res_init() == -1))
304 {
305 /* errno should have been set by res_init() in this case. */
306 return -1;
307 }
308
309 return res_nsend(_res_static, buf, buflen, ans, anssiz);
310 }
311
312 int
313 res_sendsigned(const u_char *buf, int buflen, ns_tsig_key *key, u_char *ans, int anssiz)
314 {
315 #ifdef USE__RES_9
316 _res_static = &_res_9;
317 #else
318 _res_static = &_res;
319 #endif
320
321 if (((_res_static->options & RES_INIT) == 0) && (res_init() == -1))
322 {
323 /* errno should have been set by res_init() in this case. */
324 return -1;
325 }
326
327 return res_nsendsigned(_res_static, buf, buflen, key, ans, anssiz);
328 }