+static inline int blacklist_check_reply(struct BlacklistClient *blcptr, struct rb_sockaddr_storage *addr)
+{
+ struct Blacklist *blptr = blcptr->blacklist;
+ char ipaddr[HOSTIPLEN];
+ char *lastoctet;
+ rb_dlink_node *ptr;
+
+ /* XXX the below two checks might want to change at some point
+ * e.g. if IPv6 blacklists don't use 127.x.y.z or A records anymore
+ * --Elizabeth
+ */
+ if (addr->ss_family != AF_INET ||
+ memcmp(&((struct sockaddr_in *)addr)->sin_addr, "\177", 1))
+ goto blwarn;
+
+ /* No filters and entry found - thus positive match */
+ if (!rb_dlink_list_length(&blptr->filters))
+ return 1;
+
+ rb_inet_ntop_sock((struct sockaddr *)addr, ipaddr, sizeof(ipaddr));
+
+ /* Below will prolly have to change too if the above changes */
+ if ((lastoctet = strrchr(ipaddr, '.')) == NULL || *(++lastoctet) == '\0')
+ goto blwarn;
+
+ RB_DLINK_FOREACH(ptr, blcptr->blacklist->filters.head)
+ {
+ struct BlacklistFilter *filter = ptr->data;
+ char *cmpstr;
+
+ if (filter->type == BLACKLIST_FILTER_ALL)
+ cmpstr = ipaddr;
+ else if (filter->type == BLACKLIST_FILTER_LAST)
+ cmpstr = lastoctet;
+ else
+ {
+ sendto_realops_snomask(SNO_GENERAL, L_ALL,
+ "blacklist_check_reply(): Unknown filtertype (BUG!)");
+ continue;
+ }
+
+ if (strcmp(cmpstr, filter->filterstr) == 0)
+ /* Match! */
+ return 1;
+ }
+
+ return 0;
+blwarn:
+ if (blcptr->blacklist->lastwarning + 3600 < rb_current_time())
+ {
+ sendto_realops_snomask(SNO_GENERAL, L_ALL,
+ "Garbage reply from blacklist %s",
+ blcptr->blacklist->host);
+ blcptr->blacklist->lastwarning = rb_current_time();
+ }
+ return 0;
+}
+