--- 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 @@ -101,6 +101,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 */ /* Global variables. */ --- 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 @@ -107,3 +107,22 @@ char *str; } return (runs == 4 ? inet_addr(str) : INADDR_NONE); } + +/* 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 (~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 @@ -427,8 +427,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 */ #ifndef INET6 tcpd_warn("bad net/mask expression: %s/%s", net_tok, mask_tok); #endif