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 { 434f8f669cSDavid du Colombier fprint(2, "%s: [-rx] [-f db-file]\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); 747dd7cddfSDavid du Colombier dninit(); 759a747e4fSDavid du Colombier fmtinstall('R', prettyrrfmt); 769a747e4fSDavid du Colombier if(myipaddr(ipaddr, mntpt) < 0) 777dd7cddfSDavid du Colombier sysfatal("can't read my ip address"); 787dd7cddfSDavid du Colombier opendatabase(); 797dd7cddfSDavid du Colombier 804f8f669cSDavid du Colombier if(cfg.resolver) 817dd7cddfSDavid du Colombier squirrelserveraddrs(); 827dd7cddfSDavid du Colombier 837dd7cddfSDavid du Colombier debug = 1; 847dd7cddfSDavid du Colombier 857dd7cddfSDavid du Colombier if(argc > 0){ 867dd7cddfSDavid du Colombier docmd(argc, argv); 877dd7cddfSDavid du Colombier exits(0); 887dd7cddfSDavid du Colombier } 897dd7cddfSDavid du Colombier 907dd7cddfSDavid du Colombier Binit(&in, 0, OREAD); 917dd7cddfSDavid du Colombier for(print("> "); p = Brdline(&in, '\n'); print("> ")){ 927dd7cddfSDavid du Colombier p[Blinelen(&in)-1] = 0; 937dd7cddfSDavid du Colombier n = tokenize(p, f, 3); 944f8f669cSDavid du Colombier if(n>=1) { 954f8f669cSDavid du Colombier dnpurge(); /* flush the cache */ 967dd7cddfSDavid du Colombier docmd(n, f); 974f8f669cSDavid du Colombier } 987dd7cddfSDavid du Colombier } 997dd7cddfSDavid du Colombier exits(0); 1007dd7cddfSDavid du Colombier } 1017dd7cddfSDavid du Colombier 1027dd7cddfSDavid du Colombier static char* 1037dd7cddfSDavid du Colombier longtime(long t) 1047dd7cddfSDavid du Colombier { 1057dd7cddfSDavid du Colombier int d, h, m, n; 1067dd7cddfSDavid du Colombier static char x[128]; 1077dd7cddfSDavid du Colombier 1087dd7cddfSDavid du Colombier for(d = 0; t >= 24*60*60; t -= 24*60*60) 1097dd7cddfSDavid du Colombier d++; 1107dd7cddfSDavid du Colombier for(h = 0; t >= 60*60; t -= 60*60) 1117dd7cddfSDavid du Colombier h++; 1127dd7cddfSDavid du Colombier for(m = 0; t >= 60; t -= 60) 1137dd7cddfSDavid du Colombier m++; 1147dd7cddfSDavid du Colombier n = 0; 1157dd7cddfSDavid du Colombier if(d) 1167dd7cddfSDavid du Colombier n += sprint(x, "%d day ", d); 1177dd7cddfSDavid du Colombier if(h) 1187dd7cddfSDavid du Colombier n += sprint(x+n, "%d hr ", h); 1197dd7cddfSDavid du Colombier if(m) 1207dd7cddfSDavid du Colombier n += sprint(x+n, "%d min ", m); 1217dd7cddfSDavid du Colombier if(t || n == 0) 1227dd7cddfSDavid du Colombier sprint(x+n, "%ld sec", t); 1237dd7cddfSDavid du Colombier return x; 1247dd7cddfSDavid du Colombier } 1257dd7cddfSDavid du Colombier 1267dd7cddfSDavid du Colombier int 1279a747e4fSDavid du Colombier prettyrrfmt(Fmt *f) 1287dd7cddfSDavid du Colombier { 1297dd7cddfSDavid du Colombier RR *rp; 1307dd7cddfSDavid du Colombier char buf[3*Domlen]; 1317dd7cddfSDavid du Colombier char *p, *e; 1328754a1dfSDavid du Colombier Txt *t; 1337dd7cddfSDavid du Colombier 1349a747e4fSDavid du Colombier rp = va_arg(f->args, RR*); 1357dd7cddfSDavid du Colombier if(rp == 0){ 1367dd7cddfSDavid du Colombier strcpy(buf, "<null>"); 1377dd7cddfSDavid du Colombier goto out; 1387dd7cddfSDavid du Colombier } 1397dd7cddfSDavid du Colombier 1407dd7cddfSDavid du Colombier p = buf; 1417dd7cddfSDavid du Colombier e = buf + sizeof(buf); 1427dd7cddfSDavid du Colombier p = seprint(p, e, "%-32.32s %-15.15s %-5.5s", rp->owner->name, 1437dd7cddfSDavid du Colombier longtime(rp->db? rp->ttl: (rp->ttl - now)), 1449a747e4fSDavid du Colombier rrname(rp->type, buf, sizeof buf)); 1457dd7cddfSDavid du Colombier 1467dd7cddfSDavid du Colombier if(rp->negative){ 147*72061b92SDavid du Colombier seprint(p, e, "negative rcode %d", rp->negrcode); 1487dd7cddfSDavid du Colombier goto out; 1497dd7cddfSDavid du Colombier } 1507dd7cddfSDavid du Colombier 1517dd7cddfSDavid du Colombier switch(rp->type){ 1527dd7cddfSDavid du Colombier case Thinfo: 1537dd7cddfSDavid du Colombier seprint(p, e, "\t%s %s", rp->cpu->name, rp->os->name); 1547dd7cddfSDavid du Colombier break; 1557dd7cddfSDavid du Colombier case Tcname: 1567dd7cddfSDavid du Colombier case Tmb: 1577dd7cddfSDavid du Colombier case Tmd: 1587dd7cddfSDavid du Colombier case Tmf: 1597dd7cddfSDavid du Colombier case Tns: 1604f8f669cSDavid du Colombier seprint(p, e, "\t%s", (rp->host? rp->host->name: "")); 1617dd7cddfSDavid du Colombier break; 1627dd7cddfSDavid du Colombier case Tmg: 1637dd7cddfSDavid du Colombier case Tmr: 1644f8f669cSDavid du Colombier seprint(p, e, "\t%s", (rp->mb? rp->mb->name: "")); 1657dd7cddfSDavid du Colombier break; 1667dd7cddfSDavid du Colombier case Tminfo: 1674f8f669cSDavid du Colombier seprint(p, e, "\t%s %s", (rp->mb? rp->mb->name: ""), 1684f8f669cSDavid du Colombier (rp->rmb? rp->rmb->name: "")); 1697dd7cddfSDavid du Colombier break; 1707dd7cddfSDavid du Colombier case Tmx: 1714f8f669cSDavid du Colombier seprint(p, e, "\t%lud %s", rp->pref, 1724f8f669cSDavid du Colombier (rp->host? rp->host->name: "")); 1737dd7cddfSDavid du Colombier break; 1747dd7cddfSDavid du Colombier case Ta: 1755d459b5aSDavid du Colombier case Taaaa: 1764f8f669cSDavid du Colombier seprint(p, e, "\t%s", (rp->ip? rp->ip->name: "")); 1777dd7cddfSDavid du Colombier break; 1787dd7cddfSDavid du Colombier case Tptr: 1794f8f669cSDavid du Colombier seprint(p, e, "\t%s", (rp->ptr? rp->ptr->name: "")); 1807dd7cddfSDavid du Colombier break; 1817dd7cddfSDavid du Colombier case Tsoa: 1824f8f669cSDavid du Colombier seprint(p, e, "\t%s %s %lud %lud %lud %lud %lud", 1834f8f669cSDavid du Colombier rp->host->name, rp->rmb->name, rp->soa->serial, 1844f8f669cSDavid du Colombier rp->soa->refresh, rp->soa->retry, 1857dd7cddfSDavid du Colombier rp->soa->expire, rp->soa->minttl); 1867dd7cddfSDavid du Colombier break; 1874f8f669cSDavid du Colombier case Tsrv: 1884f8f669cSDavid du Colombier seprint(p, e, "\t%ud %ud %ud %s", 189225077b0SDavid du Colombier rp->srv->pri, rp->srv->weight, rp->port, rp->host->name); 1904f8f669cSDavid du Colombier break; 1919a747e4fSDavid du Colombier case Tnull: 1929a747e4fSDavid du Colombier seprint(p, e, "\t%.*H", rp->null->dlen, rp->null->data); 1939a747e4fSDavid du Colombier break; 1947dd7cddfSDavid du Colombier case Ttxt: 1958754a1dfSDavid du Colombier p = seprint(p, e, "\t"); 1968754a1dfSDavid du Colombier for(t = rp->txt; t != nil; t = t->next) 1978754a1dfSDavid du Colombier p = seprint(p, e, "%s", t->p); 1987dd7cddfSDavid du Colombier break; 1997dd7cddfSDavid du Colombier case Trp: 2008754a1dfSDavid du Colombier seprint(p, e, "\t%s %s", rp->rmb->name, rp->rp->name); 2017dd7cddfSDavid du Colombier break; 2027dd7cddfSDavid du Colombier case Tkey: 2037dd7cddfSDavid du Colombier seprint(p, e, "\t%d %d %d", rp->key->flags, rp->key->proto, 2047dd7cddfSDavid du Colombier rp->key->alg); 2057dd7cddfSDavid du Colombier break; 2067dd7cddfSDavid du Colombier case Tsig: 2077dd7cddfSDavid du Colombier seprint(p, e, "\t%d %d %d %lud %lud %lud %d %s", 2084f8f669cSDavid du Colombier rp->sig->type, rp->sig->alg, rp->sig->labels, 2094f8f669cSDavid du Colombier rp->sig->ttl, rp->sig->exp, rp->sig->incep, 2104f8f669cSDavid du Colombier rp->sig->tag, rp->sig->signer->name); 2117dd7cddfSDavid du Colombier break; 2127dd7cddfSDavid du Colombier case Tcert: 2137dd7cddfSDavid du Colombier seprint(p, e, "\t%d %d %d", 2147dd7cddfSDavid du Colombier rp->sig->type, rp->sig->tag, rp->sig->alg); 2157dd7cddfSDavid du Colombier break; 2167dd7cddfSDavid du Colombier } 2177dd7cddfSDavid du Colombier out: 2189a747e4fSDavid du Colombier return fmtstrcpy(f, buf); 2197dd7cddfSDavid du Colombier } 2207dd7cddfSDavid du Colombier 2217dd7cddfSDavid du Colombier void 2227dd7cddfSDavid du Colombier logsection(char *flag, RR *rp) 2237dd7cddfSDavid du Colombier { 2247dd7cddfSDavid du Colombier if(rp == nil) 2257dd7cddfSDavid du Colombier return; 2267dd7cddfSDavid du Colombier print("\t%s%R\n", flag, rp); 2277dd7cddfSDavid du Colombier for(rp = rp->next; rp != nil; rp = rp->next) 2287dd7cddfSDavid du Colombier print("\t %R\n", rp); 2297dd7cddfSDavid du Colombier } 2307dd7cddfSDavid du Colombier 2317dd7cddfSDavid du Colombier void 2327dd7cddfSDavid du Colombier logreply(int id, uchar *addr, DNSmsg *mp) 2337dd7cddfSDavid du Colombier { 2347dd7cddfSDavid du Colombier RR *rp; 2354f8f669cSDavid du Colombier char buf[12], resp[32]; 2367dd7cddfSDavid du Colombier 2377dd7cddfSDavid du Colombier switch(mp->flags & Rmask){ 2387dd7cddfSDavid du Colombier case Rok: 2397dd7cddfSDavid du Colombier strcpy(resp, "OK"); 2407dd7cddfSDavid du Colombier break; 2417dd7cddfSDavid du Colombier case Rformat: 2427dd7cddfSDavid du Colombier strcpy(resp, "Format error"); 2437dd7cddfSDavid du Colombier break; 2447dd7cddfSDavid du Colombier case Rserver: 2457dd7cddfSDavid du Colombier strcpy(resp, "Server failed"); 2467dd7cddfSDavid du Colombier break; 2477dd7cddfSDavid du Colombier case Rname: 2487dd7cddfSDavid du Colombier strcpy(resp, "Nonexistent"); 2497dd7cddfSDavid du Colombier break; 2507dd7cddfSDavid du Colombier case Runimplimented: 2517dd7cddfSDavid du Colombier strcpy(resp, "Unimplemented"); 2527dd7cddfSDavid du Colombier break; 2537dd7cddfSDavid du Colombier case Rrefused: 2547dd7cddfSDavid du Colombier strcpy(resp, "Refused"); 2557dd7cddfSDavid du Colombier break; 2567dd7cddfSDavid du Colombier default: 2577dd7cddfSDavid du Colombier sprint(resp, "%d", mp->flags & Rmask); 2587dd7cddfSDavid du Colombier break; 2597dd7cddfSDavid du Colombier } 2607dd7cddfSDavid du Colombier 2617dd7cddfSDavid du Colombier print("%d: rcvd %s from %I (%s%s%s%s%s)\n", id, resp, addr, 2627dd7cddfSDavid du Colombier mp->flags & Fauth? "authoritative": "", 2637dd7cddfSDavid du Colombier mp->flags & Ftrunc? " truncated": "", 2647dd7cddfSDavid du Colombier mp->flags & Frecurse? " recurse": "", 2657dd7cddfSDavid du Colombier mp->flags & Fcanrec? " can_recurse": "", 2664f8f669cSDavid du Colombier (mp->flags & (Fauth|Rmask)) == (Fauth|Rname)? " nx": ""); 2677dd7cddfSDavid du Colombier for(rp = mp->qd; rp != nil; rp = rp->next) 2684f8f669cSDavid du Colombier print("\tQ: %s %s\n", rp->owner->name, 2694f8f669cSDavid du Colombier rrname(rp->type, buf, sizeof buf)); 2707dd7cddfSDavid du Colombier logsection("Ans: ", mp->an); 2717dd7cddfSDavid du Colombier logsection("Auth: ", mp->ns); 2727dd7cddfSDavid du Colombier logsection("Hint: ", mp->ar); 2737dd7cddfSDavid du Colombier } 2747dd7cddfSDavid du Colombier 2757dd7cddfSDavid du Colombier void 2767dd7cddfSDavid du Colombier logsend(int id, int subid, uchar *addr, char *sname, char *rname, int type) 2777dd7cddfSDavid du Colombier { 2787dd7cddfSDavid du Colombier char buf[12]; 2797dd7cddfSDavid du Colombier 2807dd7cddfSDavid du Colombier print("%d.%d: sending to %I/%s %s %s\n", id, subid, 2819a747e4fSDavid du Colombier addr, sname, rname, rrname(type, buf, sizeof buf)); 2827dd7cddfSDavid du Colombier } 2837dd7cddfSDavid du Colombier 2847dd7cddfSDavid du Colombier RR* 2857dd7cddfSDavid du Colombier getdnsservers(int class) 2867dd7cddfSDavid du Colombier { 2877dd7cddfSDavid du Colombier RR *rr; 2887dd7cddfSDavid du Colombier 2897dd7cddfSDavid du Colombier if(servername == nil) 2907dd7cddfSDavid du Colombier return dnsservers(class); 2917dd7cddfSDavid du Colombier 2927dd7cddfSDavid du Colombier rr = rralloc(Tns); 2937dd7cddfSDavid du Colombier rr->owner = dnlookup("local#dns#servers", class, 1); 2947dd7cddfSDavid du Colombier rr->host = dnlookup(servername, class, 1); 2957dd7cddfSDavid du Colombier 2967dd7cddfSDavid du Colombier return rr; 2977dd7cddfSDavid du Colombier } 2987dd7cddfSDavid du Colombier 2997dd7cddfSDavid du Colombier void 3007dd7cddfSDavid du Colombier squirrelserveraddrs(void) 3017dd7cddfSDavid du Colombier { 3027dd7cddfSDavid du Colombier RR *rr, *rp, **l; 3037dd7cddfSDavid du Colombier Request req; 3047dd7cddfSDavid du Colombier 3057dd7cddfSDavid du Colombier /* look up the resolver address first */ 3064f8f669cSDavid du Colombier cfg.resolver = 0; 3077dd7cddfSDavid du Colombier debug = 0; 3087dd7cddfSDavid du Colombier if(serveraddrs) 3097dd7cddfSDavid du Colombier rrfreelist(serveraddrs); 3107dd7cddfSDavid du Colombier serveraddrs = nil; 3117dd7cddfSDavid du Colombier rr = getdnsservers(Cin); 3127dd7cddfSDavid du Colombier l = &serveraddrs; 3137dd7cddfSDavid du Colombier for(rp = rr; rp != nil; rp = rp->next){ 3147dd7cddfSDavid du Colombier if(strcmp(ipattr(rp->host->name), "ip") == 0){ 3157dd7cddfSDavid du Colombier *l = rralloc(Ta); 3167dd7cddfSDavid du Colombier (*l)->owner = rp->host; 3177dd7cddfSDavid du Colombier (*l)->ip = rp->host; 3187dd7cddfSDavid du Colombier l = &(*l)->next; 3197dd7cddfSDavid du Colombier continue; 3207dd7cddfSDavid du Colombier } 3217dd7cddfSDavid du Colombier req.isslave = 1; 3222bee3af8SDavid du Colombier req.aborttime = now + Maxreqtm; 323271b8d73SDavid du Colombier *l = dnresolve(rp->host->name, Cin, Ta, &req, 0, 0, Recurse, 0, 0); 3247dd7cddfSDavid du Colombier while(*l != nil) 3257dd7cddfSDavid du Colombier l = &(*l)->next; 3267dd7cddfSDavid du Colombier } 3274f8f669cSDavid du Colombier cfg.resolver = 1; 3287dd7cddfSDavid du Colombier debug = 1; 3297dd7cddfSDavid du Colombier } 3307dd7cddfSDavid du Colombier 3317dd7cddfSDavid du Colombier void 3327dd7cddfSDavid du Colombier preloadserveraddrs(void) 3337dd7cddfSDavid du Colombier { 3347dd7cddfSDavid du Colombier RR *rp, **l, *first; 3357dd7cddfSDavid du Colombier 3367dd7cddfSDavid du Colombier l = &first; 3377dd7cddfSDavid du Colombier for(rp = serveraddrs; rp != nil; rp = rp->next){ 3387dd7cddfSDavid du Colombier rrcopy(rp, l); 3396dc4800dSDavid du Colombier rrattach(first, Authoritative); 3407dd7cddfSDavid du Colombier } 3417dd7cddfSDavid du Colombier } 3427dd7cddfSDavid du Colombier 3437dd7cddfSDavid du Colombier int 3447dd7cddfSDavid du Colombier setserver(char *server) 3457dd7cddfSDavid du Colombier { 3467dd7cddfSDavid du Colombier if(servername != nil){ 3477dd7cddfSDavid du Colombier free(servername); 3487dd7cddfSDavid du Colombier servername = nil; 3494f8f669cSDavid du Colombier cfg.resolver = 0; 3507dd7cddfSDavid du Colombier } 3517dd7cddfSDavid du Colombier if(server == nil || *server == 0) 3527dd7cddfSDavid du Colombier return 0; 3537dd7cddfSDavid du Colombier servername = strdup(server); 3547dd7cddfSDavid du Colombier squirrelserveraddrs(); 3557dd7cddfSDavid du Colombier if(serveraddrs == nil){ 3567dd7cddfSDavid du Colombier print("can't resolve %s\n", servername); 3574f8f669cSDavid du Colombier cfg.resolver = 0; 3584f8f669cSDavid du Colombier } else 3594f8f669cSDavid du Colombier cfg.resolver = 1; 3604f8f669cSDavid du Colombier return cfg.resolver? 0: -1; 3617dd7cddfSDavid du Colombier } 3627dd7cddfSDavid du Colombier 3637dd7cddfSDavid du Colombier void 3647dd7cddfSDavid du Colombier doquery(char *name, char *tstr) 3657dd7cddfSDavid du Colombier { 3664f8f669cSDavid du Colombier int len, type, rooted; 3676b0d5c8bSDavid du Colombier char *p, *np; 3686b0d5c8bSDavid du Colombier char buf[1024]; 3694f8f669cSDavid du Colombier RR *rr, *rp; 3704f8f669cSDavid du Colombier Request req; 3717dd7cddfSDavid du Colombier 3724f8f669cSDavid du Colombier if(cfg.resolver) 3737dd7cddfSDavid du Colombier preloadserveraddrs(); 3747dd7cddfSDavid du Colombier 3757dd7cddfSDavid du Colombier /* default to an "ip" request if alpha, "ptr" if numeric */ 3764f8f669cSDavid du Colombier if(tstr == nil || *tstr == 0) 3777dd7cddfSDavid du Colombier if(strcmp(ipattr(name), "ip") == 0) 3787dd7cddfSDavid du Colombier tstr = "ptr"; 3797dd7cddfSDavid du Colombier else 3807dd7cddfSDavid du Colombier tstr = "ip"; 3817dd7cddfSDavid du Colombier 3827dd7cddfSDavid du Colombier /* if name end in '.', remove it */ 3837dd7cddfSDavid du Colombier len = strlen(name); 384271b8d73SDavid du Colombier if(len > 0 && name[len-1] == '.'){ 385271b8d73SDavid du Colombier rooted = 1; 3867dd7cddfSDavid du Colombier name[len-1] = 0; 387271b8d73SDavid du Colombier } else 388271b8d73SDavid du Colombier rooted = 0; 3897dd7cddfSDavid du Colombier 3907dd7cddfSDavid du Colombier /* inverse queries may need to be permuted */ 3919a747e4fSDavid du Colombier strncpy(buf, name, sizeof buf); 39253874d13SDavid du Colombier if(strcmp("ptr", tstr) == 0 && cistrstr(name, ".arpa") == nil){ 39353874d13SDavid du Colombier /* TODO: reversing v6 addrs is harder */ 3947dd7cddfSDavid du Colombier for(p = name; *p; p++) 3957dd7cddfSDavid du Colombier ; 3967dd7cddfSDavid du Colombier *p = '.'; 3977dd7cddfSDavid du Colombier np = buf; 3987dd7cddfSDavid du Colombier len = 0; 3997dd7cddfSDavid du Colombier while(p >= name){ 4007dd7cddfSDavid du Colombier len++; 4017dd7cddfSDavid du Colombier p--; 4027dd7cddfSDavid du Colombier if(*p == '.'){ 4037dd7cddfSDavid du Colombier memmove(np, p+1, len); 4047dd7cddfSDavid du Colombier np += len; 4057dd7cddfSDavid du Colombier len = 0; 4067dd7cddfSDavid du Colombier } 4077dd7cddfSDavid du Colombier } 4087dd7cddfSDavid du Colombier memmove(np, p+1, len); 4097dd7cddfSDavid du Colombier np += len; 41053874d13SDavid du Colombier strcpy(np, "in-addr.arpa"); /* TODO: ip6.arpa for v6 */ 4117dd7cddfSDavid du Colombier } 4127dd7cddfSDavid du Colombier 4137dd7cddfSDavid du Colombier /* look it up */ 4147dd7cddfSDavid du Colombier type = rrtype(tstr); 4157dd7cddfSDavid du Colombier if(type < 0){ 4167dd7cddfSDavid du Colombier print("!unknown type %s\n", tstr); 4177dd7cddfSDavid du Colombier return; 4187dd7cddfSDavid du Colombier } 4197dd7cddfSDavid du Colombier 4204f8f669cSDavid du Colombier memset(&req, 0, sizeof req); 421b4b9fc2fSDavid du Colombier getactivity(&req, 0); 4227dd7cddfSDavid du Colombier req.isslave = 1; 4232bee3af8SDavid du Colombier req.aborttime = now + Maxreqtm; 424271b8d73SDavid du Colombier rr = dnresolve(buf, Cin, type, &req, 0, 0, Recurse, rooted, 0); 4257dd7cddfSDavid du Colombier if(rr){ 4267dd7cddfSDavid du Colombier print("----------------------------\n"); 4277dd7cddfSDavid du Colombier for(rp = rr; rp; rp = rp->next) 4287dd7cddfSDavid du Colombier print("answer %R\n", rp); 4297dd7cddfSDavid du Colombier print("----------------------------\n"); 4307dd7cddfSDavid du Colombier } 4317dd7cddfSDavid du Colombier rrfreelist(rr); 4327dd7cddfSDavid du Colombier 433b4b9fc2fSDavid du Colombier putactivity(0); 4347dd7cddfSDavid du Colombier } 4357dd7cddfSDavid du Colombier 4367dd7cddfSDavid du Colombier void 4377dd7cddfSDavid du Colombier docmd(int n, char **f) 4387dd7cddfSDavid du Colombier { 4397dd7cddfSDavid du Colombier int tmpsrv; 4407dd7cddfSDavid du Colombier char *name, *type; 4417dd7cddfSDavid du Colombier 4424f8f669cSDavid du Colombier name = type = nil; 4437dd7cddfSDavid du Colombier tmpsrv = 0; 4447dd7cddfSDavid du Colombier 4457dd7cddfSDavid du Colombier if(*f[0] == '@') { 4467dd7cddfSDavid du Colombier if(setserver(f[0]+1) < 0) 4477dd7cddfSDavid du Colombier return; 4487dd7cddfSDavid du Colombier 4497dd7cddfSDavid du Colombier switch(n){ 4507dd7cddfSDavid du Colombier case 3: 4517dd7cddfSDavid du Colombier type = f[2]; 4527dd7cddfSDavid du Colombier /* fall through */ 4537dd7cddfSDavid du Colombier case 2: 4547dd7cddfSDavid du Colombier name = f[1]; 4557dd7cddfSDavid du Colombier tmpsrv = 1; 4567dd7cddfSDavid du Colombier break; 4577dd7cddfSDavid du Colombier } 4584f8f669cSDavid du Colombier } else 4597dd7cddfSDavid du Colombier switch(n){ 4607dd7cddfSDavid du Colombier case 2: 4617dd7cddfSDavid du Colombier type = f[1]; 4627dd7cddfSDavid du Colombier /* fall through */ 4637dd7cddfSDavid du Colombier case 1: 4647dd7cddfSDavid du Colombier name = f[0]; 4657dd7cddfSDavid du Colombier break; 4667dd7cddfSDavid du Colombier } 4677dd7cddfSDavid du Colombier 4687dd7cddfSDavid du Colombier if(name == nil) 4697dd7cddfSDavid du Colombier return; 4707dd7cddfSDavid du Colombier 4717dd7cddfSDavid du Colombier doquery(name, type); 4727dd7cddfSDavid du Colombier 4737dd7cddfSDavid du Colombier if(tmpsrv) 4747dd7cddfSDavid du Colombier setserver(""); 4757dd7cddfSDavid du Colombier } 476