All of lore.kernel.org
 help / color / mirror / Atom feed
* [libnftables PATCH 1/6] table: json: Add Json parser support
@ 2013-07-25 20:52 Alvaro Neira
  2013-07-25 20:52 ` [libnftables PATCH 2/6] table : tests: test the table json " Alvaro Neira
                   ` (5 more replies)
  0 siblings, 6 replies; 10+ messages in thread
From: Alvaro Neira @ 2013-07-25 20:52 UTC (permalink / raw)
  To: netfilter-devel; +Cc: eric

From: Álvaro Neira Ayuso <alvaroneay@gmail.com>

Add function for parsing tables in format JSON

Signed-off-by: Alvaro Neira Ayuso <alvaroneay@gmail.com>
---
 configure.ac                |    9 ++++-
 include/libnftables/table.h |    1 +
 src/Makefile.am             |    3 +-
 src/internal.h              |   10 +++++
 src/jansson.c               |   79 +++++++++++++++++++++++++++++++++++++++++++
 src/table.c                 |   69 ++++++++++++++++++++++++++++++++++++++
 src/utils.c                 |   61 ++++++++++++++++++++-------------
 7 files changed, 206 insertions(+), 26 deletions(-)
 create mode 100644 src/jansson.c

diff --git a/configure.ac b/configure.ac
index c8075e9..834c0a3 100644
--- a/configure.ac
+++ b/configure.ac
@@ -18,7 +18,10 @@ AC_ARG_WITH([xml-parsing], AS_HELP_STRING([--with-xml-parsing], [XML parsing sup
 AS_IF([test "x$with_xml_parsing" = "xyes"], [
 	PKG_CHECK_MODULES([LIBXML], [mxml >= 2.6])
 ])
-
+AC_ARG_WITH([json-parsing], AS_HELP_STRING([--with-json-parsing], [JSON parsing support]))
+AS_IF([test "x$with_json_parsing" = "xyes"], [
+	PKG_CHECK_MODULES([LIBJSON], [jansson >= 2.3])
+])
 AC_PROG_CC
 AM_PROG_CC_C_O
 AC_DISABLE_STATIC
@@ -33,6 +36,10 @@ regular_CPPFLAGS="-D_FILE_OFFSET_BITS=64 -D_REENTRANT"
 AS_IF([test "x$with_xml_parsing" = "xyes"], [
 	regular_CPPFLAGS="$regular_CPPFLAGS -DXML_PARSING"
 ])
+
+AS_IF([test "x$with_json_parsing" = "xyes"], [
+	regular_CPPFLAGS="$regular_CPPFLAGS -DJSON_PARSING"
+])
 regular_CFLAGS="-Wall -Waggregate-return -Wmissing-declarations \
 	-Wmissing-prototypes -Wshadow -Wstrict-prototypes \
 	-Wformat=2 -pipe"
diff --git a/include/libnftables/table.h b/include/libnftables/table.h
index f3f3e89..24ca374 100644
--- a/include/libnftables/table.h
+++ b/include/libnftables/table.h
@@ -40,6 +40,7 @@ enum {
 enum nft_table_parse_type {
 	NFT_TABLE_PARSE_NONE	= 0,
 	NFT_TABLE_PARSE_XML,
+	NFT_TABLE_PARSE_JSON,
 	NFT_TABLE_PARSE_MAX,
 };
 
diff --git a/src/Makefile.am b/src/Makefile.am
index 6496511..51b40a2 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -1,7 +1,7 @@
 include $(top_srcdir)/Make_global.am
 lib_LTLIBRARIES = libnftables.la
 
-libnftables_la_LIBADD = ${LIBMNL_LIBS} ${LIBXML_LIBS}
+libnftables_la_LIBADD = ${LIBMNL_LIBS} ${LIBXML_LIBS} ${LIBJSON_LIBS}
 libnftables_la_LDFLAGS = -Wl,--version-script=$(srcdir)/libnftables.map \
 			 -version-info $(LIBVERSION)
 libnftables_la_SOURCES = utils.c		\
@@ -11,6 +11,7 @@ libnftables_la_SOURCES = utils.c		\
 			 set.c			\
 			 set_elem.c		\
 			 mxml.c			\
+			 jansson.c		\
 			 expr.c			\
 			 expr_ops.c		\
 			 expr/bitwise.c		\
diff --git a/src/internal.h b/src/internal.h
index b846814..47cd635 100644
--- a/src/internal.h
+++ b/src/internal.h
@@ -12,6 +12,7 @@
 #include "linux_list.h"
 
 #include <stdint.h>
+#include <stdbool.h>
 
 #define BASE_DEC 10
 #define BASE_HEX 16
@@ -37,6 +38,14 @@ int nft_mxml_num_parse(mxml_node_t *tree, const char *node_name, uint32_t mxml_f
 const char *nft_mxml_str_parse(mxml_node_t *tree, const char *node_name, uint32_t mxml_flags);
 #endif
 
+#ifdef JSON_PARSING
+#include <jansson.h>
+int nft_jansson_value_parse_val(json_t *root, const char *tag,
+				  int type, void *out);
+const char *nft_jansson_value_parse_str(json_t *root, const char *tag);
+bool nft_jansson_node_exist(json_t *root, const char *tag);
+#endif
+
 #define NFT_TABLE_XML_VERSION 0
 #define NFT_CHAIN_XML_VERSION 0
 #define NFT_RULE_XML_VERSION 0
@@ -51,6 +60,7 @@ int nft_str2family(const char *family);
 int nft_strtoi(const char *string, int base, void *number, enum nft_type type);
 const char *nft_verdict2str(uint32_t verdict);
 int nft_str2verdict(const char *verdict);
+int nft_get_value(enum nft_type type, void *val, void *out);
 
 struct expr_ops;
 
diff --git a/src/jansson.c b/src/jansson.c
new file mode 100644
index 0000000..2b15240
--- /dev/null
+++ b/src/jansson.c
@@ -0,0 +1,79 @@
+/*
+ * (C) 2013 by Álvaro Neira Ayuso <alvaroneay@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <internal.h>
+#include <stdlib.h>
+#include <limits.h>
+#include <stdint.h>
+#include <stdbool.h>
+#include <arpa/inet.h>
+#include <errno.h>
+#include <string.h>
+
+#ifdef JSON_PARSING
+
+static int nft_jansson_load_int_node(json_t *root, const char *tag,
+				      json_int_t *val)
+{
+	json_t *node;
+
+	node = json_object_get(root, tag);
+	if (node == NULL) {
+		errno = EINVAL;
+		return -1;
+	}
+
+	if (!json_is_integer(node)) {
+		errno = ERANGE;
+		goto err;
+	}
+
+	*val = json_integer_value(node);
+
+	return 0;
+err:
+	return -1;
+}
+
+const char *nft_jansson_value_parse_str(json_t *root, const char *tag)
+{
+	json_t *node;
+	const char *val;
+
+	node = json_object_get(root, tag);
+	if (node == NULL)
+		return NULL;
+
+	val = json_string_value(node);
+
+	return val;
+}
+
+int nft_jansson_value_parse_val(json_t *root, const char *tag, int type,
+				  void *out)
+{
+	json_int_t val;
+
+	if (nft_jansson_load_int_node(root, tag, &val) == -1)
+		goto err;
+
+	if (nft_get_value(type, &val, out) == -1)
+		goto err;
+
+	return 0;
+err:
+	errno = ERANGE;
+	return -1;
+}
+
+bool nft_jansson_node_exist(json_t *root, const char *tag)
+{
+	return json_object_get(root, tag) != NULL;
+}
+#endif
diff --git a/src/table.c b/src/table.c
index d814668..65797e8 100644
--- a/src/table.c
+++ b/src/table.c
@@ -295,6 +295,72 @@ static int nft_table_xml_parse(struct nft_table *t, char *xml)
 #endif
 }
 
+static int nft_table_json_parse(struct nft_table *t, char *json)
+{
+#ifdef JSON_PARSING
+	json_t *root;
+	json_error_t error;
+	uint64_t version;
+	uint32_t table_flag;
+	const char *str = NULL;
+
+	root = json_loadb(json, strlen(json), 0, &error);
+	if (!root) {
+		errno = EINVAL;
+		return -1;
+	}
+
+	root = json_object_get(root, "table");
+	if (root == NULL) {
+		errno = ERANGE;
+		return -1;
+	}
+
+	if (nft_jansson_value_parse_val(root, "version",
+					NFT_TYPE_U64, &version) == -1)
+		goto err;
+
+	if (version != NFT_TABLE_JSON_VERSION || version == -1)
+		goto err;
+
+	str = nft_jansson_value_parse_str(root, "name");
+	if (str == NULL)
+		goto err;
+
+	nft_table_attr_set_str(t, NFT_TABLE_ATTR_NAME, strdup(str));
+
+	root = json_object_get(root, "properties");
+	if (root == NULL)
+		goto err;
+
+	str = nft_jansson_value_parse_str(root, "family");
+	if (str == NULL)
+		goto err;
+
+	if (nft_str2family(str) < 0)
+		goto err;
+
+	nft_table_attr_set_u32(t, NFT_TABLE_ATTR_FAMILY, nft_str2family(str));
+
+	if (nft_jansson_value_parse_val(root, "table_flags",
+					NFT_TYPE_U32, &table_flag) == -1)
+		goto err;
+
+	nft_table_attr_set_u32(t, NFT_TABLE_ATTR_FLAGS, table_flag);
+
+	free(root);
+	return 0;
+err:
+	free(root);
+	errno = ERANGE;
+	return -1;
+
+#else
+	errno = EOPNOTSUPP;
+	return -1;
+#endif
+}
+
 int nft_table_parse(struct nft_table *t, enum nft_table_parse_type type,
 		    char *data)
 {
@@ -304,6 +370,9 @@ int nft_table_parse(struct nft_table *t, enum nft_table_parse_type type,
 	case NFT_TABLE_PARSE_XML:
 		ret = nft_table_xml_parse(t, data);
 		break;
+	case NFT_TABLE_PARSE_JSON:
+		ret = nft_table_json_parse(t, data);
+		break;
 	default:
 		ret = -1;
 		errno = EOPNOTSUPP;
diff --git a/src/utils.c b/src/utils.c
index ebd40b5..c6bf9ff 100644
--- a/src/utils.c
+++ b/src/utils.c
@@ -66,57 +66,70 @@ static struct {
 	[NFT_TYPE_S64]	= { .len = sizeof(int64_t), .min = INT64_MIN, .max = INT64_MAX },
 };
 
-int nft_strtoi(const char *string, int base, void *out, enum nft_type type)
+
+int nft_get_value(enum nft_type type, void *val, void *out)
 {
-	int64_t sval = 0;
-	uint64_t uval = -1;
-	char *endptr;
+	int64_t sval;
+	uint64_t uval;
 
 	switch (type) {
 	case NFT_TYPE_U8:
 	case NFT_TYPE_U16:
 	case NFT_TYPE_U32:
 	case NFT_TYPE_U64:
-		uval = strtoll(string, &endptr, base);
+		uval = *((uint64_t *)val);
+		if (uval > basetype[type].max) {
+			errno = ERANGE;
+			return -1;
+		}
+		memcpy(out, &uval, basetype[type].len);
 		break;
 	case NFT_TYPE_S8:
 	case NFT_TYPE_S16:
 	case NFT_TYPE_S32:
 	case NFT_TYPE_S64:
-		sval = strtoull(string, &endptr, base);
+		sval = *((int64_t *)val);
+		if (sval < basetype[type].min ||
+		    sval > (int64_t)basetype[type].max) {
+			errno = ERANGE;
+			return -1;
+		}
+		memcpy(out, &sval, basetype[type].len);
 		break;
-	default:
-		errno = EINVAL;
-		return -1;
 	}
 
-	if (*endptr) {
-		errno = EINVAL;
-		return -1;
-	}
+	return 0;
+}
+
+int nft_strtoi(const char *string, int base, void *out, enum nft_type type)
+{
+	int64_t sval = 0;
+	uint64_t uval = -1;
+	char *endptr;
 
 	switch (type) {
 	case NFT_TYPE_U8:
 	case NFT_TYPE_U16:
 	case NFT_TYPE_U32:
 	case NFT_TYPE_U64:
-		if (uval > basetype[type].max) {
-			errno = ERANGE;
-			return -1;
-		}
-		memcpy(out, &uval, basetype[type].len);
+		uval = strtoll(string, &endptr, base);
+		nft_get_value(type, &uval, out);
 		break;
 	case NFT_TYPE_S8:
 	case NFT_TYPE_S16:
 	case NFT_TYPE_S32:
 	case NFT_TYPE_S64:
-		if (sval < basetype[type].min ||
-		    sval > (int64_t)basetype[type].max) {
-			errno = ERANGE;
-			return -1;
-		}
-		memcpy(out, &sval, basetype[type].len);
+		sval = strtoull(string, &endptr, base);
+		nft_get_value(type, &sval, out);
 		break;
+	default:
+		errno = EINVAL;
+		return -1;
+	}
+
+	if (*endptr) {
+		errno = EINVAL;
+		return -1;
 	}
 
 	return 0;

--
To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply related	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2013-07-25 21:13 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-07-25 20:52 [libnftables PATCH 1/6] table: json: Add Json parser support Alvaro Neira
2013-07-25 20:52 ` [libnftables PATCH 2/6] table : tests: test the table json " Alvaro Neira
2013-07-25 21:07   ` Pablo Neira Ayuso
2013-07-25 20:52 ` [libnftables PATCH 3/6] examples: Add nft-table-json-add Alvaro Neira
2013-07-25 21:07   ` Pablo Neira Ayuso
2013-07-25 20:52 ` [libnftables PATCH 4/6] chain: json: add function for parsing chain Alvaro Neira
2013-07-25 21:13   ` Pablo Neira Ayuso
2013-07-25 20:52 ` [libnftables PATCH 5/6] chain: test: test the chain parser support Alvaro Neira
2013-07-25 20:52 ` [libnftables PATCH 6/6] examples: Add nft-chain-json-add Alvaro Neira
2013-07-25 21:07 ` [libnftables PATCH 1/6] table: json: Add Json parser support Pablo Neira Ayuso

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.