15 static char *servername;
16 static RR *serveraddrs;
20 char *logfile = "dnsdebug";
29 char *zonerefreshprogram;
31 void docmd(int, char**);
32 void doquery(char*, char*);
33 void preloadserveraddrs(void);
34 int prettyrrfmt(Fmt*);
36 void squirrelserveraddrs(void);
41 fprint(2, "%s: [-rx] [-f db-file] [[@server] domain [type]]\n", argv0);
46 main(int argc, char *argv[])
53 strcpy(mntpt, "/net");
58 dbfile = EARGF(usage());
64 dbfile = "/lib/ndb/external";
65 strcpy(mntpt, "/net.alt");
74 fmtinstall('R', prettyrrfmt);
79 squirrelserveraddrs();
89 for(print("> "); p = Brdline(&in, '\n'); print("> ")){
90 p[Blinelen(&in)-1] = 0;
91 n = tokenize(p, f, 3);
93 dnpurge(); /* flush the cache */
106 for(d = 0; t >= 24*60*60; t -= 24*60*60)
108 for(h = 0; t >= 60*60; t -= 60*60)
110 for(m = 0; t >= 60; t -= 60)
114 n += sprint(x, "%d day ", d);
116 n += sprint(x+n, "%d hr ", h);
118 n += sprint(x+n, "%d min ", m);
120 sprint(x+n, "%ld sec", t);
125 * convert address into a reverse lookup address
128 mkptrname(char *ip, char *rip, int rlen)
134 if(cistrstr(ip, "in-addr.arpa") || cistrstr(ip, "ip6.arpa") || parseip(a, ip) == -1)
135 snprint(rip, rlen, "%s", ip);
137 snprint(rip, rlen, "%ud.%ud.%ud.%ud.in-addr.arpa",
138 a[15], a[14], a[13], a[12]);
142 for(i = 15; i >= 0; i--){
143 p = seprint(p, e, "%ux.", a[i]&0xf);
144 p = seprint(p, e, "%ux.", a[i]>>4);
146 seprint(p, e, "ip6.arpa");
158 rp = va_arg(f->args, RR*);
160 strcpy(buf, "<null>");
165 e = buf + sizeof(buf);
166 p = seprint(p, e, "%-32.32s %-15.15s %-5.5s", rp->owner->name,
168 rrname(rp->type, buf, sizeof buf));
171 seprint(p, e, "negative rcode %d", rp->negrcode);
177 seprint(p, e, "\t%s %s", rp->cpu->name, rp->os->name);
184 seprint(p, e, "\t%s", (rp->host? rp->host->name: ""));
188 seprint(p, e, "\t%s", (rp->mb? rp->mb->name: ""));
191 seprint(p, e, "\t%s %s", (rp->mb? rp->mb->name: ""),
192 (rp->rmb? rp->rmb->name: ""));
195 seprint(p, e, "\t%lud %s", rp->pref,
196 (rp->host? rp->host->name: ""));
200 seprint(p, e, "\t%s", (rp->ip? rp->ip->name: ""));
203 seprint(p, e, "\t%s", (rp->ptr? rp->ptr->name: ""));
206 seprint(p, e, "\t%s %s %lud %lud %lud %lud %lud",
207 rp->host->name, rp->rmb->name, rp->soa->serial,
208 rp->soa->refresh, rp->soa->retry,
209 rp->soa->expire, rp->soa->minttl);
212 seprint(p, e, "\t%ud %ud %ud %s",
213 rp->srv->pri, rp->srv->weight, rp->port, rp->host->name);
216 seprint(p, e, "\t%.*H", rp->null->dlen, rp->null->data);
219 p = seprint(p, e, "\t");
220 for(t = rp->txt; t != nil; t = t->next)
221 p = seprint(p, e, "%s", t->p);
224 seprint(p, e, "\t%s %s", rp->rmb->name, rp->rp->name);
227 seprint(p, e, "\t%d %d %d", rp->key->flags, rp->key->proto,
231 seprint(p, e, "\t%d %d %d %lud %lud %lud %d %s",
232 rp->sig->type, rp->sig->alg, rp->sig->labels,
233 rp->sig->ttl, rp->sig->exp, rp->sig->incep,
234 rp->sig->tag, rp->sig->signer->name);
237 seprint(p, e, "\t%d %d %d",
238 rp->sig->type, rp->sig->tag, rp->sig->alg);
242 return fmtstrcpy(f, buf);
246 logsection(char *flag, RR *rp)
250 print("\t%s%R\n", flag, rp);
251 for(rp = rp->next; rp != nil; rp = rp->next)
252 print("\t %R\n", rp);
256 logreply(int id, uchar *addr, DNSmsg *mp)
259 char buf[12], resp[32];
261 switch(mp->flags & Rmask){
266 strcpy(resp, "Format error");
269 strcpy(resp, "Server failed");
272 strcpy(resp, "Nonexistent");
275 strcpy(resp, "Unimplemented");
278 strcpy(resp, "Refused");
281 sprint(resp, "%d", mp->flags & Rmask);
285 print("%d: rcvd %s from %I (%s%s%s%s%s)\n", id, resp, addr,
286 mp->flags & Fauth? "authoritative": "",
287 mp->flags & Ftrunc? " truncated": "",
288 mp->flags & Frecurse? " recurse": "",
289 mp->flags & Fcanrec? " can_recurse": "",
290 (mp->flags & (Fauth|Rmask)) == (Fauth|Rname)? " nx": "");
291 for(rp = mp->qd; rp != nil; rp = rp->next)
292 print("\tQ: %s %s\n", rp->owner->name,
293 rrname(rp->type, buf, sizeof buf));
294 logsection("Ans: ", mp->an);
295 logsection("Auth: ", mp->ns);
296 logsection("Hint: ", mp->ar);
300 logsend(int id, int subid, uchar *addr, char *sname, char *rname, int type)
304 print("%d.%d: sending to %I/%s %s %s\n", id, subid,
305 addr, sname, rname, rrname(type, buf, sizeof buf));
309 getdnsservers(int class)
313 if(servername == nil)
314 return dnsservers(class);
317 rr->owner = dnlookup("local#dns#servers", class, 1);
318 rr->host = idnlookup(servername, class, 1);
324 squirrelserveraddrs(void)
331 /* look up the resolver address first */
335 rrfreelist(serveraddrs);
338 rr = getdnsservers(Cin);
340 for(rp = rr; rp != nil; rp = rp->next){
341 attr = ipattr(rp->host->name);
342 v4 = strcmp(attr, "ip") == 0;
343 if(v4 || strcmp(attr, "ipv6") == 0){
344 *l = rralloc(v4? Ta: Taaaa);
345 (*l)->owner = rp->host;
350 memset(&req, 0, sizeof req);
352 req.aborttime = NS2MS(nowns) + Maxreqtm;
353 *l = dnresolve(rp->host->name, Cin, Ta, &req, 0, 0, Recurse, 0, 0);
355 *l = dnresolve(rp->host->name, Cin, Taaaa, &req,
356 0, 0, Recurse, 0, 0);
365 preloadserveraddrs(void)
371 for(rp = serveraddrs; rp != nil; rp = rp->next){
373 rrattach(first, Authoritative);
378 setserver(char *server)
380 if(servername != nil){
385 if(server == nil || *server == 0)
387 servername = strdup(server);
388 squirrelserveraddrs();
389 if(serveraddrs == nil){
390 print("can't resolve %s\n", servername);
394 return cfg.resolver? 0: -1;
398 doquery(char *name, char *tstr)
400 int len, type, rooted;
406 preloadserveraddrs();
408 /* default to an "ip" request if alpha, "ptr" if numeric */
409 if(tstr == nil || *tstr == 0)
410 if(strcmp(ipattr(name), "ip") == 0)
418 print("!unknown type %s\n", tstr);
422 /* if name end in '.', remove it */
424 if(len > 0 && name[len-1] == '.'){
430 /* inverse queries may need to be permuted */
432 mkptrname(name, buf, sizeof buf);
434 strncpy(buf, name, sizeof buf);
436 memset(&req, 0, sizeof req);
437 getactivity(&req, 0);
439 req.aborttime = NS2MS(nowns) + Maxreqtm;
440 rr = dnresolve(buf, Cin, type, &req, 0, 0, Recurse, rooted, 0);
442 print("----------------------------\n");
443 for(rp = rr; rp; rp = rp->next)
444 print("answer %R\n", rp);
445 print("----------------------------\n");
453 docmd(int n, char **f)
462 if(setserver(f[0]+1) < 0)