]> git.ipfire.org Git - thirdparty/libnftnl.git/commitdiff
src: add flag to add event wrapping in output functions
authorArturo Borrero <arturo.borrero.glez@gmail.com>
Tue, 15 Apr 2014 18:12:58 +0000 (20:12 +0200)
committerPablo Neira Ayuso <pablo@netfilter.org>
Sat, 26 Apr 2014 12:06:49 +0000 (14:06 +0200)
This patch uses the flag option of each output function to print an
event wrapper string in each object.

In order to use this functionality, the caller must pass the
corresponding flags: NFT_OF_EVENT_NEW / NFT_OF_EVENT_DEL.

(I have slightly refactorized the original code to add the xml/json
 header and footer --pablo).

Signed-off-by: Arturo Borrero Gonzalez <arturo.borrero.glez@gmail.com>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
include/libnftnl/common.h
src/chain.c
src/common.c
src/internal.h
src/rule.c
src/ruleset.c
src/set.c
src/set_elem.c
src/table.c

index f0c20f06eeccd0b800447770848065ba0e1207da..04d2906231d97ae82a24b5ee26b088ab1f33bbb7 100644 (file)
@@ -15,6 +15,12 @@ enum nft_output_type {
        NFT_OUTPUT_JSON,
 };
 
+enum nft_output_flags {
+       NFT_OF_EVENT_NEW        = (1 << 0),
+       NFT_OF_EVENT_DEL        = (1 << 1),
+       NFT_OF_EVENT_ANY        = (NFT_OF_EVENT_NEW | NFT_OF_EVENT_DEL),
+};
+
 enum nft_parse_type {
        NFT_PARSE_NONE          = 0,
        NFT_PARSE_XML,
index 472203ed6d53d602f78159516168cb4d2f23f5a9..5311af643354351017f124033ccffeff3abcd0a3 100644 (file)
@@ -924,17 +924,31 @@ static int nft_chain_snprintf_default(char *buf, size_t size,
 int nft_chain_snprintf(char *buf, size_t size, struct nft_chain *c,
                       uint32_t type, uint32_t flags)
 {
+       int ret, len = size, offset = 0;
+
+       ret = nft_event_header_snprintf(buf+offset, len, type, flags);
+       SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
+
        switch(type) {
        case NFT_OUTPUT_DEFAULT:
-               return nft_chain_snprintf_default(buf, size, c);
+               ret = nft_chain_snprintf_default(buf+offset, len, c);
+               break;
        case NFT_OUTPUT_XML:
-               return nft_chain_snprintf_xml(buf, size, c);
+               ret = nft_chain_snprintf_xml(buf+offset, len, c);
+               break;
        case NFT_OUTPUT_JSON:
-               return nft_chain_snprintf_json(buf, size, c);
-       default:
+               ret = nft_chain_snprintf_json(buf+offset, len, c);
                break;
+       default:
+               return -1;
        }
-       return -1;
+
+       SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
+
+       ret = nft_event_footer_snprintf(buf+offset, len, type, flags);
+       SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
+
+       return offset;
 }
 EXPORT_SYMBOL(nft_chain_snprintf);
 
index 336d2b4f7d3a1c16b99ec7a3a405b773bcf4c516..929f25d6d78b70f998f35c817bb8e7df1c13bce9 100644 (file)
@@ -66,3 +66,80 @@ int nft_parse_perror(const char *str, struct nft_parse_err *err)
        }
 }
 EXPORT_SYMBOL(nft_parse_perror);
