1*7dd7cddfSDavid du Colombier #include <u.h> 2*7dd7cddfSDavid du Colombier #include <libc.h> 3*7dd7cddfSDavid du Colombier #include <bio.h> 4*7dd7cddfSDavid du Colombier #include <ctype.h> 5*7dd7cddfSDavid du Colombier #include <ip.h> 6*7dd7cddfSDavid du Colombier #include <ndb.h> 7*7dd7cddfSDavid du Colombier #include "dns.h" 8*7dd7cddfSDavid du Colombier 9*7dd7cddfSDavid du Colombier enum 10*7dd7cddfSDavid du Colombier { 11*7dd7cddfSDavid du Colombier Maxrequest= 4*NAMELEN, 12*7dd7cddfSDavid du Colombier Ncache= 8, 13*7dd7cddfSDavid du Colombier Maxpath= 128, 14*7dd7cddfSDavid du Colombier Maxreply= 512, 15*7dd7cddfSDavid du Colombier Maxrrr= 16, 16*7dd7cddfSDavid du Colombier }; 17*7dd7cddfSDavid du Colombier 18*7dd7cddfSDavid du Colombier static char *servername; 19*7dd7cddfSDavid du Colombier static RR *serverrr; 20*7dd7cddfSDavid du Colombier static RR *serveraddrs; 21*7dd7cddfSDavid du Colombier 22*7dd7cddfSDavid du Colombier int debug; 23*7dd7cddfSDavid du Colombier int cachedb; 24*7dd7cddfSDavid du Colombier ulong now; 25*7dd7cddfSDavid du Colombier int testing; 26*7dd7cddfSDavid du Colombier char *trace; 27*7dd7cddfSDavid du Colombier int needrefresh; 28*7dd7cddfSDavid du Colombier int resolver; 29*7dd7cddfSDavid du Colombier uchar ipaddr[IPaddrlen]; /* my ip address */ 30*7dd7cddfSDavid du Colombier int maxage; 31*7dd7cddfSDavid du Colombier char *logfile = "dns"; 32*7dd7cddfSDavid du Colombier char *dbfile; 33*7dd7cddfSDavid du Colombier char mntpt[Maxpath]; 34*7dd7cddfSDavid du Colombier 35*7dd7cddfSDavid du Colombier int prettyrrconv(va_list*, Fconv*); 36*7dd7cddfSDavid du Colombier void preloadserveraddrs(void); 37*7dd7cddfSDavid du Colombier void squirrelserveraddrs(void); 38*7dd7cddfSDavid du Colombier int setserver(char*); 39*7dd7cddfSDavid du Colombier void doquery(char*, char*); 40*7dd7cddfSDavid du Colombier void docmd(int, char**); 41*7dd7cddfSDavid du Colombier 42*7dd7cddfSDavid du Colombier void 43*7dd7cddfSDavid du Colombier main(int argc, char *argv[]) 44*7dd7cddfSDavid du Colombier { 45*7dd7cddfSDavid du Colombier int n; 46*7dd7cddfSDavid du Colombier Biobuf in; 47*7dd7cddfSDavid du Colombier char buf[1024], *p; 48*7dd7cddfSDavid du Colombier char *f[4]; 49*7dd7cddfSDavid du Colombier 50*7dd7cddfSDavid du Colombier strcpy(mntpt, "/net"); 51*7dd7cddfSDavid du Colombier 52*7dd7cddfSDavid du Colombier ARGBEGIN{ 53*7dd7cddfSDavid du Colombier case 'r': 54*7dd7cddfSDavid du Colombier resolver = 1; 55*7dd7cddfSDavid du Colombier break; 56*7dd7cddfSDavid du Colombier case 'x': 57*7dd7cddfSDavid du Colombier dbfile = "/lib/ndb/external"; 58*7dd7cddfSDavid du Colombier strcpy(mntpt, "/net.alt"); 59*7dd7cddfSDavid du Colombier break; 60*7dd7cddfSDavid du Colombier }ARGEND 61*7dd7cddfSDavid du Colombier 62*7dd7cddfSDavid du Colombier now = time(0); 63*7dd7cddfSDavid du Colombier dninit(); 64*7dd7cddfSDavid du Colombier fmtinstall('R', prettyrrconv); 65*7dd7cddfSDavid du Colombier snprint(buf, sizeof(buf), "%s/ipifc", mntpt); 66*7dd7cddfSDavid du Colombier if(myipaddr(ipaddr, buf) < 0) 67*7dd7cddfSDavid du Colombier sysfatal("can't read my ip address"); 68*7dd7cddfSDavid du Colombier opendatabase(); 69*7dd7cddfSDavid du Colombier 70*7dd7cddfSDavid du Colombier if(resolver) 71*7dd7cddfSDavid du Colombier squirrelserveraddrs(); 72*7dd7cddfSDavid du Colombier 73*7dd7cddfSDavid du Colombier debug = 1; 74*7dd7cddfSDavid du Colombier 75*7dd7cddfSDavid du Colombier if(argc > 0){ 76*7dd7cddfSDavid du Colombier docmd(argc, argv); 77*7dd7cddfSDavid du Colombier exits(0); 78*7dd7cddfSDavid du Colombier } 79*7dd7cddfSDavid du Colombier 80*7dd7cddfSDavid du Colombier Binit(&in, 0, OREAD); 81*7dd7cddfSDavid du Colombier for(print("> "); p = Brdline(&in, '\n'); print("> ")){ 82*7dd7cddfSDavid du Colombier p[Blinelen(&in)-1] = 0; 83*7dd7cddfSDavid du Colombier n = tokenize(p, f, 3); 84*7dd7cddfSDavid du Colombier if(n<1) 85*7dd7cddfSDavid du Colombier continue; 86*7dd7cddfSDavid du Colombier 87*7dd7cddfSDavid du Colombier /* flush the cache */ 88*7dd7cddfSDavid du Colombier dnpurge(); 89*7dd7cddfSDavid du Colombier 90*7dd7cddfSDavid du Colombier docmd(n, f); 91*7dd7cddfSDavid du Colombier 92*7dd7cddfSDavid du Colombier } 93*7dd7cddfSDavid du Colombier exits(0); 94*7dd7cddfSDavid du Colombier } 95*7dd7cddfSDavid du Colombier 96*7dd7cddfSDavid du Colombier static char* 97*7dd7cddfSDavid du Colombier longtime(long t) 98*7dd7cddfSDavid du Colombier { 99*7dd7cddfSDavid du Colombier int d, h, m, n; 100*7dd7cddfSDavid du Colombier static char x[128]; 101*7dd7cddfSDavid du Colombier 102*7dd7cddfSDavid du Colombier for(d = 0; t >= 24*60*60; t -= 24*60*60) 103*7dd7cddfSDavid du Colombier d++; 104*7dd7cddfSDavid du Colombier for(h = 0; t >= 60*60; t -= 60*60) 105*7dd7cddfSDavid du Colombier h++; 106*7dd7cddfSDavid du Colombier for(m = 0; t >= 60; t -= 60) 107*7dd7cddfSDavid du Colombier m++; 108*7dd7cddfSDavid du Colombier n = 0; 109*7dd7cddfSDavid du Colombier if(d) 110*7dd7cddfSDavid du Colombier n += sprint(x, "%d day ", d); 111*7dd7cddfSDavid du Colombier if(h) 112*7dd7cddfSDavid du Colombier n += sprint(x+n, "%d hr ", h); 113*7dd7cddfSDavid du Colombier if(m) 114*7dd7cddfSDavid du Colombier n += sprint(x+n, "%d min ", m); 115*7dd7cddfSDavid du Colombier if(t || n == 0) 116*7dd7cddfSDavid du Colombier sprint(x+n, "%ld sec", t); 117*7dd7cddfSDavid du Colombier return x; 118*7dd7cddfSDavid du Colombier } 119*7dd7cddfSDavid du Colombier 120*7dd7cddfSDavid du Colombier int 121*7dd7cddfSDavid du Colombier prettyrrconv(va_list *arg, Fconv *f) 122*7dd7cddfSDavid du Colombier { 123*7dd7cddfSDavid du Colombier RR *rp; 124*7dd7cddfSDavid du Colombier char buf[3*Domlen]; 125*7dd7cddfSDavid du Colombier char *p, *e; 126*7dd7cddfSDavid du Colombier 127*7dd7cddfSDavid du Colombier rp = va_arg(*arg, RR*); 128*7dd7cddfSDavid du Colombier if(rp == 0){ 129*7dd7cddfSDavid du Colombier strcpy(buf, "<null>"); 130*7dd7cddfSDavid du Colombier goto out; 131*7dd7cddfSDavid du Colombier } 132*7dd7cddfSDavid du Colombier 133*7dd7cddfSDavid du Colombier p = buf; 134*7dd7cddfSDavid du Colombier e = buf + sizeof(buf); 135*7dd7cddfSDavid du Colombier p = seprint(p, e, "%-32.32s %-15.15s %-5.5s", rp->owner->name, 136*7dd7cddfSDavid du Colombier longtime(rp->db ? rp->ttl : (rp->ttl-now)), 137*7dd7cddfSDavid du Colombier rrname(rp->type, buf)); 138*7dd7cddfSDavid du Colombier 139*7dd7cddfSDavid du Colombier if(rp->negative){ 140*7dd7cddfSDavid du Colombier seprint(p, e, "negative rcode %d\n", rp->negrcode); 141*7dd7cddfSDavid du Colombier goto out; 142*7dd7cddfSDavid du Colombier } 143*7dd7cddfSDavid du Colombier 144*7dd7cddfSDavid du Colombier switch(rp->type){ 145*7dd7cddfSDavid du Colombier case Thinfo: 146*7dd7cddfSDavid du Colombier seprint(p, e, "\t%s %s", rp->cpu->name, rp->os->name); 147*7dd7cddfSDavid du Colombier break; 148*7dd7cddfSDavid du Colombier case Tcname: 149*7dd7cddfSDavid du Colombier case Tmb: 150*7dd7cddfSDavid du Colombier case Tmd: 151*7dd7cddfSDavid du Colombier case Tmf: 152*7dd7cddfSDavid du Colombier case Tns: 153*7dd7cddfSDavid du Colombier seprint(p, e, "\t%s", rp->host->name); 154*7dd7cddfSDavid du Colombier break; 155*7dd7cddfSDavid du Colombier case Tmg: 156*7dd7cddfSDavid du Colombier case Tmr: 157*7dd7cddfSDavid du Colombier seprint(p, e, "\t%s", rp->mb->name); 158*7dd7cddfSDavid du Colombier break; 159*7dd7cddfSDavid du Colombier case Tminfo: 160*7dd7cddfSDavid du Colombier seprint(p, e, "\t%s %s", rp->mb->name, rp->rmb->name); 161*7dd7cddfSDavid du Colombier break; 162*7dd7cddfSDavid du Colombier case Tmx: 163*7dd7cddfSDavid du Colombier seprint(p, e, "\t%lud %s", rp->pref, rp->host->name); 164*7dd7cddfSDavid du Colombier break; 165*7dd7cddfSDavid du Colombier case Ta: 166*7dd7cddfSDavid du Colombier seprint(p, e, "\t%s", rp->ip->name); 167*7dd7cddfSDavid du Colombier break; 168*7dd7cddfSDavid du Colombier case Tptr: 169*7dd7cddfSDavid du Colombier seprint(p, e, "\t%s", rp->ptr->name); 170*7dd7cddfSDavid du Colombier break; 171*7dd7cddfSDavid du Colombier case Tsoa: 172*7dd7cddfSDavid du Colombier seprint(p, e, "\t%s %s %lud %lud %lud %lud %lud", rp->host->name, 173*7dd7cddfSDavid du Colombier rp->rmb->name, rp->soa->serial, rp->soa->refresh, rp->soa->retry, 174*7dd7cddfSDavid du Colombier rp->soa->expire, rp->soa->minttl); 175*7dd7cddfSDavid du Colombier break; 176*7dd7cddfSDavid du Colombier case Ttxt: 177*7dd7cddfSDavid du Colombier seprint(p, e, "\t%s", rp->txt->name); 178*7dd7cddfSDavid du Colombier break; 179*7dd7cddfSDavid du Colombier case Trp: 180*7dd7cddfSDavid du Colombier seprint(p, e, "\t%s %s", rp->rmb->name, rp->txt->name); 181*7dd7cddfSDavid du Colombier break; 182*7dd7cddfSDavid du Colombier case Tkey: 183*7dd7cddfSDavid du Colombier seprint(p, e, "\t%d %d %d", rp->key->flags, rp->key->proto, 184*7dd7cddfSDavid du Colombier rp->key->alg); 185*7dd7cddfSDavid du Colombier break; 186*7dd7cddfSDavid du Colombier case Tsig: 187*7dd7cddfSDavid du Colombier seprint(p, e, "\t%d %d %d %lud %lud %lud %d %s", 188*7dd7cddfSDavid du Colombier rp->sig->type, rp->sig->alg, rp->sig->labels, rp->sig->ttl, 189*7dd7cddfSDavid du Colombier rp->sig->exp, rp->sig->incep, rp->sig->tag, rp->sig->signer->name); 190*7dd7cddfSDavid du Colombier break; 191*7dd7cddfSDavid du Colombier case Tcert: 192*7dd7cddfSDavid du Colombier seprint(p, e, "\t%d %d %d", 193*7dd7cddfSDavid du Colombier rp->sig->type, rp->sig->tag, rp->sig->alg); 194*7dd7cddfSDavid du Colombier break; 195*7dd7cddfSDavid du Colombier default: 196*7dd7cddfSDavid du Colombier break; 197*7dd7cddfSDavid du Colombier } 198*7dd7cddfSDavid du Colombier out: 199*7dd7cddfSDavid du Colombier strconv(buf, f); 200*7dd7cddfSDavid du Colombier return sizeof(RR*); 201*7dd7cddfSDavid du Colombier } 202*7dd7cddfSDavid du Colombier 203*7dd7cddfSDavid du Colombier void 204*7dd7cddfSDavid du Colombier logsection(char *flag, RR *rp) 205*7dd7cddfSDavid du Colombier { 206*7dd7cddfSDavid du Colombier if(rp == nil) 207*7dd7cddfSDavid du Colombier return; 208*7dd7cddfSDavid du Colombier print("\t%s%R\n", flag, rp); 209*7dd7cddfSDavid du Colombier for(rp = rp->next; rp != nil; rp = rp->next) 210*7dd7cddfSDavid du Colombier print("\t %R\n", rp); 211*7dd7cddfSDavid du Colombier } 212*7dd7cddfSDavid du Colombier 213*7dd7cddfSDavid du Colombier void 214*7dd7cddfSDavid du Colombier logreply(int id, uchar *addr, DNSmsg *mp) 215*7dd7cddfSDavid du Colombier { 216*7dd7cddfSDavid du Colombier RR *rp; 217*7dd7cddfSDavid du Colombier char buf[12]; 218*7dd7cddfSDavid du Colombier char resp[32]; 219*7dd7cddfSDavid du Colombier 220*7dd7cddfSDavid du Colombier switch(mp->flags & Rmask){ 221*7dd7cddfSDavid du Colombier case Rok: 222*7dd7cddfSDavid du Colombier strcpy(resp, "OK"); 223*7dd7cddfSDavid du Colombier break; 224*7dd7cddfSDavid du Colombier case Rformat: 225*7dd7cddfSDavid du Colombier strcpy(resp, "Format error"); 226*7dd7cddfSDavid du Colombier break; 227*7dd7cddfSDavid du Colombier case Rserver: 228*7dd7cddfSDavid du Colombier strcpy(resp, "Server failed"); 229*7dd7cddfSDavid du Colombier break; 230*7dd7cddfSDavid du Colombier case Rname: 231*7dd7cddfSDavid du Colombier strcpy(resp, "Nonexistent"); 232*7dd7cddfSDavid du Colombier break; 233*7dd7cddfSDavid du Colombier case Runimplimented: 234*7dd7cddfSDavid du Colombier strcpy(resp, "Unimplemented"); 235*7dd7cddfSDavid du Colombier break; 236*7dd7cddfSDavid du Colombier case Rrefused: 237*7dd7cddfSDavid du Colombier strcpy(resp, "Refused"); 238*7dd7cddfSDavid du Colombier break; 239*7dd7cddfSDavid du Colombier default: 240*7dd7cddfSDavid du Colombier sprint(resp, "%d", mp->flags & Rmask); 241*7dd7cddfSDavid du Colombier break; 242*7dd7cddfSDavid du Colombier } 243*7dd7cddfSDavid du Colombier 244*7dd7cddfSDavid du Colombier print("%d: rcvd %s from %I (%s%s%s%s%s)\n", id, resp, addr, 245*7dd7cddfSDavid du Colombier mp->flags & Fauth ? "authoritative" : "", 246*7dd7cddfSDavid du Colombier mp->flags & Ftrunc ? " truncated" : "", 247*7dd7cddfSDavid du Colombier mp->flags & Frecurse ? " recurse" : "", 248*7dd7cddfSDavid du Colombier mp->flags & Fcanrec ? " can_recurse" : "", 249*7dd7cddfSDavid du Colombier mp->flags & (Fauth|Rname) == (Fauth|Rname) ? 250*7dd7cddfSDavid du Colombier " nx" : ""); 251*7dd7cddfSDavid du Colombier for(rp = mp->qd; rp != nil; rp = rp->next) 252*7dd7cddfSDavid du Colombier print("\tQ: %s %s\n", rp->owner->name, rrname(rp->type, buf)); 253*7dd7cddfSDavid du Colombier logsection("Ans: ", mp->an); 254*7dd7cddfSDavid du Colombier logsection("Auth: ", mp->ns); 255*7dd7cddfSDavid du Colombier logsection("Hint: ", mp->ar); 256*7dd7cddfSDavid du Colombier } 257*7dd7cddfSDavid du Colombier 258*7dd7cddfSDavid du Colombier void 259*7dd7cddfSDavid du Colombier logsend(int id, int subid, uchar *addr, char *sname, char *rname, int type) 260*7dd7cddfSDavid du Colombier { 261*7dd7cddfSDavid du Colombier char buf[12]; 262*7dd7cddfSDavid du Colombier 263*7dd7cddfSDavid du Colombier print("%d.%d: sending to %I/%s %s %s\n", id, subid, 264*7dd7cddfSDavid du Colombier addr, sname, rname, rrname(type, buf)); 265*7dd7cddfSDavid du Colombier } 266*7dd7cddfSDavid du Colombier 267*7dd7cddfSDavid du Colombier RR* 268*7dd7cddfSDavid du Colombier getdnsservers(int class) 269*7dd7cddfSDavid du Colombier { 270*7dd7cddfSDavid du Colombier RR *rr; 271*7dd7cddfSDavid du Colombier 272*7dd7cddfSDavid du Colombier if(servername == nil) 273*7dd7cddfSDavid du Colombier return dnsservers(class); 274*7dd7cddfSDavid du Colombier 275*7dd7cddfSDavid du Colombier rr = rralloc(Tns); 276*7dd7cddfSDavid du Colombier rr->owner = dnlookup("local#dns#servers", class, 1); 277*7dd7cddfSDavid du Colombier rr->host = dnlookup(servername, class, 1); 278*7dd7cddfSDavid du Colombier 279*7dd7cddfSDavid du Colombier return rr; 280*7dd7cddfSDavid du Colombier } 281*7dd7cddfSDavid du Colombier 282*7dd7cddfSDavid du Colombier void 283*7dd7cddfSDavid du Colombier squirrelserveraddrs(void) 284*7dd7cddfSDavid du Colombier { 285*7dd7cddfSDavid du Colombier RR *rr, *rp, **l; 286*7dd7cddfSDavid du Colombier Request req; 287*7dd7cddfSDavid du Colombier 288*7dd7cddfSDavid du Colombier /* look up the resolver address first */ 289*7dd7cddfSDavid du Colombier resolver = 0; 290*7dd7cddfSDavid du Colombier debug = 0; 291*7dd7cddfSDavid du Colombier if(serveraddrs) 292*7dd7cddfSDavid du Colombier rrfreelist(serveraddrs); 293*7dd7cddfSDavid du Colombier serveraddrs = nil; 294*7dd7cddfSDavid du Colombier rr = getdnsservers(Cin); 295*7dd7cddfSDavid du Colombier l = &serveraddrs; 296*7dd7cddfSDavid du Colombier for(rp = rr; rp != nil; rp = rp->next){ 297*7dd7cddfSDavid du Colombier if(strcmp(ipattr(rp->host->name), "ip") == 0){ 298*7dd7cddfSDavid du Colombier *l = rralloc(Ta); 299*7dd7cddfSDavid du Colombier (*l)->owner = rp->host; 300*7dd7cddfSDavid du Colombier (*l)->ip = rp->host; 301*7dd7cddfSDavid du Colombier l = &(*l)->next; 302*7dd7cddfSDavid du Colombier continue; 303*7dd7cddfSDavid du Colombier } 304*7dd7cddfSDavid du Colombier req.isslave = 1; 305*7dd7cddfSDavid du Colombier req.aborttime = now + 60; /* don't spend more than 60 seconds */ 306*7dd7cddfSDavid du Colombier *l = dnresolve(rp->host->name, Cin, Ta, &req, 0, 0, Recurse, 1, 0); 307*7dd7cddfSDavid du Colombier while(*l != nil) 308*7dd7cddfSDavid du Colombier l = &(*l)->next; 309*7dd7cddfSDavid du Colombier } 310*7dd7cddfSDavid du Colombier resolver = 1; 311*7dd7cddfSDavid du Colombier debug = 1; 312*7dd7cddfSDavid du Colombier } 313*7dd7cddfSDavid du Colombier 314*7dd7cddfSDavid du Colombier void 315*7dd7cddfSDavid du Colombier preloadserveraddrs(void) 316*7dd7cddfSDavid du Colombier { 317*7dd7cddfSDavid du Colombier RR *rp, **l, *first; 318*7dd7cddfSDavid du Colombier 319*7dd7cddfSDavid du Colombier l = &first; 320*7dd7cddfSDavid du Colombier for(rp = serveraddrs; rp != nil; rp = rp->next){ 321*7dd7cddfSDavid du Colombier rrcopy(rp, l); 322*7dd7cddfSDavid du Colombier rrattach(first, 1); 323*7dd7cddfSDavid du Colombier } 324*7dd7cddfSDavid du Colombier } 325*7dd7cddfSDavid du Colombier 326*7dd7cddfSDavid du Colombier int 327*7dd7cddfSDavid du Colombier setserver(char *server) 328*7dd7cddfSDavid du Colombier { 329*7dd7cddfSDavid du Colombier if(servername != nil){ 330*7dd7cddfSDavid du Colombier free(servername); 331*7dd7cddfSDavid du Colombier servername = nil; 332*7dd7cddfSDavid du Colombier resolver = 0; 333*7dd7cddfSDavid du Colombier } 334*7dd7cddfSDavid du Colombier if(server == nil || *server == 0) 335*7dd7cddfSDavid du Colombier return 0; 336*7dd7cddfSDavid du Colombier servername = strdup(server); 337*7dd7cddfSDavid du Colombier squirrelserveraddrs(); 338*7dd7cddfSDavid du Colombier if(serveraddrs == nil){ 339*7dd7cddfSDavid du Colombier print("can't resolve %s\n", servername); 340*7dd7cddfSDavid du Colombier resolver = 0; 341*7dd7cddfSDavid du Colombier } else { 342*7dd7cddfSDavid du Colombier resolver = 1; 343*7dd7cddfSDavid du Colombier } 344*7dd7cddfSDavid du Colombier return resolver ? 0 : -1; 345*7dd7cddfSDavid du Colombier } 346*7dd7cddfSDavid du Colombier 347*7dd7cddfSDavid du Colombier void 348*7dd7cddfSDavid du Colombier doquery(char *name, char *tstr) 349*7dd7cddfSDavid du Colombier { 350*7dd7cddfSDavid du Colombier Request req; 351*7dd7cddfSDavid du Colombier RR *rr, *rp; 352*7dd7cddfSDavid du Colombier int len, type; 353*7dd7cddfSDavid du Colombier char *p, *np; 354*7dd7cddfSDavid du Colombier char buf[1024]; 355*7dd7cddfSDavid du Colombier 356*7dd7cddfSDavid du Colombier if(resolver) 357*7dd7cddfSDavid du Colombier preloadserveraddrs(); 358*7dd7cddfSDavid du Colombier 359*7dd7cddfSDavid du Colombier /* default to an "ip" request if alpha, "ptr" if numeric */ 360*7dd7cddfSDavid du Colombier if(tstr == nil || *tstr == 0) { 361*7dd7cddfSDavid du Colombier if(strcmp(ipattr(name), "ip") == 0) 362*7dd7cddfSDavid du Colombier tstr = "ptr"; 363*7dd7cddfSDavid du Colombier else 364*7dd7cddfSDavid du Colombier tstr = "ip"; 365*7dd7cddfSDavid du Colombier } 366*7dd7cddfSDavid du Colombier 367*7dd7cddfSDavid du Colombier /* if name end in '.', remove it */ 368*7dd7cddfSDavid du Colombier len = strlen(name); 369*7dd7cddfSDavid du Colombier if(len > 0 && name[len-1] == '.') 370*7dd7cddfSDavid du Colombier name[len-1] = 0; 371*7dd7cddfSDavid du Colombier 372*7dd7cddfSDavid du Colombier /* inverse queries may need to be permuted */ 373*7dd7cddfSDavid du Colombier if(strcmp("ptr", tstr) == 0 374*7dd7cddfSDavid du Colombier && strstr(name, "IN-ADDR") == 0 375*7dd7cddfSDavid du Colombier && strstr(name, "in-addr") == 0){ 376*7dd7cddfSDavid du Colombier for(p = name; *p; p++) 377*7dd7cddfSDavid du Colombier ; 378*7dd7cddfSDavid du Colombier *p = '.'; 379*7dd7cddfSDavid du Colombier np = buf; 380*7dd7cddfSDavid du Colombier len = 0; 381*7dd7cddfSDavid du Colombier while(p >= name){ 382*7dd7cddfSDavid du Colombier len++; 383*7dd7cddfSDavid du Colombier p--; 384*7dd7cddfSDavid du Colombier if(*p == '.'){ 385*7dd7cddfSDavid du Colombier memmove(np, p+1, len); 386*7dd7cddfSDavid du Colombier np += len; 387*7dd7cddfSDavid du Colombier len = 0; 388*7dd7cddfSDavid du Colombier } 389*7dd7cddfSDavid du Colombier } 390*7dd7cddfSDavid du Colombier memmove(np, p+1, len); 391*7dd7cddfSDavid du Colombier np += len; 392*7dd7cddfSDavid du Colombier strcpy(np, "in-addr.arpa"); 393*7dd7cddfSDavid du Colombier strcpy(name, buf); 394*7dd7cddfSDavid du Colombier } 395*7dd7cddfSDavid du Colombier 396*7dd7cddfSDavid du Colombier /* look it up */ 397*7dd7cddfSDavid du Colombier type = rrtype(tstr); 398*7dd7cddfSDavid du Colombier if(type < 0){ 399*7dd7cddfSDavid du Colombier print("!unknown type %s\n", tstr); 400*7dd7cddfSDavid du Colombier return; 401*7dd7cddfSDavid du Colombier } 402*7dd7cddfSDavid du Colombier 403*7dd7cddfSDavid du Colombier getactivity(&req); 404*7dd7cddfSDavid du Colombier req.isslave = 1; 405*7dd7cddfSDavid du Colombier req.aborttime = now + 60; /* don't spend more than 60 seconds */ 406*7dd7cddfSDavid du Colombier rr = dnresolve(name, Cin, type, &req, 0, 0, Recurse, 1, 0); 407*7dd7cddfSDavid du Colombier if(rr){ 408*7dd7cddfSDavid du Colombier print("----------------------------\n"); 409*7dd7cddfSDavid du Colombier for(rp = rr; rp; rp = rp->next) 410*7dd7cddfSDavid du Colombier print("answer %R\n", rp); 411*7dd7cddfSDavid du Colombier print("----------------------------\n"); 412*7dd7cddfSDavid du Colombier } 413*7dd7cddfSDavid du Colombier rrfreelist(rr); 414*7dd7cddfSDavid du Colombier 415*7dd7cddfSDavid du Colombier putactivity(); 416*7dd7cddfSDavid du Colombier } 417*7dd7cddfSDavid du Colombier 418*7dd7cddfSDavid du Colombier void 419*7dd7cddfSDavid du Colombier docmd(int n, char **f) 420*7dd7cddfSDavid du Colombier { 421*7dd7cddfSDavid du Colombier int tmpsrv; 422*7dd7cddfSDavid du Colombier char *name, *type; 423*7dd7cddfSDavid du Colombier 424*7dd7cddfSDavid du Colombier name = nil; 425*7dd7cddfSDavid du Colombier type = nil; 426*7dd7cddfSDavid du Colombier tmpsrv = 0; 427*7dd7cddfSDavid du Colombier 428*7dd7cddfSDavid du Colombier if(*f[0] == '@') { 429*7dd7cddfSDavid du Colombier if(setserver(f[0]+1) < 0) 430*7dd7cddfSDavid du Colombier return; 431*7dd7cddfSDavid du Colombier 432*7dd7cddfSDavid du Colombier switch(n){ 433*7dd7cddfSDavid du Colombier case 3: 434*7dd7cddfSDavid du Colombier type = f[2]; 435*7dd7cddfSDavid du Colombier /* fall through */ 436*7dd7cddfSDavid du Colombier case 2: 437*7dd7cddfSDavid du Colombier name = f[1]; 438*7dd7cddfSDavid du Colombier tmpsrv = 1; 439*7dd7cddfSDavid du Colombier break; 440*7dd7cddfSDavid du Colombier } 441*7dd7cddfSDavid du Colombier } else { 442*7dd7cddfSDavid du Colombier switch(n){ 443*7dd7cddfSDavid du Colombier case 2: 444*7dd7cddfSDavid du Colombier type = f[1]; 445*7dd7cddfSDavid du Colombier /* fall through */ 446*7dd7cddfSDavid du Colombier case 1: 447*7dd7cddfSDavid du Colombier name = f[0]; 448*7dd7cddfSDavid du Colombier break; 449*7dd7cddfSDavid du Colombier } 450*7dd7cddfSDavid du Colombier } 451*7dd7cddfSDavid du Colombier 452*7dd7cddfSDavid du Colombier if(name == nil) 453*7dd7cddfSDavid du Colombier return; 454*7dd7cddfSDavid du Colombier 455*7dd7cddfSDavid du Colombier doquery(name, type); 456*7dd7cddfSDavid du Colombier 457*7dd7cddfSDavid du Colombier if(tmpsrv) 458*7dd7cddfSDavid du Colombier setserver(""); 459*7dd7cddfSDavid du Colombier } 460