|
Lines 1-6
Link Here
|
| 1 |
/* OPENBSD ORIGINAL: lib/libc/net/getrrsetbyname.c */ |
1 |
/* OPENBSD ORIGINAL: lib/libc/net/getrrsetbyname.c */ |
| 2 |
|
2 |
|
| 3 |
/* $OpenBSD: getrrsetbyname.c,v 1.7 2003/03/07 07:34:14 itojun Exp $ */ |
3 |
/* $OpenBSD: getrrsetbyname.c,v 1.10 2005/03/30 02:58:28 tedu Exp $ */ |
| 4 |
|
4 |
|
| 5 |
/* |
5 |
/* |
| 6 |
* Copyright (c) 2001 Jakob Schlyter. All rights reserved. |
6 |
* Copyright (c) 2001 Jakob Schlyter. All rights reserved. |
|
Lines 51-98
Link Here
|
| 51 |
|
51 |
|
| 52 |
#include "getrrsetbyname.h" |
52 |
#include "getrrsetbyname.h" |
| 53 |
|
53 |
|
| 54 |
#define ANSWER_BUFFER_SIZE 1024*64 |
|
|
| 55 |
|
| 56 |
#if defined(HAVE_DECL_H_ERRNO) && !HAVE_DECL_H_ERRNO |
54 |
#if defined(HAVE_DECL_H_ERRNO) && !HAVE_DECL_H_ERRNO |
| 57 |
extern int h_errno; |
55 |
extern int h_errno; |
| 58 |
#endif |
56 |
#endif |
| 59 |
|
57 |
|
| 60 |
struct dns_query { |
58 |
/* We don't need multithread support here */ |
| 61 |
char *name; |
59 |
#ifdef _THREAD_PRIVATE |
| 62 |
u_int16_t type; |
60 |
# undef _THREAD_PRIVATE |
| 63 |
u_int16_t class; |
61 |
#endif |
| 64 |
struct dns_query *next; |
62 |
#define _THREAD_PRIVATE(a,b,c) (c) |
| 65 |
}; |
63 |
struct __res_state _res; |
| 66 |
|
|
|
| 67 |
struct dns_rr { |
| 68 |
char *name; |
| 69 |
u_int16_t type; |
| 70 |
u_int16_t class; |
| 71 |
u_int16_t ttl; |
| 72 |
u_int16_t size; |
| 73 |
void *rdata; |
| 74 |
struct dns_rr *next; |
| 75 |
}; |
| 76 |
|
| 77 |
struct dns_response { |
| 78 |
HEADER header; |
| 79 |
struct dns_query *query; |
| 80 |
struct dns_rr *answer; |
| 81 |
struct dns_rr *authority; |
| 82 |
struct dns_rr *additional; |
| 83 |
}; |
| 84 |
|
| 85 |
static struct dns_response *parse_dns_response(const u_char *, int); |
| 86 |
static struct dns_query *parse_dns_qsection(const u_char *, int, |
| 87 |
const u_char **, int); |
| 88 |
static struct dns_rr *parse_dns_rrsection(const u_char *, int, const u_char **, |
| 89 |
int); |
| 90 |
|
| 91 |
static void free_dns_query(struct dns_query *); |
| 92 |
static void free_dns_rr(struct dns_rr *); |
| 93 |
static void free_dns_response(struct dns_response *); |
| 94 |
|
64 |
|
| 95 |
static int count_dns_rr(struct dns_rr *, u_int16_t, u_int16_t); |
65 |
/* Necessary functions and macros */ |
| 96 |
|
66 |
|
| 97 |
/* |
67 |
/* |
| 98 |
* Inline versions of get/put short/long. Pointer is advanced. |
68 |
* Inline versions of get/put short/long. Pointer is advanced. |
|
Lines 162-175
_getlong(msgp)
Link Here
|
| 162 |
u_int32_t _getlong(register const u_char *); |
132 |
u_int32_t _getlong(register const u_char *); |
| 163 |
#endif |
133 |
#endif |
| 164 |
|
134 |
|
|
|
135 |
/* ************** */ |
| 136 |
|
| 137 |
#define ANSWER_BUFFER_SIZE 1024*64 |
| 138 |
|
| 139 |
struct dns_query { |
| 140 |
char *name; |
| 141 |
u_int16_t type; |
| 142 |
u_int16_t class; |
| 143 |
struct dns_query *next; |
| 144 |
}; |
| 145 |
|
| 146 |
struct dns_rr { |
| 147 |
char *name; |
| 148 |
u_int16_t type; |
| 149 |
u_int16_t class; |
| 150 |
u_int16_t ttl; |
| 151 |
u_int16_t size; |
| 152 |
void *rdata; |
| 153 |
struct dns_rr *next; |
| 154 |
}; |
| 155 |
|
| 156 |
struct dns_response { |
| 157 |
HEADER header; |
| 158 |
struct dns_query *query; |
| 159 |
struct dns_rr *answer; |
| 160 |
struct dns_rr *authority; |
| 161 |
struct dns_rr *additional; |
| 162 |
}; |
| 163 |
|
| 164 |
static struct dns_response *parse_dns_response(const u_char *, int); |
| 165 |
static struct dns_query *parse_dns_qsection(const u_char *, int, |
| 166 |
const u_char **, int); |
| 167 |
static struct dns_rr *parse_dns_rrsection(const u_char *, int, const u_char **, |
| 168 |
int); |
| 169 |
|
| 170 |
static void free_dns_query(struct dns_query *); |
| 171 |
static void free_dns_rr(struct dns_rr *); |
| 172 |
static void free_dns_response(struct dns_response *); |
| 173 |
|
| 174 |
static int count_dns_rr(struct dns_rr *, u_int16_t, u_int16_t); |
| 175 |
|
| 165 |
int |
176 |
int |
| 166 |
getrrsetbyname(const char *hostname, unsigned int rdclass, |
177 |
getrrsetbyname(const char *hostname, unsigned int rdclass, |
| 167 |
unsigned int rdtype, unsigned int flags, |
178 |
unsigned int rdtype, unsigned int flags, |
| 168 |
struct rrsetinfo **res) |
179 |
struct rrsetinfo **res) |
| 169 |
{ |
180 |
{ |
|
|
181 |
struct __res_state *_resp = _THREAD_PRIVATE(_res, _res, &_res); |
| 170 |
int result; |
182 |
int result; |
| 171 |
struct rrsetinfo *rrset = NULL; |
183 |
struct rrsetinfo *rrset = NULL; |
| 172 |
struct dns_response *response; |
184 |
struct dns_response *response = NULL; |
| 173 |
struct dns_rr *rr; |
185 |
struct dns_rr *rr; |
| 174 |
struct rdatainfo *rdata; |
186 |
struct rdatainfo *rdata; |
| 175 |
int length; |
187 |
int length; |
|
Lines 195-213
getrrsetbyname(const char *hostname, uns
Link Here
|
| 195 |
} |
207 |
} |
| 196 |
|
208 |
|
| 197 |
/* initialize resolver */ |
209 |
/* initialize resolver */ |
| 198 |
if ((_res.options & RES_INIT) == 0 && res_init() == -1) { |
210 |
if ((_resp->options & RES_INIT) == 0 && res_init() == -1) { |
| 199 |
result = ERRSET_FAIL; |
211 |
result = ERRSET_FAIL; |
| 200 |
goto fail; |
212 |
goto fail; |
| 201 |
} |
213 |
} |
| 202 |
|
214 |
|
| 203 |
#ifdef DEBUG |
215 |
#ifdef DEBUG |
| 204 |
_res.options |= RES_DEBUG; |
216 |
_resp->options |= RES_DEBUG; |
| 205 |
#endif /* DEBUG */ |
217 |
#endif /* DEBUG */ |
| 206 |
|
218 |
|
| 207 |
#ifdef RES_USE_DNSSEC |
219 |
#ifdef RES_USE_DNSSEC |
| 208 |
/* turn on DNSSEC if EDNS0 is configured */ |
220 |
/* turn on DNSSEC if EDNS0 is configured */ |
| 209 |
if (_res.options & RES_USE_EDNS0) |
221 |
if (_resp->options & RES_USE_EDNS0) |
| 210 |
_res.options |= RES_USE_DNSSEC; |
222 |
_resp->options |= RES_USE_DNSSEC; |
| 211 |
#endif /* RES_USE_DNSEC */ |
223 |
#endif /* RES_USE_DNSEC */ |
| 212 |
|
224 |
|
| 213 |
/* make query */ |
225 |
/* make query */ |
|
Lines 250-269
getrrsetbyname(const char *hostname, uns
Link Here
|
| 250 |
rrset->rri_ttl = response->answer->ttl; |
262 |
rrset->rri_ttl = response->answer->ttl; |
| 251 |
rrset->rri_nrdatas = response->header.ancount; |
263 |
rrset->rri_nrdatas = response->header.ancount; |
| 252 |
|
264 |
|
| 253 |
#ifdef HAVE_HEADER_AD |
|
|
| 254 |
/* check for authenticated data */ |
265 |
/* check for authenticated data */ |
| 255 |
if (response->header.ad == 1) |
266 |
if (response->header.ad == 1) |
| 256 |
rrset->rri_flags |= RRSET_VALIDATED; |
267 |
rrset->rri_flags |= RRSET_VALIDATED; |
| 257 |
#endif |
|
|
| 258 |
|
268 |
|
| 259 |
/* copy name from answer section */ |
269 |
/* copy name from answer section */ |
| 260 |
length = strlen(response->answer->name); |
270 |
rrset->rri_name = strdup(response->answer->name); |
| 261 |
rrset->rri_name = malloc(length + 1); |
|
|
| 262 |
if (rrset->rri_name == NULL) { |
271 |
if (rrset->rri_name == NULL) { |
| 263 |
result = ERRSET_NOMEMORY; |
272 |
result = ERRSET_NOMEMORY; |
| 264 |
goto fail; |
273 |
goto fail; |
| 265 |
} |
274 |
} |
| 266 |
strlcpy(rrset->rri_name, response->answer->name, length + 1); |
|
|
| 267 |
|
275 |
|
| 268 |
/* count answers */ |
276 |
/* count answers */ |
| 269 |
rrset->rri_nrdatas = count_dns_rr(response->answer, rrset->rri_rdclass, |
277 |
rrset->rri_nrdatas = count_dns_rr(response->answer, rrset->rri_rdclass, |
|
Lines 281-287
getrrsetbyname(const char *hostname, uns
Link Here
|
| 281 |
|
289 |
|
| 282 |
/* allocate memory for signatures */ |
290 |
/* allocate memory for signatures */ |
| 283 |
rrset->rri_sigs = calloc(rrset->rri_nsigs, sizeof(struct rdatainfo)); |
291 |
rrset->rri_sigs = calloc(rrset->rri_nsigs, sizeof(struct rdatainfo)); |
| 284 |
if (rrset->rri_nsigs > 0 && rrset->rri_sigs == NULL) { |
292 |
if (rrset->rri_sigs == NULL) { |
| 285 |
result = ERRSET_NOMEMORY; |
293 |
result = ERRSET_NOMEMORY; |
| 286 |
goto fail; |
294 |
goto fail; |
| 287 |
} |
295 |
} |
|
Lines 311-316
getrrsetbyname(const char *hostname, uns
Link Here
|
| 311 |
memcpy(rdata->rdi_data, rr->rdata, rr->size); |
319 |
memcpy(rdata->rdi_data, rr->rdata, rr->size); |
| 312 |
} |
320 |
} |
| 313 |
} |
321 |
} |
|
|
322 |
free_dns_response(response); |
| 314 |
|
323 |
|
| 315 |
*res = rrset; |
324 |
*res = rrset; |
| 316 |
return (ERRSET_SUCCESS); |
325 |
return (ERRSET_SUCCESS); |
|
Lines 318-323
getrrsetbyname(const char *hostname, uns
Link Here
|
| 318 |
fail: |
327 |
fail: |
| 319 |
if (rrset != NULL) |
328 |
if (rrset != NULL) |
| 320 |
freerrset(rrset); |
329 |
freerrset(rrset); |
|
|
330 |
if (response != NULL) |
| 331 |
free_dns_response(response); |
| 321 |
return (result); |
332 |
return (result); |
| 322 |
} |
333 |
} |
| 323 |
|
334 |
|
|
Lines 467-473
parse_dns_qsection(const u_char *answer,
Link Here
|
| 467 |
} |
478 |
} |
| 468 |
|
479 |
|
| 469 |
static struct dns_rr * |
480 |
static struct dns_rr * |
| 470 |
parse_dns_rrsection(const u_char *answer, int size, const u_char **cp, int count) |
481 |
parse_dns_rrsection(const u_char *answer, int size, const u_char **cp, |
|
|
482 |
int count) |
| 471 |
{ |
483 |
{ |
| 472 |
struct dns_rr *head, *curr, *prev; |
484 |
struct dns_rr *head, *curr, *prev; |
| 473 |
int i, length; |
485 |
int i, length; |