📄 dnsdebug.c
字号:
#include <u.h>#include <libc.h>#include <bio.h>#include <ctype.h>#include <ip.h>#include <ndb.h>#include "dns.h"enum{ Maxrequest= 128, Ncache= 8, Maxpath= 128, Maxreply= 512, Maxrrr= 16,};static char *servername;static RR *serverrr;static RR *serveraddrs;int debug;int cachedb;ulong now;int testing;int traceactivity;char *trace;int needrefresh;int resolver;uchar ipaddr[IPaddrlen]; /* my ip address */int maxage;char *logfile = "dns";char *dbfile;char mntpt[Maxpath];char *zonerefreshprogram;int prettyrrfmt(Fmt*);void preloadserveraddrs(void);void squirrelserveraddrs(void);int setserver(char*);void doquery(char*, char*);void docmd(int, char**);voidmain(int argc, char *argv[]){ int n; Biobuf in; char *p; char *f[4]; strcpy(mntpt, "/net"); ARGBEGIN{ case 'r': resolver = 1; break; case 'x': dbfile = "/lib/ndb/external"; strcpy(mntpt, "/net.alt"); break; case 'f': dbfile = ARGF(); break; }ARGEND now = time(0); dninit(); fmtinstall('R', prettyrrfmt); if(myipaddr(ipaddr, mntpt) < 0) sysfatal("can't read my ip address"); opendatabase(); if(resolver) squirrelserveraddrs(); debug = 1; if(argc > 0){ docmd(argc, argv); exits(0); } Binit(&in, 0, OREAD); for(print("> "); p = Brdline(&in, '\n'); print("> ")){ p[Blinelen(&in)-1] = 0; n = tokenize(p, f, 3); if(n<1) continue; /* flush the cache */ dnpurge(); docmd(n, f); } exits(0);}static char*longtime(long t){ int d, h, m, n; static char x[128]; for(d = 0; t >= 24*60*60; t -= 24*60*60) d++; for(h = 0; t >= 60*60; t -= 60*60) h++; for(m = 0; t >= 60; t -= 60) m++; n = 0; if(d) n += sprint(x, "%d day ", d); if(h) n += sprint(x+n, "%d hr ", h); if(m) n += sprint(x+n, "%d min ", m); if(t || n == 0) sprint(x+n, "%ld sec", t); return x;}intprettyrrfmt(Fmt *f){ RR *rp; char buf[3*Domlen]; char *p, *e; Txt *t; rp = va_arg(f->args, RR*); if(rp == 0){ strcpy(buf, "<null>"); goto out; } p = buf; e = buf + sizeof(buf); p = seprint(p, e, "%-32.32s %-15.15s %-5.5s", rp->owner->name, longtime(rp->db ? rp->ttl : (rp->ttl-now)), rrname(rp->type, buf, sizeof buf)); if(rp->negative){ seprint(p, e, "negative rcode %d\n", rp->negrcode); goto out; } switch(rp->type){ case Thinfo: seprint(p, e, "\t%s %s", rp->cpu->name, rp->os->name); break; case Tcname: case Tmb: case Tmd: case Tmf: case Tns: seprint(p, e, "\t%s", rp->host->name); break; case Tmg: case Tmr: seprint(p, e, "\t%s", rp->mb->name); break; case Tminfo: seprint(p, e, "\t%s %s", rp->mb->name, rp->rmb->name); break; case Tmx: seprint(p, e, "\t%lud %s", rp->pref, rp->host->name); break; case Ta: case Taaaa: seprint(p, e, "\t%s", rp->ip->name); break; case Tptr: seprint(p, e, "\t%s", rp->ptr->name); break; case Tsoa: seprint(p, e, "\t%s %s %lud %lud %lud %lud %lud", rp->host->name, rp->rmb->name, rp->soa->serial, rp->soa->refresh, rp->soa->retry, rp->soa->expire, rp->soa->minttl); break; case Tnull: seprint(p, e, "\t%.*H", rp->null->dlen, rp->null->data); break; case Ttxt: p = seprint(p, e, "\t"); for(t = rp->txt; t != nil; t = t->next) p = seprint(p, e, "%s", t->p); break; case Trp: seprint(p, e, "\t%s %s", rp->rmb->name, rp->rp->name); break; case Tkey: seprint(p, e, "\t%d %d %d", rp->key->flags, rp->key->proto, rp->key->alg); break; case Tsig: seprint(p, e, "\t%d %d %d %lud %lud %lud %d %s", rp->sig->type, rp->sig->alg, rp->sig->labels, rp->sig->ttl, rp->sig->exp, rp->sig->incep, rp->sig->tag, rp->sig->signer->name); break; case Tcert: seprint(p, e, "\t%d %d %d", rp->sig->type, rp->sig->tag, rp->sig->alg); break; default: break; }out: return fmtstrcpy(f, buf);}voidlogsection(char *flag, RR *rp){ if(rp == nil) return; print("\t%s%R\n", flag, rp); for(rp = rp->next; rp != nil; rp = rp->next) print("\t %R\n", rp);}voidlogreply(int id, uchar *addr, DNSmsg *mp){ RR *rp; char buf[12]; char resp[32]; switch(mp->flags & Rmask){ case Rok: strcpy(resp, "OK"); break; case Rformat: strcpy(resp, "Format error"); break; case Rserver: strcpy(resp, "Server failed"); break; case Rname: strcpy(resp, "Nonexistent"); break; case Runimplimented: strcpy(resp, "Unimplemented"); break; case Rrefused: strcpy(resp, "Refused"); break; default: sprint(resp, "%d", mp->flags & Rmask); break; } print("%d: rcvd %s from %I (%s%s%s%s%s)\n", id, resp, addr, mp->flags & Fauth ? "authoritative" : "", mp->flags & Ftrunc ? " truncated" : "", mp->flags & Frecurse ? " recurse" : "", mp->flags & Fcanrec ? " can_recurse" : "", mp->flags & (Fauth|Rname) == (Fauth|Rname) ? " nx" : ""); for(rp = mp->qd; rp != nil; rp = rp->next) print("\tQ: %s %s\n", rp->owner->name, rrname(rp->type, buf, sizeof buf)); logsection("Ans: ", mp->an); logsection("Auth: ", mp->ns); logsection("Hint: ", mp->ar);}voidlogsend(int id, int subid, uchar *addr, char *sname, char *rname, int type){ char buf[12]; print("%d.%d: sending to %I/%s %s %s\n", id, subid, addr, sname, rname, rrname(type, buf, sizeof buf));}RR*getdnsservers(int class){ RR *rr; if(servername == nil) return dnsservers(class); rr = rralloc(Tns); rr->owner = dnlookup("local#dns#servers", class, 1); rr->host = dnlookup(servername, class, 1); return rr;}voidsquirrelserveraddrs(void){ RR *rr, *rp, **l; Request req; /* look up the resolver address first */ resolver = 0; debug = 0; if(serveraddrs) rrfreelist(serveraddrs); serveraddrs = nil; rr = getdnsservers(Cin); l = &serveraddrs; for(rp = rr; rp != nil; rp = rp->next){ if(strcmp(ipattr(rp->host->name), "ip") == 0){ *l = rralloc(Ta); (*l)->owner = rp->host; (*l)->ip = rp->host; l = &(*l)->next; continue; } req.isslave = 1; req.aborttime = now + 60; /* don't spend more than 60 seconds */ *l = dnresolve(rp->host->name, Cin, Ta, &req, 0, 0, Recurse, 0, 0); while(*l != nil) l = &(*l)->next; } resolver = 1; debug = 1;}voidpreloadserveraddrs(void){ RR *rp, **l, *first; l = &first; for(rp = serveraddrs; rp != nil; rp = rp->next){ rrcopy(rp, l); rrattach(first, 1); }}intsetserver(char *server){ if(servername != nil){ free(servername); servername = nil; resolver = 0; } if(server == nil || *server == 0) return 0; servername = strdup(server); squirrelserveraddrs(); if(serveraddrs == nil){ print("can't resolve %s\n", servername); resolver = 0; } else { resolver = 1; } return resolver ? 0 : -1;}voiddoquery(char *name, char *tstr){ Request req; RR *rr, *rp; int len, type; char *p, *np; int rooted; char buf[1024]; if(resolver) preloadserveraddrs(); /* default to an "ip" request if alpha, "ptr" if numeric */ if(tstr == nil || *tstr == 0) { if(strcmp(ipattr(name), "ip") == 0) tstr = "ptr"; else tstr = "ip"; } /* if name end in '.', remove it */ len = strlen(name); if(len > 0 && name[len-1] == '.'){ rooted = 1; name[len-1] = 0; } else rooted = 0; /* inverse queries may need to be permuted */ strncpy(buf, name, sizeof buf); if(strcmp("ptr", tstr) == 0 && strstr(name, "IN-ADDR") == 0 && strstr(name, "in-addr") == 0){ for(p = name; *p; p++) ; *p = '.'; np = buf; len = 0; while(p >= name){ len++; p--; if(*p == '.'){ memmove(np, p+1, len); np += len; len = 0; } } memmove(np, p+1, len); np += len; strcpy(np, "in-addr.arpa"); } /* look it up */ type = rrtype(tstr); if(type < 0){ print("!unknown type %s\n", tstr); return; } getactivity(&req, 0); req.isslave = 1; req.aborttime = now + 60; /* don't spend more than 60 seconds */ rr = dnresolve(buf, Cin, type, &req, 0, 0, Recurse, rooted, 0); if(rr){ print("----------------------------\n"); for(rp = rr; rp; rp = rp->next) print("answer %R\n", rp); print("----------------------------\n"); } rrfreelist(rr); putactivity(0);}voiddocmd(int n, char **f){ int tmpsrv; char *name, *type; name = nil; type = nil; tmpsrv = 0; if(*f[0] == '@') { if(setserver(f[0]+1) < 0) return; switch(n){ case 3: type = f[2]; /* fall through */ case 2: name = f[1]; tmpsrv = 1; break; } } else { switch(n){ case 2: type = f[1]; /* fall through */ case 1: name = f[0]; break; } } if(name == nil) return; doquery(name, type); if(tmpsrv) setserver("");}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -