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 94f8f669cSDavid du Colombier enum { 109a747e4fSDavid du Colombier Maxrequest= 128, 117dd7cddfSDavid du Colombier }; 127dd7cddfSDavid du Colombier 134f8f669cSDavid du Colombier Cfg cfg; 144f8f669cSDavid du Colombier 157dd7cddfSDavid du Colombier static char *servername; 167dd7cddfSDavid du Colombier static RR *serverrr; 177dd7cddfSDavid du Colombier static RR *serveraddrs; 187dd7cddfSDavid du Colombier 194f8f669cSDavid du Colombier char *dbfile; 205aa528faSDavid du Colombier int debug; 214f8f669cSDavid du Colombier uchar ipaddr[IPaddrlen]; /* my ip address */ 224f8f669cSDavid du Colombier char *logfile = "dnsdebug"; 234f8f669cSDavid du Colombier int maxage = 60*60; 244f8f669cSDavid du Colombier char mntpt[Maxpath]; 254f8f669cSDavid du Colombier int needrefresh; 265aa528faSDavid du Colombier ulong now; 27a41547ffSDavid du Colombier vlong nowns; 285aa528faSDavid du Colombier int testing; 296b0d5c8bSDavid du Colombier char *trace; 304f8f669cSDavid du Colombier int traceactivity; 31dc5a79c1SDavid du Colombier char *zonerefreshprogram; 327dd7cddfSDavid du Colombier 336b0d5c8bSDavid du Colombier void docmd(int, char**); 344f8f669cSDavid du Colombier void doquery(char*, char*); 354f8f669cSDavid du Colombier void preloadserveraddrs(void); 364f8f669cSDavid du Colombier int prettyrrfmt(Fmt*); 374f8f669cSDavid du Colombier int setserver(char*); 384f8f669cSDavid du Colombier void squirrelserveraddrs(void); 394f8f669cSDavid du Colombier 404f8f669cSDavid du Colombier void 414f8f669cSDavid du Colombier usage(void) 424f8f669cSDavid du Colombier { 43*d9924332SDavid du Colombier fprint(2, "%s: [-rx] [-f db-file] [[@server] domain [type]]\n", argv0); 444f8f669cSDavid du Colombier exits("usage"); 454f8f669cSDavid du Colombier } 467dd7cddfSDavid du Colombier 477dd7cddfSDavid du Colombier void 487dd7cddfSDavid du Colombier main(int argc, char *argv[]) 497dd7cddfSDavid du Colombier { 507dd7cddfSDavid du Colombier int n; 517dd7cddfSDavid du Colombier Biobuf in; 5280ee5cbfSDavid du Colombier char *p; 537dd7cddfSDavid du Colombier char *f[4]; 547dd7cddfSDavid du Colombier 557dd7cddfSDavid du Colombier strcpy(mntpt, "/net"); 564f8f669cSDavid du Colombier cfg.inside = 1; 577dd7cddfSDavid du Colombier 587dd7cddfSDavid du Colombier ARGBEGIN{ 594f8f669cSDavid du Colombier case 'f': 604f8f669cSDavid du Colombier dbfile = EARGF(usage()); 614f8f669cSDavid du Colombier break; 627dd7cddfSDavid du Colombier case 'r': 634f8f669cSDavid du Colombier cfg.resolver = 1; 647dd7cddfSDavid du Colombier break; 657dd7cddfSDavid du Colombier case 'x': 667dd7cddfSDavid du Colombier dbfile = "/lib/ndb/external"; 677dd7cddfSDavid du Colombier strcpy(mntpt, "/net.alt"); 687dd7cddfSDavid du Colombier break; 694f8f669cSDavid du Colombier default: 704f8f669cSDavid du Colombier usage(); 717dd7cddfSDavid du Colombier }ARGEND 727dd7cddfSDavid du Colombier 734f8f669cSDavid du Colombier now = time(nil); 74e02f7f02SDavid du Colombier nowns = nsec(); 757dd7cddfSDavid du Colombier dninit(); 769a747e4fSDavid du Colombier fmtinstall('R', prettyrrfmt); 779a747e4fSDavid du Colombier if(myipaddr(ipaddr, mntpt) < 0) 787dd7cddfSDavid du Colombier sysfatal("can't read my ip address"); 797dd7cddfSDavid du Colombier opendatabase(); 807dd7cddfSDavid du Colombier 814f8f669cSDavid du Colombier if(cfg.resolver) 827dd7cddfSDavid du Colombier squirrelserveraddrs(); 837dd7cddfSDavid du Colombier 847dd7cddfSDavid du Colombier debug = 1; 857dd7cddfSDavid du Colombier 867dd7cddfSDavid du Colombier if(argc > 0){ 877dd7cddfSDavid du Colombier docmd(argc, argv); 887dd7cddfSDavid du Colombier exits(0); 897dd7cddfSDavid du Colombier } 907dd7cddfSDavid du Colombier 917dd7cddfSDavid du Colombier Binit(&in, 0, OREAD); 927dd7cddfSDavid du Colombier for(print("> "); p = Brdline(&in, '\n'); print("> ")){ 937dd7cddfSDavid du Colombier p[Blinelen(&in)-1] = 0; 947dd7cddfSDavid du Colombier n = tokenize(p, f, 3); 954f8f669cSDavid du Colombier if(n>=1) { 964f8f669cSDavid du Colombier dnpurge(); /* flush the cache */ 977dd7cddfSDavid du Colombier docmd(n, f); 984f8f669cSDavid du Colombier } 997dd7cddfSDavid du Colombier } 1007dd7cddfSDavid du Colombier exits(0); 1017dd7cddfSDavid du Colombier } 1027dd7cddfSDavid du Colombier 1037dd7cddfSDavid du Colombier static char* 1047dd7cddfSDavid du Colombier longtime(long t) 1057dd7cddfSDavid du Colombier { 1067dd7cddfSDavid du Colombier int d, h, m, n; 1077dd7cddfSDavid du Colombier static char x[128]; 1087dd7cddfSDavid du Colombier 1097dd7cddfSDavid du Colombier for(d = 0; t >= 24*60*60; t -= 24*60*60) 1107dd7cddfSDavid du Colombier d++; 1117dd7cddfSDavid du Colombier for(h = 0; t >= 60*60; t -= 60*60) 1127dd7cddfSDavid du Colombier h++; 1137dd7cddfSDavid du Colombier for(m = 0; t >= 60; t -= 60) 1147dd7cddfSDavid du Colombier m++; 1157dd7cddfSDavid du Colombier n = 0; 1167dd7cddfSDavid du Colombier if(d) 1177dd7cddfSDavid du Colombier n += sprint(x, "%d day ", d); 1187dd7cddfSDavid du Colombier if(h) 1197dd7cddfSDavid du Colombier n += sprint(x+n, "%d hr ", h); 1207dd7cddfSDavid du Colombier if(m) 1217dd7cddfSDavid du Colombier n += sprint(x+n, "%d min ", m); 1227dd7cddfSDavid du Colombier if(t || n == 0) 1237dd7cddfSDavid du Colombier sprint(x+n, "%ld sec", t); 1247dd7cddfSDavid du Colombier return x; 1257dd7cddfSDavid du Colombier } 1267dd7cddfSDavid du Colombier 1277dd7cddfSDavid du Colombier int 1289a747e4fSDavid du Colombier prettyrrfmt(Fmt *f) 1297dd7cddfSDavid du Colombier { 1307dd7cddfSDavid du Colombier RR *rp; 1317dd7cddfSDavid du Colombier char buf[3*Domlen]; 1327dd7cddfSDavid du Colombier char *p, *e; 1338754a1dfSDavid du Colombier Txt *t; 1347dd7cddfSDavid du Colombier 1359a747e4fSDavid du Colombier rp = va_arg(f->args, RR*); 1367dd7cddfSDavid du Colombier if(rp == 0){ 1377dd7cddfSDavid du Colombier strcpy(buf, "<null>"); 1387dd7cddfSDavid du Colombier goto out; 1397dd7cddfSDavid du Colombier } 1407dd7cddfSDavid du Colombier 1417dd7cddfSDavid du Colombier p = buf; 1427dd7cddfSDavid du Colombier e = buf + sizeof(buf); 1437dd7cddfSDavid du Colombier p = seprint(p, e, "%-32.32s %-15.15s %-5.5s", rp->owner->name, 1447dd7cddfSDavid du Colombier longtime(rp->db? rp->ttl: (rp->ttl - now)), 1459a747e4fSDavid du Colombier rrname(rp->type, buf, sizeof buf)); 1467dd7cddfSDavid du Colombier 1477dd7cddfSDavid du Colombier if(rp->negative){ 14872061b92SDavid du Colombier seprint(p, e, "negative rcode %d", rp->negrcode); 1497dd7cddfSDavid du Colombier goto out; 1507dd7cddfSDavid du Colombier } 1517dd7cddfSDavid du Colombier 1527dd7cddfSDavid du Colombier switch(rp->type){ 1537dd7cddfSDavid du Colombier case Thinfo: 1547dd7cddfSDavid du Colombier seprint(p, e, "\t%s %s", rp->cpu->name, rp->os->name); 1557dd7cddfSDavid du Colombier break; 1567dd7cddfSDavid du Colombier case Tcname: 1577dd7cddfSDavid du Colombier case Tmb: 1587dd7cddfSDavid du Colombier case Tmd: 1597dd7cddfSDavid du Colombier case Tmf: 1607dd7cddfSDavid du Colombier case Tns: 1614f8f669cSDavid du Colombier seprint(p, e, "\t%s", (rp->host? rp->host->name: "")); 1627dd7cddfSDavid du Colombier break; 1637dd7cddfSDavid du Colombier case Tmg: 1647dd7cddfSDavid du Colombier case Tmr: 1654f8f669cSDavid du Colombier seprint(p, e, "\t%s", (rp->mb? rp->mb->name: "")); 1667dd7cddfSDavid du Colombier break; 1677dd7cddfSDavid du Colombier case Tminfo: 1684f8f669cSDavid du Colombier seprint(p, e, "\t%s %s", (rp->mb? rp->mb->name: ""), 1694f8f669cSDavid du Colombier (rp->rmb? rp->rmb->name: "")); 1707dd7cddfSDavid du Colombier break; 1717dd7cddfSDavid du Colombier case Tmx: 1724f8f669cSDavid du Colombier seprint(p, e, "\t%lud %s", rp->pref, 1734f8f669cSDavid du Colombier (rp->host? rp->host->name: "")); 1747dd7cddfSDavid du Colombier break; 1757dd7cddfSDavid du Colombier case Ta: 1765d459b5aSDavid du Colombier case Taaaa: 1774f8f669cSDavid du Colombier seprint(p, e, "\t%s", (rp->ip? rp->ip->name: "")); 1787dd7cddfSDavid du Colombier break; 1797dd7cddfSDavid du Colombier case Tptr: 1804f8f669cSDavid du Colombier seprint(p, e, "\t%s", (rp->ptr? rp->ptr->name: "")); 1817dd7cddfSDavid du Colombier break; 1827dd7cddfSDavid du Colombier case Tsoa: 1834f8f669cSDavid du Colombier seprint(p, e, "\t%s %s %lud %lud %lud %lud %lud", 1844f8f669cSDavid du Colombier rp->host->name, rp->rmb->name, rp->soa->serial, 1854f8f669cSDavid du Colombier rp->soa->refresh, rp->soa->retry, 1867dd7cddfSDavid du Colombier rp->soa->expire, rp->soa->minttl); 1877dd7cddfSDavid du Colombier break; 1884f8f669cSDavid du Colombier case Tsrv: 1894f8f669cSDavid du Colombier seprint(p, e, "\t%ud %ud %ud %s", 190225077b0SDavid du Colombier rp->srv->pri, rp->srv->weight, rp->port, rp->host->name); 1914f8f669cSDavid du Colombier break; 1929a747e4fSDavid du Colombier case Tnull: 1939a747e4fSDavid du Colombier seprint(p, e, "\t%.*H", rp->null->dlen, rp->null->data); 1949a747e4fSDavid du Colombier break; 1957dd7cddfSDavid du Colombier case Ttxt: 1968754a1dfSDavid du Colombier p = seprint(p, e, "\t"); 1978754a1dfSDavid du Colombier for(t = rp->txt; t != nil; t = t->next) 1988754a1dfSDavid du Colombier p = seprint(p, e, "%s", t->p); 1997dd7cddfSDavid du Colombier break; 2007dd7cddfSDavid du Colombier case Trp: 2018754a1dfSDavid du Colombier seprint(p, e, "\t%s %s", rp->rmb->name, rp->rp->name); 2027dd7cddfSDavid du Colombier break; 2037dd7cddfSDavid du Colombier case Tkey: 2047dd7cddfSDavid du Colombier seprint(p, e, "\t%d %d %d", rp->key->flags, rp->key->proto, 2057dd7cddfSDavid du Colombier rp->key->alg); 2067dd7cddfSDavid du Colombier break; 2077dd7cddfSDavid du Colombier case Tsig: 2087dd7cddfSDavid du Colombier seprint(p, e, "\t%d %d %d %lud %lud %lud %d %s", 2094f8f669cSDavid du Colombier rp->sig->type, rp->sig->alg, rp->sig->labels, 2104f8f669cSDavid du Colombier rp->sig->ttl, rp->sig->exp, rp->sig->incep, 2114f8f669cSDavid du Colombier rp->sig->tag, rp->sig->signer->name); 2127dd7cddfSDavid du Colombier break; 2137dd7cddfSDavid du Colombier case Tcert: 2147dd7cddfSDavid du Colombier seprint(p, e, "\t%d %d %d", 2157dd7cddfSDavid du Colombier rp->sig->type, rp->sig->tag, rp->sig->alg); 2167dd7cddfSDavid du Colombier break; 2177dd7cddfSDavid du Colombier } 2187dd7cddfSDavid du Colombier out: 2199a747e4fSDavid du Colombier return fmtstrcpy(f, buf); 2207dd7cddfSDavid du Colombier } 2217dd7cddfSDavid du Colombier 2227dd7cddfSDavid du Colombier void 2237dd7cddfSDavid du Colombier logsection(char *flag, RR *rp) 2247dd7cddfSDavid du Colombier { 2257dd7cddfSDavid du Colombier if(rp == nil) 2267dd7cddfSDavid du Colombier return; 2277dd7cddfSDavid du Colombier print("\t%s%R\n", flag, rp); 2287dd7cddfSDavid du Colombier for(rp = rp->next; rp != nil; rp = rp->next) 2297dd7cddfSDavid du Colombier print("\t %R\n", rp); 2307dd7cddfSDavid du Colombier } 2317dd7cddfSDavid du Colombier 2327dd7cddfSDavid du Colombier void 2337dd7cddfSDavid du Colombier logreply(int id, uchar *addr, DNSmsg *mp) 2347dd7cddfSDavid du Colombier { 2357dd7cddfSDavid du Colombier RR *rp; 2364f8f669cSDavid du Colombier char buf[12], resp[32]; 2377dd7cddfSDavid du Colombier 2387dd7cddfSDavid du Colombier switch(mp->flags & Rmask){ 2397dd7cddfSDavid du Colombier case Rok: 2407dd7cddfSDavid du Colombier strcpy(resp, "OK"); 2417dd7cddfSDavid du Colombier break; 2427dd7cddfSDavid du Colombier case Rformat: 2437dd7cddfSDavid du Colombier strcpy(resp, "Format error"); 2447dd7cddfSDavid du Colombier break; 2457dd7cddfSDavid du Colombier case Rserver: 2467dd7cddfSDavid du Colombier strcpy(resp, "Server failed"); 2477dd7cddfSDavid du Colombier break; 2487dd7cddfSDavid du Colombier case Rname: 2497dd7cddfSDavid du Colombier strcpy(resp, "Nonexistent"); 2507dd7cddfSDavid du Colombier break; 2517dd7cddfSDavid du Colombier case Runimplimented: 2527dd7cddfSDavid du Colombier strcpy(resp, "Unimplemented"); 2537dd7cddfSDavid du Colombier break; 2547dd7cddfSDavid du Colombier case Rrefused: 2557dd7cddfSDavid du Colombier strcpy(resp, "Refused"); 2567dd7cddfSDavid du Colombier break; 2577dd7cddfSDavid du Colombier default: 2587dd7cddfSDavid du Colombier sprint(resp, "%d", mp->flags & Rmask); 2597dd7cddfSDavid du Colombier break; 2607dd7cddfSDavid du Colombier } 2617dd7cddfSDavid du Colombier 2627dd7cddfSDavid du Colombier print("%d: rcvd %s from %I (%s%s%s%s%s)\n", id, resp, addr, 2637dd7cddfSDavid du Colombier mp->flags & Fauth? "authoritative": "", 2647dd7cddfSDavid du Colombier mp->flags & Ftrunc? " truncated": "", 2657dd7cddfSDavid du Colombier mp->flags & Frecurse? " recurse": "", 2667dd7cddfSDavid du Colombier mp->flags & Fcanrec? " can_recurse": "", 2674f8f669cSDavid du Colombier (mp->flags & (Fauth|Rmask)) == (Fauth|Rname)? " nx": ""); 2687dd7cddfSDavid du Colombier for(rp = mp->qd; rp != nil; rp = rp->next) 2694f8f669cSDavid du Colombier print("\tQ: %s %s\n", rp->owner->name, 2704f8f669cSDavid du Colombier rrname(rp->type, buf, sizeof buf)); 2717dd7cddfSDavid du Colombier logsection("Ans: ", mp->an); 2727dd7cddfSDavid du Colombier logsection("Auth: ", mp->ns); 2737dd7cddfSDavid du Colombier logsection("Hint: ", mp->ar); 2747dd7cddfSDavid du Colombier } 2757dd7cddfSDavid du Colombier 2767dd7cddfSDavid du Colombier void 2777dd7cddfSDavid du Colombier logsend(int id, int subid, uchar *addr, char *sname, char *rname, int type) 2787dd7cddfSDavid du Colombier { 2797dd7cddfSDavid du Colombier char buf[12]; 2807dd7cddfSDavid du Colombier 2817dd7cddfSDavid du Colombier print("%d.%d: sending to %I/%s %s %s\n", id, subid, 2829a747e4fSDavid du Colombier addr, sname, rname, rrname(type, buf, sizeof buf)); 2837dd7cddfSDavid du Colombier } 2847dd7cddfSDavid du Colombier 2857dd7cddfSDavid du Colombier RR* 2867dd7cddfSDavid du Colombier getdnsservers(int class) 2877dd7cddfSDavid du Colombier { 2887dd7cddfSDavid du Colombier RR *rr; 2897dd7cddfSDavid du Colombier 2907dd7cddfSDavid du Colombier if(servername == nil) 2917dd7cddfSDavid du Colombier return dnsservers(class); 2927dd7cddfSDavid du Colombier 2937dd7cddfSDavid du Colombier rr = rralloc(Tns); 2947dd7cddfSDavid du Colombier rr->owner = dnlookup("local#dns#servers", class, 1); 2957dd7cddfSDavid du Colombier rr->host = dnlookup(servername, class, 1); 2967dd7cddfSDavid du Colombier 2977dd7cddfSDavid du Colombier return rr; 2987dd7cddfSDavid du Colombier } 2997dd7cddfSDavid du Colombier 3007dd7cddfSDavid du Colombier void 3017dd7cddfSDavid du Colombier squirrelserveraddrs(void) 3027dd7cddfSDavid du Colombier { 303*d9924332SDavid du Colombier int v4; 304*d9924332SDavid du Colombier char *attr; 3057dd7cddfSDavid du Colombier RR *rr, *rp, **l; 3067dd7cddfSDavid du Colombier Request req; 3077dd7cddfSDavid du Colombier 3087dd7cddfSDavid du Colombier /* look up the resolver address first */ 3094f8f669cSDavid du Colombier cfg.resolver = 0; 3107dd7cddfSDavid du Colombier debug = 0; 3117dd7cddfSDavid du Colombier if(serveraddrs) 3127dd7cddfSDavid du Colombier rrfreelist(serveraddrs); 3137dd7cddfSDavid du Colombier serveraddrs = nil; 3147dd7cddfSDavid du Colombier rr = getdnsservers(Cin); 3157dd7cddfSDavid du Colombier l = &serveraddrs; 3167dd7cddfSDavid du Colombier for(rp = rr; rp != nil; rp = rp->next){ 317*d9924332SDavid du Colombier attr = ipattr(rp->host->name); 318*d9924332SDavid du Colombier v4 = strcmp(attr, "ip") == 0; 319*d9924332SDavid du Colombier if(v4 || strcmp(attr, "ipv6") == 0){ 320*d9924332SDavid du Colombier *l = rralloc(v4? Ta: Taaaa); 3217dd7cddfSDavid du Colombier (*l)->owner = rp->host; 3227dd7cddfSDavid du Colombier (*l)->ip = rp->host; 3237dd7cddfSDavid du Colombier l = &(*l)->next; 3247dd7cddfSDavid du Colombier continue; 3257dd7cddfSDavid du Colombier } 3267dd7cddfSDavid du Colombier req.isslave = 1; 327e02f7f02SDavid du Colombier req.aborttime = NS2MS(nowns) + Maxreqtm; 328271b8d73SDavid du Colombier *l = dnresolve(rp->host->name, Cin, Ta, &req, 0, 0, Recurse, 0, 0); 329*d9924332SDavid du Colombier if(*l == nil) 330*d9924332SDavid du Colombier *l = dnresolve(rp->host->name, Cin, Taaaa, &req, 331*d9924332SDavid du Colombier 0, 0, Recurse, 0, 0); 3327dd7cddfSDavid du Colombier while(*l != nil) 3337dd7cddfSDavid du Colombier l = &(*l)->next; 3347dd7cddfSDavid du Colombier } 3354f8f669cSDavid du Colombier cfg.resolver = 1; 3367dd7cddfSDavid du Colombier debug = 1; 3377dd7cddfSDavid du Colombier } 3387dd7cddfSDavid du Colombier 3397dd7cddfSDavid du Colombier void 3407dd7cddfSDavid du Colombier preloadserveraddrs(void) 3417dd7cddfSDavid du Colombier { 3427dd7cddfSDavid du Colombier RR *rp, **l, *first; 3437dd7cddfSDavid du Colombier 3447dd7cddfSDavid du Colombier l = &first; 3457dd7cddfSDavid du Colombier for(rp = serveraddrs; rp != nil; rp = rp->next){ 3467dd7cddfSDavid du Colombier rrcopy(rp, l); 3476dc4800dSDavid du Colombier rrattach(first, Authoritative); 3487dd7cddfSDavid du Colombier } 3497dd7cddfSDavid du Colombier } 3507dd7cddfSDavid du Colombier 3517dd7cddfSDavid du Colombier int 3527dd7cddfSDavid du Colombier setserver(char *server) 3537dd7cddfSDavid du Colombier { 3547dd7cddfSDavid du Colombier if(servername != nil){ 3557dd7cddfSDavid du Colombier free(servername); 3567dd7cddfSDavid du Colombier servername = nil; 3574f8f669cSDavid du Colombier cfg.resolver = 0; 3587dd7cddfSDavid du Colombier } 3597dd7cddfSDavid du Colombier if(server == nil || *server == 0) 3607dd7cddfSDavid du Colombier return 0; 3617dd7cddfSDavid du Colombier servername = strdup(server); 3627dd7cddfSDavid du Colombier squirrelserveraddrs(); 3637dd7cddfSDavid du Colombier if(serveraddrs == nil){ 3647dd7cddfSDavid du Colombier print("can't resolve %s\n", servername); 3654f8f669cSDavid du Colombier cfg.resolver = 0; 3664f8f669cSDavid du Colombier } else 3674f8f669cSDavid du Colombier cfg.resolver = 1; 3684f8f669cSDavid du Colombier return cfg.resolver? 0: -1; 3697dd7cddfSDavid du Colombier } 3707dd7cddfSDavid du Colombier 3717dd7cddfSDavid du Colombier void 3727dd7cddfSDavid du Colombier doquery(char *name, char *tstr) 3737dd7cddfSDavid du Colombier { 3744f8f669cSDavid du Colombier int len, type, rooted; 3756b0d5c8bSDavid du Colombier char *p, *np; 3766b0d5c8bSDavid du Colombier char buf[1024]; 3774f8f669cSDavid du Colombier RR *rr, *rp; 3784f8f669cSDavid du Colombier Request req; 3797dd7cddfSDavid du Colombier 3804f8f669cSDavid du Colombier if(cfg.resolver) 3817dd7cddfSDavid du Colombier preloadserveraddrs(); 3827dd7cddfSDavid du Colombier 3837dd7cddfSDavid du Colombier /* default to an "ip" request if alpha, "ptr" if numeric */ 3844f8f669cSDavid du Colombier if(tstr == nil || *tstr == 0) 3857dd7cddfSDavid du Colombier if(strcmp(ipattr(name), "ip") == 0) 3867dd7cddfSDavid du Colombier tstr = "ptr"; 3877dd7cddfSDavid du Colombier else 3887dd7cddfSDavid du Colombier tstr = "ip"; 3897dd7cddfSDavid du Colombier 3907dd7cddfSDavid du Colombier /* if name end in '.', remove it */ 3917dd7cddfSDavid du Colombier len = strlen(name); 392271b8d73SDavid du Colombier if(len > 0 && name[len-1] == '.'){ 393271b8d73SDavid du Colombier rooted = 1; 3947dd7cddfSDavid du Colombier name[len-1] = 0; 395271b8d73SDavid du Colombier } else 396271b8d73SDavid du Colombier rooted = 0; 3977dd7cddfSDavid du Colombier 3987dd7cddfSDavid du Colombier /* inverse queries may need to be permuted */ 3999a747e4fSDavid du Colombier strncpy(buf, name, sizeof buf); 40053874d13SDavid du Colombier if(strcmp("ptr", tstr) == 0 && cistrstr(name, ".arpa") == nil){ 40153874d13SDavid du Colombier /* TODO: reversing v6 addrs is harder */ 4027dd7cddfSDavid du Colombier for(p = name; *p; p++) 4037dd7cddfSDavid du Colombier ; 4047dd7cddfSDavid du Colombier *p = '.'; 4057dd7cddfSDavid du Colombier np = buf; 4067dd7cddfSDavid du Colombier len = 0; 4077dd7cddfSDavid du Colombier while(p >= name){ 4087dd7cddfSDavid du Colombier len++; 4097dd7cddfSDavid du Colombier p--; 4107dd7cddfSDavid du Colombier if(*p == '.'){ 4117dd7cddfSDavid du Colombier memmove(np, p+1, len); 4127dd7cddfSDavid du Colombier np += len; 4137dd7cddfSDavid du Colombier len = 0; 4147dd7cddfSDavid du Colombier } 4157dd7cddfSDavid du Colombier } 4167dd7cddfSDavid du Colombier memmove(np, p+1, len); 4177dd7cddfSDavid du Colombier np += len; 41853874d13SDavid du Colombier strcpy(np, "in-addr.arpa"); /* TODO: ip6.arpa for v6 */ 4197dd7cddfSDavid du Colombier } 4207dd7cddfSDavid du Colombier 4217dd7cddfSDavid du Colombier /* look it up */ 4227dd7cddfSDavid du Colombier type = rrtype(tstr); 4237dd7cddfSDavid du Colombier if(type < 0){ 4247dd7cddfSDavid du Colombier print("!unknown type %s\n", tstr); 4257dd7cddfSDavid du Colombier return; 4267dd7cddfSDavid du Colombier } 4277dd7cddfSDavid du Colombier 4284f8f669cSDavid du Colombier memset(&req, 0, sizeof req); 429b4b9fc2fSDavid du Colombier getactivity(&req, 0); 4307dd7cddfSDavid du Colombier req.isslave = 1; 431e02f7f02SDavid du Colombier req.aborttime = NS2MS(nowns) + Maxreqtm; 432271b8d73SDavid du Colombier rr = dnresolve(buf, Cin, type, &req, 0, 0, Recurse, rooted, 0); 4337dd7cddfSDavid du Colombier if(rr){ 4347dd7cddfSDavid du Colombier print("----------------------------\n"); 4357dd7cddfSDavid du Colombier for(rp = rr; rp; rp = rp->next) 4367dd7cddfSDavid du Colombier print("answer %R\n", rp); 4377dd7cddfSDavid du Colombier print("----------------------------\n"); 4387dd7cddfSDavid du Colombier } 4397dd7cddfSDavid du Colombier rrfreelist(rr); 4407dd7cddfSDavid du Colombier 441b4b9fc2fSDavid du Colombier putactivity(0); 4427dd7cddfSDavid du Colombier } 4437dd7cddfSDavid du Colombier 4447dd7cddfSDavid du Colombier void 4457dd7cddfSDavid du Colombier docmd(int n, char **f) 4467dd7cddfSDavid du Colombier { 4477dd7cddfSDavid du Colombier int tmpsrv; 4487dd7cddfSDavid du Colombier char *name, *type; 4497dd7cddfSDavid du Colombier 4504f8f669cSDavid du Colombier name = type = nil; 4517dd7cddfSDavid du Colombier tmpsrv = 0; 4527dd7cddfSDavid du Colombier 4537dd7cddfSDavid du Colombier if(*f[0] == '@') { 4547dd7cddfSDavid du Colombier if(setserver(f[0]+1) < 0) 4557dd7cddfSDavid du Colombier return; 4567dd7cddfSDavid du Colombier 4577dd7cddfSDavid du Colombier switch(n){ 4587dd7cddfSDavid du Colombier case 3: 4597dd7cddfSDavid du Colombier type = f[2]; 4607dd7cddfSDavid du Colombier /* fall through */ 4617dd7cddfSDavid du Colombier case 2: 4627dd7cddfSDavid du Colombier name = f[1]; 4637dd7cddfSDavid du Colombier tmpsrv = 1; 4647dd7cddfSDavid du Colombier break; 4657dd7cddfSDavid du Colombier } 4664f8f669cSDavid du Colombier } else 4677dd7cddfSDavid du Colombier switch(n){ 4687dd7cddfSDavid du Colombier case 2: 4697dd7cddfSDavid du Colombier type = f[1]; 4707dd7cddfSDavid du Colombier /* fall through */ 4717dd7cddfSDavid du Colombier case 1: 4727dd7cddfSDavid du Colombier name = f[0]; 4737dd7cddfSDavid du Colombier break; 4747dd7cddfSDavid du Colombier } 4757dd7cddfSDavid du Colombier 4767dd7cddfSDavid du Colombier if(name == nil) 4777dd7cddfSDavid du Colombier return; 4787dd7cddfSDavid du Colombier 4797dd7cddfSDavid du Colombier doquery(name, type); 4807dd7cddfSDavid du Colombier 4817dd7cddfSDavid du Colombier if(tmpsrv) 4827dd7cddfSDavid du Colombier setserver(""); 4837dd7cddfSDavid du Colombier } 484