Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/lib/libc/resolv/res_data.c
39481 views
1
/*-
2
* SPDX-License-Identifier: ISC
3
*
4
* Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
5
* Copyright (c) 1995-1999 by Internet Software Consortium.
6
*
7
* Permission to use, copy, modify, and distribute this software for any
8
* purpose with or without fee is hereby granted, provided that the above
9
* copyright notice and this permission notice appear in all copies.
10
*
11
* THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
12
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR
14
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
17
* OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18
*/
19
20
#include "port_before.h"
21
22
#include <sys/param.h>
23
#include <sys/socket.h>
24
#include <sys/time.h>
25
26
#include <netinet/in.h>
27
#include <arpa/inet.h>
28
#include <arpa/nameser.h>
29
30
#include <ctype.h>
31
#include <netdb.h>
32
#include <resolv.h>
33
#include <res_update.h>
34
#include <stdio.h>
35
#include <stdlib.h>
36
#include <string.h>
37
#include <unistd.h>
38
39
#include "port_after.h"
40
41
const char *_res_opcodes[] = {
42
"QUERY",
43
"IQUERY",
44
"CQUERYM",
45
"CQUERYU", /*%< experimental */
46
"NOTIFY", /*%< experimental */
47
"UPDATE",
48
"6",
49
"7",
50
"8",
51
"9",
52
"10",
53
"11",
54
"12",
55
"13",
56
"ZONEINIT",
57
"ZONEREF",
58
};
59
60
#ifdef BIND_UPDATE
61
const char *_res_sectioncodes[] = {
62
"ZONE",
63
"PREREQUISITES",
64
"UPDATE",
65
"ADDITIONAL",
66
};
67
#endif
68
69
#ifndef __BIND_NOSTATIC
70
71
/* Proto. */
72
73
int res_ourserver_p(const res_state, const struct sockaddr_in *);
74
75
__noinline int
76
res_init(void) {
77
extern int __res_vinit(res_state, int);
78
res_state statp = &_res;
79
80
/*
81
* These three fields used to be statically initialized. This made
82
* it hard to use this code in a shared library. It is necessary,
83
* now that we're doing dynamic initialization here, that we preserve
84
* the old semantics: if an application modifies one of these three
85
* fields of _res before res_init() is called, res_init() will not
86
* alter them. Of course, if an application is setting them to
87
* _zero_ before calling res_init(), hoping to override what used
88
* to be the static default, we can't detect it and unexpected results
89
* will follow. Zero for any of these fields would make no sense,
90
* so one can safely assume that the applications were already getting
91
* unexpected results.
92
*
93
* _res.options is tricky since some apps were known to diddle the bits
94
* before res_init() was first called. We can't replicate that semantic
95
* with dynamic initialization (they may have turned bits off that are
96
* set in RES_DEFAULT). Our solution is to declare such applications
97
* "broken". They could fool us by setting RES_INIT but none do (yet).
98
*/
99
if (!statp->retrans)
100
statp->retrans = RES_TIMEOUT;
101
if (!statp->retry)
102
statp->retry = RES_DFLRETRY;
103
if (!(statp->options & RES_INIT))
104
statp->options = RES_DEFAULT;
105
106
return (__res_vinit(statp, 1));
107
}
108
109
void
110
p_query(const u_char *msg) {
111
fp_query(msg, stdout);
112
}
113
114
void
115
fp_query(const u_char *msg, FILE *file) {
116
fp_nquery(msg, PACKETSZ, file);
117
}
118
119
void
120
fp_nquery(const u_char *msg, int len, FILE *file) {
121
res_state statp = &_res;
122
if ((statp->options & RES_INIT) == 0U && res_init() == -1)
123
return;
124
125
res_pquery(statp, msg, len, file);
126
}
127
128
int
129
res_mkquery(int op, /*!< opcode of query */
130
const char *dname, /*!< domain name */
131
int class, int type, /*!< class and type of query */
132
const u_char *data, /*!< resource record data */
133
int datalen, /*!< length of data */
134
const u_char *newrr_in, /*!< new rr for modify or append */
135
u_char *buf, /*!< buffer to put query */
136
int buflen) /*!< size of buffer */
137
{
138
res_state statp = &_res;
139
if ((statp->options & RES_INIT) == 0U && res_init() == -1) {
140
RES_SET_H_ERRNO(statp, NETDB_INTERNAL);
141
return (-1);
142
}
143
return (res_nmkquery(statp, op, dname, class, type,
144
data, datalen,
145
newrr_in, buf, buflen));
146
}
147
148
int
149
res_mkupdate(ns_updrec *rrecp_in, u_char *buf, int buflen) {
150
res_state statp = &_res;
151
if ((statp->options & RES_INIT) == 0U && res_init() == -1) {
152
RES_SET_H_ERRNO(statp, NETDB_INTERNAL);
153
return (-1);
154
}
155
156
return (res_nmkupdate(statp, rrecp_in, buf, buflen));
157
}
158
159
int
160
res_query(const char *name, /*!< domain name */
161
int class, int type, /*!< class and type of query */
162
u_char *answer, /*!< buffer to put answer */
163
int anslen) /*!< size of answer buffer */
164
{
165
res_state statp = &_res;
166
if ((statp->options & RES_INIT) == 0U && res_init() == -1) {
167
RES_SET_H_ERRNO(statp, NETDB_INTERNAL);
168
return (-1);
169
}
170
return (res_nquery(statp, name, class, type, answer, anslen));
171
}
172
173
#ifndef _LIBC
174
void
175
res_send_setqhook(res_send_qhook hook) {
176
_res.qhook = hook;
177
}
178
179
void
180
res_send_setrhook(res_send_rhook hook) {
181
_res.rhook = hook;
182
}
183
#endif
184
185
int
186
res_isourserver(const struct sockaddr_in *inp) {
187
return (res_ourserver_p(&_res, inp));
188
}
189
190
int
191
res_send(const u_char *buf, int buflen, u_char *ans, int anssiz) {
192
res_state statp = &_res;
193
if ((statp->options & RES_INIT) == 0U && res_init() == -1) {
194
/* errno should have been set by res_init() in this case. */
195
return (-1);
196
}
197
198
return (res_nsend(statp, buf, buflen, ans, anssiz));
199
}
200
201
#ifndef _LIBC
202
int
203
res_sendsigned(const u_char *buf, int buflen, ns_tsig_key *key,
204
u_char *ans, int anssiz)
205
{
206
res_state statp = &_res;
207
if ((statp->options & RES_INIT) == 0U && res_init() == -1) {
208
/* errno should have been set by res_init() in this case. */
209
return (-1);
210
}
211
212
return (res_nsendsigned(statp, buf, buflen, key, ans, anssiz));
213
}
214
#endif
215
216
void
217
res_close(void) {
218
res_nclose(&_res);
219
}
220
221
int
222
res_update(ns_updrec *rrecp_in) {
223
res_state statp = &_res;
224
if ((statp->options & RES_INIT) == 0U && res_init() == -1) {
225
RES_SET_H_ERRNO(statp, NETDB_INTERNAL);
226
return (-1);
227
}
228
229
return (res_nupdate(statp, rrecp_in, NULL));
230
}
231
232
int
233
res_search(const char *name, /*!< domain name */
234
int class, int type, /*!< class and type of query */
235
u_char *answer, /*!< buffer to put answer */
236
int anslen) /*!< size of answer */
237
{
238
res_state statp = &_res;
239
if ((statp->options & RES_INIT) == 0U && res_init() == -1) {
240
RES_SET_H_ERRNO(statp, NETDB_INTERNAL);
241
return (-1);
242
}
243
244
return (res_nsearch(statp, name, class, type, answer, anslen));
245
}
246
247
int
248
res_querydomain(const char *name,
249
const char *domain,
250
int class, int type, /*!< class and type of query */
251
u_char *answer, /*!< buffer to put answer */
252
int anslen) /*!< size of answer */
253
{
254
res_state statp = &_res;
255
if ((statp->options & RES_INIT) == 0U && res_init() == -1) {
256
RES_SET_H_ERRNO(statp, NETDB_INTERNAL);
257
return (-1);
258
}
259
260
return (res_nquerydomain(statp, name, domain,
261
class, type,
262
answer, anslen));
263
}
264
265
u_int
266
res_randomid(void) {
267
res_state statp = &_res;
268
if ((statp->options & RES_INIT) == 0U && res_init() == -1) {
269
RES_SET_H_ERRNO(statp, NETDB_INTERNAL);
270
return (-1);
271
}
272
273
return (res_nrandomid(statp));
274
}
275
276
int
277
res_opt(int n0, u_char *buf, int buflen, int anslen)
278
{
279
return (res_nopt(&_res, n0, buf, buflen, anslen));
280
}
281
282
const char *
283
hostalias(const char *name) {
284
static char abuf[MAXDNAME];
285
286
return (res_hostalias(&_res, name, abuf, sizeof abuf));
287
}
288
289
#ifdef ultrix
290
int
291
local_hostname_length(const char *hostname) {
292
int len_host, len_domain;
293
res_state statp;
294
295
statp = &_res;
296
if (!*statp->defdname)
297
res_init();
298
len_host = strlen(hostname);
299
len_domain = strlen(statp->defdname);
300
if (len_host > len_domain &&
301
!strcasecmp(hostname + len_host - len_domain, statp->defdname) &&
302
hostname[len_host - len_domain - 1] == '.')
303
return (len_host - len_domain - 1);
304
return (0);
305
}
306
#endif /*ultrix*/
307
308
/*
309
* Weak aliases for applications that use certain private entry points,
310
* and fail to include <resolv.h>.
311
*/
312
#undef res_init
313
__weak_reference(__res_init, res_init);
314
#undef p_query
315
__weak_reference(__p_query, p_query);
316
#undef res_mkquery
317
__weak_reference(__res_mkquery, res_mkquery);
318
#undef res_query
319
__weak_reference(__res_query, res_query);
320
#undef res_send
321
__weak_reference(__res_send, res_send);
322
#undef res_close
323
__weak_reference(__res_close, _res_close);
324
#undef res_search
325
__weak_reference(__res_search, res_search);
326
#undef res_querydomain
327
__weak_reference(__res_querydomain, res_querydomain);
328
329
#endif
330
331
/*! \file */
332
333