aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/0tDNS.c121
1 files changed, 121 insertions, 0 deletions
diff --git a/src/0tDNS.c b/src/0tDNS.c
new file mode 100644
index 0000000..838cae6
--- /dev/null
+++ b/src/0tDNS.c
@@ -0,0 +1,121 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <arpa/inet.h>
+#include <unbound.h>
+
+/* examine the result structure in detail */
+void examine_result(const char *query, struct ub_result *result)
+{
+ int i;
+ int num;
+
+ printf("The query is for: %s\n", query);
+ printf("The result has:\n");
+ printf("qname: %s\n", result->qname);
+ printf("qtype: %d\n", result->qtype);
+ printf("qclass: %d\n", result->qclass);
+ if(result->canonname)
+ printf("canonical name: %s\n",
+ result->canonname);
+ else printf("canonical name: <none>\n");
+
+ if(result->havedata)
+ printf("has data\n");
+ else printf("has no data\n");
+
+ if(result->nxdomain)
+ printf("nxdomain (name does not exist)\n");
+ else printf("not an nxdomain (name exists)\n");
+
+ if(result->secure)
+ printf("validated to be secure\n");
+ else printf("not validated as secure\n");
+
+ if(result->bogus)
+ printf("a security failure! (bogus)\n");
+ else printf("not a security failure (not bogus)\n");
+
+ printf("DNS rcode: %d\n", result->rcode);
+
+ num = 0;
+ for(i=0; result->data[i]; i++) {
+ printf("result data element %d has length %d\n",
+ i, result->len[i]);
+ printf("result data element %d is: %s\n",
+ i, inet_ntoa(*(struct in_addr*)result->data[i]));
+ num++;
+ }
+ printf("result has %d data element(s)\n", num);
+}
+
+struct ub_ctx *ztdns_create_context_with_resolver(const char *resolver_addr) {
+ int rc;
+ struct ub_ctx* ctx;
+ ctx = ub_ctx_create();
+ if (!ctx) {
+ fprintf(stderr, "Couldn't create libunbound context.\n");
+ return NULL;
+ }
+ rc = ub_ctx_set_fwd(ctx, resolver_addr);
+ if (rc) {
+ fprintf(stderr, "Couldn't set forward server: %s\n",
+ ub_strerror(rc));
+ return NULL;
+ }
+ return ctx;
+}
+
+void ztdns_try_resolve(struct ub_ctx *ctx, const char *name) {
+ struct ub_result* result;
+ int rc;
+ rc = ub_resolve(ctx, name,
+ 1 /* TYPE A (IPv4 address) */,
+ 1 /* CLASS IN (internet) */, &result);
+ if(rc)
+ printf("resolve error: %s\n", ub_strerror(rc));
+ else
+ examine_result(name, result);
+ ub_resolve_free(result);
+}
+
+int main(int argc, char** argv)
+{
+ struct ub_ctx
+ *ctx_google1 = NULL,
+ *ctx_google2 = NULL,
+ *ctx_cloudflare = NULL;
+ int rc = EXIT_SUCCESS;
+
+ if(argc != 2) {
+ printf("usage: <hostname>\n");
+ return EXIT_FAILURE;
+ }
+
+ ctx_google1 = ztdns_create_context_with_resolver("8.8.8.8");
+ ctx_google2 = ztdns_create_context_with_resolver("8.8.4.4");
+ ctx_cloudflare = ztdns_create_context_with_resolver("1.1.1.1");
+
+ if (!ctx_google1 || !ctx_google2 || !ctx_cloudflare) {
+ rc = EXIT_FAILURE;
+ goto abort;
+ }
+
+ printf("* VIA GOOGLE (8.8.8.8)\n");
+ ztdns_try_resolve(ctx_google1, argv[1]);
+ printf("* VIA GOOGLE (8.8.4.4)\n");
+ ztdns_try_resolve(ctx_google2, argv[1]);
+ printf("* VIA CLOUDFLARE (1.1.1.1)\n");
+ ztdns_try_resolve(ctx_cloudflare, argv[1]);
+
+abort:
+ if (ctx_google1)
+ ub_ctx_delete(ctx_google1);
+ if (ctx_google2)
+ ub_ctx_delete(ctx_google2);
+ if (ctx_cloudflare)
+ ub_ctx_delete(ctx_cloudflare);
+
+ return rc;
+}