File Coverage

src/ldns/higher.c
Criterion Covered Total %
statement 87 158 55.0
branch 36 88 40.9
condition n/a
subroutine n/a
pod n/a
total 123 246 50.0


line stmt bran cond sub pod time code
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
15              
16             #include
17              
18             #ifdef HAVE_SSL
19             #include
20             #include
21             #endif /* HAVE_SSL */
22              
23             ldns_rr_list *
24 2           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 2           ldns_rr_list *result = NULL;
31             ldns_rr_list *hostsfilenames;
32             size_t i;
33             uint8_t ip6;
34              
35 2           a = NULL;
36 2           aaaa = NULL;
37 2           result = NULL;
38              
39 2 50         if (!res) {
40 0           return NULL;
41             }
42 2 50         if (ldns_rdf_get_type(name) != LDNS_RDF_TYPE_DNAME) {
43 0           return NULL;
44             }
45              
46 2           ip6 = ldns_resolver_ip6(res); /* we use INET_ANY here, save
47             what was there */
48              
49 2           ldns_resolver_set_ip6(res, LDNS_RESOLV_INETANY);
50            
51 2           hostsfilenames = ldns_get_rr_list_hosts_frm_file(NULL);
52 20 100         for (i = 0; i < ldns_rr_list_rr_count(hostsfilenames); i++) {
53 18 50         if (ldns_rdf_compare(name,
54 18           ldns_rr_owner(ldns_rr_list_rr(hostsfilenames,
55             i))) == 0) {
56 0 0         if (!result) {
57 0           result = ldns_rr_list_new();
58             }
59 0           ldns_rr_list_push_rr(result,
60 0           ldns_rr_clone(ldns_rr_list_rr(hostsfilenames, i)));
61             }
62             }
63 2           ldns_rr_list_deep_free(hostsfilenames);
64              
65 2 50         if (result) {
66 0           return result;
67             }
68              
69             /* add the RD flags, because we want an answer */
70 2           pkt = ldns_resolver_query(res, name, LDNS_RR_TYPE_AAAA, c, flags | LDNS_RD);
71 2 50         if (pkt) {
72             /* extract the data we need */
73 2           aaaa = ldns_pkt_rr_list_by_type(pkt, LDNS_RR_TYPE_AAAA,
74             LDNS_SECTION_ANSWER);
75 2           ldns_pkt_free(pkt);
76             }
77              
78 2           pkt = ldns_resolver_query(res, name, LDNS_RR_TYPE_A, c, flags | LDNS_RD);
79 2 50         if (pkt) {
80             /* extract the data we need */
81 2           a = ldns_pkt_rr_list_by_type(pkt, LDNS_RR_TYPE_A, LDNS_SECTION_ANSWER);
82 2           ldns_pkt_free(pkt);
83             }
84 2           ldns_resolver_set_ip6(res, ip6);
85              
86 2 50         if (aaaa && a) {
    50          
87 2           result = ldns_rr_list_cat_clone(aaaa, a);
88 2           ldns_rr_list_deep_free(aaaa);
89 2           ldns_rr_list_deep_free(a);
90 2           return result;
91             }
92            
93 0 0         if (aaaa) {
94 0           result = ldns_rr_list_clone(aaaa);
95             }
96            
97 0 0         if (a) {
98 0           result = ldns_rr_list_clone(a);
99             }
100              
101 0           ldns_rr_list_deep_free(aaaa);
102 0           ldns_rr_list_deep_free(a);
103 0           return result;
104             }
105              
106             ldns_rr_list *
107 2           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 2           names = NULL;
115              
116 2 50         if (!res || !addr) {
    50          
117 0           return NULL;
118             }
119              
120 2           if (ldns_rdf_get_type(addr) != LDNS_RDF_TYPE_A &&
121 0           ldns_rdf_get_type(addr) != LDNS_RDF_TYPE_AAAA) {
122 0           return NULL;
123             }
124              
125 2           name = ldns_rdf_address_reverse(addr);
126            
127             /* add the RD flags, because we want an answer */
128 2           pkt = ldns_resolver_query(res, name, LDNS_RR_TYPE_PTR, c, flags | LDNS_RD);
129 2           ldns_rdf_deep_free(name);
130 2 50         if (pkt) {
131             /* extract the data we need */
132 2           names = ldns_pkt_rr_list_by_type(pkt,
133             LDNS_RR_TYPE_PTR, LDNS_SECTION_ANSWER);
134 2           ldns_pkt_free(pkt);
135             }
136 2           return names;
137             }
138              
139             /* read a line, put it in a buffer, parse the buffer */
140             ldns_rr_list *
141 2           ldns_get_rr_list_hosts_frm_fp(FILE *fp)
142             {
143 2           return ldns_get_rr_list_hosts_frm_fp_l(fp, NULL);
144             }
145              
146             ldns_rr_list *
147 2           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 2           line = LDNS_XMALLOC(char, LDNS_MAX_LINELEN + 1);
163 2           word = LDNS_XMALLOC(char, LDNS_MAX_LINELEN + 1);
164 2           addr = LDNS_XMALLOC(char, LDNS_MAX_LINELEN + 1);
165 2           rr_str = LDNS_XMALLOC(char, LDNS_MAX_LINELEN + 1);
166 2           ip6 = false;
167 2           list = ldns_rr_list_new();
168 2           rr = NULL;
169 2 50         if(!line || !word || !addr || !rr_str || !list) {
    50          
    50          
    50          
    50          
170 0           LDNS_FREE(line);
171 0           LDNS_FREE(word);
172 0           LDNS_FREE(addr);
173 0           LDNS_FREE(rr_str);
174 0           ldns_rr_list_free(list);
175 0           return NULL;
176             }
177              
178 16 100         for(i = ldns_fget_token_l(fp, line, "\n", LDNS_MAX_LINELEN, line_nr);
179 14           i > 0; i = ldns_fget_token_l(fp, line, "\n", LDNS_MAX_LINELEN, line_nr)) {
180             /* # is comment */
181 14 50         if (line[0] == '#') {
182 0           continue;
183             }
184             /* put it in a buffer for further processing */
185 14           linebuf = LDNS_MALLOC(ldns_buffer);
186 14 50         if(!linebuf) {
187 0           LDNS_FREE(line);
188 0           LDNS_FREE(word);
189 0           LDNS_FREE(addr);
190 0           LDNS_FREE(rr_str);
191 0           ldns_rr_list_deep_free(list);
192 0           return NULL;
193             }
194              
195 14           ldns_buffer_new_frm_data(linebuf, line, (size_t) i);
196 46 100         for(cnt = 0, j = ldns_bget_token(linebuf, word, LDNS_PARSE_NO_NL, LDNS_MAX_LINELEN);
197             j > 0;
198 32           j = ldns_bget_token(linebuf, word, LDNS_PARSE_NO_NL, LDNS_MAX_LINELEN), cnt++) {
199 32 100         if (cnt == 0) {
200             /* the address */
201 14 100         if ((tmp = ldns_rdf_new_frm_str(LDNS_RDF_TYPE_AAAA,
202             word))) {
203             /* ip6 */
204 10           ldns_rdf_deep_free(tmp);
205 10           ip6 = true;
206             } else {
207 4 50         if ((tmp = ldns_rdf_new_frm_str(LDNS_RDF_TYPE_A,
208             word))) {
209             /* ip4 */
210 4           ldns_rdf_deep_free(tmp);
211 4           ip6 = false;
212             } else {
213             /* kaput */
214 0           break;
215             }
216             }
217 14           (void)strlcpy(addr, word, LDNS_MAX_LINELEN+1);
218             } else {
219             /* la al la la */
220 18 100         if (ip6) {
221 14           snprintf(rr_str, LDNS_MAX_LINELEN,
222             "%s IN AAAA %s", word, addr);
223             } else {
224 4           snprintf(rr_str, LDNS_MAX_LINELEN,
225             "%s IN A %s", word, addr);
226             }
227 18           parse_result = ldns_rr_new_frm_str(&rr, rr_str, 0, NULL, NULL);
228 18 50         if (parse_result == LDNS_STATUS_OK && ldns_rr_owner(rr) && ldns_rr_rd_count(rr) > 0) {
    50          
    50          
229 18           ldns_rr_list_push_rr(list, ldns_rr_clone(rr));
230             }
231 18           ldns_rr_free(rr);
232             }
233             }
234 14           ldns_buffer_free(linebuf);
235             }
236 2           LDNS_FREE(line);
237 2           LDNS_FREE(word);
238 2           LDNS_FREE(addr);
239 2           LDNS_FREE(rr_str);
240 2           return list;
241             }
242              
243             ldns_rr_list *
244 2           ldns_get_rr_list_hosts_frm_file(char *filename)
245             {
246             ldns_rr_list *names;
247             FILE *fp;
248              
249 2 50         if (!filename) {
250 2           fp = fopen(LDNS_RESOLV_HOSTS, "r");
251            
252             } else {
253 0           fp = fopen(filename, "r");
254             }
255 2 50         if (!fp) {
256 0           return NULL;
257             }
258              
259 2           names = ldns_get_rr_list_hosts_frm_fp(fp);
260 2           fclose(fp);
261 2           return names;
262             }
263              
264             uint16_t
265 0           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 0           t = ldns_rdf_get_type(node);
274 0           names_found = 0;
275 0           r = res;
276              
277 0 0         if (res == NULL) {
278             /* prepare a new resolver, using /etc/resolv.conf as a guide */
279 0           s = ldns_resolver_new_frm_file(&r, NULL);
280 0 0         if (s != LDNS_STATUS_OK) {
281 0           return 0;
282             }
283             }
284              
285 0 0         if (t == LDNS_RDF_TYPE_DNAME) {
286             /* we're asked to query for a name */
287 0           *ret = ldns_get_rr_list_addr_by_name(r, node, c, 0);
288 0           names_found = ldns_rr_list_rr_count(*ret);
289             }
290              
291 0 0         if (t == LDNS_RDF_TYPE_A || t == LDNS_RDF_TYPE_AAAA) {
    0          
292             /* an address */
293 0           *ret = ldns_get_rr_list_name_by_addr(r, node, c, 0);
294 0           names_found = ldns_rr_list_rr_count(*ret);
295             }
296              
297 0 0         if (res == NULL) {
298 0           ldns_resolver_deep_free(r);
299             }
300            
301 0           return names_found;
302             }
303              
304             bool
305 0           ldns_nsec_type_check(ldns_rr *nsec, ldns_rr_type t)
306             {
307 0           switch (ldns_rr_get_type(nsec)) {
308 0 0         case LDNS_RR_TYPE_NSEC : if (ldns_rr_rd_count(nsec) < 2) {
309 0           return false;
310             }
311 0           return ldns_nsec_bitmap_covers_type(
312 0           ldns_rr_rdf(nsec, 1), t);
313              
314 0 0         case LDNS_RR_TYPE_NSEC3 : if (ldns_rr_rd_count(nsec) < 6) {
315 0           return false;
316             }
317 0           return ldns_nsec_bitmap_covers_type(
318 0           ldns_rr_rdf(nsec, 5), t);
319              
320 0           default : return false;
321             }
322             }
323              
324             void
325 0           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 0           va_start(va_rdf, rdfnum);
331              
332 0 0         for (rdf = (int16_t)rdfnum; rdf != -1; rdf = (int16_t)va_arg(va_rdf, int))
    0          
333             {
334 0           rd = ldns_rr_rdf(r, rdf);
335 0 0         if (!rd) {
336 0           continue;
337             } else {
338 0           ldns_rdf_print(fp, rd);
339 0           fprintf(fp, " "); /* not sure if we want to do this */
340             }
341             }
342 0           va_end(va_rdf);
343 0           }
344