004-ipv4_prefix.patch (2362B)
1 --- a/hosts_access.5 2 +++ b/hosts_access.5 3 @@ -90,6 +90,9 @@ bitwise AND of the address and the `mask 4 pattern `131.155.72.0/255.255.254.0' matches every address in the 5 range `131.155.72.0' through `131.155.73.255'. 6 .IP \(bu 7 +An expression of the form `n.n.n.n/m\' is interpreted as a 8 +`net/prefixlen\' pair, as below, for IPv4 addresses. 9 +.IP \(bu 10 A string that begins with a `/' character is treated as a file 11 name. A host name or address is matched if it matches any host name 12 or address pattern listed in the named file. The file format is 13 --- a/tcpd.h 14 +++ b/tcpd.h 15 @@ -93,6 +93,7 @@ extern void refuse __P((struct request_i 16 extern char *xgets __P((char *, int, FILE *)); /* fgets() on steroids */ 17 extern char *split_at __P((char *, int)); /* strchr() and split */ 18 extern unsigned long dot_quad_addr __P((char *)); /* restricted inet_addr() */ 19 +extern unsigned long prefix_to_netmask __P((char *)); /* 0-32 prefix length */ 20 21 /* Global variables. */ 22 23 --- a/misc.c 24 +++ b/misc.c 25 @@ -14,6 +14,8 @@ static char sccsic[] = "@(#) misc.c 1.2 26 #include <arpa/inet.h> 27 #include <stdio.h> 28 #include <string.h> 29 +#include <ctype.h> 30 +#include <stdlib.h> 31 32 #include "tcpd.h" 33 34 @@ -85,3 +87,22 @@ char *str; 35 } 36 return (runs == 4 ? inet_addr(str) : INADDR_NONE); 37 } 38 + 39 +/* prefix_to_netmask - convert prefix (0-32) to netmask */ 40 + 41 +unsigned long prefix_to_netmask(str) 42 +char *str; 43 +{ 44 + unsigned long prefix; 45 + char *endptr; 46 + 47 + if (!isdigit(str[0])) 48 + return INADDR_NONE; 49 + 50 + prefix = strtoul(str, &endptr, 10); 51 + if ((endptr == str) || (*endptr != '\0') || (prefix > 32)) 52 + return INADDR_NONE; 53 + 54 + return htonl(~0UL << (32 - prefix)); 55 +} 56 + 57 --- a/hosts_access.c 58 +++ b/hosts_access.c 59 @@ -345,7 +345,12 @@ char *string; 60 if ((addr = dot_quad_addr(string)) == INADDR_NONE) 61 return (NO); 62 if ((net = dot_quad_addr(net_tok)) == INADDR_NONE 63 - || (mask = dot_quad_addr(mask_tok)) == INADDR_NONE) { 64 + || ((mask = dot_quad_addr(mask_tok)) == INADDR_NONE 65 + && strcmp(mask_tok, "255.255.255.255") 66 + && (mask = prefix_to_netmask(mask_tok)) == INADDR_NONE 67 + && strcmp(mask_tok, "32"))) { 68 + /* 255.255.255.255 == INADDR_NONE, separate check needed. TJ. */ 69 + /* 32 == INADDR_NONE, separate check needed. philipp */ 70 tcpd_warn("bad net/mask expression: %s/%s", net_tok, mask_tok); 71 return (NO); /* not tcpd_jump() */ 72 }