1/*++
2/* NAME
3/*	test_dns_lookup 1
4/* SUMMARY
5/*	DNS lookup test program
6/* SYNOPSIS
7/*	test_dns_lookup query-type domain-name
8/* DESCRIPTION
9/*	test_dns_lookup performs a DNS query of the specified resource
10/*	type for the specified resource name.
11/* DIAGNOSTICS
12/*	Problems are reported to the standard error stream.
13/* LICENSE
14/* .ad
15/* .fi
16/*	The Secure Mailer license must be distributed with this software.
17/* AUTHOR(S)
18/*	Wietse Venema
19/*	IBM T.J. Watson Research
20/*	P.O. Box 704
21/*	Yorktown Heights, NY 10598, USA
22/*--*/
23
24/* System library. */
25
26#include <sys_defs.h>
27#include <netinet/in.h>
28#include <arpa/inet.h>
29#include <stdlib.h>
30
31/* Utility library. */
32
33#include <vstring.h>
34#include <msg.h>
35#include <msg_vstream.h>
36#include <mymalloc.h>
37#include <argv.h>
38
39/* Application-specific. */
40
41#include "dns.h"
42
43static void print_rr(DNS_RR *rr)
44{
45    MAI_HOSTADDR_STR host;
46    size_t  i;
47
48    while (rr) {
49	printf("%s: ad: %u, ttl: %9u ", rr->rname, rr->dnssec_valid, rr->ttl);
50	switch (rr->type) {
51	case T_A:
52#ifdef T_AAAA
53	case T_AAAA:
54#endif
55	    if (dns_rr_to_pa(rr, &host) == 0)
56		msg_fatal("conversion error for resource record type %s: %m",
57			  dns_strtype(rr->type));
58	    printf("%s: %s\n", dns_strtype(rr->type), host.buf);
59	    break;
60	case T_CNAME:
61	case T_DNAME:
62	case T_MB:
63	case T_MG:
64	case T_MR:
65	case T_NS:
66	case T_PTR:
67	case T_TXT:
68	    printf("%s: %s\n", dns_strtype(rr->type), rr->data);
69	    break;
70	case T_MX:
71	    printf("pref: %d %s: %s\n",
72		   rr->pref, dns_strtype(rr->type), rr->data);
73	    break;
74	case T_TLSA:
75	    if (rr->data_len >= 3) {
76		uint8_t *ip = (uint8_t *) rr->data;
77		uint8_t usage = *ip++;
78		uint8_t selector = *ip++;
79		uint8_t mtype = *ip++;
80
81		printf("%s: %d %d %d ", dns_strtype(rr->type),
82		       usage, selector, mtype);
83		for (i = 3; i < rr->data_len; ++i)
84		    printf("%02x", *ip++);
85		putchar('\n');
86	    } else {
87		printf("%s: truncated record\n", dns_strtype(rr->type));
88	    }
89	    break;
90	default:
91	    msg_fatal("print_rr: don't know how to print type %s",
92		      dns_strtype(rr->type));
93	}
94	rr = rr->next;
95    }
96}
97
98int     main(int argc, char **argv)
99{
100    ARGV   *types_argv;
101    unsigned *types;
102    char   *name;
103    VSTRING *fqdn = vstring_alloc(100);
104    VSTRING *why = vstring_alloc(100);
105    int     rcode;
106    DNS_RR *rr;
107    int     i;
108
109    msg_vstream_init(argv[0], VSTREAM_ERR);
110    if (argc != 3)
111	msg_fatal("usage: %s types name", argv[0]);
112    types_argv = argv_split(argv[1], ", \t\r\n");
113    types = (unsigned *) mymalloc(sizeof(*types) * (types_argv->argc + 1));
114    for (i = 0; i < types_argv->argc; i++)
115	if ((types[i] = dns_type(types_argv->argv[i])) == 0)
116	    msg_fatal("invalid query type: %s", types_argv->argv[i]);
117    types[i] = 0;
118    argv_free(types_argv);
119    name = argv[2];
120    msg_verbose = 1;
121    switch (dns_lookup_rv(name, RES_DEBUG | RES_USE_DNSSEC, &rr, fqdn, why,
122			  &rcode, DNS_REQ_FLAG_NONE, types)) {
123    default:
124	msg_fatal("%s (rcode=%d)", vstring_str(why), rcode);
125    case DNS_OK:
126	printf("%s: fqdn: %s\n", name, vstring_str(fqdn));
127	print_rr(rr);
128	dns_rr_free(rr);
129    }
130    myfree((char *) types);
131    exit(0);
132}
133