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 
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  }
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  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  }
135  return names;
136 }
137 
138 /* read a line, put it in a buffer, parse the buffer */
139 ldns_rr_list *
141 {
142  return ldns_get_rr_list_hosts_frm_fp_l(fp, NULL);
143 }
144 
145 ldns_rr_list *
146 ldns_get_rr_list_hosts_frm_fp_l(FILE *fp, int *line_nr)
147 {
148  ssize_t i, j;
149  size_t cnt;
150  char *line;
151  char *word;
152  char *addr;
153  char *rr_str;
154  ldns_buffer *linebuf;
155  ldns_rr *rr;
156  ldns_rr_list *list;
157  ldns_rdf *tmp;
158  bool ip6;
159  ldns_status parse_result;
160 
161  line = LDNS_XMALLOC(char, LDNS_MAX_LINELEN + 1);
162  word = LDNS_XMALLOC(char, LDNS_MAX_LINELEN + 1);
163  addr = LDNS_XMALLOC(char, LDNS_MAX_LINELEN + 1);
164  rr_str = LDNS_XMALLOC(char, LDNS_MAX_LINELEN + 1);
165  ip6 = false;
166  list = ldns_rr_list_new();
167  rr = NULL;
168  if(!line || !word || !addr || !rr_str || !list) {
169  LDNS_FREE(line);
170  LDNS_FREE(word);
171  LDNS_FREE(addr);
172  LDNS_FREE(rr_str);
173  ldns_rr_list_free(list);
174  return NULL;
175  }
176 
177  for(i = ldns_fget_token_l(fp, line, "\n", LDNS_MAX_LINELEN, line_nr);
178  i > 0; i = ldns_fget_token_l(fp, line, "\n", LDNS_MAX_LINELEN, line_nr)) {
179  /* # is comment */
180  if (line[0] == '#') {
181  continue;
182  }
183  /* put it in a buffer for further processing */
184  linebuf = LDNS_MALLOC(ldns_buffer);
185  if(!linebuf) {
186  LDNS_FREE(line);
187  LDNS_FREE(word);
188  LDNS_FREE(addr);
189  LDNS_FREE(rr_str);
191  return NULL;
192  }
193 
194  ldns_buffer_new_frm_data(linebuf, line, (size_t) i);
195  for(cnt = 0, j = ldns_bget_token(linebuf, word, LDNS_PARSE_NO_NL, LDNS_MAX_LINELEN);
196  j > 0;
197  j = ldns_bget_token(linebuf, word, LDNS_PARSE_NO_NL, LDNS_MAX_LINELEN), cnt++) {
198  if (cnt == 0) {
199  /* the address */
201  word))) {
202  /* ip6 */
203  ldns_rdf_deep_free(tmp);
204  ip6 = true;
205  } else {
207  word))) {
208  /* ip4 */
209  ldns_rdf_deep_free(tmp);
210  ip6 = false;
211  } else {
212  /* kaput */
213  break;
214  }
215  }
216  (void)strlcpy(addr, word, LDNS_MAX_LINELEN+1);
217  } else {
218  /* la al la la */
219  if (ip6) {
220  snprintf(rr_str, LDNS_MAX_LINELEN,
221  "%s IN AAAA %s", word, addr);
222  } else {
223  snprintf(rr_str, LDNS_MAX_LINELEN,
224  "%s IN A %s", word, addr);
225  }
226  parse_result = ldns_rr_new_frm_str(&rr, rr_str, 0, NULL, NULL);
227  if (parse_result == LDNS_STATUS_OK && ldns_rr_owner(rr) && ldns_rr_rd_count(rr) > 0) {
229  }
230  ldns_rr_free(rr);
231  }
232  }
233  ldns_buffer_free(linebuf);
234  }
235  LDNS_FREE(line);
236  LDNS_FREE(word);
237  LDNS_FREE(addr);
238  LDNS_FREE(rr_str);
239  return list;
240 }
241 
242 ldns_rr_list *
244 {
245  ldns_rr_list *names;
246  FILE *fp;
247 
248  if (!filename) {
249  fp = fopen(LDNS_RESOLV_HOSTS, "r");
250 
251  } else {
252  fp = fopen(filename, "r");
253  }
254  if (!fp) {
255  return NULL;
256  }
257 
258  names = ldns_get_rr_list_hosts_frm_fp(fp);
259  fclose(fp);
260  return names;
261 }
262 
263 uint16_t
265  ldns_rr_list **ret)
266 {
267  ldns_rdf_type t;
268  uint16_t names_found;
269  ldns_resolver *r;
270  ldns_status s;
271 
272  t = ldns_rdf_get_type(node);
273  names_found = 0;
274  r = res;
275 
276  if (res == NULL) {
277  /* prepare a new resolver, using /etc/resolv.conf as a guide */
278  s = ldns_resolver_new_frm_file(&r, NULL);
279  if (s != LDNS_STATUS_OK) {
280  return 0;
281  }
282  }
283 
284  if (t == LDNS_RDF_TYPE_DNAME) {
285  /* we're asked to query for a name */
286  *ret = ldns_get_rr_list_addr_by_name(r, node, c, 0);
287  names_found = ldns_rr_list_rr_count(*ret);
288  }
289 
290  if (t == LDNS_RDF_TYPE_A || t == LDNS_RDF_TYPE_AAAA) {
291  /* an address */
292  *ret = ldns_get_rr_list_name_by_addr(r, node, c, 0);
293  names_found = ldns_rr_list_rr_count(*ret);
294  }
295 
296  if (res == NULL) {
298  }
299 
300  return names_found;
301 }
302 
303 bool
305 {
306  /* does the nsec cover the t given? */
307  /* copied from host2str.c line 465: ldns_rdf2buffer_str_nsec */
308  uint8_t window_block_nr;
309  uint8_t bitmap_length;
310  uint16_t type;
311  uint16_t pos = 0;
312  uint16_t bit_pos;
313  ldns_rdf *nsec_type_list = ldns_rr_rdf(nsec, 1);
314  uint8_t *data;
315 
316  if (nsec_type_list == NULL) {
317  return false;
318  }
319  data = ldns_rdf_data(nsec_type_list);
320 
321  while(pos < ldns_rdf_size(nsec_type_list)) {
322  window_block_nr = data[pos];
323  bitmap_length = data[pos + 1];
324  pos += 2;
325 
326  for (bit_pos = 0; bit_pos < (bitmap_length) * 8; bit_pos++) {
327  if (ldns_get_bit(&data[pos], bit_pos)) {
328  type = 256 * (uint16_t) window_block_nr + bit_pos;
329 
330  if ((ldns_rr_type)type == t) {
331  /* we have a winner */
332  return true;
333  }
334  }
335  }
336  pos += (uint16_t) bitmap_length;
337  }
338  return false;
339 }
340 
341 void
342 ldns_print_rr_rdf(FILE *fp, ldns_rr *r, int rdfnum, ...)
343 {
344  int16_t rdf;
345  ldns_rdf *rd;
346  va_list va_rdf;
347  va_start(va_rdf, rdfnum);
348 
349  for (rdf = (int16_t)rdfnum; rdf != -1; rdf = (int16_t)va_arg(va_rdf, int))
350  {
351  rd = ldns_rr_rdf(r, rdf);
352  if (!rd) {
353  continue;
354  } else {
355  ldns_rdf_print(fp, rd);
356  fprintf(fp, " "); /* not sure if we want to do this */
357  }
358  }
359  va_end(va_rdf);
360 }