From a67fad9d68482dd03f920bd6e262ea190a1ab182 Mon Sep 17 00:00:00 2001 From: Willy Tarreau Date: Tue, 8 May 2007 19:50:09 +0200 Subject: [PATCH] [MINOR] implement acl_parse_ip and acl_match_ip The ACL can now compare IP addresses. The client's IP address can be checked. --- include/proto/acl.h | 10 ++++++++++ include/types/acl.h | 5 ++++- src/acl.c | 23 +++++++++++++++++++++++ src/client.c | 2 +- 4 files changed, 38 insertions(+), 2 deletions(-) diff --git a/include/proto/acl.h b/include/proto/acl.h index 19642b4191..86cbe74ff5 100644 --- a/include/proto/acl.h +++ b/include/proto/acl.h @@ -118,6 +118,13 @@ int acl_parse_range(const char *text, struct acl_pattern *pattern); /* 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_dir(struct acl_test *test, struct acl_pattern *pattern); */ int acl_match_dom(struct acl_test *test, struct acl_pattern *pattern); +/* Check that the IPv4 address in 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 229ea6335f..31f30fa13b 100644 --- a/include/types/acl.h +++ b/include/types/acl.h @@ -74,7 +74,10 @@ struct acl_pattern { 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 2912f082ad..e5d7594ea7 100644 --- a/src/acl.c +++ b/src/acl.c @@ -172,6 +172,19 @@ int acl_match_max(struct acl_test *test, struct acl_pattern *pattern) 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 @@ int acl_parse_range(const char *text, struct acl_pattern *pattern) 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 as a list of valid keywords for next * parsing sessions. diff --git a/src/client.c b/src/client.c index 113708efd0..b947cd9920 100644 --- a/src/client.c +++ b/src/client.c @@ -489,8 +489,8 @@ static int acl_fetch_dconn(struct proxy *px, struct session *l4, void *l7, void /* Note: must not be declared 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 }, -- 2.47.2