/** Request the name (PTR) record for an IPv4 address. */ int dns_name4_r(struct dns_transmit* tx, struct dns_result* out, const ipv4addr *ip) { char name[DNS_NAME4_DOMAIN]; dns_name4_domain(name,ip); if (dns_resolve(tx,name,DNS_T_PTR) == -1) return -1; if (dns_name_packet(out,tx->packet,tx->packetlen) == -1) return -1; dns_transmit_free(tx); return 0; }
int main() { int fddata; int i; int j; int k; char ch; unsigned long ttl; char ttd[8]; char loc[2]; unsigned long u; char ip[4]; char ip6[16]; char type[2]; char soa[20]; char buf[4]; umask(022); fddata = open_read("data"); if (fddata == -1) strerr_die2sys(111,FATAL,"unable to open data: "); defaultsoa_init(fddata); buffer_init(&b,buffer_unixread,fddata,bspace,sizeof bspace); fdcdb = open_trunc("data.tmp"); if (fdcdb == -1) die_datatmp(); if (cdb_make_start(&cdb,fdcdb) == -1) die_datatmp(); while (match) { ++linenum; if (getln(&b,&line,&match,'\n') == -1) strerr_die2sys(111,FATAL,"unable to read line: "); while (line.len) { ch = line.s[line.len - 1]; if ((ch != ' ') && (ch != '\t') && (ch != '\n')) break; --line.len; } if (!line.len) continue; if (line.s[0] == '#') continue; if (line.s[0] == '-') continue; j = 1; for (i = 0;i < NUMFIELDS;++i) { if (j >= line.len) { if (!stralloc_copys(&f[i],"")) nomem(); } else { k = byte_chr(line.s + j,line.len - j,':'); if (!stralloc_copyb(&f[i],line.s + j,k)) nomem(); j += k + 1; } } switch(line.s[0]) { case '%': locparse(&f[0],loc); if (!stralloc_copyb(&key,"\0%",2)) nomem(); if (!stralloc_0(&f[1])) nomem(); ipprefix_cat(&key,f[1].s); if (cdb_make_add(&cdb,key.s,key.len,loc,2) == -1) die_datatmp(); break; case 'Z': if (!dns_domain_fromdot(&d1,f[0].s,f[0].len)) nomem(); if (!stralloc_0(&f[3])) nomem(); if (!scan_ulong(f[3].s,&u)) uint32_unpack_big(defaultsoa,&u); uint32_pack_big(soa,u); if (!stralloc_0(&f[4])) nomem(); if (!scan_ulong(f[4].s,&u)) uint32_unpack_big(defaultsoa + 4,&u); uint32_pack_big(soa + 4,u); if (!stralloc_0(&f[5])) nomem(); if (!scan_ulong(f[5].s,&u)) uint32_unpack_big(defaultsoa + 8,&u); uint32_pack_big(soa + 8,u); if (!stralloc_0(&f[6])) nomem(); if (!scan_ulong(f[6].s,&u)) uint32_unpack_big(defaultsoa + 12,&u); uint32_pack_big(soa + 12,u); if (!stralloc_0(&f[7])) nomem(); if (!scan_ulong(f[7].s,&u)) uint32_unpack_big(defaultsoa + 16,&u); uint32_pack_big(soa + 16,u); if (!stralloc_0(&f[8])) nomem(); if (!scan_ulong(f[8].s,&ttl)) ttl = TTL_NEGATIVE; ttdparse(&f[9],ttd); locparse(&f[10],loc); rr_start(DNS_T_SOA,ttl,ttd,loc); if (!dns_domain_fromdot(&d2,f[1].s,f[1].len)) nomem(); rr_addname(d2); if (!dns_domain_fromdot(&d2,f[2].s,f[2].len)) nomem(); rr_addname(d2); rr_add(soa,20); rr_finish(d1); break; case '.': case '&': if (!dns_domain_fromdot(&d1,f[0].s,f[0].len)) nomem(); if (!stralloc_0(&f[3])) nomem(); if (!scan_ulong(f[3].s,&ttl)) ttl = TTL_NS; ttdparse(&f[4],ttd); locparse(&f[5],loc); if (!stralloc_0(&f[1])) nomem(); if (byte_chr(f[2].s,f[2].len,'.') >= f[2].len) { if (!stralloc_cats(&f[2],".ns.")) nomem(); if (!stralloc_catb(&f[2],f[0].s,f[0].len)) nomem(); } if (!dns_domain_fromdot(&d2,f[2].s,f[2].len)) nomem(); if (line.s[0] == '.') { rr_start(DNS_T_SOA,ttl ? TTL_NEGATIVE : 0,ttd,loc); rr_addname(d2); rr_add("\12hostmaster",11); rr_addname(d1); rr_add(defaultsoa,20); rr_finish(d1); } rr_start(DNS_T_NS,ttl,ttd,loc); rr_addname(d2); rr_finish(d1); if (ip4_scan(f[1].s,ip)) { rr_start(DNS_T_A,ttl,ttd,loc); rr_add(ip,4); rr_finish(d2); } break; case '+': case '=': if (!dns_domain_fromdot(&d1,f[0].s,f[0].len)) nomem(); if (!stralloc_0(&f[2])) nomem(); if (!scan_ulong(f[2].s,&ttl)) ttl = TTL_POSITIVE; ttdparse(&f[3],ttd); locparse(&f[4],loc); if (!stralloc_0(&f[1])) nomem(); if (ip4_scan(f[1].s,ip)) { rr_start(DNS_T_A,ttl,ttd,loc); rr_add(ip,4); rr_finish(d1); if (line.s[0] == '=') { dns_name4_domain(dptr,ip); rr_start(DNS_T_PTR,ttl,ttd,loc); rr_addname(d1); rr_finish(dptr); } } break; case '6': case '3': if (!dns_domain_fromdot(&d1,f[0].s,f[0].len)) nomem(); if (!stralloc_0(&f[2])) nomem(); if (!scan_ulong(f[2].s,&ttl)) ttl = TTL_POSITIVE; ttdparse(&f[3],ttd); locparse(&f[4],loc); if (!stralloc_0(&f[1])) nomem(); if (ip6_scan_flat(f[1].s,ip6)) { rr_start(DNS_T_AAAA,ttl,ttd,loc); rr_add(ip6,16); rr_finish(d1); if (line.s[0] == '6') { /* emit both .ip6.arpa and .ip6.int */ dns_name6_domain(d6ptr,ip6,DNS_IP6_ARPA); rr_start(DNS_T_PTR,ttl,ttd,loc); rr_addname(d1); rr_finish(d6ptr); dns_name6_domain(d6ptr,ip6,DNS_IP6_INT); rr_start(DNS_T_PTR,ttl,ttd,loc); rr_addname(d1); rr_finish(d6ptr); } } break; case '@': if (!dns_domain_fromdot(&d1,f[0].s,f[0].len)) nomem(); if (!stralloc_0(&f[4])) nomem(); if (!scan_ulong(f[4].s,&ttl)) ttl = TTL_POSITIVE; ttdparse(&f[5],ttd); locparse(&f[6],loc); if (!stralloc_0(&f[1])) nomem(); if (byte_chr(f[2].s,f[2].len,'.') >= f[2].len) { if (!stralloc_cats(&f[2],".mx.")) nomem(); if (!stralloc_catb(&f[2],f[0].s,f[0].len)) nomem(); } if (!dns_domain_fromdot(&d2,f[2].s,f[2].len)) nomem(); if (!stralloc_0(&f[3])) nomem(); if (!scan_ulong(f[3].s,&u)) u = 0; rr_start(DNS_T_MX,ttl,ttd,loc); uint16_pack_big(buf,u); rr_add(buf,2); rr_addname(d2); rr_finish(d1); if (ip4_scan(f[1].s,ip)) { rr_start(DNS_T_A,ttl,ttd,loc); rr_add(ip,4); rr_finish(d2); } break; case '^': case 'C': if (!dns_domain_fromdot(&d1,f[0].s,f[0].len)) nomem(); if (!dns_domain_fromdot(&d2,f[1].s,f[1].len)) nomem(); if (!stralloc_0(&f[2])) nomem(); if (!scan_ulong(f[2].s,&ttl)) ttl = TTL_POSITIVE; ttdparse(&f[3],ttd); locparse(&f[4],loc); if (line.s[0] == 'C') rr_start(DNS_T_CNAME,ttl,ttd,loc); else rr_start(DNS_T_PTR,ttl,ttd,loc); rr_addname(d2); rr_finish(d1); break; case '\'': if (!dns_domain_fromdot(&d1,f[0].s,f[0].len)) nomem(); if (!stralloc_0(&f[2])) nomem(); if (!scan_ulong(f[2].s,&ttl)) ttl = TTL_POSITIVE; ttdparse(&f[3],ttd); locparse(&f[4],loc); rr_start(DNS_T_TXT,ttl,ttd,loc); txtparse(&f[1]); i = 0; while (i < f[1].len) { k = f[1].len - i; if (k > 127) k = 127; ch = k; rr_add(&ch,1); rr_add(f[1].s + i,k); i += k; } rr_finish(d1); break; case ':': if (!dns_domain_fromdot(&d1,f[0].s,f[0].len)) nomem(); if (!stralloc_0(&f[3])) nomem(); if (!scan_ulong(f[3].s,&ttl)) ttl = TTL_POSITIVE; ttdparse(&f[4],ttd); locparse(&f[5],loc); if (!stralloc_0(&f[1])) nomem(); scan_ulong(f[1].s,&u); uint16_pack_big(type,u); if (byte_equal(type,2,DNS_T_AXFR)) syntaxerror(": type AXFR prohibited"); if (byte_equal(type,2,"\0\0")) syntaxerror(": type 0 prohibited"); if (byte_equal(type,2,DNS_T_SOA)) syntaxerror(": type SOA prohibited"); if (byte_equal(type,2,DNS_T_NS)) syntaxerror(": type NS prohibited"); if (byte_equal(type,2,DNS_T_CNAME)) syntaxerror(": type CNAME prohibited"); if (byte_equal(type,2,DNS_T_PTR)) syntaxerror(": type PTR prohibited"); if (byte_equal(type,2,DNS_T_MX)) syntaxerror(": type MX prohibited"); txtparse(&f[2]); rr_start(type,ttl,ttd,loc); rr_add(f[2].s,f[2].len); rr_finish(d1); break; default: syntaxerror(": unrecognized leading character"); } } if (cdb_make_finish(&cdb) == -1) die_datatmp(); if (fsync(fdcdb) == -1) die_datatmp(); if (close(fdcdb) == -1) die_datatmp(); /* NFS stupidity */ if (rename("data.tmp","data.cdb") == -1) strerr_die2sys(111,FATAL,"unable to move data.tmp to data.cdb: "); _exit(0); }
int main(int argc, char **argv) { int fddata; uint32 loc; //int v; char ipa[4]; //char ipb[4]; //ip4_cidr_t *subnets = (ip4_cidr_t *)NULL; //unsigned int slen = 0; uint32 ipinta = 0U; //unsigned int ipintb = 0; unsigned short mask; uint32 uid = 0; uint32 mid = 0; int i; int j; int k; char ch; unsigned long ttl; char ttd[8]; //uint32 loc; unsigned char keyloc[15]; unsigned long u; char ip[4]; char locp[4]; //char map[9]; char type[2]; char soa[20]; char buf[4]; //int namlen = 0; umask(022); fddata = STDIN_FILENO; if (argc != 3) { fddata = open_read("data"); if (fddata == -1) strerr_die2sys(111,FATAL,"unable to open data: "); if ( (fdcdb = open_trunc("data.tmp")) == -1) die_datatmp(); } else { fddata = STDIN_FILENO; if ( (fdcdb = open_trunc(argv[1])) == -1) die_datatmp(); } defaultsoa_init(fddata); buffer_init(&b,buffer_unixread,fddata,bspace,sizeof bspace); if (cdb_make_start(&cdb,fdcdb) == -1) die_datatmp(); while (match) { ++linenum; if (getln(&b,&line,&match,'\n') == -1) strerr_die2sys(111,FATAL,"unable to read line: "); while (line.len) { ch = line.s[line.len - 1]; if ((ch != ' ') && (ch != '\t') && (ch != '\n')) break; --line.len; } if (!line.len) continue; if (line.s[0] == '#') continue; if (line.s[0] == '-') continue; //write(1,line.s,line.len); //write(1,"\n",1); j = 1; for (i = 0;i < NUMFIELDS;++i) { if (j >= line.len) { if (!stralloc_copys(&f[i],"")) nomem(); } else { k = byte_chr(line.s + j,line.len - j,':'); if (!stralloc_copyb(&f[i],line.s + j,k)) nomem(); j += k + 1; } } switch(line.s[0]) { #ifdef USE_LOCMAPS case '%': //locparse(&f[0],loc); loc = gethash(f[0].s,f[0].len); uint32_pack(locp,loc); if (!stralloc_0(&f[1])) nomem(); if (!stralloc_0(&f[2])) nomem(); ip4_scan(f[1].s,ipa); //ip4_scan(f[2].s,ipb); scan_ushort(f[2].s,&mask); ip4_num(&ipinta,ipa); //ip4_num(&ipintb,ipb); //if (ipintb<ipinta) nomem(); //if (ip4_deaggregate(ipinta,ipintb,&subnets,&slen) <= 0) nomem(); mid = gethash(f[3].s,f[3].len); uid = gethash(f[4].s,f[4].len); //for (v = 0; v < slen; v++) { ipdb_key4build(keyloc,ipinta,(unsigned char )mask&0xff,mid,uid); //ipdb_key_from_uint(keyloc,ipinta,(unsigned char )mask&0xff,0,mid,uid); cdb_make_add(&cdb,keyloc,15,locp,4); //} uid = 0; //alloc_free(subnets); //subnets = NULL; //slen = 0; byte_zero(ipa,4);ipinta=0; //byte_zero(ipb,4);ipinta=0;ipintb=0; break; #endif case 'Z': if (!dns_domain_fromdot(&d1,f[0].s,f[0].len)) nomem(); if (!stralloc_0(&f[3])) nomem(); if (!scan_ulong(f[3].s,&u)) uint32_unpack_big(defaultsoa,&u); uint32_pack_big(soa,u); if (!stralloc_0(&f[4])) nomem(); if (!scan_ulong(f[4].s,&u)) uint32_unpack_big(defaultsoa + 4,&u); uint32_pack_big(soa + 4,u); if (!stralloc_0(&f[5])) nomem(); if (!scan_ulong(f[5].s,&u)) uint32_unpack_big(defaultsoa + 8,&u); uint32_pack_big(soa + 8,u); if (!stralloc_0(&f[6])) nomem(); if (!scan_ulong(f[6].s,&u)) uint32_unpack_big(defaultsoa + 12,&u); uint32_pack_big(soa + 12,u); if (!stralloc_0(&f[7])) nomem(); if (!scan_ulong(f[7].s,&u)) uint32_unpack_big(defaultsoa + 16,&u); uint32_pack_big(soa + 16,u); if (!stralloc_0(&f[8])) nomem(); if (!scan_ulong(f[8].s,&ttl)) ttl = TTL_NEGATIVE; ttdparse(&f[9],ttd); loc = gethash(f[10].s,f[10].len); mid = gethash(f[11].s,f[11].len); uid = gethash(f[12].s,f[12].len); rr_addloq(DNS_T_SOA,d1,loc,mid,uid); rr_start(DNS_T_SOA,ttl,ttd,loc); if (!dns_domain_fromdot(&d2,f[1].s,f[1].len)) nomem(); rr_addname(d2); if (!dns_domain_fromdot(&d2,f[2].s,f[2].len)) nomem(); rr_addname(d2); rr_add(soa,20); rr_finish(d1); break; case '.': case '&': if (!dns_domain_fromdot(&d1,f[0].s,f[0].len)) nomem(); if (!stralloc_0(&f[3])) nomem(); if (!scan_ulong(f[3].s,&ttl)) ttl = TTL_NS; ttdparse(&f[4],ttd); loc = gethash(f[5].s,f[5].len); mid = gethash(f[6].s,f[6].len); uid = gethash(f[7].s,f[7].len); if (!stralloc_0(&f[1])) nomem(); if (byte_chr(f[2].s,f[2].len,'.') >= f[2].len) { if (!stralloc_cats(&f[2],".ns.")) nomem(); if (!stralloc_catb(&f[2],f[0].s,f[0].len)) nomem(); } if (!dns_domain_fromdot(&d2,f[2].s,f[2].len)) nomem(); if (line.s[0] == '.') { rr_start(DNS_T_SOA,ttl ? TTL_NEGATIVE : 0,ttd,loc); rr_addloq(DNS_T_SOA,d1,loc,mid,uid); rr_addname(d2); rr_add("\12hostmaster",11); rr_addname(d1); rr_add(defaultsoa,20); rr_finish(d1); } rr_start(DNS_T_NS,ttl,ttd,loc); rr_addname(d2); rr_addloq(DNS_T_NS,d2,loc,mid,uid); rr_finish(d1); if (ip4_scan(f[1].s,ip)) { rr_start(DNS_T_A,ttl,ttd,loc); rr_addloq(DNS_T_A,d2,loc,mid,uid); rr_add(ip,4); rr_finish(d2); } break; case '+': case '=': if (!dns_domain_fromdot(&d1,f[0].s,f[0].len)) nomem(); if (!stralloc_0(&f[2])) nomem(); if (!scan_ulong(f[2].s,&ttl)) ttl = TTL_POSITIVE; ttdparse(&f[3],ttd); loc = gethash(f[4].s,f[4].len); mid = gethash(f[5].s,f[5].len); uid = gethash(f[6].s,f[6].len); if (!stralloc_0(&f[1])) nomem(); if (ip4_scan(f[1].s,ip)) { rr_addloq(DNS_T_A,d1,loc,mid,uid); rr_start(DNS_T_A,ttl,ttd,loc); //dbger("+addloq:d=%s,loc=%u,uid=%u,mid=%u",d1,loc,uid,mid); rr_add(ip,4); rr_finish(d1); if (line.s[0] == '=') { rr_addloq(DNS_T_PTR,d1,loc,mid,uid); //??????????????????/ TODO: checkthis dns_name4_domain(dptr,ip); rr_start(DNS_T_PTR,ttl,ttd,loc); rr_addname(d1); rr_finish(dptr); } } break; case '@': if (!dns_domain_fromdot(&d1,f[0].s,f[0].len)) nomem(); if (!stralloc_0(&f[4])) nomem(); if (!scan_ulong(f[4].s,&ttl)) ttl = TTL_POSITIVE; ttdparse(&f[5],ttd); loc = gethash(f[6].s,f[6].len); mid = gethash(f[7].s,f[7].len); uid = gethash(f[8].s,f[8].len); if (!stralloc_0(&f[1])) nomem(); if (byte_chr(f[2].s,f[2].len,'.') >= f[2].len) { if (!stralloc_cats(&f[2],".mx.")) nomem(); if (!stralloc_catb(&f[2],f[0].s,f[0].len)) nomem(); } if (!dns_domain_fromdot(&d2,f[2].s,f[2].len)) nomem(); if (!stralloc_0(&f[3])) nomem(); if (!scan_ulong(f[3].s,&u)) u = 0; rr_addloq(DNS_T_MX,d1,loc,mid,uid); rr_start(DNS_T_MX,ttl,ttd,loc); uint16_pack_big(buf,u); rr_add(buf,2); rr_addname(d2); rr_finish(d1); if (ip4_scan(f[1].s,ip)) { rr_addloq(DNS_T_A,d2,loc,mid,uid); rr_start(DNS_T_A,ttl,ttd,loc); rr_add(ip,4); rr_finish(d2); } break; case '^': case 'C': if (!dns_domain_fromdot(&d1,f[0].s,f[0].len)) nomem(); if (!dns_domain_fromdot(&d2,f[1].s,f[1].len)) nomem(); if (!stralloc_0(&f[2])) nomem(); if (!scan_ulong(f[2].s,&ttl)) ttl = TTL_POSITIVE; ttdparse(&f[3],ttd); loc = gethash(f[4].s,f[4].len); mid = gethash(f[5].s,f[5].len); uid = gethash(f[6].s,f[6].len); if (line.s[0] == 'C') { //rr_addloq(DNS_T_CNAME,d1,loc,mid,uid); //dbger("add loq for cname!"); rr_addloq(DNS_T_A,d1,loc,mid,uid); rr_addloq(DNS_T_CNAME,d1,loc,mid,uid); rr_start(DNS_T_CNAME,ttl,ttd,loc); } else { rr_addloq(DNS_T_PTR,d1,loc,mid,uid); rr_start(DNS_T_PTR,ttl,ttd,loc); } rr_addname(d2); rr_finish(d1); break; case '\'': if (!dns_domain_fromdot(&d1,f[0].s,f[0].len)) nomem(); if (!stralloc_0(&f[2])) nomem(); if (!scan_ulong(f[2].s,&ttl)) ttl = TTL_POSITIVE; ttdparse(&f[3],ttd); loc = gethash(f[4].s,f[4].len); mid = gethash(f[5].s,f[5].len); uid = gethash(f[6].s,f[6].len); rr_addloq(DNS_T_TXT,d1,loc,mid,uid); rr_start(DNS_T_TXT,ttl,ttd,loc); txtparse(&f[1]); i = 0; while (i < f[1].len) { k = f[1].len - i; if (k > 127) k = 127; ch = k; rr_add(&ch,1); rr_add(f[1].s + i,k); i += k; } rr_finish(d1); break; case ':': if (!dns_domain_fromdot(&d1,f[0].s,f[0].len)) nomem(); if (!stralloc_0(&f[3])) nomem(); if (!scan_ulong(f[3].s,&ttl)) ttl = TTL_POSITIVE; ttdparse(&f[4],ttd); loc = gethash(f[5].s,f[5].len); mid = gethash(f[6].s,f[6].len); uid = gethash(f[7].s,f[7].len); if (!stralloc_0(&f[1])) nomem(); scan_ulong(f[1].s,&u); uint16_pack_big(type,u); if (byte_equal(type,2,DNS_T_AXFR)) syntaxerror(": type AXFR prohibited"); if (byte_equal(type,2,"\0\0")) syntaxerror(": type 0 prohibited"); if (byte_equal(type,2,DNS_T_SOA)) syntaxerror(": type SOA prohibited"); if (byte_equal(type,2,DNS_T_NS)) syntaxerror(": type NS prohibited"); if (byte_equal(type,2,DNS_T_CNAME)) syntaxerror(": type CNAME prohibited"); if (byte_equal(type,2,DNS_T_PTR)) syntaxerror(": type PTR prohibited"); if (byte_equal(type,2,DNS_T_MX)) syntaxerror(": type MX prohibited"); txtparse(&f[2]); rr_addloq(type,d1,loc,mid,uid); rr_start(type,ttl,ttd,loc); rr_add(f[2].s,f[2].len); rr_finish(d1); break; default: dienow("error here: %s\n", line.s); syntaxerror(": unrecognized leading character"); } } if (cdb_make_finish(&cdb) == -1) die_datatmp(); if (fsync(fdcdb) == -1) die_datatmp(); if (close(fdcdb) == -1) die_datatmp(); /* NFS stupidity */ if (argc == 3) { if (rename(argv[1],argv[2]) == -1) strerr_die2sys(111,FATAL,"unable to move data.tmp to data.cdb: "); } else { if (rename("data.tmp","data.cdb") == -1) strerr_die2sys(111,FATAL,"unable to move data.tmp to data.cdb: "); } _exit(0); }
int main(int argc, char *argv[]) { int fddata = 0; unsigned int i = 0, j = 0, k = 0; unsigned long u = 0; unsigned long ttl = 0; char ch = 0; char *x = NULL; char ttd[8], loc[2]; char ip[4], type[2]; char soa[20], buf[4]; prog = strdup ((x = strrchr (argv[0], '/')) != NULL ? x + 1 : argv[0]); i = check_option (argc, argv); argv += i; argc -= i; umask(022); if ((fddata = open_read ("data")) == -1) err (-1, "could not open file `data'"); defaultsoa_init (fddata); buffer_init (&b, buffer_unixread, fddata, bspace, sizeof bspace); if ((fdcdb = open_trunc ("data.tmp")) == -1) err (-1, "could not create file `data.tmp'"); if (cdb_make_start (&cdb, fdcdb) == -1) err (-1, "could not create file `data.tmp'"); while (match) { linenum++; if (getln (&b, &line, &match, '\n') == -1) err (-1, "could not read line: %ld", linenum); while (line.len) { ch = line.s[line.len - 1]; if ((ch != ' ') && (ch != '\t') && (ch != '\n')) break; --line.len; } if (!line.len) continue; if (line.s[0] == '#') continue; if (line.s[0] == '-') continue; j = 1; for (i = 0; i < NUMFIELDS; i++) { if (j >= line.len) { if (!stralloc_copys (&f[i], "")) err (-1, "could not allocate enough memory"); } else { k = byte_chr (line.s + j, line.len - j, ':'); if (!stralloc_copyb (&f[i], line.s + j, k)) err (-1, "could not allocate enough memory"); j += k + 1; } } switch (line.s[0]) { case '%': locparse (&f[0], loc); if (!stralloc_copyb (&key, "\0%", 2)) err (-1, "could not allocate enough memory"); if (!stralloc_0 (&f[1])) err (-1, "could not allocate enough memory"); ipprefix_cat (&key, f[1].s); if (cdb_make_add(&cdb,key.s,key.len,loc,2) == -1) err (-1, "could not create file `data.tmp'"); break; case 'Z': if (!dns_domain_fromdot (&d1, f[0].s, f[0].len)) err (-1, "could not allocate enough memory"); if (!stralloc_0 (&f[3])) err (-1, "could not allocate enough memory"); if (!scan_ulong (f[3].s, &u)) uint32_unpack_big (defaultsoa, (uint32 *)&u); uint32_pack_big (soa, u); if (!stralloc_0 (&f[4])) err (-1, "could not allocate enough memory"); if (!scan_ulong (f[4].s, &u)) uint32_unpack_big (defaultsoa + 4, (uint32 *)&u); uint32_pack_big (soa + 4, u); if (!stralloc_0 (&f[5])) err (-1, "could not allocate enough memory"); if (!scan_ulong (f[5].s, &u)) uint32_unpack_big (defaultsoa + 8, (uint32 *)&u); uint32_pack_big (soa + 8, u); if (!stralloc_0 (&f[6])) err (-1, "could not allocate enough memory"); if (!scan_ulong (f[6].s, &u)) uint32_unpack_big (defaultsoa + 12, (uint32 *)&u); uint32_pack_big (soa + 12, u); if (!stralloc_0 (&f[7])) err (-1, "could not allocate enough memory"); if (!scan_ulong (f[7].s, &u)) uint32_unpack_big (defaultsoa + 16, (uint32 *)&u); uint32_pack_big (soa + 16, u); if (!stralloc_0 (&f[8])) err (-1, "could not allocate enough memory"); if (!scan_ulong(f[8].s,&ttl)) ttl = TTL_NEGATIVE; ttdparse (&f[9], ttd); locparse (&f[10], loc); rr_start (DNS_T_SOA, ttl, ttd, loc); if (!dns_domain_fromdot (&d2, f[1].s, f[1].len)) err (-1, "could not allocate enough memory"); rr_addname (d2); if (!dns_domain_fromdot (&d2, f[2].s, f[2].len)) err (-1, "could not allocate enough memory"); rr_addname (d2); rr_add (soa, 20); rr_finish (d1); break; case '.': case '&': if (!dns_domain_fromdot (&d1, f[0].s, f[0].len)) err (-1, "could not allocate enough memory"); if (!stralloc_0 (&f[3])) err (-1, "could not allocate enough memory"); if (!scan_ulong (f[3].s, &ttl)) ttl = TTL_NS; ttdparse (&f[4], ttd); locparse (&f[5], loc); if (!stralloc_0 (&f[1])) err (-1, "could not allocate enough memory"); if (byte_chr (f[2].s, f[2].len, '.') >= f[2].len) { if (!stralloc_cats (&f[2], ".ns.")) err (-1, "could not allocate enough memory"); if (!stralloc_catb (&f[2], f[0].s, f[0].len)) err (-1, "could not allocate enough memory"); } if (!dns_domain_fromdot (&d2, f[2].s, f[2].len)) err (-1, "could not allocate enough memory"); if (line.s[0] == '.') { rr_start (DNS_T_SOA, ttl ? TTL_NEGATIVE : 0, ttd, loc); rr_addname (d2); rr_add ("\12hostmaster", 11); rr_addname (d1); rr_add (defaultsoa, 20); rr_finish (d1); } rr_start (DNS_T_NS, ttl, ttd, loc); rr_addname (d2); rr_finish (d1); if (ip4_scan (f[1].s, ip)) { rr_start (DNS_T_A, ttl, ttd, loc); rr_add (ip, 4); rr_finish (d2); } break; case '+': case '=': if (!dns_domain_fromdot (&d1, f[0].s, f[0].len)) err (-1, "could not allocate enough memory"); if (!stralloc_0 (&f[2])) err (-1, "could not allocate enough memory"); if (!scan_ulong (f[2].s, &ttl)) ttl = TTL_POSITIVE; ttdparse (&f[3], ttd); locparse (&f[4], loc); if (!stralloc_0 (&f[1])) err (-1, "could not allocate enough memory"); if (ip4_scan (f[1].s, ip)) { rr_start (DNS_T_A, ttl, ttd, loc); rr_add (ip, 4); rr_finish (d1); if (line.s[0] == '=') { dns_name4_domain (dptr,ip); rr_start (DNS_T_PTR, ttl, ttd, loc); rr_addname (d1); rr_finish (dptr); } } break; case '@': if (!dns_domain_fromdot (&d1, f[0].s, f[0].len)) err (-1, "could not allocate enough memory"); if (!stralloc_0 (&f[4])) err (-1, "could not allocate enough memory"); if (!scan_ulong (f[4].s, &ttl)) ttl = TTL_POSITIVE; ttdparse (&f[5], ttd); locparse (&f[6], loc); if (!stralloc_0 (&f[1])) err (-1, "could not allocate enough memory"); if (byte_chr (f[2].s, f[2].len, '.') >= f[2].len) { if (!stralloc_cats (&f[2], ".mx.")) err (-1, "could not allocate enough memory"); if (!stralloc_catb (&f[2], f[0].s, f[0].len)) err (-1, "could not allocate enough memory"); } if (!dns_domain_fromdot (&d2, f[2].s, f[2].len)) err (-1, "could not allocate enough memory"); if (!stralloc_0 (&f[3])) err (-1, "could not allocate enough memory"); if (!scan_ulong (f[3].s, &u)) u = 0; rr_start (DNS_T_MX, ttl, ttd, loc); uint16_pack_big (buf, u); rr_add (buf, 2); rr_addname (d2); rr_finish (d1); if (ip4_scan (f[1].s, ip)) { rr_start (DNS_T_A, ttl, ttd, loc); rr_add (ip, 4); rr_finish (d2); } break; case '^': case 'C': if (!dns_domain_fromdot (&d1, f[0].s, f[0].len)) err (-1, "could not allocate enough memory"); if (!dns_domain_fromdot (&d2, f[1].s, f[1].len)) err (-1, "could not allocate enough memory"); if (!stralloc_0 (&f[2])) err (-1, "could not allocate enough memory"); if (!scan_ulong (f[2].s, &ttl)) ttl = TTL_POSITIVE; ttdparse (&f[3], ttd); locparse (&f[4], loc); if (line.s[0] == 'C') rr_start (DNS_T_CNAME, ttl, ttd, loc); else rr_start (DNS_T_PTR, ttl, ttd, loc); rr_addname (d2); rr_finish (d1); break; case '\'': if (!dns_domain_fromdot (&d1, f[0].s, f[0].len)) err (-1, "could not allocate enough memory"); if (!stralloc_0 (&f[2])) err (-1, "could not allocate enough memory"); if (!scan_ulong (f[2].s, &ttl)) ttl = TTL_POSITIVE; ttdparse (&f[3], ttd); locparse (&f[4], loc); rr_start (DNS_T_TXT, ttl, ttd, loc); txtparse (&f[1]); i = 0; while (i < f[1].len) { k = f[1].len - i; if (k > 127) k = 127; ch = k; rr_add (&ch, 1); rr_add (f[1].s + i, k); i += k; } rr_finish (d1); break; case ':': if (!dns_domain_fromdot (&d1, f[0].s, f[0].len)) err (-1, "could not allocate enough memory"); if (!stralloc_0 (&f[3])) err (-1, "could not allocate enough memory"); if (!scan_ulong (f[3].s, &ttl)) ttl = TTL_POSITIVE; ttdparse (&f[4], ttd); locparse (&f[5], loc); if (!stralloc_0 (&f[1])) err (-1, "could not allocate enough memory"); scan_ulong (f[1].s, &u); uint16_pack_big (type, u); if (byte_equal (type, 2, DNS_T_AXFR)) syntaxerror (": type AXFR prohibited"); if (byte_equal (type, 2, "\0\0")) syntaxerror (": type 0 prohibited"); if (byte_equal (type, 2, DNS_T_SOA)) syntaxerror (": type SOA prohibited"); if (byte_equal (type, 2, DNS_T_NS)) syntaxerror (": type NS prohibited"); if (byte_equal (type, 2, DNS_T_CNAME)) syntaxerror (": type CNAME prohibited"); if (byte_equal (type, 2, DNS_T_PTR)) syntaxerror (": type PTR prohibited"); if (byte_equal (type, 2, DNS_T_MX)) syntaxerror (": type MX prohibited"); txtparse (&f[2]); rr_start (type, ttl, ttd, loc); rr_add (f[2].s, f[2].len); rr_finish (d1); break; default: syntaxerror (": unrecognized leading character"); } } if (cdb_make_finish (&cdb) == -1) err (-1, "could not create file `data.tmp'"); if (fsync (fdcdb) == -1) err (-1, "could not create file `data.tmp'"); if (close (fdcdb) == -1) err (-1, "could not create file `data.tmp'"); /* NFS stupidity */ if (rename ("data.tmp", "data.cdb") == -1) err (-1, "could not move `data.tmp' to `data.cdb'"); return 0; }
int main(int argc,char **argv) { struct taia stamp; struct taia deadline; int opt; unsigned long u; int i; int j; int r; while ((opt = getopt(argc,argv,"c:l:")) != opteof) switch(opt) { case 'c': scan_ulong(optarg,&u); if (u < 1) u = 1; if (u > 1000) u = 1000; maxactive = u; break; case 'l': scan_ulong(optarg,&u); if (u < 1) u = 1; if (u > 1000000) u = 1000000; xmax = u; break; default: strerr_die1x(111,"dnsfilter: usage: dnsfilter [ -c concurrency ] [ -l lines ]"); } x = (struct line *) alloc(xmax * sizeof(struct line)); if (!x) nomem(); byte_zero(x,xmax * sizeof(struct line)); io = (iopause_fd *) alloc((xmax + 1) * sizeof(iopause_fd)); if (!io) nomem(); if (!stralloc_copys(&partial,"")) nomem(); while (flag0 || inbuflen || partial.len || xnum) { taia_now(&stamp); taia_uint(&deadline,120); taia_add(&deadline,&deadline,&stamp); iolen = 0; if (flag0) if (inbuflen < sizeof inbuf) { inio = io + iolen++; inio->fd = 0; inio->events = IOPAUSE_READ; } for (i = 0;i < xnum;++i) if (x[i].flagactive) { x[i].io = io + iolen++; dns_transmit_io(&x[i].dt,x[i].io,&deadline); } iopause(io,iolen,&deadline,&stamp); if (flag0) if (inbuflen < sizeof inbuf) if (inio->revents) { r = read(0,inbuf + inbuflen,(sizeof inbuf) - inbuflen); if (r <= 0) flag0 = 0; else inbuflen += r; } for (i = 0;i < xnum;++i) if (x[i].flagactive) { r = dns_transmit_get(&x[i].dt,x[i].io,&stamp); if (r == -1) { errout(i); x[i].flagactive = 0; --numactive; } else if (r == 1) { if (dns_name_packet(&x[i].middle,x[i].dt.packet,x[i].dt.packetlen) == -1) errout(i); if (x[i].middle.len) if (!stralloc_cats(&x[i].left,"=")) nomem(); x[i].flagactive = 0; --numactive; } } for (;;) { if (xnum && !x[0].flagactive) { buffer_put(buffer_1,x[0].left.s,x[0].left.len); buffer_put(buffer_1,x[0].middle.s,x[0].middle.len); buffer_put(buffer_1,x[0].right.s,x[0].right.len); buffer_flush(buffer_1); --xnum; tmp = x[0]; for (i = 0;i < xnum;++i) x[i] = x[i + 1]; x[xnum] = tmp; continue; } if ((xnum < xmax) && (numactive < maxactive)) { i = byte_chr(inbuf,inbuflen,'\n'); if (inbuflen && (i == inbuflen)) { if (!stralloc_catb(&partial,inbuf,inbuflen)) nomem(); inbuflen = 0; continue; } if ((i < inbuflen) || (!flag0 && partial.len)) { if (i < inbuflen) ++i; if (!stralloc_catb(&partial,inbuf,i)) nomem(); inbuflen -= i; for (j = 0;j < inbuflen;++j) inbuf[j] = inbuf[j + i]; if (partial.len) { i = byte_chr(partial.s,partial.len,'\n'); i = byte_chr(partial.s,i,'\t'); i = byte_chr(partial.s,i,' '); if (!stralloc_copyb(&x[xnum].left,partial.s,i)) nomem(); if (!stralloc_copys(&x[xnum].middle,"")) nomem(); if (!stralloc_copyb(&x[xnum].right,partial.s + i,partial.len - i)) nomem(); x[xnum].flagactive = 0; partial.len = i; if (!stralloc_0(&partial)) nomem(); if (ip4_scan(partial.s,ip)) { dns_name4_domain(name,ip); if (dns_resolvconfip(servers) == -1) strerr_die2sys(111,FATAL,"unable to read /etc/resolv.conf: "); if (dns_transmit_start(&x[xnum].dt,servers,1,name,DNS_T_PTR,"\0\0\0\0") == -1) errout(xnum); else { x[xnum].flagactive = 1; ++numactive; } } ++xnum; } partial.len = 0; continue; } } break; } } _exit(0); }