diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/chain.c | 24 | ||||
-rw-r--r-- | src/common.c | 77 | ||||
-rw-r--r-- | src/internal.h | 6 | ||||
-rw-r--r-- | src/rule.c | 30 | ||||
-rw-r--r-- | src/ruleset.c | 38 | ||||
-rw-r--r-- | src/set.c | 30 | ||||
-rw-r--r-- | src/set_elem.c | 24 | ||||
-rw-r--r-- | src/table.c | 23 |
8 files changed, 218 insertions, 34 deletions
diff --git a/src/chain.c b/src/chain.c index 472203e..5311af6 100644 --- a/src/chain.c +++ b/src/chain.c @@ -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); diff --git a/src/common.c b/src/common.c index 336d2b4..929f25d 100644 --- a/src/common.c +++ b/src/common.c @@ -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); +} diff --git a/src/internal.h b/src/internal.h index ba994c8..6595e70 100644 --- a/src/internal.h +++ b/src/internal.h @@ -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); @@ -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); diff --git a/src/ruleset.c b/src/ruleset.c index 3cbec09..98c4367 100644 --- a/src/ruleset.c +++ b/src/ruleset.c @@ -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); @@ -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); diff --git a/src/set_elem.c b/src/set_elem.c index 05fd08b..1eddce2 100644 --- a/src/set_elem.c +++ b/src/set_elem.c @@ -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); diff --git a/src/table.c b/src/table.c index 44e9a7b..b4d1663 100644 --- a/src/table.c +++ b/src/table.c @@ -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); |