--- mod_access.c.ORIG	Fri May 17 20:33:08 2002
+++ mod_access.c	Sun Nov 10 19:22:00 2002
@@ -61,6 +61,7 @@
  * 
  * Module derived from code originally written by Rob McCool
  * 
+ * 'via' mods to handle RBL style dns lookup by blarson@blars.org
  */
 
 #include "apr_strings.h"
@@ -87,6 +88,7 @@
     T_ALL,
     T_IP,
     T_HOST,
+    T_VIA,
     T_FAIL
 };
 
@@ -158,8 +160,17 @@
     char msgbuf[120];
     apr_status_t rv;
 
-    if (strcasecmp(from, "from"))
-	return "allow and deny must be followed by 'from'";
+    if (!strcasecmp(from, "via")) {
+        if (strlen(where) > 80)
+	    return "'via' location limited to 80 characters";
+	a = (allowdeny *) apr_array_push(cmd->info ? d->allows : d->denys);
+        a->limited = cmd->limited;
+	a->type = T_VIA;
+	a->x.from = where;
+	return NULL;
+    }
+    else if (strcasecmp(from, "from"))
+	return "allow and deny must be followed by 'from' or 'via'";
 
     a = (allowdeny *) apr_array_push(cmd->info ? d->allows : d->denys);
     a->x.from = where;
@@ -236,6 +247,40 @@
 	return 0;
 }
 
+static int check_via(request_rec *r, const char *via_list)
+{
+    char hb[100];
+    char *ha, *s, *sb, *sc;
+
+/* take the network address, convert to ascii, reverse the order of
+ * the numbers, tack on the rbl-style list to search, add a period
+ * at the end if there isn't one already, and see if it's listed */
+/* perhaps caching results would be a good idea */
+
+    ha = r->connection->remote_ip;
+    s = ha + strlen(ha);
+    sb = hb;
+    while (--s != ha) {
+        if (*s == '.') {
+	    sc = s;
+	    while (*++sc != '.' && *sc) *sb++ = *sc;
+	    *sb++ = '.';
+	}
+    }
+    sc = s;
+    while (*sc != '.' && *sc) *sb++ = *sc++;
+    *sb++ = '.';
+    sc = (char *)via_list;
+    while (*sb++ = *sc++) ;
+    if (sb[-2] != '.') {
+	sb[-1] = '.';
+	*sb = '\0';
+    }
+    ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_DEBUG, 0, r,
+		  "looking up %s\n", hb);
+    return gethostbyname(hb) != NULL;
+}
+
 static int find_allowdeny(request_rec *r, apr_array_header_t *a, int method)
 {
 
@@ -279,6 +324,11 @@
 	    }
 
 	    if ((gothost == 2) && in_domain(ap[i].x.from, remotehost))
+		return 1;
+	    break;
+
+	case T_VIA:
+	    if (check_via(r, ap[i].x.from))
 		return 1;
 	    break;
 
