djbdnscurve6 45
djbdnscurve6
Loading...
Searching...
No Matches
rbldns.c
Go to the documentation of this file.
1#include <unistd.h>
2#include "str.h"
3#include "byte.h"
4#include "ip.h"
5#include "open.h"
6#include "env.h"
7#include "cdbread.h"
8#include "dns.h"
9#include "dd.h"
10#include "response.h"
11#include "logmsg.h"
12#include "uint_t.h"
13#include "scan.h"
14
15#define WHO "rbldns"
16const char *fatal = "rbldns";
18
19static char *base;
20
21static struct cdb c;
22static char data[100 + IP6_FMT];
23
24static int doit(char *q,char qtype[2])
25{
26 int flaga;
27 int flaga4;
28 int flagtxt;
29 int flagip6;
30 char ch;
31 char reverseip4[4];
32 char reverseip6[16];
33 char ip4[4];
34 char ip5[16]; /* aehm */
35 char ip6[16];
36 uint32 ipnum4;
37 uint64 ipnum5; /* aehm */
38 struct uint128_t ipnum6;
39 uint32 dlen;
40 int r;
41 int i;
42 stralloc ipstring = {0};
43 stralloc tmp = {0};
44
45 flaga = byte_equal(qtype,2,DNS_T_A);
46 flaga4 = byte_equal(qtype,2,DNS_T_AAAA);
47 flagtxt = byte_equal(qtype,2,DNS_T_TXT);
48 if (byte_equal(qtype,2,DNS_T_ANY)) flaga = flaga4 = flagtxt = 1;
49 if (!(flaga || flaga4) && !flagtxt) goto REFUSE;
50
51 if (flaga || flagtxt) {
52 r = dd4(q,base,reverseip4);
53 if (r < 0) goto IPV6;
54 if (r != 4) goto REFUSE;
55 uint32_unpack(reverseip4,&ipnum4);
56 uint32_pack_big(ip4,ipnum4);
57 if (ip4_bytestring(&ipstring,ip4,32)) return 0;
58
59 for (i = 32; i > 0; --i) {
60 if (!stralloc_copys(&tmp,"")) return 0;
61 if (!stralloc_catb(&tmp,ipstring.s,i)) return 0;
62 r = cdb_find(&c,tmp.s,i);
63 if (r == -1) return 0;
64 if (r) goto BASE;
65 }
66 if (!r) { response_nxdomain(); return 1; }
67 }
68
69
70 IPV6:
71 if (flaga4 || flagtxt) {
72 flagip6 = 1;
73 if (dd6(q,base,reverseip6) != 16) goto REFUSE;
74
75 uint128_unpack(reverseip6,&ipnum6); // IPv6 incl. link token
76 uint128_pack_big(ip6,ipnum6);
77 if (ip6_bytestring(&ipstring,ip6,128)) return 0;
78 if (!stralloc_copys(&tmp,"^")) return 0;
79 if (!stralloc_catb(&tmp,ipstring.s,128)) return 0;
80 r = cdb_find(&c,tmp.s,129);
81 if (r) goto BASE;
82
83 uint64_unpack(reverseip6+8,&ipnum5); // IPv6 net-id only
84 uint64_pack_big(ip5,ipnum5);
85 if (ip6_bytestring(&ipstring,ip5,64)) return 0;
86
87 for (i = 64; i > 0; --i) {
88 if (!stralloc_copys(&tmp,"^")) return 0;
89 if (!stralloc_catb(&tmp,ipstring.s,i)) return 0;
90 r = cdb_find(&c,tmp.s,i);
91 if (r == -1) return 0;
92 if (r) goto BASE;
93 }
94 if (!r) { response_nxdomain(); return 1; }
95 }
96
97
98 BASE:
99 r = cdb_find(&c,"",0);
100 if (r == -1) return 0;
101 if (r && ((dlen = cdb_datalen(&c)) >= 4)) {
102 if (dlen > 256) dlen = 256;
103 if (cdb_read(&c,data,dlen,cdb_datapos(&c)) == -1) return 0;
104 }
105 else {
106 dlen = 12;
107 byte_copy(data,dlen,"\177\0\0\2Listed $");
108 }
109
110 if ((dlen >= 5) && (data[dlen - 1] == '$')) {
111 --dlen;
112 if (flagip6)
113 dlen += ip6_fmt(data + dlen,ip6);
114 else
115 dlen += ip4_fmt(data + dlen,ip4);
116 }
117
118 if (flaga) {
119 if (!response_rstart(q,DNS_T_A,2048)) return 0;
120 if (!response_addbytes(data,4)) return 0;
122 }
123 if (flaga4) {
124 if (!response_rstart(q,DNS_T_AAAA,2048)) return 0;
125 if (!response_addbytes(data,16)) return 0;
127 }
128 if (flagtxt) {
129 if (!response_rstart(q,DNS_T_TXT,2048)) return 0;
130 ch = dlen - 4;
131 if (!response_addbytes(&ch,1)) return 0;
132 if (!response_addbytes(data + 4,dlen - 4)) return 0;
134 }
135
136 return 1;
137
138
139 REFUSE:
140 response[2] &= ~4;
141 response[3] &= ~15;
142 response[3] |= 5;
143 return 1;
144}
145
146int respond(char *q,char qtype[2],char ip[16])
147{
148 int fd;
149 int result;
150
151 fd = open_read("data.cdb");
152 if (fd == -1) return 0;
153 cdb_init(&c,fd);
154 result = doit(q,qtype);
155 cdb_free(&c);
156 close(fd);
157 return result;
158}
159
160const char *starting = "starting rbldns ";
161
162void init_server(void)
163{
164 char *x;
165
166 x = env_get("BASE");
167 if (!x)
168 logmsg(WHO,111,ERROR,"$BASE not set");
169 if (dns_domain_fromdot(&base,x,str_len(x)) <= 0)
170 logmsg(WHO,111,FATAL,"unable to parse $BASE");
171}
int fd
Definition: axfr-get.c:103
unsigned int doit(char *buf, unsigned int len, unsigned int pos)
Definition: axfr-get.c:131
char data[32767]
Definition: axfrdns.c:130
char ip[16]
Definition: axfrdns.c:125
uint32 dlen
Definition: axfrdns.c:131
int dd6(const char *q, const char *base, char ip[16])
Definition: dd.c:40
int dd4(const char *q, const char *base, char ip[4])
Definition: dd.c:7
#define DNS_T_A
Definition: dns.h:56
#define DNS_T_ANY
Definition: dns.h:85
#define DNS_T_TXT
Definition: dns.h:63
#define DNS_T_AAAA
Definition: dns.h:67
int dns_domain_fromdot(char **out, const char *buf, unsigned int n)
Definition: dns_dfd.c:6
char ip6[16]
Definition: dnsfilter.c:51
struct line * x
char ip4[4]
Definition: dnsfilter.c:50
struct line tmp
Definition: dnsfilter.c:32
char * base
Definition: rbldns-conf.c:20
struct cdb_make cdb
Definition: rbldns-data.c:36
int respond(char *q, char qtype[2], char ip[16])
Definition: rbldns.c:146
int flagcurved
Definition: rbldns.c:17
const char * fatal
Definition: rbldns.c:16
void init_server(void)
Definition: rbldns.c:162
const char * starting
Definition: rbldns.c:160
#define WHO
Definition: rbldns.c:15
void response_rfinish(int)
Definition: response.c:89
int response_addbytes(const char *, unsigned int)
Definition: response.c:17
char response[]
Definition: response.c:6
int response_rstart(const char *, const char *, uint32)
#define RESPONSE_ANSWER
Definition: response.h:23
void response_nxdomain(void)
Definition: response.c:103