dns.c 8.5 KB

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