123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948 |
- #include <u.h>
- #include <libc.h>
- #include <bio.h>
- #include <ndb.h>
- #include <ip.h>
- #include "dns.h"
- static Ndb *db;
- static RR* dblookup1(char*, int, int, int);
- static RR* addrrr(Ndbtuple*, Ndbtuple*);
- static RR* nsrr(Ndbtuple*, Ndbtuple*);
- static RR* cnamerr(Ndbtuple*, Ndbtuple*);
- static RR* mxrr(Ndbtuple*, Ndbtuple*);
- static RR* soarr(Ndbtuple*, Ndbtuple*);
- static RR* ptrrr(Ndbtuple*, Ndbtuple*);
- static Ndbtuple* look(Ndbtuple*, Ndbtuple*, char*);
- static RR* doaxfr(Ndb*, char*);
- static RR* nullrr(Ndbtuple *entry, Ndbtuple *pair);
- static RR* txtrr(Ndbtuple *entry, Ndbtuple *pair);
- static Lock dblock;
- static void createptrs(void);
- static int implemented[Tall] =
- {
- [Ta] 1,
- [Tns] 1,
- [Tsoa] 1,
- [Tmx] 1,
- [Tptr] 1,
- [Tcname] 1,
- [Tnull] 1,
- [Ttxt] 1,
- };
- static void
- nstrcpy(char *to, char *from, int len)
- {
- strncpy(to, from, len);
- to[len-1] = 0;
- }
- int
- opendatabase(void)
- {
- char buf[256];
- Ndb *xdb;
- if(db == nil){
- snprint(buf, sizeof(buf), "%s/ndb", mntpt);
- xdb = ndbopen(dbfile);
- if(xdb != nil)
- xdb->nohash = 1;
- db = ndbcat(ndbopen(buf), xdb);
- }
- if(db == nil)
- return -1;
- else
- return 0;
- }
- /*
- * lookup an RR in the network database, look for matches
- * against both the domain name and the wildcarded domain name.
- *
- * the lock makes sure only one process can be accessing the data
- * base at a time. This is important since there's a lot of
- * shared state there.
- *
- * e.g. for x.research.bell-labs.com, first look for a match against
- * the x.research.bell-labs.com. If nothing matches, try *.research.bell-labs.com.
- */
- RR*
- dblookup(char *name, int class, int type, int auth, int ttl)
- {
- RR *rp, *tp;
- char buf[256];
- char *wild, *cp;
- DN *dp, *ndp;
- int err;
- static int parallel;
- static int parfd[2];
- static char token[1];
- /* so far only internet lookups are implemented */
- if(class != Cin)
- return 0;
- err = Rname;
- if(type == Tall){
- rp = 0;
- for (type = Ta; type < Tall; type++)
- if(implemented[type])
- rrcat(&rp, dblookup(name, class, type, auth, ttl));
- return rp;
- }
- lock(&dblock);
- dp = dnlookup(name, class, 1);
- if(opendatabase() < 0)
- goto out;
- if(dp->rr)
- err = 0;
- /* first try the given name */
- rp = 0;
- if(cachedb)
- rp = rrlookup(dp, type, NOneg);
- else
- rp = dblookup1(name, type, auth, ttl);
- if(rp)
- goto out;
- /* try lower case version */
- for(cp = name; *cp; cp++)
- *cp = tolower(*cp);
- if(cachedb)
- rp = rrlookup(dp, type, NOneg);
- else
- rp = dblookup1(name, type, auth, ttl);
- if(rp)
- goto out;
- /* walk the domain name trying the wildcard '*' at each position */
- for(wild = strchr(name, '.'); wild; wild = strchr(wild+1, '.')){
- snprint(buf, sizeof(buf), "*%s", wild);
- ndp = dnlookup(buf, class, 1);
- if(ndp->rr)
- err = 0;
- if(cachedb)
- rp = rrlookup(ndp, type, NOneg);
- else
- rp = dblookup1(buf, type, auth, ttl);
- if(rp)
- break;
- }
- out:
- /* add owner to uncached records */
- if(rp){
- for(tp = rp; tp; tp = tp->next)
- tp->owner = dp;
- } else {
- /* don't call it non-existent if it's not ours */
- if(err == Rname && !inmyarea(name))
- err = Rserver;
- dp->nonexistent = err;
- }
- unlock(&dblock);
- return rp;
- }
- /*
- * lookup an RR in the network database
- */
- static RR*
- dblookup1(char *name, int type, int auth, int ttl)
- {
- Ndbtuple *t, *nt;
- RR *rp, *list, **l;
- Ndbs s;
- char dname[Domlen];
- char *attr;
- DN *dp;
- RR *(*f)(Ndbtuple*, Ndbtuple*);
- int found, x;
- dp = 0;
- switch(type){
- case Tptr:
- attr = "ptr";
- f = ptrrr;
- break;
- case Ta:
- attr = "ip";
- f = addrrr;
- break;
- case Tnull:
- attr = "nullrr";
- f = nullrr;
- break;
- case Tns:
- attr = "ns";
- f = nsrr;
- break;
- case Tsoa:
- attr = "soa";
- f = soarr;
- break;
- case Tmx:
- attr = "mx";
- f = mxrr;
- break;
- case Tcname:
- attr = "cname";
- f = cnamerr;
- break;
- case Taxfr:
- case Tixfr:
- return doaxfr(db, name);
- default:
- return nil;
- }
- /*
- * find a matching entry in the database
- */
- free(ndbgetvalue(db, &s, "dom", name, attr, &t));
- /*
- * hack for local names
- */
- if(t == 0 && strchr(name, '.') == 0)
- free(ndbgetvalue(db, &s, "sys", name, attr, &t));
- if(t == 0)
- return nil;
- /* search whole entry for default domain name */
- strncpy(dname, name, sizeof dname);
- for(nt = t; nt; nt = nt->entry)
- if(strcmp(nt->attr, "dom") == 0){
- nstrcpy(dname, nt->val, sizeof dname);
- break;
- }
- /* ttl is maximum of soa minttl and entry's ttl ala rfc883 */
- nt = look(t, s.t, "ttl");
- if(nt){
- x = atoi(nt->val);
- if(x > ttl)
- ttl = x;
- }
- /* default ttl is one day */
- if(ttl < 0)
- ttl = DEFTTL;
- /*
- * The database has 2 levels of precedence; line and entry.
- * Pairs on the same line bind tighter than pairs in the
- * same entry, so we search the line first.
- */
- found = 0;
- list = 0;
- l = &list;
- for(nt = s.t;; ){
- if(found == 0 && strcmp(nt->attr, "dom") == 0){
- nstrcpy(dname, nt->val, sizeof dname);
- found = 1;
- }
- if(cistrcmp(attr, nt->attr) == 0){
- rp = (*f)(t, nt);
- rp->auth = auth;
- rp->db = 1;
- if(ttl)
- rp->ttl = ttl;
- if(dp == 0)
- dp = dnlookup(dname, Cin, 1);
- rp->owner = dp;
- *l = rp;
- l = &rp->next;
- nt->ptr = 1;
- }
- nt = nt->line;
- if(nt == s.t)
- break;
- }
- /* search whole entry */
- for(nt = t; nt; nt = nt->entry)
- if(nt->ptr == 0 && cistrcmp(attr, nt->attr) == 0){
- rp = (*f)(t, nt);
- rp->db = 1;
- if(ttl)
- rp->ttl = ttl;
- rp->auth = auth;
- if(dp == 0)
- dp = dnlookup(dname, Cin, 1);
- rp->owner = dp;
- *l = rp;
- l = &rp->next;
- }
- ndbfree(t);
- return list;
- }
- /*
- * make various types of resource records from a database entry
- */
- static RR*
- addrrr(Ndbtuple *entry, Ndbtuple *pair)
- {
- RR *rp;
- uchar addr[IPaddrlen];
- USED(entry);
- parseip(addr, pair->val);
- if(isv4(addr))
- rp = rralloc(Ta);
- else
- rp = rralloc(Taaaa);
- rp->ip = dnlookup(pair->val, Cin, 1);
- return rp;
- }
- static RR*
- nullrr(Ndbtuple *entry, Ndbtuple *pair)
- {
- RR *rp;
- USED(entry);
- rp = rralloc(Tnull);
- rp->null->data = (uchar*)estrdup(pair->val);
- rp->null->dlen = strlen((char*)rp->null->data);
- return rp;
- }
- /*
- * txt rr strings are at most 255 bytes long. one
- * can represent longer strings by multiple concatenated
- * <= 255 byte ones.
- */
- static RR*
- txtrr(Ndbtuple *entry, Ndbtuple *pair)
- {
- RR *rp;
- Txt *t, **l;
- int i, len, sofar;
- USED(entry);
- rp = rralloc(Ttxt);
- l = &rp->txt;
- rp->txt = nil;
- len = strlen(pair->val);
- sofar = 0;
- while(len > sofar){
- t = emalloc(sizeof(*t));
- t->next = nil;
- i = len-sofar;
- if(i > 255)
- i = 255;
- t->p = emalloc(i+1);
- memmove(t->p, pair->val+sofar, i);
- t->p[i] = 0;
- sofar += i;
- *l = t;
- l = &t->next;
- }
- return rp;
- }
- static RR*
- cnamerr(Ndbtuple *entry, Ndbtuple *pair)
- {
- RR *rp;
- USED(entry);
- rp = rralloc(Tcname);
- rp->host = dnlookup(pair->val, Cin, 1);
- return rp;
- }
- static RR*
- mxrr(Ndbtuple *entry, Ndbtuple *pair)
- {
- RR * rp;
- rp = rralloc(Tmx);
- rp->host = dnlookup(pair->val, Cin, 1);
- pair = look(entry, pair, "pref");
- if(pair)
- rp->pref = atoi(pair->val);
- else
- rp->pref = 1;
- return rp;
- }
- static RR*
- nsrr(Ndbtuple *entry, Ndbtuple *pair)
- {
- RR *rp;
- Ndbtuple *t;
- rp = rralloc(Tns);
- rp->host = dnlookup(pair->val, Cin, 1);
- t = look(entry, pair, "soa");
- if(t && t->val[0] == 0)
- rp->local = 1;
- return rp;
- }
- static RR*
- ptrrr(Ndbtuple *entry, Ndbtuple *pair)
- {
- RR *rp;
- USED(entry);
- rp = rralloc(Tns);
- rp->ptr = dnlookup(pair->val, Cin, 1);
- return rp;
- }
- static RR*
- soarr(Ndbtuple *entry, Ndbtuple *pair)
- {
- RR *rp;
- Ndbtuple *ns, *mb, *t;
- char mailbox[Domlen];
- Ndb *ndb;
- char *p;
- rp = rralloc(Tsoa);
- rp->soa->serial = 1;
- for(ndb = db; ndb; ndb = ndb->next)
- if(ndb->mtime > rp->soa->serial)
- rp->soa->serial = ndb->mtime;
- rp->soa->refresh = Day;
- rp->soa->retry = Hour;
- rp->soa->expire = Day;
- rp->soa->minttl = Day;
- t = look(entry, pair, "retry");
- if(t)
- rp->soa->retry = atoi(t->val);
- t = look(entry, pair, "expire");
- if(t)
- rp->soa->expire = atoi(t->val);
- t = look(entry, pair, "ttl");
- if(t)
- rp->soa->minttl = atoi(t->val);
- t = look(entry, pair, "refresh");
- if(t)
- rp->soa->refresh = atoi(t->val);
- t = look(entry, pair, "serial");
- if(t)
- rp->soa->serial = strtoul(t->val, 0, 10);
- ns = look(entry, pair, "ns");
- if(ns == 0)
- ns = look(entry, pair, "dom");
- rp->host = dnlookup(ns->val, Cin, 1);
- /* accept all of:
- * mbox=person
- * mbox=person@machine.dom
- * mbox=person.machine.dom
- */
- mb = look(entry, pair, "mbox");
- if(mb == nil)
- mb = look(entry, pair, "mb");
- if(mb){
- if(strchr(mb->val, '.')) {
- p = strchr(mb->val, '@');
- if(p != nil)
- *p = '.';
- rp->rmb = dnlookup(mb->val, Cin, 1);
- } else {
- snprint(mailbox, sizeof(mailbox), "%s.%s",
- mb->val, ns->val);
- rp->rmb = dnlookup(mailbox, Cin, 1);
- }
- } else {
- snprint(mailbox, sizeof(mailbox), "postmaster.%s",
- ns->val);
- rp->rmb = dnlookup(mailbox, Cin, 1);
- }
- /* hang dns slaves off of the soa. this is
- * for managing the area.
- */
- for(t = entry; t != nil; t = t->entry)
- if(strcmp(t->attr, "dnsslave") == 0)
- addserver(&rp->soa->slaves, t->val);
-
- return rp;
- }
- /*
- * Look for a pair with the given attribute. look first on the same line,
- * then in the whole entry.
- */
- static Ndbtuple*
- look(Ndbtuple *entry, Ndbtuple *line, char *attr)
- {
- Ndbtuple *nt;
- /* first look on same line (closer binding) */
- for(nt = line;;){
- if(cistrcmp(attr, nt->attr) == 0)
- return nt;
- nt = nt->line;
- if(nt == line)
- break;
- }
- /* search whole tuple */
- for(nt = entry; nt; nt = nt->entry)
- if(cistrcmp(attr, nt->attr) == 0)
- return nt;
- return 0;
- }
- static RR**
- linkrr(RR *rp, DN *dp, RR **l)
- {
- rp->owner = dp;
- rp->auth = 1;
- rp->db = 1;
- *l = rp;
- return &rp->next;
- }
- /* these are answered specially by the tcp version */
- static RR*
- doaxfr(Ndb *db, char *name)
- {
- USED(db, name);
- return 0;
- }
- /*
- * read the all the soa's from the database to determine area's.
- * this is only used when we're not caching the database.
- */
- static void
- dbfile2area(Ndb *db)
- {
- Ndbtuple *t;
- if(debug)
- syslog(0, logfile, "rereading %s", db->file);
- Bseek(&db->b, 0, 0);
- while(t = ndbparse(db)){
- ndbfree(t);
- }
- }
- /*
- * read the database into the cache
- */
- static void
- dbpair2cache(DN *dp, Ndbtuple *entry, Ndbtuple *pair)
- {
- RR *rp;
- Ndbtuple *t;
- static ulong ord;
- rp = 0;
- if(cistrcmp(pair->attr, "ip") == 0){
- dp->ordinal = ord++;
- rp = addrrr(entry, pair);
- } else if(cistrcmp(pair->attr, "ns") == 0){
- rp = nsrr(entry, pair);
- } else if(cistrcmp(pair->attr, "soa") == 0){
- rp = soarr(entry, pair);
- addarea(dp, rp, pair);
- } else if(cistrcmp(pair->attr, "mx") == 0){
- rp = mxrr(entry, pair);
- } else if(cistrcmp(pair->attr, "cname") == 0){
- rp = cnamerr(entry, pair);
- } else if(cistrcmp(pair->attr, "nullrr") == 0){
- rp = nullrr(entry, pair);
- } else if(cistrcmp(pair->attr, "txtrr") == 0){
- rp = txtrr(entry, pair);
- }
- if(rp == 0)
- return;
- rp->owner = dp;
- rp->db = 1;
- t = look(entry, pair, "ttl");
- if(t)
- rp->ttl = atoi(t->val);
- rrattach(rp, 0);
- }
- static void
- dbtuple2cache(Ndbtuple *t)
- {
- Ndbtuple *et, *nt;
- DN *dp;
- for(et = t; et; et = et->entry){
- if(strcmp(et->attr, "dom") == 0){
- dp = dnlookup(et->val, Cin, 1);
- /* first same line */
- for(nt = et->line; nt != et; nt = nt->line){
- dbpair2cache(dp, t, nt);
- nt->ptr = 1;
- }
- /* then rest of entry */
- for(nt = t; nt; nt = nt->entry){
- if(nt->ptr == 0)
- dbpair2cache(dp, t, nt);
- nt->ptr = 0;
- }
- }
- }
- }
- static void
- dbfile2cache(Ndb *db)
- {
- Ndbtuple *t;
- if(debug)
- syslog(0, logfile, "rereading %s", db->file);
- Bseek(&db->b, 0, 0);
- while(t = ndbparse(db)){
- dbtuple2cache(t);
- ndbfree(t);
- }
- }
- void
- db2cache(int doit)
- {
- Ndb *ndb;
- Dir *d;
- ulong youngest, temp;
- static ulong lastcheck;
- static ulong lastyoungest;
- /* no faster than once every 2 minutes */
- if(now < lastcheck + 2*Min && !doit)
- return;
- refresh_areas(owned);
- lock(&dblock);
- if(opendatabase() < 0){
- unlock(&dblock);
- return;
- }
- /*
- * file may be changing as we are reading it, so loop till
- * mod times are consistent.
- *
- * we don't use the times in the ndb records because they may
- * change outside of refreshing our cached knowledge.
- */
- for(;;){
- lastcheck = now;
- youngest = 0;
- for(ndb = db; ndb; ndb = ndb->next){
- /* the dirfstat avoids walking the mount table each time */
- if((d = dirfstat(Bfildes(&ndb->b))) != nil ||
- (d = dirstat(ndb->file)) != nil){
- temp = d->mtime; /* ulong vs int crap */
- if(temp > youngest)
- youngest = temp;
- free(d);
- }
- }
- if(!doit && youngest == lastyoungest)
- break;
-
- /* forget our area definition */
- freearea(&owned);
- freearea(&delegated);
-
- /* reopen all the files (to get oldest for time stamp) */
- for(ndb = db; ndb; ndb = ndb->next)
- ndbreopen(ndb);
- if(cachedb){
- /* mark all db records as timed out */
- dnagedb();
-
- /* read in new entries */
- for(ndb = db; ndb; ndb = ndb->next)
- dbfile2cache(ndb);
-
- /* mark as authentic anything in our domain */
- dnauthdb();
-
- /* remove old entries */
- dnageall(1);
- } else {
- /* read all the soa's to get database defaults */
- for(ndb = db; ndb; ndb = ndb->next)
- dbfile2area(ndb);
- }
- doit = 0;
- lastyoungest = youngest;
- createptrs();
- }
- unlock(&dblock);
- }
- extern uchar ipaddr[IPaddrlen];
- /*
- * get all my xxx
- */
- Ndbtuple*
- lookupinfo(char *attr)
- {
- char buf[64];
- char *a[2];
- static Ndbtuple *t;
- snprint(buf, sizeof buf, "%I", ipaddr);
- a[0] = attr;
-
- lock(&dblock);
- if(opendatabase() < 0){
- unlock(&dblock);
- return nil;
- }
- t = ndbipinfo(db, "ip", buf, a, 1);
- unlock(&dblock);
- return t;
- }
- char *localservers = "local#dns#servers";
- char *localserverprefix = "local#dns#server";
- /*
- * return non-zero is this is a bad delegation
- */
- int
- baddelegation(RR *rp, RR *nsrp, uchar *addr)
- {
- Ndbtuple *nt;
- static Ndbtuple *t;
- if(t == nil)
- t = lookupinfo("dom");
- if(t == nil)
- return 0;
- for(; rp; rp = rp->next){
- if(rp->type != Tns)
- continue;
- /* see if delegation is looping */
- if(nsrp)
- if(rp->owner != nsrp->owner)
- if(subsume(rp->owner->name, nsrp->owner->name) &&
- strcmp(nsrp->owner->name, localservers) != 0){
- syslog(0, logfile, "delegation loop %R -> %R from %I", nsrp, rp, addr);
- return 1;
- }
- /* see if delegating to us what we don't own */
- for(nt = t; nt != nil; nt = nt->entry)
- if(rp->host && cistrcmp(rp->host->name, nt->val) == 0)
- break;
- if(nt != nil && !inmyarea(rp->owner->name)){
- syslog(0, logfile, "bad delegation %R from %I", rp, addr);
- return 1;
- }
- }
- return 0;
- }
- static void
- addlocaldnsserver(DN *dp, int class, char *ipaddr, int i)
- {
- DN *nsdp;
- RR *rp;
- char buf[32];
- /* ns record for name server, make up an impossible name */
- rp = rralloc(Tns);
- snprint(buf, sizeof(buf), "%s%d", localserverprefix, i);
- nsdp = dnlookup(buf, class, 1);
- rp->host = nsdp;
- rp->owner = dp;
- rp->local = 1;
- rp->db = 1;
- rp->ttl = 10*Min;
- rrattach(rp, 1);
- /* A record */
- rp = rralloc(Ta);
- rp->ip = dnlookup(ipaddr, class, 1);
- rp->owner = nsdp;
- rp->local = 1;
- rp->db = 1;
- rp->ttl = 10*Min;
- rrattach(rp, 1);
- }
- /*
- * return list of dns server addresses to use when
- * acting just as a resolver.
- */
- RR*
- dnsservers(int class)
- {
- Ndbtuple *t, *nt;
- RR *nsrp;
- DN *dp;
- char *p;
- int i, n;
- char *buf, *args[5];
- dp = dnlookup(localservers, class, 1);
- nsrp = rrlookup(dp, Tns, NOneg);
- if(nsrp != nil)
- return nsrp;
- p = getenv("DNSSERVER");
- if(p != nil){
- buf = estrdup(p);
- n = tokenize(buf, args, nelem(args));
- for(i = 0; i < n; i++)
- addlocaldnsserver(dp, class, args[i], i);
- free(buf);
- } else {
- t = lookupinfo("@dns");
- if(t == nil)
- return nil;
- i = 0;
- for(nt = t; nt != nil; nt = nt->entry){
- addlocaldnsserver(dp, class, nt->val, i);
- i++;
- }
- ndbfree(t);
- }
- return rrlookup(dp, Tns, NOneg);
- }
- static void
- addlocaldnsdomain(DN *dp, int class, char *domain)
- {
- RR *rp;
- /* A record */
- rp = rralloc(Tptr);
- rp->ptr = dnlookup(domain, class, 1);
- rp->owner = dp;
- rp->db = 1;
- rp->ttl = 10*Min;
- rrattach(rp, 1);
- }
- /*
- * return list of domains to use when resolving names without '.'s
- */
- RR*
- domainlist(int class)
- {
- Ndbtuple *t, *nt;
- RR *rp;
- DN *dp;
- dp = dnlookup("local#dns#domains", class, 1);
- rp = rrlookup(dp, Tptr, NOneg);
- if(rp != nil)
- return rp;
- t = lookupinfo("dnsdomain");
- if(t == nil)
- return nil;
- for(nt = t; nt != nil; nt = nt->entry)
- addlocaldnsdomain(dp, class, nt->val);
- ndbfree(t);
- return rrlookup(dp, Tptr, NOneg);
- }
- char *v4ptrdom = ".in-addr.arpa";
- char *v6ptrdom = ".ip6.arpa"; /* ip6.int deprecated, rfc 3152 */
- char *attribs[] = {
- "ipmask",
- 0
- };
- /*
- * create ptrs that are in our areas
- */
- static void
- createptrs(void)
- {
- int len, dlen, n;
- Area *s;
- char *f[40];
- char buf[Domlen+1];
- uchar net[IPaddrlen];
- uchar mask[IPaddrlen];
- char ipa[48];
- Ndbtuple *t, *nt;
- dlen = strlen(v4ptrdom);
- for(s = owned; s; s = s->next){
- len = strlen(s->soarr->owner->name);
- if(len <= dlen)
- continue;
- if(cistrcmp(s->soarr->owner->name+len-dlen, v4ptrdom) != 0)
- continue;
- /* get mask and net value */
- strncpy(buf, s->soarr->owner->name, sizeof(buf));
- buf[sizeof(buf)-1] = 0;
- n = getfields(buf, f, nelem(f), 0, ".");
- memset(mask, 0xff, IPaddrlen);
- ipmove(net, v4prefix);
- switch(n){
- case 3: /* /8 */
- net[IPv4off] = atoi(f[0]);
- mask[IPv4off+1] = 0;
- mask[IPv4off+2] = 0;
- mask[IPv4off+3] = 0;
- break;
- case 4: /* /16 */
- net[IPv4off] = atoi(f[1]);
- net[IPv4off+1] = atoi(f[0]);
- mask[IPv4off+2] = 0;
- mask[IPv4off+3] = 0;
- break;
- case 5: /* /24 */
- net[IPv4off] = atoi(f[2]);
- net[IPv4off+1] = atoi(f[1]);
- net[IPv4off+2] = atoi(f[0]);
- mask[IPv4off+3] = 0;
- break;
- case 6: /* rfc2317 */
- net[IPv4off] = atoi(f[3]);
- net[IPv4off+1] = atoi(f[2]);
- net[IPv4off+2] = atoi(f[1]);
- net[IPv4off+3] = atoi(f[0]);
- sprint(ipa, "%I", net);
- t = ndbipinfo(db, "ip", ipa, attribs, 1);
- if(t == nil) /* could be a reverse with no forward */
- continue;
- nt = look(t, t, "ipmask");
- if(nt == nil){ /* we're confused */
- ndbfree(t);
- continue;
- }
- parseipmask(mask, nt->val);
- n = 5;
- break;
- default:
- continue;
- }
- /* go through all domain entries looking for RR's in this network and create ptrs */
- dnptr(net, mask, s->soarr->owner->name, 6-n, 0);
- }
- }
|