+
+int nft_event_header_snprintf(char *buf, size_t size, uint32_t type,
+                             uint32_t flags)
+{
+       int ret = 0;
+
+       switch (type) {
+       case NFT_OUTPUT_XML:
+               if (flags & NFT_OF_EVENT_NEW) {
+                       ret = snprintf(buf, size, "<event><type>new</type>");
+               } else if (flags & NFT_OF_EVENT_DEL) {
+                       ret = snprintf(buf, size,
+                                      "<event><type>delete</type>");
+               } else {
+                       ret = snprintf(buf, size,
+                                      "<event><type>unknown</type>");
+               }
+               break;
+       case NFT_OUTPUT_JSON:
+               if (flags & NFT_OF_EVENT_NEW) {
+                       ret = snprintf(buf, size, "{event:{type:\"new\",{\"");
+               } else if (flags & NFT_OF_EVENT_DEL) {
+                       ret = snprintf(buf, size,
+                                      "{event:{type:\"delete\",{\"");
+               } else {
+                       ret = snprintf(buf, size,
+                                      "{event:{type:\"unknown\",{\"");
+               }
+               break;
+       default:
+               if (flags & NFT_OF_EVENT_NEW) {
+                       ret = snprintf(buf, size, "%9s", "[NEW] ");
+               } else if (flags & NFT_OF_EVENT_DEL) {
+                       ret = snprintf(buf, size, "%9s", "[DELETE] ");
+               } else {
+                       ret = snprintf(buf, size, "%9s", "[unknown] ");
+               }
+               break;
+       }
+       return ret;
+}
+
+int nft_event_header_fprintf(FILE *fp, uint32_t type, uint32_t flags)
+{
+       char buf[64]; /* enough for the maximum string length above */
+
+       nft_event_header_snprintf(buf, sizeof(buf), type, flags);
+       buf[sizeof(buf) - 1] = '\0';
+
+       return fprintf(fp, "%s", buf);
+}
+
+int nft_event_footer_snprintf(char *buf, size_t size, uint32_t type,
+                             uint32_t flags)
+{
+       if (!(flags & NFT_OF_EVENT_ANY))
+               return 0;
+
+       switch (type) {
+       case NFT_OUTPUT_XML:
+               return snprintf(buf, size, "</event>");
+       case NFT_OUTPUT_JSON:
+               return snprintf(buf, size, "}}}");
+       default:
+               return 0;
+       }
+}
+
+int nft_event_footer_fprintf(FILE *fp, uint32_t type, uint32_t flags)
+{
+       char buf[32]; /* enough for the maximum string length above */
+
+       nft_event_footer_snprintf(buf, sizeof(buf), type, flags);
+       buf[sizeof(buf) - 1] = '\0';
+
+       return fprintf(fp, "%s", buf);
+}
index ba994c82f29cd5bf773d07a50e2801534f32b512..6595e707d2b458cb89b51ef8f8cd81623e7a7182 100644 (file)
@@ -136,6 +136,12 @@ int nft_get_value(enum nft_type type, void *val, void *out);
 
 #include <stdio.h>
 int nft_fprintf(FILE *fp, void *obj, uint32_t type, uint32_t flags, int (*snprintf_cb)(char *buf, size_t bufsiz, void *obj, uint32_t type, uint32_t flags));
+int nft_event_header_snprintf(char *buf, size_t bufsize,
+                             uint32_t format, uint32_t flags);
+int nft_event_header_fprintf(FILE *fp, uint32_t format, uint32_t flags);
+int nft_event_footer_snprintf(char *buf, size_t bufsize,
+                             uint32_t format, uint32_t flags);
+int nft_event_footer_fprintf(FILE *fp, uint32_t format, uint32_t flags);
 
 void xfree(const void *ptr);
 
