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