]> git.saurik.com Git - apple/libresolv.git/blob - res_data.c
libresolv-19.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 const char *__res_opcodes[] = {
51 "QUERY",
52 "IQUERY",
53 "CQUERYM",
54 "CQUERYU", /* experimental */
55 "NOTIFY", /* experimental */
56 "UPDATE",
57 "6",
58 "7",
59 "8",
60 "9",
61 "10",
62 "11",
63 "12",
64 "13",
65 "ZONEINIT",
66 "ZONEREF",
67 };
68
69 void
70 __h_errno_set(struct __res_state *res, int err)
71 {
72 h_errno = res->res_h_errno = err;
73 }
74
75 void
76 res_client_close(res_state res)
77 {
78 if (res == NULL) return;
79
80 if (res->_u._ext.ext != NULL) free(res->_u._ext.ext);
81 free(res);
82 }
83
84 res_state
85 res_state_new()
86 {
87 res_state x;
88
89 x = (res_state)calloc(1, sizeof(struct __res_state));
90 if (x == NULL) return NULL;
91
92 /*
93 * We use _pad (normally unused) to hold a version number.
94 * We use it provide limited compatibility between versions.
95 */
96 x->_pad = 9;
97
98 x->_u._ext.ext = (struct __res_state_ext *)calloc(1, sizeof(struct __res_state_ext));
99 if (x->_u._ext.ext == NULL)
100 {
101 free(x);
102 return NULL;
103 }
104
105 return x;
106 }
107
108 int
109 res_init(void)
110 {
111 extern int __res_vinit(res_state, int);
112 unsigned int save_retrans, save_retry, save_options, save_id;
113 struct __res_state_ext *save_ext;
114
115 #ifdef USE__RES_9
116 _res_static = &_res_9;
117 #else
118 _res_static = &_res;
119 #endif
120
121 save_retrans = RES_TIMEOUT;
122 save_retry = RES_DFLRETRY;
123 save_options = RES_DEFAULT;
124 save_id = res_randomid();
125 save_ext = _res_static->_u._ext.ext;
126
127 if (_res_static->options & RES_INIT)
128 {
129 /* Caller wants to override default options */
130 save_options = _res_static->options;
131 if (_res_static->retrans != 0) save_retrans = _res_static->retrans;
132 if (_res_static->retry != 0) save_retry = _res_static->retry;
133 if (_res_static->id != 0) save_id = _res_static->id;
134 }
135
136 memset(_res_static, 0, sizeof(struct __res_state));
137 _res_static->_vcsock = -1;
138
139 _res_static->retrans = save_retrans;
140 _res_static->retry = save_retry;
141 _res_static->id = save_id;
142 _res_static->options = save_options;
143 _res_static->_u._ext.ext = save_ext;
144
145 _res_static->_pad = 9;
146
147 if (_res_static->_u._ext.ext == NULL) _res_static->_u._ext.ext = (struct __res_state_ext *)calloc(1, sizeof(struct __res_state_ext));
148
149 return (__res_vinit(_res_static, 1));
150 }
151
152 int
153 res_query(const char *name, int class, int type, u_char *answer, int anslen)
154 {
155 #ifdef USE__RES_9
156 _res_static = &_res_9;
157 #else
158 _res_static = &_res;
159 #endif
160
161 if (((_res_static->options & RES_INIT) == 0) && (res_init() == -1))
162 {
163 RES_SET_H_ERRNO(_res_static, NETDB_INTERNAL);
164 return -1;
165 }
166 return (res_nquery(_res_static, name, class, type, answer, anslen));
167 }
168
169 void
170 fp_nquery(const u_char *msg, int len, FILE *file)
171 {
172 #ifdef USE__RES_9
173 _res_static = &_res_9;
174 #else
175 _res_static = &_res;
176 #endif
177
178 if (((_res_static->options & RES_INIT) == 0) && (res_init() == -1)) return;
179
180 res_pquery(_res_static, msg, len, file);
181 }
182
183 void
184 fp_query(const u_char *msg, FILE *file)
185 {
186 fp_nquery(msg, NS_PACKETSZ, file);
187 }
188
189 void
190 p_query(const u_char *msg)
191 {
192 fp_query(msg, stdout);
193 }
194
195 const char *
196 hostalias(const char *name)
197 {
198 static char abuf[NS_MAXDNAME];
199
200 #ifdef USE__RES_9
201 _res_static = &_res_9;
202 #else
203 _res_static = &_res;
204 #endif
205
206 return (res_hostalias(_res_static, name, abuf, sizeof abuf));
207 }
208
209 void
210 res_close(void)
211 {
212 #ifdef USE__RES_9
213 _res_static = &_res_9;
214 #else
215 _res_static = &_res;
216 #endif
217
218 res_nclose(_res_static);
219 }
220
221 int
222 res_isourserver(const struct sockaddr_in *inp)
223 {
224 #ifdef USE__RES_9
225 _res_static = &_res_9;
226 #else
227 _res_static = &_res;
228 #endif
229
230 return (res_ourserver_p(_res_static, (const struct sockaddr *)inp));
231 }
232
233 int
234 res_nisourserver(const res_state res, const struct sockaddr_in *inp)
235 {
236 return (res_ourserver_p(res, (const struct sockaddr *)inp));
237 }
238
239 int
240 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)
241 {
242 #ifdef USE__RES_9
243 _res_static = &_res_9;
244 #else
245 _res_static = &_res;
246 #endif
247
248 if (((_res_static->options & RES_INIT) == 0) && (res_init() == -1))
249 {
250 RES_SET_H_ERRNO(_res_static, NETDB_INTERNAL);
251 return -1;
252 }
253
254 return res_nmkquery(_res_static, op, dname, class, type, data, datalen, newrr_in, buf, buflen);
255 }
256
257 int
258 res_querydomain(const char *name, const char *domain, int class, int type, u_char *answer, int anslen)
259 {
260 #ifdef USE__RES_9
261 _res_static = &_res_9;
262 #else
263 _res_static = &_res;
264 #endif
265
266 if (((_res_static->options & RES_INIT) == 0) && (res_init() == -1))
267 {
268 RES_SET_H_ERRNO(_res_static, NETDB_INTERNAL);
269 return -1;
270 }
271
272 return res_nquerydomain(_res_static, name, domain, class, type, answer, anslen);
273 }
274
275 int
276 res_search(const char *name, int class, int type, u_char *answer, int anslen)
277 {
278 #ifdef USE__RES_9
279 _res_static = &_res_9;
280 #else
281 _res_static = &_res;
282 #endif
283
284 if (((_res_static->options & RES_INIT) == 0) && (res_init() == -1))
285 {
286 RES_SET_H_ERRNO(_res_static, NETDB_INTERNAL);
287 return -1;
288 }
289
290 return res_nsearch(_res_static, name, class, type, answer, anslen);
291 }
292
293 int
294 res_send(const u_char *buf, int buflen, u_char *ans, int anssiz)
295 {
296 #ifdef USE__RES_9
297 _res_static = &_res_9;
298 #else
299 _res_static = &_res;
300 #endif
301
302 if (((_res_static->options & RES_INIT) == 0) && (res_init() == -1))
303 {
304 /* errno should have been set by res_init() in this case. */
305 return -1;
306 }
307
308 return res_nsend(_res_static, buf, buflen, ans, anssiz);
309 }
310
311 int
312 res_sendsigned(const u_char *buf, int buflen, ns_tsig_key *key, u_char *ans, int anssiz)
313 {
314 #ifdef USE__RES_9
315 _res_static = &_res_9;
316 #else
317 _res_static = &_res;
318 #endif
319
320 if (((_res_static->options & RES_INIT) == 0) && (res_init() == -1))
321 {
322 /* errno should have been set by res_init() in this case. */
323 return -1;
324 }
325
326 return res_nsendsigned(_res_static, buf, buflen, key, ans, anssiz);
327 }