acpi: Narrow workaround for broken interrupt settings
[dragonfly.git] / contrib / ldns / higher.c
blob4ca347b439a9c676ee0aca0473d5726f4b23a8cf
1 /*
2 * higher.c
4 * Specify some higher level functions that would
5 * be useful to would be developers
7 * a Net::DNS like library for C
9 * (c) NLnet Labs, 2004-2006
11 * See the file LICENSE for the license
14 #include <ldns/config.h>
16 #include <ldns/ldns.h>
18 #ifdef HAVE_SSL
19 #include <openssl/ssl.h>
20 #include <openssl/sha.h>
21 #endif /* HAVE_SSL */
23 ldns_rr_list *
24 ldns_get_rr_list_addr_by_name(ldns_resolver *res, const ldns_rdf *name,
25 ldns_rr_class c, uint16_t flags)
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;
35 a = NULL;
36 aaaa = NULL;
37 result = NULL;
39 if (!res) {
40 return NULL;
42 if (ldns_rdf_get_type(name) != LDNS_RDF_TYPE_DNAME) {
43 return NULL;
46 ip6 = ldns_resolver_ip6(res); /* we use INET_ANY here, save
47 what was there */
49 ldns_resolver_set_ip6(res, LDNS_RESOLV_INETANY);
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();
59 ldns_rr_list_push_rr(result,
60 ldns_rr_clone(ldns_rr_list_rr(hostsfilenames, i)));
63 ldns_rr_list_deep_free(hostsfilenames);
65 if (result) {
66 return result;
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);
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);
84 ldns_resolver_set_ip6(res, ip6);
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;
93 if (aaaa) {
94 result = ldns_rr_list_clone(aaaa);
97 if (a) {
98 result = ldns_rr_list_clone(a);
101 ldns_rr_list_deep_free(aaaa);
102 ldns_rr_list_deep_free(a);
103 return result;
106 ldns_rr_list *
107 ldns_get_rr_list_name_by_addr(ldns_resolver *res, const ldns_rdf *addr,
108 ldns_rr_class c, uint16_t flags)
110 ldns_pkt *pkt;
111 ldns_rr_list *names;
112 ldns_rdf *name;
114 names = NULL;
116 if (!res || !addr) {
117 return NULL;
120 if (ldns_rdf_get_type(addr) != LDNS_RDF_TYPE_A &&
121 ldns_rdf_get_type(addr) != LDNS_RDF_TYPE_AAAA) {
122 return NULL;
125 name = ldns_rdf_address_reverse(addr);
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);
136 return names;
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)
143 return ldns_get_rr_list_hosts_frm_fp_l(fp, NULL);
146 ldns_rr_list *
147 ldns_get_rr_list_hosts_frm_fp_l(FILE *fp, int *line_nr)
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;
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;
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;
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;
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;
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);
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) {
232 ldns_rr_list_push_rr(list, ldns_rr_clone(rr));
233 ldns_rr_free(rr);
237 ldns_buffer_free(linebuf);
239 LDNS_FREE(line);
240 LDNS_FREE(word);
241 LDNS_FREE(addr);
242 LDNS_FREE(rr_str);
243 return list;
246 ldns_rr_list *
247 ldns_get_rr_list_hosts_frm_file(char *filename)
249 ldns_rr_list *names;
250 FILE *fp;
252 if (!filename) {
253 fp = fopen(LDNS_RESOLV_HOSTS, "r");
255 } else {
256 fp = fopen(filename, "r");
258 if (!fp) {
259 return NULL;
262 names = ldns_get_rr_list_hosts_frm_fp(fp);
263 fclose(fp);
264 return names;
267 uint16_t
268 ldns_getaddrinfo(ldns_resolver *res, const ldns_rdf *node,
269 ldns_rr_class c, ldns_rr_list **ret)
271 ldns_rdf_type t;
272 uint16_t names_found;
273 ldns_resolver *r;
274 ldns_status s;
276 t = ldns_rdf_get_type(node);
277 names_found = 0;
278 r = res;
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;
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);
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);
300 if (res == NULL) {
301 ldns_resolver_deep_free(r);
304 return names_found;
307 bool
308 ldns_nsec_type_check(const ldns_rr *nsec, ldns_rr_type t)
310 switch (ldns_rr_get_type(nsec)) {
311 case LDNS_RR_TYPE_NSEC : if (ldns_rr_rd_count(nsec) < 2) {
312 return false;
314 return ldns_nsec_bitmap_covers_type(
315 ldns_rr_rdf(nsec, 1), t);
317 case LDNS_RR_TYPE_NSEC3 : if (ldns_rr_rd_count(nsec) < 6) {
318 return false;
320 return ldns_nsec_bitmap_covers_type(
321 ldns_rr_rdf(nsec, 5), t);
323 default : return false;
327 void
328 ldns_print_rr_rdf(FILE *fp, ldns_rr *r, int rdfnum, ...)
330 int16_t rdf;
331 ldns_rdf *rd;
332 va_list va_rdf;
333 va_start(va_rdf, rdfnum);
335 for (rdf = (int16_t)rdfnum; rdf != -1; rdf = (int16_t)va_arg(va_rdf, int))
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 */
345 va_end(va_rdf);