summaryrefslogtreecommitdiff
path: root/tools/dnssec/common.c
diff options
context:
space:
mode:
authorLinus Nordberg <linus@nordu.net>2016-03-30 21:35:31 +0200
committerLinus Nordberg <linus@nordu.net>2016-03-30 21:35:31 +0200
commitb69ff1c846250939de3e4f32ff4d07d6ee415009 (patch)
tree4b5755c39fdac519cb9b878d011ee33a729b8a62 /tools/dnssec/common.c
parent8106050f24d1552f9fe9f0f1521eb3068de08ea4 (diff)
Add validatechain.c and move some code to common.c.
dns-net2wire.c is nothing but an ugly hack on top of getdns_query.c making it save answer, validation_chain and trust anchors to three separate files. Used for testing purposes. validatechain takes the above mentioned three files as input and performs DNSSEC validation.
Diffstat (limited to 'tools/dnssec/common.c')
-rw-r--r--tools/dnssec/common.c201
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, &section);
+ if (r) {
+ fprintf(stderr,
+ "unable to get section \"%s\" from reply\n",
+ section_name);
+ return r;
+ }
+
+ r = getdns_list_get_length(section, &section_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;
+}