1 /*        $NetBSD: test_dns_lookup.c,v 1.4 2025/02/25 19:15:44 christos Exp $   */
2 
3 /*++
4 /* NAME
5 /*        test_dns_lookup 1
6 /* SUMMARY
7 /*        DNS lookup test program
8 /* SYNOPSIS
9 /*        test_dns_lookup query-type domain-name
10 /* DESCRIPTION
11 /*        test_dns_lookup performs a DNS query of the specified resource
12 /*        type for the specified resource name.
13 /* DIAGNOSTICS
14 /*        Problems are reported to the standard error stream.
15 /* LICENSE
16 /* .ad
17 /* .fi
18 /*        The Secure Mailer license must be distributed with this software.
19 /* AUTHOR(S)
20 /*        Wietse Venema
21 /*        IBM T.J. Watson Research
22 /*        P.O. Box 704
23 /*        Yorktown Heights, NY 10598, USA
24 /*
25 /*        Wietse Venema
26 /*        Google, Inc.
27 /*        111 8th Avenue
28 /*        New York, NY 10011, USA
29 /*--*/
30 
31 /* System library. */
32 
33 #include <sys_defs.h>
34 #include <netinet/in.h>
35 #include <arpa/inet.h>
36 #include <stdlib.h>
37 
38 /* Utility library. */
39 
40 #include <vstring.h>
41 #include <msg.h>
42 #include <msg_vstream.h>
43 #include <mymalloc.h>
44 #include <argv.h>
45 
46 /* Global library. */
47 
48 #include <mail_params.h>
49 
50 /* Application-specific. */
51 
52 #include "dns.h"
53 
print_rr(VSTRING * buf,DNS_RR * rr)54 static void print_rr(VSTRING *buf, DNS_RR *rr)
55 {
56     while (rr) {
57           vstream_printf("ad: %u, rr: %s\n",
58                            rr->dnssec_valid, dns_strrecord(buf, rr));
59           rr = rr->next;
60     }
61 }
62 
usage(char ** argv)63 static NORETURN usage(char **argv)
64 {
65     msg_fatal("usage: %s [-npv] [-f filter] types name", argv[0]);
66 }
67 
main(int argc,char ** argv)68 int     main(int argc, char **argv)
69 {
70     ARGV   *types_argv;
71     unsigned *types;
72     char   *name;
73     VSTRING *fqdn = vstring_alloc(100);
74     VSTRING *why = vstring_alloc(100);
75     VSTRING *buf;
76     int     rcode;
77     DNS_RR *rr;
78     int     i;
79     int     ch;
80     int     lflags = DNS_REQ_FLAG_NONE;
81 
82     var_dnssec_probe = "";
83 
84     msg_vstream_init(argv[0], VSTREAM_ERR);
85     while ((ch = GETOPT(argc, argv, "f:l:npvs")) > 0) {
86           switch (ch) {
87           case 'v':
88               msg_verbose++;
89               break;
90           case 'f':
91               dns_rr_filter_compile("DNS reply filter", optarg);
92               break;
93           case 'l':
94               var_dns_rr_list_limit = atoi(optarg);
95               break;
96           case 'n':
97               lflags |= DNS_REQ_FLAG_NCACHE_TTL;
98               break;
99           case 'p':
100               var_dns_ncache_ttl_fix = 1;
101               break;
102           case 's':
103               var_dnssec_probe = DEF_DNSSEC_PROBE;
104               break;
105           default:
106               usage(argv);
107           }
108     }
109     if (argc != optind + 2)
110           usage(argv);
111     types_argv = argv_split(argv[optind], CHARS_COMMA_SP);
112     types = (unsigned *) mymalloc(sizeof(*types) * (types_argv->argc + 1));
113     for (i = 0; i < types_argv->argc; i++)
114           if ((types[i] = dns_type(types_argv->argv[i])) == 0)
115               msg_fatal("invalid query type: %s", types_argv->argv[i]);
116     types[i] = 0;
117     argv_free(types_argv);
118     name = argv[optind + 1];
119     msg_verbose = 1;
120     switch (dns_lookup_rv(name, RES_USE_DNSSEC, &rr, fqdn, why,
121                                 &rcode, lflags, types)) {
122     default:
123           msg_warn("%s (rcode=%d)", vstring_str(why), rcode);
124     case DNS_OK:
125           if (rr) {
126               vstream_printf("%s: fqdn: %s\n", name, vstring_str(fqdn));
127               buf = vstring_alloc(100);
128               print_rr(buf, rr);
129               vstream_fflush(VSTREAM_OUT);
130               if (DNS_RR_IS_TRUNCATED(rr))
131                     msg_warn("one or more excess DNS_RR records were dropped");
132               dns_rr_free(rr);
133               vstring_free(buf);
134           }
135     }
136     myfree((void *) types);
137     exit(0);
138 }
139