diff options
Diffstat (limited to 'tools/dnssec/common.c')
-rw-r--r-- | tools/dnssec/common.c | 201 |
1 files changed, 201 insertions, 0 deletions
diff --git a/tools/dnssec/common.c b/tools/dnssec/common.c new file mode 100644 index 0000000..4382a1d --- /dev/null +++ b/tools/dnssec/common.c @@ -0,0 +1,201 @@ +#include <string.h> +#include <errno.h> +#include <getdns/getdns.h> +#include <getdns/getdns_ext_libevent.h> + +static int debug = 0; + +static getdns_return_t +dump_reply(FILE *fp, getdns_dict *reply, const char *section_name) +{ + getdns_list *section = NULL; + size_t section_len = -1; + getdns_return_t r; + uint8_t *res = NULL; + size_t res_len; + + r = getdns_dict_get_list(reply, section_name, §ion); + if (r) { + fprintf(stderr, + "unable to get section \"%s\" from reply\n", + section_name); + return r; + } + + r = getdns_list_get_length(section, §ion_len); + if (r) { + fprintf(stderr, "unable to get length of section\n"); + return r; + } + + for (size_t j = 0; j < section_len; j++) { + getdns_dict *rr = NULL; + + r = getdns_list_get_dict(section, j , &rr); + if (r) { + fprintf(stderr, "unable to get rr from entry " + "%d: %d\n", j, r); + return r; + } + + r = getdns_rr_dict2wire(rr, &res, &res_len); + if (r) { + fprintf(stderr, + "unable to convert entry %d " + "to wire format: %d\n", j, r); + return r; + } + + if (0 && debug) { + char *s = getdns_pretty_print_dict(rr); + puts(s); + free(s); + } + + if (fwrite(res, 1, res_len, fp) != res_len) { + fprintf(stderr, + "unable to write buffer to file: %s\n", + strerror(errno)); + return -errno; + } + + free(res); + } + + return 0; +} + +int +dump_tree(FILE *fp, const getdns_dict *response, const char *tree_name, const char *section_name) +{ + getdns_return_t r; + getdns_list *tree = NULL; + size_t n_replies = -1; + + r = getdns_dict_get_list(response, tree_name, &tree); + if (r) { + fprintf(stderr, "unable to get tree %s\n", tree_name); + return r; + } + + if (section_name == NULL) { + size_t tree_len = 0; + r = getdns_list_get_length(tree, &tree_len); + if (r) { + fprintf(stderr, "unable to get tree length\n"); + return r; + } + for (size_t i = 0; i < tree_len; i++) { + getdns_dict *rr = NULL; + r = getdns_list_get_dict(tree, i , &rr); + if (r) { + fprintf(stderr, "unable to get rr from entry %d: %d\n", i, r); + return r; + } + uint8_t *res = NULL; + size_t res_len = 0; + r = getdns_rr_dict2wire(rr, &res, &res_len); + if (r) { + fprintf(stderr, + "unable to convert entry %d " + "to wire format: %d\n", i, r); + return r; + } + if (fwrite(res, 1, res_len, fp) != res_len) { + fprintf(stderr, + "unable to write buffer to file: %s\n", + strerror(errno)); + return errno; + } + free(res); + } + } else { + r = getdns_list_get_length(tree, &n_replies); + if (r) { + fprintf(stderr, "unable to get number of replies\n"); + return r; + } + + for (size_t i = 0; i < n_replies; i++) { + getdns_dict *reply = NULL; + + r = getdns_list_get_dict(tree, i, &reply); + if (r) { + fprintf(stderr, "unable to get reply %d from tree\n", i); + return r; + } + + if (debug) { + char *s = getdns_pretty_print_dict(reply); + printf("Pretty-printing reply #%d:%s\n", i, s); + free(s); + } + + dump_reply(fp, reply, section_name); + } + } + + return 0; +} + +#define CHUNKSIZE 4096 + +size_t +read_buffer(FILE *infp, uint8_t **bufp_out, size_t size_hint) +{ + size_t nread = 0; + uint8_t *wirebuf = NULL; + size_t chunksize = CHUNKSIZE; + int chunks = 1; + + if (size_hint > 0) + chunksize = size_hint; + wirebuf = malloc(chunksize); + + if (wirebuf == NULL) + goto out; + + while (1) + { + size_t n = fread(wirebuf + nread, 1, chunksize, infp); + nread += n; + if (n < chunksize) + break; /* Done. */ + + wirebuf = realloc(wirebuf, ++chunks * chunksize); + if (wirebuf == NULL) + break; + } + + out: + if (bufp_out != NULL) + *bufp_out = wirebuf; + return nread; +} + +getdns_return_t +wire_rrs2list(const uint8_t *buf, size_t buf_len, getdns_list **list_out) +{ + getdns_return_t r = GETDNS_RETURN_GOOD; + getdns_list *list = getdns_list_create(); + getdns_dict *dict = NULL; + size_t rr_count = 0; + + if (list == NULL) + return GETDNS_RETURN_MEMORY_ERROR; + while (buf_len > 0) + { + r = getdns_wire2rr_dict_scan(&buf, &buf_len, &dict); + if (r) + break; + r = getdns_list_set_dict(list, rr_count, dict); + getdns_dict_destroy(dict); /* The list has a copy. */ + if (r) + break; + rr_count++; + } + + if (list_out) + *list_out = list; + return r; +} |