readers.conf ignores specified IPv6 prefixes

Antonio Querubin tony at lava.net
Thu Mar 21 21:34:45 UTC 2002


On Sun, 17 Mar 2002, Russ Allbery wrote:

> Antonio Querubin <tony at lava.net> writes:
>
> > Just wanted to report a problem with the way the current snapshot
> > handles (or doesn't) specified IPv6 prefixes.
>
> > If an IPv6 prefix is specified in readers.conf, it disconnects
> > immediately for IPv6 connections and generates a 502 error:
>
> Known incompleteness of the existing implementation; see doc/IPv6-info.
> Patches welcome if you feel like coding this.  :)

Attached is a patch for nnrpd/perm.c to fix the above problem.

I also notice from the doc that the bindaddress/sourceaddress6 parameters
don't work either.  I'll try to take a look at that as well.


-- Attached file included as plaintext by Ecartis --
-- File: perm.c.diff

--- nnrpd/perm.c.orig	Sun Mar 17 00:00:49 2002
+++ nnrpd/perm.c	Thu Mar 21 11:18:00 2002
@@ -1640,9 +1640,6 @@
     *cpto = '\0';
 }
 
-/* FIXME - MatchHost is totally unaware of IPv6 yet, but it should be not
-   too much work to make it so.  I think.  -lutchann */
-
 static bool MatchHost(char *hostlist, char *host, char *ip)
 {
     char    **list;
@@ -1676,26 +1673,54 @@
 	if (!ret && *ip) {
 	    ret = wildmat(ip, pat);
 	    if (!ret && (p = strchr(pat, '/')) != (char *)NULL) {
-		unsigned int bits, c;
+		unsigned int bits, c, b;
 		struct in_addr ia, net, tmp;
+#ifdef HAVE_INET6
+		struct in6_addr ia6, net6;
+		uint8_t	bits8;
+#endif
 		unsigned int mask;
 
 		*p = '\0';
                 if (inet_aton(ip, &ia) && inet_aton(pat, &net)) {
 		    if (strchr(p+1, '.') == (char *)NULL) {
+			/* string following / is a masklength */
 			mask = atoi(p+1);
 			for (bits = c = 0; c < mask && c < 32; c++)
 			    bits |= (1 << (31 - c));
 			mask = htonl(bits);
-		    } else {
+		    } else {	/* or it may be a dotted quad bitmask */
                         if (inet_aton(p+1, &tmp))
                             mask = tmp.s_addr;
-                        else
+                        else	/* otherwise skip it */
                             continue;
 		    }
 		    if ((ia.s_addr & mask) == (net.s_addr & mask))
 			ret = TRUE;
 		}
+#ifdef HAVE_INET6
+                else if (inet_pton(AF_INET6, ip, &ia6) && 
+			 inet_pton(AF_INET6, pat, &net6)) {
+		    mask = atoi(p+1);
+		    ret = TRUE;
+		    /* do a prefix match byte by byte */
+		    for (c = 0; c*8 < mask && c < sizeof(ia6); c++) {
+			if ( (c+1)*8 <= mask &&
+			    ia6.s6_addr[c] != net6.s6_addr[c] ) {
+			    ret = FALSE;
+			    break;
+			} else if ( (c+1)*8 > mask ) {
+			    for (bits8 = b = 0; b < mask && b < 8; b++)
+				bits8 |= (1 << (7 - b));
+			    if ((ia6.s6_addr[c] & bits8) !=
+			    	(net6.s6_addr[c] & bits8) ) {
+				ret = FALSE;
+				break;
+			    }
+			}
+		    }
+		}
+#endif
 	    }
         }
 	if (ret)



More information about the inn-bugs mailing list