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