dns.c 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529
  1. /*
  2. * This file is part of the UCB release of Plan 9. It is subject to the license
  3. * terms in the LICENSE file found in the top-level directory of this
  4. * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No
  5. * part of the UCB release of Plan 9, including this file, may be copied,
  6. * modified, propagated, or distributed except according to the terms contained
  7. * in the LICENSE file.
  8. */
  9. #include <u.h>
  10. #include <libc.h>
  11. #include <ip.h>
  12. #include "dat.h"
  13. #include "protos.h"
  14. #include "../../ndb/dns.h"
  15. /* names of RR types - /sys/src/cmd/ndb/dn.c:/rrtname */
  16. char *rrtname[] =
  17. {
  18. [Ta] "ip",
  19. [Tns] "ns",
  20. [Tmd] "md",
  21. [Tmf] "mf",
  22. [Tcname] "cname",
  23. [Tsoa] "soa",
  24. [Tmb] "mb",
  25. [Tmg] "mg",
  26. [Tmr] "mr",
  27. [Tnull] "null",
  28. [Twks] "wks",
  29. [Tptr] "ptr",
  30. [Thinfo] "hinfo",
  31. [Tminfo] "minfo",
  32. [Tmx] "mx",
  33. [Ttxt] "txt",
  34. [Trp] "rp",
  35. [Tafsdb] "afsdb",
  36. [Tx25] "x.25",
  37. [Tisdn] "isdn",
  38. [Trt] "rt",
  39. [Tnsap] "nsap",
  40. [Tnsapptr] "nsap-ptr",
  41. [Tsig] "sig",
  42. [Tkey] "key",
  43. [Tpx] "px",
  44. [Tgpos] "gpos",
  45. [Taaaa] "ipv6",
  46. [Tloc] "loc",
  47. [Tnxt] "nxt",
  48. [Teid] "eid",
  49. [Tnimloc] "nimrod",
  50. [Tsrv] "srv",
  51. [Tatma] "atma",
  52. [Tnaptr] "naptr",
  53. [Tkx] "kx",
  54. [Tcert] "cert",
  55. [Ta6] "a6",
  56. [Tdname] "dname",
  57. [Tsink] "sink",
  58. [Topt] "opt",
  59. [Tapl] "apl",
  60. [Tds] "ds",
  61. [Tsshfp] "sshfp",
  62. [Tipseckey] "ipseckey",
  63. [Trrsig] "rrsig",
  64. [Tnsec] "nsec",
  65. [Tdnskey] "dnskey",
  66. [Tspf] "spf",
  67. [Tuinfo] "uinfo",
  68. [Tuid] "uid",
  69. [Tgid] "gid",
  70. [Tunspec] "unspec",
  71. [Ttkey] "tkey",
  72. [Ttsig] "tsig",
  73. [Tixfr] "ixfr",
  74. [Taxfr] "axfr",
  75. [Tmailb] "mailb",
  76. [Tmaila] "maila",
  77. [Tall] "all",
  78. 0,
  79. };
  80. static char*
  81. rrtypestr(int t)
  82. {
  83. char buf[20];
  84. if(t >= 0 && t < nelem(rrtname) && rrtname[t])
  85. return rrtname[t];
  86. snprint(buf, sizeof buf, "type%d", t);
  87. return buf;
  88. }
  89. static void
  90. fmtrr(Msg *m, RR **rrp, int quest)
  91. {
  92. Txt *t;
  93. RR *rr;
  94. rr = *rrp;
  95. if(rr == nil)
  96. return;
  97. *rrp = rr->next;
  98. m->p = seprint(m->p, m->e, "%s name=%s ttl=%lu",
  99. rrtypestr(rr->type),
  100. rr->owner->name, rr->ttl);
  101. if(!quest)
  102. switch(rr->type){
  103. default:
  104. break;
  105. case Thinfo:
  106. m->p = seprint(m->p, m->e, " cpu=%s os=%s",
  107. rr->cpu->name, rr->os->name);
  108. break;
  109. case Tcname:
  110. case Tmb:
  111. case Tmd:
  112. case Tmf:
  113. case Tns:
  114. m->p = seprint(m->p, m->e, " host=%s", rr->host->name);
  115. break;
  116. case Tmg:
  117. case Tmr:
  118. m->p = seprint(m->p, m->e, " mb=%s", rr->mb->name);
  119. break;
  120. case Tminfo:
  121. m->p = seprint(m->p, m->e, " rmb=%s", rr->rmb->name);
  122. m->p = seprint(m->p, m->e, " mb=%s", rr->mb->name);
  123. break;
  124. case Tmx:
  125. m->p = seprint(m->p, m->e, " pref=%lu", rr->pref);
  126. m->p = seprint(m->p, m->e, " host=%s", rr->host->name);
  127. break;
  128. case Ta:
  129. case Taaaa:
  130. m->p = seprint(m->p, m->e, " ip=%s", rr->ip->name);
  131. break;
  132. case Tptr:
  133. m->p = seprint(m->p, m->e, " ptr=%s", rr->ptr->name);
  134. break;
  135. case Tsoa:
  136. m->p = seprint(m->p, m->e, " host=%s", rr->host->name);
  137. m->p = seprint(m->p, m->e, " rmb=%s", rr->rmb->name);
  138. m->p = seprint(m->p, m->e, " soa.serial=%lu", rr->soa->serial);
  139. m->p = seprint(m->p, m->e, " soa.refresh=%lu", rr->soa->refresh);
  140. m->p = seprint(m->p, m->e, " soa.retry=%lu", rr->soa->retry);
  141. m->p = seprint(m->p, m->e, " soa.expire=%lu", rr->soa->expire);
  142. m->p = seprint(m->p, m->e, " soa.minttl=%lu", rr->soa->minttl);
  143. break;
  144. case Ttxt:
  145. for(t=rr->txt; t; t=t->next)
  146. m->p = seprint(m->p, m->e, " txt=%q", t->p);
  147. break;
  148. case Tnull:
  149. m->p = seprint(m->p, m->e, " null=%.*H",
  150. rr->null->dlen, rr->null->data);
  151. break;
  152. case Trp:
  153. m->p = seprint(m->p, m->e, " rmb=%s", rr->rmb->name);
  154. m->p = seprint(m->p, m->e, " rp=%s", rr->rp->name);
  155. break;
  156. case Tkey:
  157. m->p = seprint(m->p, m->e, " flags=%d proto=%d alg=%d data=%.*H",
  158. rr->key->flags, rr->key->proto, rr->key->alg,
  159. rr->key->dlen, rr->key->data);
  160. break;
  161. case Tsig:
  162. m->p = seprint(m->p, m->e,
  163. " type=%d alg=%d labels=%d ttl=%lu exp=%lu incep=%lu tag=%d signer=%s data=%.*H",
  164. rr->sig->type, rr->sig->alg, rr->sig->labels,
  165. rr->sig->ttl, rr->sig->exp, rr->sig->incep, rr->sig->tag,
  166. rr->sig->signer->name, rr->sig->dlen, rr->sig->data);
  167. break;
  168. case Tcert:
  169. m->p = seprint(m->p, m->e, " type=%d tag=%d alg=%d data=%.*H",
  170. rr->cert->type, rr->cert->tag, rr->cert->alg,
  171. rr->cert->dlen, rr->cert->data);
  172. break;
  173. }
  174. rrfree(rr);
  175. }
  176. void freealldn(void);
  177. static Proto dnsqd, dnsan, dnsns, dnsar;
  178. static void donext(Msg*);
  179. static DNSmsg dm;
  180. static int
  181. p_seprint(Msg *m)
  182. {
  183. char *e;
  184. if((e = convM2DNS(m->ps, m->pe-m->ps, &dm, nil)) != nil){
  185. m->p = seprint(m->p, m->e, "error: %s", e);
  186. return 0;
  187. }
  188. m->p = seprint(m->p, m->e, "id=%d flags=%#x", dm.id, dm.flags);
  189. donext(m);
  190. return 0;
  191. }
  192. static void
  193. donext(Msg *m)
  194. {
  195. if(dm.qd)
  196. m->pr = &dnsqd;
  197. else if(dm.an)
  198. m->pr = &dnsan;
  199. else if(dm.ns)
  200. m->pr = &dnsns;
  201. else if(dm.ar)
  202. m->pr = &dnsar;
  203. else{
  204. freealldn();
  205. memset(&dm, 0, sizeof dm);
  206. m->pr = nil;
  207. }
  208. }
  209. static int
  210. p_seprintqd(Msg *m)
  211. {
  212. fmtrr(m, &dm.qd, 1);
  213. donext(m);
  214. return 0;
  215. }
  216. static int
  217. p_seprintan(Msg *m)
  218. {
  219. fmtrr(m, &dm.an, 0);
  220. donext(m);
  221. return 0;
  222. }
  223. static int
  224. p_seprintns(Msg *m)
  225. {
  226. fmtrr(m, &dm.ns, 1);
  227. donext(m);
  228. return 0;
  229. }
  230. static int
  231. p_seprintar(Msg *m)
  232. {
  233. fmtrr(m, &dm.ar, 1);
  234. donext(m);
  235. return 0;
  236. }
  237. Proto dns =
  238. {
  239. "dns",
  240. nil,
  241. nil,
  242. p_seprint,
  243. nil,
  244. nil,
  245. nil,
  246. defaultframer,
  247. };
  248. static Proto dnsqd =
  249. {
  250. "dns.qd",
  251. nil,
  252. nil,
  253. p_seprintqd,
  254. nil,
  255. nil,
  256. nil,
  257. defaultframer,
  258. };
  259. static Proto dnsan =
  260. {
  261. "dns.an",
  262. nil,
  263. nil,
  264. p_seprintan,
  265. nil,
  266. nil,
  267. nil,
  268. defaultframer,
  269. };
  270. static Proto dnsns =
  271. {
  272. "dns.ns",
  273. nil,
  274. nil,
  275. p_seprintns,
  276. nil,
  277. nil,
  278. nil,
  279. defaultframer,
  280. };
  281. static Proto dnsar =
  282. {
  283. "dns.ar",
  284. nil,
  285. nil,
  286. p_seprintar,
  287. nil,
  288. nil,
  289. nil,
  290. defaultframer,
  291. };
  292. void*
  293. emalloc(int n)
  294. {
  295. void *v;
  296. v = mallocz(n, 1);
  297. if(v == nil)
  298. sysfatal("out of memory");
  299. return v;
  300. }
  301. char*
  302. estrdup(char *s)
  303. {
  304. s = strdup(s);
  305. if(s == nil)
  306. sysfatal("out of memory");
  307. return s;
  308. }
  309. DN *alldn;
  310. DN*
  311. dnlookup(char *name, int class, int)
  312. {
  313. DN *dn;
  314. dn = emalloc(sizeof *dn);
  315. dn->name = estrdup(name);
  316. dn->class = class;
  317. dn->magic = DNmagic;
  318. dn->next = alldn;
  319. alldn = dn;
  320. return dn;
  321. }
  322. void
  323. freealldn(void)
  324. {
  325. DN *dn;
  326. while(dn = alldn){
  327. alldn = dn->next;
  328. free(dn->name);
  329. free(dn);
  330. }
  331. }
  332. int debug; /* for ndb/dns.h */
  333. uint32_t now = 0;
  334. void
  335. dnslog(char *fmt, ...) /* don't log */
  336. {
  337. USED(fmt);
  338. }
  339. /*************************************************
  340. * Everything below here is copied from /sys/src/cmd/ndb/dn.c
  341. * without modification and can be recopied to update.
  342. */
  343. /*
  344. * convert an integer RR type to it's ascii name
  345. */
  346. char*
  347. rrname(int type, char *buf, int len)
  348. {
  349. char *t;
  350. t = nil;
  351. if(type >= 0 && type <= Tall)
  352. t = rrtname[type];
  353. if(t==nil){
  354. snprint(buf, len, "%d", type);
  355. t = buf;
  356. }
  357. return t;
  358. }
  359. /*
  360. * free a list of resource records and any related structs
  361. */
  362. void
  363. rrfreelist(RR *rp)
  364. {
  365. RR *next;
  366. for(; rp; rp = next){
  367. next = rp->next;
  368. rrfree(rp);
  369. }
  370. }
  371. void
  372. freeserverlist(Server *s)
  373. {
  374. Server *next;
  375. for(; s != nil; s = next){
  376. next = s->next;
  377. free(s);
  378. }
  379. }
  380. /*
  381. * allocate a resource record of a given type
  382. */
  383. RR*
  384. rralloc(int type)
  385. {
  386. RR *rp;
  387. rp = emalloc(sizeof(*rp));
  388. rp->magic = RRmagic;
  389. rp->pc = getcallerpc(&type);
  390. rp->type = type;
  391. setmalloctag(rp, rp->pc);
  392. switch(type){
  393. case Tsoa:
  394. rp->soa = emalloc(sizeof(*rp->soa));
  395. rp->soa->slaves = nil;
  396. setmalloctag(rp->soa, rp->pc);
  397. break;
  398. case Tsrv:
  399. rp->srv = emalloc(sizeof(*rp->srv));
  400. setmalloctag(rp->srv, rp->pc);
  401. break;
  402. case Tkey:
  403. rp->key = emalloc(sizeof(*rp->key));
  404. setmalloctag(rp->key, rp->pc);
  405. break;
  406. case Tcert:
  407. rp->cert = emalloc(sizeof(*rp->cert));
  408. setmalloctag(rp->cert, rp->pc);
  409. break;
  410. case Tsig:
  411. rp->sig = emalloc(sizeof(*rp->sig));
  412. setmalloctag(rp->sig, rp->pc);
  413. break;
  414. case Tnull:
  415. rp->null = emalloc(sizeof(*rp->null));
  416. setmalloctag(rp->null, rp->pc);
  417. break;
  418. }
  419. rp->ttl = 0;
  420. rp->expire = 0;
  421. rp->next = 0;
  422. return rp;
  423. }
  424. /*
  425. * free a resource record and any related structs
  426. */
  427. void
  428. rrfree(RR *rp)
  429. {
  430. DN *dp;
  431. RR *nrp;
  432. Txt *t;
  433. assert(rp->magic = RRmagic);
  434. assert(!rp->cached);
  435. dp = rp->owner;
  436. if(dp){
  437. assert(dp->magic == DNmagic);
  438. for(nrp = dp->rr; nrp; nrp = nrp->next)
  439. assert(nrp != rp); /* "rrfree of live rr" */
  440. }
  441. switch(rp->type){
  442. case Tsoa:
  443. freeserverlist(rp->soa->slaves);
  444. memset(rp->soa, 0, sizeof *rp->soa); /* cause trouble */
  445. free(rp->soa);
  446. break;
  447. case Tsrv:
  448. memset(rp->srv, 0, sizeof *rp->srv); /* cause trouble */
  449. free(rp->srv);
  450. break;
  451. case Tkey:
  452. free(rp->key->data);
  453. memset(rp->key, 0, sizeof *rp->key); /* cause trouble */
  454. free(rp->key);
  455. break;
  456. case Tcert:
  457. free(rp->cert->data);
  458. memset(rp->cert, 0, sizeof *rp->cert); /* cause trouble */
  459. free(rp->cert);
  460. break;
  461. case Tsig:
  462. free(rp->sig->data);
  463. memset(rp->sig, 0, sizeof *rp->sig); /* cause trouble */
  464. free(rp->sig);
  465. break;
  466. case Tnull:
  467. free(rp->null->data);
  468. memset(rp->null, 0, sizeof *rp->null); /* cause trouble */
  469. free(rp->null);
  470. break;
  471. case Ttxt:
  472. while(rp->txt != nil){
  473. t = rp->txt;
  474. rp->txt = t->next;
  475. free(t->p);
  476. memset(t, 0, sizeof *t); /* cause trouble */
  477. free(t);
  478. }
  479. break;
  480. }
  481. rp->magic = ~rp->magic;
  482. memset(rp, 0, sizeof *rp); /* cause trouble */
  483. free(rp);
  484. }