1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
|
#include <unistd.h>
#include "str.h"
#include "byte.h"
#include "ip4.h"
#include "open.h"
#include "env.h"
#include "cdb.h"
#include "dns.h"
#include "dd.h"
#include "strerr.h"
#include "response.h"
static char *base;
static struct cdb c;
static char key[5];
static char data[100 + IP4_FMT];
static int doit(char *q,char qtype[2])
{
int flaga;
int flagtxt;
char ch;
char reverseip[4];
char ip[4];
uint32 ipnum;
int r;
uint32 dlen;
int i;
flaga = byte_equal(qtype,2,DNS_T_A);
flagtxt = byte_equal(qtype,2,DNS_T_TXT);
if (byte_equal(qtype,2,DNS_T_ANY)) flaga = flagtxt = 1;
if (!flaga && !flagtxt) goto REFUSE;
if (dd(q,base,reverseip) != 4) goto REFUSE;
uint32_unpack(reverseip,&ipnum);
uint32_pack_big(ip,ipnum);
for (i = 0;i <= 24;++i) {
ipnum >>= i;
ipnum <<= i;
uint32_pack_big(key,ipnum);
key[4] = 32 - i;
r = cdb_find(&c,key,5);
if (r == -1) return 0;
if (r) break;
}
if (!r) { response_nxdomain(); return 1; }
r = cdb_find(&c,"",0);
if (r == -1) return 0;
if (r && ((dlen = cdb_datalen(&c)) >= 4)) {
if (dlen > 100) dlen = 100;
if (cdb_read(&c,data,dlen,cdb_datapos(&c)) == -1) return 0;
}
else {
dlen = 12;
byte_copy(data,dlen,"\177\0\0\2Listed $");
}
if ((dlen >= 5) && (data[dlen - 1] == '$')) {
--dlen;
dlen += ip4_fmt(data + dlen,ip);
}
if (flaga) {
if (!response_rstart(q,DNS_T_A,2048)) return 0;
if (!response_addbytes(data,4)) return 0;
response_rfinish(RESPONSE_ANSWER);
}
if (flagtxt) {
if (!response_rstart(q,DNS_T_TXT,2048)) return 0;
ch = dlen - 4;
if (!response_addbytes(&ch,1)) return 0;
if (!response_addbytes(data + 4,dlen - 4)) return 0;
response_rfinish(RESPONSE_ANSWER);
}
return 1;
REFUSE:
response[2] &= ~4;
response[3] &= ~15;
response[3] |= 5;
return 1;
}
int respond(char *q,char qtype[2],char ip[4])
{
int fd;
int result;
fd = open_read("data.cdb");
if (fd == -1) return 0;
cdb_init(&c,fd);
result = doit(q,qtype);
cdb_free(&c);
close(fd);
return result;
}
const char *fatal = "rbldns: fatal: ";
const char *starting = "starting rbldns\n";
void initialize(void)
{
char *x;
x = env_get("BASE");
if (!x)
strerr_die2x(111,fatal,"$BASE not set");
if (!dns_domain_fromdot(&base,x,str_len(x)))
strerr_die2x(111,fatal,"unable to parse $BASE");
}
|