17b5038d7SDag-Erling Smørgrav /*
27b5038d7SDag-Erling Smørgrav * drill.c
37b5038d7SDag-Erling Smørgrav * the main file of drill
47b5038d7SDag-Erling Smørgrav * (c) 2005-2008 NLnet Labs
57b5038d7SDag-Erling Smørgrav *
67b5038d7SDag-Erling Smørgrav * See the file LICENSE for the license
77b5038d7SDag-Erling Smørgrav *
87b5038d7SDag-Erling Smørgrav */
97b5038d7SDag-Erling Smørgrav
107b5038d7SDag-Erling Smørgrav #include "drill.h"
117b5038d7SDag-Erling Smørgrav #include <ldns/ldns.h>
127b5038d7SDag-Erling Smørgrav
137b5038d7SDag-Erling Smørgrav #ifdef HAVE_SSL
147b5038d7SDag-Erling Smørgrav #include <openssl/err.h>
157b5038d7SDag-Erling Smørgrav #endif
167b5038d7SDag-Erling Smørgrav
177b5038d7SDag-Erling Smørgrav /* query debug, 2 hex dumps */
187b5038d7SDag-Erling Smørgrav int verbosity;
197b5038d7SDag-Erling Smørgrav
20986ba33cSDag-Erling Smørgrav static int
is_ixfr_with_serial(const char * name,uint32_t * serial)21986ba33cSDag-Erling Smørgrav is_ixfr_with_serial(const char* name, uint32_t *serial)
22986ba33cSDag-Erling Smørgrav {
23986ba33cSDag-Erling Smørgrav char* end;
24986ba33cSDag-Erling Smørgrav if (strlen(name) > 5 &&
25986ba33cSDag-Erling Smørgrav strncasecmp(name, "IXFR", 4) == 0 &&
26986ba33cSDag-Erling Smørgrav name[4] == '=') {
27986ba33cSDag-Erling Smørgrav *serial = (uint32_t) strtol((name+5), &end, 10);
28986ba33cSDag-Erling Smørgrav return 1;
29986ba33cSDag-Erling Smørgrav }
30986ba33cSDag-Erling Smørgrav return 0;
31986ba33cSDag-Erling Smørgrav }
32986ba33cSDag-Erling Smørgrav
337b5038d7SDag-Erling Smørgrav static void
usage(FILE * stream,const char * progname)347b5038d7SDag-Erling Smørgrav usage(FILE *stream, const char *progname)
357b5038d7SDag-Erling Smørgrav {
367b5038d7SDag-Erling Smørgrav fprintf(stream, " Usage: %s name [@server] [type] [class]\n", progname);
377b5038d7SDag-Erling Smørgrav fprintf(stream, "\t<name> can be a domain name or an IP address (-x lookups)\n");
387b5038d7SDag-Erling Smørgrav fprintf(stream, "\t<type> defaults to A\n");
397b5038d7SDag-Erling Smørgrav fprintf(stream, "\t<class> defaults to IN\n");
407b5038d7SDag-Erling Smørgrav fprintf(stream, "\n\targuments may be placed in random order\n");
417b5038d7SDag-Erling Smørgrav fprintf(stream, "\n Options:\n");
427b5038d7SDag-Erling Smørgrav fprintf(stream, "\t-D\t\tenable DNSSEC (DO bit)\n");
437b5038d7SDag-Erling Smørgrav #ifdef HAVE_SSL
447b5038d7SDag-Erling Smørgrav fprintf(stream, "\t-T\t\ttrace from the root down to <name>\n");
45986ba33cSDag-Erling Smørgrav fprintf(stream, "\t-S\t\tchase signature(s) from <name> to a known key [*]\n");
467b5038d7SDag-Erling Smørgrav #endif /*HAVE_SSL*/
4717d15b25SDag-Erling Smørgrav fprintf(stream, "\t-I <address>\tsource address to query from\n");
487b5038d7SDag-Erling Smørgrav fprintf(stream, "\t-V <number>\tverbosity (0-5)\n");
497b5038d7SDag-Erling Smørgrav fprintf(stream, "\t-Q\t\tquiet mode (overrules -V)\n");
507b5038d7SDag-Erling Smørgrav fprintf(stream, "\n");
517b5038d7SDag-Erling Smørgrav fprintf(stream, "\t-f file\t\tread packet from file and send it\n");
527b5038d7SDag-Erling Smørgrav fprintf(stream, "\t-i file\t\tread packet from file and print it\n");
537b5038d7SDag-Erling Smørgrav fprintf(stream, "\t-w file\t\twrite answer packet to file\n");
547b5038d7SDag-Erling Smørgrav fprintf(stream, "\t-q file\t\twrite query packet to file\n");
557b5038d7SDag-Erling Smørgrav fprintf(stream, "\t-h\t\tshow this help\n");
567b5038d7SDag-Erling Smørgrav fprintf(stream, "\t-v\t\tshow version\n");
577b5038d7SDag-Erling Smørgrav fprintf(stream, "\n Query options:\n");
587b5038d7SDag-Erling Smørgrav fprintf(stream, "\t-4\t\tstay on ip4\n");
597b5038d7SDag-Erling Smørgrav fprintf(stream, "\t-6\t\tstay on ip6\n");
607b5038d7SDag-Erling Smørgrav fprintf(stream, "\t-a\t\tfallback to EDNS0 and TCP if the answer is truncated\n");
617b5038d7SDag-Erling Smørgrav fprintf(stream, "\t-b <bufsize>\tuse <bufsize> as the buffer size (defaults to 512 b)\n");
62*5afab0e5SDag-Erling Smørgrav fprintf(stream, "\t-c <file>\tuse file for recursive nameserver configuration"
632787e39aSDag-Erling Smørgrav "\n\t\t\t(/etc/resolv.conf)\n");
642787e39aSDag-Erling Smørgrav fprintf(stream, "\t-k <file>\tspecify a file that contains a trusted DNSSEC key [**]\n");
652787e39aSDag-Erling Smørgrav fprintf(stream, "\t\t\tUsed to verify any signatures in the current answer.\n");
662787e39aSDag-Erling Smørgrav fprintf(stream, "\t\t\tWhen DNSSEC enabled tracing (-TD) or signature\n"
672787e39aSDag-Erling Smørgrav "\t\t\tchasing (-S) and no key files are given, keys are read\n"
682787e39aSDag-Erling Smørgrav "\t\t\tfrom: %s\n",
692787e39aSDag-Erling Smørgrav LDNS_TRUST_ANCHOR_FILE);
702787e39aSDag-Erling Smørgrav fprintf(stream, "\t-o <mnemonic>\tset flags to:"
712787e39aSDag-Erling Smørgrav "\n\t\t\t[QR|qr][AA|aa][TC|tc][RD|rd][CD|cd][RA|ra][AD|ad]\n");
727b5038d7SDag-Erling Smørgrav fprintf(stream, "\t\t\tlowercase: unset bit, uppercase: set bit\n");
737b5038d7SDag-Erling Smørgrav fprintf(stream, "\t-p <port>\tuse <port> as remote port number\n");
747b5038d7SDag-Erling Smørgrav fprintf(stream, "\t-s\t\tshow the DS RR for each key in a packet\n");
757b5038d7SDag-Erling Smørgrav fprintf(stream, "\t-u\t\tsend the query with udp (the default)\n");
767b5038d7SDag-Erling Smørgrav fprintf(stream, "\t-x\t\tdo a reverse lookup\n");
777b5038d7SDag-Erling Smørgrav fprintf(stream, "\twhen doing a secure trace:\n");
782787e39aSDag-Erling Smørgrav fprintf(stream, "\t-r <file>\tuse file as root servers hint file\n");
797b5038d7SDag-Erling Smørgrav fprintf(stream, "\t-t\t\tsend the query with tcp (connected)\n");
802787e39aSDag-Erling Smørgrav fprintf(stream, "\t-d <domain>\tuse domain as the start point for the trace\n");
817b5038d7SDag-Erling Smørgrav fprintf(stream, "\t-y <name:key[:algo]>\tspecify named base64 tsig key, and optional an\n\t\t\talgorithm (defaults to hmac-md5.sig-alg.reg.int)\n");
827b5038d7SDag-Erling Smørgrav fprintf(stream, "\t-z\t\tdon't randomize the nameservers before use\n");
837b5038d7SDag-Erling Smørgrav fprintf(stream, "\n [*] = enables/implies DNSSEC\n");
847b5038d7SDag-Erling Smørgrav fprintf(stream, " [**] = can be given more than once\n");
857b5038d7SDag-Erling Smørgrav fprintf(stream, "\n ldns-team@nlnetlabs.nl | http://www.nlnetlabs.nl/ldns/\n");
867b5038d7SDag-Erling Smørgrav }
877b5038d7SDag-Erling Smørgrav
887b5038d7SDag-Erling Smørgrav /**
897b5038d7SDag-Erling Smørgrav * Prints the drill version to stderr
907b5038d7SDag-Erling Smørgrav */
917b5038d7SDag-Erling Smørgrav static void
version(FILE * stream,const char * progname)927b5038d7SDag-Erling Smørgrav version(FILE *stream, const char *progname)
937b5038d7SDag-Erling Smørgrav {
947b5038d7SDag-Erling Smørgrav fprintf(stream, "%s version %s (ldns version %s)\n", progname, DRILL_VERSION, ldns_version());
957b5038d7SDag-Erling Smørgrav fprintf(stream, "Written by NLnet Labs.\n");
967b5038d7SDag-Erling Smørgrav fprintf(stream, "\nCopyright (c) 2004-2008 NLnet Labs.\n");
977b5038d7SDag-Erling Smørgrav fprintf(stream, "Licensed under the revised BSD license.\n");
987b5038d7SDag-Erling Smørgrav fprintf(stream, "There is NO warranty; not even for MERCHANTABILITY or FITNESS\n");
997b5038d7SDag-Erling Smørgrav fprintf(stream, "FOR A PARTICULAR PURPOSE.\n");
1007b5038d7SDag-Erling Smørgrav }
1017b5038d7SDag-Erling Smørgrav
1027b5038d7SDag-Erling Smørgrav
1037b5038d7SDag-Erling Smørgrav /**
1047b5038d7SDag-Erling Smørgrav * Main function of drill
1057b5038d7SDag-Erling Smørgrav * parse the arguments and prepare a query
1067b5038d7SDag-Erling Smørgrav */
1077b5038d7SDag-Erling Smørgrav int
main(int argc,char * argv[])1087b5038d7SDag-Erling Smørgrav main(int argc, char *argv[])
1097b5038d7SDag-Erling Smørgrav {
1107b5038d7SDag-Erling Smørgrav ldns_resolver *res = NULL;
1117b5038d7SDag-Erling Smørgrav ldns_resolver *cmdline_res = NULL; /* only used to resolv @name names */
1127b5038d7SDag-Erling Smørgrav ldns_rr_list *cmdline_rr_list = NULL;
1137b5038d7SDag-Erling Smørgrav ldns_rdf *cmdline_dname = NULL;
114*5afab0e5SDag-Erling Smørgrav ldns_rdf *qname;
1157b5038d7SDag-Erling Smørgrav ldns_pkt *pkt;
1167b5038d7SDag-Erling Smørgrav ldns_pkt *qpkt;
1177b5038d7SDag-Erling Smørgrav char *serv;
11817d15b25SDag-Erling Smørgrav char *src = NULL;
1197b5038d7SDag-Erling Smørgrav const char *name;
1207b5038d7SDag-Erling Smørgrav char *progname;
1217b5038d7SDag-Erling Smørgrav char *query_file = NULL;
1227b5038d7SDag-Erling Smørgrav char *answer_file = NULL;
1237b5038d7SDag-Erling Smørgrav ldns_buffer *query_buffer = NULL;
1247b5038d7SDag-Erling Smørgrav ldns_rdf *serv_rdf;
12517d15b25SDag-Erling Smørgrav ldns_rdf *src_rdf = NULL;
1267b5038d7SDag-Erling Smørgrav ldns_rr_type type;
1277b5038d7SDag-Erling Smørgrav ldns_rr_class clas;
1287b5038d7SDag-Erling Smørgrav #if 0
1297b5038d7SDag-Erling Smørgrav ldns_pkt_opcode opcode = LDNS_PACKET_QUERY;
1307b5038d7SDag-Erling Smørgrav #endif
1317b5038d7SDag-Erling Smørgrav int i, c;
1327b5038d7SDag-Erling Smørgrav int int_type;
1337b5038d7SDag-Erling Smørgrav int int_clas;
1347b5038d7SDag-Erling Smørgrav int PURPOSE;
1357b5038d7SDag-Erling Smørgrav char *tsig_name = NULL;
1367b5038d7SDag-Erling Smørgrav char *tsig_data = NULL;
1377b5038d7SDag-Erling Smørgrav char *tsig_algorithm = NULL;
1387b5038d7SDag-Erling Smørgrav size_t tsig_separator;
1397b5038d7SDag-Erling Smørgrav size_t tsig_separator2;
1407b5038d7SDag-Erling Smørgrav ldns_rr *axfr_rr;
1417b5038d7SDag-Erling Smørgrav ldns_status status;
1427b5038d7SDag-Erling Smørgrav char *type_str;
143986ba33cSDag-Erling Smørgrav uint32_t serial = 0;
1447b5038d7SDag-Erling Smørgrav /* list of keys used in dnssec operations */
1457b5038d7SDag-Erling Smørgrav ldns_rr_list *key_list = ldns_rr_list_new();
1467b5038d7SDag-Erling Smørgrav /* what key verify the current answer */
1477b5038d7SDag-Erling Smørgrav ldns_rr_list *key_verified;
1487b5038d7SDag-Erling Smørgrav
1497b5038d7SDag-Erling Smørgrav /* resolver options */
1507b5038d7SDag-Erling Smørgrav uint16_t qflags;
1517b5038d7SDag-Erling Smørgrav uint16_t qbuf;
1527b5038d7SDag-Erling Smørgrav uint16_t qport;
1537b5038d7SDag-Erling Smørgrav uint8_t qfamily;
1547b5038d7SDag-Erling Smørgrav bool qdnssec;
1557b5038d7SDag-Erling Smørgrav bool qfallback;
1567b5038d7SDag-Erling Smørgrav bool qds;
1577b5038d7SDag-Erling Smørgrav bool qusevc;
1587b5038d7SDag-Erling Smørgrav bool qrandom;
159*5afab0e5SDag-Erling Smørgrav bool drill_reverse = false;
1607b5038d7SDag-Erling Smørgrav
1617b5038d7SDag-Erling Smørgrav char *resolv_conf_file = NULL;
1627b5038d7SDag-Erling Smørgrav
1637b5038d7SDag-Erling Smørgrav ldns_rdf *trace_start_name = NULL;
1647b5038d7SDag-Erling Smørgrav
1657b5038d7SDag-Erling Smørgrav int result = 0;
1667b5038d7SDag-Erling Smørgrav
167986ba33cSDag-Erling Smørgrav uint8_t s6addr[16];
168986ba33cSDag-Erling Smørgrav char ip6_arpa_str[74];
169*5afab0e5SDag-Erling Smørgrav uint8_t s4addr[4];
170*5afab0e5SDag-Erling Smørgrav char in_addr_arpa_str[40];
171986ba33cSDag-Erling Smørgrav
1727b5038d7SDag-Erling Smørgrav #ifdef USE_WINSOCK
1737b5038d7SDag-Erling Smørgrav int r;
1747b5038d7SDag-Erling Smørgrav WSADATA wsa_data;
1757b5038d7SDag-Erling Smørgrav #endif
176*5afab0e5SDag-Erling Smørgrav ldns_output_format_storage fmt_storage;
177*5afab0e5SDag-Erling Smørgrav ldns_output_format* fmt = ldns_output_format_init(&fmt_storage);
1787b5038d7SDag-Erling Smørgrav
1797b5038d7SDag-Erling Smørgrav int_type = -1; serv = NULL; type = 0;
1807b5038d7SDag-Erling Smørgrav int_clas = -1; name = NULL; clas = 0;
18117d15b25SDag-Erling Smørgrav qname = NULL; src = NULL;
1827b5038d7SDag-Erling Smørgrav progname = strdup(argv[0]);
1837b5038d7SDag-Erling Smørgrav
1847b5038d7SDag-Erling Smørgrav #ifdef USE_WINSOCK
1857b5038d7SDag-Erling Smørgrav r = WSAStartup(MAKEWORD(2,2), &wsa_data);
1867b5038d7SDag-Erling Smørgrav if(r != 0) {
1877b5038d7SDag-Erling Smørgrav printf("Failed WSAStartup: %d\n", r);
1887b5038d7SDag-Erling Smørgrav result = EXIT_FAILURE;
1897b5038d7SDag-Erling Smørgrav goto exit;
1907b5038d7SDag-Erling Smørgrav }
1917b5038d7SDag-Erling Smørgrav #endif /* USE_WINSOCK */
1927b5038d7SDag-Erling Smørgrav
1937b5038d7SDag-Erling Smørgrav
1947b5038d7SDag-Erling Smørgrav PURPOSE = DRILL_QUERY;
1957b5038d7SDag-Erling Smørgrav qflags = LDNS_RD;
1967b5038d7SDag-Erling Smørgrav qport = LDNS_PORT;
1977b5038d7SDag-Erling Smørgrav verbosity = 2;
1987b5038d7SDag-Erling Smørgrav qdnssec = false;
1997b5038d7SDag-Erling Smørgrav qfamily = LDNS_RESOLV_INETANY;
2007b5038d7SDag-Erling Smørgrav qfallback = false;
2017b5038d7SDag-Erling Smørgrav qds = false;
2027b5038d7SDag-Erling Smørgrav qbuf = 0;
2037b5038d7SDag-Erling Smørgrav qusevc = false;
2047b5038d7SDag-Erling Smørgrav qrandom = true;
2057b5038d7SDag-Erling Smørgrav key_verified = NULL;
206*5afab0e5SDag-Erling Smørgrav ldns_edns_option_list* edns_list = NULL;
2077b5038d7SDag-Erling Smørgrav
2087b5038d7SDag-Erling Smørgrav ldns_init_random(NULL, 0);
2097b5038d7SDag-Erling Smørgrav
2107b5038d7SDag-Erling Smørgrav /* string from orig drill: "i:w:I46Sk:TNp:b:DsvhVcuaq:f:xr" */
2117b5038d7SDag-Erling Smørgrav /* global first, query opt next, option with parm's last
2127b5038d7SDag-Erling Smørgrav * and sorted */ /* "46DITSVQf:i:w:q:achuvxzy:so:p:b:k:" */
2137b5038d7SDag-Erling Smørgrav
21417d15b25SDag-Erling Smørgrav while ((c = getopt(argc, argv, "46ab:c:d:Df:hi:I:k:o:p:q:Qr:sStTuvV:w:xy:z")) != -1) {
2157b5038d7SDag-Erling Smørgrav switch(c) {
2167b5038d7SDag-Erling Smørgrav /* global options */
2177b5038d7SDag-Erling Smørgrav case '4':
2187b5038d7SDag-Erling Smørgrav qfamily = LDNS_RESOLV_INET;
2197b5038d7SDag-Erling Smørgrav break;
2207b5038d7SDag-Erling Smørgrav case '6':
2217b5038d7SDag-Erling Smørgrav qfamily = LDNS_RESOLV_INET6;
2227b5038d7SDag-Erling Smørgrav break;
2237b5038d7SDag-Erling Smørgrav case 'D':
2247b5038d7SDag-Erling Smørgrav qdnssec = true;
2257b5038d7SDag-Erling Smørgrav break;
2267b5038d7SDag-Erling Smørgrav case 'I':
22717d15b25SDag-Erling Smørgrav src = optarg;
2287b5038d7SDag-Erling Smørgrav break;
2297b5038d7SDag-Erling Smørgrav case 'T':
2307b5038d7SDag-Erling Smørgrav if (PURPOSE == DRILL_CHASE) {
2317b5038d7SDag-Erling Smørgrav fprintf(stderr, "-T and -S cannot be used at the same time.\n");
2327b5038d7SDag-Erling Smørgrav exit(EXIT_FAILURE);
2337b5038d7SDag-Erling Smørgrav }
2347b5038d7SDag-Erling Smørgrav PURPOSE = DRILL_TRACE;
2357b5038d7SDag-Erling Smørgrav break;
2367b5038d7SDag-Erling Smørgrav #ifdef HAVE_SSL
2377b5038d7SDag-Erling Smørgrav case 'S':
2387b5038d7SDag-Erling Smørgrav if (PURPOSE == DRILL_TRACE) {
2397b5038d7SDag-Erling Smørgrav fprintf(stderr, "-T and -S cannot be used at the same time.\n");
2407b5038d7SDag-Erling Smørgrav exit(EXIT_FAILURE);
2417b5038d7SDag-Erling Smørgrav }
2427b5038d7SDag-Erling Smørgrav PURPOSE = DRILL_CHASE;
2437b5038d7SDag-Erling Smørgrav break;
2447b5038d7SDag-Erling Smørgrav #endif /* HAVE_SSL */
2457b5038d7SDag-Erling Smørgrav case 'V':
2467b5038d7SDag-Erling Smørgrav if (strtok(optarg, "0123456789") != NULL) {
2477b5038d7SDag-Erling Smørgrav fprintf(stderr, "-V expects an number as an argument.\n");
2487b5038d7SDag-Erling Smørgrav exit(EXIT_FAILURE);
2497b5038d7SDag-Erling Smørgrav }
2507b5038d7SDag-Erling Smørgrav verbosity = atoi(optarg);
2517b5038d7SDag-Erling Smørgrav break;
2527b5038d7SDag-Erling Smørgrav case 'Q':
253*5afab0e5SDag-Erling Smørgrav fmt->flags |= LDNS_FMT_SHORT;
2547b5038d7SDag-Erling Smørgrav verbosity = -1;
2557b5038d7SDag-Erling Smørgrav break;
2567b5038d7SDag-Erling Smørgrav case 'f':
2577b5038d7SDag-Erling Smørgrav query_file = optarg;
2587b5038d7SDag-Erling Smørgrav break;
2597b5038d7SDag-Erling Smørgrav case 'i':
2607b5038d7SDag-Erling Smørgrav answer_file = optarg;
2617b5038d7SDag-Erling Smørgrav PURPOSE = DRILL_AFROMFILE;
2627b5038d7SDag-Erling Smørgrav break;
2637b5038d7SDag-Erling Smørgrav case 'w':
2647b5038d7SDag-Erling Smørgrav answer_file = optarg;
2657b5038d7SDag-Erling Smørgrav break;
2667b5038d7SDag-Erling Smørgrav case 'q':
2677b5038d7SDag-Erling Smørgrav query_file = optarg;
2687b5038d7SDag-Erling Smørgrav PURPOSE = DRILL_QTOFILE;
2697b5038d7SDag-Erling Smørgrav break;
2707b5038d7SDag-Erling Smørgrav case 'r':
2717b5038d7SDag-Erling Smørgrav if (global_dns_root) {
2727b5038d7SDag-Erling Smørgrav fprintf(stderr, "There was already a series of root servers set\n");
2737b5038d7SDag-Erling Smørgrav exit(EXIT_FAILURE);
2747b5038d7SDag-Erling Smørgrav }
2757b5038d7SDag-Erling Smørgrav global_dns_root = read_root_hints(optarg);
2767b5038d7SDag-Erling Smørgrav if (!global_dns_root) {
2777b5038d7SDag-Erling Smørgrav fprintf(stderr, "Unable to read root hints file %s, aborting\n", optarg);
2787b5038d7SDag-Erling Smørgrav exit(EXIT_FAILURE);
2797b5038d7SDag-Erling Smørgrav }
2807b5038d7SDag-Erling Smørgrav break;
2817b5038d7SDag-Erling Smørgrav /* query options */
2827b5038d7SDag-Erling Smørgrav case 'a':
2837b5038d7SDag-Erling Smørgrav qfallback = true;
2847b5038d7SDag-Erling Smørgrav break;
2857b5038d7SDag-Erling Smørgrav case 'b':
2867b5038d7SDag-Erling Smørgrav qbuf = (uint16_t)atoi(optarg);
2877b5038d7SDag-Erling Smørgrav if (qbuf == 0) {
2887b5038d7SDag-Erling Smørgrav error("%s", "<bufsize> could not be converted");
2897b5038d7SDag-Erling Smørgrav }
2907b5038d7SDag-Erling Smørgrav break;
2917b5038d7SDag-Erling Smørgrav case 'c':
2927b5038d7SDag-Erling Smørgrav resolv_conf_file = optarg;
2937b5038d7SDag-Erling Smørgrav break;
2947b5038d7SDag-Erling Smørgrav case 't':
2957b5038d7SDag-Erling Smørgrav qusevc = true;
2967b5038d7SDag-Erling Smørgrav break;
2977b5038d7SDag-Erling Smørgrav case 'k':
2982787e39aSDag-Erling Smørgrav status = read_key_file(optarg,
2992787e39aSDag-Erling Smørgrav key_list, false);
3007b5038d7SDag-Erling Smørgrav if (status != LDNS_STATUS_OK) {
3017b5038d7SDag-Erling Smørgrav error("Could not parse the key file %s: %s", optarg, ldns_get_errorstr_by_id(status));
3027b5038d7SDag-Erling Smørgrav }
3037b5038d7SDag-Erling Smørgrav qdnssec = true; /* enable that too */
3047b5038d7SDag-Erling Smørgrav break;
3057b5038d7SDag-Erling Smørgrav case 'o':
3067b5038d7SDag-Erling Smørgrav /* only looks at the first hit: capital=ON, lowercase=OFF*/
3077b5038d7SDag-Erling Smørgrav if (strstr(optarg, "QR")) {
3087b5038d7SDag-Erling Smørgrav DRILL_ON(qflags, LDNS_QR);
3097b5038d7SDag-Erling Smørgrav }
3107b5038d7SDag-Erling Smørgrav if (strstr(optarg, "qr")) {
3117b5038d7SDag-Erling Smørgrav DRILL_OFF(qflags, LDNS_QR);
3127b5038d7SDag-Erling Smørgrav }
3137b5038d7SDag-Erling Smørgrav if (strstr(optarg, "AA")) {
3147b5038d7SDag-Erling Smørgrav DRILL_ON(qflags, LDNS_AA);
3157b5038d7SDag-Erling Smørgrav }
3167b5038d7SDag-Erling Smørgrav if (strstr(optarg, "aa")) {
3177b5038d7SDag-Erling Smørgrav DRILL_OFF(qflags, LDNS_AA);
3187b5038d7SDag-Erling Smørgrav }
3197b5038d7SDag-Erling Smørgrav if (strstr(optarg, "TC")) {
3207b5038d7SDag-Erling Smørgrav DRILL_ON(qflags, LDNS_TC);
3217b5038d7SDag-Erling Smørgrav }
3227b5038d7SDag-Erling Smørgrav if (strstr(optarg, "tc")) {
3237b5038d7SDag-Erling Smørgrav DRILL_OFF(qflags, LDNS_TC);
3247b5038d7SDag-Erling Smørgrav }
3257b5038d7SDag-Erling Smørgrav if (strstr(optarg, "RD")) {
3267b5038d7SDag-Erling Smørgrav DRILL_ON(qflags, LDNS_RD);
3277b5038d7SDag-Erling Smørgrav }
3287b5038d7SDag-Erling Smørgrav if (strstr(optarg, "rd")) {
3297b5038d7SDag-Erling Smørgrav DRILL_OFF(qflags, LDNS_RD);
3307b5038d7SDag-Erling Smørgrav }
3317b5038d7SDag-Erling Smørgrav if (strstr(optarg, "CD")) {
3327b5038d7SDag-Erling Smørgrav DRILL_ON(qflags, LDNS_CD);
3337b5038d7SDag-Erling Smørgrav }
3347b5038d7SDag-Erling Smørgrav if (strstr(optarg, "cd")) {
3357b5038d7SDag-Erling Smørgrav DRILL_OFF(qflags, LDNS_CD);
3367b5038d7SDag-Erling Smørgrav }
3377b5038d7SDag-Erling Smørgrav if (strstr(optarg, "RA")) {
3387b5038d7SDag-Erling Smørgrav DRILL_ON(qflags, LDNS_RA);
3397b5038d7SDag-Erling Smørgrav }
3407b5038d7SDag-Erling Smørgrav if (strstr(optarg, "ra")) {
3417b5038d7SDag-Erling Smørgrav DRILL_OFF(qflags, LDNS_RA);
3427b5038d7SDag-Erling Smørgrav }
3437b5038d7SDag-Erling Smørgrav if (strstr(optarg, "AD")) {
3447b5038d7SDag-Erling Smørgrav DRILL_ON(qflags, LDNS_AD);
3457b5038d7SDag-Erling Smørgrav }
3467b5038d7SDag-Erling Smørgrav if (strstr(optarg, "ad")) {
3477b5038d7SDag-Erling Smørgrav DRILL_OFF(qflags, LDNS_AD);
3487b5038d7SDag-Erling Smørgrav }
3497b5038d7SDag-Erling Smørgrav break;
3507b5038d7SDag-Erling Smørgrav case 'p':
3517b5038d7SDag-Erling Smørgrav qport = (uint16_t)atoi(optarg);
3527b5038d7SDag-Erling Smørgrav if (qport == 0) {
3537b5038d7SDag-Erling Smørgrav error("%s", "<port> could not be converted");
3547b5038d7SDag-Erling Smørgrav }
3557b5038d7SDag-Erling Smørgrav break;
3567b5038d7SDag-Erling Smørgrav case 's':
3577b5038d7SDag-Erling Smørgrav qds = true;
3587b5038d7SDag-Erling Smørgrav break;
3597b5038d7SDag-Erling Smørgrav case 'u':
3607b5038d7SDag-Erling Smørgrav qusevc = false;
3617b5038d7SDag-Erling Smørgrav break;
3627b5038d7SDag-Erling Smørgrav case 'v':
3637b5038d7SDag-Erling Smørgrav version(stdout, progname);
3647b5038d7SDag-Erling Smørgrav result = EXIT_SUCCESS;
3657b5038d7SDag-Erling Smørgrav goto exit;
3667b5038d7SDag-Erling Smørgrav case 'x':
367*5afab0e5SDag-Erling Smørgrav drill_reverse = true;
3687b5038d7SDag-Erling Smørgrav break;
3697b5038d7SDag-Erling Smørgrav case 'y':
3707b5038d7SDag-Erling Smørgrav #ifdef HAVE_SSL
3717b5038d7SDag-Erling Smørgrav if (strchr(optarg, ':')) {
3727b5038d7SDag-Erling Smørgrav tsig_separator = (size_t) (strchr(optarg, ':') - optarg);
373*5afab0e5SDag-Erling Smørgrav if (tsig_algorithm) {
374*5afab0e5SDag-Erling Smørgrav free(tsig_algorithm);
375*5afab0e5SDag-Erling Smørgrav tsig_algorithm = NULL;
376*5afab0e5SDag-Erling Smørgrav }
3777b5038d7SDag-Erling Smørgrav if (strchr(optarg + tsig_separator + 1, ':')) {
3787b5038d7SDag-Erling Smørgrav tsig_separator2 = (size_t) (strchr(optarg + tsig_separator + 1, ':') - optarg);
3797b5038d7SDag-Erling Smørgrav tsig_algorithm = xmalloc(strlen(optarg) - tsig_separator2);
3807b5038d7SDag-Erling Smørgrav strncpy(tsig_algorithm, optarg + tsig_separator2 + 1, strlen(optarg) - tsig_separator2);
3817b5038d7SDag-Erling Smørgrav tsig_algorithm[strlen(optarg) - tsig_separator2 - 1] = '\0';
3827b5038d7SDag-Erling Smørgrav } else {
3837b5038d7SDag-Erling Smørgrav tsig_separator2 = strlen(optarg);
384986ba33cSDag-Erling Smørgrav tsig_algorithm = strdup("hmac-md5.sig-alg.reg.int");
3857b5038d7SDag-Erling Smørgrav }
3867b5038d7SDag-Erling Smørgrav tsig_name = xmalloc(tsig_separator + 1);
3877b5038d7SDag-Erling Smørgrav tsig_data = xmalloc(tsig_separator2 - tsig_separator);
3887b5038d7SDag-Erling Smørgrav strncpy(tsig_name, optarg, tsig_separator);
3897b5038d7SDag-Erling Smørgrav strncpy(tsig_data, optarg + tsig_separator + 1, tsig_separator2 - tsig_separator - 1);
3907b5038d7SDag-Erling Smørgrav /* strncpy does not append \0 if source is longer than n */
3917b5038d7SDag-Erling Smørgrav tsig_name[tsig_separator] = '\0';
3927b5038d7SDag-Erling Smørgrav tsig_data[ tsig_separator2 - tsig_separator - 1] = '\0';
3937b5038d7SDag-Erling Smørgrav }
3947b5038d7SDag-Erling Smørgrav #else
3957b5038d7SDag-Erling Smørgrav fprintf(stderr, "TSIG requested, but SSL is not supported\n");
3967b5038d7SDag-Erling Smørgrav result = EXIT_FAILURE;
3977b5038d7SDag-Erling Smørgrav goto exit;
3987b5038d7SDag-Erling Smørgrav #endif /* HAVE_SSL */
3997b5038d7SDag-Erling Smørgrav break;
4007b5038d7SDag-Erling Smørgrav case 'z':
4017b5038d7SDag-Erling Smørgrav qrandom = false;
4027b5038d7SDag-Erling Smørgrav break;
4037b5038d7SDag-Erling Smørgrav case 'd':
4047b5038d7SDag-Erling Smørgrav trace_start_name = ldns_dname_new_frm_str(optarg);
4057b5038d7SDag-Erling Smørgrav if (!trace_start_name) {
4067b5038d7SDag-Erling Smørgrav fprintf(stderr, "Unable to parse argument for -%c\n", c);
4077b5038d7SDag-Erling Smørgrav result = EXIT_FAILURE;
4087b5038d7SDag-Erling Smørgrav goto exit;
4097b5038d7SDag-Erling Smørgrav }
4107b5038d7SDag-Erling Smørgrav break;
4117b5038d7SDag-Erling Smørgrav case 'h':
4127b5038d7SDag-Erling Smørgrav version(stdout, progname);
4137b5038d7SDag-Erling Smørgrav usage(stdout, progname);
4147b5038d7SDag-Erling Smørgrav result = EXIT_SUCCESS;
4157b5038d7SDag-Erling Smørgrav goto exit;
4167b5038d7SDag-Erling Smørgrav break;
4177b5038d7SDag-Erling Smørgrav default:
4187b5038d7SDag-Erling Smørgrav fprintf(stderr, "Unknown argument: -%c, use -h to see usage\n", c);
4197b5038d7SDag-Erling Smørgrav result = EXIT_FAILURE;
4207b5038d7SDag-Erling Smørgrav goto exit;
4217b5038d7SDag-Erling Smørgrav }
4227b5038d7SDag-Erling Smørgrav }
4237b5038d7SDag-Erling Smørgrav argc -= optind;
4247b5038d7SDag-Erling Smørgrav argv += optind;
4257b5038d7SDag-Erling Smørgrav
4262787e39aSDag-Erling Smørgrav if ((PURPOSE == DRILL_CHASE || (PURPOSE == DRILL_TRACE && qdnssec)) &&
4272787e39aSDag-Erling Smørgrav ldns_rr_list_rr_count(key_list) == 0) {
4282787e39aSDag-Erling Smørgrav
4292787e39aSDag-Erling Smørgrav (void) read_key_file(LDNS_TRUST_ANCHOR_FILE, key_list, true);
4302787e39aSDag-Erling Smørgrav }
4312787e39aSDag-Erling Smørgrav if (ldns_rr_list_rr_count(key_list) > 0) {
4322787e39aSDag-Erling Smørgrav printf(";; Number of trusted keys: %d\n",
4332787e39aSDag-Erling Smørgrav (int) ldns_rr_list_rr_count(key_list));
4342787e39aSDag-Erling Smørgrav }
4357b5038d7SDag-Erling Smørgrav /* do a secure trace when requested */
4367b5038d7SDag-Erling Smørgrav if (PURPOSE == DRILL_TRACE && qdnssec) {
4377b5038d7SDag-Erling Smørgrav #ifdef HAVE_SSL
4387b5038d7SDag-Erling Smørgrav if (ldns_rr_list_rr_count(key_list) == 0) {
4397b5038d7SDag-Erling Smørgrav warning("%s", "No trusted keys were given. Will not be able to verify authenticity!");
4407b5038d7SDag-Erling Smørgrav }
4417b5038d7SDag-Erling Smørgrav PURPOSE = DRILL_SECTRACE;
4427b5038d7SDag-Erling Smørgrav #else
4437b5038d7SDag-Erling Smørgrav fprintf(stderr, "ldns has not been compiled with OpenSSL support. Secure trace not available\n");
4447b5038d7SDag-Erling Smørgrav exit(1);
4457b5038d7SDag-Erling Smørgrav #endif /* HAVE_SSL */
4467b5038d7SDag-Erling Smørgrav }
4477b5038d7SDag-Erling Smørgrav
4487b5038d7SDag-Erling Smørgrav /* parse the arguments, with multiple arguments, the last argument
4497b5038d7SDag-Erling Smørgrav * found is used */
4507b5038d7SDag-Erling Smørgrav for(i = 0; i < argc; i++) {
4517b5038d7SDag-Erling Smørgrav
4527b5038d7SDag-Erling Smørgrav /* if ^@ then it's a server */
4537b5038d7SDag-Erling Smørgrav if (argv[i][0] == '@') {
4547b5038d7SDag-Erling Smørgrav if (strlen(argv[i]) == 1) {
4557b5038d7SDag-Erling Smørgrav warning("%s", "No nameserver given");
4567b5038d7SDag-Erling Smørgrav exit(EXIT_FAILURE);
4577b5038d7SDag-Erling Smørgrav }
4587b5038d7SDag-Erling Smørgrav serv = argv[i] + 1;
4597b5038d7SDag-Erling Smørgrav continue;
4607b5038d7SDag-Erling Smørgrav }
461*5afab0e5SDag-Erling Smørgrav /* if ^+ then it's an EDNS option */
462*5afab0e5SDag-Erling Smørgrav if (argv[i][0] == '+') {
463*5afab0e5SDag-Erling Smørgrav if (!strcmp(argv[i]+1, "nsid")) {
464*5afab0e5SDag-Erling Smørgrav ldns_edns_option *edns;
465*5afab0e5SDag-Erling Smørgrav edns_list = ldns_edns_option_list_new();
466*5afab0e5SDag-Erling Smørgrav
467*5afab0e5SDag-Erling Smørgrav /* create NSID EDNS*/
468*5afab0e5SDag-Erling Smørgrav edns = ldns_edns_new_from_data(LDNS_EDNS_NSID, 0, NULL);
469*5afab0e5SDag-Erling Smørgrav
470*5afab0e5SDag-Erling Smørgrav if (edns_list == NULL || edns == NULL) {
471*5afab0e5SDag-Erling Smørgrav error("EDNS option could not be allocated");
472*5afab0e5SDag-Erling Smørgrav break;
473*5afab0e5SDag-Erling Smørgrav }
474*5afab0e5SDag-Erling Smørgrav
475*5afab0e5SDag-Erling Smørgrav if (!(ldns_edns_option_list_push(edns_list, edns))) {
476*5afab0e5SDag-Erling Smørgrav error("EDNS option NSID could not be attached");
477*5afab0e5SDag-Erling Smørgrav break;
478*5afab0e5SDag-Erling Smørgrav }
479*5afab0e5SDag-Erling Smørgrav continue;
480*5afab0e5SDag-Erling Smørgrav }
481*5afab0e5SDag-Erling Smørgrav else {
482*5afab0e5SDag-Erling Smørgrav error("Unsupported argument after '+'");
483*5afab0e5SDag-Erling Smørgrav break;
484*5afab0e5SDag-Erling Smørgrav }
485*5afab0e5SDag-Erling Smørgrav }
4867b5038d7SDag-Erling Smørgrav /* if has a dot, it's a name */
4877b5038d7SDag-Erling Smørgrav if (strchr(argv[i], '.')) {
4887b5038d7SDag-Erling Smørgrav name = argv[i];
4897b5038d7SDag-Erling Smørgrav continue;
4907b5038d7SDag-Erling Smørgrav }
4917b5038d7SDag-Erling Smørgrav /* if it matches a type, it's a type */
4927b5038d7SDag-Erling Smørgrav if (int_type == -1) {
4937b5038d7SDag-Erling Smørgrav type = ldns_get_rr_type_by_name(argv[i]);
4947b5038d7SDag-Erling Smørgrav if (type != 0) {
4957b5038d7SDag-Erling Smørgrav int_type = 0;
4967b5038d7SDag-Erling Smørgrav continue;
497986ba33cSDag-Erling Smørgrav } else if (is_ixfr_with_serial(argv[i], &serial)) {
498986ba33cSDag-Erling Smørgrav type = LDNS_RR_TYPE_IXFR;
499986ba33cSDag-Erling Smørgrav int_type = 0;
500986ba33cSDag-Erling Smørgrav continue;
5017b5038d7SDag-Erling Smørgrav }
5027b5038d7SDag-Erling Smørgrav }
5037b5038d7SDag-Erling Smørgrav /* if it matches a class, it's a class */
5047b5038d7SDag-Erling Smørgrav if (int_clas == -1) {
5057b5038d7SDag-Erling Smørgrav clas = ldns_get_rr_class_by_name(argv[i]);
5067b5038d7SDag-Erling Smørgrav if (clas != 0) {
5077b5038d7SDag-Erling Smørgrav int_clas = 0;
5087b5038d7SDag-Erling Smørgrav continue;
5097b5038d7SDag-Erling Smørgrav }
5107b5038d7SDag-Erling Smørgrav }
5117b5038d7SDag-Erling Smørgrav /* it all fails assume it's a name */
5127b5038d7SDag-Erling Smørgrav name = argv[i];
5137b5038d7SDag-Erling Smørgrav }
5147b5038d7SDag-Erling Smørgrav /* act like dig and use for . NS */
5157b5038d7SDag-Erling Smørgrav if (!name) {
5167b5038d7SDag-Erling Smørgrav name = ".";
5177b5038d7SDag-Erling Smørgrav int_type = 0;
5187b5038d7SDag-Erling Smørgrav type = LDNS_RR_TYPE_NS;
5197b5038d7SDag-Erling Smørgrav }
5207b5038d7SDag-Erling Smørgrav
5217b5038d7SDag-Erling Smørgrav /* defaults if not given */
5227b5038d7SDag-Erling Smørgrav if (int_clas == -1) {
5237b5038d7SDag-Erling Smørgrav clas = LDNS_RR_CLASS_IN;
5247b5038d7SDag-Erling Smørgrav }
5257b5038d7SDag-Erling Smørgrav if (int_type == -1) {
526*5afab0e5SDag-Erling Smørgrav if (!drill_reverse) {
5277b5038d7SDag-Erling Smørgrav type = LDNS_RR_TYPE_A;
5287b5038d7SDag-Erling Smørgrav } else {
5297b5038d7SDag-Erling Smørgrav type = LDNS_RR_TYPE_PTR;
5307b5038d7SDag-Erling Smørgrav }
5317b5038d7SDag-Erling Smørgrav }
532*5afab0e5SDag-Erling Smørgrav if (!drill_reverse)
533*5afab0e5SDag-Erling Smørgrav ; /* pass */
534*5afab0e5SDag-Erling Smørgrav else if (strchr(name, ':')) { /* ipv4 or ipv6 addr? */
535*5afab0e5SDag-Erling Smørgrav if (!inet_pton(AF_INET6, name, &s6addr)) {
536*5afab0e5SDag-Erling Smørgrav error("Syntax error: cannot parse IPv6 address\n");
537*5afab0e5SDag-Erling Smørgrav }
538*5afab0e5SDag-Erling Smørgrav (void) snprintf(ip6_arpa_str, sizeof(ip6_arpa_str),
539*5afab0e5SDag-Erling Smørgrav "%x.%x.%x.%x.%x.%x.%x.%x."
540*5afab0e5SDag-Erling Smørgrav "%x.%x.%x.%x.%x.%x.%x.%x."
541*5afab0e5SDag-Erling Smørgrav "%x.%x.%x.%x.%x.%x.%x.%x."
542*5afab0e5SDag-Erling Smørgrav "%x.%x.%x.%x.%x.%x.%x.%x.ip6.arpa.",
543*5afab0e5SDag-Erling Smørgrav (unsigned int)(s6addr[15] & 0x0F),
544*5afab0e5SDag-Erling Smørgrav (unsigned int)(s6addr[15] >> 4),
545*5afab0e5SDag-Erling Smørgrav (unsigned int)(s6addr[14] & 0x0F),
546*5afab0e5SDag-Erling Smørgrav (unsigned int)(s6addr[14] >> 4),
547*5afab0e5SDag-Erling Smørgrav (unsigned int)(s6addr[13] & 0x0F),
548*5afab0e5SDag-Erling Smørgrav (unsigned int)(s6addr[13] >> 4),
549*5afab0e5SDag-Erling Smørgrav (unsigned int)(s6addr[12] & 0x0F),
550*5afab0e5SDag-Erling Smørgrav (unsigned int)(s6addr[12] >> 4),
551*5afab0e5SDag-Erling Smørgrav (unsigned int)(s6addr[11] & 0x0F),
552*5afab0e5SDag-Erling Smørgrav (unsigned int)(s6addr[11] >> 4),
553*5afab0e5SDag-Erling Smørgrav (unsigned int)(s6addr[10] & 0x0F),
554*5afab0e5SDag-Erling Smørgrav (unsigned int)(s6addr[10] >> 4),
555*5afab0e5SDag-Erling Smørgrav (unsigned int)(s6addr[9] & 0x0F),
556*5afab0e5SDag-Erling Smørgrav (unsigned int)(s6addr[9] >> 4),
557*5afab0e5SDag-Erling Smørgrav (unsigned int)(s6addr[8] & 0x0F),
558*5afab0e5SDag-Erling Smørgrav (unsigned int)(s6addr[8] >> 4),
559*5afab0e5SDag-Erling Smørgrav (unsigned int)(s6addr[7] & 0x0F),
560*5afab0e5SDag-Erling Smørgrav (unsigned int)(s6addr[7] >> 4),
561*5afab0e5SDag-Erling Smørgrav (unsigned int)(s6addr[6] & 0x0F),
562*5afab0e5SDag-Erling Smørgrav (unsigned int)(s6addr[6] >> 4),
563*5afab0e5SDag-Erling Smørgrav (unsigned int)(s6addr[5] & 0x0F),
564*5afab0e5SDag-Erling Smørgrav (unsigned int)(s6addr[5] >> 4),
565*5afab0e5SDag-Erling Smørgrav (unsigned int)(s6addr[4] & 0x0F),
566*5afab0e5SDag-Erling Smørgrav (unsigned int)(s6addr[4] >> 4),
567*5afab0e5SDag-Erling Smørgrav (unsigned int)(s6addr[3] & 0x0F),
568*5afab0e5SDag-Erling Smørgrav (unsigned int)(s6addr[3] >> 4),
569*5afab0e5SDag-Erling Smørgrav (unsigned int)(s6addr[2] & 0x0F),
570*5afab0e5SDag-Erling Smørgrav (unsigned int)(s6addr[2] >> 4),
571*5afab0e5SDag-Erling Smørgrav (unsigned int)(s6addr[1] & 0x0F),
572*5afab0e5SDag-Erling Smørgrav (unsigned int)(s6addr[1] >> 4),
573*5afab0e5SDag-Erling Smørgrav (unsigned int)(s6addr[0] & 0x0F),
574*5afab0e5SDag-Erling Smørgrav (unsigned int)(s6addr[0] >> 4));
575*5afab0e5SDag-Erling Smørgrav name = ip6_arpa_str;
576*5afab0e5SDag-Erling Smørgrav
577*5afab0e5SDag-Erling Smørgrav } else if (!inet_pton(AF_INET, name, &s4addr)) {
578*5afab0e5SDag-Erling Smørgrav error("Syntax error: cannot parse IPv4 address\n");
579*5afab0e5SDag-Erling Smørgrav
580*5afab0e5SDag-Erling Smørgrav } else {
581*5afab0e5SDag-Erling Smørgrav (void) snprintf(in_addr_arpa_str, sizeof(in_addr_arpa_str),
582*5afab0e5SDag-Erling Smørgrav "%d.%d.%d.%d.in-addr.arpa.", (int)s4addr[3],
583*5afab0e5SDag-Erling Smørgrav (int)s4addr[2], (int)s4addr[1], (int)s4addr[0]);
584*5afab0e5SDag-Erling Smørgrav name = in_addr_arpa_str;
585*5afab0e5SDag-Erling Smørgrav }
5867b5038d7SDag-Erling Smørgrav
58717d15b25SDag-Erling Smørgrav if (src) {
58817d15b25SDag-Erling Smørgrav src_rdf = ldns_rdf_new_addr_frm_str(src);
58917d15b25SDag-Erling Smørgrav if(!src_rdf) {
590986ba33cSDag-Erling Smørgrav fprintf(stderr, "-I must be a valid IP[v6] address.\n");
59117d15b25SDag-Erling Smørgrav exit(EXIT_FAILURE);
59217d15b25SDag-Erling Smørgrav }
593986ba33cSDag-Erling Smørgrav if (ldns_rdf_size(src_rdf) == 4) {
594986ba33cSDag-Erling Smørgrav qfamily = LDNS_RESOLV_INET;
595986ba33cSDag-Erling Smørgrav
596986ba33cSDag-Erling Smørgrav } else if (ldns_rdf_size(src_rdf) == 16) {
597986ba33cSDag-Erling Smørgrav qfamily = LDNS_RESOLV_INET6;
598986ba33cSDag-Erling Smørgrav }
59917d15b25SDag-Erling Smørgrav }
60017d15b25SDag-Erling Smørgrav
6017b5038d7SDag-Erling Smørgrav /* set the nameserver to use */
6027b5038d7SDag-Erling Smørgrav if (!serv) {
603986ba33cSDag-Erling Smørgrav /* no server given -- make a resolver from /etc/resolv.conf */
6047b5038d7SDag-Erling Smørgrav status = ldns_resolver_new_frm_file(&res, resolv_conf_file);
6057b5038d7SDag-Erling Smørgrav if (status != LDNS_STATUS_OK) {
6067b5038d7SDag-Erling Smørgrav warning("Could not create a resolver structure: %s (%s)\n"
6077b5038d7SDag-Erling Smørgrav "Try drill @localhost if you have a resolver running on your machine.",
6087b5038d7SDag-Erling Smørgrav ldns_get_errorstr_by_id(status), resolv_conf_file);
6097b5038d7SDag-Erling Smørgrav result = EXIT_FAILURE;
6107b5038d7SDag-Erling Smørgrav goto exit;
6117b5038d7SDag-Erling Smørgrav }
6127b5038d7SDag-Erling Smørgrav } else {
6137b5038d7SDag-Erling Smørgrav res = ldns_resolver_new();
6147b5038d7SDag-Erling Smørgrav if (!res || strlen(serv) <= 0) {
6157b5038d7SDag-Erling Smørgrav warning("Could not create a resolver structure");
6167b5038d7SDag-Erling Smørgrav result = EXIT_FAILURE;
6177b5038d7SDag-Erling Smørgrav goto exit;
6187b5038d7SDag-Erling Smørgrav }
6197b5038d7SDag-Erling Smørgrav /* add the nameserver */
6207b5038d7SDag-Erling Smørgrav serv_rdf = ldns_rdf_new_addr_frm_str(serv);
6217b5038d7SDag-Erling Smørgrav if (!serv_rdf) {
6227b5038d7SDag-Erling Smørgrav /* try to resolv the name if possible */
6237b5038d7SDag-Erling Smørgrav status = ldns_resolver_new_frm_file(&cmdline_res, resolv_conf_file);
6247b5038d7SDag-Erling Smørgrav
6257b5038d7SDag-Erling Smørgrav if (status != LDNS_STATUS_OK) {
6267b5038d7SDag-Erling Smørgrav error("%s", "@server ip could not be converted");
6277b5038d7SDag-Erling Smørgrav }
6287b5038d7SDag-Erling Smørgrav ldns_resolver_set_dnssec(cmdline_res, qdnssec);
6297b5038d7SDag-Erling Smørgrav ldns_resolver_set_ip6(cmdline_res, qfamily);
6307b5038d7SDag-Erling Smørgrav ldns_resolver_set_fallback(cmdline_res, qfallback);
6317b5038d7SDag-Erling Smørgrav ldns_resolver_set_usevc(cmdline_res, qusevc);
63217d15b25SDag-Erling Smørgrav ldns_resolver_set_source(cmdline_res, src_rdf);
6337b5038d7SDag-Erling Smørgrav
6347b5038d7SDag-Erling Smørgrav cmdline_dname = ldns_dname_new_frm_str(serv);
6357b5038d7SDag-Erling Smørgrav
6367b5038d7SDag-Erling Smørgrav cmdline_rr_list = ldns_get_rr_list_addr_by_name(
6377b5038d7SDag-Erling Smørgrav cmdline_res,
6387b5038d7SDag-Erling Smørgrav cmdline_dname,
6397b5038d7SDag-Erling Smørgrav LDNS_RR_CLASS_IN,
6407b5038d7SDag-Erling Smørgrav qflags);
6417b5038d7SDag-Erling Smørgrav ldns_rdf_deep_free(cmdline_dname);
6427b5038d7SDag-Erling Smørgrav if (!cmdline_rr_list) {
6437b5038d7SDag-Erling Smørgrav /* This error msg is not always accurate */
6447b5038d7SDag-Erling Smørgrav error("%s `%s\'", "could not find any address for the name:", serv);
6457b5038d7SDag-Erling Smørgrav } else {
6467b5038d7SDag-Erling Smørgrav if (ldns_resolver_push_nameserver_rr_list(
6477b5038d7SDag-Erling Smørgrav res,
6487b5038d7SDag-Erling Smørgrav cmdline_rr_list
6497b5038d7SDag-Erling Smørgrav ) != LDNS_STATUS_OK) {
6507b5038d7SDag-Erling Smørgrav error("%s", "pushing nameserver");
6517b5038d7SDag-Erling Smørgrav }
6527b5038d7SDag-Erling Smørgrav }
6537b5038d7SDag-Erling Smørgrav } else {
6547b5038d7SDag-Erling Smørgrav if (ldns_resolver_push_nameserver(res, serv_rdf) != LDNS_STATUS_OK) {
6557b5038d7SDag-Erling Smørgrav error("%s", "pushing nameserver");
6567b5038d7SDag-Erling Smørgrav } else {
6577b5038d7SDag-Erling Smørgrav ldns_rdf_deep_free(serv_rdf);
6587b5038d7SDag-Erling Smørgrav }
6597b5038d7SDag-Erling Smørgrav }
6607b5038d7SDag-Erling Smørgrav }
6617b5038d7SDag-Erling Smørgrav /* set the resolver options */
662986ba33cSDag-Erling Smørgrav ldns_resolver_set_ixfr_serial(res, serial);
6637b5038d7SDag-Erling Smørgrav ldns_resolver_set_port(res, qport);
66417d15b25SDag-Erling Smørgrav ldns_resolver_set_source(res, src_rdf);
6657b5038d7SDag-Erling Smørgrav if (verbosity >= 5) {
6667b5038d7SDag-Erling Smørgrav ldns_resolver_set_debug(res, true);
6677b5038d7SDag-Erling Smørgrav } else {
6687b5038d7SDag-Erling Smørgrav ldns_resolver_set_debug(res, false);
6697b5038d7SDag-Erling Smørgrav }
6707b5038d7SDag-Erling Smørgrav ldns_resolver_set_dnssec(res, qdnssec);
6717b5038d7SDag-Erling Smørgrav /* ldns_resolver_set_dnssec_cd(res, qdnssec);*/
6727b5038d7SDag-Erling Smørgrav ldns_resolver_set_ip6(res, qfamily);
6737b5038d7SDag-Erling Smørgrav ldns_resolver_set_fallback(res, qfallback);
6747b5038d7SDag-Erling Smørgrav ldns_resolver_set_usevc(res, qusevc);
6757b5038d7SDag-Erling Smørgrav ldns_resolver_set_random(res, qrandom);
6767b5038d7SDag-Erling Smørgrav if (qbuf != 0) {
6777b5038d7SDag-Erling Smørgrav ldns_resolver_set_edns_udp_size(res, qbuf);
6787b5038d7SDag-Erling Smørgrav }
6797b5038d7SDag-Erling Smørgrav
6807b5038d7SDag-Erling Smørgrav if (!name &&
6817b5038d7SDag-Erling Smørgrav PURPOSE != DRILL_AFROMFILE &&
6827b5038d7SDag-Erling Smørgrav !query_file
6837b5038d7SDag-Erling Smørgrav ) {
6847b5038d7SDag-Erling Smørgrav usage(stdout, progname);
6857b5038d7SDag-Erling Smørgrav result = EXIT_FAILURE;
6867b5038d7SDag-Erling Smørgrav goto exit;
6877b5038d7SDag-Erling Smørgrav }
6887b5038d7SDag-Erling Smørgrav
6897b5038d7SDag-Erling Smørgrav if (tsig_name && tsig_data) {
690986ba33cSDag-Erling Smørgrav /* With dig TSIG keys are also specified with -y,
691986ba33cSDag-Erling Smørgrav * but format with drill is: -y <name:key[:algo]>
692986ba33cSDag-Erling Smørgrav * and with dig: -y [hmac:]name:key
693986ba33cSDag-Erling Smørgrav *
694986ba33cSDag-Erling Smørgrav * When we detect an unknown tsig algorithm in algo,
695986ba33cSDag-Erling Smørgrav * but a known algorithm in name, we cane assume dig
696986ba33cSDag-Erling Smørgrav * order was used.
697986ba33cSDag-Erling Smørgrav *
698986ba33cSDag-Erling Smørgrav * Following if statement is to anticipate and correct dig order
699986ba33cSDag-Erling Smørgrav */
700986ba33cSDag-Erling Smørgrav if ( strcasecmp(tsig_algorithm, "hmac-md5.sig-alg.reg.int")
701986ba33cSDag-Erling Smørgrav && strcasecmp(tsig_algorithm, "hmac-md5")
702986ba33cSDag-Erling Smørgrav && strcasecmp(tsig_algorithm, "hmac-sha1")
703986ba33cSDag-Erling Smørgrav && strcasecmp(tsig_algorithm, "hmac-sha256")
704986ba33cSDag-Erling Smørgrav && (
705986ba33cSDag-Erling Smørgrav strcasecmp(tsig_name, "hmac-md5.sig-alg.reg.int") == 0
706986ba33cSDag-Erling Smørgrav || strcasecmp(tsig_name, "hmac-md5") == 0
707986ba33cSDag-Erling Smørgrav || strcasecmp(tsig_name, "hmac-sha1") == 0
708986ba33cSDag-Erling Smørgrav || strcasecmp(tsig_name, "hmac-sha256") == 0
709986ba33cSDag-Erling Smørgrav )) {
710986ba33cSDag-Erling Smørgrav
711986ba33cSDag-Erling Smørgrav /* Roll options */
712986ba33cSDag-Erling Smørgrav char *tmp_tsig_algorithm = tsig_name;
713986ba33cSDag-Erling Smørgrav tsig_name = tsig_data;
714986ba33cSDag-Erling Smørgrav tsig_data = tsig_algorithm;
715986ba33cSDag-Erling Smørgrav tsig_algorithm = tmp_tsig_algorithm;
716986ba33cSDag-Erling Smørgrav }
717986ba33cSDag-Erling Smørgrav
718986ba33cSDag-Erling Smørgrav if (strcasecmp(tsig_algorithm, "hmac-md5") == 0) {
719986ba33cSDag-Erling Smørgrav free(tsig_algorithm);
720986ba33cSDag-Erling Smørgrav tsig_algorithm = strdup("hmac-md5.sig-alg.reg.int");
721986ba33cSDag-Erling Smørgrav }
722986ba33cSDag-Erling Smørgrav
7237b5038d7SDag-Erling Smørgrav ldns_resolver_set_tsig_keyname(res, tsig_name);
7247b5038d7SDag-Erling Smørgrav ldns_resolver_set_tsig_keydata(res, tsig_data);
7257b5038d7SDag-Erling Smørgrav ldns_resolver_set_tsig_algorithm(res, tsig_algorithm);
7267b5038d7SDag-Erling Smørgrav }
7277b5038d7SDag-Erling Smørgrav
7287b5038d7SDag-Erling Smørgrav /* main switching part of drill */
7297b5038d7SDag-Erling Smørgrav switch(PURPOSE) {
7307b5038d7SDag-Erling Smørgrav case DRILL_TRACE:
7317b5038d7SDag-Erling Smørgrav /* do a trace from the root down */
7327b5038d7SDag-Erling Smørgrav if (!global_dns_root) {
7337b5038d7SDag-Erling Smørgrav init_root();
7347b5038d7SDag-Erling Smørgrav }
7357b5038d7SDag-Erling Smørgrav qname = ldns_dname_new_frm_str(name);
7367b5038d7SDag-Erling Smørgrav if (!qname) {
7377b5038d7SDag-Erling Smørgrav error("%s", "parsing query name");
7387b5038d7SDag-Erling Smørgrav }
7397b5038d7SDag-Erling Smørgrav /* don't care about return packet */
740986ba33cSDag-Erling Smørgrav do_trace(res, qname, type, clas);
7417b5038d7SDag-Erling Smørgrav clear_root();
7427b5038d7SDag-Erling Smørgrav break;
7437b5038d7SDag-Erling Smørgrav case DRILL_SECTRACE:
7447b5038d7SDag-Erling Smørgrav /* do a secure trace from the root down */
7457b5038d7SDag-Erling Smørgrav if (!global_dns_root) {
7467b5038d7SDag-Erling Smørgrav init_root();
7477b5038d7SDag-Erling Smørgrav }
7487b5038d7SDag-Erling Smørgrav qname = ldns_dname_new_frm_str(name);
7497b5038d7SDag-Erling Smørgrav if (!qname) {
7507b5038d7SDag-Erling Smørgrav error("%s", "making qname");
7517b5038d7SDag-Erling Smørgrav }
7527b5038d7SDag-Erling Smørgrav /* don't care about return packet */
7537b5038d7SDag-Erling Smørgrav #ifdef HAVE_SSL
7547b5038d7SDag-Erling Smørgrav result = do_secure_trace(res, qname, type, clas, key_list, trace_start_name);
7557b5038d7SDag-Erling Smørgrav #endif /* HAVE_SSL */
7567b5038d7SDag-Erling Smørgrav clear_root();
7577b5038d7SDag-Erling Smørgrav break;
7587b5038d7SDag-Erling Smørgrav case DRILL_CHASE:
7597b5038d7SDag-Erling Smørgrav qname = ldns_dname_new_frm_str(name);
7607b5038d7SDag-Erling Smørgrav if (!qname) {
7617b5038d7SDag-Erling Smørgrav error("%s", "making qname");
7627b5038d7SDag-Erling Smørgrav }
7637b5038d7SDag-Erling Smørgrav
7647b5038d7SDag-Erling Smørgrav ldns_resolver_set_dnssec(res, true);
7657b5038d7SDag-Erling Smørgrav ldns_resolver_set_dnssec_cd(res, true);
7667b5038d7SDag-Erling Smørgrav /* set dnssec implies udp_size of 4096 */
7677b5038d7SDag-Erling Smørgrav ldns_resolver_set_edns_udp_size(res, 4096);
76817d15b25SDag-Erling Smørgrav pkt = NULL;
76917d15b25SDag-Erling Smørgrav status = ldns_resolver_query_status(
77017d15b25SDag-Erling Smørgrav &pkt, res, qname, type, clas, qflags);
77117d15b25SDag-Erling Smørgrav if (status != LDNS_STATUS_OK) {
77217d15b25SDag-Erling Smørgrav error("error sending query: %s",
77317d15b25SDag-Erling Smørgrav ldns_get_errorstr_by_id(status));
77417d15b25SDag-Erling Smørgrav }
7757b5038d7SDag-Erling Smørgrav if (!pkt) {
77617d15b25SDag-Erling Smørgrav if (status == LDNS_STATUS_OK) {
7777b5038d7SDag-Erling Smørgrav error("%s", "error pkt sending");
77817d15b25SDag-Erling Smørgrav }
7797b5038d7SDag-Erling Smørgrav result = EXIT_FAILURE;
7807b5038d7SDag-Erling Smørgrav } else {
7817b5038d7SDag-Erling Smørgrav if (verbosity >= 3) {
7827b5038d7SDag-Erling Smørgrav ldns_pkt_print(stdout, pkt);
7837b5038d7SDag-Erling Smørgrav }
7847b5038d7SDag-Erling Smørgrav
7857b5038d7SDag-Erling Smørgrav if (!ldns_pkt_answer(pkt)) {
7867b5038d7SDag-Erling Smørgrav mesg("No answer in packet");
7877b5038d7SDag-Erling Smørgrav } else {
7887b5038d7SDag-Erling Smørgrav #ifdef HAVE_SSL
7897b5038d7SDag-Erling Smørgrav ldns_resolver_set_dnssec_anchors(res, ldns_rr_list_clone(key_list));
7907b5038d7SDag-Erling Smørgrav result = do_chase(res, qname, type,
7917b5038d7SDag-Erling Smørgrav clas, key_list,
792986ba33cSDag-Erling Smørgrav pkt, qflags, NULL);
7937b5038d7SDag-Erling Smørgrav if (result == LDNS_STATUS_OK) {
7947b5038d7SDag-Erling Smørgrav if (verbosity != -1) {
7957b5038d7SDag-Erling Smørgrav mesg("Chase successful");
7967b5038d7SDag-Erling Smørgrav }
7977b5038d7SDag-Erling Smørgrav result = 0;
7987b5038d7SDag-Erling Smørgrav } else {
7997b5038d7SDag-Erling Smørgrav if (verbosity != -1) {
8007b5038d7SDag-Erling Smørgrav mesg("Chase failed.");
8017b5038d7SDag-Erling Smørgrav }
8027b5038d7SDag-Erling Smørgrav }
8037b5038d7SDag-Erling Smørgrav #endif /* HAVE_SSL */
8047b5038d7SDag-Erling Smørgrav }
8057b5038d7SDag-Erling Smørgrav ldns_pkt_free(pkt);
8067b5038d7SDag-Erling Smørgrav }
8077b5038d7SDag-Erling Smørgrav break;
8087b5038d7SDag-Erling Smørgrav case DRILL_AFROMFILE:
8097b5038d7SDag-Erling Smørgrav pkt = read_hex_pkt(answer_file);
8107b5038d7SDag-Erling Smørgrav if (pkt) {
8117b5038d7SDag-Erling Smørgrav if (verbosity != -1) {
8127b5038d7SDag-Erling Smørgrav ldns_pkt_print(stdout, pkt);
8137b5038d7SDag-Erling Smørgrav }
8147b5038d7SDag-Erling Smørgrav ldns_pkt_free(pkt);
8157b5038d7SDag-Erling Smørgrav }
8167b5038d7SDag-Erling Smørgrav
8177b5038d7SDag-Erling Smørgrav break;
8187b5038d7SDag-Erling Smørgrav case DRILL_QTOFILE:
8197b5038d7SDag-Erling Smørgrav qname = ldns_dname_new_frm_str(name);
8207b5038d7SDag-Erling Smørgrav if (!qname) {
8217b5038d7SDag-Erling Smørgrav error("%s", "making qname");
8227b5038d7SDag-Erling Smørgrav }
8237b5038d7SDag-Erling Smørgrav status = ldns_resolver_prepare_query_pkt(&qpkt, res, qname, type, clas, qflags);
8247b5038d7SDag-Erling Smørgrav if(status != LDNS_STATUS_OK) {
8257b5038d7SDag-Erling Smørgrav error("%s", "making query: %s",
8267b5038d7SDag-Erling Smørgrav ldns_get_errorstr_by_id(status));
8277b5038d7SDag-Erling Smørgrav }
8287b5038d7SDag-Erling Smørgrav dump_hex(qpkt, query_file);
8297b5038d7SDag-Erling Smørgrav ldns_pkt_free(qpkt);
8307b5038d7SDag-Erling Smørgrav break;
8317b5038d7SDag-Erling Smørgrav case DRILL_NSEC:
8327b5038d7SDag-Erling Smørgrav break;
8337b5038d7SDag-Erling Smørgrav case DRILL_QUERY:
8347b5038d7SDag-Erling Smørgrav default:
8357b5038d7SDag-Erling Smørgrav if (query_file) {
8367b5038d7SDag-Erling Smørgrav /* this old way, the query packet needed
8377b5038d7SDag-Erling Smørgrav to be parseable, but we want to be able
8387b5038d7SDag-Erling Smørgrav to send mangled packets, so we need
8397b5038d7SDag-Erling Smørgrav to do it directly */
8407b5038d7SDag-Erling Smørgrav #if 0
8417b5038d7SDag-Erling Smørgrav qpkt = read_hex_pkt(query_file);
8427b5038d7SDag-Erling Smørgrav if (qpkt) {
8437b5038d7SDag-Erling Smørgrav status = ldns_resolver_send_pkt(&pkt, res, qpkt);
8447b5038d7SDag-Erling Smørgrav if (status != LDNS_STATUS_OK) {
8457b5038d7SDag-Erling Smørgrav printf("Error: %s\n", ldns_get_errorstr_by_id(status));
8467b5038d7SDag-Erling Smørgrav exit(1);
8477b5038d7SDag-Erling Smørgrav }
8487b5038d7SDag-Erling Smørgrav } else {
8497b5038d7SDag-Erling Smørgrav /* qpkt was bogus, reset pkt */
8507b5038d7SDag-Erling Smørgrav pkt = NULL;
8517b5038d7SDag-Erling Smørgrav }
8527b5038d7SDag-Erling Smørgrav #endif
8537b5038d7SDag-Erling Smørgrav query_buffer = read_hex_buffer(query_file);
8547b5038d7SDag-Erling Smørgrav if (query_buffer) {
8557b5038d7SDag-Erling Smørgrav status = ldns_send_buffer(&pkt, res, query_buffer, NULL);
8567b5038d7SDag-Erling Smørgrav ldns_buffer_free(query_buffer);
8577b5038d7SDag-Erling Smørgrav if (status != LDNS_STATUS_OK) {
8587b5038d7SDag-Erling Smørgrav printf("Error: %s\n", ldns_get_errorstr_by_id(status));
8597b5038d7SDag-Erling Smørgrav exit(1);
8607b5038d7SDag-Erling Smørgrav }
8617b5038d7SDag-Erling Smørgrav } else {
8627b5038d7SDag-Erling Smørgrav printf("NO BUFFER\n");
8637b5038d7SDag-Erling Smørgrav pkt = NULL;
8647b5038d7SDag-Erling Smørgrav }
8657b5038d7SDag-Erling Smørgrav } else {
8667b5038d7SDag-Erling Smørgrav qname = ldns_dname_new_frm_str(name);
8677b5038d7SDag-Erling Smørgrav if (!qname) {
8687b5038d7SDag-Erling Smørgrav error("%s", "error in making qname");
8697b5038d7SDag-Erling Smørgrav }
8707b5038d7SDag-Erling Smørgrav
8717b5038d7SDag-Erling Smørgrav if (type == LDNS_RR_TYPE_AXFR) {
8727b5038d7SDag-Erling Smørgrav status = ldns_axfr_start(res, qname, clas);
8737b5038d7SDag-Erling Smørgrav if(status != LDNS_STATUS_OK) {
8747b5038d7SDag-Erling Smørgrav error("Error starting axfr: %s",
8757b5038d7SDag-Erling Smørgrav ldns_get_errorstr_by_id(status));
8767b5038d7SDag-Erling Smørgrav }
8777b5038d7SDag-Erling Smørgrav axfr_rr = ldns_axfr_next(res);
8787b5038d7SDag-Erling Smørgrav if(!axfr_rr) {
8797b5038d7SDag-Erling Smørgrav fprintf(stderr, "AXFR failed.\n");
8807b5038d7SDag-Erling Smørgrav ldns_pkt_print(stdout,
8817b5038d7SDag-Erling Smørgrav ldns_axfr_last_pkt(res));
8827b5038d7SDag-Erling Smørgrav goto exit;
8837b5038d7SDag-Erling Smørgrav }
8847b5038d7SDag-Erling Smørgrav while (axfr_rr) {
8857b5038d7SDag-Erling Smørgrav if (verbosity != -1) {
8867b5038d7SDag-Erling Smørgrav ldns_rr_print(stdout, axfr_rr);
8877b5038d7SDag-Erling Smørgrav }
8887b5038d7SDag-Erling Smørgrav ldns_rr_free(axfr_rr);
8897b5038d7SDag-Erling Smørgrav axfr_rr = ldns_axfr_next(res);
8907b5038d7SDag-Erling Smørgrav }
8917b5038d7SDag-Erling Smørgrav
8927b5038d7SDag-Erling Smørgrav goto exit;
8937b5038d7SDag-Erling Smørgrav } else {
8947b5038d7SDag-Erling Smørgrav /* create a packet and set the RD flag on it */
89517d15b25SDag-Erling Smørgrav pkt = NULL;
896*5afab0e5SDag-Erling Smørgrav
897*5afab0e5SDag-Erling Smørgrav status = ldns_resolver_prepare_query_pkt(&qpkt,
898*5afab0e5SDag-Erling Smørgrav res, qname, type, clas, qflags);
899*5afab0e5SDag-Erling Smørgrav if(status != LDNS_STATUS_OK) {
900*5afab0e5SDag-Erling Smørgrav error("%s", "making query: %s",
901*5afab0e5SDag-Erling Smørgrav ldns_get_errorstr_by_id(status));
902*5afab0e5SDag-Erling Smørgrav }
903*5afab0e5SDag-Erling Smørgrav
904*5afab0e5SDag-Erling Smørgrav if (edns_list) {
905*5afab0e5SDag-Erling Smørgrav /* attach the structed EDNS options */
906*5afab0e5SDag-Erling Smørgrav ldns_pkt_set_edns_option_list(qpkt, edns_list);
907*5afab0e5SDag-Erling Smørgrav }
908*5afab0e5SDag-Erling Smørgrav
909*5afab0e5SDag-Erling Smørgrav status = ldns_resolver_send_pkt(&pkt, res, qpkt);
910*5afab0e5SDag-Erling Smørgrav ldns_pkt_free(qpkt);
911*5afab0e5SDag-Erling Smørgrav
91217d15b25SDag-Erling Smørgrav if (status != LDNS_STATUS_OK) {
91317d15b25SDag-Erling Smørgrav error("error sending query: %s"
91417d15b25SDag-Erling Smørgrav , ldns_get_errorstr_by_id(
91517d15b25SDag-Erling Smørgrav status));
91617d15b25SDag-Erling Smørgrav }
9177b5038d7SDag-Erling Smørgrav }
9187b5038d7SDag-Erling Smørgrav }
9197b5038d7SDag-Erling Smørgrav
920*5afab0e5SDag-Erling Smørgrav /* now handling the response message/packet */
9217b5038d7SDag-Erling Smørgrav if (!pkt) {
9227b5038d7SDag-Erling Smørgrav mesg("No packet received");
9237b5038d7SDag-Erling Smørgrav result = EXIT_FAILURE;
9247b5038d7SDag-Erling Smørgrav } else {
925*5afab0e5SDag-Erling Smørgrav ldns_pkt_print_fmt(stdout, fmt, pkt);
9267b5038d7SDag-Erling Smørgrav if (verbosity != -1) {
9277b5038d7SDag-Erling Smørgrav if (ldns_pkt_tc(pkt)) {
9287b5038d7SDag-Erling Smørgrav fprintf(stdout,
9297b5038d7SDag-Erling Smørgrav "\n;; WARNING: The answer packet was truncated; you might want to\n");
9307b5038d7SDag-Erling Smørgrav fprintf(stdout,
9317b5038d7SDag-Erling Smørgrav ";; query again with TCP (-t argument), or EDNS0 (-b for buffer size)\n");
9327b5038d7SDag-Erling Smørgrav }
9337b5038d7SDag-Erling Smørgrav }
9347b5038d7SDag-Erling Smørgrav if (qds) {
9357b5038d7SDag-Erling Smørgrav if (verbosity != -1) {
9367b5038d7SDag-Erling Smørgrav print_ds_of_keys(pkt);
9377b5038d7SDag-Erling Smørgrav printf("\n");
9387b5038d7SDag-Erling Smørgrav }
9397b5038d7SDag-Erling Smørgrav }
9407b5038d7SDag-Erling Smørgrav
9417b5038d7SDag-Erling Smørgrav if (ldns_rr_list_rr_count(key_list) > 0) {
9427b5038d7SDag-Erling Smørgrav /* -k's were given on the cmd line */
9437b5038d7SDag-Erling Smørgrav ldns_rr_list *rrset_verified;
9447b5038d7SDag-Erling Smørgrav uint16_t key_count;
9457b5038d7SDag-Erling Smørgrav
9467b5038d7SDag-Erling Smørgrav rrset_verified = ldns_pkt_rr_list_by_name_and_type(
9477b5038d7SDag-Erling Smørgrav pkt, qname, type,
9487b5038d7SDag-Erling Smørgrav LDNS_SECTION_ANY_NOQUESTION);
9497b5038d7SDag-Erling Smørgrav
9507b5038d7SDag-Erling Smørgrav if (type == LDNS_RR_TYPE_ANY) {
9517b5038d7SDag-Erling Smørgrav /* don't verify this */
9527b5038d7SDag-Erling Smørgrav break;
9537b5038d7SDag-Erling Smørgrav }
9547b5038d7SDag-Erling Smørgrav
9557b5038d7SDag-Erling Smørgrav if (verbosity != -1) {
9567b5038d7SDag-Erling Smørgrav printf("; ");
9577b5038d7SDag-Erling Smørgrav ldns_rr_list_print(stdout, rrset_verified);
9587b5038d7SDag-Erling Smørgrav }
9597b5038d7SDag-Erling Smørgrav
9607b5038d7SDag-Erling Smørgrav /* verify */
9617b5038d7SDag-Erling Smørgrav #ifdef HAVE_SSL
9627b5038d7SDag-Erling Smørgrav key_verified = ldns_rr_list_new();
9637b5038d7SDag-Erling Smørgrav result = ldns_pkt_verify(pkt, type, qname, key_list, NULL, key_verified);
9647b5038d7SDag-Erling Smørgrav
9657b5038d7SDag-Erling Smørgrav if (result == LDNS_STATUS_ERR) {
9667b5038d7SDag-Erling Smørgrav /* is the existence denied then? */
9677b5038d7SDag-Erling Smørgrav result = ldns_verify_denial(pkt, qname, type, NULL, NULL);
9687b5038d7SDag-Erling Smørgrav if (result == LDNS_STATUS_OK) {
9697b5038d7SDag-Erling Smørgrav if (verbosity != -1) {
9707b5038d7SDag-Erling Smørgrav printf("Existence denied for ");
9717b5038d7SDag-Erling Smørgrav ldns_rdf_print(stdout, qname);
9727b5038d7SDag-Erling Smørgrav type_str = ldns_rr_type2str(type);
9737b5038d7SDag-Erling Smørgrav printf("\t%s\n", type_str);
9747b5038d7SDag-Erling Smørgrav LDNS_FREE(type_str);
9757b5038d7SDag-Erling Smørgrav }
9767b5038d7SDag-Erling Smørgrav } else {
9777b5038d7SDag-Erling Smørgrav if (verbosity != -1) {
9787b5038d7SDag-Erling Smørgrav printf("Bad data; RR for name and "
9797b5038d7SDag-Erling Smørgrav "type not found or failed to "
9807b5038d7SDag-Erling Smørgrav "verify, and denial of "
9817b5038d7SDag-Erling Smørgrav "existence failed.\n");
9827b5038d7SDag-Erling Smørgrav }
9837b5038d7SDag-Erling Smørgrav }
9847b5038d7SDag-Erling Smørgrav } else if (result == LDNS_STATUS_OK) {
9857b5038d7SDag-Erling Smørgrav for(key_count = 0; key_count < ldns_rr_list_rr_count(key_verified);
9867b5038d7SDag-Erling Smørgrav key_count++) {
9877b5038d7SDag-Erling Smørgrav if (verbosity != -1) {
9887b5038d7SDag-Erling Smørgrav printf("; VALIDATED by id = %u, owner = ",
9897b5038d7SDag-Erling Smørgrav (unsigned int)ldns_calc_keytag(
9907b5038d7SDag-Erling Smørgrav ldns_rr_list_rr(key_verified, key_count)));
9917b5038d7SDag-Erling Smørgrav ldns_rdf_print(stdout, ldns_rr_owner(
9927b5038d7SDag-Erling Smørgrav ldns_rr_list_rr(key_list, key_count)));
9937b5038d7SDag-Erling Smørgrav printf("\n");
9947b5038d7SDag-Erling Smørgrav }
9957b5038d7SDag-Erling Smørgrav }
9967b5038d7SDag-Erling Smørgrav } else {
9977b5038d7SDag-Erling Smørgrav for(key_count = 0; key_count < ldns_rr_list_rr_count(key_list);
9987b5038d7SDag-Erling Smørgrav key_count++) {
9997b5038d7SDag-Erling Smørgrav if (verbosity != -1) {
10007b5038d7SDag-Erling Smørgrav printf("; %s for id = %u, owner = ",
10017b5038d7SDag-Erling Smørgrav ldns_get_errorstr_by_id(result),
10027b5038d7SDag-Erling Smørgrav (unsigned int)ldns_calc_keytag(
10037b5038d7SDag-Erling Smørgrav ldns_rr_list_rr(key_list, key_count)));
10047b5038d7SDag-Erling Smørgrav ldns_rdf_print(stdout, ldns_rr_owner(
10057b5038d7SDag-Erling Smørgrav
10067b5038d7SDag-Erling Smørgrav ldns_rr_list_rr(key_list,
10077b5038d7SDag-Erling Smørgrav key_count)));
10087b5038d7SDag-Erling Smørgrav printf("\n");
10097b5038d7SDag-Erling Smørgrav }
10107b5038d7SDag-Erling Smørgrav }
10117b5038d7SDag-Erling Smørgrav }
10127b5038d7SDag-Erling Smørgrav ldns_rr_list_free(key_verified);
10137b5038d7SDag-Erling Smørgrav #else
10147b5038d7SDag-Erling Smørgrav (void) key_count;
10157b5038d7SDag-Erling Smørgrav #endif /* HAVE_SSL */
10167b5038d7SDag-Erling Smørgrav }
10177b5038d7SDag-Erling Smørgrav if (answer_file) {
10187b5038d7SDag-Erling Smørgrav dump_hex(pkt, answer_file);
10197b5038d7SDag-Erling Smørgrav }
10207b5038d7SDag-Erling Smørgrav ldns_pkt_free(pkt);
10217b5038d7SDag-Erling Smørgrav }
10227b5038d7SDag-Erling Smørgrav
10237b5038d7SDag-Erling Smørgrav break;
10247b5038d7SDag-Erling Smørgrav }
10257b5038d7SDag-Erling Smørgrav
10267b5038d7SDag-Erling Smørgrav exit:
10277b5038d7SDag-Erling Smørgrav ldns_rdf_deep_free(qname);
102817d15b25SDag-Erling Smørgrav ldns_rdf_deep_free(src_rdf);
10297b5038d7SDag-Erling Smørgrav ldns_resolver_deep_free(res);
10307b5038d7SDag-Erling Smørgrav ldns_resolver_deep_free(cmdline_res);
10317b5038d7SDag-Erling Smørgrav ldns_rr_list_deep_free(key_list);
10327b5038d7SDag-Erling Smørgrav ldns_rr_list_deep_free(cmdline_rr_list);
10337b5038d7SDag-Erling Smørgrav ldns_rdf_deep_free(trace_start_name);
10347b5038d7SDag-Erling Smørgrav xfree(progname);
10357b5038d7SDag-Erling Smørgrav xfree(tsig_name);
10367b5038d7SDag-Erling Smørgrav xfree(tsig_data);
10377b5038d7SDag-Erling Smørgrav xfree(tsig_algorithm);
10387b5038d7SDag-Erling Smørgrav
10397b5038d7SDag-Erling Smørgrav #ifdef HAVE_SSL
1040*5afab0e5SDag-Erling Smørgrav #if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(HAVE_LIBRESSL)
1041*5afab0e5SDag-Erling Smørgrav #ifdef HAVE_CRYPTO_CLEANUP_ALL_EX_DATA
10427b5038d7SDag-Erling Smørgrav CRYPTO_cleanup_all_ex_data ();
1043*5afab0e5SDag-Erling Smørgrav #endif
1044*5afab0e5SDag-Erling Smørgrav #ifdef HAVE_ERR_FREE_STRINGS
10457b5038d7SDag-Erling Smørgrav ERR_free_strings ();
1046*5afab0e5SDag-Erling Smørgrav #endif
1047*5afab0e5SDag-Erling Smørgrav #ifdef HAVE_EVP_CLEANUP
10487b5038d7SDag-Erling Smørgrav EVP_cleanup ();
10497b5038d7SDag-Erling Smørgrav #endif
1050*5afab0e5SDag-Erling Smørgrav #endif
1051*5afab0e5SDag-Erling Smørgrav #endif
10527b5038d7SDag-Erling Smørgrav #ifdef USE_WINSOCK
10537b5038d7SDag-Erling Smørgrav WSACleanup();
10547b5038d7SDag-Erling Smørgrav #endif
10557b5038d7SDag-Erling Smørgrav
10567b5038d7SDag-Erling Smørgrav return result;
10577b5038d7SDag-Erling Smørgrav }
1058