]> git.ipfire.org Git - thirdparty/libnftnl.git/commitdiff
set: add json output
authorÁlvaro Neira Ayuso <alvaroneay@gmail.com>
Fri, 5 Jul 2013 12:41:28 +0000 (14:41 +0200)
committerPablo Neira Ayuso <pablo@netfilter.org>
Fri, 5 Jul 2013 22:00:45 +0000 (00:00 +0200)
This patch allows you to dump set and their content in json format.

Signed-off-by: Alvaro Neira Ayuso <alvaroneay@gmail.com>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
examples/nft-set-elem-get.c
examples/nft-set-get.c
include/libnftables/set.h
src/set.c
src/set_elem.c

index 34dfca2c3062202d2a71ddc92518f57d30ab8df6..353a752b61222b44c23bc8da623b854bee411abb 100644 (file)
@@ -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));
index d4588ba66c029d8ba07f052182a89362a2aa1aef..5ef654c0c19e30017cd7990bc07b4774e3877c79 100644 (file)
@@ -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));
index 63b30fc71e394f0832dc0bf9f18ff71f271650be..2d41c8e26efd4b15b72e610be91884c98e05f05b 100644 (file)
@@ -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);
index 69f25ac021fcf8eccfd3705f49fc635805cd1b55..4f2e8a51947df8daffdf27ea3e1a0c1c3d25ca71 100644 (file)
--- 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)
index 969189509de133e33115016204e8e011e9ac6200..c5c3de48232e684a588ee5231667a04f1d7c223f 100644 (file)
@@ -384,8 +384,41 @@ 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, numregs;
+
+       ret = snprintf(buf, size, "\"flags\" : %u", e->set_elem_flags);
+       SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
+
+       numregs = div_round_up(e->key.len, sizeof(uint32_t));
+       if (numregs != 0) {
+               ret = snprintf(buf+offset, len, ", \"key\" : \"0x");
+               SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
+               for (i = 0; i < numregs; 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);
+       }
+
+       numregs = div_round_up(e->data.len, sizeof(uint32_t));
+       if (numregs != 0) {
+               ret = snprintf(buf+offset, size, " ,\"data\" : \"0x");
+               SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
+               for (i = 0; i < numregs; 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;
 
@@ -410,6 +443,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,