summaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorJozsef Kadlecsik <kadlec@blackhole.kfki.hu>2010-06-15 13:30:55 +0200
committerJozsef Kadlecsik <kadlec@blackhole.kfki.hu>2010-06-15 13:30:55 +0200
commit3fd6b24ace319b139ec3c4e3031a5f05d21e304e (patch)
treee6ac952e95fa44968196149e0172b1ef13e8236f /lib
parent00bcb2b40450eca4c7ad785bf85b12692e8d29af (diff)
ipset 5 in an almost ready state - milestonev5.0-pre1
Reworked protocol and internal interfaces, missing set types added, backward compatibility verified, lots of tests added (and thanks to the tests, bugs fixed), even the manpage is rewritten ;-). Countless changes everywhere... The missing bits before announcing ipset 5: - net namespace support - new iptables/ip6tables extension library - iptables/ip6tables match and target tests (backward/forward compatibility) - tests on catching syntax errors
Diffstat (limited to 'lib')
-rw-r--r--lib/Makefile.am4
-rw-r--r--lib/PROTOCOL6
-rw-r--r--lib/data.c67
-rw-r--r--lib/mnl.c2
-rw-r--r--lib/parse.c449
-rw-r--r--lib/print.c27
-rw-r--r--lib/session.c98
-rw-r--r--lib/types.c58
-rw-r--r--lib/utils.c103
9 files changed, 535 insertions, 279 deletions
diff --git a/lib/Makefile.am b/lib/Makefile.am
index 74b6651..bf4e133 100644
--- a/lib/Makefile.am
+++ b/lib/Makefile.am
@@ -12,9 +12,7 @@ libipset_la_SOURCES = \
parse.c \
print.c \
session.c \
- types.c \
- utils.c
-
+ types.c
#%.o: %.c
# ${AM_VERBOSE_CC} ${CC} ${AM_DEPFLAGS} ${AM_CFLAGS} ${CFLAGS} -o $@ -c $<
diff --git a/lib/PROTOCOL b/lib/PROTOCOL
index e1a139e..6f07445 100644
--- a/lib/PROTOCOL
+++ b/lib/PROTOCOL
@@ -33,7 +33,11 @@ req: msg: IPSET_CMD_LIST|SAVE
attr: IPSET_ATTR_PROTOCOL
IPSET_ATTR_SETNAME (optional)
-resp: attr: IPSET_ATTR_DATA
+resp: attr: IPSET_ATTR_SETNAME
+ IPSET_ATTR_TYPENAME
+ IPSET_ATTR_REVISION
+ IPSET_ATTR_FAMILY
+ IPSET_ATTR_DATA
create-specific-data
IPSET_ATTR_ADT
IPSET_ATTR_DATA
diff --git a/lib/data.c b/lib/data.c
index 0de91a1..f8ff4a9 100644
--- a/lib/data.c
+++ b/lib/data.c
@@ -12,6 +12,7 @@
#include <string.h> /* memset */
#include <libipset/linux_ip_set.h> /* IPSET_MAXNAMELEN */
+#include <libipset/debug.h> /* D() */
#include <libipset/types.h> /* struct ipset_type */
#include <libipset/utils.h> /* inXcpy */
#include <libipset/data.h> /* prototypes */
@@ -26,13 +27,16 @@
struct ipset_data {
/* Option bits: which fields are set */
uint64_t bits;
+ /* Option bits: which options are ignored */
+ uint64_t ignored;
/* Setname */
char setname[IPSET_MAXNAMELEN];
const struct ipset_type *type;
/* Common CADT options */
uint8_t cidr;
uint8_t family;
- uint32_t flags;
+ uint32_t flags; /* command level flags */
+ uint32_t cadt_flags; /* data level flags */
uint32_t timeout;
union nf_inet_addr ip;
union nf_inet_addr ip_to;
@@ -79,6 +83,25 @@ copy_addr(uint8_t family, union nf_inet_addr *ip, const void *value)
}
/**
+ * ipset_strncpy - copy the string from src to dst
+ * @dst: the target string buffer
+ * @src: the source string buffer
+ * @len: the length of bytes to copy, including the terminating null byte.
+ *
+ * Copy the string from src to destination, but at most len bytes are
+ * copied. The target is unconditionally terminated by the null byte.
+ */
+void
+ipset_strncpy(char *dst, const char *src, size_t len)
+{
+ assert(dst);
+ assert(src);
+
+ strncpy(dst, src, len);
+ dst[len - 1] = '\0';
+}
+
+/**
* ipset_data_flags_test - test option bits in the data blob
* @data: data blob
* @flags: the option flags to test
@@ -122,13 +145,38 @@ ipset_data_flags_unset(struct ipset_data *data, uint64_t flags)
data->bits &= ~flags;
}
-#define flag_type_attr(data, opt, flag) \
-do { \
- data->flags |= (1 << flag); \
- opt = IPSET_OPT_FLAGS; \
+#define flag_type_attr(data, opt, flag) \
+do { \
+ data->flags |= flag; \
+ opt = IPSET_OPT_FLAGS; \
+} while (0)
+
+#define cadt_flag_type_attr(data, opt, flag) \
+do { \
+ data->cadt_flags |= flag; \
+ opt = IPSET_OPT_CADT_FLAGS; \
} while (0)
/**
+ * ipset_data_ignored - test and set ignored bits in the data blob
+ * @data: data blob
+ * @flags: the option flags which is ignored
+ *
+ * Returns true if the option was not already ignored.
+ */
+bool
+ipset_data_ignored(struct ipset_data *data, enum ipset_opt opt)
+{
+ bool ignored;
+ assert(data);
+
+ ignored = data->ignored & IPSET_FLAG(opt);
+ data->ignored |= IPSET_FLAG(opt);
+
+ return ignored;
+}
+
+/**
* ipset_data_set - put data into the data blob
* @data: data blob
* @opt: the option kind of the data
@@ -249,11 +297,14 @@ ipset_data_set(struct ipset_data *data, enum ipset_opt opt, const void *value)
flag_type_attr(data, opt, IPSET_FLAG_EXIST);
break;
case IPSET_OPT_BEFORE:
- flag_type_attr(data, opt, IPSET_FLAG_BEFORE);
+ cadt_flag_type_attr(data, opt, IPSET_FLAG_BEFORE);
break;
case IPSET_OPT_FLAGS:
data->flags = *(const uint32_t *)value;
break;
+ case IPSET_OPT_CADT_FLAGS:
+ data->cadt_flags = *(const uint32_t *)value;
+ break;
default:
return -1;
};
@@ -351,8 +402,10 @@ ipset_data_get(const struct ipset_data *data, enum ipset_opt opt)
/* flags */
case IPSET_OPT_FLAGS:
case IPSET_OPT_EXIST:
- case IPSET_OPT_BEFORE:
return &data->flags;
+ case IPSET_OPT_CADT_FLAGS:
+ case IPSET_OPT_BEFORE:
+ return &data->cadt_flags;
default:
return NULL;
}
diff --git a/lib/mnl.c b/lib/mnl.c
index 5662a47..8056427 100644
--- a/lib/mnl.c
+++ b/lib/mnl.c
@@ -8,8 +8,10 @@
#include <errno.h> /* errno */
#include <stdlib.h> /* calloc, free */
#include <time.h> /* time */
+#include <arpa/inet.h> /* hto* */
#include <libipset/linux_ip_set.h> /* enum ipset_cmd */
+#include <libipset/debug.h> /* D() */
#include <libipset/session.h> /* ipset_session_handle */
#include <libipset/ui.h> /* IPSET_ENV_EXIST */
#include <libipset/utils.h> /* UNUSED */
diff --git a/lib/parse.c b/lib/parse.c
index 0e0e7f1..e347c69 100644
--- a/lib/parse.c
+++ b/lib/parse.c
@@ -13,6 +13,7 @@
#include <sys/socket.h> /* getaddrinfo, AF_ */
#include <net/ethernet.h> /* ETH_ALEN */
+#include <libipset/debug.h> /* D() */
#include <libipset/data.h> /* IPSET_OPT_* */
#include <libipset/pfxlen.h> /* prefixlen_netmask_map */
#include <libipset/session.h> /* ipset_err */
@@ -22,14 +23,31 @@
/* Parse input data */
-#define ipset_cidr_separator(str) ipset_strchr(str, IPSET_CIDR_SEPARATOR)
-#define ipset_range_separator(str) ipset_strchr(str, IPSET_RANGE_SEPARATOR)
-#define ipset_elem_separator(str) ipset_strchr(str, IPSET_ELEM_SEPARATOR)
-#define ipset_name_separator(str) ipset_strchr(str, IPSET_NAME_SEPARATOR)
+#define cidr_separator(str) ipset_strchr(str, IPSET_CIDR_SEPARATOR)
+#define range_separator(str) ipset_strchr(str, IPSET_RANGE_SEPARATOR)
+#define elem_separator(str) ipset_strchr(str, IPSET_ELEM_SEPARATOR)
+#define name_separator(str) ipset_strchr(str, IPSET_NAME_SEPARATOR)
#define syntax_err(fmt, args...) \
ipset_err(session, "Syntax error: " fmt , ## args)
+static char *
+ipset_strchr(const char *str, const char *sep)
+{
+ char *match;
+
+ assert(str);
+ assert(sep);
+
+ for (; *sep != '\0'; sep++)
+ if ((match = strchr(str, (int)sep[0])) != NULL
+ && str[0] != sep[0]
+ && str[strlen(str)-1] != sep[0])
+ return match;
+
+ return NULL;
+}
+
/*
* Parser functions, shamelessly taken from iptables.c, ip6tables.c
* and parser.c from libnetfilter_conntrack.
@@ -70,33 +88,53 @@ string_to_number_ll(struct ipset_session *session,
}
static int
-string_to_number_l(struct ipset_session *session,
- const char *str,
- unsigned long min,
- unsigned long max,
- unsigned long *ret)
+string_to_u8(struct ipset_session *session,
+ const char *str, uint8_t *ret)
{
int err;
- unsigned long long number = 0;
+ unsigned long long num = 0;
- err = string_to_number_ll(session, str, min, max, &number);
- *ret = (unsigned long) number;
+ err = string_to_number_ll(session, str, 0, 255, &num);
+ *ret = (uint8_t) num;
return err;
}
static int
-string_to_number(struct ipset_session *session,
- const char *str,
- unsigned int min,
- unsigned int max,
- unsigned int *ret)
+string_to_cidr(struct ipset_session *session,
+ const char *str, uint8_t min, uint8_t max, uint8_t *ret)
+{
+ int err = string_to_u8(session, str, ret);
+
+ if (!err && (*ret < min || *ret > max))
+ return syntax_err("'%s' is out of range %u-%u",
+ str, min, max);
+
+ return err;
+}
+
+static int
+string_to_u16(struct ipset_session *session,
+ const char *str, uint16_t *ret)
+{
+ int err;
+ unsigned long long num = 0;
+
+ err = string_to_number_ll(session, str, 0, USHRT_MAX, &num);
+ *ret = (uint16_t) num;
+
+ return err;
+}
+
+static int
+string_to_u32(struct ipset_session *session,
+ const char *str, uint32_t *ret)
{
int err;
- unsigned long number = 0;
+ unsigned long long num = 0;
- err = string_to_number_l(session, str, min, max, &number);
- *ret = (unsigned int) number;
+ err = string_to_number_ll(session, str, 0, UINT_MAX, &num);
+ *ret = (uint32_t) num;
return err;
}
@@ -161,12 +199,6 @@ parse_portname(struct ipset_session *session, const char *str, uint16_t *port)
return syntax_err("cannot parse '%s' as a (TCP) port", str);
}
-static int
-parse_portnum(struct ipset_session *session, const char *str, uint16_t *port)
-{
- return string_to_number(session, str, 0, 65535, (unsigned int *)port);
-}
-
/**
* ipset_parse_single_port - parse a single (TCP) port number or name
* @session: session structure
@@ -189,7 +221,7 @@ ipset_parse_single_port(struct ipset_session *session,
assert(opt == IPSET_OPT_PORT || opt == IPSET_OPT_PORT_TO);
assert(str);
- if ((err = parse_portnum(session, str, &port)) == 0
+ if ((err = string_to_u16(session, str, &port)) == 0
|| (err = parse_portname(session, str, &port)) == 0)
err = ipset_session_data_set(session, opt, &port);
@@ -229,7 +261,7 @@ ipset_parse_port(struct ipset_session *session,
"Cannot allocate memory to duplicate %s.",
str);
- a = ipset_range_separator(tmp);
+ a = range_separator(tmp);
if (a != NULL) {
/* port-port */
*a++ = '\0';
@@ -256,14 +288,20 @@ error:
* Returns 0 on success or a negative error code.
*/
int
-ipset_parse_family(struct ipset_session *session, int opt, const char *str)
+ipset_parse_family(struct ipset_session *session,
+ enum ipset_opt opt, const char *str)
{
+ struct ipset_data *data;
uint8_t family;
assert(session);
assert(opt == IPSET_OPT_FAMILY);
assert(str);
+ data = ipset_session_data(session);
+ if (ipset_data_flags_test(data, IPSET_FLAG(IPSET_OPT_FAMILY)))
+ syntax_err("protocol family may not be specified multiple times");
+
if (STREQ(str, "inet") || STREQ(str, "ipv4") || STREQ(str, "-4"))
family = AF_INET;
else if (STREQ(str, "inet6") || STREQ(str, "ipv6") || STREQ(str, "-6"))
@@ -273,7 +311,7 @@ ipset_parse_family(struct ipset_session *session, int opt, const char *str)
else
return syntax_err("unknown INET family %s", str);
- return ipset_session_data_set(session, opt, &family);
+ return ipset_data_set(data, opt, &family);
}
/*
@@ -316,8 +354,8 @@ get_addrinfo##f(struct ipset_session *session, \
int found; \
\
if ((*info = get_addrinfo(session, str, family)) == NULL) { \
- syntax_err("cannot parse %s: resolving " \
- IP " failed", str); \
+ syntax_err("cannot parse %s: " IP " resolving failed", \
+ str); \
return EINVAL; \
} \
\
@@ -347,7 +385,7 @@ static int \
parse_ipv##f(struct ipset_session *session, \
enum ipset_opt opt, const char *str) \
{ \
- unsigned int m = mask; \
+ uint8_t m = mask; \
int aerr = EINVAL, err = 0, range = 0; \
char *saved = strdup(str); \
char *a, *tmp = saved; \
@@ -361,14 +399,14 @@ parse_ipv##f(struct ipset_session *session, \
return ipset_err(session, \
"Cannot allocate memory to duplicate %s.",\
str); \
- if ((a = ipset_cidr_separator(tmp)) != NULL) { \
+ if ((a = cidr_separator(tmp)) != NULL) { \
/* IP/mask */ \
*a++ = '\0'; \
\
- if ((err = string_to_number(session, a, 0, m, &m)) != 0 \
+ if ((err = string_to_cidr(session, a, 0, m, &m)) != 0 \
|| (err = ipset_data_set(data, copt, &m)) != 0) \
goto out; \
- } else if ((a = ipset_range_separator(tmp)) != NULL) { \
+ } else if ((a = range_separator(tmp)) != NULL) { \
/* IP-IP */ \
*a++ = '\0'; \
D("range %s", a); \
@@ -420,17 +458,17 @@ parse_ip(struct ipset_session *session,
switch (addrtype) {
case IPADDR_PLAIN:
- if (ipset_range_separator(str) || ipset_cidr_separator(str))
+ if (range_separator(str) || cidr_separator(str))
return syntax_err("plain IP address must be supplied: %s",
str);
break;
case IPADDR_NET:
- if (!ipset_cidr_separator(str) || ipset_range_separator(str))
+ if (!cidr_separator(str) || range_separator(str))
return syntax_err("IP/netblock must be supplied: %s",
str);
break;
case IPADDR_RANGE:
- if (!ipset_range_separator(str) || ipset_cidr_separator(str))
+ if (!range_separator(str) || cidr_separator(str))
return syntax_err("IP-IP range must supplied: %s",
str);
break;
@@ -539,7 +577,7 @@ ipset_parse_range(struct ipset_session *session,
enum ipset_opt opt, const char *str)
{
assert(session);
- assert(opt == IPSET_OPT_IP);
+ assert(opt == IPSET_OPT_IP || opt == IPSET_OPT_IP2);
assert(str);
return parse_ip(session, IPSET_OPT_IP, str, IPADDR_RANGE);
@@ -563,15 +601,118 @@ ipset_parse_netrange(struct ipset_session *session,
enum ipset_opt opt, const char *str)
{
assert(session);
- assert(opt == IPSET_OPT_IP);
+ assert(opt == IPSET_OPT_IP || opt == IPSET_OPT_IP2);
assert(str);
- if (!(ipset_range_separator(str) || ipset_cidr_separator(str)))
- return syntax_err("IP/net or IP-IP range must be specified: %s",
+ if (!(range_separator(str) || cidr_separator(str)))
+ return syntax_err("IP/cidr or IP-IP range must be specified: %s",
str);
return parse_ip(session, opt, str, IPADDR_ANY);
}
+/**
+ * ipset_parse_iprange - parse IPv4|IPv6 address or range
+ * @session: session structure
+ * @opt: option kind of the data
+ * @str: string to parse
+ *
+ * Parse string as an IPv4|IPv6 address pattern or a range
+ * of addresses separated by a dash. If family is not set yet in
+ * the data blob, INET is assumed.
+ * The value is stored in the data blob of the session.
+ *
+ * Returns 0 on success or a negative error code.
+ */
+int
+ipset_parse_iprange(struct ipset_session *session,
+ enum ipset_opt opt, const char *str)
+{
+ assert(session);
+ assert(opt == IPSET_OPT_IP || opt == IPSET_OPT_IP2);
+ assert(str);
+
+ if (cidr_separator(str))
+ return syntax_err("IP address or IP-IP range must be specified: %s",
+ str);
+ return parse_ip(session, opt, str, IPADDR_ANY);
+}
+
+/**
+ * ipset_parse_ipnet - 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.
+ * If family is not set yet in the data blob, INET is assumed.
+ * The value is stored in the data blob of the session.
+ *
+ * Returns 0 on success or a negative error code.
+ */
+int
+ipset_parse_ipnet(struct ipset_session *session,
+ enum ipset_opt opt, const char *str)
+{
+ assert(session);
+ assert(opt == IPSET_OPT_IP || opt == IPSET_OPT_IP2);
+ assert(str);
+
+ if (range_separator(str))
+ return syntax_err("IP address or IP/cidr must be specified: %s",
+ str);
+ return parse_ip(session, opt, str, IPADDR_ANY);
+}
+
+/**
+ * ipset_parse_iptimeout - parse IPv4|IPv6 address and timeout
+ * @session: session structure
+ * @opt: option kind of the data
+ * @str: string to parse
+ *
+ * Parse string as an IPv4|IPv6 address and timeout parameter.
+ * If family is not set yet in the data blob, INET is assumed.
+ * The value is stored in the data blob of the session.
+ *
+ * Compatibility parser.
+ *
+ * Returns 0 on success or a negative error code.
+ */
+int
+ipset_parse_iptimeout(struct ipset_session *session,
+ enum ipset_opt opt, const char *str)
+{
+ char *tmp, *saved, *a;
+ int err;
+
+ assert(session);
+ assert(opt == IPSET_OPT_IP);
+ assert(str);
+
+ /* IP,timeout */
+ if (ipset_data_flags_test(ipset_session_data(session),
+ IPSET_FLAG(IPSET_OPT_TIMEOUT)))
+ return syntax_err("mixed syntax, timeout already specified");
+
+ tmp = saved = strdup(str);
+ if (saved == NULL)
+ return ipset_err(session,
+ "Cannot allocate memory to duplicate %s.",
+ str);
+
+ a = elem_separator(tmp);
+ if (a == NULL) {
+ free(saved);
+ return syntax_err("Missing separator from %s", str);
+ }
+ *a++ = '\0';
+ err = parse_ip(session, opt, tmp, IPADDR_ANY);
+ if (!err)
+ err = ipset_parse_uint32(session, IPSET_OPT_TIMEOUT, a);
+
+ free(saved);
+ return err;
+}
+
#define check_setname(str, saved) \
do { \
if (strlen(str) > IPSET_MAXNAMELEN - 1) { \
@@ -584,7 +725,7 @@ do { \
/**
- * ipset_parse_name - parse setname as element
+ * ipset_parse_name_compat - parse setname as element
* @session: session structure
* @opt: option kind of the data
* @str: string to parse
@@ -597,8 +738,8 @@ do { \
* Returns 0 on success or a negative error code.
*/
int
-ipset_parse_name(struct ipset_session *session,
- enum ipset_opt opt, const char *str)
+ipset_parse_name_compat(struct ipset_session *session,
+ enum ipset_opt opt, const char *str)
{
char *saved;
char *a = NULL, *b = NULL, *tmp;
@@ -607,25 +748,22 @@ ipset_parse_name(struct ipset_session *session,
struct ipset_data *data;
assert(session);
- assert(opt == IPSET_OPT_NAME || opt == IPSET_OPT_SETNAME2);
+ assert(opt == IPSET_OPT_NAME);
assert(str);
data = ipset_session_data(session);
- if (opt == IPSET_OPT_SETNAME2) {
- check_setname(str, NULL);
-
- return ipset_data_set(data, opt, str);
- }
+ if (ipset_data_flags_test(data, IPSET_FLAG(IPSET_OPT_NAMEREF)))
+ syntax_err("mixed syntax, before|after option already used");
tmp = saved = strdup(str);
if (saved == NULL)
return ipset_err(session,
"Cannot allocate memory to duplicate %s.",
str);
- if ((a = ipset_elem_separator(tmp)) != NULL) {
+ if ((a = elem_separator(tmp)) != NULL) {
/* setname,[before|after,setname */
*a++ = '\0';
- if ((b = ipset_elem_separator(a)) != NULL)
+ if ((b = elem_separator(a)) != NULL)
*b++ = '\0';
if (b == NULL
|| !(STREQ(a, "before") || STREQ(a, "after"))) {
@@ -644,7 +782,7 @@ ipset_parse_name(struct ipset_session *session,
if ((err = ipset_data_set(data,
IPSET_OPT_NAMEREF, b)) != 0)
goto out;
-
+
if (before)
err = ipset_data_set(data, IPSET_OPT_BEFORE, &before);
@@ -654,12 +792,12 @@ out:
}
/**
- * ipset_parse_setname - parse name as the name of the (current) set
+ * ipset_parse_setname - parse string as a setname
* @session: session structure
* @opt: option kind of the data
* @str: string to parse
*
- * Parse string as the name of the (current) set.
+ * Parse string as a setname.
* The value is stored in the data blob of the session.
*
* Returns 0 on success or a negative error code.
@@ -669,7 +807,9 @@ ipset_parse_setname(struct ipset_session *session,
enum ipset_opt opt, const char *str)
{
assert(session);
- assert(opt == IPSET_SETNAME);
+ assert(opt == IPSET_SETNAME
+ || opt == IPSET_OPT_NAME
+ || opt == IPSET_OPT_SETNAME2);
assert(str);
check_setname(str, NULL);
@@ -678,6 +818,67 @@ ipset_parse_setname(struct ipset_session *session,
}
/**
+ * ipset_parse_before - parse string as "before" reference setname
+ * @session: session structure
+ * @opt: option kind of the data
+ * @str: string to parse
+ *
+ * Parse string as a "before" reference setname for list:set
+ * type of sets. The value is stored in the data blob of the session.
+ *
+ * Returns 0 on success or a negative error code.
+ */
+int
+ipset_parse_before(struct ipset_session *session,
+ enum ipset_opt opt, const char *str)
+{
+ struct ipset_data *data;
+
+ assert(session);
+ assert(opt == IPSET_OPT_NAMEREF);
+ assert(str);
+
+ data = ipset_session_data(session);
+ if (ipset_data_flags_test(data, IPSET_FLAG(IPSET_OPT_NAMEREF)))
+ syntax_err("mixed syntax, before|after option already used");
+
+ check_setname(str, NULL);
+ ipset_data_set(data, IPSET_OPT_BEFORE, str);
+
+ return ipset_data_set(data, opt, str);
+}
+
+/**
+ * ipset_parse_after - parse string as "after" reference setname
+ * @session: session structure
+ * @opt: option kind of the data
+ * @str: string to parse
+ *
+ * Parse string as a "after" reference setname for list:set
+ * type of sets. The value is stored in the data blob of the session.
+ *
+ * Returns 0 on success or a negative error code.
+ */
+int
+ipset_parse_after(struct ipset_session *session,
+ enum ipset_opt opt, const char *str)
+{
+ struct ipset_data *data;
+
+ assert(session);
+ assert(opt == IPSET_OPT_NAMEREF);
+ assert(str);
+
+ data = ipset_session_data(session);
+ if (ipset_data_flags_test(data, IPSET_FLAG(IPSET_OPT_NAMEREF)))
+ syntax_err("mixed syntax, before|after option already used");
+
+ check_setname(str, NULL);
+
+ return ipset_data_set(data, opt, str);
+}
+
+/**
* ipset_parse_uint32 - parse string as an unsigned integer
* @session: session structure
* @opt: option kind of the data
@@ -698,7 +899,7 @@ ipset_parse_uint32(struct ipset_session *session,
assert(session);
assert(str);
- if ((err = string_to_number(session, str, 0, 0, &value)) == 0)
+ if ((err = string_to_u32(session, str, &value)) == 0)
return ipset_session_data_set(session, opt, &value);
return err;
@@ -719,13 +920,13 @@ int
ipset_parse_uint8(struct ipset_session *session,
enum ipset_opt opt, const char *str)
{
- unsigned int value;
+ uint8_t value;
int err;
assert(session);
assert(str);
- if ((err = string_to_number(session, str, 0, 255, &value)) == 0)
+ if ((err = string_to_u8(session, str, &value)) == 0)
return ipset_session_data_set(session, opt, &value);
return err;
@@ -747,7 +948,7 @@ int
ipset_parse_netmask(struct ipset_session *session,
enum ipset_opt opt, const char *str)
{
- unsigned int family, cidr;
+ uint8_t family, cidr;
struct ipset_data *data;
int err = 0;
@@ -762,10 +963,10 @@ ipset_parse_netmask(struct ipset_session *session,
ipset_data_set(data, IPSET_OPT_FAMILY, &family);
}
- err = string_to_number(session, str,
- family == AF_INET ? 1 : 4,
- family == AF_INET ? 31 : 124,
- &cidr);
+ err = string_to_cidr(session, str,
+ family == AF_INET ? 1 : 4,
+ family == AF_INET ? 31 : 124,
+ &cidr);
if (err)
return syntax_err("netmask is out of the inclusive range "
@@ -864,15 +1065,72 @@ ipset_parse_output(struct ipset_session *session,
return syntax_err("unkown output mode '%s'", str);
}
+/**
+ * ipset_parse_ignored - "parse" ignored option
+ * @session: session structure
+ * @opt: option kind of the data
+ * @str: string to parse
+ *
+ * Ignore deprecated options. A single warning is generated
+ * for every ignored opton.
+ *
+ * Returns 0.
+ */
+int
+ipset_parse_ignored(struct ipset_session *session,
+ enum ipset_opt opt, const char *str)
+{
+ assert(session);
+ assert(str);
+
+ if (!ipset_data_ignored(ipset_session_data(session), opt))
+ ipset_warn(session,
+ "Option %s is ignored. Please upgrade your syntax.", str);
+
+ return 0;
+}
+
+/**
+ * ipset_call_parser - call a parser function
+ * @session: session structure
+ * @parsefn: parser function
+ * @optstr: option name
+ * @opt: option kind of the data
+ * @str: string to parse
+ *
+ * Wrapper to call the parser functions so that ignored options
+ * are handled properly.
+ *
+ * Returns 0 on success or a negative error code.
+ */
+int
+ipset_call_parser(struct ipset_session *session,
+ ipset_parsefn parse, const char *optstr,
+ enum ipset_opt opt, const char *str)
+{
+ if (ipset_data_flags_test(ipset_session_data(session),
+ IPSET_FLAG(opt)))
+ syntax_err("%s already specified", optstr);
+
+ return parse(session, opt, parse == ipset_parse_ignored
+ ? optstr : str);
+}
+
#define parse_elem(s, t, d, str) \
do { \
- if (!t->elem[d].parse) \
+ if (!(t)->elem[d].parse) \
goto internal; \
- err = t->elem[d].parse(s, t->elem[d].opt, str); \
- if (err) \
+ ret = (t)->elem[d].parse(s, (t)->elem[d].opt, str); \
+ if (ret) \
goto out; \
} while (0)
+#define elem_syntax_err(fmt, args...) \
+do { \
+ free(saved); \
+ return syntax_err(fmt , ## args);\
+} while (0)
+
/**
* ipset_parse_elem - parse ADT elem, depending on settype
* @session: session structure
@@ -890,7 +1148,7 @@ ipset_parse_elem(struct ipset_session *session,
{
const struct ipset_type *type;
char *a = NULL, *b = NULL, *tmp, *saved;
- int err;
+ int ret;
assert(session);
assert(str);
@@ -906,40 +1164,43 @@ ipset_parse_elem(struct ipset_session *session,
"Cannot allocate memory to duplicate %s.",
str);
- a = ipset_elem_separator(tmp);
+ a = elem_separator(tmp);
if (type->dimension > IPSET_DIM_ONE) {
if (a != NULL) {
/* elem,elem */
*a++ = '\0';
- } else if (type->dimension > IPSET_DIM_TWO && !optional) {
- free(tmp);
- return syntax_err("Second element is missing from %s.",
- str);
+ } else if (!optional)
+ elem_syntax_err("Second element is missing from %s.",
+ str);
+ } else if (a != NULL) {
+ if (type->compat_parse_elem) {
+ ret = type->compat_parse_elem(session,
+ type->elem[IPSET_DIM_ONE].opt,
+ saved);
+ goto out;
}
- } else if (a != NULL)
- return syntax_err("Elem separator in %s, "
- "but settype %s supports none.",
- str, type->name);
+ elem_syntax_err("Elem separator in %s, "
+ "but settype %s supports none.",
+ str, type->name);
+ }
if (a)
- b = ipset_elem_separator(a);
+ b = elem_separator(a);
if (type->dimension > IPSET_DIM_TWO) {
if (b != NULL) {
/* elem,elem,elem */
*b++ = '\0';
- } else if (!optional) {
- free(tmp);
- return syntax_err("Third element is missing from %s.",
- str);
- }
+ } else if (!optional)
+ elem_syntax_err("Third element is missing from %s.",
+ str);
} else if (b != NULL)
- return syntax_err("Two elem separators in %s, "
- "but settype %s supports one.",
- str, type->name);
- if (b != NULL && ipset_elem_separator(b))
- return syntax_err("Three elem separators in %s, "
- "but settype %s supports two.",
- str, type->name);
+ elem_syntax_err("Two elem separators in %s, "
+ "but settype %s supports one.",
+ str, type->name);
+ if (b != NULL && elem_separator(b))
+ elem_syntax_err("Three elem separators in %s, "
+ "but settype %s supports two.",
+ str, type->name);
D("parse elem part one: %s", tmp);
parse_elem(session, type, IPSET_DIM_ONE, tmp);
@@ -954,10 +1215,10 @@ ipset_parse_elem(struct ipset_session *session,
goto out;
internal:
- err = ipset_err(session,
+ ret = ipset_err(session,
"Internal error: missing parser function for %s",
type->name);
out:
free(saved);
- return err;
+ return ret;
}
diff --git a/lib/print.c b/lib/print.c
index 4df0905..d96e643 100644
--- a/lib/print.c
+++ b/lib/print.c
@@ -13,6 +13,7 @@
#include <arpa/inet.h> /* inet_ntop */
#include <net/ethernet.h> /* ETH_ALEN */
+#include <libipset/debug.h> /* D() */
#include <libipset/data.h> /* ipset_data_* */
#include <libipset/parse.h> /* IPSET_*_SEPARATOR */
#include <libipset/types.h> /* ipset set types */
@@ -86,7 +87,7 @@ ipset_print_ether(char *buf, unsigned int len,
*/
int
ipset_print_family(char *buf, unsigned int len,
- const struct ipset_data *data, int opt,
+ const struct ipset_data *data, enum ipset_opt opt,
uint8_t env UNUSED)
{
uint8_t family;
@@ -172,10 +173,10 @@ snprintf_ipv##f(char *buf, unsigned int len, int flags, \
size = __getnameinfo##f(buf, len, flags, ip); \
SNPRINTF_FAILURE(size, len, offset); \
\
+ D("cidr %u mask %u", cidr, mask); \
if (cidr == mask) \
return offset; \
- if ((unsigned int)(size + 5) < len) \
- return -1; \
+ D("print cidr"); \
size = snprintf(buf + offset, len, \
"%s%u", IPSET_CIDR_SEPARATOR, cidr); \
SNPRINTF_FAILURE(size, len, offset); \
@@ -218,9 +219,10 @@ ipset_print_ip(char *buf, unsigned int len,
D("len: %u", len);
family = ipset_data_family(data);
cidropt = opt == IPSET_OPT_IP ? IPSET_OPT_CIDR : IPSET_OPT_CIDR2;
- if (ipset_data_test(data, cidropt))
+ if (ipset_data_test(data, cidropt)) {
cidr = *(uint8_t *) ipset_data_get(data, cidropt);
- else
+ D("CIDR: %u", cidr);
+ } else
cidr = family == AF_INET6 ? 128 : 32;
flags = env & (1 << IPSET_ENV_RESOLVE) ? 0 : NI_NUMERICHOST;
@@ -373,11 +375,14 @@ ipset_print_name(char *buf, unsigned int len,
SNPRINTF_FAILURE(size, len, offset);
if (ipset_data_test(data, IPSET_OPT_NAMEREF)) {
- bool before = ipset_data_test(data, IPSET_OPT_BEFORE);
+ bool before = false;
+ if (ipset_data_flags_test(data, IPSET_FLAG(IPSET_OPT_FLAGS))) {
+ uint32_t *flags =
+ (uint32_t *)ipset_data_get(data, IPSET_OPT_FLAGS);
+ before = (*flags) & IPSET_FLAG_BEFORE;
+ }
size = snprintf(buf + offset, len,
- "%s%s%s%s", IPSET_ELEM_SEPARATOR,
- before ? "before" : "after",
- IPSET_ELEM_SEPARATOR,
+ " %s %s", before ? "before" : "after",
(const char *) ipset_data_get(data,
IPSET_OPT_NAMEREF));
SNPRINTF_FAILURE(size, len, offset);
@@ -468,8 +473,8 @@ ipset_print_elem(char *buf, unsigned int len,
size = type->elem[IPSET_DIM_ONE].print(buf, len, data,
type->elem[IPSET_DIM_ONE].opt, env);
SNPRINTF_FAILURE(size, len, offset);
- if (ipset_data_test(data, type->elem[IPSET_DIM_TWO].opt))
- D("print second elem");
+ IF_D(ipset_data_test(data, type->elem[IPSET_DIM_TWO].opt),
+ "print second elem");
if (type->dimension == IPSET_DIM_ONE
|| (type->last_elem_optional
&& !ipset_data_test(data, type->elem[IPSET_DIM_TWO].opt)))
diff --git a/lib/session.c b/lib/session.c
index 2c4e39a..2c85468 100644
--- a/lib/session.c
+++ b/lib/session.c
@@ -13,6 +13,7 @@
#include <unistd.h> /* getpagesize */
#include <net/ethernet.h> /* ETH_ALEN */
+#include <libipset/debug.h> /* D() */
#include <libipset/data.h> /* IPSET_OPT_* */
#include <libipset/errcode.h> /* ipset_errcode */
#include <libipset/print.h> /* ipset_print_* */
@@ -189,6 +190,8 @@ ipset_session_report(struct ipset_session *session,
if (len >= IPSET_ERRORBUFLEN - 1 - offset)
session->report[IPSET_ERRORBUFLEN - 1] = '\0';
+ if (strlen(session->report) < IPSET_ERRORBUFLEN - 1)
+ strcat(session->report, "\n");
if (type == IPSET_ERROR) {
session->errmsg = session->report;
@@ -278,6 +281,10 @@ const struct ipset_attr_policy cmd_attrs[] = {
.type = MNL_TYPE_U8,
.opt = IPSET_OPT_FAMILY,
},
+ [IPSET_ATTR_FLAGS] = {
+ .type = MNL_TYPE_U32,
+ .opt = IPSET_OPT_FLAGS,
+ },
[IPSET_ATTR_DATA] = {
.type = MNL_TYPE_NESTED,
},
@@ -320,9 +327,9 @@ const struct ipset_attr_policy create_attrs[] = {
.type = MNL_TYPE_U32,
.opt = IPSET_OPT_TIMEOUT,
},
- [IPSET_ATTR_FLAGS] = {
+ [IPSET_ATTR_CADT_FLAGS] = {
.type = MNL_TYPE_U32,
- .opt = IPSET_OPT_FLAGS,
+ .opt = IPSET_OPT_CADT_FLAGS,
},
[IPSET_ATTR_GC] = {
.type = MNL_TYPE_U32,
@@ -391,9 +398,9 @@ const struct ipset_attr_policy adt_attrs[] = {
.type = MNL_TYPE_U32,
.opt = IPSET_OPT_TIMEOUT,
},
- [IPSET_ATTR_FLAGS] = {
+ [IPSET_ATTR_CADT_FLAGS] = {
.type = MNL_TYPE_U32,
- .opt = IPSET_OPT_FLAGS,
+ .opt = IPSET_OPT_CADT_FLAGS,
},
[IPSET_ATTR_LINENO] = {
.type = MNL_TYPE_U32,
@@ -434,6 +441,7 @@ attr2data(struct ipset_session *session, struct nlattr *nla[],
struct ipset_data *data = session->data;
const struct ipset_attr_policy *attr;
const void *d;
+ int ret;
attr = &attrs[type];
d = mnl_attr_get_payload(nla[type]);
@@ -480,7 +488,14 @@ attr2data(struct ipset_session *session, struct nlattr *nla[],
break;
}
}
- return ipset_data_set(data, attr->opt, d);
+ if (type == IPSET_ATTR_TYPENAME)
+ D("nla typename %s", (char *) d);
+ ret = ipset_data_set(data, attr->opt, d);
+ if (type == IPSET_ATTR_TYPENAME)
+ D("nla typename %s",
+ (char *) ipset_data_get(data, IPSET_OPT_TYPENAME));
+
+ return ret;
}
#define ATTR2DATA(session, nla, type, attrs) \
@@ -579,8 +594,9 @@ list_adt(struct ipset_session *session, struct nlattr *nla[])
const struct ipset_type *type;
const struct ipset_arg *arg;
uint8_t family;
- int i;
-
+ int i, found = 0;
+
+ D("enter");
/* Check and load type, family */
if (!ipset_data_test(data, IPSET_OPT_TYPE))
type = ipset_type_get(session, IPSET_CMD_ADD);
@@ -591,6 +607,15 @@ list_adt(struct ipset_session *session, struct nlattr *nla[])
return MNL_CB_ERROR;
family = ipset_data_family(data);
+ for (i = IPSET_ATTR_UNSPEC + 1; i <= IPSET_ATTR_ADT_MAX; i++)
+ if (nla[i]) {
+ found++;
+ ATTR2DATA(session, nla, i, adt_attrs);
+ }
+ D("attr found %u", found);
+ if (!found)
+ return MNL_CB_OK;
+
switch (session->mode) {
case IPSET_LIST_SAVE:
safe_snprintf(session, "add %s ", ipset_data_setname(data));
@@ -603,10 +628,6 @@ list_adt(struct ipset_session *session, struct nlattr *nla[])
break;
}
- for (i = IPSET_ATTR_UNSPEC + 1; i <= IPSET_ATTR_ADT_MAX; i++)
- if (nla[i])
- ATTR2DATA(session, nla, i, adt_attrs);
-
safe_dprintf(session, ipset_print_elem, IPSET_OPT_ELEM);
for (arg = type->args[IPSET_ADD]; arg != NULL && arg->print; arg++) {
@@ -646,6 +667,10 @@ list_adt(struct ipset_session *session, struct nlattr *nla[])
return MNL_CB_OK;
}
+#define FAMILY_TO_STR(f) \
+ ((f) == AF_INET ? "inet" : \
+ (f) == AF_INET6 ? "inet6" : "any")
+
static int
list_create(struct ipset_session *session, struct nlattr *nla[])
{
@@ -671,33 +696,29 @@ list_create(struct ipset_session *session, struct nlattr *nla[])
safe_snprintf(session, "create %s %s ",
ipset_data_setname(data),
type->name);
- if (family == AF_INET6)
- sprintf(session->outbuf, "family inet6 ");
break;
case IPSET_LIST_PLAIN:
- safe_snprintf(session, "Name: %s\nType: %s\n",
+ safe_snprintf(session, "Name: %s\n"
+ "Type: %s\nHeader: ",
ipset_data_setname(data),
type->name);
- if (family == AF_INET6)
- safe_snprintf(session, "Family: INET6\n");
- safe_snprintf(session, "Header: ");
break;
case IPSET_LIST_XML:
safe_snprintf(session,
"<ipset name=\"%s\">\n"
- " <type>%s</type>\n",
+ " <type>%s</type>\n"
+ " <header>\n",
ipset_data_setname(data),
type->name);
- if (family == AF_INET6)
- safe_snprintf(session, " <family>INET6</family>\n");
- safe_snprintf(session, " <header>\n");
break;
default:
break;
}
- for (arg = type->args[IPSET_CREATE]; arg != NULL && arg->print; arg++) {
- if (!ipset_data_test(data, arg->opt))
+ for (arg = type->args[IPSET_CREATE]; arg != NULL && arg->opt; arg++) {
+ if (!arg->print
+ || !ipset_data_test(data, arg->opt)
+ || (arg->opt == IPSET_OPT_FAMILY && family == type->family))
continue;
switch (session->mode) {
case IPSET_LIST_SAVE:
@@ -730,8 +751,6 @@ list_create(struct ipset_session *session, struct nlattr *nla[])
safe_snprintf(session, "\n");
break;
case IPSET_LIST_PLAIN:
- safe_snprintf(session, "\nElements: ");
- safe_dprintf(session, ipset_print_number, IPSET_OPT_ELEMENTS);
safe_snprintf(session, "\nSize in memory: ");
safe_dprintf(session, ipset_print_number, IPSET_OPT_MEMSIZE);
safe_snprintf(session, "\nReferences: ");
@@ -739,8 +758,6 @@ list_create(struct ipset_session *session, struct nlattr *nla[])
safe_snprintf(session, "\nMembers:\n");
break;
case IPSET_LIST_XML:
- safe_snprintf(session, " <elements>");
- safe_dprintf(session, ipset_print_number, IPSET_OPT_ELEMENTS);
safe_snprintf(session, "</elements>\n <memsize>");
safe_dprintf(session, ipset_print_number, IPSET_OPT_MEMSIZE);
safe_snprintf(session, "</memsize>\n <references>");
@@ -757,7 +774,8 @@ list_create(struct ipset_session *session, struct nlattr *nla[])
static int
print_set_done(struct ipset_session *session)
{
- D("called");
+ D("called for %s", session->saved_setname[0] == '\0'
+ ? "NONE" : session->saved_setname);
switch (session->mode) {
case IPSET_LIST_XML:
if (session->saved_setname[0] == '\0')
@@ -824,6 +842,7 @@ callback_list(struct ipset_session *session, struct nlattr *nla[],
cmd2name[cmd]);
ATTR2DATA(session, nla, IPSET_ATTR_SETNAME, cmd_attrs);
+ D("setname %s", ipset_data_setname(data));
if (STREQ(ipset_data_setname(data), session->saved_setname)) {
/* Header part already seen */
if (ipset_data_test(data, IPSET_OPT_TYPE)
@@ -851,12 +870,18 @@ callback_list(struct ipset_session *session, struct nlattr *nla[],
!nla[IPSET_ATTR_TYPENAME] ? "typename" :
!nla[IPSET_ATTR_FAMILY] ? "family" : "revision");
+ /* Reset CREATE specific flags */
+ ipset_data_flags_unset(data, IPSET_CREATE_FLAGS);
+ D("nla typename %s",
+ (char *) mnl_attr_get_payload(nla[IPSET_ATTR_TYPENAME]));
+ D("nla typename %s",
+ (char *) mnl_attr_get_payload(nla[IPSET_ATTR_TYPENAME]));
ATTR2DATA(session, nla, IPSET_ATTR_FAMILY, cmd_attrs);
ATTR2DATA(session, nla, IPSET_ATTR_TYPENAME, cmd_attrs);
ATTR2DATA(session, nla, IPSET_ATTR_REVISION, cmd_attrs);
-
- /* Reset CREATE specific flags */
- ipset_data_flags_unset(data, IPSET_CREATE_FLAGS);
+ D("head: family %u, typename %s",
+ ipset_data_family(data),
+ (char *) ipset_data_get(data, IPSET_OPT_TYPENAME));
if (mnl_attr_parse_nested(nla[IPSET_ATTR_DATA],
create_attr_cb, cattr) < 0)
FAILURE("Broken %s kernel message: "
@@ -869,8 +894,9 @@ callback_list(struct ipset_session *session, struct nlattr *nla[],
if (nla[IPSET_ATTR_ADT] != NULL) {
struct nlattr *tb, *adt[IPSET_ATTR_ADT_MAX+1];
-
+
mnl_attr_for_each_nested(tb, nla[IPSET_ATTR_ADT]) {
+ D("ADT attributes for %s", ipset_data_setname(data));
memset(adt, 0, sizeof(adt));
/* Reset ADT specific flags */
ipset_data_flags_unset(data, IPSET_ADT_FLAGS);
@@ -950,6 +976,7 @@ callback_header(struct ipset_session *session, struct nlattr *nla[])
ATTR2DATA(session, nla, IPSET_ATTR_TYPENAME, cmd_attrs);
ATTR2DATA(session, nla, IPSET_ATTR_REVISION, cmd_attrs);
ATTR2DATA(session, nla, IPSET_ATTR_FAMILY, cmd_attrs);
+ D("got family: %u", ipset_data_family(session->data));
return MNL_CB_STOP;
}
@@ -1150,7 +1177,8 @@ callback_error(const struct nlmsghdr *nlh, void *cbdata)
case IPSET_CMD_CREATE:
/* Add successfully created set to the cache */
ipset_cache_add(ipset_data_setname(data),
- ipset_data_get(data, IPSET_OPT_TYPE));
+ ipset_data_get(data, IPSET_OPT_TYPE),
+ ipset_data_family(data));
break;
case IPSET_CMD_DESTROY:
/* Delete destroyed sets from the cache */
@@ -1750,7 +1778,7 @@ ipset_session_init(ipset_outfn outfn)
if (session->data == NULL)
goto free_session;
- ipset_types_init();
+ ipset_cache_init();
return session;
free_session:
@@ -1776,7 +1804,7 @@ ipset_session_fini(struct ipset_session *session)
if (session->data)
ipset_data_fini(session->data);
- ipset_types_fini();
+ ipset_cache_fini();
free(session);
return 0;
}
diff --git a/lib/types.c b/lib/types.c
index a6476ea..b39a04f 100644
--- a/lib/types.c
+++ b/lib/types.c
@@ -13,6 +13,7 @@
#include <stdlib.h> /* malloc, free */
#include <stdio.h> /* FIXME: debug */
+#include <libipset/debug.h> /* D() */
#include <libipset/data.h> /* ipset_data_* */
#include <libipset/session.h> /* ipset_cmd */
#include <libipset/utils.h> /* STREQ */
@@ -23,6 +24,7 @@
struct ipset {
char name[IPSET_MAXNAMELEN]; /* set name */
const struct ipset_type *type; /* set type */
+ uint8_t family; /* family */
struct ipset *next;
};
@@ -40,7 +42,8 @@ static struct ipset *setlist = NULL; /* cached sets */
* Returns 0 on success or a negative error code.
*/
int
-ipset_cache_add(const char *name, const struct ipset_type *type)
+ipset_cache_add(const char *name, const struct ipset_type *type,
+ uint8_t family)
{
struct ipset *s, *n;
@@ -53,13 +56,14 @@ ipset_cache_add(const char *name, const struct ipset_type *type)
ipset_strncpy(n->name, name, IPSET_MAXNAMELEN);
n->type = type;
+ n->family = family;
n->next = NULL;
if (setlist == NULL) {
setlist = n;
return 0;
}
- for (s = setlist; s->next == NULL; s = s->next) {
+ for (s = setlist; s->next != NULL; s = s->next) {
if (STREQ(name, s->name)) {
free(n);
return -EEXIST;
@@ -171,6 +175,22 @@ ipset_cache_swap(const char *from, const char *to)
#define MATCH_FAMILY(type, f) \
(f == AF_UNSPEC || type->family == f || type->family == AF_INET46)
+bool
+ipset_match_typename(const char *name, const struct ipset_type *type)
+{
+ const char * const * alias = type->alias;
+
+ if (STREQ(name, type->name))
+ return true;
+
+ while (alias[0]) {
+ if (STREQ(name, alias[0]))
+ return true;
+ alias++;
+ }
+ return false;
+}
+
static inline const struct ipset_type *
create_type_get(struct ipset_session *session)
{
@@ -192,7 +212,7 @@ create_type_get(struct ipset_session *session)
/* Skip revisions which are unsupported by the kernel */
if (t->kernel_check == IPSET_KERNEL_MISMATCH)
continue;
- if ((STREQ(typename, t->name) || STREQ(typename, t->alias))
+ if (ipset_match_typename(typename, t)
&& MATCH_FAMILY(t, family)) {
if (match == NULL) {
match = t;
@@ -390,8 +410,9 @@ ipset_type_check(struct ipset_session *session)
for (t = typelist; t != NULL && match == NULL; t = t->next) {
if (t->kernel_check == IPSET_KERNEL_MISMATCH)
continue;
- if ((STREQ(typename, t->name) || STREQ(typename, t->alias))
- && MATCH_FAMILY(t, family) && t->revision == revision)
+ if (ipset_match_typename(typename, t)
+ && MATCH_FAMILY(t, family)
+ && t->revision == revision)
match = t;
}
if (!match)
@@ -503,7 +524,7 @@ ipset_typename_resolve(const char *str)
const struct ipset_type *t;
for (t = typelist; t != NULL; t = t->next)
- if (STREQ(str, t->name) || STREQ(str, t->alias))
+ if (ipset_match_typename(str, t))
return t->name;
return NULL;
}
@@ -523,38 +544,25 @@ ipset_types(void)
}
/**
- * ipset_types_init - initialize known set types
+ * ipset_cache_init - initialize set cache
*
- * Initialize the type list with the known, supported set types.
+ * Initialize the set cache in userspace.
*
* Returns 0 on success or a negative error code.
*/
int
-ipset_types_init(void)
+ipset_cache_init(void)
{
- if (typelist != NULL)
- return 0;
-
- ipset_type_add(&ipset_bitmap_ip0);
- ipset_type_add(&ipset_bitmap_ipmac0);
- ipset_type_add(&ipset_bitmap_port0);
- ipset_type_add(&ipset_hash_ip0);
- ipset_type_add(&ipset_hash_net0);
- ipset_type_add(&ipset_hash_ipport0);
- ipset_type_add(&ipset_hash_ipportip0);
- ipset_type_add(&ipset_hash_ipportnet0);
- ipset_type_add(&ipset_tree_ip0);
- ipset_type_add(&ipset_list_set0);
return 0;
}
/**
- * ipset_types_fini - release initialized known set types
+ * ipset_cache_fini - release the set cache
*
- * Release initialized known set types and remove the set cache.
+ * Release the set cache.
*/
void
-ipset_types_fini(void)
+ipset_cache_fini(void)
{
struct ipset *set;
diff --git a/lib/utils.c b/lib/utils.c
deleted file mode 100644
index bddeb87..0000000
--- a/lib/utils.c
+++ /dev/null
@@ -1,103 +0,0 @@
-/* Copyright 2007-20010 Jozsef Kadlecsik (kadlec@blackhole.kfki.hu)
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-#include <assert.h> /* assert */
-#include <stdbool.h> /* bool */
-#include <stdlib.h> /* malloc, free */
-#include <string.h> /* memset, str* */
-
-#include <libipset/session.h> /* ipset_err */
-#include <libipset/utils.h> /* prototypes */
-
-/**
- * ipset_strchr - locate character(s) in string
- * @str: string to locate the character(s) in
- * @sep: string of characters to locate
- *
- * Return a pointer to the first occurence of any of the
- * characters to be located in the string. NULL is returned
- * if no character is found.
- */
-char *
-ipset_strchr(const char *str, const char *sep)
-{
- char *match;
-
- assert(str);
- assert(sep);
-
- for (; *sep != '\0'; sep++)
- if ((match = strchr(str, (int)sep[0])) != NULL)
- return match;
-
- return NULL;
-}
-
-/**
- * ipset_name_match - match a string against an array of strings
- * @arg: string
- * @name: array of strings, last one is a NULL pointer
- *
- * Return true if arg matches any of the strings in the array.
- */
-bool
-ipset_name_match(const char *arg, const char * const name[])
-{
- int i = 0;
-
- assert(arg);
- assert(name);
-
- while (name[i]) {
- if (STREQ(arg, name[i]))
- return true;
- i++;
- }
-
- return false;
-}
-
-/**
- * ipset_shift_argv - shift off an argument
- * @arc: argument count
- * @argv: array of argument strings
- * @from: from where shift off an argument
- *
- * Shift off the argument at "from" from the array of
- * arguments argv of size argc.
- */
-void
-ipset_shift_argv(int *argc, char *argv[], int from)
-{
- int i;
-
- assert(*argc >= from + 1);
-
- for (i = from + 1; i <= *argc; i++) {
- argv[i-1] = argv[i];
- }
- (*argc)--;
- return;
-}
-
-/**
- * ipset_strncpy - copy the string from src to dst
- * @dst: the target string buffer
- * @src: the source string buffer
- * @len: the length of bytes to copy, including the terminating null byte.
- *
- * Copy the string from src to destination, but at most len bytes are
- * copied. The target is unconditionally terminated by the null byte.
- */
-void
-ipset_strncpy(char *dst, const char *src, size_t len)
-{
- assert(dst);
- assert(src);
-
- strncpy(dst, src, len);
- dst[len - 1] = '\0';
-}