All of lore.kernel.org
 help / color / mirror / Atom feed
From: Alvaro Neira <alvaroneay@gmail.com>
To: netfilter-devel@vger.kernel.org
Cc: eric@regit.org
Subject: [libnftables PATCH 1/2] set: add Json Export Support
Date: Fri, 05 Jul 2013 14:41:28 +0200	[thread overview]
Message-ID: <20130705124128.23285.30238.stgit@Ph0enix> (raw)
In-Reply-To: <20130705123837.23285.5489.stgit@Ph0enix>

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

Signed-off-by: Alvaro Neira Ayuso <alvaroneay@gmail.com>
---
 examples/nft-set-elem-get.c |   15 ++++++++----
 examples/nft-set-get.c      |   15 ++++++++----
 include/libnftables/set.h   |    5 ++++
 src/set.c                   |   56 +++++++++++++++++++++++++++++++++++++++++--
 src/set_elem.c              |   49 ++++++++++++++++++++++++++++++++++++--
 5 files changed, 126 insertions(+), 14 deletions(-)

diff --git a/examples/nft-set-elem-get.c b/examples/nft-set-elem-get.c
index 34dfca2..353a752 100644
--- a/examples/nft-set-elem-get.c
+++ b/examples/nft-set-elem-get.c
@@ -23,6 +23,7 @@ static int set_cb(const struct nlmsghdr *nlh, void *data)
 {
 	struct nft_set *t;
 	char buf[4096];
+	uint32_t *type = data;
 
 	t = nft_set_alloc();
 	if (t == NULL) {
@@ -35,7 +36,7 @@ static int set_cb(const struct nlmsghdr *nlh, void *data)
 		goto err_free;
 	}
 
-	nft_set_snprintf(buf, sizeof(buf), t, 0, 0);
+	nft_set_snprintf(buf, sizeof(buf), t, *type, 0);
 	printf("%s\n", buf);
 
 err_free:
@@ -50,11 +51,12 @@ int main(int argc, char *argv[])
 	char buf[MNL_SOCKET_BUFFER_SIZE];
 	struct nlmsghdr *nlh;
 	uint32_t portid, seq, family;
+	uint32_t type = NFT_SET_O_DEFAULT;
 	struct nft_set *t = NULL;
 	int ret;
 
-	if (argc != 4) {
-		fprintf(stderr, "%s <family> <table> <set>\n", argv[0]);
+	if (argc < 4 || argc > 5) {
+		fprintf(stderr, "%s <family> <table> <set> [default|json]\n", argv[0]);
 		return EXIT_FAILURE;
 	}
 	t = nft_set_alloc();
@@ -67,13 +69,16 @@ int main(int argc, char *argv[])
 		family = AF_INET;
 	else if (strcmp(argv[1], "ip6") == 0)
 		family = AF_INET6;
-	else if (strcmp(argv[2], "bridge") == 0)
+	else if (strcmp(argv[1], "bridge") == 0)
 		family = AF_BRIDGE;
 	else {
 		fprintf(stderr, "Unknown family: ip, ip6, bridge\n");
 		exit(EXIT_FAILURE);
 	}
 
+	if (argc == 5 && strcmp(argv[4], "json") == 0 )
+		type = NFT_SET_O_JSON;
+
 	nlh = nft_set_nlmsg_build_hdr(buf, NFT_MSG_GETSETELEM, family,
 					NLM_F_DUMP|NLM_F_ACK, seq);
 	nft_set_attr_set(t, NFT_SET_ATTR_NAME, argv[3]);
@@ -100,7 +105,7 @@ int main(int argc, char *argv[])
 
 	ret = mnl_socket_recvfrom(nl, buf, sizeof(buf));
 	while (ret > 0) {
-		ret = mnl_cb_run(buf, ret, seq, portid, set_cb, NULL);
+		ret = mnl_cb_run(buf, ret, seq, portid, set_cb, &type);
 		if (ret <= 0)
 			break;
 		ret = mnl_socket_recvfrom(nl, buf, sizeof(buf));
diff --git a/examples/nft-set-get.c b/examples/nft-set-get.c
index d4588ba..5ef654c 100644
--- a/examples/nft-set-get.c
+++ b/examples/nft-set-get.c
@@ -23,6 +23,7 @@ static int set_cb(const struct nlmsghdr *nlh, void *data)
 {
 	struct nft_set *t;
 	char buf[4096];
+	uint32_t *type = data;
 
 	t = nft_set_alloc();
 	if (t == NULL) {
@@ -35,7 +36,7 @@ static int set_cb(const struct nlmsghdr *nlh, void *data)
 		goto err_free;
 	}
 
-	nft_set_snprintf(buf, sizeof(buf), t, 0, 0);
+	nft_set_snprintf(buf, sizeof(buf), t, *type, 0);
 	printf("%s\n", buf);
 
 err_free:
@@ -50,11 +51,12 @@ int main(int argc, char *argv[])
 	char buf[MNL_SOCKET_BUFFER_SIZE];
 	struct nlmsghdr *nlh;
 	uint32_t portid, seq, family;
+	uint32_t type = NFT_SET_O_DEFAULT;
 	struct nft_set *t = NULL;
 	int ret;
 
-	if (argc != 3) {
-		fprintf(stderr, "%s <family> <table>\n", argv[0]);
+	if (argc < 3 || argc > 4) {
+		fprintf(stderr, "%s <family> <table> [default|json]\n", argv[0]);
 		return EXIT_FAILURE;
 	}
 	t = nft_set_alloc();
@@ -67,13 +69,16 @@ int main(int argc, char *argv[])
 		family = AF_INET;
 	else if (strcmp(argv[1], "ip6") == 0)
 		family = AF_INET6;
-	else if (strcmp(argv[2], "bridge") == 0)
+	else if (strcmp(argv[1], "bridge") == 0)
 		family = AF_BRIDGE;
 	else {
 		fprintf(stderr, "Unknown family: ip, ip6, bridge\n");
 		exit(EXIT_FAILURE);
 	}
 
+	if (argc == 4 && strcmp(argv[3], "json") == 0)
+		type = NFT_SET_O_JSON;
+
 	nlh = nft_set_nlmsg_build_hdr(buf, NFT_MSG_GETSET, family,
 					NLM_F_DUMP|NLM_F_ACK, seq);
 	nft_set_attr_set(t, NFT_SET_ATTR_TABLE, argv[2]);
@@ -99,7 +104,7 @@ int main(int argc, char *argv[])
 
 	ret = mnl_socket_recvfrom(nl, buf, sizeof(buf));
 	while (ret > 0) {
-		ret = mnl_cb_run(buf, ret, seq, portid, set_cb, NULL);
+		ret = mnl_cb_run(buf, ret, seq, portid, set_cb, &type);
 		if (ret <= 0)
 			break;
 		ret = mnl_socket_recvfrom(nl, buf, sizeof(buf));
diff --git a/include/libnftables/set.h b/include/libnftables/set.h
index 63b30fc..2d41c8e 100644
--- a/include/libnftables/set.h
+++ b/include/libnftables/set.h
@@ -62,6 +62,11 @@ enum {
 	NFT_SET_ELEM_ATTR_DATA,
 };
 
+enum {
+	NFT_SET_O_DEFAULT	= 0,
+	NFT_SET_O_JSON,
+};
+
 struct nft_set_elem;
 
 struct nft_set_elem *nft_set_elem_alloc(void);
diff --git a/src/set.c b/src/set.c
index b8d431e..f60999c 100644
--- a/src/set.c
+++ b/src/set.c
@@ -316,8 +316,46 @@ int nft_set_nlmsg_parse(const struct nlmsghdr *nlh, struct nft_set *s)
 }
 EXPORT_SYMBOL(nft_set_nlmsg_parse);
 
-int nft_set_snprintf(char *buf, size_t size, struct nft_set *s,
-		     uint32_t type, uint32_t flags)
+static int nft_set_snprintf_json(char *buf, size_t size, struct nft_set *s,
+			   uint32_t type, uint32_t flags)
+{
+	int ret;
+	int len = size, offset = 0;
+	struct nft_set_elem *elem;
+
+	ret = snprintf(buf, size, "{ \"set\" : { \"name\" : \"%s\", \"table\" : \"%s\", \"flags\" : %u",
+			s->name, s->table, s->set_flags);
+	SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
+
+	/* Empty set? Skip printinf of elements */
+	if (list_empty(&s->element_list)){
+		ret = snprintf(buf+offset, size, "}}");
+		SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
+		return offset;
+	}
+
+	ret = snprintf(buf+offset, size, ", \"set_elem\" : [");
+	SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
+
+	list_for_each_entry(elem, &s->element_list, head) {
+		ret = snprintf(buf+offset, size, "{");
+		SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
+
+		ret = nft_set_elem_snprintf(buf+offset, size, elem, type, flags);
+		SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
+
+		ret = snprintf(buf+offset, size, "}, ");
+		SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
+	}
+
+	ret = snprintf(buf+offset-2, size, "]}}");
+	SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
+
+	return offset;
+}
+
+static int nft_set_snprintf_default(char *buf, size_t size, struct nft_set *s,
+			      uint32_t type, uint32_t flags)
 {
 	int ret;
 	int len = size, offset = 0;
@@ -344,6 +382,20 @@ int nft_set_snprintf(char *buf, size_t size, struct nft_set *s,
 
 	return offset;
 }
+
+int nft_set_snprintf(char *buf, size_t size, struct nft_set *s,
+		      uint32_t type, uint32_t flags)
+{
+	switch(type) {
+	case NFT_SET_O_DEFAULT:
+		return nft_set_snprintf_default(buf, size, s, type, flags);
+	case NFT_SET_O_JSON:
+		return nft_set_snprintf_json(buf, size, s, type, flags);
+	default:
+		break;
+	}
+	return -1;
+}
 EXPORT_SYMBOL(nft_set_snprintf);
 
 void nft_set_elem_add(struct nft_set *s, struct nft_set_elem *elem)
diff --git a/src/set_elem.c b/src/set_elem.c
index 0cbb9b7..288f843 100644
--- a/src/set_elem.c
+++ b/src/set_elem.c
@@ -384,8 +384,39 @@ int nft_set_elems_nlmsg_parse(const struct nlmsghdr *nlh, struct nft_set *s)
 }
 EXPORT_SYMBOL(nft_set_elems_nlmsg_parse);
 
-int nft_set_elem_snprintf(char *buf, size_t size, struct nft_set_elem *e,
-			  uint32_t type, uint32_t flags)
+static int nft_set_elem_snprintf_json(char *buf, size_t size, struct nft_set_elem *e)
+{
+	int ret, len = size, offset = 0, i;
+
+	ret = snprintf(buf, size, "\"flags\" : %u", e->set_elem_flags);
+	SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
+
+	if (e->key.len/sizeof(uint32_t) != 0) {
+		ret = snprintf(buf+offset, len, ", \"key\" : \"0x");
+		SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
+		for (i=0; i<e->key.len/sizeof(uint32_t); i++) {
+			ret = snprintf(buf+offset, len, "%.8x", e->key.val[i]);
+			SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
+		}
+		ret = snprintf(buf+offset, len, "\"");
+		SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
+	}
+
+	if (e->data.len/sizeof(uint32_t) != 0) {
+		ret = snprintf(buf+offset, size, " ,\"data\" : \"0x");
+		SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
+		for (i=0; i<e->data.len/sizeof(uint32_t); i++) {
+			ret = snprintf(buf+offset, len, "%.8x", e->data.val[i]);
+			SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
+		}
+		ret = snprintf(buf+offset, len, "\"");
+		SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
+	}
+
+	return offset;
+}
+
+static int nft_set_elem_snprintf_default(char *buf, size_t size, struct nft_set_elem *e)
 {
 	int ret, len = size, offset = 0, i;
 
@@ -407,6 +438,20 @@ int nft_set_elem_snprintf(char *buf, size_t size, struct nft_set_elem *e,
 
 	return offset;
 }
+
+int nft_set_elem_snprintf(char *buf, size_t size, struct nft_set_elem *e,
+			   uint32_t type, uint32_t flags)
+{
+	switch(type) {
+	case NFT_SET_O_DEFAULT:
+		return nft_set_elem_snprintf_default(buf, size, e);
+	case NFT_SET_O_JSON:
+		return nft_set_elem_snprintf_json(buf, size, e);
+	default:
+		break;
+	}
+	return -1;
+}
 EXPORT_SYMBOL(nft_set_elem_snprintf);
 
 int nft_set_elem_foreach(struct nft_set *s,

--
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

  reply	other threads:[~2013-07-05 12:41 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-07-05 12:41 [libnftables PATCH 0/2] Series Add Json Support Alvaro Neira
2013-07-05 12:41 ` Alvaro Neira [this message]
2013-07-05 22:22   ` [libnftables PATCH 1/2] set: add Json Export Support Pablo Neira Ayuso
2013-07-05 12:41 ` [libnftables PATCH 2/2] examples: nft-table-get different families options Alvaro Neira
2013-07-05 22:23   ` Pablo Neira Ayuso

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20130705124128.23285.30238.stgit@Ph0enix \
    --to=alvaroneay@gmail.com \
    --cc=eric@regit.org \
    --cc=netfilter-devel@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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.