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