higher.c
Go to the documentation of this file.
1 /*
2  * higher.c
3  *
4  * Specify some higher level functions that would
5  * be useful 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 
25  ldns_rr_class c, 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  }
43  return NULL;
44  }
45 
46  ip6 = ldns_resolver_ip6(res); /* we use INET_ANY here, save
47  what was there */
48 
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 */
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 */
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);
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 
103  return result;
104 }
105 
106 ldns_rr_list *
108  ldns_rr_class c, 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 &&
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,
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 *
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);
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 */
202  word))) {
203  /* ip6 */
204  ldns_rdf_deep_free(tmp);
205  ip6 = true;
206  } else {
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  /* Stop parsing line when a comment begins. */
220  if (word[0] == '#')
221  break;
222  /* la al la la */
223  if (ip6) {
224  snprintf(rr_str, LDNS_MAX_LINELEN,
225  "%s IN AAAA %s", word, addr);
226  } else {
227  snprintf(rr_str, LDNS_MAX_LINELEN,
228  "%s IN A %s", word, addr);
229  }
230  parse_result = ldns_rr_new_frm_str(&rr, rr_str, 0, NULL, NULL);
231  if (parse_result == LDNS_STATUS_OK && ldns_rr_owner(rr) && ldns_rr_rd_count(rr) > 0) {
233  ldns_rr_free(rr);
234  }
235  }
236  }
237  ldns_buffer_free(linebuf);
238  }
239  LDNS_FREE(line);
240  LDNS_FREE(word);
241  LDNS_FREE(addr);
242  LDNS_FREE(rr_str);
243  return list;
244 }
245 
246 ldns_rr_list *
248 {
249  ldns_rr_list *names;
250  FILE *fp;
251 
252  if (!filename) {
253  fp = fopen(LDNS_RESOLV_HOSTS, "r");
254 
255  } else {
256  fp = fopen(filename, "r");
257  }
258  if (!fp) {
259  return NULL;
260  }
261 
262  names = ldns_get_rr_list_hosts_frm_fp(fp);
263  fclose(fp);
264  return names;
265 }
266 
267 uint16_t
269  ldns_rr_class c, ldns_rr_list **ret)
270 {
271  ldns_rdf_type t;
272  uint16_t names_found;
273  ldns_resolver *r;
274  ldns_status s;
275 
276  t = ldns_rdf_get_type(node);
277  names_found = 0;
278  r = res;
279 
280  if (res == NULL) {
281  /* prepare a new resolver, using /etc/resolv.conf as a guide */
282  s = ldns_resolver_new_frm_file(&r, NULL);
283  if (s != LDNS_STATUS_OK) {
284  return 0;
285  }
286  }
287 
288  if (t == LDNS_RDF_TYPE_DNAME) {
289  /* we're asked to query for a name */
290  *ret = ldns_get_rr_list_addr_by_name(r, node, c, 0);
291  names_found = ldns_rr_list_rr_count(*ret);
292  }
293 
294  if (t == LDNS_RDF_TYPE_A || t == LDNS_RDF_TYPE_AAAA) {
295  /* an address */
296  *ret = ldns_get_rr_list_name_by_addr(r, node, c, 0);
297  names_found = ldns_rr_list_rr_count(*ret);
298  }
299 
300  if (res == NULL) {
302  }
303 
304  return names_found;
305 }
306 
307 bool
309 {
310  switch (ldns_rr_get_type(nsec)) {
311  case LDNS_RR_TYPE_NSEC : if (ldns_rr_rd_count(nsec) < 2) {
312  return false;
313  }
315  ldns_rr_rdf(nsec, 1), t);
316 
317  case LDNS_RR_TYPE_NSEC3 : if (ldns_rr_rd_count(nsec) < 6) {
318  return false;
319  }
321  ldns_rr_rdf(nsec, 5), t);
322 
323  default : return false;
324  }
325 }
326 
327 void
328 ldns_print_rr_rdf(FILE *fp, ldns_rr *r, int rdfnum, ...)
329 {
330  int16_t rdf;
331  ldns_rdf *rd;
332  va_list va_rdf;
333  va_start(va_rdf, rdfnum);
334 
335  for (rdf = (int16_t)rdfnum; rdf != -1; rdf = (int16_t)va_arg(va_rdf, int))
336  {
337  rd = ldns_rr_rdf(r, rdf);
338  if (!rd) {
339  continue;
340  } else {
341  ldns_rdf_print(fp, rd);
342  fprintf(fp, " "); /* not sure if we want to do this */
343  }
344  }
345  va_end(va_rdf);
346 }
347 
void ldns_buffer_free(ldns_buffer *buffer)
frees the buffer.
Definition: buffer.c:137
void ldns_buffer_new_frm_data(ldns_buffer *buffer, const void *data, size_t size)
creates a buffer with the specified data.
Definition: buffer.c:41
size_t strlcpy(char *dst, const char *src, size_t siz)
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:1393
@ LDNS_STATUS_OK
Definition: error.h:26
enum ldns_enum_status ldns_status
Definition: error.h:146
ldns_rr_list * ldns_get_rr_list_name_by_addr(ldns_resolver *res, const ldns_rdf *addr, ldns_rr_class c, uint16_t flags)
ask the resolver about the address and return the name
Definition: higher.c:107
void ldns_print_rr_rdf(FILE *fp, ldns_rr *r, int rdfnum,...)
Print a number of rdf's of the RR.
Definition: higher.c:328
uint16_t ldns_getaddrinfo(ldns_resolver *res, const 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:268
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:247
bool ldns_nsec_type_check(const ldns_rr *nsec, ldns_rr_type t)
Check if t is enumerated in the nsec type rdata.
Definition: higher.c:308
ldns_rr_list * ldns_get_rr_list_addr_by_name(ldns_resolver *res, const 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_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 * 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
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:3386
Including this file will include all ldns files, and define some lookup tables.
void ldns_pkt_free(ldns_pkt *packet)
frees the packet structure and all data that it contains.
Definition: packet.c:895
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:304
@ LDNS_SECTION_ANSWER
Definition: packet.h:279
#define LDNS_RD
Definition: packet.h:30
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:220
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:274
#define LDNS_MAX_LINELEN
Definition: parse.h:23
#define LDNS_PARSE_NO_NL
Definition: parse.h:22
ldns_rdf_type ldns_rdf_get_type(const ldns_rdf *rd)
returns the type of the rdf.
Definition: rdata.c:31
void ldns_rdf_deep_free(ldns_rdf *rd)
frees a rdf structure and frees the data.
Definition: rdata.c:230
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_rdf * ldns_rdf_address_reverse(const ldns_rdf *rd)
reverses an rdf, only actually useful for AAAA and A records.
Definition: rdata.c:419
int ldns_rdf_compare(const ldns_rdf *rd1, const ldns_rdf *rd2)
compares two rdf's on their wire formats.
Definition: rdata.c:657
@ LDNS_RDF_TYPE_AAAA
AAAA record.
Definition: rdata.h:60
@ LDNS_RDF_TYPE_DNAME
domain name
Definition: rdata.h:50
@ LDNS_RDF_TYPE_A
A record.
Definition: rdata.h:58
enum ldns_enum_rdf_type ldns_rdf_type
Definition: rdata.h:151
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:1164
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:1002
uint8_t ldns_resolver_ip6(const ldns_resolver *r)
Does the resolver use ip6 or ip4.
Definition: resolver.c:60
void ldns_resolver_set_ip6(ldns_resolver *r, uint8_t ip6)
Whether the resolver uses ip6.
Definition: resolver.c:440
void ldns_resolver_deep_free(ldns_resolver *res)
Frees the allocated space for this resolver and all it's data.
Definition: resolver.c:1039
#define LDNS_RESOLV_INETANY
Definition: resolver.h:49
#define LDNS_RESOLV_HOSTS
Default location of the hosts file.
Definition: resolver.h:38
void ldns_rr_list_free(ldns_rr_list *rr_list)
frees an rr_list structure.
Definition: rr.c:1011
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:990
ldns_status ldns_rr_new_frm_str(ldns_rr **newrr, const char *str, uint32_t default_ttl, const ldns_rdf *origin, ldns_rdf **prev)
creates an rr from a string.
Definition: rr.c:676
ldns_rdf * ldns_rr_owner(const ldns_rr *rr)
returns the owner name of an rr structure.
Definition: rr.c:919
void ldns_rr_list_deep_free(ldns_rr_list *rr_list)
frees an rr_list structure and all rrs contained therein.
Definition: rr.c:1020
void ldns_rr_free(ldns_rr *rr)
frees an RR structure
Definition: rr.c:81
size_t ldns_rr_rd_count(const ldns_rr *rr)
returns the rd_count of an rr structure.
Definition: rr.c:937
size_t ldns_rr_list_rr_count(const ldns_rr_list *rr_list)
returns the number of rr's in an rr_list.
Definition: rr.c:957
ldns_rr_type ldns_rr_get_type(const ldns_rr *rr)
returns the type of the rr.
Definition: rr.c:943
bool ldns_rr_list_push_rr(ldns_rr_list *rr_list, const ldns_rr *rr)
pushes an rr to an rrlist.
Definition: rr.c:1132
ldns_rr_list * ldns_rr_list_cat_clone(const ldns_rr_list *left, const ldns_rr_list *right)
concatenates two ldns_rr_lists together, but makes clones of the rr's (instead of pointer copying).
Definition: rr.c:1059
ldns_rr_list * ldns_rr_list_new(void)
creates a new rr_list structure.
Definition: rr.c:1000
ldns_rr * ldns_rr_clone(const ldns_rr *rr)
clones a rr and all its data
Definition: rr.c:1400
ldns_rr_list * ldns_rr_list_clone(const ldns_rr_list *rrlist)
clones an rrlist.
Definition: rr.c:1431
ldns_rdf * ldns_rr_rdf(const ldns_rr *rr, size_t nr)
returns the rdata field member counter.
Definition: rr.c:909
enum ldns_enum_rr_type ldns_rr_type
Definition: rr.h:243
@ LDNS_RR_TYPE_A
a host address
Definition: rr.h:80
@ LDNS_RR_TYPE_NSEC
Definition: rr.h:171
@ LDNS_RR_TYPE_NSEC3
Definition: rr.h:176
@ LDNS_RR_TYPE_PTR
a domain name pointer
Definition: rr.h:102
@ LDNS_RR_TYPE_AAAA
ipv6 address
Definition: rr.h:134
enum ldns_enum_rr_class ldns_rr_class
Definition: rr.h:61
implementation of buffers to ease operations
Definition: buffer.h:51
DNS packet.
Definition: packet.h:235
Resource record data field.
Definition: rdata.h:197
DNS stub resolver structure.
Definition: resolver.h:60
List or Set of Resource Records.
Definition: rr.h:338
Resource Record.
Definition: rr.h:310
#define LDNS_FREE(ptr)
Definition: util.h:60
#define LDNS_MALLOC(type)
Memory management macros.
Definition: util.h:49
#define LDNS_XMALLOC(type, count)
Definition: util.h:51