int response_cname(const char *c,const char *d,uint32 ttl) { if (!response_rstart(c,DNS_T_CNAME,ttl)) return 0; if (!response_addname(d)) return 0; response_rfinish(RESPONSE_ANSWER); return 1; }
int response_cname(char *c,char *d) { if (!response_rstart(c,DNS_T_CNAME,"\0\0\0\0")) return 0; if (!response_addname(d)) return 0; response_rfinish(RESPONSE_ANSWER); return 1; }
int response_rstart(char *d,char type[2],char ttl[4]) { if (!response_addname(d)) return 0; if (!response_addbytes(type,2)) return 0; if (!response_addbytes(DNS_C_IN,2)) return 0; if (!response_addbytes(ttl,4)) return 0; if (!response_addbytes("\0\0",2)) return 0; dpos = response_len; return 1; }
int response_query(char *q,char qtype[2]) { response_len = 0; name_num = 0; if (!response_addbytes("\0\0\201\200\0\1\0\0\0\0\0\0",12)) return 0; if (!response_addname(q)) return 0; if (!response_addbytes(qtype,2)) return 0; if (!response_addbytes(DNS_C_IN,2)) return 0; tctarget = response_len; return 1; }
int response_rstart(const char *d,const char type[2],uint32 ttl) { char ttlstr[4]; if (!response_addname(d)) return 0; if (!response_addbytes(type,2)) return 0; if (!response_addbytes(DNS_C_IN,2)) return 0; if (flaghidettl) ttl = 0; uint32_pack_big(ttlstr,ttl); if (!response_addbytes(ttlstr,4)) return 0; if (!response_addbytes("\0\0",2)) return 0; dpos = response_len; return 1; }
int response_query (const char *q, const char qtype[2], const char qclass[2]) { response_len = name_num = 0; if (!response_addbytes ("\0\0\201\200\0\1\0\0\0\0\0\0", 12)) return 0; if (!response_addname (q)) return 0; if (!response_addbytes (qtype, 2)) return 0; if (!response_addbytes (qclass, 2)) return 0; tctarget = response_len; return 1; }
static int doname(void) { dpos = dns_packet_getname(data,dlen,dpos,&d1); if (!dpos) return 0; return response_addname(d1); }
static int doit(char *q,char qtype[2]) { unsigned int bpos; unsigned int anpos; unsigned int aupos; unsigned int arpos; char *control; char *wild; int flaggavesoa; int flagfound; int r; int flagns; int flagauthoritative; char x[20]; uint16 u16; char addr[8][4]; int addrnum; uint32 addrttl; int i; anpos = response_len; control = q; for (;;) { flagns = 0; flagauthoritative = 0; cdb_findstart(&c); while (r = find(control,0)) { if (r == -1) return 0; if (byte_equal(type,2,DNS_T_SOA)) flagauthoritative = 1; if (byte_equal(type,2,DNS_T_NS)) flagns = 1; } if (flagns) break; if (!*control) { /* q is not within our bailiwick */ flagfound = 0; if (byte_diff(lameip,4,"\0\0\0\0")) if (byte_equal(qtype,2,DNS_T_A) || byte_equal(qtype,2,DNS_T_ANY)) { if (!response_rstart(q,DNS_T_A,3600)) return 0; if (!response_addbytes(lameip,4)) return 0; response_rfinish(RESPONSE_ANSWER); flagfound = 1; } if (lamemx) if (byte_equal(qtype,2,DNS_T_MX) || byte_equal(qtype,2,DNS_T_ANY)) { if (!response_rstart(q,DNS_T_MX,3600)) return 0; if (!response_addbytes("\0\0",2)) return 0; if (!response_addname(lamemx)) return 0; response_rfinish(RESPONSE_ANSWER); flagfound = 1; } if (lametxt.len) if (byte_equal(qtype,2,DNS_T_TXT) || byte_equal(qtype,2,DNS_T_ANY)) { if (!response_rstart(q,DNS_T_TXT,3600)) return 0; if (!response_addbytes(lametxt.s,lametxt.len)) return 0; response_rfinish(RESPONSE_ANSWER); flagfound = 1; } if (flagfound) return 2; return 0; } control += *control; control += 1; } if (!flagauthoritative) { response[2] &= ~4; goto AUTHORITY; /* q is in a child zone */ } flaggavesoa = 0; flagfound = 0; wild = q; for (;;) { addrnum = 0; addrttl = 0; cdb_findstart(&c); while (r = find(wild,wild != q)) { if (r == -1) return 0; flagfound = 1; if (flaggavesoa && byte_equal(type,2,DNS_T_SOA)) continue; if (byte_diff(type,2,qtype) && byte_diff(qtype,2,DNS_T_ANY) && byte_diff(type,2,DNS_T_CNAME)) continue; if (byte_equal(type,2,DNS_T_A) && (dlen - dpos == 4)) { addrttl = ttl; i = dns_random(addrnum + 1); if (i < 8) { if ((i < addrnum) && (addrnum < 8)) byte_copy(addr[addrnum],4,addr[i]); byte_copy(addr[i],4,data + dpos); } if (addrnum < 1000000) ++addrnum; continue; } if (!response_rstart(q,type,ttl)) return 0; if (byte_equal(type,2,DNS_T_NS) || byte_equal(type,2,DNS_T_CNAME) || byte_equal(type,2,DNS_T_PTR)) { if (!doname()) return 0; } else if (byte_equal(type,2,DNS_T_MX)) { if (!dobytes(2)) return 0; if (!doname()) return 0; } else if (byte_equal(type,2,DNS_T_SOA)) { if (!doname()) return 0; if (!doname()) return 0; if (!dobytes(20)) return 0; flaggavesoa = 1; } else if (!response_addbytes(data + dpos,dlen - dpos)) return 0; response_rfinish(RESPONSE_ANSWER); } for (i = 0;i < addrnum;++i) if (i < 8) { if (!response_rstart(q,DNS_T_A,addrttl)) return 0; if (!response_addbytes(addr[i],4)) return 0; response_rfinish(RESPONSE_ANSWER); } if (flagfound) break; if (wild == control) break; if (!*wild) break; /* impossible */ wild += *wild; wild += 1; } if (!flagfound) response_nxdomain(); AUTHORITY: aupos = response_len; if (flagauthoritative && (aupos == anpos)) { cdb_findstart(&c); while (r = find(control,0)) { if (r == -1) return 0; if (byte_equal(type,2,DNS_T_SOA)) { if (!response_rstart(control,DNS_T_SOA,ttl)) return 0; if (!doname()) return 0; if (!doname()) return 0; if (!dobytes(20)) return 0; response_rfinish(RESPONSE_AUTHORITY); break; } } } else if (want(control,DNS_T_NS)) { cdb_findstart(&c); while (r = find(control,0)) { if (r == -1) return 0; if (byte_equal(type,2,DNS_T_NS)) { if (!response_rstart(control,DNS_T_NS,ttl)) return 0; if (!doname()) return 0; response_rfinish(RESPONSE_AUTHORITY); } } } arpos = response_len; bpos = anpos; while (bpos < arpos) { bpos = dns_packet_skipname(response,arpos,bpos); if (!bpos) return 0; bpos = dns_packet_copy(response,arpos,bpos,x,10); if (!bpos) return 0; if (byte_equal(x,2,DNS_T_NS) || byte_equal(x,2,DNS_T_MX)) { if (byte_equal(x,2,DNS_T_NS)) { if (!dns_packet_getname(response,arpos,bpos,&d1)) return 0; } else if (!dns_packet_getname(response,arpos,bpos + 2,&d1)) return 0; case_lowerb(d1,dns_domain_length(d1)); if (want(d1,DNS_T_A)) { cdb_findstart(&c); while (r = find(d1,0)) { if (r == -1) return 0; if (byte_equal(type,2,DNS_T_A)) { if (!response_rstart(d1,DNS_T_A,ttl)) return 0; if (!dobytes(4)) return 0; response_rfinish(RESPONSE_ADDITIONAL); } } } } uint16_unpack_big(x + 8,&u16); bpos += u16; } if (flagauthoritative && (response_len > 512)) { byte_zero(response + RESPONSE_ADDITIONAL,2); response_len = arpos; if (response_len > 512) { byte_zero(response + RESPONSE_AUTHORITY,2); response_len = aupos; } } return 1; }