ldns documentation

- Main Page
- Related Pages
- Data Structures
- Files

- File List
- Globals

higher.c
Go to the documentation of this file.
1 /*
2 * higher.c
3 *
4 * Specify some higher level functions that would
5 * be usefull to would be developers
6 *
7 * a Net::DNS like library for C
8 *
9 * (c) NLnet Labs, 2004-2006
10 *
11 * See the file LICENSE for the license
12 */
13
14 #include <ldns/config.h>
15
16 #include <ldns/ldns.h>
17
18 #ifdef HAVE_SSL
19 #include <openssl/ssl.h>
20 #include <openssl/sha.h>
21 #endif /* HAVE_SSL */
22
23 ldns_rr_list *
24 ldns_get_rr_list_addr_by_name(ldns_resolver *res, ldns_rdf *name, ldns_rr_class c,
25 uint16_t flags)
26 {
27 ldns_pkt *pkt;
28 ldns_rr_list *aaaa;
29 ldns_rr_list *a;
30 ldns_rr_list *result = NULL;
31 ldns_rr_list *hostsfilenames;
32 size_t i;
33 uint8_t ip6;
34
35 a = NULL;
36 aaaa = NULL;
37 result = NULL;
38
39 if (!res) {
40 return NULL;
41 }
42 if (ldns_rdf_get_type(name) != LDNS_RDF_TYPE_DNAME) {
43 return NULL;
44 }
45
46 ip6 = ldns_resolver_ip6(res); /* we use INET_ANY here, save
47 what was there */
48
49 ldns_resolver_set_ip6(res, LDNS_RESOLV_INETANY);
50
51 hostsfilenames = ldns_get_rr_list_hosts_frm_file(NULL);
52 for (i = 0; i < ldns_rr_list_rr_count(hostsfilenames); i++) {
53 if (ldns_rdf_compare(name,
54 ldns_rr_owner(ldns_rr_list_rr(hostsfilenames,
55 i))) == 0) {
56 if (!result) {
57 result = ldns_rr_list_new();
58 }
59 ldns_rr_list_push_rr(result,
60 ldns_rr_clone(ldns_rr_list_rr(hostsfilenames, i)));
61 }
62 }
63 ldns_rr_list_deep_free(hostsfilenames);
64
65 if (result) {
66 return result;
67 }
68
69 /* add the RD flags, because we want an answer */
70 pkt = ldns_resolver_query(res, name, LDNS_RR_TYPE_AAAA, c, flags | LDNS_RD);
71 if (pkt) {
72 /* extract the data we need */
73 aaaa = ldns_pkt_rr_list_by_type(pkt, LDNS_RR_TYPE_AAAA,
74 LDNS_SECTION_ANSWER);
75 ldns_pkt_free(pkt);
76 }
77
78 pkt = ldns_resolver_query(res, name, LDNS_RR_TYPE_A, c, flags | LDNS_RD);
79 if (pkt) {
80 /* extract the data we need */
81 a = ldns_pkt_rr_list_by_type(pkt, LDNS_RR_TYPE_A, LDNS_SECTION_ANSWER);
82 ldns_pkt_free(pkt);
83 }
84 ldns_resolver_set_ip6(res, ip6);
85
86 if (aaaa && a) {
87 result = ldns_rr_list_cat_clone(aaaa, a);
88 ldns_rr_list_deep_free(aaaa);
89 ldns_rr_list_deep_free(a);
90 return result;
91 }
92
93 if (aaaa) {
94 result = ldns_rr_list_clone(aaaa);
95 }
96
97 if (a) {
98 result = ldns_rr_list_clone(a);
99 }
100
101 ldns_rr_list_deep_free(aaaa);
102 ldns_rr_list_deep_free(a);
103 return result;
104 }
105
106 ldns_rr_list *
107 ldns_get_rr_list_name_by_addr(ldns_resolver *res, ldns_rdf *addr, ldns_rr_class c,
108 uint16_t flags)
109 {
110 ldns_pkt *pkt;
111 ldns_rr_list *names;
112 ldns_rdf *name;
113
114 names = NULL;
115
116 if (!res || !addr) {
117 return NULL;
118 }
119
120 if (ldns_rdf_get_type(addr) != LDNS_RDF_TYPE_A &&
121 ldns_rdf_get_type(addr) != LDNS_RDF_TYPE_AAAA) {
122 return NULL;
123 }
124
125 name = ldns_rdf_address_reverse(addr);
126
127 /* add the RD flags, because we want an answer */
128 pkt = ldns_resolver_query(res, name, LDNS_RR_TYPE_PTR, c, flags | LDNS_RD);
129 ldns_rdf_deep_free(name);
130 if (pkt) {
131 /* extract the data we need */
132 names = ldns_pkt_rr_list_by_type(pkt,
133 LDNS_RR_TYPE_PTR, LDNS_SECTION_ANSWER);
134 ldns_pkt_free(pkt);
135 }
136 return names;
137 }
138
139 /* read a line, put it in a buffer, parse the buffer */
140 ldns_rr_list *
141 ldns_get_rr_list_hosts_frm_fp(FILE *fp)
142 {
143 return ldns_get_rr_list_hosts_frm_fp_l(fp, NULL);
144 }
145
146 ldns_rr_list *
147 ldns_get_rr_list_hosts_frm_fp_l(FILE *fp, int *line_nr)
148 {
149 ssize_t i, j;
150 size_t cnt;
151 char *line;
152 char *word;
153 char *addr;
154 char *rr_str;
155 ldns_buffer *linebuf;
156 ldns_rr *rr;
157 ldns_rr_list *list;
158 ldns_rdf *tmp;
159 bool ip6;
160 ldns_status parse_result;
161
162 line = LDNS_XMALLOC(char, LDNS_MAX_LINELEN + 1);
163 word = LDNS_XMALLOC(char, LDNS_MAX_LINELEN + 1);
164 addr = LDNS_XMALLOC(char, LDNS_MAX_LINELEN + 1);
165 rr_str = LDNS_XMALLOC(char, LDNS_MAX_LINELEN + 1);
166 ip6 = false;
167 list = ldns_rr_list_new();
168 rr = NULL;
169 if(!line || !word || !addr || !rr_str || !list) {
170 LDNS_FREE(line);
171 LDNS_FREE(word);
172 LDNS_FREE(addr);
173 LDNS_FREE(rr_str);
174 ldns_rr_list_free(list);
175 return NULL;
176 }
177
178 for(i = ldns_fget_token_l(fp, line, "\n", LDNS_MAX_LINELEN, line_nr);
179 i > 0; i = ldns_fget_token_l(fp, line, "\n", LDNS_MAX_LINELEN, line_nr)) {
180 /* # is comment */
181 if (line[0] == '#') {
182 continue;
183 }
184 /* put it in a buffer for further processing */
185 linebuf = LDNS_MALLOC(ldns_buffer);
186 if(!linebuf) {
187 LDNS_FREE(line);
188 LDNS_FREE(word);
189 LDNS_FREE(addr);
190 LDNS_FREE(rr_str);
191 ldns_rr_list_deep_free(list);
192 return NULL;
193 }
194
195 ldns_buffer_new_frm_data(linebuf, line, (size_t) i);
196 for(cnt = 0, j = ldns_bget_token(linebuf, word, LDNS_PARSE_NO_NL, LDNS_MAX_LINELEN);
197 j > 0;
198 j = ldns_bget_token(linebuf, word, LDNS_PARSE_NO_NL, LDNS_MAX_LINELEN), cnt++) {
199 if (cnt == 0) {
200 /* the address */
201 if ((tmp = ldns_rdf_new_frm_str(LDNS_RDF_TYPE_AAAA,
202 word))) {
203 /* ip6 */
204 ldns_rdf_deep_free(tmp);
205 ip6 = true;
206 } else {
207 if ((tmp = ldns_rdf_new_frm_str(LDNS_RDF_TYPE_A,
208 word))) {
209 /* ip4 */
210 ldns_rdf_deep_free(tmp);
211 ip6 = false;
212 } else {
213 /* kaput */
214 break;
215 }
216 }
217 (void)strlcpy(addr, word, LDNS_MAX_LINELEN+1);
218 } else {
219 /* la al la la */
220 if (ip6) {
221 snprintf(rr_str, LDNS_MAX_LINELEN,
222 "%s IN AAAA %s", word, addr);
223 } else {
224 snprintf(rr_str, LDNS_MAX_LINELEN,
225 "%s IN A %s", word, addr);
226 }
227 parse_result = ldns_rr_new_frm_str(&rr, rr_str, 0, NULL, NULL);
228 if (parse_result == LDNS_STATUS_OK && ldns_rr_owner(rr) && ldns_rr_rd_count(rr) > 0) {
229 ldns_rr_list_push_rr(list, ldns_rr_clone(rr));
230 }
231 ldns_rr_free(rr);
232 }
233 }
234 ldns_buffer_free(linebuf);
235 }
236 LDNS_FREE(line);
237 LDNS_FREE(word);
238 LDNS_FREE(addr);
239 LDNS_FREE(rr_str);
240 return list;
241 }
242
243 ldns_rr_list *
244 ldns_get_rr_list_hosts_frm_file(char *filename)
245 {
246 ldns_rr_list *names;
247 FILE *fp;
248
249 if (!filename) {
250 fp = fopen(LDNS_RESOLV_HOSTS, "r");
251
252 } else {
253 fp = fopen(filename, "r");
254 }
255 if (!fp) {
256 return NULL;
257 }
258
259 names = ldns_get_rr_list_hosts_frm_fp(fp);
260 fclose(fp);
261 return names;
262 }
263
264 uint16_t
265 ldns_getaddrinfo(ldns_resolver *res, ldns_rdf *node, ldns_rr_class c,
266 ldns_rr_list **ret)
267 {
268 ldns_rdf_type t;
269 uint16_t names_found;
270 ldns_resolver *r;
271 ldns_status s;
272
273 t = ldns_rdf_get_type(node);
274 names_found = 0;
275 r = res;
276
277 if (res == NULL) {
278 /* prepare a new resolver, using /etc/resolv.conf as a guide */
279 s = ldns_resolver_new_frm_file(&r, NULL);
280 if (s != LDNS_STATUS_OK) {
281 return 0;
282 }
283 }
284
285 if (t == LDNS_RDF_TYPE_DNAME) {
286 /* we're asked to query for a name */
287 *ret = ldns_get_rr_list_addr_by_name(r, node, c, 0);
288 names_found = ldns_rr_list_rr_count(*ret);
289 }
290
291 if (t == LDNS_RDF_TYPE_A || t == LDNS_RDF_TYPE_AAAA) {
292 /* an address */
293 *ret = ldns_get_rr_list_name_by_addr(r, node, c, 0);
294 names_found = ldns_rr_list_rr_count(*ret);
295 }
296
297 if (res == NULL) {
298 ldns_resolver_deep_free(r);
299 }
300
301 return names_found;
302 }
303
304 bool
305 ldns_nsec_type_check(ldns_rr *nsec, ldns_rr_type t)
306 {
307 switch (ldns_rr_get_type(nsec)) {
308 case LDNS_RR_TYPE_NSEC : if (ldns_rr_rd_count(nsec) < 2) {
309 return false;
310 }
311 return ldns_nsec_bitmap_covers_type(
312 ldns_rr_rdf(nsec, 1), t);
313
314 case LDNS_RR_TYPE_NSEC3 : if (ldns_rr_rd_count(nsec) < 6) {
315 return false;
316 }
317 return ldns_nsec_bitmap_covers_type(
318 ldns_rr_rdf(nsec, 5), t);
319
320 default : return false;
321 }
322 }
323
324 void
325 ldns_print_rr_rdf(FILE *fp, ldns_rr *r, int rdfnum, ...)
326 {
327 int16_t rdf;
328 ldns_rdf *rd;
329 va_list va_rdf;
330 va_start(va_rdf, rdfnum);
331
332 for (rdf = (int16_t)rdfnum; rdf != -1; rdf = (int16_t)va_arg(va_rdf, int))
333 {
334 rd = ldns_rr_rdf(r, rdf);
335 if (!rd) {
336 continue;
337 } else {
338 ldns_rdf_print(fp, rd);
339 fprintf(fp, " "); /* not sure if we want to do this */
340 }
341 }
342 va_end(va_rdf);
343 }
344
ldns_rr_rdf
ldns_rdf * ldns_rr_rdf(const ldns_rr *rr, size_t nr)
returns the rdata field member counter.
Definition: rr.c:873
ldns_resolver_ip6
uint8_t ldns_resolver_ip6(const ldns_resolver *r)
Does the resolver use ip6 or ip4.
Definition: resolver.c:60
ldns_struct_buffer
implementation of buffers to ease operations
Definition: buffer.h:50
ldns_get_rr_list_hosts_frm_file
ldns_rr_list * ldns_get_rr_list_hosts_frm_file(char *filename)
wade through fp (a /etc/hosts like file) and return a rr_list containing all the defined hosts in the...
Definition: higher.c:244
ldns_rr_clone
ldns_rr * ldns_rr_clone(const ldns_rr *rr)
clones a rr and all its data
Definition: rr.c:1363
ldns_rdf_deep_free
void ldns_rdf_deep_free(ldns_rdf *rd)
frees a rdf structure and frees the data.
Definition: rdata.c:230
LDNS_SECTION_ANSWER
Definition: packet.h:274
LDNS_RR_TYPE_A
a host address
Definition: rr.h:83
ldns_get_rr_list_hosts_frm_fp
ldns_rr_list * ldns_get_rr_list_hosts_frm_fp(FILE *fp)
wade through fp (a /etc/hosts like file) and return a rr_list containing all the defined hosts in the...
Definition: higher.c:141
strlcpy
size_t strlcpy(char *dst, const char *src, size_t siz)
LDNS_PARSE_NO_NL
#define LDNS_PARSE_NO_NL
Definition: parse.h:22
ldns_struct_resolver
DNS stub resolver structure.
Definition: resolver.h:59
ldns_rr_class
enum ldns_enum_rr_class ldns_rr_class
Definition: rr.h:64
ldns_rr_list_push_rr
bool ldns_rr_list_push_rr(ldns_rr_list *rr_list, const ldns_rr *rr)
pushes an rr to an rrlist.
Definition: rr.c:1096
ldns_resolver_query
ldns_pkt * ldns_resolver_query(const ldns_resolver *r, const ldns_rdf *name, ldns_rr_type t, ldns_rr_class c, uint16_t flags)
Send a query to a nameserver.
Definition: resolver.c:1057
ldns_struct_rr_list
List or Set of Resource Records.
Definition: rr.h:327
ldns_resolver_deep_free
void ldns_resolver_deep_free(ldns_resolver *res)
Frees the allocated space for this resolver and all it&#39;s data.
Definition: resolver.c:945
LDNS_STATUS_OK
Definition: error.h:26
LDNS_RD
#define LDNS_RD
Definition: packet.h:30
ldns_rdf_address_reverse
ldns_rdf * ldns_rdf_address_reverse(ldns_rdf *rd)
reverses an rdf, only actually useful for AAAA and A records.
Definition: rdata.c:404
LDNS_XMALLOC
#define LDNS_XMALLOC(type, count)
Definition: util.h:51
ldns_rr_list_deep_free
void ldns_rr_list_deep_free(ldns_rr_list *rr_list)
frees an rr_list structure and all rrs contained therein.
Definition: rr.c:984
ldns_buffer_free
void ldns_buffer_free(ldns_buffer *buffer)
frees the buffer.
Definition: buffer.c:137
ldns_rr_rd_count
size_t ldns_rr_rd_count(const ldns_rr *rr)
returns the rd_count of an rr structure.
Definition: rr.c:901
ldns_rr_free
void ldns_rr_free(ldns_rr *rr)
frees an RR structure
Definition: rr.c:75
ldns_bget_token
ssize_t ldns_bget_token(ldns_buffer *b, char *token, const char *delim, size_t limit)
returns a token/char from the buffer b.
Definition: parse.c:217
LDNS_RESOLV_HOSTS
#define LDNS_RESOLV_HOSTS
Default location of the hosts file.
Definition: resolver.h:38
ldns_get_rr_list_hosts_frm_fp_l
ldns_rr_list * ldns_get_rr_list_hosts_frm_fp_l(FILE *fp, int *line_nr)
wade through fp (a /etc/hosts like file) and return a rr_list containing all the defined hosts in the...
Definition: higher.c:147
ldns_rr_list_free
void ldns_rr_list_free(ldns_rr_list *rr_list)
frees an rr_list structure.
Definition: rr.c:975
ldns_pkt_rr_list_by_type
ldns_rr_list * ldns_pkt_rr_list_by_type(const ldns_pkt *packet, ldns_rr_type type, ldns_pkt_section sec)
return all the rr with a specific type from a packet.
Definition: packet.c:284
ldns_struct_rr
Resource Record.
Definition: rr.h:299
ldns_print_rr_rdf
void ldns_print_rr_rdf(FILE *fp, ldns_rr *r, int rdfnum,...)
Print a number of rdf&#39;s of the RR.
Definition: higher.c:325
ldns_rr_new_frm_str
ldns_status ldns_rr_new_frm_str(ldns_rr **newrr, const char *str, uint32_t default_ttl, ldns_rdf *origin, ldns_rdf **prev)
creates an rr from a string.
Definition: rr.c:649
ldns.h
Including this file will include all ldns files, and define some lookup tables.
LDNS_RR_TYPE_AAAA
ipv6 address
Definition: rr.h:137
ldns_rr_list_rr
ldns_rr * ldns_rr_list_rr(const ldns_rr_list *rr_list, size_t nr)
returns a specific rr of an rrlist.
Definition: rr.c:954
ldns_get_rr_list_name_by_addr
ldns_rr_list * ldns_get_rr_list_name_by_addr(ldns_resolver *res, ldns_rdf *addr, ldns_rr_class c, uint16_t flags)
ask the resolver about the address and return the name
Definition: higher.c:107
ldns_rdf_type
enum ldns_enum_rdf_type ldns_rdf_type
Definition: rdata.h:137
LDNS_RDF_TYPE_A
A record.
Definition: rdata.h:58
ldns_rr_list_new
ldns_rr_list * ldns_rr_list_new(void)
creates a new rr_list structure.
Definition: rr.c:964
LDNS_RDF_TYPE_AAAA
AAAA record.
Definition: rdata.h:60
ldns_rdf_new_frm_str
ldns_rdf * ldns_rdf_new_frm_str(ldns_rdf_type type, const char *str)
creates a new rdf from a string.
Definition: rdata.c:249
LDNS_RR_TYPE_NSEC
Definition: rr.h:174
ldns_rr_list_clone
ldns_rr_list * ldns_rr_list_clone(const ldns_rr_list *rrlist)
clones an rrlist.
Definition: rr.c:1394
ldns_nsec_bitmap_covers_type
bool ldns_nsec_bitmap_covers_type(const ldns_rdf *bitmap, ldns_rr_type type)
Check if RR type t is enumerated and set in the RR type bitmap rdf.
Definition: dnssec.c:1357
ldns_fget_token_l
ssize_t ldns_fget_token_l(FILE *f, char *token, const char *delim, size_t limit, int *line_nr)
returns a token/char from the stream F.
Definition: parse.c:31
ldns_rr_list_cat_clone
ldns_rr_list * ldns_rr_list_cat_clone(ldns_rr_list *left, ldns_rr_list *right)
concatenates two ldns_rr_lists together, but makes clones of the rr&#39;s (instead of pointer copying)...
Definition: rr.c:1023
ldns_rdf_get_type
ldns_rdf_type ldns_rdf_get_type(const ldns_rdf *rd)
returns the type of the rdf.
Definition: rdata.c:31
ldns_struct_pkt
DNS packet.
Definition: packet.h:233
LDNS_RR_TYPE_PTR
a domain name pointer
Definition: rr.h:105
ldns_rdf_print
void ldns_rdf_print(FILE *output, const ldns_rdf *rdf)
Prints the data in the rdata field to the given file stream (in presentation format) ...
Definition: host2str.c:2489
ldns_rr_get_type
ldns_rr_type ldns_rr_get_type(const ldns_rr *rr)
returns the type of the rr.
Definition: rr.c:907
LDNS_RR_TYPE_NSEC3
Definition: rr.h:179
ldns_status
enum ldns_enum_status ldns_status
Definition: error.h:131
ldns_resolver_new_frm_file
ldns_status ldns_resolver_new_frm_file(ldns_resolver **res, const char *filename)
Configure a resolver by means of a resolv.conf file The file may be NULL in which case there will be ...
Definition: resolver.c:908
LDNS_MALLOC
#define LDNS_MALLOC(type)
Memory management macros.
Definition: util.h:49
ldns_nsec_type_check
bool ldns_nsec_type_check(ldns_rr *nsec, ldns_rr_type t)
Check if t is enumerated in the nsec type rdata.
Definition: higher.c:305
ldns_getaddrinfo
uint16_t ldns_getaddrinfo(ldns_resolver *res, ldns_rdf *node, ldns_rr_class c, ldns_rr_list **ret)
This function is a wrapper function for ldns_get_rr_list_name_by_addr and ldns_get_rr_list_addr_by_na...
Definition: higher.c:265
LDNS_MAX_LINELEN
#define LDNS_MAX_LINELEN
Definition: parse.h:23
ldns_struct_rdf
Resource record data field.
Definition: rdata.h:166
ldns_rr_owner
ldns_rdf * ldns_rr_owner(const ldns_rr *rr)
returns the owner name of an rr structure.
Definition: rr.c:883
LDNS_RESOLV_INETANY
#define LDNS_RESOLV_INETANY
Definition: resolver.h:49
ldns_rr_list_rr_count
size_t ldns_rr_list_rr_count(const ldns_rr_list *rr_list)
returns the number of rr&#39;s in an rr_list.
Definition: rr.c:921
ldns_rr_type
enum ldns_enum_rr_type ldns_rr_type
Definition: rr.h:236
LDNS_FREE
#define LDNS_FREE(ptr)
Definition: util.h:60
ldns_resolver_set_ip6
void ldns_resolver_set_ip6(ldns_resolver *r, uint8_t ip6)
Whether the resolver uses ip6.
Definition: resolver.c:440
LDNS_RDF_TYPE_DNAME
domain name
Definition: rdata.h:50
ldns_buffer_new_frm_data
void ldns_buffer_new_frm_data(ldns_buffer *buffer, void *data, size_t size)
creates a buffer with the specified data.
Definition: buffer.c:41
ldns_pkt_free
void ldns_pkt_free(ldns_pkt *packet)
frees the packet structure and all data that it contains.
Definition: packet.c:784
ldns_get_rr_list_addr_by_name
ldns_rr_list * ldns_get_rr_list_addr_by_name(ldns_resolver *res, ldns_rdf *name, ldns_rr_class c, uint16_t flags)
Ask the resolver about name and return all address records.
Definition: higher.c:24
ldns_rdf_compare
int ldns_rdf_compare(const ldns_rdf *rd1, const ldns_rdf *rd2)
compares two rdf&#39;s on their wire formats.
Definition: rdata.c:642
config.h