djbdnscurve6 50
djbdnscurve6
Loading...
Searching...
No Matches
tinydns-data.c
Go to the documentation of this file.
1#include <unistd.h>
2#include <sys/types.h>
3#include <sys/stat.h>
4#include "uint_t.h"
5#include "str.h"
6#include "byte.h"
7#include "fmt.h"
8#include "ip.h"
9#include "exit.h"
10#include "case.h"
11#include "scan.h"
12#include "buffer.h"
13#include "logmsg.h"
14#include "getln.h"
15#include "cdbmake.h"
16#include "stralloc.h"
17#include "readclose.h"
18#include "open.h"
19#include "dns.h"
20
21#define TTL_NS 259200
22#define TTL_POSITIVE 86400
23#define TTL_NEGATIVE 2560
24#define TXT_LABLEN 255
25
26#define WHO "tinydns-data"
27
28int rename(const char *,const char *); // keep compiler silent
29
30void die_datatmp(void)
31{
32 logmsg(WHO,111,FATAL,"unable to create data.tmp");
33}
34
35void nomem(void)
36{
37 logmsg(WHO,111,FATAL,"nomem");
38}
39
40void ttdparse(stralloc *sa,char ttd[8])
41{
42 unsigned int i;
43 char ch;
44
45 byte_zero(ttd,8);
46 for (i = 0; (i < 16) && (i < sa->len); ++i) {
47 ch = sa->s[i];
48 if ((ch >= '0') && (ch <= '9'))
49 ch -= '0';
50 else if ((ch >= 'a') && (ch <= 'f'))
51 ch -= 'a' - 10;
52 else
53 ch = 0;
54 if (!(i & 1)) ch <<= 4;
55 ttd[i >> 1] |= ch;
56 }
57}
58
59void locparse(stralloc *sa,char loc[2])
60{
61 loc[0] = (sa->len > 0) ? sa->s[0] : 0;
62 loc[1] = (sa->len > 1) ? sa->s[1] : 0;
63}
64
65/* input *s = IPv4/6 address
66 output out = IPv4/6 address byte string for lookup */
67
68void ipprefix_get(stralloc *out,char *s)
69{
70 char ip4[4];
71 char ip6[16];
72 unsigned long plen;
73
74 if (!stralloc_copys(out,"")) nomem();
75 if (!str_len(s)) return;
76
77 if (str_chr(s,':') < str_len(s)) {
78 ip6_cidr(s,ip6,&plen);
79 ip6_bytestring(out,ip6,plen);
80 } else if (str_chr(s,'.') < str_len(s)) {
81 ip4_cidr(s,ip4,&plen);
82 ip4_bytestring(out,ip4,plen);
83 }
84}
85
86void hexparse(stralloc *sa)
87{
88 char ch, lo;
89 unsigned int i;
90 unsigned int j;
91
92 j = 0;
93 i = 0;
94 while (i < sa->len) {
95 ch = sa->s[i++];
96 if ((ch >= '0') && (ch <= '9')) ch -= 48;
97 if ((ch >= 'a') && (ch <= 'f')) ch -= 87;
98 ch <<= 4;
99 lo = sa->s[i++];
100 if ((lo >= '0') && (lo <= '9')) lo -= 48;
101 if ((lo >= 'a') && (lo <= 'f')) lo -= 87;
102 ch += lo;
103 sa->s[j++] = ch;
104 }
105 sa->len = j;
106}
107
108void txtparse(stralloc *sa)
109{
110 char ch;
111 unsigned int i;
112 unsigned int j;
113
114 j = 0;
115 i = 0;
116 while (i < sa->len) {
117 ch = sa->s[i++];
118 if (ch == '\\') {
119 if (i >= sa->len) break;
120 ch = sa->s[i++];
121 if ((ch >= '0') && (ch <= '7')) {
122 ch -= '0';
123 if ((i < sa->len) && (sa->s[i] >= '0') && (sa->s[i] <= '7')) {
124 ch <<= 3;
125 ch += sa->s[i++] - '0';
126 if ((i < sa->len) && (sa->s[i] >= '0') && (sa->s[i] <= '7')) {
127 ch <<= 3;
128 ch += sa->s[i++] - '0';
129 }
130 }
131 }
132 }
133 sa->s[j++] = ch;
134 }
135 sa->len = j;
136}
137
138void textparse(stralloc *sa)
139{
140 char ch;
141 unsigned int i;
142 unsigned int j;
143
144 j = 0;
145 i = 0;
146 while (i < sa->len) {
147 ch = sa->s[i++];
148 if (ch >= ' ' && ch <= '~')
149 { sa->s[j] = ch; j++; }
150 }
151 sa -> s[j] = '\0';
152 sa->len = j ;
153}
154
155char defaultsoa[20];
156
158{
159 struct stat st;
160 if (fstat(fd,&st) == -1)
161 logmsg(WHO,111,FATAL,"unable to stat data");
162 uint32_pack_big(defaultsoa,st.st_mtime);
163 if (byte_equal(defaultsoa,4,"\0\0\0\0"))
164 defaultsoa[3] = 1;
165 byte_copy(defaultsoa + 4,16,"\0\0\100\000\0\0\010\000\0\020\000\000\0\0\012\000");
166}
167
169struct cdb_make cdb;
170static stralloc key;
171static stralloc ipstring;
172static stralloc result;
173
174void rr_add(const char *buf,unsigned int len)
175{
176 if (!stralloc_catb(&result,buf,len)) nomem();
177}
178
179void rr_addname(const char *d)
180{
182}
183
184void rr_start(const char type[2],unsigned long ttl,const char ttd[8],const char loc[2])
185{
186 char buf[4];
187 if (!stralloc_copyb(&result,type,2)) nomem();
188 if (byte_equal(loc,2,"\0\0"))
189 rr_add("=",1);
190 else {
191 rr_add(">",1);
192 rr_add(loc,2);
193 }
194 uint32_pack_big(buf,ttl);
195 rr_add(buf,4);
196 rr_add(ttd,8);
197}
198
199void rr_finish(const char *owner)
200{
201 if (byte_equal(owner,2,"\1*")) {
202 owner += 2;
203 result.s[2] -= 19;
204 }
205 if (!stralloc_copyb(&key,owner,dns_domain_length(owner))) nomem();
206 case_lowerb(key.s,key.len);
207 if (cdb_make_add(&cdb,key.s,key.len,result.s,result.len) == -1)
208 die_datatmp();
209}
210
211buffer b;
212char bspace[1024];
213
214static stralloc line;
215int match = 1;
216unsigned long linenum = 0;
217
218#define NUMFIELDS 15
219static stralloc f[NUMFIELDS];
220
221static char *d1;
222static char *d2;
225
226char strnum[FMT_ULONG];
227
228void syntaxerror(const char *why)
229{
230 strnum[fmt_dnum(strnum,linenum)] = 0;
231 logmsg(WHO,111,FATAL,B("unable to parse data line: ",strnum,why));
232}
233
234int main()
235{
236 int fddata;
237 int i;
238 int j;
239 int k;
240 unsigned char ch;
241 char ttd[8];
242 char loc[2];
243 char ip64[32];
244 char ip4[4];
245 char ip6[16];
246 char type[2];
247 char soa[20];
248 char buf[4];
249 uint32_t ttl, u;
250 unsigned char us, sl, ty;
251 umask(022);
252
253 fddata = open_read("data");
254 if (fddata == -1)
255 logmsg(WHO,111,FATAL,"unable to open data");
256
257 defaultsoa_init(fddata);
258 buffer_init(&b,buffer_unixread,fddata,bspace,sizeof(bspace));
259
260 fdcdb = open_trunc("data.tmp");
261 if (fdcdb == -1) die_datatmp();
262 if (cdb_make_start(&cdb,fdcdb) == -1) die_datatmp();
263
264 while (match) {
265 ++linenum;
266 if (getln(&b,&line,&match,'\n') == -1)
267 logmsg(WHO,111,FATAL,"unable to read line");
268
269 while (line.len) {
270 ch = line.s[line.len - 1];
271 if ((ch != ' ') && (ch != '\t') && (ch != '\n')) break;
272 --line.len;
273 }
274 if (!line.len) continue;
275 if (line.s[0] == '#') continue;
276 if (line.s[0] == '-') continue;
277
278 /* Tokenization of input fields; delimitor: | */
279
280 for (j = 1, i = 0; i < NUMFIELDS; ++i) {
281 if (j >= line.len) {
282 if (!stralloc_copys(&f[i],"")) nomem();
283 }
284 else {
285 k = byte_chr(line.s + j,line.len - j,'|');
286 if (!stralloc_copyb(&f[i],line.s + j,k)) nomem();
287 j += k + 1;
288 }
289 }
290
291 switch (line.s[0]) {
292
293 case '%': /* local extension */
294 locparse(&f[0],loc);
295 if (!stralloc_copyb(&key,"\0%",2)) nomem();
296 if (!stralloc_0(&f[1])) nomem();
297 ipprefix_get(&ipstring,f[1].s);
298 if (ipstring.len > 1)
299 if (!stralloc_catb(&key,ipstring.s,ipstring.len - 1)) nomem();
300 if (cdb_make_add(&cdb,key.s,key.len,loc,2) == -1)
301 die_datatmp();
302 break;
303
304 case 'Z': /* SOA records */
305 if (dns_domain_fromdot(&d1,f[0].s,f[0].len) <= 0) nomem();
306
307 if (!stralloc_0(&f[3])) nomem();
308 if (!scan_dnum(f[3].s,&u)) uint32_unpack_big(defaultsoa,&u);
309 uint32_pack_big(soa,u);
310 if (!stralloc_0(&f[4])) nomem();
311 if (!scan_dnum(f[4].s,&u)) uint32_unpack_big(defaultsoa + 4,&u);
312 uint32_pack_big(soa + 4,u);
313 if (!stralloc_0(&f[5])) nomem();
314 if (!scan_dnum(f[5].s,&u)) uint32_unpack_big(defaultsoa + 8,&u);
315 uint32_pack_big(soa + 8,u);
316 if (!stralloc_0(&f[6])) nomem();
317 if (!scan_dnum(f[6].s,&u)) uint32_unpack_big(defaultsoa + 12,&u);
318 uint32_pack_big(soa + 12,u);
319 if (!stralloc_0(&f[7])) nomem();
320 if (!scan_dnum(f[7].s,&u)) uint32_unpack_big(defaultsoa + 16,&u);
321 uint32_pack_big(soa + 16,u);
322
323 if (!stralloc_0(&f[8])) nomem();
324 if (!scan_dnum(f[8].s,&ttl)) ttl = TTL_NEGATIVE;
325 ttdparse(&f[9],ttd);
326 locparse(&f[10],loc);
327
328 rr_start(DNS_T_SOA,ttl,ttd,loc);
329 if (dns_domain_fromdot(&d2,f[1].s,f[1].len) <= 0) nomem();
330 rr_addname(d2);
331 if (dns_domain_fromdot(&d2,f[2].s,f[2].len) <= 0) nomem();
332 rr_addname(d2);
333 rr_add(soa,20);
334 rr_finish(d1);
335 break;
336
337 case '.': case '&': /* NS records */
338 if (dns_domain_fromdot(&d1,f[0].s,f[0].len) <= 0) nomem();
339 if (!stralloc_0(&f[3])) nomem();
340 if (!scan_dnum(f[3].s,&ttl)) ttl = TTL_NS;
341 ttdparse(&f[4],ttd);
342 locparse(&f[5],loc);
343
344 if (!stralloc_0(&f[1])) nomem();
345
346 if (byte_chr(f[2].s,f[2].len,'.') >= f[2].len) {
347 if (!stralloc_cats(&f[2],".ns.")) nomem();
348 if (!stralloc_catb(&f[2],f[0].s,f[0].len)) nomem();
349 }
350 if (dns_domain_fromdot(&d2,f[2].s,f[2].len) <= 0) nomem();
351
352 if (line.s[0] == '.') {
353 rr_start(DNS_T_SOA,ttl ? TTL_NEGATIVE : 0,ttd,loc);
354 rr_addname(d2);
355 rr_add("\12hostmaster",11);
356 rr_addname(d1);
357 rr_add(defaultsoa,20);
358 rr_finish(d1);
359 }
360
361 rr_start(DNS_T_NS,ttl,ttd,loc);
362 rr_addname(d2);
363 rr_finish(d1);
364
365 if (byte_chr(f[1].s,f[1].len,':') < f[1].len) {
366 if (ip6_scan(f[1].s,ip6)) {
367 rr_start(DNS_T_AAAA,ttl,ttd,loc);
368 rr_add(ip6,16);
369 rr_finish(d2);
370 }
371 } else {
372 if (ip4_scan(f[1].s,ip4)) {
373 rr_start(DNS_T_A,ttl,ttd,loc);
374 rr_add(ip4,4);
375 rr_finish(d2);
376 }
377 }
378 break;
379
380 case '+': case '=': /* A records */
381 if (dns_domain_fromdot(&d1,f[0].s,f[0].len) <= 0) nomem();
382 if (!stralloc_0(&f[2])) nomem();
383 if (!scan_dnum(f[2].s,&ttl)) ttl = TTL_POSITIVE;
384 ttdparse(&f[3],ttd);
385 locparse(&f[4],loc);
386
387 if (!stralloc_0(&f[1])) nomem();
388
389 if (ip4_scan(f[1].s,ip4)) {
390 rr_start(DNS_T_A,ttl,ttd,loc);
391 rr_add(ip4,4);
392 rr_finish(d1);
393
394 if (line.s[0] == '=') {
396 rr_start(DNS_T_PTR,ttl,ttd,loc);
397 rr_addname(d1);
399 }
400 }
401 break;
402
403 case ':': case '~': /* AAAA records */
404 if (dns_domain_fromdot(&d1,f[0].s,f[0].len) <= 0) nomem();
405 if (!stralloc_0(&f[2])) nomem();
406 if (!scan_dnum(f[2].s,&ttl)) ttl = TTL_POSITIVE;
407 ttdparse(&f[3],ttd);
408 locparse(&f[4],loc);
409
410 if (!stralloc_0(&f[1])) nomem();
411
412 if (ip6_scan(f[1].s,ip6)) {
413 rr_start(DNS_T_AAAA,ttl,ttd,loc);
414 rr_add(ip6,16);
415 rr_finish(d1);
416
417 if (line.s[0] == ':') {
419 rr_start(DNS_T_PTR,ttl,ttd,loc);
420 rr_addname(d1);
422 }
423 }
424 break;
425
426 case '@': /* MX Records */
427 if (dns_domain_fromdot(&d1,f[0].s,f[0].len) <= 0) nomem();
428 if (!stralloc_0(&f[4])) nomem();
429 if (!scan_dnum(f[4].s,&ttl)) ttl = TTL_POSITIVE;
430 ttdparse(&f[5],ttd);
431 locparse(&f[6],loc);
432
433 if (!stralloc_0(&f[1])) nomem();
434
435 if (byte_chr(f[2].s,f[2].len,'.') >= f[2].len) {
436 if (!stralloc_cats(&f[2],".mx.")) nomem();
437 if (!stralloc_catb(&f[2],f[0].s,f[0].len)) nomem();
438 }
439 if (dns_domain_fromdot(&d2,f[2].s,f[2].len) <= 0) nomem();
440
441 if (!stralloc_0(&f[3])) nomem();
442 if (!scan_dnum(f[3].s,&u)) u = 0;
443
444 rr_start(DNS_T_MX,ttl,ttd,loc);
445 uint16_pack_big(buf,u);
446 rr_add(buf,2);
447 rr_addname(d2);
448 rr_finish(d1);
449
450 if (byte_chr(f[1].s,f[1].len,':') < f[1].len) {
451 if (ip6_scan(f[1].s,ip6))
452 if (!ip6_isv4mapped(ip6)) {
453 rr_start(DNS_T_AAAA,ttl,ttd,loc);
454 rr_add(ip6,16);
455 rr_finish(d2);
456 }
457 } else
458 if (ip4_scan(f[1].s,ip4)) {
459 rr_start(DNS_T_A,ttl,ttd,loc);
460 rr_add(ip4,4);
461 rr_finish(d2);
462 }
463 break;
464
465 case '^': case 'C': /* Pointer + CName Records */
466 if (dns_domain_fromdot(&d1,f[0].s,f[0].len) <= 0) nomem();
467 if (dns_domain_fromdot(&d2,f[1].s,f[1].len) <= 0) nomem();
468 if (!stralloc_0(&f[2])) nomem();
469 if (!scan_dnum(f[2].s,&ttl)) ttl = TTL_POSITIVE;
470 ttdparse(&f[3],ttd);
471 locparse(&f[4],loc);
472
473 if (line.s[0] == 'C')
474 rr_start(DNS_T_CNAME,ttl,ttd,loc);
475 else
476 rr_start(DNS_T_PTR,ttl,ttd,loc);
477 rr_addname(d2);
478 rr_finish(d1);
479 break;
480
481 case '\'': /* TXT Records*/
482 if (dns_domain_fromdot(&d1,f[0].s,f[0].len) <= 0) nomem();
483 if (!stralloc_0(&f[2])) nomem();
484 if (!scan_dnum(f[2].s,&ttl)) ttl = TTL_POSITIVE;
485 ttdparse(&f[3],ttd);
486 locparse(&f[4],loc);
487
488 rr_start(DNS_T_TXT,ttl,ttd,loc);
489
490 textparse(&f[1]);
491 i = 0;
492 while (i < f[1].len) {
493 k = f[1].len - i;
494 if (k > TXT_LABLEN) k = TXT_LABLEN;
495 ch = k;
496 rr_add((char *)&ch,1);
497 rr_add(f[1].s + i,k);
498 i += k;
499 }
500 rr_finish(d1);
501 break;
502
503 case 'D': /* DKIM Records*/
504 /* Dfqdn|pubkey|selector|keytype|hash|service|type|ttl|timestamp|lo */
505 /* 0 1 2 3 4 5 6 7 8 9 */
506
507 if (dns_domain_fromdot(&d1,f[0].s,f[0].len) <= 0) nomem(); // d1
508 if (!stralloc_0(&f[7])) nomem();
509 if (!scan_dnum(f[7].s,&ttl)) ttl = TTL_POSITIVE;
510 ttdparse(&f[8],ttd);
511 locparse(&f[9],loc);
512
513 /* The TXT Rdata stored in f[8], the domain name in f[9] */
514
515 // Basic
516 if (!stralloc_copys(&f[8],"v=DKIM1;")) nomem();
517 // Key tag
518 if (!f[3].len) {
519 if (!stralloc_cats(&f[8],"k=rsa;")) nomem();
520 } else {
521 if (!stralloc_cats(&f[8],"k=")) nomem();
522 if (!stralloc_catb(&f[8],f[3].s,f[3].len)) nomem();
523 if (!stralloc_cats(&f[8],";")) nomem();
524 }
525 // Hash tag
526 if (!f[4].len) {
527 if (!stralloc_cats(&f[8],"h=sha256;")) nomem();
528 } else {
529 if (!stralloc_cats(&f[8],"h=")) nomem();
530 if (!stralloc_catb(&f[8],f[4].s,f[4].len)) nomem();
531 if (!stralloc_cats(&f[8],";")) nomem();
532 }
533 // Service tag
534 if (f[5].len) {
535 if (!stralloc_cats(&f[8],"s=")) nomem();
536 if (!stralloc_catb(&f[8],f[5].s,f[5].len)) nomem();
537 if (!stralloc_cats(&f[8],";")) nomem();
538 }
539 // Type tag
540 if (f[6].len > 0) {
541 if (!stralloc_cats(&f[8],"t=")) nomem();
542 if (!stralloc_catb(&f[8],f[6].s,f[6].len)) nomem();
543 if (!stralloc_cats(&f[8],";")) nomem();
544 }
545 // Public key
546 if (!f[1].len) {
547 syntaxerror(": DKIM public key is required");
548 } else {
549 textparse(&f[1]);
550 if (!stralloc_cats(&f[8],"p=")) nomem();
551 if (!stralloc_catb(&f[8],f[1].s,f[1].len)) nomem();
552 }
553
554 /* The domain name: [selector]._domainkey.fqdn */
555
556 if (f[2].len > 0) {
557 if (!stralloc_copyb(&f[9],f[2].s,f[2].len)) nomem();
558 if (!stralloc_cats(&f[9],".")) nomem();
559 } else {
560 if (!stralloc_cats(&f[9],"default.")) nomem();
561 }
562 if (!stralloc_cats(&f[9],"_domainkey.")) nomem();
563 if (!stralloc_catb(&f[9],f[0].s,f[0].len)) nomem();
564
565 if (dns_domain_fromdot(&d2,f[9].s,f[9].len) <= 0) nomem(); // d2 - new record
566
567 rr_start(DNS_T_TXT,ttl,ttd,loc);
568 i = 0;
569 while (i < f[8].len) {
570 k = f[8].len - i;
571 if (k > TXT_LABLEN) k = TXT_LABLEN;
572 ch = k;
573 rr_add((char *)&ch,1); // write length; new label
574 rr_add(f[8].s + i,k);
575 i += k;
576 }
577 rr_finish(d2);
578 break;
579
580 case '_': /* TLSA Records*/
581 /* _fqdn|u|s|fingerprint|x|port|proto|ttl|timestamp|lo */
582 /* 0 1 2 3 4 5 6 7 8 9 */
583
584 if (dns_domain_fromdot(&d1,f[0].s,f[0].len) <= 0) nomem(); // d1
585 if (!stralloc_0(&f[7])) nomem();
586 if (!scan_uint(f[7].s,&ttl)) ttl = TTL_POSITIVE;
587 ttdparse(&f[8],ttd);
588 locparse(&f[9],loc);
589
590 if (!stralloc_0(&f[1])) nomem(); // usage
591 if (!scan_uint(f[1].s,(uint *)&us)) us = 003;
592 if (!stralloc_0(&f[2])) nomem(); // selector
593 if (!scan_uint(f[2].s,(uint *)&sl)) sl = 001;
594 f[2].len = 0;
595 ty = 000; // type
596 if (f[3].len == 64) ty = 001;
597 if (f[3].len == 128) ty = 002;
598
599 if (f[4].len == 0 && f[5].len == 0 && f[6].len == 0) { // _25._tcp.mx.fqdn
600 if (!stralloc_copys(&f[2],"_25._tcp.mail.")) nomem();
601 if (!stralloc_catb(&f[2],f[0].s,f[0].len)) nomem();
602 } else if (f[4].s[0] != '_') { // synthesize base domain
603 if (!stralloc_copys(&f[2],"_")) nomem();
604 if (f[5].len > 0) {
605 if (!stralloc_catb(&f[2],f[5].s,f[5].len)) nomem();
606 } else
607 if (!stralloc_cats(&f[2],"25")) nomem();
608 if (!stralloc_cats(&f[2],"._")) nomem();
609 if (f[6].len > 0) {
610 if (!stralloc_catb(&f[2],f[6].s,f[6].len)) nomem();
611 } else
612 if (!stralloc_cats(&f[2],"tcp")) nomem();
613 if (f[4].s[0] != '.')
614 if (!stralloc_cats(&f[2],".")) nomem();
615 if (!stralloc_catb(&f[2],f[4].s,f[4].len)) nomem();
616 if (!stralloc_cats(&f[2],".")) nomem();
617 if (!stralloc_catb(&f[2],f[0].s,f[0].len)) nomem();
618 } else
619 if (!stralloc_copy(&f[2],&f[4])) nomem();
620
621 if (dns_domain_fromdot(&d2,f[2].s,f[2].len) <= 0) nomem(); // d2 - new record
622
623 rr_start(DNS_T_TLSA,ttl,ttd,loc);
624
625 buf[0] = us;
626 rr_add(buf,1);
627 buf[0] = sl;
628 rr_add(buf,1);
629 buf[0] = ty;
630 rr_add(buf,1);
631
632 case_lowerb(f[3].s,f[3].len);
633 hexparse(&f[3]);
634 i = 0;
635 while (i < f[3].len) {
636 k = f[3].len - i;
637 if (k > TXT_LABLEN) k = TXT_LABLEN;
638 ch = k;
639 rr_add((char *)&ch,1); // write length; new label
640 rr_add(f[3].s + i,k);
641 i += k;
642 }
643 rr_finish(d2);
644 break;
645
646 case 'O': /* Any other Records with Octal representation */
647 if (dns_domain_fromdot(&d1,f[0].s,f[0].len) <= 0) nomem();
648 if (!stralloc_0(&f[3])) nomem();
649 if (!scan_dnum(f[3].s,&ttl)) ttl = TTL_POSITIVE;
650 ttdparse(&f[4],ttd);
651 locparse(&f[5],loc);
652
653 if (!stralloc_0(&f[1])) nomem();
654 scan_dnum(f[1].s,&u);
655 uint16_pack_big(type,u);
656 if (byte_equal(type,2,DNS_T_AXFR))
657 syntaxerror(": type AXFR prohibited");
658 if (byte_equal(type,2,"\0\0"))
659 syntaxerror(": type 0 prohibited");
660 if (byte_equal(type,2,DNS_T_SOA))
661 syntaxerror(": type SOA prohibited");
662 if (byte_equal(type,2,DNS_T_NS))
663 syntaxerror(": type NS prohibited");
664 if (byte_equal(type,2,DNS_T_CNAME))
665 syntaxerror(": type CNAME prohibited");
666 if (byte_equal(type,2,DNS_T_PTR))
667 syntaxerror(": type PTR prohibited");
668 if (byte_equal(type,2,DNS_T_MX))
669 syntaxerror(": type MX prohibited");
670
671 txtparse(&f[2]);
672
673 rr_start(type,ttl,ttd,loc);
674 rr_add(f[2].s,f[2].len);
675 rr_finish(d1);
676 break;
677
678 case 'x': case 'X': /* 6-to-4 DNS xlat AAAA records */
679 /* xfqdn|ip4|localprefix|ttl|timestamp|lo */
680 /* 0 1 2 3 4 5 */
681 if (dns_domain_fromdot(&d1,f[0].s,f[0].len) <= 0) nomem();
682 if (!stralloc_0(&f[3])) nomem();
683 if (!scan_dnum(f[3].s,&ttl)) ttl = TTL_POSITIVE;
684 ttdparse(&f[4],ttd);
685 locparse(&f[5],loc);
686
687 if (!stralloc_0(&f[1])) nomem();
688 if (ip4_scan(f[1].s,ip4)) {
689 byte_copy(ip64,16,IP6_64PREFIX_GLOBAL); // 64 global prefix
690 if (f[2].len) ip6_scan(f[2].s,ip64 + 4); // [00]64:ff9b:XXXX ... f2 = XXXX
691 byte_copy(ip64 + 12,4,ip4); // f1 = ip4
692
693 rr_start(DNS_T_AAAA,ttl,ttd,loc);
694 rr_add(ip64,16);
695 rr_finish(d1);
696
697 if (line.s[0] == 'X') {
699 rr_start(DNS_T_PTR,ttl,ttd,loc);
700 rr_addname(d1);
702 }
703 }
704 break;
705
706 default:
707 syntaxerror(": unrecognized leading character");
708 }
709 }
710
711 if (cdb_make_finish(&cdb) == -1) die_datatmp();
712 if (fsync(fdcdb) == -1) die_datatmp();
713 if (close(fdcdb) == -1) die_datatmp(); /* NFS stupidity */
714 if (rename("data.tmp","data.cdb") == -1)
715 logmsg(WHO,111,FATAL,"unable to move data.tmp to data.cdb");
716
717 _exit(0);
718}
int fd
Definition: axfr-get.c:103
uint16 len
Definition: axfrdns.c:319
char buf[MSGSIZE]
Definition: axfrdns.c:318
#define DNS_NAME4_DOMAIN
Definition: dns.h:166
#define DNS_T_A
Definition: dns.h:56
#define DNS_T_TLSA
Definition: dns.h:80
#define DNS_T_AXFR
Definition: dns.h:84
#define DNS_T_TXT
Definition: dns.h:63
#define DNS_T_PTR
Definition: dns.h:60
#define IP6_64PREFIX_GLOBAL
Definition: dns.h:91
#define DNS_T_SOA
Definition: dns.h:59
#define DNS_T_NS
Definition: dns.h:57
#define DNS_NAME6_DOMAIN
Definition: dns.h:179
#define DNS_T_CNAME
Definition: dns.h:58
#define DNS_T_AAAA
Definition: dns.h:67
#define DNS_T_MX
Definition: dns.h:62
int dns_domain_fromdot(char **out, const char *buf, unsigned int n)
Definition: dns_dfd.c:6
unsigned int dns_domain_length(const char *dn)
Definition: dns_domain.c:6
int dns_name4_domain(char name[DNS_NAME4_DOMAIN], const char ip[4])
Definition: dns_nd.c:6
int dns_name6_domain(char name[DNS_NAME6_DOMAIN], const char ip[16])
Definition: dns_nd.c:28
char ip6[16]
Definition: dnsfilter.c:51
char ip4[4]
Definition: dnsfilter.c:50
char type[2]
Definition: dnsq.c:56
void owner(int uid, int gid)
Definition: generic-conf.c:76
void out(const char *s, unsigned int len)
Definition: generic-conf.c:54
void d(const char *home, const char *subdir, int uid, int gid, int mode)
Definition: dnsfilter.c:23
void ipprefix_get(stralloc *out, char *s)
Definition: tinydns-data.c:68
void textparse(stralloc *sa)
Definition: tinydns-data.c:138
void die_datatmp(void)
Definition: tinydns-data.c:30
#define TXT_LABLEN
Definition: tinydns-data.c:24
struct cdb_make cdb
Definition: tinydns-data.c:169
char bspace[1024]
Definition: tinydns-data.c:212
void ttdparse(stralloc *sa, char ttd[8])
Definition: tinydns-data.c:40
int fdcdb
Definition: tinydns-data.c:168
unsigned long linenum
Definition: tinydns-data.c:216
void rr_addname(const char *d)
Definition: tinydns-data.c:179
void hexparse(stralloc *sa)
Definition: tinydns-data.c:86
char strnum[FMT_ULONG]
Definition: tinydns-data.c:226
int rename(const char *, const char *)
char d4ptr[DNS_NAME4_DOMAIN]
Definition: tinydns-data.c:223
buffer b
Definition: tinydns-data.c:211
void locparse(stralloc *sa, char loc[2])
Definition: tinydns-data.c:59
#define TTL_POSITIVE
Definition: tinydns-data.c:22
#define TTL_NEGATIVE
Definition: tinydns-data.c:23
void nomem(void)
Definition: tinydns-data.c:35
#define TTL_NS
Definition: tinydns-data.c:21
char d6ptr[DNS_NAME6_DOMAIN]
Definition: tinydns-data.c:224
void rr_add(const char *buf, unsigned int len)
Definition: tinydns-data.c:174
#define NUMFIELDS
Definition: tinydns-data.c:218
void syntaxerror(const char *why)
Definition: tinydns-data.c:228
void txtparse(stralloc *sa)
Definition: tinydns-data.c:108
void rr_start(const char type[2], unsigned long ttl, const char ttd[8], const char loc[2])
Definition: tinydns-data.c:184
int match
Definition: tinydns-data.c:215
#define WHO
Definition: tinydns-data.c:26
void defaultsoa_init(int fd)
Definition: tinydns-data.c:157
int main()
Definition: tinydns-data.c:234
char defaultsoa[20]
Definition: tinydns-data.c:155
void rr_finish(const char *owner)
Definition: tinydns-data.c:199
unsigned long u
Definition: utime.c:10