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