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){ 1477dd7cddfSDavid du Colombier seprint(p, e, "negative rcode %d\n", 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", 1894f8f669cSDavid du Colombier rp->srv->pri, rp->srv->weight, rp->srv->port, 1904f8f669cSDavid du Colombier rp->srv->target->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 { 3037dd7cddfSDavid du Colombier RR *rr, *rp, **l; 3047dd7cddfSDavid du Colombier Request req; 3057dd7cddfSDavid du Colombier 3067dd7cddfSDavid du Colombier /* look up the resolver address first */ 3074f8f669cSDavid du Colombier cfg.resolver = 0; 3087dd7cddfSDavid du Colombier debug = 0; 3097dd7cddfSDavid du Colombier if(serveraddrs) 3107dd7cddfSDavid du Colombier rrfreelist(serveraddrs); 3117dd7cddfSDavid du Colombier serveraddrs = nil; 3127dd7cddfSDavid du Colombier rr = getdnsservers(Cin); 3137dd7cddfSDavid du Colombier l = &serveraddrs; 3147dd7cddfSDavid du Colombier for(rp = rr; rp != nil; rp = rp->next){ 3157dd7cddfSDavid du Colombier if(strcmp(ipattr(rp->host->name), "ip") == 0){ 3167dd7cddfSDavid du Colombier *l = rralloc(Ta); 3177dd7cddfSDavid du Colombier (*l)->owner = rp->host; 3187dd7cddfSDavid du Colombier (*l)->ip = rp->host; 3197dd7cddfSDavid du Colombier l = &(*l)->next; 3207dd7cddfSDavid du Colombier continue; 3217dd7cddfSDavid du Colombier } 3227dd7cddfSDavid du Colombier req.isslave = 1; 3232bee3af8SDavid du Colombier req.aborttime = now + Maxreqtm; 324271b8d73SDavid du Colombier *l = dnresolve(rp->host->name, Cin, Ta, &req, 0, 0, Recurse, 0, 0); 3257dd7cddfSDavid du Colombier while(*l != nil) 3267dd7cddfSDavid du Colombier l = &(*l)->next; 3277dd7cddfSDavid du Colombier } 3284f8f669cSDavid du Colombier cfg.resolver = 1; 3297dd7cddfSDavid du Colombier debug = 1; 3307dd7cddfSDavid du Colombier } 3317dd7cddfSDavid du Colombier 3327dd7cddfSDavid du Colombier void 3337dd7cddfSDavid du Colombier preloadserveraddrs(void) 3347dd7cddfSDavid du Colombier { 3357dd7cddfSDavid du Colombier RR *rp, **l, *first; 3367dd7cddfSDavid du Colombier 3377dd7cddfSDavid du Colombier l = &first; 3387dd7cddfSDavid du Colombier for(rp = serveraddrs; rp != nil; rp = rp->next){ 3397dd7cddfSDavid du Colombier rrcopy(rp, l); 3406dc4800dSDavid du Colombier rrattach(first, Authoritative); 3417dd7cddfSDavid du Colombier } 3427dd7cddfSDavid du Colombier } 3437dd7cddfSDavid du Colombier 3447dd7cddfSDavid du Colombier int 3457dd7cddfSDavid du Colombier setserver(char *server) 3467dd7cddfSDavid du Colombier { 3477dd7cddfSDavid du Colombier if(servername != nil){ 3487dd7cddfSDavid du Colombier free(servername); 3497dd7cddfSDavid du Colombier servername = nil; 3504f8f669cSDavid du Colombier cfg.resolver = 0; 3517dd7cddfSDavid du Colombier } 3527dd7cddfSDavid du Colombier if(server == nil || *server == 0) 3537dd7cddfSDavid du Colombier return 0; 3547dd7cddfSDavid du Colombier servername = strdup(server); 3557dd7cddfSDavid du Colombier squirrelserveraddrs(); 3567dd7cddfSDavid du Colombier if(serveraddrs == nil){ 3577dd7cddfSDavid du Colombier print("can't resolve %s\n", servername); 3584f8f669cSDavid du Colombier cfg.resolver = 0; 3594f8f669cSDavid du Colombier } else 3604f8f669cSDavid du Colombier cfg.resolver = 1; 3614f8f669cSDavid du Colombier return cfg.resolver? 0: -1; 3627dd7cddfSDavid du Colombier } 3637dd7cddfSDavid du Colombier 3647dd7cddfSDavid du Colombier void 3657dd7cddfSDavid du Colombier doquery(char *name, char *tstr) 3667dd7cddfSDavid du Colombier { 3674f8f669cSDavid du Colombier int len, type, rooted; 3686b0d5c8bSDavid du Colombier char *p, *np; 3696b0d5c8bSDavid du Colombier char buf[1024]; 3704f8f669cSDavid du Colombier RR *rr, *rp; 3714f8f669cSDavid du Colombier Request req; 3727dd7cddfSDavid du Colombier 3734f8f669cSDavid du Colombier if(cfg.resolver) 3747dd7cddfSDavid du Colombier preloadserveraddrs(); 3757dd7cddfSDavid du Colombier 3767dd7cddfSDavid du Colombier /* default to an "ip" request if alpha, "ptr" if numeric */ 3774f8f669cSDavid du Colombier if(tstr == nil || *tstr == 0) 3787dd7cddfSDavid du Colombier if(strcmp(ipattr(name), "ip") == 0) 3797dd7cddfSDavid du Colombier tstr = "ptr"; 3807dd7cddfSDavid du Colombier else 3817dd7cddfSDavid du Colombier tstr = "ip"; 3827dd7cddfSDavid du Colombier 3837dd7cddfSDavid du Colombier /* if name end in '.', remove it */ 3847dd7cddfSDavid du Colombier len = strlen(name); 385271b8d73SDavid du Colombier if(len > 0 && name[len-1] == '.'){ 386271b8d73SDavid du Colombier rooted = 1; 3877dd7cddfSDavid du Colombier name[len-1] = 0; 388271b8d73SDavid du Colombier } else 389271b8d73SDavid du Colombier rooted = 0; 3907dd7cddfSDavid du Colombier 3917dd7cddfSDavid du Colombier /* inverse queries may need to be permuted */ 3929a747e4fSDavid du Colombier strncpy(buf, name, sizeof buf); 393*53874d13SDavid du Colombier if(strcmp("ptr", tstr) == 0 && cistrstr(name, ".arpa") == nil){ 394*53874d13SDavid du Colombier /* TODO: reversing v6 addrs is harder */ 3957dd7cddfSDavid du Colombier for(p = name; *p; p++) 3967dd7cddfSDavid du Colombier ; 3977dd7cddfSDavid du Colombier *p = '.'; 3987dd7cddfSDavid du Colombier np = buf; 3997dd7cddfSDavid du Colombier len = 0; 4007dd7cddfSDavid du Colombier while(p >= name){ 4017dd7cddfSDavid du Colombier len++; 4027dd7cddfSDavid du Colombier p--; 4037dd7cddfSDavid du Colombier if(*p == '.'){ 4047dd7cddfSDavid du Colombier memmove(np, p+1, len); 4057dd7cddfSDavid du Colombier np += len; 4067dd7cddfSDavid du Colombier len = 0; 4077dd7cddfSDavid du Colombier } 4087dd7cddfSDavid du Colombier } 4097dd7cddfSDavid du Colombier memmove(np, p+1, len); 4107dd7cddfSDavid du Colombier np += len; 411*53874d13SDavid du Colombier strcpy(np, "in-addr.arpa"); /* TODO: ip6.arpa for v6 */ 4127dd7cddfSDavid du Colombier } 4137dd7cddfSDavid du Colombier 4147dd7cddfSDavid du Colombier /* look it up */ 4157dd7cddfSDavid du Colombier type = rrtype(tstr); 4167dd7cddfSDavid du Colombier if(type < 0){ 4177dd7cddfSDavid du Colombier print("!unknown type %s\n", tstr); 4187dd7cddfSDavid du Colombier return; 4197dd7cddfSDavid du Colombier } 4207dd7cddfSDavid du Colombier 4214f8f669cSDavid du Colombier memset(&req, 0, sizeof req); 422b4b9fc2fSDavid du Colombier getactivity(&req, 0); 4237dd7cddfSDavid du Colombier req.isslave = 1; 4242bee3af8SDavid du Colombier req.aborttime = now + Maxreqtm; 425271b8d73SDavid du Colombier rr = dnresolve(buf, Cin, type, &req, 0, 0, Recurse, rooted, 0); 4267dd7cddfSDavid du Colombier if(rr){ 4277dd7cddfSDavid du Colombier print("----------------------------\n"); 4287dd7cddfSDavid du Colombier for(rp = rr; rp; rp = rp->next) 4297dd7cddfSDavid du Colombier print("answer %R\n", rp); 4307dd7cddfSDavid du Colombier print("----------------------------\n"); 4317dd7cddfSDavid du Colombier } 4327dd7cddfSDavid du Colombier rrfreelist(rr); 4337dd7cddfSDavid du Colombier 434b4b9fc2fSDavid du Colombier putactivity(0); 4357dd7cddfSDavid du Colombier } 4367dd7cddfSDavid du Colombier 4377dd7cddfSDavid du Colombier void 4387dd7cddfSDavid du Colombier docmd(int n, char **f) 4397dd7cddfSDavid du Colombier { 4407dd7cddfSDavid du Colombier int tmpsrv; 4417dd7cddfSDavid du Colombier char *name, *type; 4427dd7cddfSDavid du Colombier 4434f8f669cSDavid du Colombier name = type = nil; 4447dd7cddfSDavid du Colombier tmpsrv = 0; 4457dd7cddfSDavid du Colombier 4467dd7cddfSDavid du Colombier if(*f[0] == '@') { 4477dd7cddfSDavid du Colombier if(setserver(f[0]+1) < 0) 4487dd7cddfSDavid du Colombier return; 4497dd7cddfSDavid du Colombier 4507dd7cddfSDavid du Colombier switch(n){ 4517dd7cddfSDavid du Colombier case 3: 4527dd7cddfSDavid du Colombier type = f[2]; 4537dd7cddfSDavid du Colombier /* fall through */ 4547dd7cddfSDavid du Colombier case 2: 4557dd7cddfSDavid du Colombier name = f[1]; 4567dd7cddfSDavid du Colombier tmpsrv = 1; 4577dd7cddfSDavid du Colombier break; 4587dd7cddfSDavid du Colombier } 4594f8f669cSDavid du Colombier } else 4607dd7cddfSDavid du Colombier switch(n){ 4617dd7cddfSDavid du Colombier case 2: 4627dd7cddfSDavid du Colombier type = f[1]; 4637dd7cddfSDavid du Colombier /* fall through */ 4647dd7cddfSDavid du Colombier case 1: 4657dd7cddfSDavid du Colombier name = f[0]; 4667dd7cddfSDavid du Colombier break; 4677dd7cddfSDavid du Colombier } 4687dd7cddfSDavid du Colombier 4697dd7cddfSDavid du Colombier if(name == nil) 4707dd7cddfSDavid du Colombier return; 4717dd7cddfSDavid du Colombier 4727dd7cddfSDavid du Colombier doquery(name, type); 4737dd7cddfSDavid du Colombier 4747dd7cddfSDavid du Colombier if(tmpsrv) 4757dd7cddfSDavid du Colombier setserver(""); 4767dd7cddfSDavid du Colombier } 477