xref: /freebsd/contrib/ldns/higher.c (revision 2787e39aaaaffd1fb07657ffaa2e3561858b3c73)
17b5038d7SDag-Erling Smørgrav /*
27b5038d7SDag-Erling Smørgrav  * higher.c
37b5038d7SDag-Erling Smørgrav  *
47b5038d7SDag-Erling Smørgrav  * Specify some higher level functions that would
57b5038d7SDag-Erling Smørgrav  * be usefull to would be developers
67b5038d7SDag-Erling Smørgrav  *
77b5038d7SDag-Erling Smørgrav  * a Net::DNS like library for C
87b5038d7SDag-Erling Smørgrav  *
97b5038d7SDag-Erling Smørgrav  * (c) NLnet Labs, 2004-2006
107b5038d7SDag-Erling Smørgrav  *
117b5038d7SDag-Erling Smørgrav  * See the file LICENSE for the license
127b5038d7SDag-Erling Smørgrav  */
137b5038d7SDag-Erling Smørgrav 
147b5038d7SDag-Erling Smørgrav #include <ldns/config.h>
157b5038d7SDag-Erling Smørgrav 
167b5038d7SDag-Erling Smørgrav #include <ldns/ldns.h>
177b5038d7SDag-Erling Smørgrav 
187b5038d7SDag-Erling Smørgrav #ifdef HAVE_SSL
197b5038d7SDag-Erling Smørgrav #include <openssl/ssl.h>
207b5038d7SDag-Erling Smørgrav #include <openssl/sha.h>
217b5038d7SDag-Erling Smørgrav #endif /* HAVE_SSL */
227b5038d7SDag-Erling Smørgrav 
237b5038d7SDag-Erling Smørgrav ldns_rr_list *
247b5038d7SDag-Erling Smørgrav ldns_get_rr_list_addr_by_name(ldns_resolver *res, ldns_rdf *name, ldns_rr_class c,
257b5038d7SDag-Erling Smørgrav 		uint16_t flags)
267b5038d7SDag-Erling Smørgrav {
277b5038d7SDag-Erling Smørgrav 	ldns_pkt *pkt;
287b5038d7SDag-Erling Smørgrav 	ldns_rr_list *aaaa;
297b5038d7SDag-Erling Smørgrav 	ldns_rr_list *a;
307b5038d7SDag-Erling Smørgrav 	ldns_rr_list *result = NULL;
317b5038d7SDag-Erling Smørgrav 	ldns_rr_list *hostsfilenames;
327b5038d7SDag-Erling Smørgrav 	size_t i;
337b5038d7SDag-Erling Smørgrav 	uint8_t ip6;
347b5038d7SDag-Erling Smørgrav 
357b5038d7SDag-Erling Smørgrav 	a = NULL;
367b5038d7SDag-Erling Smørgrav 	aaaa = NULL;
377b5038d7SDag-Erling Smørgrav 	result = NULL;
387b5038d7SDag-Erling Smørgrav 
397b5038d7SDag-Erling Smørgrav 	if (!res) {
407b5038d7SDag-Erling Smørgrav 		return NULL;
417b5038d7SDag-Erling Smørgrav 	}
427b5038d7SDag-Erling Smørgrav 	if (ldns_rdf_get_type(name) != LDNS_RDF_TYPE_DNAME) {
437b5038d7SDag-Erling Smørgrav 		return NULL;
447b5038d7SDag-Erling Smørgrav 	}
457b5038d7SDag-Erling Smørgrav 
467b5038d7SDag-Erling Smørgrav 	ip6 = ldns_resolver_ip6(res); /* we use INET_ANY here, save
477b5038d7SDag-Erling Smørgrav 					 what was there */
487b5038d7SDag-Erling Smørgrav 
497b5038d7SDag-Erling Smørgrav 	ldns_resolver_set_ip6(res, LDNS_RESOLV_INETANY);
507b5038d7SDag-Erling Smørgrav 
517b5038d7SDag-Erling Smørgrav 	hostsfilenames = ldns_get_rr_list_hosts_frm_file(NULL);
527b5038d7SDag-Erling Smørgrav 	for (i = 0; i < ldns_rr_list_rr_count(hostsfilenames); i++) {
537b5038d7SDag-Erling Smørgrav 		if (ldns_rdf_compare(name,
547b5038d7SDag-Erling Smørgrav 					ldns_rr_owner(ldns_rr_list_rr(hostsfilenames,
557b5038d7SDag-Erling Smørgrav 							i))) == 0) {
567b5038d7SDag-Erling Smørgrav 			if (!result) {
577b5038d7SDag-Erling Smørgrav 				result = ldns_rr_list_new();
587b5038d7SDag-Erling Smørgrav 			}
597b5038d7SDag-Erling Smørgrav 			ldns_rr_list_push_rr(result,
607b5038d7SDag-Erling Smørgrav 					ldns_rr_clone(ldns_rr_list_rr(hostsfilenames, i)));
617b5038d7SDag-Erling Smørgrav 		}
627b5038d7SDag-Erling Smørgrav 	}
637b5038d7SDag-Erling Smørgrav 	ldns_rr_list_deep_free(hostsfilenames);
647b5038d7SDag-Erling Smørgrav 
657b5038d7SDag-Erling Smørgrav 	if (result) {
667b5038d7SDag-Erling Smørgrav 		return result;
677b5038d7SDag-Erling Smørgrav 	}
687b5038d7SDag-Erling Smørgrav 
697b5038d7SDag-Erling Smørgrav 	/* add the RD flags, because we want an answer */
707b5038d7SDag-Erling Smørgrav 	pkt = ldns_resolver_query(res, name, LDNS_RR_TYPE_AAAA, c, flags | LDNS_RD);
717b5038d7SDag-Erling Smørgrav 	if (pkt) {
727b5038d7SDag-Erling Smørgrav 		/* extract the data we need */
737b5038d7SDag-Erling Smørgrav 		aaaa = ldns_pkt_rr_list_by_type(pkt, LDNS_RR_TYPE_AAAA,
747b5038d7SDag-Erling Smørgrav 			LDNS_SECTION_ANSWER);
757b5038d7SDag-Erling Smørgrav 		ldns_pkt_free(pkt);
767b5038d7SDag-Erling Smørgrav 	}
777b5038d7SDag-Erling Smørgrav 
787b5038d7SDag-Erling Smørgrav 	pkt = ldns_resolver_query(res, name, LDNS_RR_TYPE_A, c, flags | LDNS_RD);
797b5038d7SDag-Erling Smørgrav 	if (pkt) {
807b5038d7SDag-Erling Smørgrav 		/* extract the data we need */
817b5038d7SDag-Erling Smørgrav 		a = ldns_pkt_rr_list_by_type(pkt, LDNS_RR_TYPE_A, LDNS_SECTION_ANSWER);
827b5038d7SDag-Erling Smørgrav 		ldns_pkt_free(pkt);
837b5038d7SDag-Erling Smørgrav 	}
847b5038d7SDag-Erling Smørgrav 	ldns_resolver_set_ip6(res, ip6);
857b5038d7SDag-Erling Smørgrav 
867b5038d7SDag-Erling Smørgrav 	if (aaaa && a) {
877b5038d7SDag-Erling Smørgrav 		result = ldns_rr_list_cat_clone(aaaa, a);
887b5038d7SDag-Erling Smørgrav 		ldns_rr_list_deep_free(aaaa);
897b5038d7SDag-Erling Smørgrav 		ldns_rr_list_deep_free(a);
907b5038d7SDag-Erling Smørgrav 		return result;
917b5038d7SDag-Erling Smørgrav 	}
927b5038d7SDag-Erling Smørgrav 
937b5038d7SDag-Erling Smørgrav 	if (aaaa) {
947b5038d7SDag-Erling Smørgrav 		result = ldns_rr_list_clone(aaaa);
957b5038d7SDag-Erling Smørgrav 	}
967b5038d7SDag-Erling Smørgrav 
977b5038d7SDag-Erling Smørgrav 	if (a) {
987b5038d7SDag-Erling Smørgrav 		result = ldns_rr_list_clone(a);
997b5038d7SDag-Erling Smørgrav 	}
1007b5038d7SDag-Erling Smørgrav 
1017b5038d7SDag-Erling Smørgrav 	ldns_rr_list_deep_free(aaaa);
1027b5038d7SDag-Erling Smørgrav 	ldns_rr_list_deep_free(a);
1037b5038d7SDag-Erling Smørgrav 	return result;
1047b5038d7SDag-Erling Smørgrav }
1057b5038d7SDag-Erling Smørgrav 
1067b5038d7SDag-Erling Smørgrav ldns_rr_list *
1077b5038d7SDag-Erling Smørgrav ldns_get_rr_list_name_by_addr(ldns_resolver *res, ldns_rdf *addr, ldns_rr_class c,
1087b5038d7SDag-Erling Smørgrav 		uint16_t flags)
1097b5038d7SDag-Erling Smørgrav {
1107b5038d7SDag-Erling Smørgrav 	ldns_pkt *pkt;
1117b5038d7SDag-Erling Smørgrav 	ldns_rr_list *names;
1127b5038d7SDag-Erling Smørgrav 	ldns_rdf *name;
1137b5038d7SDag-Erling Smørgrav 
1147b5038d7SDag-Erling Smørgrav 	names = NULL;
1157b5038d7SDag-Erling Smørgrav 
1167b5038d7SDag-Erling Smørgrav 	if (!res || !addr) {
1177b5038d7SDag-Erling Smørgrav 		return NULL;
1187b5038d7SDag-Erling Smørgrav 	}
1197b5038d7SDag-Erling Smørgrav 
1207b5038d7SDag-Erling Smørgrav 	if (ldns_rdf_get_type(addr) != LDNS_RDF_TYPE_A &&
1217b5038d7SDag-Erling Smørgrav 			ldns_rdf_get_type(addr) != LDNS_RDF_TYPE_AAAA) {
1227b5038d7SDag-Erling Smørgrav 		return NULL;
1237b5038d7SDag-Erling Smørgrav 	}
1247b5038d7SDag-Erling Smørgrav 
1257b5038d7SDag-Erling Smørgrav 	name = ldns_rdf_address_reverse(addr);
1267b5038d7SDag-Erling Smørgrav 
1277b5038d7SDag-Erling Smørgrav 	/* add the RD flags, because we want an answer */
1287b5038d7SDag-Erling Smørgrav 	pkt = ldns_resolver_query(res, name, LDNS_RR_TYPE_PTR, c, flags | LDNS_RD);
129*2787e39aSDag-Erling Smørgrav 	ldns_rdf_deep_free(name);
1307b5038d7SDag-Erling Smørgrav 	if (pkt) {
1317b5038d7SDag-Erling Smørgrav 		/* extract the data we need */
1327b5038d7SDag-Erling Smørgrav 		names = ldns_pkt_rr_list_by_type(pkt,
1337b5038d7SDag-Erling Smørgrav 				LDNS_RR_TYPE_PTR, LDNS_SECTION_ANSWER);
1347b5038d7SDag-Erling Smørgrav 	}
1357b5038d7SDag-Erling Smørgrav 	return names;
1367b5038d7SDag-Erling Smørgrav }
1377b5038d7SDag-Erling Smørgrav 
1387b5038d7SDag-Erling Smørgrav /* read a line, put it in a buffer, parse the buffer */
1397b5038d7SDag-Erling Smørgrav ldns_rr_list *
1407b5038d7SDag-Erling Smørgrav ldns_get_rr_list_hosts_frm_fp(FILE *fp)
1417b5038d7SDag-Erling Smørgrav {
1427b5038d7SDag-Erling Smørgrav 	return ldns_get_rr_list_hosts_frm_fp_l(fp, NULL);
1437b5038d7SDag-Erling Smørgrav }
1447b5038d7SDag-Erling Smørgrav 
1457b5038d7SDag-Erling Smørgrav ldns_rr_list *
1467b5038d7SDag-Erling Smørgrav ldns_get_rr_list_hosts_frm_fp_l(FILE *fp, int *line_nr)
1477b5038d7SDag-Erling Smørgrav {
1487b5038d7SDag-Erling Smørgrav 	ssize_t i, j;
1497b5038d7SDag-Erling Smørgrav 	size_t cnt;
1507b5038d7SDag-Erling Smørgrav 	char *line;
1517b5038d7SDag-Erling Smørgrav 	char *word;
1527b5038d7SDag-Erling Smørgrav 	char *addr;
1537b5038d7SDag-Erling Smørgrav 	char *rr_str;
1547b5038d7SDag-Erling Smørgrav 	ldns_buffer *linebuf;
1557b5038d7SDag-Erling Smørgrav 	ldns_rr *rr;
1567b5038d7SDag-Erling Smørgrav 	ldns_rr_list *list;
1577b5038d7SDag-Erling Smørgrav 	ldns_rdf *tmp;
1587b5038d7SDag-Erling Smørgrav 	bool ip6;
1597b5038d7SDag-Erling Smørgrav 	ldns_status parse_result;
1607b5038d7SDag-Erling Smørgrav 
1617b5038d7SDag-Erling Smørgrav 	line = LDNS_XMALLOC(char, LDNS_MAX_LINELEN + 1);
1627b5038d7SDag-Erling Smørgrav 	word = LDNS_XMALLOC(char, LDNS_MAX_LINELEN + 1);
1637b5038d7SDag-Erling Smørgrav 	addr = LDNS_XMALLOC(char, LDNS_MAX_LINELEN + 1);
1647b5038d7SDag-Erling Smørgrav 	rr_str = LDNS_XMALLOC(char, LDNS_MAX_LINELEN + 1);
1657b5038d7SDag-Erling Smørgrav 	ip6 = false;
1667b5038d7SDag-Erling Smørgrav 	list = ldns_rr_list_new();
1677b5038d7SDag-Erling Smørgrav 	rr = NULL;
1687b5038d7SDag-Erling Smørgrav 	if(!line || !word || !addr || !rr_str || !list) {
1697b5038d7SDag-Erling Smørgrav 		LDNS_FREE(line);
1707b5038d7SDag-Erling Smørgrav 		LDNS_FREE(word);
1717b5038d7SDag-Erling Smørgrav 		LDNS_FREE(addr);
1727b5038d7SDag-Erling Smørgrav 		LDNS_FREE(rr_str);
1737b5038d7SDag-Erling Smørgrav 		ldns_rr_list_free(list);
1747b5038d7SDag-Erling Smørgrav 		return NULL;
1757b5038d7SDag-Erling Smørgrav 	}
1767b5038d7SDag-Erling Smørgrav 
1777b5038d7SDag-Erling Smørgrav 	for(i = ldns_fget_token_l(fp, line, "\n", LDNS_MAX_LINELEN, line_nr);
1787b5038d7SDag-Erling Smørgrav 			i > 0; i = ldns_fget_token_l(fp, line, "\n", LDNS_MAX_LINELEN, line_nr)) {
1797b5038d7SDag-Erling Smørgrav 		/* # is comment */
1807b5038d7SDag-Erling Smørgrav 		if (line[0] == '#') {
1817b5038d7SDag-Erling Smørgrav 			continue;
1827b5038d7SDag-Erling Smørgrav 		}
1837b5038d7SDag-Erling Smørgrav 		/* put it in a buffer for further processing */
1847b5038d7SDag-Erling Smørgrav 		linebuf = LDNS_MALLOC(ldns_buffer);
1857b5038d7SDag-Erling Smørgrav 		if(!linebuf) {
1867b5038d7SDag-Erling Smørgrav 			LDNS_FREE(line);
1877b5038d7SDag-Erling Smørgrav 			LDNS_FREE(word);
1887b5038d7SDag-Erling Smørgrav 			LDNS_FREE(addr);
1897b5038d7SDag-Erling Smørgrav 			LDNS_FREE(rr_str);
1907b5038d7SDag-Erling Smørgrav 			ldns_rr_list_deep_free(list);
1917b5038d7SDag-Erling Smørgrav 			return NULL;
1927b5038d7SDag-Erling Smørgrav 		}
1937b5038d7SDag-Erling Smørgrav 
1947b5038d7SDag-Erling Smørgrav 		ldns_buffer_new_frm_data(linebuf, line, (size_t) i);
1957b5038d7SDag-Erling Smørgrav 		for(cnt = 0, j = ldns_bget_token(linebuf, word, LDNS_PARSE_NO_NL, LDNS_MAX_LINELEN);
1967b5038d7SDag-Erling Smørgrav 				j > 0;
1977b5038d7SDag-Erling Smørgrav 				j = ldns_bget_token(linebuf, word, LDNS_PARSE_NO_NL, LDNS_MAX_LINELEN), cnt++) {
1987b5038d7SDag-Erling Smørgrav 			if (cnt == 0) {
1997b5038d7SDag-Erling Smørgrav 				/* the address */
2007b5038d7SDag-Erling Smørgrav 				if ((tmp = ldns_rdf_new_frm_str(LDNS_RDF_TYPE_AAAA,
2017b5038d7SDag-Erling Smørgrav 								word))) {
2027b5038d7SDag-Erling Smørgrav 					/* ip6 */
2037b5038d7SDag-Erling Smørgrav 					ldns_rdf_deep_free(tmp);
2047b5038d7SDag-Erling Smørgrav 					ip6 = true;
2057b5038d7SDag-Erling Smørgrav 				} else {
2067b5038d7SDag-Erling Smørgrav 					if ((tmp = ldns_rdf_new_frm_str(LDNS_RDF_TYPE_A,
2077b5038d7SDag-Erling Smørgrav 									word))) {
2087b5038d7SDag-Erling Smørgrav 						/* ip4 */
2097b5038d7SDag-Erling Smørgrav 						ldns_rdf_deep_free(tmp);
2107b5038d7SDag-Erling Smørgrav 						ip6 = false;
2117b5038d7SDag-Erling Smørgrav 					} else {
2127b5038d7SDag-Erling Smørgrav 						/* kaput */
2137b5038d7SDag-Erling Smørgrav 						break;
2147b5038d7SDag-Erling Smørgrav 					}
2157b5038d7SDag-Erling Smørgrav 				}
2167b5038d7SDag-Erling Smørgrav 				(void)strlcpy(addr, word, LDNS_MAX_LINELEN+1);
2177b5038d7SDag-Erling Smørgrav 			} else {
2187b5038d7SDag-Erling Smørgrav 				/* la al la la */
2197b5038d7SDag-Erling Smørgrav 				if (ip6) {
2207b5038d7SDag-Erling Smørgrav 					snprintf(rr_str, LDNS_MAX_LINELEN,
2217b5038d7SDag-Erling Smørgrav 						"%s IN AAAA %s", word, addr);
2227b5038d7SDag-Erling Smørgrav 				} else {
2237b5038d7SDag-Erling Smørgrav 					snprintf(rr_str, LDNS_MAX_LINELEN,
2247b5038d7SDag-Erling Smørgrav 						"%s IN A %s", word, addr);
2257b5038d7SDag-Erling Smørgrav 				}
2267b5038d7SDag-Erling Smørgrav 				parse_result = ldns_rr_new_frm_str(&rr, rr_str, 0, NULL, NULL);
2277b5038d7SDag-Erling Smørgrav 				if (parse_result == LDNS_STATUS_OK && ldns_rr_owner(rr) && ldns_rr_rd_count(rr) > 0) {
2287b5038d7SDag-Erling Smørgrav 					ldns_rr_list_push_rr(list, ldns_rr_clone(rr));
2297b5038d7SDag-Erling Smørgrav 				}
2307b5038d7SDag-Erling Smørgrav 				ldns_rr_free(rr);
2317b5038d7SDag-Erling Smørgrav 			}
2327b5038d7SDag-Erling Smørgrav 		}
2337b5038d7SDag-Erling Smørgrav 		ldns_buffer_free(linebuf);
2347b5038d7SDag-Erling Smørgrav 	}
2357b5038d7SDag-Erling Smørgrav 	LDNS_FREE(line);
2367b5038d7SDag-Erling Smørgrav 	LDNS_FREE(word);
2377b5038d7SDag-Erling Smørgrav 	LDNS_FREE(addr);
2387b5038d7SDag-Erling Smørgrav 	LDNS_FREE(rr_str);
2397b5038d7SDag-Erling Smørgrav 	return list;
2407b5038d7SDag-Erling Smørgrav }
2417b5038d7SDag-Erling Smørgrav 
2427b5038d7SDag-Erling Smørgrav ldns_rr_list *
2437b5038d7SDag-Erling Smørgrav ldns_get_rr_list_hosts_frm_file(char *filename)
2447b5038d7SDag-Erling Smørgrav {
2457b5038d7SDag-Erling Smørgrav 	ldns_rr_list *names;
2467b5038d7SDag-Erling Smørgrav 	FILE *fp;
2477b5038d7SDag-Erling Smørgrav 
2487b5038d7SDag-Erling Smørgrav 	if (!filename) {
2497b5038d7SDag-Erling Smørgrav                 fp = fopen(LDNS_RESOLV_HOSTS, "r");
2507b5038d7SDag-Erling Smørgrav 
2517b5038d7SDag-Erling Smørgrav         } else {
2527b5038d7SDag-Erling Smørgrav                 fp = fopen(filename, "r");
2537b5038d7SDag-Erling Smørgrav         }
2547b5038d7SDag-Erling Smørgrav         if (!fp) {
2557b5038d7SDag-Erling Smørgrav                 return NULL;
2567b5038d7SDag-Erling Smørgrav         }
2577b5038d7SDag-Erling Smørgrav 
2587b5038d7SDag-Erling Smørgrav 	names = ldns_get_rr_list_hosts_frm_fp(fp);
2597b5038d7SDag-Erling Smørgrav 	fclose(fp);
2607b5038d7SDag-Erling Smørgrav 	return names;
2617b5038d7SDag-Erling Smørgrav }
2627b5038d7SDag-Erling Smørgrav 
2637b5038d7SDag-Erling Smørgrav uint16_t
2647b5038d7SDag-Erling Smørgrav ldns_getaddrinfo(ldns_resolver *res, ldns_rdf *node, ldns_rr_class c,
2657b5038d7SDag-Erling Smørgrav 		ldns_rr_list **ret)
2667b5038d7SDag-Erling Smørgrav {
2677b5038d7SDag-Erling Smørgrav 	ldns_rdf_type t;
2687b5038d7SDag-Erling Smørgrav 	uint16_t names_found;
2697b5038d7SDag-Erling Smørgrav 	ldns_resolver *r;
2707b5038d7SDag-Erling Smørgrav 	ldns_status s;
2717b5038d7SDag-Erling Smørgrav 
2727b5038d7SDag-Erling Smørgrav 	t = ldns_rdf_get_type(node);
2737b5038d7SDag-Erling Smørgrav 	names_found = 0;
2747b5038d7SDag-Erling Smørgrav 	r = res;
2757b5038d7SDag-Erling Smørgrav 
2767b5038d7SDag-Erling Smørgrav 	if (res == NULL) {
2777b5038d7SDag-Erling Smørgrav 		/* prepare a new resolver, using /etc/resolv.conf as a guide  */
2787b5038d7SDag-Erling Smørgrav 		s = ldns_resolver_new_frm_file(&r, NULL);
2797b5038d7SDag-Erling Smørgrav 		if (s != LDNS_STATUS_OK) {
2807b5038d7SDag-Erling Smørgrav 			return 0;
2817b5038d7SDag-Erling Smørgrav 		}
2827b5038d7SDag-Erling Smørgrav 	}
2837b5038d7SDag-Erling Smørgrav 
2847b5038d7SDag-Erling Smørgrav 	if (t == LDNS_RDF_TYPE_DNAME) {
2857b5038d7SDag-Erling Smørgrav 		/* we're asked to query for a name */
2867b5038d7SDag-Erling Smørgrav 		*ret = ldns_get_rr_list_addr_by_name(r, node, c, 0);
2877b5038d7SDag-Erling Smørgrav 		names_found = ldns_rr_list_rr_count(*ret);
2887b5038d7SDag-Erling Smørgrav 	}
2897b5038d7SDag-Erling Smørgrav 
2907b5038d7SDag-Erling Smørgrav 	if (t == LDNS_RDF_TYPE_A || t == LDNS_RDF_TYPE_AAAA) {
2917b5038d7SDag-Erling Smørgrav 		/* an address */
2927b5038d7SDag-Erling Smørgrav 		*ret = ldns_get_rr_list_name_by_addr(r, node, c, 0);
2937b5038d7SDag-Erling Smørgrav 		names_found = ldns_rr_list_rr_count(*ret);
2947b5038d7SDag-Erling Smørgrav 	}
2957b5038d7SDag-Erling Smørgrav 
2967b5038d7SDag-Erling Smørgrav 	if (res == NULL) {
2977b5038d7SDag-Erling Smørgrav 		ldns_resolver_deep_free(r);
2987b5038d7SDag-Erling Smørgrav 	}
2997b5038d7SDag-Erling Smørgrav 
3007b5038d7SDag-Erling Smørgrav 	return names_found;
3017b5038d7SDag-Erling Smørgrav }
3027b5038d7SDag-Erling Smørgrav 
3037b5038d7SDag-Erling Smørgrav bool
3047b5038d7SDag-Erling Smørgrav ldns_nsec_type_check(ldns_rr *nsec, ldns_rr_type t)
3057b5038d7SDag-Erling Smørgrav {
3067b5038d7SDag-Erling Smørgrav 	/* does the nsec cover the t given? */
3077b5038d7SDag-Erling Smørgrav 	/* copied from host2str.c line 465: ldns_rdf2buffer_str_nsec */
3087b5038d7SDag-Erling Smørgrav         uint8_t window_block_nr;
3097b5038d7SDag-Erling Smørgrav         uint8_t bitmap_length;
3107b5038d7SDag-Erling Smørgrav         uint16_t type;
3117b5038d7SDag-Erling Smørgrav         uint16_t pos = 0;
3127b5038d7SDag-Erling Smørgrav         uint16_t bit_pos;
3137b5038d7SDag-Erling Smørgrav 	ldns_rdf *nsec_type_list = ldns_rr_rdf(nsec, 1);
3147b5038d7SDag-Erling Smørgrav 	uint8_t *data;
3157b5038d7SDag-Erling Smørgrav 
3167b5038d7SDag-Erling Smørgrav 	if (nsec_type_list == NULL) {
3177b5038d7SDag-Erling Smørgrav 		return false;
3187b5038d7SDag-Erling Smørgrav 	}
3197b5038d7SDag-Erling Smørgrav 	data  = ldns_rdf_data(nsec_type_list);
3207b5038d7SDag-Erling Smørgrav 
3217b5038d7SDag-Erling Smørgrav 	while(pos < ldns_rdf_size(nsec_type_list)) {
3227b5038d7SDag-Erling Smørgrav 		window_block_nr = data[pos];
3237b5038d7SDag-Erling Smørgrav 		bitmap_length = data[pos + 1];
3247b5038d7SDag-Erling Smørgrav 		pos += 2;
3257b5038d7SDag-Erling Smørgrav 
3267b5038d7SDag-Erling Smørgrav 		for (bit_pos = 0; bit_pos < (bitmap_length) * 8; bit_pos++) {
3277b5038d7SDag-Erling Smørgrav 			if (ldns_get_bit(&data[pos], bit_pos)) {
3287b5038d7SDag-Erling Smørgrav 				type = 256 * (uint16_t) window_block_nr + bit_pos;
3297b5038d7SDag-Erling Smørgrav 
3307b5038d7SDag-Erling Smørgrav 				if ((ldns_rr_type)type == t) {
3317b5038d7SDag-Erling Smørgrav 					/* we have a winner */
3327b5038d7SDag-Erling Smørgrav 					return true;
3337b5038d7SDag-Erling Smørgrav 				}
3347b5038d7SDag-Erling Smørgrav 			}
3357b5038d7SDag-Erling Smørgrav 		}
3367b5038d7SDag-Erling Smørgrav 		pos += (uint16_t) bitmap_length;
3377b5038d7SDag-Erling Smørgrav 	}
3387b5038d7SDag-Erling Smørgrav 	return false;
3397b5038d7SDag-Erling Smørgrav }
3407b5038d7SDag-Erling Smørgrav 
3417b5038d7SDag-Erling Smørgrav void
3427b5038d7SDag-Erling Smørgrav ldns_print_rr_rdf(FILE *fp, ldns_rr *r, int rdfnum, ...)
3437b5038d7SDag-Erling Smørgrav {
3447b5038d7SDag-Erling Smørgrav 	int16_t rdf;
3457b5038d7SDag-Erling Smørgrav 	ldns_rdf *rd;
3467b5038d7SDag-Erling Smørgrav 	va_list va_rdf;
3477b5038d7SDag-Erling Smørgrav 	va_start(va_rdf, rdfnum);
3487b5038d7SDag-Erling Smørgrav 
3497b5038d7SDag-Erling Smørgrav 	for (rdf = (int16_t)rdfnum; rdf != -1; rdf = (int16_t)va_arg(va_rdf, int))
3507b5038d7SDag-Erling Smørgrav 	{
3517b5038d7SDag-Erling Smørgrav 		rd = ldns_rr_rdf(r, rdf);
3527b5038d7SDag-Erling Smørgrav 		if (!rd) {
3537b5038d7SDag-Erling Smørgrav 			continue;
3547b5038d7SDag-Erling Smørgrav 		} else {
3557b5038d7SDag-Erling Smørgrav 			ldns_rdf_print(fp, rd);
3567b5038d7SDag-Erling Smørgrav 			fprintf(fp, " "); /* not sure if we want to do this */
3577b5038d7SDag-Erling Smørgrav 		}
3587b5038d7SDag-Erling Smørgrav 	}
3597b5038d7SDag-Erling Smørgrav 	va_end(va_rdf);
3607b5038d7SDag-Erling Smørgrav }
361