[MINOR] implement acl_parse_ip and acl_match_ip

The ACL can now compare IP addresses. The client's IP address
can be checked.
diff --git a/include/proto/acl.h b/include/proto/acl.h
index 19642b4..86cbe74 100644
--- a/include/proto/acl.h
+++ b/include/proto/acl.h
@@ -118,6 +118,13 @@
 /* Parse a string. It is allocated and duplicated. */
 int acl_parse_str(const char *text, struct acl_pattern *pattern);
 
+/* Parse an IP address and an optional mask in the form addr[/mask].
+ * The addr may either be an IPv4 address or a hostname. The mask
+ * may either be a dotted mask or a number of bits. Returns 1 if OK,
+ * otherwise 0.
+ */
+int acl_parse_ip(const char *text, struct acl_pattern *pattern);
+
 /* Checks that the pattern matches the end of the tested string. */
 int acl_match_end(struct acl_test *test, struct acl_pattern *pattern);
 
@@ -139,6 +146,9 @@
  */
 int acl_match_dom(struct acl_test *test, struct acl_pattern *pattern);
 
+/* Check that the IPv4 address in <test> matches the IP/mask in pattern */
+int acl_match_ip(struct acl_test *test, struct acl_pattern *pattern);
+
 #endif /* _PROTO_ACL_H */
 
 /*
diff --git a/include/types/acl.h b/include/types/acl.h
index 229ea63..31f30fa 100644
--- a/include/types/acl.h
+++ b/include/types/acl.h
@@ -74,7 +74,10 @@
 	union {
 		int i;                          /* integer value */
 		struct { int min, max; } range; /* integer range */
-		struct sockaddr_in ipv4;        /* IPv4 address */
+		struct {
+			struct in_addr addr;
+			struct in_addr mask;
+		} ipv4;                         /* IPv4 address */
 		struct acl_time time;           /* valid hours and days */
 	} val;                                  /* direct value */
 	union {
diff --git a/src/acl.c b/src/acl.c
index 2912f08..e5d7594 100644
--- a/src/acl.c
+++ b/src/acl.c
@@ -172,6 +172,19 @@
 	return 0;
 }
 
+int acl_match_ip(struct acl_test *test, struct acl_pattern *pattern)
+{
+	struct in_addr *s;
+
+	if (test->i != AF_INET)
+		return 0;
+
+	s = (void *)test->ptr;
+	if (((s->s_addr ^ pattern->val.ipv4.addr.s_addr) & pattern->val.ipv4.mask.s_addr) == 0)
+		return 1;
+	return 0;
+}
+
 /* Parse a string. It is allocated and duplicated. */
 int acl_parse_str(const char *text, struct acl_pattern *pattern)
 {
@@ -222,6 +235,16 @@
 	return 1;
 }
 
+/* Parse an IP address and an optional mask in the form addr[/mask].
+ * The addr may either be an IPv4 address or a hostname. The mask
+ * may either be a dotted mask or a number of bits. Returns 1 if OK,
+ * otherwise 0.
+ */
+int acl_parse_ip(const char *text, struct acl_pattern *pattern)
+{
+	return str2net(text, &pattern->val.ipv4.addr, &pattern->val.ipv4.mask);
+}
+
 /*
  * Registers the ACL keyword list <kwl> as a list of valid keywords for next
  * parsing sessions.
diff --git a/src/client.c b/src/client.c
index 113708e..b947cd9 100644
--- a/src/client.c
+++ b/src/client.c
@@ -489,8 +489,8 @@
 /* Note: must not be declared <const> as its list will be overwritten */
 static struct acl_kw_list acl_kws = {{ },{
 	{ "src_port",   acl_parse_range, acl_fetch_sport,  acl_match_range },
-#if 0
 	{ "src",        acl_parse_ip,    acl_fetch_src,    acl_match_ip    },
+#if 0
 	{ "dst",        acl_parse_ip,    acl_fetch_dst,    acl_match_ip    },
 
 	{ "dst_port",   acl_parse_range, acl_fetch_dport,  acl_match_range },