Blob Blame History Raw
--- tcp_wrappers_7.6/hosts_access.5.orig	2011-04-20 16:10:25.000000000 -0600
+++ tcp_wrappers_7.6/hosts_access.5	2011-04-20 16:29:50.000000000 -0600
@@ -90,6 +90,9 @@ bitwise AND of the address and the `mask
 pattern `131.155.72.0/255.255.254.0\' matches every address in the
 range `131.155.72.0\' through `131.155.73.255\'.
 .IP \(bu
+An expression of the form `n.n.n.n/m\' is interpreted as a
+`net/prefixlen\' pair, as below, for IPv4 addresses.
+.IP \(bu
 An expression of the form `[n:n:n:n:n:n:n:n/m]\' is interpreted as a
 `[net/prefixlen]\' pair. An IPv6 host address is matched if
 `prefixlen\' bits of `net\' is equal to the `prefixlen\' bits of the
--- tcp_wrappers_7.6/tcpd.h.orig	2011-04-20 16:10:25.000000000 -0600
+++ tcp_wrappers_7.6/tcpd.h	2011-04-20 16:11:56.000000000 -0600
@@ -164,6 +164,7 @@ extern void refuse __P((struct request_i
 extern char *xgets __P((char *, int, FILE *));			/* fgets() on steroids */
 extern char *split_at __P((char *, int));		/* strchr() and split */
 extern unsigned long dot_quad_addr __P((char *));	/* restricted inet_addr() */
+extern unsigned long prefix_to_netmask __P((char *)); /* 0-32 prefix length */
 extern int numeric_addr __P((char *, union gen_addr *, int *, int *));		/* IP4/IP6 inet_addr (restricted) */
 extern struct hostent *tcpd_gethostbyname __P((char *, int));
 					/* IP4/IP6 gethostbyname */
--- tcp_wrappers_7.6/misc.c.orig	2011-04-20 16:10:25.000000000 -0600
+++ tcp_wrappers_7.6/misc.c	2011-04-20 16:13:39.000000000 -0600
@@ -16,6 +16,7 @@ static char sccsic[] = "@(#) misc.c 1.2
 #include <string.h>
 #include <ctype.h>
 #include <netdb.h>
+#include <stdlib.h>
 
 #include "tcpd.h"
 
@@ -214,3 +215,21 @@ char *str;
     }
 }
 #endif /* HAVE_IPV6 */
+
+/* prefix_to_netmask - convert prefix (0-32) to netmask */
+
+unsigned long prefix_to_netmask(str)
+char   *str;
+{
+    unsigned long prefix;
+    char *endptr;
+
+    if (!isdigit(str[0]))
+	return INADDR_NONE;
+
+    prefix = strtoul(str, &endptr, 10);
+    if ((endptr == str) || (*endptr != '\0') || (prefix > 32))
+	return INADDR_NONE;
+
+    return htonl(~0UL << (32 - prefix));
+}
--- tcp_wrappers_7.6/hosts_access.c.orig	2011-04-20 16:10:25.000000000 -0600
+++ tcp_wrappers_7.6/hosts_access.c	2011-04-20 16:21:07.000000000 -0600
@@ -420,8 +420,11 @@ char   *string;
 	return (NO);
     if ((net = dot_quad_addr(net_tok)) == INADDR_NONE
 	|| ((mask = dot_quad_addr(mask_tok)) == INADDR_NONE
-	    && strcmp(mask_tok, "255.255.255.255"))) {
+	    && strcmp(mask_tok, "255.255.255.255")
+	    && (mask = prefix_to_netmask(mask_tok)) == INADDR_NONE
+	    && strcmp(mask_tok, "32"))) {
 	/* 255.255.255.255 == INADDR_NONE, separate check needed. TJ. */
+	/* 32 == INADDR_NONE, separate check needed. philipp */
 	tcpd_warn("bad net/mask expression: %s/%s", net_tok, mask_tok);
 	return (NO);				/* not tcpd_jump() */
     }