13e12c5d1SDavid du Colombier #include <u.h> 23e12c5d1SDavid du Colombier #include <libc.h> 33e12c5d1SDavid du Colombier #include <bio.h> 43e12c5d1SDavid du Colombier #include <ndb.h> 57dd7cddfSDavid du Colombier #include <ip.h> 63e12c5d1SDavid du Colombier #include "dns.h" 73e12c5d1SDavid du Colombier 8617c0e1eSDavid du Colombier enum { 9617c0e1eSDavid du Colombier Nibwidth = 4, 10617c0e1eSDavid du Colombier Nibmask = (1<<Nibwidth) - 1, 11617c0e1eSDavid du Colombier V6maxrevdomdepth = 128 / Nibwidth, /* bits / bits-per-nibble */ 12617c0e1eSDavid du Colombier 13*0a12e455SDavid du Colombier /* 14*0a12e455SDavid du Colombier * ttl for generated ptr records. it was zero, which might seem 15*0a12e455SDavid du Colombier * like a good idea, but some dns implementations seem to be 16*0a12e455SDavid du Colombier * confused by a zero ttl, and instead of using the data and then 17*0a12e455SDavid du Colombier * discarding the RR, they conclude that they don't have valid data. 18*0a12e455SDavid du Colombier */ 19*0a12e455SDavid du Colombier Ptrttl = 300, 20617c0e1eSDavid du Colombier }; 21617c0e1eSDavid du Colombier 223e12c5d1SDavid du Colombier static Ndb *db; 23bd389b36SDavid du Colombier static Lock dblock; 244f8f669cSDavid du Colombier 254f8f669cSDavid du Colombier static RR* addrrr(Ndbtuple*, Ndbtuple*); 264f8f669cSDavid du Colombier static RR* cnamerr(Ndbtuple*, Ndbtuple*); 273ff48bf5SDavid du Colombier static void createptrs(void); 284f8f669cSDavid du Colombier static RR* dblookup1(char*, int, int, int); 294f8f669cSDavid du Colombier static RR* doaxfr(Ndb*, char*); 304f8f669cSDavid du Colombier static Ndbtuple*look(Ndbtuple*, Ndbtuple*, char*); 314f8f669cSDavid du Colombier static RR* mxrr(Ndbtuple*, Ndbtuple*); 324f8f669cSDavid du Colombier static RR* nsrr(Ndbtuple*, Ndbtuple*); 334f8f669cSDavid du Colombier static RR* nullrr(Ndbtuple*, Ndbtuple*); 344f8f669cSDavid du Colombier static RR* ptrrr(Ndbtuple*, Ndbtuple*); 354f8f669cSDavid du Colombier static RR* soarr(Ndbtuple*, Ndbtuple*); 364f8f669cSDavid du Colombier static RR* srvrr(Ndbtuple*, Ndbtuple*); 374f8f669cSDavid du Colombier static RR* txtrr(Ndbtuple*, Ndbtuple*); 38bd389b36SDavid du Colombier 39219b2ee8SDavid du Colombier static int implemented[Tall] = 40bd389b36SDavid du Colombier { 41219b2ee8SDavid du Colombier [Ta] 1, 424f8f669cSDavid du Colombier [Taaaa] 1, 437dd7cddfSDavid du Colombier [Tcname] 1, 444f8f669cSDavid du Colombier [Tmx] 1, 454f8f669cSDavid du Colombier [Tns] 1, 469a747e4fSDavid du Colombier [Tnull] 1, 474f8f669cSDavid du Colombier [Tptr] 1, 484f8f669cSDavid du Colombier [Tsoa] 1, 494f8f669cSDavid du Colombier [Tsrv] 1, 509a747e4fSDavid du Colombier [Ttxt] 1, 51219b2ee8SDavid du Colombier }; 52bd389b36SDavid du Colombier 534f8f669cSDavid du Colombier /* straddle server configuration */ 544f8f669cSDavid du Colombier static Ndbtuple *indoms, *innmsrvs, *outnmsrvs; 554f8f669cSDavid du Colombier 5657837e0bSDavid du Colombier static void 5757837e0bSDavid du Colombier nstrcpy(char *to, char *from, int len) 5857837e0bSDavid du Colombier { 5957837e0bSDavid du Colombier strncpy(to, from, len); 6057837e0bSDavid du Colombier to[len-1] = 0; 6157837e0bSDavid du Colombier } 6257837e0bSDavid du Colombier 637dd7cddfSDavid du Colombier int 647dd7cddfSDavid du Colombier opendatabase(void) 657dd7cddfSDavid du Colombier { 664f8f669cSDavid du Colombier char netdbnm[256]; 674f8f669cSDavid du Colombier Ndb *xdb, *netdb; 687dd7cddfSDavid du Colombier 694f8f669cSDavid du Colombier if (db) 707dd7cddfSDavid du Colombier return 0; 714f8f669cSDavid du Colombier 724f8f669cSDavid du Colombier xdb = ndbopen(dbfile); /* /lib/ndb */ 734f8f669cSDavid du Colombier if(xdb) 744f8f669cSDavid du Colombier xdb->nohash = 1; /* seems odd */ 754f8f669cSDavid du Colombier 764f8f669cSDavid du Colombier snprint(netdbnm, sizeof netdbnm, "%s/ndb", mntpt); 774f8f669cSDavid du Colombier netdb = ndbopen(netdbnm); /* /net/ndb */ 784f8f669cSDavid du Colombier // if(netdb) 794f8f669cSDavid du Colombier // netdb->nohash = 1; /* cs does this; seems right */ 804f8f669cSDavid du Colombier 814f8f669cSDavid du Colombier db = ndbcat(netdb, xdb); /* both */ 824f8f669cSDavid du Colombier return db? 0: -1; 837dd7cddfSDavid du Colombier } 847dd7cddfSDavid du Colombier 853e12c5d1SDavid du Colombier /* 863e12c5d1SDavid du Colombier * lookup an RR in the network database, look for matches 873e12c5d1SDavid du Colombier * against both the domain name and the wildcarded domain name. 883e12c5d1SDavid du Colombier * 89bd389b36SDavid du Colombier * the lock makes sure only one process can be accessing the data 90bd389b36SDavid du Colombier * base at a time. This is important since there's a lot of 91bd389b36SDavid du Colombier * shared state there. 92bd389b36SDavid du Colombier * 937dd7cddfSDavid du Colombier * e.g. for x.research.bell-labs.com, first look for a match against 944f8f669cSDavid du Colombier * the x.research.bell-labs.com. If nothing matches, 954f8f669cSDavid du Colombier * try *.research.bell-labs.com. 963e12c5d1SDavid du Colombier */ 973e12c5d1SDavid du Colombier RR* 987dd7cddfSDavid du Colombier dblookup(char *name, int class, int type, int auth, int ttl) 993e12c5d1SDavid du Colombier { 1006b0d5c8bSDavid du Colombier int err; 1014f8f669cSDavid du Colombier char *wild, *cp; 1024f8f669cSDavid du Colombier char buf[256]; 1034f8f669cSDavid du Colombier RR *rp, *tp; 1044f8f669cSDavid du Colombier DN *dp, *ndp; 105bd389b36SDavid du Colombier static int parallel; 106bd389b36SDavid du Colombier static int parfd[2]; 107bd389b36SDavid du Colombier static char token[1]; 1083e12c5d1SDavid du Colombier 1093e12c5d1SDavid du Colombier /* so far only internet lookups are implemented */ 1103e12c5d1SDavid du Colombier if(class != Cin) 1113e12c5d1SDavid du Colombier return 0; 1123e12c5d1SDavid du Colombier 1137dd7cddfSDavid du Colombier err = Rname; 1147dd7cddfSDavid du Colombier 115219b2ee8SDavid du Colombier if(type == Tall){ 1164f8f669cSDavid du Colombier rp = nil; 1177dd7cddfSDavid du Colombier for (type = Ta; type < Tall; type++) 118a41547ffSDavid du Colombier /* HACK: exclude Taaaa (ipv6) for speed for now */ 119a41547ffSDavid du Colombier if(implemented[type] && (1 || type != Taaaa)) 1203ff48bf5SDavid du Colombier rrcat(&rp, dblookup(name, class, type, auth, ttl)); 121219b2ee8SDavid du Colombier return rp; 122219b2ee8SDavid du Colombier } 123bd389b36SDavid du Colombier 1244f8f669cSDavid du Colombier rp = nil; 1254f8f669cSDavid du Colombier 126219b2ee8SDavid du Colombier lock(&dblock); 1273ff48bf5SDavid du Colombier dp = dnlookup(name, class, 1); 1284f8f669cSDavid du Colombier 1297dd7cddfSDavid du Colombier if(opendatabase() < 0) 130bd389b36SDavid du Colombier goto out; 1317dd7cddfSDavid du Colombier if(dp->rr) 1327dd7cddfSDavid du Colombier err = 0; 1333e12c5d1SDavid du Colombier 1343e12c5d1SDavid du Colombier /* first try the given name */ 1354f8f669cSDavid du Colombier if(cfg.cachedb) 1367dd7cddfSDavid du Colombier rp = rrlookup(dp, type, NOneg); 1377dd7cddfSDavid du Colombier else 1383ff48bf5SDavid du Colombier rp = dblookup1(name, type, auth, ttl); 1393e12c5d1SDavid du Colombier if(rp) 140bd389b36SDavid du Colombier goto out; 1413e12c5d1SDavid du Colombier 1423e12c5d1SDavid du Colombier /* try lower case version */ 1433e12c5d1SDavid du Colombier for(cp = name; *cp; cp++) 1443e12c5d1SDavid du Colombier *cp = tolower(*cp); 1454f8f669cSDavid du Colombier if(cfg.cachedb) 1467dd7cddfSDavid du Colombier rp = rrlookup(dp, type, NOneg); 1477dd7cddfSDavid du Colombier else 1483ff48bf5SDavid du Colombier rp = dblookup1(name, type, auth, ttl); 1493e12c5d1SDavid du Colombier if(rp) 150bd389b36SDavid du Colombier goto out; 1513e12c5d1SDavid du Colombier 1527dd7cddfSDavid du Colombier /* walk the domain name trying the wildcard '*' at each position */ 1537dd7cddfSDavid du Colombier for(wild = strchr(name, '.'); wild; wild = strchr(wild+1, '.')){ 1544f8f669cSDavid du Colombier snprint(buf, sizeof buf, "*%s", wild); 1557dd7cddfSDavid du Colombier ndp = dnlookup(buf, class, 1); 1567dd7cddfSDavid du Colombier if(ndp->rr) 1577dd7cddfSDavid du Colombier err = 0; 1584f8f669cSDavid du Colombier if(cfg.cachedb) 1597dd7cddfSDavid du Colombier rp = rrlookup(ndp, type, NOneg); 1607dd7cddfSDavid du Colombier else 1617dd7cddfSDavid du Colombier rp = dblookup1(buf, type, auth, ttl); 1627dd7cddfSDavid du Colombier if(rp) 1637dd7cddfSDavid du Colombier break; 1647dd7cddfSDavid du Colombier } 1657dd7cddfSDavid du Colombier out: 1667dd7cddfSDavid du Colombier /* add owner to uncached records */ 1674f8f669cSDavid du Colombier if(rp) 1683e12c5d1SDavid du Colombier for(tp = rp; tp; tp = tp->next) 1693e12c5d1SDavid du Colombier tp->owner = dp; 1704f8f669cSDavid du Colombier else { 171a41547ffSDavid du Colombier /* 172a41547ffSDavid du Colombier * don't call it non-existent if it's not ours 173a41547ffSDavid du Colombier * (unless we're a resolver). 174a41547ffSDavid du Colombier */ 175a41547ffSDavid du Colombier if(err == Rname && (!inmyarea(name) || cfg.resolver)) 176271b8d73SDavid du Colombier err = Rserver; 1774f8f669cSDavid du Colombier dp->respcode = err; 178fb7f0c93SDavid du Colombier } 1797dd7cddfSDavid du Colombier 180bd389b36SDavid du Colombier unlock(&dblock); 1813e12c5d1SDavid du Colombier return rp; 1823e12c5d1SDavid du Colombier } 1833e12c5d1SDavid du Colombier 1844f8f669cSDavid du Colombier static ulong 1854f8f669cSDavid du Colombier intval(Ndbtuple *entry, Ndbtuple *pair, char *attr, ulong def) 1864f8f669cSDavid du Colombier { 1874f8f669cSDavid du Colombier Ndbtuple *t = look(entry, pair, attr); 1884f8f669cSDavid du Colombier 1894f8f669cSDavid du Colombier return (t? strtoul(t->val, 0, 10): def); 1904f8f669cSDavid du Colombier } 1914f8f669cSDavid du Colombier 1923e12c5d1SDavid du Colombier /* 1933e12c5d1SDavid du Colombier * lookup an RR in the network database 1943e12c5d1SDavid du Colombier */ 1953e12c5d1SDavid du Colombier static RR* 1967dd7cddfSDavid du Colombier dblookup1(char *name, int type, int auth, int ttl) 1973e12c5d1SDavid du Colombier { 1983e12c5d1SDavid du Colombier Ndbtuple *t, *nt; 1993e12c5d1SDavid du Colombier RR *rp, *list, **l; 2003e12c5d1SDavid du Colombier Ndbs s; 20157837e0bSDavid du Colombier char dname[Domlen]; 2023e12c5d1SDavid du Colombier char *attr; 2033e12c5d1SDavid du Colombier DN *dp; 2043e12c5d1SDavid du Colombier RR *(*f)(Ndbtuple*, Ndbtuple*); 2057dd7cddfSDavid du Colombier int found, x; 2063e12c5d1SDavid du Colombier 2074f8f669cSDavid du Colombier dp = nil; 2083e12c5d1SDavid du Colombier switch(type){ 2097dd7cddfSDavid du Colombier case Tptr: 2107dd7cddfSDavid du Colombier attr = "ptr"; 2117dd7cddfSDavid du Colombier f = ptrrr; 2127dd7cddfSDavid du Colombier break; 2133e12c5d1SDavid du Colombier case Ta: 2143e12c5d1SDavid du Colombier attr = "ip"; 2153e12c5d1SDavid du Colombier f = addrrr; 2163e12c5d1SDavid du Colombier break; 2179a747e4fSDavid du Colombier case Tnull: 2189a747e4fSDavid du Colombier attr = "nullrr"; 2199a747e4fSDavid du Colombier f = nullrr; 2209a747e4fSDavid du Colombier break; 2213e12c5d1SDavid du Colombier case Tns: 2223e12c5d1SDavid du Colombier attr = "ns"; 2233e12c5d1SDavid du Colombier f = nsrr; 2243e12c5d1SDavid du Colombier break; 2253e12c5d1SDavid du Colombier case Tsoa: 2263e12c5d1SDavid du Colombier attr = "soa"; 2273e12c5d1SDavid du Colombier f = soarr; 2283e12c5d1SDavid du Colombier break; 2294f8f669cSDavid du Colombier case Tsrv: 2304f8f669cSDavid du Colombier attr = "srv"; 2314f8f669cSDavid du Colombier f = srvrr; 2324f8f669cSDavid du Colombier break; 2333e12c5d1SDavid du Colombier case Tmx: 2343e12c5d1SDavid du Colombier attr = "mx"; 2353e12c5d1SDavid du Colombier f = mxrr; 2363e12c5d1SDavid du Colombier break; 2377dd7cddfSDavid du Colombier case Tcname: 2387dd7cddfSDavid du Colombier attr = "cname"; 2397dd7cddfSDavid du Colombier f = cnamerr; 2407dd7cddfSDavid du Colombier break; 2417dd7cddfSDavid du Colombier case Taxfr: 2427dd7cddfSDavid du Colombier case Tixfr: 2437dd7cddfSDavid du Colombier return doaxfr(db, name); 2443e12c5d1SDavid du Colombier default: 2454f8f669cSDavid du Colombier // dnslog("dnlookup1(%s) bad type", name); 2467dd7cddfSDavid du Colombier return nil; 2473e12c5d1SDavid du Colombier } 2483e12c5d1SDavid du Colombier 2493e12c5d1SDavid du Colombier /* 2503e12c5d1SDavid du Colombier * find a matching entry in the database 2513e12c5d1SDavid du Colombier */ 2524f8f669cSDavid du Colombier t = nil; 25357837e0bSDavid du Colombier free(ndbgetvalue(db, &s, "dom", name, attr, &t)); 254219b2ee8SDavid du Colombier 255219b2ee8SDavid du Colombier /* 256219b2ee8SDavid du Colombier * hack for local names 257219b2ee8SDavid du Colombier */ 2584f8f669cSDavid du Colombier if(t == nil && strchr(name, '.') == nil) 25957837e0bSDavid du Colombier free(ndbgetvalue(db, &s, "sys", name, attr, &t)); 2604f8f669cSDavid du Colombier if(t == nil) { 2614f8f669cSDavid du Colombier // dnslog("dnlookup1(%s) name not found", name); 2627dd7cddfSDavid du Colombier return nil; 2634f8f669cSDavid du Colombier } 2647dd7cddfSDavid du Colombier 2657dd7cddfSDavid du Colombier /* search whole entry for default domain name */ 26657837e0bSDavid du Colombier strncpy(dname, name, sizeof dname); 2677dd7cddfSDavid du Colombier for(nt = t; nt; nt = nt->entry) 2687dd7cddfSDavid du Colombier if(strcmp(nt->attr, "dom") == 0){ 26957837e0bSDavid du Colombier nstrcpy(dname, nt->val, sizeof dname); 2707dd7cddfSDavid du Colombier break; 2717dd7cddfSDavid du Colombier } 2727dd7cddfSDavid du Colombier 2737dd7cddfSDavid du Colombier /* ttl is maximum of soa minttl and entry's ttl ala rfc883 */ 2744f8f669cSDavid du Colombier x = intval(t, s.t, "ttl", 0); 2757dd7cddfSDavid du Colombier if(x > ttl) 2767dd7cddfSDavid du Colombier ttl = x; 2777dd7cddfSDavid du Colombier 2787dd7cddfSDavid du Colombier /* default ttl is one day */ 2797dd7cddfSDavid du Colombier if(ttl < 0) 2807dd7cddfSDavid du Colombier ttl = DEFTTL; 2813e12c5d1SDavid du Colombier 2823e12c5d1SDavid du Colombier /* 2833e12c5d1SDavid du Colombier * The database has 2 levels of precedence; line and entry. 2843e12c5d1SDavid du Colombier * Pairs on the same line bind tighter than pairs in the 2853e12c5d1SDavid du Colombier * same entry, so we search the line first. 2863e12c5d1SDavid du Colombier */ 2877dd7cddfSDavid du Colombier found = 0; 2883e12c5d1SDavid du Colombier list = 0; 2893e12c5d1SDavid du Colombier l = &list; 2903e12c5d1SDavid du Colombier for(nt = s.t;; ){ 2917dd7cddfSDavid du Colombier if(found == 0 && strcmp(nt->attr, "dom") == 0){ 29257837e0bSDavid du Colombier nstrcpy(dname, nt->val, sizeof dname); 2937dd7cddfSDavid du Colombier found = 1; 2947dd7cddfSDavid du Colombier } 2953e12c5d1SDavid du Colombier if(cistrcmp(attr, nt->attr) == 0){ 2963e12c5d1SDavid du Colombier rp = (*f)(t, nt); 2973e12c5d1SDavid du Colombier rp->auth = auth; 2983e12c5d1SDavid du Colombier rp->db = 1; 2997dd7cddfSDavid du Colombier if(ttl) 3007dd7cddfSDavid du Colombier rp->ttl = ttl; 3014f8f669cSDavid du Colombier if(dp == nil) 3027dd7cddfSDavid du Colombier dp = dnlookup(dname, Cin, 1); 3033e12c5d1SDavid du Colombier rp->owner = dp; 3043e12c5d1SDavid du Colombier *l = rp; 3053e12c5d1SDavid du Colombier l = &rp->next; 3063e12c5d1SDavid du Colombier nt->ptr = 1; 3073e12c5d1SDavid du Colombier } 3083e12c5d1SDavid du Colombier nt = nt->line; 3093e12c5d1SDavid du Colombier if(nt == s.t) 3103e12c5d1SDavid du Colombier break; 3113e12c5d1SDavid du Colombier } 3123e12c5d1SDavid du Colombier 3133e12c5d1SDavid du Colombier /* search whole entry */ 3143e12c5d1SDavid du Colombier for(nt = t; nt; nt = nt->entry) 3153e12c5d1SDavid du Colombier if(nt->ptr == 0 && cistrcmp(attr, nt->attr) == 0){ 3163e12c5d1SDavid du Colombier rp = (*f)(t, nt); 3173e12c5d1SDavid du Colombier rp->db = 1; 3187dd7cddfSDavid du Colombier if(ttl) 3197dd7cddfSDavid du Colombier rp->ttl = ttl; 3203e12c5d1SDavid du Colombier rp->auth = auth; 3214f8f669cSDavid du Colombier if(dp == nil) 3227dd7cddfSDavid du Colombier dp = dnlookup(dname, Cin, 1); 3233e12c5d1SDavid du Colombier rp->owner = dp; 3243e12c5d1SDavid du Colombier *l = rp; 3253e12c5d1SDavid du Colombier l = &rp->next; 3263e12c5d1SDavid du Colombier } 3273e12c5d1SDavid du Colombier ndbfree(t); 3283e12c5d1SDavid du Colombier 3294f8f669cSDavid du Colombier // dnslog("dnlookup1(%s) -> %#p", name, list); 3303e12c5d1SDavid du Colombier return list; 3313e12c5d1SDavid du Colombier } 3323e12c5d1SDavid du Colombier 3333e12c5d1SDavid du Colombier /* 3343e12c5d1SDavid du Colombier * make various types of resource records from a database entry 3353e12c5d1SDavid du Colombier */ 3363e12c5d1SDavid du Colombier static RR* 3373e12c5d1SDavid du Colombier addrrr(Ndbtuple *entry, Ndbtuple *pair) 3383e12c5d1SDavid du Colombier { 3393e12c5d1SDavid du Colombier RR *rp; 3405d459b5aSDavid du Colombier uchar addr[IPaddrlen]; 3413e12c5d1SDavid du Colombier 3423e12c5d1SDavid du Colombier USED(entry); 3435d459b5aSDavid du Colombier parseip(addr, pair->val); 3445d459b5aSDavid du Colombier if(isv4(addr)) 3453e12c5d1SDavid du Colombier rp = rralloc(Ta); 3465d459b5aSDavid du Colombier else 3475d459b5aSDavid du Colombier rp = rralloc(Taaaa); 3483e12c5d1SDavid du Colombier rp->ip = dnlookup(pair->val, Cin, 1); 3493e12c5d1SDavid du Colombier return rp; 3503e12c5d1SDavid du Colombier } 3513e12c5d1SDavid du Colombier static RR* 3529a747e4fSDavid du Colombier nullrr(Ndbtuple *entry, Ndbtuple *pair) 3539a747e4fSDavid du Colombier { 3549a747e4fSDavid du Colombier RR *rp; 3559a747e4fSDavid du Colombier 3569a747e4fSDavid du Colombier USED(entry); 3579a747e4fSDavid du Colombier rp = rralloc(Tnull); 3589a747e4fSDavid du Colombier rp->null->data = (uchar*)estrdup(pair->val); 3599a747e4fSDavid du Colombier rp->null->dlen = strlen((char*)rp->null->data); 3609a747e4fSDavid du Colombier return rp; 3619a747e4fSDavid du Colombier } 36260845620SDavid du Colombier /* 36360845620SDavid du Colombier * txt rr strings are at most 255 bytes long. one 36460845620SDavid du Colombier * can represent longer strings by multiple concatenated 36560845620SDavid du Colombier * <= 255 byte ones. 36660845620SDavid du Colombier */ 3679a747e4fSDavid du Colombier static RR* 3689a747e4fSDavid du Colombier txtrr(Ndbtuple *entry, Ndbtuple *pair) 3699a747e4fSDavid du Colombier { 3709a747e4fSDavid du Colombier RR *rp; 37160845620SDavid du Colombier Txt *t, **l; 37260845620SDavid du Colombier int i, len, sofar; 3739a747e4fSDavid du Colombier 3749a747e4fSDavid du Colombier USED(entry); 3759a747e4fSDavid du Colombier rp = rralloc(Ttxt); 37660845620SDavid du Colombier l = &rp->txt; 37760845620SDavid du Colombier rp->txt = nil; 37860845620SDavid du Colombier len = strlen(pair->val); 37960845620SDavid du Colombier sofar = 0; 38060845620SDavid du Colombier while(len > sofar){ 38160845620SDavid du Colombier t = emalloc(sizeof(*t)); 38260845620SDavid du Colombier t->next = nil; 38360845620SDavid du Colombier 38460845620SDavid du Colombier i = len-sofar; 38560845620SDavid du Colombier if(i > 255) 38660845620SDavid du Colombier i = 255; 38760845620SDavid du Colombier 38860845620SDavid du Colombier t->p = emalloc(i+1); 38960845620SDavid du Colombier memmove(t->p, pair->val+sofar, i); 39060845620SDavid du Colombier t->p[i] = 0; 39160845620SDavid du Colombier sofar += i; 39260845620SDavid du Colombier 39360845620SDavid du Colombier *l = t; 39460845620SDavid du Colombier l = &t->next; 39560845620SDavid du Colombier } 3969a747e4fSDavid du Colombier return rp; 3979a747e4fSDavid du Colombier } 3989a747e4fSDavid du Colombier static RR* 3997dd7cddfSDavid du Colombier cnamerr(Ndbtuple *entry, Ndbtuple *pair) 4007dd7cddfSDavid du Colombier { 4017dd7cddfSDavid du Colombier RR *rp; 4027dd7cddfSDavid du Colombier 4037dd7cddfSDavid du Colombier USED(entry); 4047dd7cddfSDavid du Colombier rp = rralloc(Tcname); 4057dd7cddfSDavid du Colombier rp->host = dnlookup(pair->val, Cin, 1); 4067dd7cddfSDavid du Colombier return rp; 4077dd7cddfSDavid du Colombier } 4087dd7cddfSDavid du Colombier static RR* 4093e12c5d1SDavid du Colombier mxrr(Ndbtuple *entry, Ndbtuple *pair) 4103e12c5d1SDavid du Colombier { 4113e12c5d1SDavid du Colombier RR *rp; 4123e12c5d1SDavid du Colombier 4133e12c5d1SDavid du Colombier rp = rralloc(Tmx); 4143e12c5d1SDavid du Colombier rp->host = dnlookup(pair->val, Cin, 1); 4154f8f669cSDavid du Colombier rp->pref = intval(entry, pair, "pref", 1); 4163e12c5d1SDavid du Colombier return rp; 4173e12c5d1SDavid du Colombier } 4183e12c5d1SDavid du Colombier static RR* 4193e12c5d1SDavid du Colombier nsrr(Ndbtuple *entry, Ndbtuple *pair) 4203e12c5d1SDavid du Colombier { 4213e12c5d1SDavid du Colombier RR *rp; 4227dd7cddfSDavid du Colombier Ndbtuple *t; 4233e12c5d1SDavid du Colombier 4243e12c5d1SDavid du Colombier rp = rralloc(Tns); 4253e12c5d1SDavid du Colombier rp->host = dnlookup(pair->val, Cin, 1); 4267dd7cddfSDavid du Colombier t = look(entry, pair, "soa"); 4277dd7cddfSDavid du Colombier if(t && t->val[0] == 0) 4283e12c5d1SDavid du Colombier rp->local = 1; 4293e12c5d1SDavid du Colombier return rp; 4303e12c5d1SDavid du Colombier } 4317dd7cddfSDavid du Colombier static RR* 4327dd7cddfSDavid du Colombier ptrrr(Ndbtuple *entry, Ndbtuple *pair) 4337dd7cddfSDavid du Colombier { 4347dd7cddfSDavid du Colombier RR *rp; 4353e12c5d1SDavid du Colombier 4367dd7cddfSDavid du Colombier USED(entry); 4377dd7cddfSDavid du Colombier rp = rralloc(Tns); 4387dd7cddfSDavid du Colombier rp->ptr = dnlookup(pair->val, Cin, 1); 4397dd7cddfSDavid du Colombier return rp; 4407dd7cddfSDavid du Colombier } 4413e12c5d1SDavid du Colombier static RR* 4423e12c5d1SDavid du Colombier soarr(Ndbtuple *entry, Ndbtuple *pair) 4433e12c5d1SDavid du Colombier { 4443e12c5d1SDavid du Colombier RR *rp; 4457dd7cddfSDavid du Colombier Ndbtuple *ns, *mb, *t; 4463e12c5d1SDavid du Colombier char mailbox[Domlen]; 4477dd7cddfSDavid du Colombier Ndb *ndb; 4487dd7cddfSDavid du Colombier char *p; 4493e12c5d1SDavid du Colombier 4503e12c5d1SDavid du Colombier rp = rralloc(Tsoa); 4517dd7cddfSDavid du Colombier rp->soa->serial = 1; 4527dd7cddfSDavid du Colombier for(ndb = db; ndb; ndb = ndb->next) 4537dd7cddfSDavid du Colombier if(ndb->mtime > rp->soa->serial) 4547dd7cddfSDavid du Colombier rp->soa->serial = ndb->mtime; 4554f8f669cSDavid du Colombier 4564f8f669cSDavid du Colombier rp->soa->retry = intval(entry, pair, "retry", Hour); 4574f8f669cSDavid du Colombier rp->soa->expire = intval(entry, pair, "expire", Day); 4584f8f669cSDavid du Colombier rp->soa->minttl = intval(entry, pair, "ttl", Day); 4594f8f669cSDavid du Colombier rp->soa->refresh = intval(entry, pair, "refresh", Day); 4604f8f669cSDavid du Colombier rp->soa->serial = intval(entry, pair, "serial", rp->soa->serial); 4617dd7cddfSDavid du Colombier 4623e12c5d1SDavid du Colombier ns = look(entry, pair, "ns"); 4634f8f669cSDavid du Colombier if(ns == nil) 4643e12c5d1SDavid du Colombier ns = look(entry, pair, "dom"); 4653e12c5d1SDavid du Colombier rp->host = dnlookup(ns->val, Cin, 1); 4667dd7cddfSDavid du Colombier 4677dd7cddfSDavid du Colombier /* accept all of: 4687dd7cddfSDavid du Colombier * mbox=person 4697dd7cddfSDavid du Colombier * mbox=person@machine.dom 4707dd7cddfSDavid du Colombier * mbox=person.machine.dom 4717dd7cddfSDavid du Colombier */ 4727dd7cddfSDavid du Colombier mb = look(entry, pair, "mbox"); 4737dd7cddfSDavid du Colombier if(mb == nil) 4743e12c5d1SDavid du Colombier mb = look(entry, pair, "mb"); 4754f8f669cSDavid du Colombier if(mb) 4767dd7cddfSDavid du Colombier if(strchr(mb->val, '.')) { 4777dd7cddfSDavid du Colombier p = strchr(mb->val, '@'); 4787dd7cddfSDavid du Colombier if(p != nil) 4797dd7cddfSDavid du Colombier *p = '.'; 4803e12c5d1SDavid du Colombier rp->rmb = dnlookup(mb->val, Cin, 1); 4817dd7cddfSDavid du Colombier } else { 4824f8f669cSDavid du Colombier snprint(mailbox, sizeof mailbox, "%s.%s", 4837dd7cddfSDavid du Colombier mb->val, ns->val); 4843e12c5d1SDavid du Colombier rp->rmb = dnlookup(mailbox, Cin, 1); 4853e12c5d1SDavid du Colombier } 4864f8f669cSDavid du Colombier else { 4874f8f669cSDavid du Colombier snprint(mailbox, sizeof mailbox, "postmaster.%s", ns->val); 4883e12c5d1SDavid du Colombier rp->rmb = dnlookup(mailbox, Cin, 1); 4893e12c5d1SDavid du Colombier } 490dc5a79c1SDavid du Colombier 4914f8f669cSDavid du Colombier /* 4924f8f669cSDavid du Colombier * hang dns slaves off of the soa. this is 493dc5a79c1SDavid du Colombier * for managing the area. 494dc5a79c1SDavid du Colombier */ 495dc5a79c1SDavid du Colombier for(t = entry; t != nil; t = t->entry) 496dc5a79c1SDavid du Colombier if(strcmp(t->attr, "dnsslave") == 0) 497dc5a79c1SDavid du Colombier addserver(&rp->soa->slaves, t->val); 498dc5a79c1SDavid du Colombier 4993e12c5d1SDavid du Colombier return rp; 5003e12c5d1SDavid du Colombier } 5013e12c5d1SDavid du Colombier 5024f8f669cSDavid du Colombier static RR* 5034f8f669cSDavid du Colombier srvrr(Ndbtuple *entry, Ndbtuple *pair) 5044f8f669cSDavid du Colombier { 5054f8f669cSDavid du Colombier RR *rp; 5064f8f669cSDavid du Colombier 5074f8f669cSDavid du Colombier rp = rralloc(Tsrv); 5084f8f669cSDavid du Colombier rp->srv->target = dnlookup(pair->val, Cin, 1); 5094f8f669cSDavid du Colombier rp->srv->pri = intval(entry, pair, "pri", 0); 5104f8f669cSDavid du Colombier rp->srv->weight = intval(entry, pair, "weight", 0); 51153874d13SDavid du Colombier /* TODO: translate service name to port # */ 5124f8f669cSDavid du Colombier rp->srv->port = intval(entry, pair, "port", 0); 5134f8f669cSDavid du Colombier return rp; 5144f8f669cSDavid du Colombier } 5154f8f669cSDavid du Colombier 5163e12c5d1SDavid du Colombier /* 5173e12c5d1SDavid du Colombier * Look for a pair with the given attribute. look first on the same line, 5183e12c5d1SDavid du Colombier * then in the whole entry. 5193e12c5d1SDavid du Colombier */ 5203e12c5d1SDavid du Colombier static Ndbtuple* 5213e12c5d1SDavid du Colombier look(Ndbtuple *entry, Ndbtuple *line, char *attr) 5223e12c5d1SDavid du Colombier { 5233e12c5d1SDavid du Colombier Ndbtuple *nt; 5243e12c5d1SDavid du Colombier 5253e12c5d1SDavid du Colombier /* first look on same line (closer binding) */ 5263e12c5d1SDavid du Colombier for(nt = line;;){ 5273e12c5d1SDavid du Colombier if(cistrcmp(attr, nt->attr) == 0) 5283e12c5d1SDavid du Colombier return nt; 5293e12c5d1SDavid du Colombier nt = nt->line; 5303e12c5d1SDavid du Colombier if(nt == line) 5313e12c5d1SDavid du Colombier break; 5323e12c5d1SDavid du Colombier } 5333e12c5d1SDavid du Colombier /* search whole tuple */ 5343e12c5d1SDavid du Colombier for(nt = entry; nt; nt = nt->entry) 5353e12c5d1SDavid du Colombier if(cistrcmp(attr, nt->attr) == 0) 5363e12c5d1SDavid du Colombier return nt; 5373e12c5d1SDavid du Colombier return 0; 5383e12c5d1SDavid du Colombier } 5393e12c5d1SDavid du Colombier 5407dd7cddfSDavid du Colombier static RR** 5417dd7cddfSDavid du Colombier linkrr(RR *rp, DN *dp, RR **l) 5427dd7cddfSDavid du Colombier { 5437dd7cddfSDavid du Colombier rp->owner = dp; 5447dd7cddfSDavid du Colombier rp->auth = 1; 5457dd7cddfSDavid du Colombier rp->db = 1; 5467dd7cddfSDavid du Colombier *l = rp; 5477dd7cddfSDavid du Colombier return &rp->next; 5487dd7cddfSDavid du Colombier } 5497dd7cddfSDavid du Colombier 5507dd7cddfSDavid du Colombier /* these are answered specially by the tcp version */ 5517dd7cddfSDavid du Colombier static RR* 5527dd7cddfSDavid du Colombier doaxfr(Ndb *db, char *name) 5537dd7cddfSDavid du Colombier { 5547dd7cddfSDavid du Colombier USED(db, name); 5557dd7cddfSDavid du Colombier return 0; 5567dd7cddfSDavid du Colombier } 5577dd7cddfSDavid du Colombier 5587dd7cddfSDavid du Colombier 5597dd7cddfSDavid du Colombier /* 5607dd7cddfSDavid du Colombier * read the all the soa's from the database to determine area's. 5617dd7cddfSDavid du Colombier * this is only used when we're not caching the database. 5627dd7cddfSDavid du Colombier */ 5637dd7cddfSDavid du Colombier static void 5647dd7cddfSDavid du Colombier dbfile2area(Ndb *db) 5657dd7cddfSDavid du Colombier { 5667dd7cddfSDavid du Colombier Ndbtuple *t; 5677dd7cddfSDavid du Colombier 56859cc4ca5SDavid du Colombier if(debug) 5694f8f669cSDavid du Colombier dnslog("rereading %s", db->file); 5707dd7cddfSDavid du Colombier Bseek(&db->b, 0, 0); 5714f8f669cSDavid du Colombier while(t = ndbparse(db)) 5727dd7cddfSDavid du Colombier ndbfree(t); 5737dd7cddfSDavid du Colombier } 5747dd7cddfSDavid du Colombier 5757dd7cddfSDavid du Colombier /* 5767dd7cddfSDavid du Colombier * read the database into the cache 5777dd7cddfSDavid du Colombier */ 5787dd7cddfSDavid du Colombier static void 5797dd7cddfSDavid du Colombier dbpair2cache(DN *dp, Ndbtuple *entry, Ndbtuple *pair) 5807dd7cddfSDavid du Colombier { 5817dd7cddfSDavid du Colombier RR *rp; 5823ff48bf5SDavid du Colombier static ulong ord; 5837dd7cddfSDavid du Colombier 5847dd7cddfSDavid du Colombier rp = 0; 5857dd7cddfSDavid du Colombier if(cistrcmp(pair->attr, "ip") == 0){ 5863ff48bf5SDavid du Colombier dp->ordinal = ord++; 5877dd7cddfSDavid du Colombier rp = addrrr(entry, pair); 5884f8f669cSDavid du Colombier } else if(cistrcmp(pair->attr, "ns") == 0) 5897dd7cddfSDavid du Colombier rp = nsrr(entry, pair); 5904f8f669cSDavid du Colombier else if(cistrcmp(pair->attr, "soa") == 0) { 5917dd7cddfSDavid du Colombier rp = soarr(entry, pair); 5927dd7cddfSDavid du Colombier addarea(dp, rp, pair); 5934f8f669cSDavid du Colombier } else if(cistrcmp(pair->attr, "mx") == 0) 5947dd7cddfSDavid du Colombier rp = mxrr(entry, pair); 59576783259SDavid du Colombier else if(cistrcmp(pair->attr, "srv") == 0) 59676783259SDavid du Colombier rp = srvrr(entry, pair); 5974f8f669cSDavid du Colombier else if(cistrcmp(pair->attr, "cname") == 0) 5987dd7cddfSDavid du Colombier rp = cnamerr(entry, pair); 5994f8f669cSDavid du Colombier else if(cistrcmp(pair->attr, "nullrr") == 0) 6009a747e4fSDavid du Colombier rp = nullrr(entry, pair); 6014f8f669cSDavid du Colombier else if(cistrcmp(pair->attr, "txtrr") == 0) 6029a747e4fSDavid du Colombier rp = txtrr(entry, pair); 6034f8f669cSDavid du Colombier if(rp == nil) 6047dd7cddfSDavid du Colombier return; 6057dd7cddfSDavid du Colombier 6067dd7cddfSDavid du Colombier rp->owner = dp; 6077dd7cddfSDavid du Colombier rp->db = 1; 6084f8f669cSDavid du Colombier rp->ttl = intval(entry, pair, "ttl", rp->ttl); 6096dc4800dSDavid du Colombier rrattach(rp, Notauthoritative); 6107dd7cddfSDavid du Colombier } 6117dd7cddfSDavid du Colombier static void 6127dd7cddfSDavid du Colombier dbtuple2cache(Ndbtuple *t) 6137dd7cddfSDavid du Colombier { 6147dd7cddfSDavid du Colombier Ndbtuple *et, *nt; 6157dd7cddfSDavid du Colombier DN *dp; 6167dd7cddfSDavid du Colombier 6174f8f669cSDavid du Colombier for(et = t; et; et = et->entry) 6187dd7cddfSDavid du Colombier if(strcmp(et->attr, "dom") == 0){ 6197dd7cddfSDavid du Colombier dp = dnlookup(et->val, Cin, 1); 6207dd7cddfSDavid du Colombier 6217dd7cddfSDavid du Colombier /* first same line */ 6227dd7cddfSDavid du Colombier for(nt = et->line; nt != et; nt = nt->line){ 6237dd7cddfSDavid du Colombier dbpair2cache(dp, t, nt); 6247dd7cddfSDavid du Colombier nt->ptr = 1; 6257dd7cddfSDavid du Colombier } 6267dd7cddfSDavid du Colombier 6277dd7cddfSDavid du Colombier /* then rest of entry */ 6287dd7cddfSDavid du Colombier for(nt = t; nt; nt = nt->entry){ 6297dd7cddfSDavid du Colombier if(nt->ptr == 0) 6307dd7cddfSDavid du Colombier dbpair2cache(dp, t, nt); 6317dd7cddfSDavid du Colombier nt->ptr = 0; 6327dd7cddfSDavid du Colombier } 6337dd7cddfSDavid du Colombier } 6347dd7cddfSDavid du Colombier } 6357dd7cddfSDavid du Colombier static void 6367dd7cddfSDavid du Colombier dbfile2cache(Ndb *db) 6377dd7cddfSDavid du Colombier { 6387dd7cddfSDavid du Colombier Ndbtuple *t; 6397dd7cddfSDavid du Colombier 64059cc4ca5SDavid du Colombier if(debug) 6414f8f669cSDavid du Colombier dnslog("rereading %s", db->file); 6427dd7cddfSDavid du Colombier Bseek(&db->b, 0, 0); 6437dd7cddfSDavid du Colombier while(t = ndbparse(db)){ 6447dd7cddfSDavid du Colombier dbtuple2cache(t); 6457dd7cddfSDavid du Colombier ndbfree(t); 6467dd7cddfSDavid du Colombier } 6477dd7cddfSDavid du Colombier } 6484f8f669cSDavid du Colombier 6494f8f669cSDavid du Colombier /* called with dblock held */ 6504f8f669cSDavid du Colombier static void 6514f8f669cSDavid du Colombier loaddomsrvs(void) 6524f8f669cSDavid du Colombier { 6534f8f669cSDavid du Colombier Ndbs s; 6544f8f669cSDavid du Colombier 6554f8f669cSDavid du Colombier if (!cfg.inside || !cfg.straddle || !cfg.serve) 6564f8f669cSDavid du Colombier return; 6574f8f669cSDavid du Colombier if (indoms) { 6584f8f669cSDavid du Colombier ndbfree(indoms); 6594f8f669cSDavid du Colombier ndbfree(innmsrvs); 6604f8f669cSDavid du Colombier ndbfree(outnmsrvs); 6614f8f669cSDavid du Colombier indoms = innmsrvs = outnmsrvs = nil; 6624f8f669cSDavid du Colombier } 6634f8f669cSDavid du Colombier if (db == nil) 6644f8f669cSDavid du Colombier opendatabase(); 6654f8f669cSDavid du Colombier free(ndbgetvalue(db, &s, "sys", "inside-dom", "dom", &indoms)); 6664f8f669cSDavid du Colombier free(ndbgetvalue(db, &s, "sys", "inside-ns", "ip", &innmsrvs)); 6674f8f669cSDavid du Colombier free(ndbgetvalue(db, &s, "sys", "outside-ns", "ip", &outnmsrvs)); 6684f8f669cSDavid du Colombier dnslog("[%d] ndb changed: reloaded inside-dom, inside-ns, outside-ns", 6694f8f669cSDavid du Colombier getpid()); 6704f8f669cSDavid du Colombier } 6714f8f669cSDavid du Colombier 6727dd7cddfSDavid du Colombier void 6737dd7cddfSDavid du Colombier db2cache(int doit) 6747dd7cddfSDavid du Colombier { 6754f8f669cSDavid du Colombier ulong youngest, temp; 6767dd7cddfSDavid du Colombier Ndb *ndb; 6779a747e4fSDavid du Colombier Dir *d; 6784f8f669cSDavid du Colombier static ulong lastcheck, lastyoungest; 6797dd7cddfSDavid du Colombier 680dc5a79c1SDavid du Colombier /* no faster than once every 2 minutes */ 6817dd7cddfSDavid du Colombier if(now < lastcheck + 2*Min && !doit) 6827dd7cddfSDavid du Colombier return; 6837dd7cddfSDavid du Colombier 684dc5a79c1SDavid du Colombier refresh_areas(owned); 685dc5a79c1SDavid du Colombier 6867dd7cddfSDavid du Colombier lock(&dblock); 6877dd7cddfSDavid du Colombier 6887dd7cddfSDavid du Colombier if(opendatabase() < 0){ 6897dd7cddfSDavid du Colombier unlock(&dblock); 6907dd7cddfSDavid du Colombier return; 6917dd7cddfSDavid du Colombier } 6927dd7cddfSDavid du Colombier 6937dd7cddfSDavid du Colombier /* 6947dd7cddfSDavid du Colombier * file may be changing as we are reading it, so loop till 6957dd7cddfSDavid du Colombier * mod times are consistent. 6967dd7cddfSDavid du Colombier * 6977dd7cddfSDavid du Colombier * we don't use the times in the ndb records because they may 6987dd7cddfSDavid du Colombier * change outside of refreshing our cached knowledge. 6997dd7cddfSDavid du Colombier */ 7007dd7cddfSDavid du Colombier for(;;){ 7017dd7cddfSDavid du Colombier lastcheck = now; 7027dd7cddfSDavid du Colombier youngest = 0; 7034f8f669cSDavid du Colombier for(ndb = db; ndb; ndb = ndb->next) 7044f8f669cSDavid du Colombier /* dirfstat avoids walking the mount table each time */ 7059a747e4fSDavid du Colombier if((d = dirfstat(Bfildes(&ndb->b))) != nil || 7069a747e4fSDavid du Colombier (d = dirstat(ndb->file)) != nil){ 7079a747e4fSDavid du Colombier temp = d->mtime; /* ulong vs int crap */ 7087dd7cddfSDavid du Colombier if(temp > youngest) 7097dd7cddfSDavid du Colombier youngest = temp; 7109a747e4fSDavid du Colombier free(d); 7117dd7cddfSDavid du Colombier } 712b85a8364SDavid du Colombier if(!doit && youngest == lastyoungest) 713b85a8364SDavid du Colombier break; 7147dd7cddfSDavid du Colombier 7157dd7cddfSDavid du Colombier /* forget our area definition */ 7167dd7cddfSDavid du Colombier freearea(&owned); 7177dd7cddfSDavid du Colombier freearea(&delegated); 7187dd7cddfSDavid du Colombier 7197dd7cddfSDavid du Colombier /* reopen all the files (to get oldest for time stamp) */ 7207dd7cddfSDavid du Colombier for(ndb = db; ndb; ndb = ndb->next) 7217dd7cddfSDavid du Colombier ndbreopen(ndb); 7227dd7cddfSDavid du Colombier 7234f8f669cSDavid du Colombier /* reload straddle-server configuration */ 7244f8f669cSDavid du Colombier loaddomsrvs(); 7254f8f669cSDavid du Colombier 7264f8f669cSDavid du Colombier if(cfg.cachedb){ 7277dd7cddfSDavid du Colombier /* mark all db records as timed out */ 7287dd7cddfSDavid du Colombier dnagedb(); 7297dd7cddfSDavid du Colombier 7307dd7cddfSDavid du Colombier /* read in new entries */ 7317dd7cddfSDavid du Colombier for(ndb = db; ndb; ndb = ndb->next) 7327dd7cddfSDavid du Colombier dbfile2cache(ndb); 7337dd7cddfSDavid du Colombier 7344f8f669cSDavid du Colombier /* mark as authoritative anything in our domain */ 7357dd7cddfSDavid du Colombier dnauthdb(); 7367dd7cddfSDavid du Colombier 7377dd7cddfSDavid du Colombier /* remove old entries */ 7387dd7cddfSDavid du Colombier dnageall(1); 7394f8f669cSDavid du Colombier } else 7407dd7cddfSDavid du Colombier /* read all the soa's to get database defaults */ 7417dd7cddfSDavid du Colombier for(ndb = db; ndb; ndb = ndb->next) 7427dd7cddfSDavid du Colombier dbfile2area(ndb); 7437dd7cddfSDavid du Colombier 7447dd7cddfSDavid du Colombier doit = 0; 7457dd7cddfSDavid du Colombier lastyoungest = youngest; 7463ff48bf5SDavid du Colombier createptrs(); 7477dd7cddfSDavid du Colombier } 7487dd7cddfSDavid du Colombier 7497dd7cddfSDavid du Colombier unlock(&dblock); 7507dd7cddfSDavid du Colombier } 7517dd7cddfSDavid du Colombier 75221abd8f2SDavid du Colombier void 75321abd8f2SDavid du Colombier dnforceage(void) 75421abd8f2SDavid du Colombier { 75521abd8f2SDavid du Colombier lock(&dblock); 75621abd8f2SDavid du Colombier dnageall(1); 75721abd8f2SDavid du Colombier unlock(&dblock); 75821abd8f2SDavid du Colombier } 75921abd8f2SDavid du Colombier 760b322bd99SDavid du Colombier extern uchar ipaddr[IPaddrlen]; /* my ip address */ 7617dd7cddfSDavid du Colombier 7627dd7cddfSDavid du Colombier /* 7637dd7cddfSDavid du Colombier * get all my xxx 76453874d13SDavid du Colombier * caller ndbfrees the result 7657dd7cddfSDavid du Colombier */ 7667dd7cddfSDavid du Colombier Ndbtuple* 7677dd7cddfSDavid du Colombier lookupinfo(char *attr) 7687dd7cddfSDavid du Colombier { 7697dd7cddfSDavid du Colombier char buf[64]; 7707dd7cddfSDavid du Colombier char *a[2]; 77153874d13SDavid du Colombier Ndbtuple *t; 7727dd7cddfSDavid du Colombier 7739a747e4fSDavid du Colombier snprint(buf, sizeof buf, "%I", ipaddr); 7747dd7cddfSDavid du Colombier a[0] = attr; 7757dd7cddfSDavid du Colombier 7767dd7cddfSDavid du Colombier lock(&dblock); 7777dd7cddfSDavid du Colombier if(opendatabase() < 0){ 7787dd7cddfSDavid du Colombier unlock(&dblock); 7797dd7cddfSDavid du Colombier return nil; 7807dd7cddfSDavid du Colombier } 7817dd7cddfSDavid du Colombier t = ndbipinfo(db, "ip", buf, a, 1); 7827dd7cddfSDavid du Colombier unlock(&dblock); 7837dd7cddfSDavid du Colombier return t; 7847dd7cddfSDavid du Colombier } 7857dd7cddfSDavid du Colombier 78659cc4ca5SDavid du Colombier char *localservers = "local#dns#servers"; 78759cc4ca5SDavid du Colombier char *localserverprefix = "local#dns#server"; 78859cc4ca5SDavid du Colombier 7897dd7cddfSDavid du Colombier /* 7907dd7cddfSDavid du Colombier * return non-zero is this is a bad delegation 7917dd7cddfSDavid du Colombier */ 7927dd7cddfSDavid du Colombier int 7937dd7cddfSDavid du Colombier baddelegation(RR *rp, RR *nsrp, uchar *addr) 7947dd7cddfSDavid du Colombier { 7957dd7cddfSDavid du Colombier Ndbtuple *nt; 7967dd7cddfSDavid du Colombier static Ndbtuple *t; 7977dd7cddfSDavid du Colombier 7987dd7cddfSDavid du Colombier if(t == nil) 7997dd7cddfSDavid du Colombier t = lookupinfo("dom"); 8007dd7cddfSDavid du Colombier if(t == nil) 8017dd7cddfSDavid du Colombier return 0; 8027dd7cddfSDavid du Colombier 8037dd7cddfSDavid du Colombier for(; rp; rp = rp->next){ 8047dd7cddfSDavid du Colombier if(rp->type != Tns) 8057dd7cddfSDavid du Colombier continue; 8067dd7cddfSDavid du Colombier 8077dd7cddfSDavid du Colombier /* see if delegation is looping */ 8087dd7cddfSDavid du Colombier if(nsrp) 8097dd7cddfSDavid du Colombier if(rp->owner != nsrp->owner) 81059cc4ca5SDavid du Colombier if(subsume(rp->owner->name, nsrp->owner->name) && 81159cc4ca5SDavid du Colombier strcmp(nsrp->owner->name, localservers) != 0){ 8124f8f669cSDavid du Colombier dnslog("delegation loop %R -> %R from %I", 8134f8f669cSDavid du Colombier nsrp, rp, addr); 8147dd7cddfSDavid du Colombier return 1; 8157dd7cddfSDavid du Colombier } 8167dd7cddfSDavid du Colombier 8177dd7cddfSDavid du Colombier /* see if delegating to us what we don't own */ 8187dd7cddfSDavid du Colombier for(nt = t; nt != nil; nt = nt->entry) 8197dd7cddfSDavid du Colombier if(rp->host && cistrcmp(rp->host->name, nt->val) == 0) 8207dd7cddfSDavid du Colombier break; 8217dd7cddfSDavid du Colombier if(nt != nil && !inmyarea(rp->owner->name)){ 822a41547ffSDavid du Colombier dnslog("bad delegation %R from %I", rp, addr); 8237dd7cddfSDavid du Colombier return 1; 8247dd7cddfSDavid du Colombier } 8257dd7cddfSDavid du Colombier } 8267dd7cddfSDavid du Colombier 8277dd7cddfSDavid du Colombier return 0; 8287dd7cddfSDavid du Colombier } 8297dd7cddfSDavid du Colombier 8304e153993SDavid du Colombier int 831a41547ffSDavid du Colombier myaddr(char *addr) 832a41547ffSDavid du Colombier { 833a41547ffSDavid du Colombier char *name, *line, *sp; 834a41547ffSDavid du Colombier char buf[64]; 835a41547ffSDavid du Colombier Biobuf *bp; 836a41547ffSDavid du Colombier 837a41547ffSDavid du Colombier snprint(buf, sizeof buf, "%I", ipaddr); 838a41547ffSDavid du Colombier if (strcmp(addr, buf) == 0) { 839a41547ffSDavid du Colombier dnslog("rejecting my ip %s as local dns server", addr); 840a41547ffSDavid du Colombier return 1; 841a41547ffSDavid du Colombier } 842a41547ffSDavid du Colombier 843a41547ffSDavid du Colombier name = smprint("%s/ipselftab", mntpt); 844a41547ffSDavid du Colombier bp = Bopen(name, OREAD); 845a41547ffSDavid du Colombier free(name); 846a41547ffSDavid du Colombier if (bp != nil) { 847a41547ffSDavid du Colombier while ((line = Brdline(bp, '\n')) != nil) { 848a41547ffSDavid du Colombier line[Blinelen(bp) - 1] = '\0'; 849a41547ffSDavid du Colombier sp = strchr(line, ' '); 850a41547ffSDavid du Colombier if (sp) { 851a41547ffSDavid du Colombier *sp = '\0'; 852a41547ffSDavid du Colombier if (strcmp(addr, line) == 0) { 853a41547ffSDavid du Colombier dnslog("rejecting my ip %s as local dns server", 854a41547ffSDavid du Colombier addr); 855a41547ffSDavid du Colombier return 1; 856a41547ffSDavid du Colombier } 857a41547ffSDavid du Colombier } 858a41547ffSDavid du Colombier } 859a41547ffSDavid du Colombier Bterm(bp); 860a41547ffSDavid du Colombier } 861a41547ffSDavid du Colombier return 0; 862a41547ffSDavid du Colombier } 863a41547ffSDavid du Colombier 864a41547ffSDavid du Colombier static char *locdns[20]; 865a41547ffSDavid du Colombier 8667dd7cddfSDavid du Colombier static void 8677dd7cddfSDavid du Colombier addlocaldnsserver(DN *dp, int class, char *ipaddr, int i) 8687dd7cddfSDavid du Colombier { 869a41547ffSDavid du Colombier int n; 8707dd7cddfSDavid du Colombier DN *nsdp; 8717dd7cddfSDavid du Colombier RR *rp; 8727dd7cddfSDavid du Colombier char buf[32]; 8734e153993SDavid du Colombier static QLock locdnslck; 8747dd7cddfSDavid du Colombier 875a41547ffSDavid du Colombier /* reject our own ip addresses so we don't query ourselves via udp */ 876a41547ffSDavid du Colombier if (myaddr(ipaddr)) 877a41547ffSDavid du Colombier return; 878a41547ffSDavid du Colombier 8794e153993SDavid du Colombier qlock(&locdnslck); 880a41547ffSDavid du Colombier for (n = 0; n < i && n < nelem(locdns) && locdns[n]; n++) 881a41547ffSDavid du Colombier if (strcmp(locdns[n], ipaddr) == 0) { 882a41547ffSDavid du Colombier dnslog("rejecting duplicate local dns server ip %s", 883a41547ffSDavid du Colombier ipaddr); 8844e153993SDavid du Colombier qunlock(&locdnslck); 885a41547ffSDavid du Colombier return; 886a41547ffSDavid du Colombier } 887a41547ffSDavid du Colombier if (n < nelem(locdns)) 888a41547ffSDavid du Colombier if (locdns[n] == nil || ++n < nelem(locdns)) 889a41547ffSDavid du Colombier locdns[n] = strdup(ipaddr); /* remember first few local ns */ 8904e153993SDavid du Colombier qunlock(&locdnslck); 891a41547ffSDavid du Colombier 8927dd7cddfSDavid du Colombier /* ns record for name server, make up an impossible name */ 8937dd7cddfSDavid du Colombier rp = rralloc(Tns); 8944f8f669cSDavid du Colombier snprint(buf, sizeof buf, "%s%d", localserverprefix, i); 8957dd7cddfSDavid du Colombier nsdp = dnlookup(buf, class, 1); 8967dd7cddfSDavid du Colombier rp->host = nsdp; 897a41547ffSDavid du Colombier rp->owner = dp; /* e.g., local#dns#servers */ 8987dd7cddfSDavid du Colombier rp->local = 1; 8997dd7cddfSDavid du Colombier rp->db = 1; 900a41547ffSDavid du Colombier // rp->ttl = 10*Min; /* seems too short */ 901a41547ffSDavid du Colombier rp->ttl = (1UL<<31)-1; 9026dc4800dSDavid du Colombier rrattach(rp, Authoritative); /* will not attach rrs in my area */ 9037dd7cddfSDavid du Colombier 9047dd7cddfSDavid du Colombier /* A record */ 9057dd7cddfSDavid du Colombier rp = rralloc(Ta); 9067dd7cddfSDavid du Colombier rp->ip = dnlookup(ipaddr, class, 1); 9077dd7cddfSDavid du Colombier rp->owner = nsdp; 9087dd7cddfSDavid du Colombier rp->local = 1; 9097dd7cddfSDavid du Colombier rp->db = 1; 910a41547ffSDavid du Colombier // rp->ttl = 10*Min; /* seems too short */ 911a41547ffSDavid du Colombier rp->ttl = (1UL<<31)-1; 9126dc4800dSDavid du Colombier rrattach(rp, Authoritative); /* will not attach rrs in my area */ 913a41547ffSDavid du Colombier 914a41547ffSDavid du Colombier dnslog("added local dns server %s at %s", buf, ipaddr); 9157dd7cddfSDavid du Colombier } 9167dd7cddfSDavid du Colombier 9177dd7cddfSDavid du Colombier /* 9187dd7cddfSDavid du Colombier * return list of dns server addresses to use when 9197dd7cddfSDavid du Colombier * acting just as a resolver. 9207dd7cddfSDavid du Colombier */ 9217dd7cddfSDavid du Colombier RR* 9227dd7cddfSDavid du Colombier dnsservers(int class) 9237dd7cddfSDavid du Colombier { 9244f8f669cSDavid du Colombier int i, n; 9254f8f669cSDavid du Colombier char *p, *buf; 9264f8f669cSDavid du Colombier char *args[5]; 9277dd7cddfSDavid du Colombier Ndbtuple *t, *nt; 9287dd7cddfSDavid du Colombier RR *nsrp; 9297dd7cddfSDavid du Colombier DN *dp; 9307dd7cddfSDavid du Colombier 93159cc4ca5SDavid du Colombier dp = dnlookup(localservers, class, 1); 9327dd7cddfSDavid du Colombier nsrp = rrlookup(dp, Tns, NOneg); 9337dd7cddfSDavid du Colombier if(nsrp != nil) 9347dd7cddfSDavid du Colombier return nsrp; 9357dd7cddfSDavid du Colombier 936b322bd99SDavid du Colombier p = getenv("DNSSERVER"); /* list of ip addresses */ 9377dd7cddfSDavid du Colombier if(p != nil){ 9389a747e4fSDavid du Colombier buf = estrdup(p); 9397dd7cddfSDavid du Colombier n = tokenize(buf, args, nelem(args)); 9407dd7cddfSDavid du Colombier for(i = 0; i < n; i++) 9417dd7cddfSDavid du Colombier addlocaldnsserver(dp, class, args[i], i); 9427dd7cddfSDavid du Colombier free(buf); 9437dd7cddfSDavid du Colombier } else { 944b322bd99SDavid du Colombier t = lookupinfo("@dns"); /* @dns=ip1 @dns=ip2 ... */ 9457dd7cddfSDavid du Colombier if(t == nil) 9467dd7cddfSDavid du Colombier return nil; 9477dd7cddfSDavid du Colombier i = 0; 9487dd7cddfSDavid du Colombier for(nt = t; nt != nil; nt = nt->entry){ 9497dd7cddfSDavid du Colombier addlocaldnsserver(dp, class, nt->val, i); 9507dd7cddfSDavid du Colombier i++; 9517dd7cddfSDavid du Colombier } 9527dd7cddfSDavid du Colombier ndbfree(t); 9537dd7cddfSDavid du Colombier } 9547dd7cddfSDavid du Colombier 9557dd7cddfSDavid du Colombier return rrlookup(dp, Tns, NOneg); 9567dd7cddfSDavid du Colombier } 9577dd7cddfSDavid du Colombier 9587dd7cddfSDavid du Colombier static void 9597dd7cddfSDavid du Colombier addlocaldnsdomain(DN *dp, int class, char *domain) 9607dd7cddfSDavid du Colombier { 9617dd7cddfSDavid du Colombier RR *rp; 9627dd7cddfSDavid du Colombier 9637dd7cddfSDavid du Colombier /* A record */ 9647dd7cddfSDavid du Colombier rp = rralloc(Tptr); 9657dd7cddfSDavid du Colombier rp->ptr = dnlookup(domain, class, 1); 9667dd7cddfSDavid du Colombier rp->owner = dp; 9677dd7cddfSDavid du Colombier rp->db = 1; 9687dd7cddfSDavid du Colombier rp->ttl = 10*Min; 9696dc4800dSDavid du Colombier rrattach(rp, Authoritative); 9707dd7cddfSDavid du Colombier } 9717dd7cddfSDavid du Colombier 9727dd7cddfSDavid du Colombier /* 9737dd7cddfSDavid du Colombier * return list of domains to use when resolving names without '.'s 9747dd7cddfSDavid du Colombier */ 9757dd7cddfSDavid du Colombier RR* 9767dd7cddfSDavid du Colombier domainlist(int class) 9777dd7cddfSDavid du Colombier { 9787dd7cddfSDavid du Colombier Ndbtuple *t, *nt; 9797dd7cddfSDavid du Colombier RR *rp; 9807dd7cddfSDavid du Colombier DN *dp; 9817dd7cddfSDavid du Colombier 9827dd7cddfSDavid du Colombier dp = dnlookup("local#dns#domains", class, 1); 9837dd7cddfSDavid du Colombier rp = rrlookup(dp, Tptr, NOneg); 9847dd7cddfSDavid du Colombier if(rp != nil) 9857dd7cddfSDavid du Colombier return rp; 9867dd7cddfSDavid du Colombier 9877dd7cddfSDavid du Colombier t = lookupinfo("dnsdomain"); 9887dd7cddfSDavid du Colombier if(t == nil) 9897dd7cddfSDavid du Colombier return nil; 9907dd7cddfSDavid du Colombier for(nt = t; nt != nil; nt = nt->entry) 9917dd7cddfSDavid du Colombier addlocaldnsdomain(dp, class, nt->val); 9927dd7cddfSDavid du Colombier ndbfree(t); 9937dd7cddfSDavid du Colombier 9947dd7cddfSDavid du Colombier return rrlookup(dp, Tptr, NOneg); 9957dd7cddfSDavid du Colombier } 9963ff48bf5SDavid du Colombier 9973ff48bf5SDavid du Colombier char *v4ptrdom = ".in-addr.arpa"; 9987def40e1SDavid du Colombier char *v6ptrdom = ".ip6.arpa"; /* ip6.int deprecated, rfc 3152 */ 9993ff48bf5SDavid du Colombier 10003ff48bf5SDavid du Colombier char *attribs[] = { 10013ff48bf5SDavid du Colombier "ipmask", 10023ff48bf5SDavid du Colombier 0 10033ff48bf5SDavid du Colombier }; 10043ff48bf5SDavid du Colombier 10053ff48bf5SDavid du Colombier /* 100653874d13SDavid du Colombier * create ptrs that are in our v4 areas 10073ff48bf5SDavid du Colombier */ 10083ff48bf5SDavid du Colombier static void 100953874d13SDavid du Colombier createv4ptrs(void) 10103ff48bf5SDavid du Colombier { 10113ff48bf5SDavid du Colombier int len, dlen, n; 101253874d13SDavid du Colombier char *dom; 10134f8f669cSDavid du Colombier char buf[Domlen+1], ipa[48]; 10146b0d5c8bSDavid du Colombier char *f[40]; 10154f8f669cSDavid du Colombier uchar net[IPaddrlen], mask[IPaddrlen]; 10164f8f669cSDavid du Colombier Area *s; 10173ff48bf5SDavid du Colombier Ndbtuple *t, *nt; 10183ff48bf5SDavid du Colombier 10193ff48bf5SDavid du Colombier dlen = strlen(v4ptrdom); 10203ff48bf5SDavid du Colombier for(s = owned; s; s = s->next){ 102153874d13SDavid du Colombier dom = s->soarr->owner->name; 102253874d13SDavid du Colombier len = strlen(dom); 102353874d13SDavid du Colombier if((len <= dlen || cistrcmp(dom+len-dlen, v4ptrdom) != 0) && 102453874d13SDavid du Colombier cistrcmp(dom, v4ptrdom+1) != 0) 10253ff48bf5SDavid du Colombier continue; 10263ff48bf5SDavid du Colombier 10273ff48bf5SDavid du Colombier /* get mask and net value */ 102853874d13SDavid du Colombier strncpy(buf, dom, sizeof buf); 10294f8f669cSDavid du Colombier buf[sizeof buf-1] = 0; 103053874d13SDavid du Colombier /* buf contains something like 178.204.in-addr.arpa (n==4) */ 10313ff48bf5SDavid du Colombier n = getfields(buf, f, nelem(f), 0, "."); 10323ff48bf5SDavid du Colombier memset(mask, 0xff, IPaddrlen); 10333ff48bf5SDavid du Colombier ipmove(net, v4prefix); 10343ff48bf5SDavid du Colombier switch(n){ 10353ff48bf5SDavid du Colombier case 3: /* /8 */ 10363ff48bf5SDavid du Colombier net[IPv4off] = atoi(f[0]); 10373ff48bf5SDavid du Colombier mask[IPv4off+1] = 0; 10383ff48bf5SDavid du Colombier mask[IPv4off+2] = 0; 10393ff48bf5SDavid du Colombier mask[IPv4off+3] = 0; 10403ff48bf5SDavid du Colombier break; 10413ff48bf5SDavid du Colombier case 4: /* /16 */ 10423ff48bf5SDavid du Colombier net[IPv4off] = atoi(f[1]); 10433ff48bf5SDavid du Colombier net[IPv4off+1] = atoi(f[0]); 10443ff48bf5SDavid du Colombier mask[IPv4off+2] = 0; 10453ff48bf5SDavid du Colombier mask[IPv4off+3] = 0; 10463ff48bf5SDavid du Colombier break; 10473ff48bf5SDavid du Colombier case 5: /* /24 */ 10483ff48bf5SDavid du Colombier net[IPv4off] = atoi(f[2]); 10493ff48bf5SDavid du Colombier net[IPv4off+1] = atoi(f[1]); 10503ff48bf5SDavid du Colombier net[IPv4off+2] = atoi(f[0]); 10513ff48bf5SDavid du Colombier mask[IPv4off+3] = 0; 10523ff48bf5SDavid du Colombier break; 10533ff48bf5SDavid du Colombier case 6: /* rfc2317 */ 10543ff48bf5SDavid du Colombier net[IPv4off] = atoi(f[3]); 10553ff48bf5SDavid du Colombier net[IPv4off+1] = atoi(f[2]); 10563ff48bf5SDavid du Colombier net[IPv4off+2] = atoi(f[1]); 10573ff48bf5SDavid du Colombier net[IPv4off+3] = atoi(f[0]); 10583ff48bf5SDavid du Colombier sprint(ipa, "%I", net); 10593ff48bf5SDavid du Colombier t = ndbipinfo(db, "ip", ipa, attribs, 1); 106008fd2d13SDavid du Colombier if(t == nil) /* could be a reverse with no forward */ 106108fd2d13SDavid du Colombier continue; 10623ff48bf5SDavid du Colombier nt = look(t, t, "ipmask"); 10633ff48bf5SDavid du Colombier if(nt == nil){ /* we're confused */ 10643ff48bf5SDavid du Colombier ndbfree(t); 10653ff48bf5SDavid du Colombier continue; 10663ff48bf5SDavid du Colombier } 10673ff48bf5SDavid du Colombier parseipmask(mask, nt->val); 1068018fc28bSDavid du Colombier ndbfree(t); 10693ff48bf5SDavid du Colombier n = 5; 10703ff48bf5SDavid du Colombier break; 10713ff48bf5SDavid du Colombier default: 10723ff48bf5SDavid du Colombier continue; 10733ff48bf5SDavid du Colombier } 10743ff48bf5SDavid du Colombier 10754f8f669cSDavid du Colombier /* 10764f8f669cSDavid du Colombier * go through all domain entries looking for RR's 107753874d13SDavid du Colombier * in this network and create ptrs. 107853874d13SDavid du Colombier * +2 for ".in-addr.arpa". 10794f8f669cSDavid du Colombier */ 1080617c0e1eSDavid du Colombier dnptr(net, mask, dom, Ta, 4+2-n, Ptrttl); 10813ff48bf5SDavid du Colombier } 10823ff48bf5SDavid du Colombier } 10834f8f669cSDavid du Colombier 108453874d13SDavid du Colombier /* convert bytes to nibbles, big-endian */ 108553874d13SDavid du Colombier void 108653874d13SDavid du Colombier bytes2nibbles(uchar *nibbles, uchar *bytes, int nbytes) 108753874d13SDavid du Colombier { 108853874d13SDavid du Colombier while (nbytes-- > 0) { 108953874d13SDavid du Colombier *nibbles++ = *bytes >> Nibwidth; 109053874d13SDavid du Colombier *nibbles++ = *bytes++ & Nibmask; 109153874d13SDavid du Colombier } 109253874d13SDavid du Colombier } 109353874d13SDavid du Colombier 109453874d13SDavid du Colombier void 109553874d13SDavid du Colombier nibbles2bytes(uchar *bytes, uchar *nibbles, int nnibs) 109653874d13SDavid du Colombier { 109753874d13SDavid du Colombier for (; nnibs >= 2; nnibs -= 2) { 109853874d13SDavid du Colombier *bytes++ = nibbles[0] << Nibwidth | (nibbles[1]&Nibmask); 109953874d13SDavid du Colombier nibbles += 2; 110053874d13SDavid du Colombier } 110153874d13SDavid du Colombier if (nnibs > 0) 110253874d13SDavid du Colombier *bytes = nibbles[0] << Nibwidth; 110353874d13SDavid du Colombier } 110453874d13SDavid du Colombier 110553874d13SDavid du Colombier /* 110653874d13SDavid du Colombier * create ptrs that are in our v6 areas. see rfc3596 110753874d13SDavid du Colombier */ 110853874d13SDavid du Colombier static void 110953874d13SDavid du Colombier createv6ptrs(void) 111053874d13SDavid du Colombier { 111153874d13SDavid du Colombier int len, dlen, i, n, pfxnibs; 111253874d13SDavid du Colombier char *dom; 111353874d13SDavid du Colombier char buf[Domlen+1]; 111453874d13SDavid du Colombier char *f[40]; 111553874d13SDavid du Colombier uchar net[IPaddrlen], mask[IPaddrlen]; 111653874d13SDavid du Colombier uchar nibnet[IPaddrlen*2], nibmask[IPaddrlen*2]; 111753874d13SDavid du Colombier Area *s; 111853874d13SDavid du Colombier 111953874d13SDavid du Colombier dlen = strlen(v6ptrdom); 112053874d13SDavid du Colombier for(s = owned; s; s = s->next){ 112153874d13SDavid du Colombier dom = s->soarr->owner->name; 112253874d13SDavid du Colombier len = strlen(dom); 112353874d13SDavid du Colombier if((len <= dlen || cistrcmp(dom+len-dlen, v6ptrdom) != 0) && 112453874d13SDavid du Colombier cistrcmp(dom, v6ptrdom+1) != 0) 112553874d13SDavid du Colombier continue; 112653874d13SDavid du Colombier 112753874d13SDavid du Colombier /* get mask and net value */ 112853874d13SDavid du Colombier strncpy(buf, dom, sizeof buf); 112953874d13SDavid du Colombier buf[sizeof buf-1] = 0; 113053874d13SDavid du Colombier /* buf contains something like 2.0.0.2.ip6.arpa (n==6) */ 113153874d13SDavid du Colombier n = getfields(buf, f, nelem(f), 0, "."); 113253874d13SDavid du Colombier pfxnibs = n - 2; 113353874d13SDavid du Colombier if (pfxnibs < 0 || pfxnibs > V6maxrevdomdepth) 113453874d13SDavid du Colombier continue; 113553874d13SDavid du Colombier 113653874d13SDavid du Colombier memset(net, 0, IPaddrlen); 113753874d13SDavid du Colombier memset(mask, 0xff, IPaddrlen); 113853874d13SDavid du Colombier bytes2nibbles(nibnet, net, IPaddrlen); 113953874d13SDavid du Colombier bytes2nibbles(nibmask, mask, IPaddrlen); 114053874d13SDavid du Colombier 114153874d13SDavid du Colombier /* copy prefix of f, in reverse order, to start of net. */ 114253874d13SDavid du Colombier for (i = 0; i < pfxnibs; i++) 114353874d13SDavid du Colombier nibnet[i] = strtol(f[pfxnibs - 1 - i], nil, 16); 114453874d13SDavid du Colombier /* zero nibbles of mask after prefix in net */ 114553874d13SDavid du Colombier memset(nibmask + pfxnibs, 0, V6maxrevdomdepth - pfxnibs); 114653874d13SDavid du Colombier 114753874d13SDavid du Colombier nibbles2bytes(net, nibnet, 2*IPaddrlen); 114853874d13SDavid du Colombier nibbles2bytes(mask, nibmask, 2*IPaddrlen); 114953874d13SDavid du Colombier 115053874d13SDavid du Colombier /* 115153874d13SDavid du Colombier * go through all domain entries looking for RR's 115253874d13SDavid du Colombier * in this network and create ptrs. 115353874d13SDavid du Colombier * +2 for .ip6.arpa. 115453874d13SDavid du Colombier */ 1155617c0e1eSDavid du Colombier dnptr(net, mask, dom, Taaaa, V6maxrevdomdepth - pfxnibs, Ptrttl); 115653874d13SDavid du Colombier } 115753874d13SDavid du Colombier } 115853874d13SDavid du Colombier 115953874d13SDavid du Colombier /* 116053874d13SDavid du Colombier * create ptrs that are in our areas 116153874d13SDavid du Colombier */ 116253874d13SDavid du Colombier static void 116353874d13SDavid du Colombier createptrs(void) 116453874d13SDavid du Colombier { 116553874d13SDavid du Colombier createv4ptrs(); 116653874d13SDavid du Colombier createv6ptrs(); 116753874d13SDavid du Colombier } 116853874d13SDavid du Colombier 11694f8f669cSDavid du Colombier /* 11704f8f669cSDavid du Colombier * is this domain (or DOMAIN or Domain or dOMAIN) 11714f8f669cSDavid du Colombier * internal to our organisation (behind our firewall)? 11724f8f669cSDavid du Colombier * only inside straddling servers care, everybody else gets told `yes', 11734f8f669cSDavid du Colombier * so they'll use mntpt for their queries. 11744f8f669cSDavid du Colombier */ 11754f8f669cSDavid du Colombier int 11764f8f669cSDavid du Colombier insideaddr(char *dom) 11774f8f669cSDavid du Colombier { 11784f8f669cSDavid du Colombier int domlen, vallen, rv; 11794f8f669cSDavid du Colombier Ndbtuple *t; 11804f8f669cSDavid du Colombier 11814f8f669cSDavid du Colombier if (!cfg.inside || !cfg.straddle || !cfg.serve) 11824f8f669cSDavid du Colombier return 1; 11834f8f669cSDavid du Colombier 11844f8f669cSDavid du Colombier lock(&dblock); 11854f8f669cSDavid du Colombier if (indoms == nil) 11864f8f669cSDavid du Colombier loaddomsrvs(); 11874f8f669cSDavid du Colombier if (indoms == nil) { 11884f8f669cSDavid du Colombier unlock(&dblock); 11894f8f669cSDavid du Colombier return 1; /* no "inside" sys, try inside nameservers */ 11904f8f669cSDavid du Colombier } 11914f8f669cSDavid du Colombier 11924f8f669cSDavid du Colombier rv = 0; 11934f8f669cSDavid du Colombier domlen = strlen(dom); 11944f8f669cSDavid du Colombier for (t = indoms; t != nil; t = t->entry) { 11954f8f669cSDavid du Colombier if (strcmp(t->attr, "dom") != 0) 11964f8f669cSDavid du Colombier continue; 11974f8f669cSDavid du Colombier vallen = strlen(t->val); 11984f8f669cSDavid du Colombier if (cistrcmp(dom, t->val) == 0 || 11994f8f669cSDavid du Colombier domlen > vallen && 12004f8f669cSDavid du Colombier cistrcmp(dom + domlen - vallen, t->val) == 0 && 12014f8f669cSDavid du Colombier dom[domlen - vallen - 1] == '.') { 12024f8f669cSDavid du Colombier rv = 1; 12034f8f669cSDavid du Colombier break; 12044f8f669cSDavid du Colombier } 12054f8f669cSDavid du Colombier } 12064f8f669cSDavid du Colombier unlock(&dblock); 12074f8f669cSDavid du Colombier return rv; 12084f8f669cSDavid du Colombier } 12094f8f669cSDavid du Colombier 12104f8f669cSDavid du Colombier int 12114f8f669cSDavid du Colombier insidens(uchar *ip) 12124f8f669cSDavid du Colombier { 12134f8f669cSDavid du Colombier uchar ipa[IPaddrlen]; 12144f8f669cSDavid du Colombier Ndbtuple *t; 12154f8f669cSDavid du Colombier 12164f8f669cSDavid du Colombier for (t = innmsrvs; t != nil; t = t->entry) 12174f8f669cSDavid du Colombier if (strcmp(t->attr, "ip") == 0) { 12184f8f669cSDavid du Colombier parseip(ipa, t->val); 12194f8f669cSDavid du Colombier if (memcmp(ipa, ip, sizeof ipa) == 0) 12204f8f669cSDavid du Colombier return 1; 12214f8f669cSDavid du Colombier } 12224f8f669cSDavid du Colombier return 0; 12234f8f669cSDavid du Colombier } 12244f8f669cSDavid du Colombier 12254f8f669cSDavid du Colombier uchar * 12264f8f669cSDavid du Colombier outsidens(int n) 12274f8f669cSDavid du Colombier { 12284f8f669cSDavid du Colombier int i; 12294f8f669cSDavid du Colombier Ndbtuple *t; 12304f8f669cSDavid du Colombier static uchar ipa[IPaddrlen]; 12314f8f669cSDavid du Colombier 12324f8f669cSDavid du Colombier i = 0; 12334f8f669cSDavid du Colombier for (t = outnmsrvs; t != nil; t = t->entry) 12344f8f669cSDavid du Colombier if (strcmp(t->attr, "ip") == 0 && i++ == n) { 12354f8f669cSDavid du Colombier parseip(ipa, t->val); 12364f8f669cSDavid du Colombier return ipa; 12374f8f669cSDavid du Colombier } 12384f8f669cSDavid du Colombier return nil; 12394f8f669cSDavid du Colombier } 1240