123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529 |
- /*
- * This file is part of the UCB release of Plan 9. It is subject to the license
- * terms in the LICENSE file found in the top-level directory of this
- * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No
- * part of the UCB release of Plan 9, including this file, may be copied,
- * modified, propagated, or distributed except according to the terms contained
- * in the LICENSE file.
- */
- #include <u.h>
- #include <libc.h>
- #include <ip.h>
- #include "dat.h"
- #include "protos.h"
- #include "../../ndb/dns.h"
- /* names of RR types - /sys/src/cmd/ndb/dn.c:/rrtname */
- char *rrtname[] =
- {
- [Ta] "ip",
- [Tns] "ns",
- [Tmd] "md",
- [Tmf] "mf",
- [Tcname] "cname",
- [Tsoa] "soa",
- [Tmb] "mb",
- [Tmg] "mg",
- [Tmr] "mr",
- [Tnull] "null",
- [Twks] "wks",
- [Tptr] "ptr",
- [Thinfo] "hinfo",
- [Tminfo] "minfo",
- [Tmx] "mx",
- [Ttxt] "txt",
- [Trp] "rp",
- [Tafsdb] "afsdb",
- [Tx25] "x.25",
- [Tisdn] "isdn",
- [Trt] "rt",
- [Tnsap] "nsap",
- [Tnsapptr] "nsap-ptr",
- [Tsig] "sig",
- [Tkey] "key",
- [Tpx] "px",
- [Tgpos] "gpos",
- [Taaaa] "ipv6",
- [Tloc] "loc",
- [Tnxt] "nxt",
- [Teid] "eid",
- [Tnimloc] "nimrod",
- [Tsrv] "srv",
- [Tatma] "atma",
- [Tnaptr] "naptr",
- [Tkx] "kx",
- [Tcert] "cert",
- [Ta6] "a6",
- [Tdname] "dname",
- [Tsink] "sink",
- [Topt] "opt",
- [Tapl] "apl",
- [Tds] "ds",
- [Tsshfp] "sshfp",
- [Tipseckey] "ipseckey",
- [Trrsig] "rrsig",
- [Tnsec] "nsec",
- [Tdnskey] "dnskey",
- [Tspf] "spf",
- [Tuinfo] "uinfo",
- [Tuid] "uid",
- [Tgid] "gid",
- [Tunspec] "unspec",
- [Ttkey] "tkey",
- [Ttsig] "tsig",
- [Tixfr] "ixfr",
- [Taxfr] "axfr",
- [Tmailb] "mailb",
- [Tmaila] "maila",
- [Tall] "all",
- 0,
- };
- static char*
- rrtypestr(int t)
- {
- char buf[20];
- if(t >= 0 && t < nelem(rrtname) && rrtname[t])
- return rrtname[t];
- snprint(buf, sizeof buf, "type%d", t);
- return buf;
- }
- static void
- fmtrr(Msg *m, RR **rrp, int quest)
- {
- Txt *t;
- RR *rr;
- rr = *rrp;
- if(rr == nil)
- return;
- *rrp = rr->next;
- m->p = seprint(m->p, m->e, "%s name=%s ttl=%lu",
- rrtypestr(rr->type),
- rr->owner->name, rr->ttl);
- if(!quest)
- switch(rr->type){
- default:
- break;
- case Thinfo:
- m->p = seprint(m->p, m->e, " cpu=%s os=%s",
- rr->cpu->name, rr->os->name);
- break;
- case Tcname:
- case Tmb:
- case Tmd:
- case Tmf:
- case Tns:
- m->p = seprint(m->p, m->e, " host=%s", rr->host->name);
- break;
- case Tmg:
- case Tmr:
- m->p = seprint(m->p, m->e, " mb=%s", rr->mb->name);
- break;
- case Tminfo:
- m->p = seprint(m->p, m->e, " rmb=%s", rr->rmb->name);
- m->p = seprint(m->p, m->e, " mb=%s", rr->mb->name);
- break;
- case Tmx:
- m->p = seprint(m->p, m->e, " pref=%lu", rr->pref);
- m->p = seprint(m->p, m->e, " host=%s", rr->host->name);
- break;
- case Ta:
- case Taaaa:
- m->p = seprint(m->p, m->e, " ip=%s", rr->ip->name);
- break;
- case Tptr:
- m->p = seprint(m->p, m->e, " ptr=%s", rr->ptr->name);
- break;
- case Tsoa:
- m->p = seprint(m->p, m->e, " host=%s", rr->host->name);
- m->p = seprint(m->p, m->e, " rmb=%s", rr->rmb->name);
- m->p = seprint(m->p, m->e, " soa.serial=%lu", rr->soa->serial);
- m->p = seprint(m->p, m->e, " soa.refresh=%lu", rr->soa->refresh);
- m->p = seprint(m->p, m->e, " soa.retry=%lu", rr->soa->retry);
- m->p = seprint(m->p, m->e, " soa.expire=%lu", rr->soa->expire);
- m->p = seprint(m->p, m->e, " soa.minttl=%lu", rr->soa->minttl);
- break;
- case Ttxt:
- for(t=rr->txt; t; t=t->next)
- m->p = seprint(m->p, m->e, " txt=%q", t->p);
- break;
- case Tnull:
- m->p = seprint(m->p, m->e, " null=%.*H",
- rr->null->dlen, rr->null->data);
- break;
- case Trp:
- m->p = seprint(m->p, m->e, " rmb=%s", rr->rmb->name);
- m->p = seprint(m->p, m->e, " rp=%s", rr->rp->name);
- break;
- case Tkey:
- m->p = seprint(m->p, m->e, " flags=%d proto=%d alg=%d data=%.*H",
- rr->key->flags, rr->key->proto, rr->key->alg,
- rr->key->dlen, rr->key->data);
- break;
- case Tsig:
- m->p = seprint(m->p, m->e,
- " type=%d alg=%d labels=%d ttl=%lu exp=%lu incep=%lu tag=%d signer=%s data=%.*H",
- rr->sig->type, rr->sig->alg, rr->sig->labels,
- rr->sig->ttl, rr->sig->exp, rr->sig->incep, rr->sig->tag,
- rr->sig->signer->name, rr->sig->dlen, rr->sig->data);
- break;
- case Tcert:
- m->p = seprint(m->p, m->e, " type=%d tag=%d alg=%d data=%.*H",
- rr->cert->type, rr->cert->tag, rr->cert->alg,
- rr->cert->dlen, rr->cert->data);
- break;
- }
- rrfree(rr);
- }
- void freealldn(void);
- static Proto dnsqd, dnsan, dnsns, dnsar;
- static void donext(Msg*);
- static DNSmsg dm;
- static int
- p_seprint(Msg *m)
- {
- char *e;
- if((e = convM2DNS(m->ps, m->pe-m->ps, &dm, nil)) != nil){
- m->p = seprint(m->p, m->e, "error: %s", e);
- return 0;
- }
- m->p = seprint(m->p, m->e, "id=%d flags=%#ux", dm.id, dm.flags);
- donext(m);
- return 0;
- }
- static void
- donext(Msg *m)
- {
- if(dm.qd)
- m->pr = &dnsqd;
- else if(dm.an)
- m->pr = &dnsan;
- else if(dm.ns)
- m->pr = &dnsns;
- else if(dm.ar)
- m->pr = &dnsar;
- else{
- freealldn();
- memset(&dm, 0, sizeof dm);
- m->pr = nil;
- }
- }
- static int
- p_seprintqd(Msg *m)
- {
- fmtrr(m, &dm.qd, 1);
- donext(m);
- return 0;
- }
- static int
- p_seprintan(Msg *m)
- {
- fmtrr(m, &dm.an, 0);
- donext(m);
- return 0;
- }
- static int
- p_seprintns(Msg *m)
- {
- fmtrr(m, &dm.ns, 1);
- donext(m);
- return 0;
- }
- static int
- p_seprintar(Msg *m)
- {
- fmtrr(m, &dm.ar, 1);
- donext(m);
- return 0;
- }
- Proto dns =
- {
- "dns",
- nil,
- nil,
- p_seprint,
- nil,
- nil,
- nil,
- defaultframer,
- };
- static Proto dnsqd =
- {
- "dns.qd",
- nil,
- nil,
- p_seprintqd,
- nil,
- nil,
- nil,
- defaultframer,
- };
- static Proto dnsan =
- {
- "dns.an",
- nil,
- nil,
- p_seprintan,
- nil,
- nil,
- nil,
- defaultframer,
- };
- static Proto dnsns =
- {
- "dns.ns",
- nil,
- nil,
- p_seprintns,
- nil,
- nil,
- nil,
- defaultframer,
- };
- static Proto dnsar =
- {
- "dns.ar",
- nil,
- nil,
- p_seprintar,
- nil,
- nil,
- nil,
- defaultframer,
- };
- void*
- emalloc(int n)
- {
- void *v;
- v = mallocz(n, 1);
- if(v == nil)
- sysfatal("out of memory");
- return v;
- }
- char*
- estrdup(char *s)
- {
- s = strdup(s);
- if(s == nil)
- sysfatal("out of memory");
- return s;
- }
- DN *alldn;
- DN*
- dnlookup(char *name, int class, int)
- {
- DN *dn;
- dn = emalloc(sizeof *dn);
- dn->name = estrdup(name);
- dn->class = class;
- dn->magic = DNmagic;
- dn->next = alldn;
- alldn = dn;
- return dn;
- }
- void
- freealldn(void)
- {
- DN *dn;
- while(dn = alldn){
- alldn = dn->next;
- free(dn->name);
- free(dn);
- }
- }
- int debug; /* for ndb/dns.h */
- uint32_t now = 0;
- void
- dnslog(char *fmt, ...) /* don't log */
- {
- USED(fmt);
- }
- /*************************************************
- * Everything below here is copied from /sys/src/cmd/ndb/dn.c
- * without modification and can be recopied to update.
- */
- /*
- * convert an integer RR type to it's ascii name
- */
- char*
- rrname(int type, char *buf, int len)
- {
- char *t;
- t = nil;
- if(type >= 0 && type <= Tall)
- t = rrtname[type];
- if(t==nil){
- snprint(buf, len, "%d", type);
- t = buf;
- }
- return t;
- }
- /*
- * free a list of resource records and any related structs
- */
- void
- rrfreelist(RR *rp)
- {
- RR *next;
- for(; rp; rp = next){
- next = rp->next;
- rrfree(rp);
- }
- }
- void
- freeserverlist(Server *s)
- {
- Server *next;
- for(; s != nil; s = next){
- next = s->next;
- free(s);
- }
- }
- /*
- * allocate a resource record of a given type
- */
- RR*
- rralloc(int type)
- {
- RR *rp;
- rp = emalloc(sizeof(*rp));
- rp->magic = RRmagic;
- rp->pc = getcallerpc(&type);
- rp->type = type;
- setmalloctag(rp, rp->pc);
- switch(type){
- case Tsoa:
- rp->soa = emalloc(sizeof(*rp->soa));
- rp->soa->slaves = nil;
- setmalloctag(rp->soa, rp->pc);
- break;
- case Tsrv:
- rp->srv = emalloc(sizeof(*rp->srv));
- setmalloctag(rp->srv, rp->pc);
- break;
- case Tkey:
- rp->key = emalloc(sizeof(*rp->key));
- setmalloctag(rp->key, rp->pc);
- break;
- case Tcert:
- rp->cert = emalloc(sizeof(*rp->cert));
- setmalloctag(rp->cert, rp->pc);
- break;
- case Tsig:
- rp->sig = emalloc(sizeof(*rp->sig));
- setmalloctag(rp->sig, rp->pc);
- break;
- case Tnull:
- rp->null = emalloc(sizeof(*rp->null));
- setmalloctag(rp->null, rp->pc);
- break;
- }
- rp->ttl = 0;
- rp->expire = 0;
- rp->next = 0;
- return rp;
- }
- /*
- * free a resource record and any related structs
- */
- void
- rrfree(RR *rp)
- {
- DN *dp;
- RR *nrp;
- Txt *t;
- assert(rp->magic = RRmagic);
- assert(!rp->cached);
- dp = rp->owner;
- if(dp){
- assert(dp->magic == DNmagic);
- for(nrp = dp->rr; nrp; nrp = nrp->next)
- assert(nrp != rp); /* "rrfree of live rr" */
- }
- switch(rp->type){
- case Tsoa:
- freeserverlist(rp->soa->slaves);
- memset(rp->soa, 0, sizeof *rp->soa); /* cause trouble */
- free(rp->soa);
- break;
- case Tsrv:
- memset(rp->srv, 0, sizeof *rp->srv); /* cause trouble */
- free(rp->srv);
- break;
- case Tkey:
- free(rp->key->data);
- memset(rp->key, 0, sizeof *rp->key); /* cause trouble */
- free(rp->key);
- break;
- case Tcert:
- free(rp->cert->data);
- memset(rp->cert, 0, sizeof *rp->cert); /* cause trouble */
- free(rp->cert);
- break;
- case Tsig:
- free(rp->sig->data);
- memset(rp->sig, 0, sizeof *rp->sig); /* cause trouble */
- free(rp->sig);
- break;
- case Tnull:
- free(rp->null->data);
- memset(rp->null, 0, sizeof *rp->null); /* cause trouble */
- free(rp->null);
- break;
- case Ttxt:
- while(rp->txt != nil){
- t = rp->txt;
- rp->txt = t->next;
- free(t->p);
- memset(t, 0, sizeof *t); /* cause trouble */
- free(t);
- }
- break;
- }
- rp->magic = ~rp->magic;
- memset(rp, 0, sizeof *rp); /* cause trouble */
- free(rp);
- }
|