index df9dd803ca16924475520e2015a63650a6ed84a4..ac88abb48bb646d98cff611d53eb73e4c7a84176 100644 (file)
@@ -967,17 +967,37 @@ static int nft_rule_snprintf_default(char *buf, size_t size, struct nft_rule *r,
 int nft_rule_snprintf(char *buf, size_t size, struct nft_rule *r,
                       uint32_t type, uint32_t flags)
 {
+       int ret, len = size, offset = 0;
+       uint32_t inner_flags = flags;
+
+       inner_flags &= ~NFT_OF_EVENT_ANY;
+
+       ret = nft_event_header_snprintf(buf+offset, len, type, flags);
+       SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
+
        switch(type) {
        case NFT_OUTPUT_DEFAULT:
-               return nft_rule_snprintf_default(buf, size, r, type, flags);
+               ret = nft_rule_snprintf_default(buf+offset, len, r, type,
+                                               inner_flags);
+               break;
        case NFT_OUTPUT_XML:
-               return nft_rule_snprintf_xml(buf, size, r, type, flags);
+               ret = nft_rule_snprintf_xml(buf+offset, len, r, type,
+                                           inner_flags);
+               break;
        case NFT_OUTPUT_JSON:
-               return nft_rule_snprintf_json(buf, size, r, type, flags);
-       default:
+               ret = nft_rule_snprintf_json(buf+offset, len, r, type,
+                                            inner_flags);
                break;
+       default:
+               return -1;
        }
-       return -1;
+
+       SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
+
+       ret = nft_event_footer_snprintf(buf+offset, len, type, flags);
+       SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
+
+       return offset;
 }
 EXPORT_SYMBOL(nft_rule_snprintf);
 
index 3cbec09050b873aafd60f85041cbab859b2de6eb..98c4367b1244cefe4bfcd9676cd3b10c27cea664 100644 (file)
@@ -765,14 +765,21 @@ nft_ruleset_do_snprintf(char *buf, size_t size, const struct nft_ruleset *rs,
 {
        int ret, len = size, offset = 0;
        void *prev = NULL;
+       uint32_t inner_flags = flags;
 
-       ret = snprintf(buf+offset, size, "%s", nft_ruleset_o_opentag(type));
+       /* dont pass events flags to child calls of _snprintf() */
+       inner_flags &= ~NFT_OF_EVENT_ANY;
+
+       ret = nft_event_header_snprintf(buf+offset, len, type, flags);
+       SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
+
+       ret = snprintf(buf+offset, len, "%s", nft_ruleset_o_opentag(type));
        SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
 
        if (nft_ruleset_attr_is_set(rs, NFT_RULESET_ATTR_TABLELIST) &&
            (!nft_table_list_is_empty(rs->table_list))) {
                ret = nft_ruleset_snprintf_table(buf+offset, len, rs,
-                                                type, flags);
+                                                type, inner_flags);
                SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
 
                if (ret > 0)
@@ -786,7 +793,7 @@ nft_ruleset_do_snprintf(char *buf, size_t size, const struct nft_ruleset *rs,
                SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
 
                ret = nft_ruleset_snprintf_chain(buf+offset, len, rs,
-                                                type, flags);
+                                                type, inner_flags);
                SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
 
                if (ret > 0)
@@ -800,7 +807,7 @@ nft_ruleset_do_snprintf(char *buf, size_t size, const struct nft_ruleset *rs,
                SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
 
                ret = nft_ruleset_snprintf_set(buf+offset, len, rs,
-                                              type, flags);
+                                              type, inner_flags);
                SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
 
                if (ret > 0)
@@ -814,13 +821,16 @@ nft_ruleset_do_snprintf(char *buf, size_t size, const struct nft_ruleset *rs,
                SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
 
                ret = nft_ruleset_snprintf_rule(buf+offset, len, rs,
-                                               type, flags);
+                                               type, inner_flags);
                SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
        }
 
        ret = snprintf(buf+offset, size, "%s", nft_ruleset_o_closetag(type));
        SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
 
+       ret = nft_event_footer_snprintf(buf+offset, len, type, flags);
+       SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
+
        return offset;
 }
 
@@ -989,13 +999,20 @@ int nft_ruleset_fprintf(FILE *fp, const struct nft_ruleset *rs, uint32_t type,
 {
        int len = 0, ret = 0;
        void *prev = NULL;
+       uint32_t inner_flags = flags;
+
+       /* dont pass events flags to child calls of _snprintf() */
+       inner_flags &= ~NFT_OF_EVENT_ANY;
+
+       ret = nft_event_header_fprintf(fp, type, flags);
+       NFT_FPRINTF_RETURN_OR_FIXLEN(ret, len);
 
        ret = fprintf(fp, "%s", nft_ruleset_o_opentag(type));
        NFT_FPRINTF_RETURN_OR_FIXLEN(ret, len);
 
        if ((nft_ruleset_attr_is_set(rs, NFT_RULESET_ATTR_TABLELIST)) &&
            (!nft_table_list_is_empty(rs->table_list))) {
-               ret = nft_ruleset_fprintf_tables(fp, rs, type, flags);
+               ret = nft_ruleset_fprintf_tables(fp, rs, type, inner_flags);
                NFT_FPRINTF_RETURN_OR_FIXLEN(ret, len);
 
                if (ret > 0)
@@ -1007,7 +1024,7 @@ int nft_ruleset_fprintf(FILE *fp, const struct nft_ruleset *rs, uint32_t type,
                ret = fprintf(fp, "%s", nft_ruleset_o_separator(prev, type));
                NFT_FPRINTF_RETURN_OR_FIXLEN(ret, len);
 
-               ret = nft_ruleset_fprintf_chains(fp, rs, type, flags);
+               ret = nft_ruleset_fprintf_chains(fp, rs, type, inner_flags);
                NFT_FPRINTF_RETURN_OR_FIXLEN(ret, len);
 
                if (ret > 0)
@@ -1019,7 +1036,7 @@ int nft_ruleset_fprintf(FILE *fp, const struct nft_ruleset *rs, uint32_t type,
                ret = fprintf(fp, "%s", nft_ruleset_o_separator(prev, type));
                NFT_FPRINTF_RETURN_OR_FIXLEN(ret, len);
 
-               ret = nft_ruleset_fprintf_sets(fp, rs, type, flags);
+               ret = nft_ruleset_fprintf_sets(fp, rs, type, inner_flags);
                NFT_FPRINTF_RETURN_OR_FIXLEN(ret, len);
 
                if (ret > 0)
@@ -1031,13 +1048,16 @@ int nft_ruleset_fprintf(FILE *fp, const struct nft_ruleset *rs, uint32_t type,
                ret = fprintf(fp, "%s", nft_ruleset_o_separator(prev, type));
                NFT_FPRINTF_RETURN_OR_FIXLEN(ret, len);
 
-               ret = nft_ruleset_fprintf_rules(fp, rs, type, flags);
+               ret = nft_ruleset_fprintf_rules(fp, rs, type, inner_flags);
                NFT_FPRINTF_RETURN_OR_FIXLEN(ret, len);
        }
 
        ret = fprintf(fp, "%s", nft_ruleset_o_closetag(type));
        NFT_FPRINTF_RETURN_OR_FIXLEN(ret, len);
 
+       ret = nft_event_footer_fprintf(fp, type, flags);
+       NFT_FPRINTF_RETURN_OR_FIXLEN(ret, len);
+
        return len;
 }
 EXPORT_SYMBOL(nft_ruleset_fprintf);
index 550c262a619e51c550a69098ab2a3431e61bd93b..7c158571f477e84185584f705b64d1faf0c3b519 100644 (file)
--- a/src/set.c
+++ b/src/set.c
@@ -704,17 +704,37 @@ static int nft_set_snprintf_xml(char *buf, size_t size, struct nft_set *s,
 int nft_set_snprintf(char *buf, size_t size, struct nft_set *s,
                     uint32_t type, uint32_t flags)
 {
+       int ret, len = size, offset = 0;
+       uint32_t inner_flags = flags;
+
+       /* prevent set_elems to print as events */
+       inner_flags &= ~NFT_OF_EVENT_ANY;
+
+       ret = nft_event_header_snprintf(buf+offset, len, type, flags);
+       SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
+
        switch(type) {
        case NFT_OUTPUT_DEFAULT:
-               return nft_set_snprintf_default(buf, size, s, type, flags);
+               ret = nft_set_snprintf_default(buf+offset, len, s, type,
+                                              inner_flags);
+               break;
        case NFT_OUTPUT_XML:
-               return nft_set_snprintf_xml(buf, size, s, flags);
+               ret = nft_set_snprintf_xml(buf+offset, len, s, inner_flags);
+               break;
        case NFT_OUTPUT_JSON:
-               return nft_set_snprintf_json(buf, size, s, type, flags);
-       default:
+               ret = nft_set_snprintf_json(buf+offset, len, s, type,
+                                           inner_flags);
                break;
+       default:
+               return -1;
        }
-       return -1;
+
+       SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
+
+       ret = nft_event_footer_snprintf(buf+offset, len, type, flags);
+       SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
+
+       return offset;
 }
 EXPORT_SYMBOL(nft_set_snprintf);
 
index 05fd08b59c36205aa9f9f067dedd9a2f0ceab675..1eddce2e9a74bd0ae800584252c940647b58d61b 100644 (file)
@@ -597,17 +597,31 @@ static int nft_set_elem_snprintf_xml(char *buf, size_t size,
 int nft_set_elem_snprintf(char *buf, size_t size, struct nft_set_elem *e,
                           uint32_t type, uint32_t flags)
 {
+       int ret, len = size, offset = 0;
+
+       ret = nft_event_header_snprintf(buf+offset, len, type, flags);
+       SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
+
        switch(type) {
        case NFT_OUTPUT_DEFAULT:
-               return nft_set_elem_snprintf_default(buf, size, e);
+               ret = nft_set_elem_snprintf_default(buf+offset, len, e);
+               break;
        case NFT_OUTPUT_XML:
-               return nft_set_elem_snprintf_xml(buf, size, e, flags);
+               ret = nft_set_elem_snprintf_xml(buf+offset, len, e, flags);
+               break;
        case NFT_OUTPUT_JSON:
-               return nft_set_elem_snprintf_json(buf, size, e, flags);
-       default:
+               ret = nft_set_elem_snprintf_json(buf+offset, len, e, flags);
                break;
+       default:
+               return -1;
        }
-       return -1;
+
+       SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
+
+       ret = nft_event_footer_snprintf(buf+offset, len, type, flags);
+       SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
+
+       return offset;
 }
 EXPORT_SYMBOL(nft_set_elem_snprintf);
 
index 44e9a7b50de4b784b18cc0635fbdf66ceb2cb787..b4d1663a5297096d4b950f50d32dd323efb06247 100644 (file)
@@ -441,17 +441,30 @@ static int nft_table_snprintf_default(char *buf, size_t size, struct nft_table *
 int nft_table_snprintf(char *buf, size_t size, struct nft_table *t,
                       uint32_t type, uint32_t flags)
 {
+       int ret, len = size, offset = 0;
+
+       ret = nft_event_header_snprintf(buf+offset, len, type, flags);
+       SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
+
        switch(type) {
        case NFT_OUTPUT_DEFAULT:
-               return nft_table_snprintf_default(buf, size, t);
+               ret = nft_table_snprintf_default(buf+offset, len, t);
+               break;
        case NFT_OUTPUT_XML:
-               return nft_table_snprintf_xml(buf, size, t);
+               ret = nft_table_snprintf_xml(buf+offset, len, t);
+               break;
        case NFT_OUTPUT_JSON:
-               return nft_table_snprintf_json(buf, size, t);
-       default:
+               ret = nft_table_snprintf_json(buf+offset, len, t);
                break;
+       default:
+               return -1;
        }
-       return -1;
+       SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
+
+       ret = nft_event_footer_snprintf(buf+offset, len, type, flags);
+       SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
+
+       return offset;
 }
 EXPORT_SYMBOL(nft_table_snprintf);