17dd7cddfSDavid du Colombier #include <u.h> 27dd7cddfSDavid du Colombier #include <libc.h> 37dd7cddfSDavid du Colombier #include <bio.h> 47dd7cddfSDavid du Colombier #include <ctype.h> 57dd7cddfSDavid du Colombier #include <ip.h> 67dd7cddfSDavid du Colombier #include <ndb.h> 77dd7cddfSDavid du Colombier #include "dns.h" 87dd7cddfSDavid du Colombier 97dd7cddfSDavid du Colombier enum 107dd7cddfSDavid du Colombier { 119a747e4fSDavid du Colombier Maxrequest= 128, 127dd7cddfSDavid du Colombier Ncache= 8, 137dd7cddfSDavid du Colombier Maxpath= 128, 147dd7cddfSDavid du Colombier Maxreply= 512, 157dd7cddfSDavid du Colombier Maxrrr= 16, 167dd7cddfSDavid du Colombier }; 177dd7cddfSDavid du Colombier 187dd7cddfSDavid du Colombier static char *servername; 197dd7cddfSDavid du Colombier static RR *serverrr; 207dd7cddfSDavid du Colombier static RR *serveraddrs; 217dd7cddfSDavid du Colombier 227dd7cddfSDavid du Colombier int debug; 237dd7cddfSDavid du Colombier int cachedb; 247dd7cddfSDavid du Colombier ulong now; 257dd7cddfSDavid du Colombier int testing; 2667031067SDavid du Colombier int traceactivity; 277dd7cddfSDavid du Colombier char *trace; 287dd7cddfSDavid du Colombier int needrefresh; 297dd7cddfSDavid du Colombier int resolver; 307dd7cddfSDavid du Colombier uchar ipaddr[IPaddrlen]; /* my ip address */ 317dd7cddfSDavid du Colombier int maxage; 327dd7cddfSDavid du Colombier char *logfile = "dns"; 337dd7cddfSDavid du Colombier char *dbfile; 347dd7cddfSDavid du Colombier char mntpt[Maxpath]; 35dc5a79c1SDavid du Colombier char *zonerefreshprogram; 367dd7cddfSDavid du Colombier 379a747e4fSDavid du Colombier int prettyrrfmt(Fmt*); 387dd7cddfSDavid du Colombier void preloadserveraddrs(void); 397dd7cddfSDavid du Colombier void squirrelserveraddrs(void); 407dd7cddfSDavid du Colombier int setserver(char*); 417dd7cddfSDavid du Colombier void doquery(char*, char*); 427dd7cddfSDavid du Colombier void docmd(int, char**); 437dd7cddfSDavid du Colombier 447dd7cddfSDavid du Colombier void 457dd7cddfSDavid du Colombier main(int argc, char *argv[]) 467dd7cddfSDavid du Colombier { 477dd7cddfSDavid du Colombier int n; 487dd7cddfSDavid du Colombier Biobuf in; 4980ee5cbfSDavid du Colombier char *p; 507dd7cddfSDavid du Colombier char *f[4]; 517dd7cddfSDavid du Colombier 527dd7cddfSDavid du Colombier strcpy(mntpt, "/net"); 537dd7cddfSDavid du Colombier 547dd7cddfSDavid du Colombier ARGBEGIN{ 557dd7cddfSDavid du Colombier case 'r': 567dd7cddfSDavid du Colombier resolver = 1; 577dd7cddfSDavid du Colombier break; 587dd7cddfSDavid du Colombier case 'x': 597dd7cddfSDavid du Colombier dbfile = "/lib/ndb/external"; 607dd7cddfSDavid du Colombier strcpy(mntpt, "/net.alt"); 617dd7cddfSDavid du Colombier break; 6234f77ae3SDavid du Colombier case 'f': 6334f77ae3SDavid du Colombier dbfile = ARGF(); 6434f77ae3SDavid du Colombier break; 657dd7cddfSDavid du Colombier }ARGEND 667dd7cddfSDavid du Colombier 677dd7cddfSDavid du Colombier now = time(0); 687dd7cddfSDavid du Colombier dninit(); 699a747e4fSDavid du Colombier fmtinstall('R', prettyrrfmt); 709a747e4fSDavid du Colombier if(myipaddr(ipaddr, mntpt) < 0) 717dd7cddfSDavid du Colombier sysfatal("can't read my ip address"); 727dd7cddfSDavid du Colombier opendatabase(); 737dd7cddfSDavid du Colombier 747dd7cddfSDavid du Colombier if(resolver) 757dd7cddfSDavid du Colombier squirrelserveraddrs(); 767dd7cddfSDavid du Colombier 777dd7cddfSDavid du Colombier debug = 1; 787dd7cddfSDavid du Colombier 797dd7cddfSDavid du Colombier if(argc > 0){ 807dd7cddfSDavid du Colombier docmd(argc, argv); 817dd7cddfSDavid du Colombier exits(0); 827dd7cddfSDavid du Colombier } 837dd7cddfSDavid du Colombier 847dd7cddfSDavid du Colombier Binit(&in, 0, OREAD); 857dd7cddfSDavid du Colombier for(print("> "); p = Brdline(&in, '\n'); print("> ")){ 867dd7cddfSDavid du Colombier p[Blinelen(&in)-1] = 0; 877dd7cddfSDavid du Colombier n = tokenize(p, f, 3); 887dd7cddfSDavid du Colombier if(n<1) 897dd7cddfSDavid du Colombier continue; 907dd7cddfSDavid du Colombier 917dd7cddfSDavid du Colombier /* flush the cache */ 927dd7cddfSDavid du Colombier dnpurge(); 937dd7cddfSDavid du Colombier 947dd7cddfSDavid du Colombier docmd(n, f); 957dd7cddfSDavid du Colombier 967dd7cddfSDavid du Colombier } 977dd7cddfSDavid du Colombier exits(0); 987dd7cddfSDavid du Colombier } 997dd7cddfSDavid du Colombier 1007dd7cddfSDavid du Colombier static char* 1017dd7cddfSDavid du Colombier longtime(long t) 1027dd7cddfSDavid du Colombier { 1037dd7cddfSDavid du Colombier int d, h, m, n; 1047dd7cddfSDavid du Colombier static char x[128]; 1057dd7cddfSDavid du Colombier 1067dd7cddfSDavid du Colombier for(d = 0; t >= 24*60*60; t -= 24*60*60) 1077dd7cddfSDavid du Colombier d++; 1087dd7cddfSDavid du Colombier for(h = 0; t >= 60*60; t -= 60*60) 1097dd7cddfSDavid du Colombier h++; 1107dd7cddfSDavid du Colombier for(m = 0; t >= 60; t -= 60) 1117dd7cddfSDavid du Colombier m++; 1127dd7cddfSDavid du Colombier n = 0; 1137dd7cddfSDavid du Colombier if(d) 1147dd7cddfSDavid du Colombier n += sprint(x, "%d day ", d); 1157dd7cddfSDavid du Colombier if(h) 1167dd7cddfSDavid du Colombier n += sprint(x+n, "%d hr ", h); 1177dd7cddfSDavid du Colombier if(m) 1187dd7cddfSDavid du Colombier n += sprint(x+n, "%d min ", m); 1197dd7cddfSDavid du Colombier if(t || n == 0) 1207dd7cddfSDavid du Colombier sprint(x+n, "%ld sec", t); 1217dd7cddfSDavid du Colombier return x; 1227dd7cddfSDavid du Colombier } 1237dd7cddfSDavid du Colombier 1247dd7cddfSDavid du Colombier int 1259a747e4fSDavid du Colombier prettyrrfmt(Fmt *f) 1267dd7cddfSDavid du Colombier { 1277dd7cddfSDavid du Colombier RR *rp; 1287dd7cddfSDavid du Colombier char buf[3*Domlen]; 1297dd7cddfSDavid du Colombier char *p, *e; 1308754a1dfSDavid du Colombier Txt *t; 1317dd7cddfSDavid du Colombier 1329a747e4fSDavid du Colombier rp = va_arg(f->args, RR*); 1337dd7cddfSDavid du Colombier if(rp == 0){ 1347dd7cddfSDavid du Colombier strcpy(buf, "<null>"); 1357dd7cddfSDavid du Colombier goto out; 1367dd7cddfSDavid du Colombier } 1377dd7cddfSDavid du Colombier 1387dd7cddfSDavid du Colombier p = buf; 1397dd7cddfSDavid du Colombier e = buf + sizeof(buf); 1407dd7cddfSDavid du Colombier p = seprint(p, e, "%-32.32s %-15.15s %-5.5s", rp->owner->name, 1417dd7cddfSDavid du Colombier longtime(rp->db ? rp->ttl : (rp->ttl-now)), 1429a747e4fSDavid du Colombier rrname(rp->type, buf, sizeof buf)); 1437dd7cddfSDavid du Colombier 1447dd7cddfSDavid du Colombier if(rp->negative){ 1457dd7cddfSDavid du Colombier seprint(p, e, "negative rcode %d\n", rp->negrcode); 1467dd7cddfSDavid du Colombier goto out; 1477dd7cddfSDavid du Colombier } 1487dd7cddfSDavid du Colombier 1497dd7cddfSDavid du Colombier switch(rp->type){ 1507dd7cddfSDavid du Colombier case Thinfo: 1517dd7cddfSDavid du Colombier seprint(p, e, "\t%s %s", rp->cpu->name, rp->os->name); 1527dd7cddfSDavid du Colombier break; 1537dd7cddfSDavid du Colombier case Tcname: 1547dd7cddfSDavid du Colombier case Tmb: 1557dd7cddfSDavid du Colombier case Tmd: 1567dd7cddfSDavid du Colombier case Tmf: 1577dd7cddfSDavid du Colombier case Tns: 1587dd7cddfSDavid du Colombier seprint(p, e, "\t%s", rp->host->name); 1597dd7cddfSDavid du Colombier break; 1607dd7cddfSDavid du Colombier case Tmg: 1617dd7cddfSDavid du Colombier case Tmr: 1627dd7cddfSDavid du Colombier seprint(p, e, "\t%s", rp->mb->name); 1637dd7cddfSDavid du Colombier break; 1647dd7cddfSDavid du Colombier case Tminfo: 1657dd7cddfSDavid du Colombier seprint(p, e, "\t%s %s", rp->mb->name, rp->rmb->name); 1667dd7cddfSDavid du Colombier break; 1677dd7cddfSDavid du Colombier case Tmx: 1687dd7cddfSDavid du Colombier seprint(p, e, "\t%lud %s", rp->pref, rp->host->name); 1697dd7cddfSDavid du Colombier break; 1707dd7cddfSDavid du Colombier case Ta: 1715d459b5aSDavid du Colombier case Taaaa: 1727dd7cddfSDavid du Colombier seprint(p, e, "\t%s", rp->ip->name); 1737dd7cddfSDavid du Colombier break; 1747dd7cddfSDavid du Colombier case Tptr: 1757dd7cddfSDavid du Colombier seprint(p, e, "\t%s", rp->ptr->name); 1767dd7cddfSDavid du Colombier break; 1777dd7cddfSDavid du Colombier case Tsoa: 1787dd7cddfSDavid du Colombier seprint(p, e, "\t%s %s %lud %lud %lud %lud %lud", rp->host->name, 1797dd7cddfSDavid du Colombier rp->rmb->name, rp->soa->serial, rp->soa->refresh, rp->soa->retry, 1807dd7cddfSDavid du Colombier rp->soa->expire, rp->soa->minttl); 1817dd7cddfSDavid du Colombier break; 1829a747e4fSDavid du Colombier case Tnull: 1839a747e4fSDavid du Colombier seprint(p, e, "\t%.*H", rp->null->dlen, rp->null->data); 1849a747e4fSDavid du Colombier break; 1857dd7cddfSDavid du Colombier case Ttxt: 1868754a1dfSDavid du Colombier p = seprint(p, e, "\t"); 1878754a1dfSDavid du Colombier for(t = rp->txt; t != nil; t = t->next) 1888754a1dfSDavid du Colombier p = seprint(p, e, "%s", t->p); 1897dd7cddfSDavid du Colombier break; 1907dd7cddfSDavid du Colombier case Trp: 1918754a1dfSDavid du Colombier seprint(p, e, "\t%s %s", rp->rmb->name, rp->rp->name); 1927dd7cddfSDavid du Colombier break; 1937dd7cddfSDavid du Colombier case Tkey: 1947dd7cddfSDavid du Colombier seprint(p, e, "\t%d %d %d", rp->key->flags, rp->key->proto, 1957dd7cddfSDavid du Colombier rp->key->alg); 1967dd7cddfSDavid du Colombier break; 1977dd7cddfSDavid du Colombier case Tsig: 1987dd7cddfSDavid du Colombier seprint(p, e, "\t%d %d %d %lud %lud %lud %d %s", 1997dd7cddfSDavid du Colombier rp->sig->type, rp->sig->alg, rp->sig->labels, rp->sig->ttl, 2007dd7cddfSDavid du Colombier rp->sig->exp, rp->sig->incep, rp->sig->tag, rp->sig->signer->name); 2017dd7cddfSDavid du Colombier break; 2027dd7cddfSDavid du Colombier case Tcert: 2037dd7cddfSDavid du Colombier seprint(p, e, "\t%d %d %d", 2047dd7cddfSDavid du Colombier rp->sig->type, rp->sig->tag, rp->sig->alg); 2057dd7cddfSDavid du Colombier break; 2067dd7cddfSDavid du Colombier default: 2077dd7cddfSDavid du Colombier break; 2087dd7cddfSDavid du Colombier } 2097dd7cddfSDavid du Colombier out: 2109a747e4fSDavid du Colombier return fmtstrcpy(f, buf); 2117dd7cddfSDavid du Colombier } 2127dd7cddfSDavid du Colombier 2137dd7cddfSDavid du Colombier void 2147dd7cddfSDavid du Colombier logsection(char *flag, RR *rp) 2157dd7cddfSDavid du Colombier { 2167dd7cddfSDavid du Colombier if(rp == nil) 2177dd7cddfSDavid du Colombier return; 2187dd7cddfSDavid du Colombier print("\t%s%R\n", flag, rp); 2197dd7cddfSDavid du Colombier for(rp = rp->next; rp != nil; rp = rp->next) 2207dd7cddfSDavid du Colombier print("\t %R\n", rp); 2217dd7cddfSDavid du Colombier } 2227dd7cddfSDavid du Colombier 2237dd7cddfSDavid du Colombier void 2247dd7cddfSDavid du Colombier logreply(int id, uchar *addr, DNSmsg *mp) 2257dd7cddfSDavid du Colombier { 2267dd7cddfSDavid du Colombier RR *rp; 2277dd7cddfSDavid du Colombier char buf[12]; 2287dd7cddfSDavid du Colombier char resp[32]; 2297dd7cddfSDavid du Colombier 2307dd7cddfSDavid du Colombier switch(mp->flags & Rmask){ 2317dd7cddfSDavid du Colombier case Rok: 2327dd7cddfSDavid du Colombier strcpy(resp, "OK"); 2337dd7cddfSDavid du Colombier break; 2347dd7cddfSDavid du Colombier case Rformat: 2357dd7cddfSDavid du Colombier strcpy(resp, "Format error"); 2367dd7cddfSDavid du Colombier break; 2377dd7cddfSDavid du Colombier case Rserver: 2387dd7cddfSDavid du Colombier strcpy(resp, "Server failed"); 2397dd7cddfSDavid du Colombier break; 2407dd7cddfSDavid du Colombier case Rname: 2417dd7cddfSDavid du Colombier strcpy(resp, "Nonexistent"); 2427dd7cddfSDavid du Colombier break; 2437dd7cddfSDavid du Colombier case Runimplimented: 2447dd7cddfSDavid du Colombier strcpy(resp, "Unimplemented"); 2457dd7cddfSDavid du Colombier break; 2467dd7cddfSDavid du Colombier case Rrefused: 2477dd7cddfSDavid du Colombier strcpy(resp, "Refused"); 2487dd7cddfSDavid du Colombier break; 2497dd7cddfSDavid du Colombier default: 2507dd7cddfSDavid du Colombier sprint(resp, "%d", mp->flags & Rmask); 2517dd7cddfSDavid du Colombier break; 2527dd7cddfSDavid du Colombier } 2537dd7cddfSDavid du Colombier 2547dd7cddfSDavid du Colombier print("%d: rcvd %s from %I (%s%s%s%s%s)\n", id, resp, addr, 2557dd7cddfSDavid du Colombier mp->flags & Fauth ? "authoritative" : "", 2567dd7cddfSDavid du Colombier mp->flags & Ftrunc ? " truncated" : "", 2577dd7cddfSDavid du Colombier mp->flags & Frecurse ? " recurse" : "", 2587dd7cddfSDavid du Colombier mp->flags & Fcanrec ? " can_recurse" : "", 2597dd7cddfSDavid du Colombier mp->flags & (Fauth|Rname) == (Fauth|Rname) ? 2607dd7cddfSDavid du Colombier " nx" : ""); 2617dd7cddfSDavid du Colombier for(rp = mp->qd; rp != nil; rp = rp->next) 2629a747e4fSDavid du Colombier print("\tQ: %s %s\n", rp->owner->name, rrname(rp->type, buf, sizeof buf)); 2637dd7cddfSDavid du Colombier logsection("Ans: ", mp->an); 2647dd7cddfSDavid du Colombier logsection("Auth: ", mp->ns); 2657dd7cddfSDavid du Colombier logsection("Hint: ", mp->ar); 2667dd7cddfSDavid du Colombier } 2677dd7cddfSDavid du Colombier 2687dd7cddfSDavid du Colombier void 2697dd7cddfSDavid du Colombier logsend(int id, int subid, uchar *addr, char *sname, char *rname, int type) 2707dd7cddfSDavid du Colombier { 2717dd7cddfSDavid du Colombier char buf[12]; 2727dd7cddfSDavid du Colombier 2737dd7cddfSDavid du Colombier print("%d.%d: sending to %I/%s %s %s\n", id, subid, 2749a747e4fSDavid du Colombier addr, sname, rname, rrname(type, buf, sizeof buf)); 2757dd7cddfSDavid du Colombier } 2767dd7cddfSDavid du Colombier 2777dd7cddfSDavid du Colombier RR* 2787dd7cddfSDavid du Colombier getdnsservers(int class) 2797dd7cddfSDavid du Colombier { 2807dd7cddfSDavid du Colombier RR *rr; 2817dd7cddfSDavid du Colombier 2827dd7cddfSDavid du Colombier if(servername == nil) 2837dd7cddfSDavid du Colombier return dnsservers(class); 2847dd7cddfSDavid du Colombier 2857dd7cddfSDavid du Colombier rr = rralloc(Tns); 2867dd7cddfSDavid du Colombier rr->owner = dnlookup("local#dns#servers", class, 1); 2877dd7cddfSDavid du Colombier rr->host = dnlookup(servername, class, 1); 2887dd7cddfSDavid du Colombier 2897dd7cddfSDavid du Colombier return rr; 2907dd7cddfSDavid du Colombier } 2917dd7cddfSDavid du Colombier 2927dd7cddfSDavid du Colombier void 2937dd7cddfSDavid du Colombier squirrelserveraddrs(void) 2947dd7cddfSDavid du Colombier { 2957dd7cddfSDavid du Colombier RR *rr, *rp, **l; 2967dd7cddfSDavid du Colombier Request req; 2977dd7cddfSDavid du Colombier 2987dd7cddfSDavid du Colombier /* look up the resolver address first */ 2997dd7cddfSDavid du Colombier resolver = 0; 3007dd7cddfSDavid du Colombier debug = 0; 3017dd7cddfSDavid du Colombier if(serveraddrs) 3027dd7cddfSDavid du Colombier rrfreelist(serveraddrs); 3037dd7cddfSDavid du Colombier serveraddrs = nil; 3047dd7cddfSDavid du Colombier rr = getdnsservers(Cin); 3057dd7cddfSDavid du Colombier l = &serveraddrs; 3067dd7cddfSDavid du Colombier for(rp = rr; rp != nil; rp = rp->next){ 3077dd7cddfSDavid du Colombier if(strcmp(ipattr(rp->host->name), "ip") == 0){ 3087dd7cddfSDavid du Colombier *l = rralloc(Ta); 3097dd7cddfSDavid du Colombier (*l)->owner = rp->host; 3107dd7cddfSDavid du Colombier (*l)->ip = rp->host; 3117dd7cddfSDavid du Colombier l = &(*l)->next; 3127dd7cddfSDavid du Colombier continue; 3137dd7cddfSDavid du Colombier } 3147dd7cddfSDavid du Colombier req.isslave = 1; 3157dd7cddfSDavid du Colombier req.aborttime = now + 60; /* don't spend more than 60 seconds */ 316271b8d73SDavid du Colombier *l = dnresolve(rp->host->name, Cin, Ta, &req, 0, 0, Recurse, 0, 0); 3177dd7cddfSDavid du Colombier while(*l != nil) 3187dd7cddfSDavid du Colombier l = &(*l)->next; 3197dd7cddfSDavid du Colombier } 3207dd7cddfSDavid du Colombier resolver = 1; 3217dd7cddfSDavid du Colombier debug = 1; 3227dd7cddfSDavid du Colombier } 3237dd7cddfSDavid du Colombier 3247dd7cddfSDavid du Colombier void 3257dd7cddfSDavid du Colombier preloadserveraddrs(void) 3267dd7cddfSDavid du Colombier { 3277dd7cddfSDavid du Colombier RR *rp, **l, *first; 3287dd7cddfSDavid du Colombier 3297dd7cddfSDavid du Colombier l = &first; 3307dd7cddfSDavid du Colombier for(rp = serveraddrs; rp != nil; rp = rp->next){ 3317dd7cddfSDavid du Colombier rrcopy(rp, l); 3327dd7cddfSDavid du Colombier rrattach(first, 1); 3337dd7cddfSDavid du Colombier } 3347dd7cddfSDavid du Colombier } 3357dd7cddfSDavid du Colombier 3367dd7cddfSDavid du Colombier int 3377dd7cddfSDavid du Colombier setserver(char *server) 3387dd7cddfSDavid du Colombier { 3397dd7cddfSDavid du Colombier if(servername != nil){ 3407dd7cddfSDavid du Colombier free(servername); 3417dd7cddfSDavid du Colombier servername = nil; 3427dd7cddfSDavid du Colombier resolver = 0; 3437dd7cddfSDavid du Colombier } 3447dd7cddfSDavid du Colombier if(server == nil || *server == 0) 3457dd7cddfSDavid du Colombier return 0; 3467dd7cddfSDavid du Colombier servername = strdup(server); 3477dd7cddfSDavid du Colombier squirrelserveraddrs(); 3487dd7cddfSDavid du Colombier if(serveraddrs == nil){ 3497dd7cddfSDavid du Colombier print("can't resolve %s\n", servername); 3507dd7cddfSDavid du Colombier resolver = 0; 3517dd7cddfSDavid du Colombier } else { 3527dd7cddfSDavid du Colombier resolver = 1; 3537dd7cddfSDavid du Colombier } 3547dd7cddfSDavid du Colombier return resolver ? 0 : -1; 3557dd7cddfSDavid du Colombier } 3567dd7cddfSDavid du Colombier 3577dd7cddfSDavid du Colombier void 3587dd7cddfSDavid du Colombier doquery(char *name, char *tstr) 3597dd7cddfSDavid du Colombier { 3607dd7cddfSDavid du Colombier Request req; 3617dd7cddfSDavid du Colombier RR *rr, *rp; 3627dd7cddfSDavid du Colombier int len, type; 3637dd7cddfSDavid du Colombier char *p, *np; 364271b8d73SDavid du Colombier int rooted; 3657dd7cddfSDavid du Colombier char buf[1024]; 3667dd7cddfSDavid du Colombier 3677dd7cddfSDavid du Colombier if(resolver) 3687dd7cddfSDavid du Colombier preloadserveraddrs(); 3697dd7cddfSDavid du Colombier 3707dd7cddfSDavid du Colombier /* default to an "ip" request if alpha, "ptr" if numeric */ 3717dd7cddfSDavid du Colombier if(tstr == nil || *tstr == 0) { 3727dd7cddfSDavid du Colombier if(strcmp(ipattr(name), "ip") == 0) 3737dd7cddfSDavid du Colombier tstr = "ptr"; 3747dd7cddfSDavid du Colombier else 3757dd7cddfSDavid du Colombier tstr = "ip"; 3767dd7cddfSDavid du Colombier } 3777dd7cddfSDavid du Colombier 3787dd7cddfSDavid du Colombier /* if name end in '.', remove it */ 3797dd7cddfSDavid du Colombier len = strlen(name); 380271b8d73SDavid du Colombier if(len > 0 && name[len-1] == '.'){ 381271b8d73SDavid du Colombier rooted = 1; 3827dd7cddfSDavid du Colombier name[len-1] = 0; 383271b8d73SDavid du Colombier } else 384271b8d73SDavid du Colombier rooted = 0; 3857dd7cddfSDavid du Colombier 3867dd7cddfSDavid du Colombier /* inverse queries may need to be permuted */ 3879a747e4fSDavid du Colombier strncpy(buf, name, sizeof buf); 3887dd7cddfSDavid du Colombier if(strcmp("ptr", tstr) == 0 3897dd7cddfSDavid du Colombier && strstr(name, "IN-ADDR") == 0 3907dd7cddfSDavid du Colombier && strstr(name, "in-addr") == 0){ 3917dd7cddfSDavid du Colombier for(p = name; *p; p++) 3927dd7cddfSDavid du Colombier ; 3937dd7cddfSDavid du Colombier *p = '.'; 3947dd7cddfSDavid du Colombier np = buf; 3957dd7cddfSDavid du Colombier len = 0; 3967dd7cddfSDavid du Colombier while(p >= name){ 3977dd7cddfSDavid du Colombier len++; 3987dd7cddfSDavid du Colombier p--; 3997dd7cddfSDavid du Colombier if(*p == '.'){ 4007dd7cddfSDavid du Colombier memmove(np, p+1, len); 4017dd7cddfSDavid du Colombier np += len; 4027dd7cddfSDavid du Colombier len = 0; 4037dd7cddfSDavid du Colombier } 4047dd7cddfSDavid du Colombier } 4057dd7cddfSDavid du Colombier memmove(np, p+1, len); 4067dd7cddfSDavid du Colombier np += len; 4077dd7cddfSDavid du Colombier strcpy(np, "in-addr.arpa"); 4087dd7cddfSDavid du Colombier } 4097dd7cddfSDavid du Colombier 4107dd7cddfSDavid du Colombier /* look it up */ 4117dd7cddfSDavid du Colombier type = rrtype(tstr); 4127dd7cddfSDavid du Colombier if(type < 0){ 4137dd7cddfSDavid du Colombier print("!unknown type %s\n", tstr); 4147dd7cddfSDavid du Colombier return; 4157dd7cddfSDavid du Colombier } 4167dd7cddfSDavid du Colombier 417*b4b9fc2fSDavid du Colombier getactivity(&req, 0); 4187dd7cddfSDavid du Colombier req.isslave = 1; 4197dd7cddfSDavid du Colombier req.aborttime = now + 60; /* don't spend more than 60 seconds */ 420271b8d73SDavid du Colombier rr = dnresolve(buf, Cin, type, &req, 0, 0, Recurse, rooted, 0); 4217dd7cddfSDavid du Colombier if(rr){ 4227dd7cddfSDavid du Colombier print("----------------------------\n"); 4237dd7cddfSDavid du Colombier for(rp = rr; rp; rp = rp->next) 4247dd7cddfSDavid du Colombier print("answer %R\n", rp); 4257dd7cddfSDavid du Colombier print("----------------------------\n"); 4267dd7cddfSDavid du Colombier } 4277dd7cddfSDavid du Colombier rrfreelist(rr); 4287dd7cddfSDavid du Colombier 429*b4b9fc2fSDavid du Colombier putactivity(0); 4307dd7cddfSDavid du Colombier } 4317dd7cddfSDavid du Colombier 4327dd7cddfSDavid du Colombier void 4337dd7cddfSDavid du Colombier docmd(int n, char **f) 4347dd7cddfSDavid du Colombier { 4357dd7cddfSDavid du Colombier int tmpsrv; 4367dd7cddfSDavid du Colombier char *name, *type; 4377dd7cddfSDavid du Colombier 4387dd7cddfSDavid du Colombier name = nil; 4397dd7cddfSDavid du Colombier type = nil; 4407dd7cddfSDavid du Colombier tmpsrv = 0; 4417dd7cddfSDavid du Colombier 4427dd7cddfSDavid du Colombier if(*f[0] == '@') { 4437dd7cddfSDavid du Colombier if(setserver(f[0]+1) < 0) 4447dd7cddfSDavid du Colombier return; 4457dd7cddfSDavid du Colombier 4467dd7cddfSDavid du Colombier switch(n){ 4477dd7cddfSDavid du Colombier case 3: 4487dd7cddfSDavid du Colombier type = f[2]; 4497dd7cddfSDavid du Colombier /* fall through */ 4507dd7cddfSDavid du Colombier case 2: 4517dd7cddfSDavid du Colombier name = f[1]; 4527dd7cddfSDavid du Colombier tmpsrv = 1; 4537dd7cddfSDavid du Colombier break; 4547dd7cddfSDavid du Colombier } 4557dd7cddfSDavid du Colombier } else { 4567dd7cddfSDavid du Colombier switch(n){ 4577dd7cddfSDavid du Colombier case 2: 4587dd7cddfSDavid du Colombier type = f[1]; 4597dd7cddfSDavid du Colombier /* fall through */ 4607dd7cddfSDavid du Colombier case 1: 4617dd7cddfSDavid du Colombier name = f[0]; 4627dd7cddfSDavid du Colombier break; 4637dd7cddfSDavid du Colombier } 4647dd7cddfSDavid du Colombier } 4657dd7cddfSDavid du Colombier 4667dd7cddfSDavid du Colombier if(name == nil) 4677dd7cddfSDavid du Colombier return; 4687dd7cddfSDavid du Colombier 4697dd7cddfSDavid du Colombier doquery(name, type); 4707dd7cddfSDavid du Colombier 4717dd7cddfSDavid du Colombier if(tmpsrv) 4727dd7cddfSDavid du Colombier setserver(""); 4737dd7cddfSDavid du Colombier } 474