From 56d70baa79ae5907b11445364bbea9b31ee4cd20 Mon Sep 17 00:00:00 2001
From: Linus Nordberg <linus@nordu.net>
Date: Sun, 27 Mar 2016 19:27:30 +0200
Subject: WIP

---
 tools/dnssec/dns-wire2text.c | 149 +++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 149 insertions(+)
 create mode 100644 tools/dnssec/dns-wire2text.c

(limited to 'tools/dnssec/dns-wire2text.c')

diff --git a/tools/dnssec/dns-wire2text.c b/tools/dnssec/dns-wire2text.c
new file mode 100644
index 0000000..8e4b55d
--- /dev/null
+++ b/tools/dnssec/dns-wire2text.c
@@ -0,0 +1,149 @@
+/*
+  Read RR's in getdns wire format and print them in presentation
+  format on stdout.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <assert.h>
+#include <errno.h>
+#include <getdns/getdns.h>
+#include <getdns/getdns_extra.h>
+
+#undef DEBUG
+
+#if defined(DEBUG)
+static void
+hd(const char *buf, size_t buf_len)
+{
+  for (size_t n = 0; n < buf_len; n++)
+    {
+      if (n % 16 == 0)
+        {
+          if (n != 0)
+            fprintf(stderr, "\n");
+          fprintf(stderr, "%08x  ", n);
+        }
+      else if (n % 8 == 0)
+        fprintf(stderr, " ");
+      fprintf(stderr, "%02hhx ", buf[n]);
+    }
+  fprintf(stderr, "\n");
+}
+#else  /* !DEBUG */
+#define hd(a,b)
+#endif
+
+/* Return value:
+   <0 -- error, the return value being -errorcode
+    0 -- done
+   >0 -- not done yet, call me again
+*/
+static int
+read_rr(const uint8_t **buf, size_t *buf_len, getdns_dict **rr_dict)
+{
+  getdns_return_t r = getdns_wire2rr_dict_scan(buf, buf_len, rr_dict);
+
+  if (r)
+    return -r;
+  return *buf_len;
+}
+
+#define INBUFLEN 4096
+
+static size_t
+read_inbuf(FILE *infp, uint8_t **bufp_out)
+{
+  size_t nread = 0;
+  uint8_t *wirebuf = malloc(INBUFLEN);
+  int chunks = 1;
+
+  if (wirebuf == NULL)
+    goto out;
+
+  while (1)
+    {
+      size_t n = fread(wirebuf + nread, 1, INBUFLEN, infp);
+      nread += n;
+      if (n < INBUFLEN)
+        break;                  /* Done. */
+
+      wirebuf = realloc(wirebuf, ++chunks * INBUFLEN);
+      if (wirebuf == NULL)
+        break;
+    }
+
+ out:
+  if (bufp_out != NULL)
+    *bufp_out = wirebuf;
+  return nread;
+}
+
+int
+main(int argc, char *argv[])
+{
+  int rrv = 0;
+  uint8_t *inbuf = NULL;
+  const uint8_t *bufp = NULL;
+  size_t inbuf_len = 0;
+  getdns_dict *rr_dict = NULL;
+  getdns_return_t r = 0;
+  FILE *infp = stdin;
+
+  if (argc > 1)
+    {
+      infp = fopen(argv[1], "r");
+      if (infp == NULL)
+        {
+          perror("fopen(argv[1])");
+          return -errno;
+        }
+    }
+  inbuf_len = read_inbuf(infp, &inbuf);
+  if (inbuf == NULL)
+    {
+      perror("read_inbuf");
+      return -errno;
+    }
+  if (infp != stdin)
+    if (fclose(infp))
+      perror("fclose");
+  hd((const char *) wirebuf, n);
+
+  bufp = inbuf;
+  while (1)
+    {
+      char *stringbuf = NULL;
+
+      rrv = read_rr(&bufp, &inbuf_len, &rr_dict);
+      if (rrv < 0)
+        break;
+
+      r = getdns_rr_dict2str(rr_dict, &stringbuf);
+      if (r)
+        break;
+
+      getdns_dict_destroy(rr_dict);
+      printf("%s", stringbuf);
+      free(stringbuf);
+
+      if (rrv == 0)
+        break;                  /* Done. */
+    }
+  free(inbuf);
+
+  if (rrv < 0)
+    {
+      fprintf(stderr, "parsing input failed: %s\n",
+              getdns_get_errorstr_by_id(-rrv));
+      return rrv;
+    }
+  if (r)
+    {
+      fprintf(stderr, "converting dict to string failed: %s\n",
+              getdns_get_errorstr_by_id(r));
+      return -r;
+    }
+
+  return 0;
+}
-- 
cgit v1.1