summaryrefslogtreecommitdiff
path: root/usr.bin/dnsquery/dnsquery.c
diff options
context:
space:
mode:
Diffstat (limited to 'usr.bin/dnsquery/dnsquery.c')
-rw-r--r--usr.bin/dnsquery/dnsquery.c202
1 files changed, 202 insertions, 0 deletions
diff --git a/usr.bin/dnsquery/dnsquery.c b/usr.bin/dnsquery/dnsquery.c
new file mode 100644
index 000000000000..d28f9294900b
--- /dev/null
+++ b/usr.bin/dnsquery/dnsquery.c
@@ -0,0 +1,202 @@
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/nameser.h>
+#include <netdb.h>
+#include <resolv.h>
+#include <errno.h>
+
+#include "../conf/portability.h"
+
+extern int errno;
+extern int h_errno;
+extern char *h_errlist[];
+
+main(argc, argv)
+int argc;
+char *argv[];
+{
+ char name[MAXDNAME];
+ u_char answer[8*1024];
+ register int c, i = 0;
+ unsigned long ul;
+ int nameservers = 0, class, type, len;
+ struct in_addr q_nsaddr[MAXNS];
+ struct hostent *q_nsname;
+ extern int optind, opterr;
+ extern char *optarg;
+ HEADER *hp;
+ int stream = 0, debug = 0;
+
+ /* set defaults */
+ len = MAXDNAME;
+ gethostname(name, len);
+ class = C_IN;
+ type = T_ANY;
+
+ /* if no args, exit */
+ if (argc == 1) {
+ fprintf(stderr, "Usage: %s [-h] host [-n ns] [-t type] [-c class] [-r retry] [-p period] [-s] [-v] [-d] [-a]\n", argv[0]);
+ exit(-1);
+ }
+
+ /* handle args */
+ while ((c = getopt(argc, argv, "c:dh:n:p:r:st:u:v")) != EOF) {
+ switch (c) {
+
+ case 'r' : _res.retry = atoi(optarg);
+ break;
+
+ case 'p' : _res.retrans = atoi(optarg);
+ break;
+
+ case 'h' : strcpy(name, optarg);
+ break;
+
+ case 'c' : if (!strcasecmp(optarg, "IN"))
+ class = C_IN;
+ else if (!strcasecmp(optarg, "HS"))
+ class = C_HS;
+ else if (!strcasecmp(optarg, "CHAOS"))
+ class = C_CHAOS;
+ else if (!strcasecmp(optarg, "ANY"))
+ class = C_ANY;
+ else {
+ class = T_ANY;
+ fprintf(stderr, "optarg=%s\n", optarg);
+ }
+ break;
+
+ case 't' : if (!strcasecmp(optarg, "A"))
+ type = T_A;
+ else if (!strcasecmp(optarg, "NS"))
+ type = T_NS;
+ else if (!strcasecmp(optarg, "CNAME"))
+ type = T_CNAME;
+ else if (!strcasecmp(optarg, "SOA"))
+ type = T_SOA;
+ else if (!strcasecmp(optarg, "WKS"))
+ type = T_WKS;
+ else if (!strcasecmp(optarg, "PTR"))
+ type = T_PTR;
+ else if (!strcasecmp(optarg, "HINFO"))
+ type = T_HINFO;
+ else if (!strcasecmp(optarg, "MINFO"))
+ type = T_MINFO;
+ else if (!strcasecmp(optarg, "MX"))
+ type = T_MX;
+ else if (!strcasecmp(optarg, "MG"))
+ type = T_MG;
+ else if (!strcasecmp(optarg, "RP"))
+ type = T_RP;
+ else if (!strcasecmp(optarg, "TXT"))
+ type = T_TXT;
+ else if (!strcasecmp(optarg, "AFSDB"))
+ type = T_AFSDB;
+ else if (!strcasecmp(optarg, "ANY"))
+ type = T_ANY;
+ else {
+ fprintf(stderr, "Bad type (%s)\n", optarg);
+ exit(-1);
+ }
+ break;
+
+ case 'd' : debug++;
+ break;
+
+ case 's' :
+ case 'v' : stream++;
+ break;
+
+ case 'n' :
+ /*
+ * If we set some nameservers here without
+ * using gethostbyname() first, then they will
+ * get overwritten when we do the first query.
+ * So, we must init the resolver before any
+ * of this.
+ */
+ if (!(_res.options & RES_INIT))
+ if (res_init() == -1) {
+ fprintf(stderr,
+ "res_init() failed\n");
+ exit(-1);
+ }
+ if (nameservers >= MAXNS) break;
+ (void) inet_aton(optarg,
+ &q_nsaddr[nameservers]);
+ if (!inet_aton(optarg, &ul)) {
+ q_nsname = gethostbyname(optarg);
+ if (q_nsname == 0) {
+ fprintf(stderr,
+ "Bad nameserver (%s)\n",
+ optarg);
+ exit(-1);
+ }
+ bcopy((char *) q_nsname->h_addr,
+ (char *) &q_nsaddr[nameservers],
+ INADDRSZ);
+ }
+ else
+ q_nsaddr[nameservers].s_addr = ul;
+ nameservers++;
+ break;
+
+ default : fprintf(stderr,
+ "\tUsage: %s [-n ns] [-h host] [-t type] [-c class] [-r retry] [-p period] [-s] [-v] [-d] [-a]\n", argv[0]);
+ exit(-1);
+ }
+ }
+ if (optind < argc)
+ strcpy(name, argv[optind]);
+
+ len = sizeof(answer);
+
+ /*
+ * set these here so they aren't set for a possible call to
+ * gethostbyname above
+ */
+ if (debug)
+ _res.options |= RES_DEBUG;
+ if (stream)
+ _res.options |= RES_USEVC;
+
+ /* if the -n flag was used, add them to the resolver's list */
+ if (nameservers != 0) {
+ _res.nscount = nameservers;
+ for (i = nameservers - 1; i >= 0; i--) {
+ _res.nsaddr_list[i].sin_addr.s_addr = q_nsaddr[i].s_addr;
+ _res.nsaddr_list[i].sin_family = AF_INET;
+ _res.nsaddr_list[i].sin_port = htons(NAMESERVER_PORT);
+ }
+ }
+
+ /*
+ * if the -h arg is fully-qualified, use res_query() since
+ * using res_search() will lead to use of res_querydomain()
+ * which will strip the trailing dot
+ */
+ if (name[strlen(name) - 1] == '.') {
+ if (res_query(name, class, type, answer, len) < 0) {
+ hp = (HEADER *) answer;
+ if ((hp->rcode == 0) && (hp->ancount > 0))
+ __p_query(answer);
+ else
+ fprintf(stderr, "Query failed (h_errno = %d) : %s\n",
+ h_errno, h_errlist[h_errno]);
+ exit(-1);
+ }
+ }
+ else if (res_search(name, class, type, answer, len) < 0) {
+ hp = (HEADER *) answer;
+ if ((hp->rcode == 0) && (hp->ancount > 0))
+ __p_query(answer);
+ else
+ fprintf(stderr, "Query failed (h_errno = %d) : %s\n",
+ h_errno, h_errlist[h_errno]);
+ exit(-1);
+ }
+ __p_query(answer);
+ exit(0);
+}