summaryrefslogtreecommitdiffstats
path: root/lib/parse.c
diff options
context:
space:
mode:
authorJozsef Kadlecsik <kadlec@blackhole.kfki.hu>2011-05-15 12:04:19 +0200
committerJozsef Kadlecsik <kadlec@blackhole.kfki.hu>2011-05-15 12:04:19 +0200
commitbb4f6b818fe371b754abd61cffb97cb5145e8e1d (patch)
tree34fb558facd8bc4ca1f1cdda8cc62eb4fd929e6f /lib/parse.c
parent774c80b578172aa7797ea60264e8a929302d5e83 (diff)
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
Diffstat (limited to 'lib/parse.c')
-rw-r--r--lib/parse.c53
1 files changed, 50 insertions, 3 deletions
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)
@@ -974,6 +981,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
* @opt: option kind of the data