From bb4f6b818fe371b754abd61cffb97cb5145e8e1d Mon Sep 17 00:00:00 2001 From: Jozsef Kadlecsik Date: Sun, 15 May 2011 12:04:19 +0200 Subject: Support range for IPv4 at adding/deleting elements for hash:*net* types The range internally is converted to the network(s) equal to the range. Example: # ipset new test hash:net # ipset add test 10.2.0.0-10.2.1.12 # ipset list test Name: test Type: hash:net Header: family inet hashsize 1024 maxelem 65536 Size in memory: 16888 References: 0 Members: 10.2.1.12 10.2.1.0/29 10.2.0.0/24 10.2.1.8/30 --- lib/parse.c | 53 ++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 50 insertions(+), 3 deletions(-) (limited to 'lib/parse.c') diff --git a/lib/parse.c b/lib/parse.c index 0c15231..091fc6d 100644 --- a/lib/parse.c +++ b/lib/parse.c @@ -667,8 +667,15 @@ parse_ipaddr(struct ipset_session *session, char *saved = strdup(str); char *a, *tmp = saved; struct addrinfo *info; - enum ipset_opt copt = opt == IPSET_OPT_IP ? IPSET_OPT_CIDR - : IPSET_OPT_CIDR2; + enum ipset_opt copt, opt2; + + if (opt == IPSET_OPT_IP) { + copt = IPSET_OPT_CIDR; + opt2 = IPSET_OPT_IP_TO; + } else { + copt = IPSET_OPT_CIDR2; + opt2 = IPSET_OPT_IP2_TO; + } if (tmp == NULL) return ipset_err(session, @@ -691,7 +698,7 @@ parse_ipaddr(struct ipset_session *session, || !range) goto out; freeaddrinfo(info); - aerr = get_addrinfo(session, IPSET_OPT_IP_TO, a, &info, family); + aerr = get_addrinfo(session, opt2, a, &info, family); out: if (aerr != EINVAL) @@ -973,6 +980,46 @@ ipset_parse_ip4_single6(struct ipset_session *session, } +/** + * ipset_parse_ip4_net6 - parse IPv4|IPv6 address or address/cidr pattern + * @session: session structure + * @opt: option kind of the data + * @str: string to parse + * + * Parse string as an IPv4|IPv6 address or address/cidr pattern. For IPv4, + * address range is valid too. + * If family is not set yet in the data blob, INET is assumed. + * The values are stored in the data blob of the session. + * + * FIXME: if the hostname resolves to multiple addresses, + * the first one is used only. + * + * Returns 0 on success or a negative error code. + */ +int +ipset_parse_ip4_net6(struct ipset_session *session, + enum ipset_opt opt, const char *str) +{ + struct ipset_data *data; + uint8_t family; + + assert(session); + assert(opt == IPSET_OPT_IP || opt == IPSET_OPT_IP2); + assert(str); + + data = ipset_session_data(session); + family = ipset_data_family(data); + + if (family == AF_UNSPEC) { + family = AF_INET; + ipset_data_set(data, IPSET_OPT_FAMILY, &family); + } + + return family == AF_INET ? parse_ip(session, opt, str, IPADDR_ANY) + : ipset_parse_ipnet(session, opt, str); + +} + /** * ipset_parse_iptimeout - parse IPv4|IPv6 address and timeout * @session: session structure -- cgit v1.2.3