]>
jfr.im git - irc/quakenet/newserv.git/blob - rbl/rbl_zonefile.c
3 #include "../core/hooks.h"
4 #include "../control/control.h"
5 #include "../irc/irc.h"
6 #include "../lib/irc_string.h"
7 #include "../lib/version.h"
8 #include "../core/config.h"
9 #include "rbl_zonefile.h"
13 static int rbl_zf_cmpip(const struct irc_in_addr
*a
, const struct irc_in_addr
*b
) {
14 for (int i
= 0; i
< 8; i
++) {
15 if (ntohs(a
->in6_16
[i
]) < ntohs(b
->in6_16
[i
]))
17 else if (ntohs(a
->in6_16
[i
]) > ntohs(b
->in6_16
[i
]))
24 static int rbl_zf_bsearch(array
*entries
, struct irc_in_addr
*ip
, char *message
, size_t msglen
) {
28 last
= entries
->cursi
- 1;
29 mid
= (first
+ last
) / 2;
31 while (first
<= last
) {
32 rbl_zf_entry
*ze
= &((rbl_zf_entry
*)entries
->content
)[mid
];
34 if (rbl_zf_cmpip(&ze
->ipaddress
, ip
) < 0 && !ipmask_check(&ze
->ipaddress
, ip
, ze
->bits
))
36 else if (ipmask_check(&ze
->ipaddress
, ip
, ze
->bits
)) {
39 strncpy(message
, ze
->message
->content
, msglen
);
48 mid
= (first
+ last
) / 2;
54 static int rbl_zf_lookup(rbl_instance
*rbl
, struct irc_in_addr
*ip
, char *message
, size_t msglen
) {
55 rbl_zf_udata
*udata
= rbl
->udata
;
57 if (rbl_zf_bsearch(&udata
->whitelist
, ip
, NULL
, 0) > 0)
60 return rbl_zf_bsearch(&udata
->blacklist
, ip
, message
, msglen
);
63 static void rbl_zf_freeentries(array
*entries
) {
67 for (i
= 0; i
< entries
->cursi
; i
++) {
68 ze
= &((rbl_zf_entry
*)entries
->content
)[i
];
69 freesstring(ze
->message
);
74 static int rbl_zf_parseentry(rbl_instance
*rbl
, const char *line
) {
75 rbl_zf_udata
*udata
= rbl
->udata
;
77 char mask
[255], message
[255];
78 struct irc_in_addr ip
;
82 if (line
[0] == '$' || line
[0] == ':')
83 return 0; /* Ignore option lines */
92 if (sscanf(line
, "%s %[^\n]", mask
, message
) < 1)
95 if (!ipmask_parse(mask
, &ip
, &bits
))
99 slot
= array_getfreeslot(&udata
->whitelist
);
100 ze
= &((rbl_zf_entry
*)udata
->whitelist
.content
)[slot
];
102 slot
= array_getfreeslot(&udata
->blacklist
);
103 ze
= &((rbl_zf_entry
*)udata
->blacklist
.content
)[slot
];
106 memcpy(&ze
->ipaddress
, &ip
, sizeof(ip
));
109 ze
->message
= getsstring(message
, 255);
114 static int rbl_zf_cmpentry(const void *a
, const void *b
) {
115 const rbl_zf_entry
*za
= a
;
116 const rbl_zf_entry
*zb
= b
;
118 return rbl_zf_cmpip(&za
->ipaddress
, &zb
->ipaddress
);
121 static int rbl_zf_refresh(rbl_instance
*rbl
) {
123 rbl_zf_udata
*udata
= rbl
->udata
;
124 FILE *fp
= fopen(udata
->file
->content
, "r");
129 rbl_zf_freeentries(&udata
->whitelist
);
130 array_init(&udata
->whitelist
, sizeof(rbl_zf_entry
));
132 rbl_zf_freeentries(&udata
->blacklist
);
133 array_init(&udata
->blacklist
, sizeof(rbl_zf_entry
));
136 if (fgets(line
, sizeof(line
), fp
) == NULL
)
139 if (line
[strlen(line
) - 1] == '\n')
140 line
[strlen(line
) - 1] = '\0';
142 if (line
[strlen(line
) - 1] == '\r')
143 line
[strlen(line
) - 1] = '\0';
146 rbl_zf_parseentry(rbl
, line
);
151 qsort(udata
->whitelist
.content
, udata
->whitelist
.cursi
, sizeof(rbl_zf_entry
), rbl_zf_cmpentry
);
152 qsort(udata
->blacklist
.content
, udata
->blacklist
.cursi
, sizeof(rbl_zf_entry
), rbl_zf_cmpentry
);
157 static void rbl_zf_dtor(rbl_instance
*rbl
) {
158 rbl_zf_udata
*udata
= rbl
->udata
;
159 freesstring(udata
->file
);
160 rbl_zf_freeentries(&udata
->whitelist
);
161 rbl_zf_freeentries(&udata
->blacklist
);
164 static rbl_ops rbl_zonefile_ops
= {
165 .lookup
= rbl_zf_lookup
,
166 .refresh
= rbl_zf_refresh
,
170 int rbl_zf_load(const char *name
, const char *file
) {
171 rbl_zf_udata
*udata
= malloc(sizeof(*udata
));
172 udata
->file
= getsstring(file
, 512);
173 array_init(&udata
->whitelist
, sizeof(rbl_zf_entry
));
174 array_init(&udata
->blacklist
, sizeof(rbl_zf_entry
));
175 return registerrbl(name
, &rbl_zonefile_ops
, udata
);
181 zfiles
= getconfigitems("rbl_zonefile", "zone");
183 Error("rbl_zonefile", ERR_INFO
, "No zonefiles added.");
185 sstring
**files
= (sstring
**)(zfiles
->content
);
187 for(i
=0;i
<zfiles
->cursi
;i
++) {
191 strncpy(line
, files
[i
]->content
, sizeof(line
));
193 pos
= strchr(line
, ',');
196 Error("rbl_zonefile", ERR_INFO
, "RBL zonefile line is missing zone path: %s", line
);
202 if (rbl_zf_load(line
, pos
+ 1) < 0)
203 Error("rbl_zonefile", ERR_WARNING
, "Failed to load zonefile: %s", pos
+ 1);
209 deregisterrblbyops(&rbl_zonefile_ops
);