xref: /plan9/sys/src/cmd/ndb/dnsquery.c (revision 6d0458a288b4b39e156904f1f374744fe0fe51f4)
1 #include <u.h>
2 #include <libc.h>
3 #include <bio.h>
4 #include <ctype.h>
5 #include <ndb.h>
6 #include "dns.h"
7 #include "ip.h"
8 
9 static int domount;
10 static char *mtpt, *dns, *srv;
11 
12 static int
setup(int argc,char ** argv)13 setup(int argc, char **argv)
14 {
15 	int fd;
16 
17 	if(argc == 1){
18 		domount = 0;
19 		mtpt = argv[0];
20 	}
21 
22 	fd = open(dns, ORDWR);
23 	if(fd < 0){
24 		if(domount == 0)
25 			sysfatal("can't open %s: %r", dns);
26 		fd = open(srv, ORDWR);
27 		if(fd < 0)
28 			sysfatal("can't open %s: %r", srv);
29 		if(mount(fd, -1, mtpt, MBEFORE, "") < 0)
30 			sysfatal("can't mount(%s, %s): %r", srv, mtpt);
31 		fd = open(dns, ORDWR);
32 		if(fd < 0)
33 			sysfatal("can't open %s: %r", dns);
34 	}
35 	return fd;
36 }
37 
38 static void
querydns(int fd,char * line,int n)39 querydns(int fd, char *line, int n)
40 {
41 	char buf[1024];
42 
43 	seek(fd, 0, 0);
44 	if(write(fd, line, n) != n) {
45 		print("!%r\n");
46 		return;
47 	}
48 	seek(fd, 0, 0);
49 	buf[0] = '\0';
50 	while((n = read(fd, buf, sizeof(buf))) > 0){
51 		buf[n] = '\0';
52 		print("%s\n", buf);
53 	}
54 }
55 
56 static void
query(int fd)57 query(int fd)
58 {
59 	int n, len;
60 	char *lp, *p, *np;
61 	char buf[1024], line[1024];
62 	Biobuf in;
63 
64 	Binit(&in, 0, OREAD);
65 	for(print("> "); lp = Brdline(&in, '\n'); print("> ")){
66 		n = Blinelen(&in) -1;
67 		while(isspace(lp[n]))
68 			lp[n--] = 0;
69 		n++;
70 		while(isspace(*lp)){
71 			lp++;
72 			n--;
73 		}
74 		if(!*lp)
75 			continue;
76 		strcpy(line, lp);
77 
78 		/* default to an "ip" request if alpha, "ptr" if numeric */
79 		if(strchr(line, ' ') == nil)
80 			if(strcmp(ipattr(line), "ip") == 0) {
81 				strcat(line, " ptr");
82 				n += 4;
83 			} else {
84 				strcat(line, " ip");
85 				n += 3;
86 			}
87 
88 		/* inverse queries may need to be permuted */
89 		if(n > 4 && strcmp(" ptr", &line[n-4]) == 0 &&
90 		    cistrstr(line, ".arpa") == nil){
91 			/* TODO: reversing v6 addrs is harder */
92 			for(p = line; *p; p++)
93 				if(*p == ' '){
94 					*p = '.';
95 					break;
96 				}
97 			np = buf;
98 			len = 0;
99 			while(p >= line){
100 				len++;
101 				p--;
102 				if(*p == '.'){
103 					memmove(np, p+1, len);
104 					np += len;
105 					len = 0;
106 				}
107 			}
108 			memmove(np, p+1, len);
109 			np += len;
110 			strcpy(np, "in-addr.arpa ptr");	/* TODO: ip6.arpa for v6 */
111 			strcpy(line, buf);
112 			n = strlen(line);
113 		}
114 
115 		querydns(fd, line, n);
116 	}
117 	Bterm(&in);
118 }
119 
120 void
main(int argc,char * argv[])121 main(int argc, char *argv[])
122 {
123 	mtpt = "/net";
124 	dns = "/net/dns";
125 	srv = "/srv/dns";
126 	domount = 1;
127 	ARGBEGIN {
128 	case 'x':
129 		mtpt = "/net.alt";
130 		dns = "/net.alt/dns";
131 		srv = "/srv/dns_net.alt";
132 		break;
133 	default:
134 		fprint(2, "usage: %s [-x] [dns-mount-point]\n", argv0);
135 		exits("usage");
136 	} ARGEND;
137 
138 	query(setup(argc, argv));
139 	exits(0);
140 }
141