summaryrefslogtreecommitdiffstats
path: root/src/set.c
diff options
context:
space:
mode:
authorArturo Borrero <arturo.borrero.glez@gmail.com>2013-07-26 14:22:03 +0200
committerPablo Neira Ayuso <pablo@netfilter.org>2013-07-26 14:54:10 +0200
commit44928cd546f00a73797a570dcaee44f0bfe5bea7 (patch)
treec69ee7a0333842ee4fd7df523c1a69d8d125f452 /src/set.c
parent986c098a1b7c3329d66a60838c1b304c993063f8 (diff)
set: add XML parsing
Sets are now parsed, following this previous snprintf pattern: <set> <set_name>string</set_name> <set_table>table</set_table> <set_xml_version>int</set_xml_version> <set_flags>uint32_t</set_flags> <key_type>uint32_t</key_type> <key_len>size_t</key_len> <data_type>uint32_t</data_type> <data_len>size_t</data_len> <set_elem> <set_elem_flags>uint32_t</set_elem_flags> <set_elem_key> <data_reg type="value"> <len></len> <dataN></dataN> </data_reg> </set_elem_key> <set_elem_data> <data_reg type="xx"> [...] </data_reg> </set_elem_data> </set_elem> </set> Signed-off-by: Arturo Borrero González <arturo.borrero.glez@gmail.com> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Diffstat (limited to 'src/set.c')
-rw-r--r--src/set.c140
1 files changed, 140 insertions, 0 deletions
diff --git a/src/set.c b/src/set.c
index b729195..4b0ec6a 100644
--- a/src/set.c
+++ b/src/set.c
@@ -16,6 +16,8 @@
#include <stdlib.h>
#include <string.h>
#include <netinet/in.h>
+#include <limits.h>
+#include <errno.h>
#include <libmnl/libmnl.h>
#include <linux/netfilter/nfnetlink.h>
@@ -301,6 +303,144 @@ int nft_set_nlmsg_parse(const struct nlmsghdr *nlh, struct nft_set *s)
}
EXPORT_SYMBOL(nft_set_nlmsg_parse);
+static int nft_set_xml_parse(struct nft_set *s, char *xml)
+{
+#ifdef XML_PARSING
+ mxml_node_t *tree;
+ mxml_node_t *node = NULL;
+ struct nft_set_elem *elem;
+ char *name;
+ char *table;
+ int version;
+ int family;
+ char *family_str;
+
+ tree = mxmlLoadString(NULL, xml, MXML_OPAQUE_CALLBACK);
+ if (tree == NULL) {
+ errno = EINVAL;
+ return -1;
+ }
+
+ if (strcmp(tree->value.opaque, "set") != 0)
+ goto err;
+
+ if (nft_mxml_num_parse(tree, "set_xml_version", MXML_DESCEND_FIRST,
+ BASE_DEC, &version, NFT_TYPE_S32) != 0)
+ goto err;
+
+ if (version != NFT_SET_XML_VERSION)
+ goto err;
+
+ name = (char *)nft_mxml_str_parse(tree, "set_name",
+ MXML_DESCEND_FIRST);
+ if (name == NULL)
+ goto err;
+
+ if (s->name)
+ free(s->name);
+
+ s->name = name;
+ s->flags |= (1 << NFT_SET_ATTR_NAME);
+
+ table = (char *)nft_mxml_str_parse(tree, "set_table",
+ MXML_DESCEND_FIRST);
+ if (table == NULL)
+ goto err;
+
+ if (s->table)
+ free(s->table);
+
+ s->table = strdup(table);
+ s->flags |= (1 << NFT_SET_ATTR_TABLE);
+
+ family_str = (char *)nft_mxml_str_parse(tree, "family",
+ MXML_DESCEND_FIRST);
+ if (family_str == NULL)
+ goto err;
+
+ family = nft_str2family(family_str);
+
+ if (family < 0)
+ goto err;
+
+ s->family = family;
+
+ s->flags |= (1 << NFT_SET_ATTR_FAMILY);
+
+ if (nft_mxml_num_parse(tree, "set_flags", MXML_DESCEND_FIRST,
+ BASE_DEC, &s->set_flags, NFT_TYPE_U32) != 0)
+ goto err;
+
+ s->flags |= (1 << NFT_SET_ATTR_FLAGS);
+
+
+ if (nft_mxml_num_parse(tree, "key_type", MXML_DESCEND_FIRST,
+ BASE_DEC, &s->key_type, NFT_TYPE_U32) != 0)
+ goto err;
+
+ s->flags |= (1 << NFT_SET_ATTR_KEY_TYPE);
+
+ if (nft_mxml_num_parse(tree, "key_len", MXML_DESCEND_FIRST,
+ BASE_DEC, &s->key_type, NFT_TYPE_U32) != 0)
+ goto err;
+
+ s->flags |= (1 << NFT_SET_ATTR_KEY_LEN);
+
+ if (nft_mxml_num_parse(tree, "data_type", MXML_DESCEND_FIRST,
+ BASE_DEC, &s->data_type, NFT_TYPE_U32) != 0)
+ goto err;
+
+ s->flags |= (1 << NFT_SET_ATTR_DATA_TYPE);
+
+ if (nft_mxml_num_parse(tree, "data_len", MXML_DESCEND_FIRST,
+ BASE_DEC, &s->data_len, NFT_TYPE_U32) != 0)
+ goto err;
+
+ s->flags |= (1 << NFT_SET_ATTR_DATA_LEN);
+
+ /* Iterate over each <set_elem> */
+ for (node = mxmlFindElement(tree, tree, "set_elem", NULL,
+ NULL, MXML_DESCEND);
+ node != NULL;
+ node = mxmlFindElement(node, tree, "set_elem", NULL,
+ NULL, MXML_DESCEND)) {
+
+ elem = nft_mxml_set_elem_parse(node);
+ if (elem == NULL)
+ goto err;
+
+ list_add_tail(&elem->head, &s->element_list);
+ }
+
+ mxmlDelete(tree);
+ return 0;
+err:
+ mxmlDelete(tree);
+ return -1;
+#else
+ errno = EOPNOTSUPP;
+ return -1;
+#endif
+}
+
+int nft_set_parse(struct nft_set *s, enum nft_set_parse_type type, char *data)
+{
+ int ret;
+
+ switch (type) {
+ case NFT_SET_PARSE_XML:
+ ret = nft_set_xml_parse(s, data);
+ break;
+ default:
+ ret = -1;
+ errno = EOPNOTSUPP;
+ break;
+ }
+
+ return ret;
+}
+EXPORT_SYMBOL(nft_set_parse);
+
static int nft_set_snprintf_json(char *buf, size_t size, struct nft_set *s,
uint32_t type, uint32_t flags)
{