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'.
7 +An expression of the form `n.n.n.n/m\' is interpreted as a
8 +`net/prefixlen\' pair, as below, for IPv4 addresses.
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
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 */
21 /* Global variables. */
25 @@ -14,6 +14,8 @@ static char sccsic[] = "@(#) misc.c 1.2
26 #include <arpa/inet.h>
34 @@ -85,3 +87,22 @@ char *str;
36 return (runs == 4 ? inet_addr(str) : INADDR_NONE);
39 +/* prefix_to_netmask - convert prefix (0-32) to netmask */
41 +unsigned long prefix_to_netmask(str)
44 + unsigned long prefix;
47 + if (!isdigit(str[0]))
50 + prefix = strtoul(str, &endptr, 10);
51 + if ((endptr == str) || (*endptr != '\0') || (prefix > 32))
54 + return htonl(~0UL << (32 - prefix));
59 @@ -345,7 +345,12 @@ char *string;
60 if ((addr = dot_quad_addr(string)) == INADDR_NONE)
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() */