diff options
-rw-r--r-- | include/Makefile.am | 3 | ||||
-rw-r--r-- | include/buffer.h | 80 | ||||
-rw-r--r-- | src/Makefile.am | 1 | ||||
-rw-r--r-- | src/buffer.c | 160 | ||||
-rw-r--r-- | src/chain.c | 174 | ||||
-rw-r--r-- | src/expr/bitwise.c | 112 | ||||
-rw-r--r-- | src/expr/byteorder.c | 101 | ||||
-rw-r--r-- | src/expr/cmp.c | 65 | ||||
-rw-r--r-- | src/expr/counter.c | 48 | ||||
-rw-r--r-- | src/expr/ct.c | 73 | ||||
-rw-r--r-- | src/expr/exthdr.c | 75 | ||||
-rw-r--r-- | src/expr/immediate.c | 71 | ||||
-rw-r--r-- | src/expr/limit.c | 50 | ||||
-rw-r--r-- | src/expr/log.c | 98 | ||||
-rw-r--r-- | src/expr/lookup.c | 56 | ||||
-rw-r--r-- | src/expr/masq.c | 33 | ||||
-rw-r--r-- | src/expr/match.c | 35 | ||||
-rw-r--r-- | src/expr/meta.c | 64 | ||||
-rw-r--r-- | src/expr/nat.c | 102 | ||||
-rw-r--r-- | src/expr/payload.c | 69 | ||||
-rw-r--r-- | src/expr/queue.c | 65 | ||||
-rw-r--r-- | src/expr/redir.c | 64 | ||||
-rw-r--r-- | src/expr/reject.c | 51 | ||||
-rw-r--r-- | src/expr/target.c | 35 | ||||
-rw-r--r-- | src/table.c | 86 | ||||
-rw-r--r-- | tests/jsonfiles/11-chain.json | 2 | ||||
-rw-r--r-- | tests/jsonfiles/12-chain.json | 2 | ||||
-rw-r--r-- | tests/jsonfiles/13-chain.json | 2 | ||||
-rw-r--r-- | tests/xmlfiles/10-chain.xml | 2 | ||||
-rw-r--r-- | tests/xmlfiles/11-chain.xml | 2 | ||||
-rw-r--r-- | tests/xmlfiles/12-chain.xml | 2 |
31 files changed, 573 insertions, 1210 deletions
diff --git a/include/Makefile.am b/include/Makefile.am index 5976bbd..102d5ab 100644 --- a/include/Makefile.am +++ b/include/Makefile.am @@ -1,3 +1,4 @@ SUBDIRS = libnftnl linux -noinst_HEADERS = linux_list.h +noinst_HEADERS = linux_list.h \ + buffer.h diff --git a/include/buffer.h b/include/buffer.h new file mode 100644 index 0000000..2b497f2 --- /dev/null +++ b/include/buffer.h @@ -0,0 +1,80 @@ +#ifndef _NFT_BUFFER_H_ +#define _NFT_BUFFER_H_ + +#include <stdint.h> +#include <stdbool.h> + +struct nft_buf { + char *buf; + size_t size; + size_t len; + uint32_t off; + bool fail; +}; + +#define NFT_BUF_INIT(__b, __buf, __len) \ + struct nft_buf __b = { \ + .buf = __buf, \ + .len = __len, \ + }; + +int nft_buf_update(struct nft_buf *b, int ret); +int nft_buf_done(struct nft_buf *b); + +union nft_data_reg; + +int nft_buf_open(struct nft_buf *b, int type, const char *tag); +int nft_buf_close(struct nft_buf *b, int type, const char *tag); + +int nft_buf_u32(struct nft_buf *b, int type, uint32_t value, const char *tag); +int nft_buf_s32(struct nft_buf *b, int type, uint32_t value, const char *tag); +int nft_buf_u64(struct nft_buf *b, int type, uint64_t value, const char *tag); +int nft_buf_str(struct nft_buf *b, int type, const char *str, const char *tag); +int nft_buf_reg(struct nft_buf *b, int type, union nft_data_reg *reg, + int reg_type, const char *tag); + +#define BASE "base" +#define BYTES "bytes" +#define CHAIN "chain" +#define CODE "code" +#define DATA "data" +#define DIR "dir" +#define DREG "dreg" +#define EXTHDR_TYPE "exthdr_type" +#define FAMILY "family" +#define FLAGS "flags" +#define GROUP "group" +#define HANDLE "handle" +#define HOOKNUM "hooknum" +#define KEY "key" +#define LEN "len" +#define LEVEL "level" +#define MASK "mask" +#define NAT_TYPE "nat_type" +#define NAME "name" +#define NUM "num" +#define OFFSET "offset" +#define OP "op" +#define PACKETS "packets" +#define PKTS "pkts" +#define POLICY "policy" +#define PREFIX "prefix" +#define PRIO "prio" +#define QTHRESH "qthreshold" +#define RATE "rate" +#define SET "set" +#define SIZE "size" +#define SNAPLEN "snaplen" +#define SREG_ADDR_MAX "sreg_addr_max" +#define SREG_ADDR_MIN "sreg_addr_min" +#define SREG_PROTO_MAX "sreg_proto_max" +#define SREG_PROTO_MIN "sreg_proto_min" +#define SREG "sreg" +#define TABLE "table" +#define TOTAL "total" +#define TYPE "type" +#define UNIT "unit" +#define USE "use" +#define XOR "xor" + +#endif diff --git a/src/Makefile.am b/src/Makefile.am index 941e69e..c77c3cc 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -6,6 +6,7 @@ libnftnl_la_LDFLAGS = -Wl,--version-script=$(srcdir)/libnftnl.map \ -version-info $(LIBVERSION) libnftnl_la_SOURCES = utils.c \ + buffer.c \ common.c \ gen.c \ table.c \ diff --git a/src/buffer.c b/src/buffer.c new file mode 100644 index 0000000..4fac110 --- /dev/null +++ b/src/buffer.c @@ -0,0 +1,160 @@ +/* + * (C) 2012-2014 by Pablo Neira Ayuso <pablo@netfilter.org> + * + * 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 <stdio.h> +#include <stdint.h> +#include <inttypes.h> +#include <string.h> +#include <buffer.h> +#include <libnftnl/common.h> +#include "internal.h" + +int nft_buf_update(struct nft_buf *b, int ret) +{ + if (ret < 0) { + b->fail = true; + } else { + b->off += ret; + if (ret > b->len) + ret = b->len; + b->size += ret; + b->len -= ret; + } + + return ret; +} + +int nft_buf_done(struct nft_buf *b) +{ + if (b->fail) + return -1; + + /* Remove trailing comma in json */ + if (b->size > 0 && b->buf[b->size - 1] == ',') { + b->off--; + b->size--; + b->len++; + } + + return b->off; +} + +static int nft_buf_put(struct nft_buf *b, const char *fmt, ...) +{ + int ret; + va_list ap; + + va_start(ap, fmt); + ret = vsnprintf(b->buf + b->off, b->len, fmt, ap); + ret = nft_buf_update(b, ret); + va_end(ap); + + return ret; +} + +int nft_buf_open(struct nft_buf *b, int type, const char *tag) +{ + switch (type) { + case NFT_OUTPUT_XML: + return nft_buf_put(b, "<%s>", tag); + case NFT_OUTPUT_JSON: + return nft_buf_put(b, "{\"%s\":{", tag); + default: + return 0; + } +} + +int nft_buf_close(struct nft_buf *b, int type, const char *tag) +{ + switch (type) { + case NFT_OUTPUT_XML: + return nft_buf_put(b, "</%s>"); + case NFT_OUTPUT_JSON: + /* Remove trailing comma in json */ + if (b->size > 0 && b->buf[b->size - 1] == ',') { + b->off--; + b->size--; + b->len++; + } + + return nft_buf_put(b, "}}"); + default: + return 0; + } +} + +int nft_buf_u32(struct nft_buf *b, int type, uint32_t value, const char *tag) +{ + switch (type) { + case NFT_OUTPUT_XML: + return nft_buf_put(b, "<%s>%u</%s>", tag, value, tag); + case NFT_OUTPUT_JSON: + return nft_buf_put(b, "\"%s\":%u,", tag, value); + default: + return 0; + } +} + +int nft_buf_s32(struct nft_buf *b, int type, uint32_t value, const char *tag) +{ + switch (type) { + case NFT_OUTPUT_XML: + return nft_buf_put(b, "<%s>%d</%s>", tag, value, tag); + case NFT_OUTPUT_JSON: + return nft_buf_put(b, "\"%s\":%d,", tag, value); + default: + return 0; + } +} + +int nft_buf_u64(struct nft_buf *b, int type, uint64_t value, const char *tag) +{ + switch (type) { + case NFT_OUTPUT_XML: + return nft_buf_put(b, "<%s>%"PRIu64"</%s>", tag, value, tag); + case NFT_OUTPUT_JSON: + return nft_buf_put(b, "\"%s\":%"PRIu64",", tag, value); + default: + return 0; + } +} + +int nft_buf_str(struct nft_buf *b, int type, const char *str, const char *tag) +{ + switch (type) { + case NFT_OUTPUT_XML: + return nft_buf_put(b, "<%s>%s</%s>", tag, str, tag); + case NFT_OUTPUT_JSON: + return nft_buf_put(b, "\"%s\":\"%s\",", tag, str); + default: + return 0; + } +} + +int nft_buf_reg(struct nft_buf *b, int type, union nft_data_reg *reg, + int reg_type, const char *tag) +{ + int ret; + + switch (type) { + case NFT_OUTPUT_XML: + ret = nft_buf_put(b, "<%s>", tag); + ret = nft_data_reg_snprintf(b->buf + b->off, b->len, reg, + NFT_OUTPUT_XML, 0, reg_type); + nft_buf_update(b, ret); + return nft_buf_put(b, "</%s>", tag); + case NFT_OUTPUT_JSON: + nft_buf_put(b, "\"%s\":{", tag); + ret = nft_data_reg_snprintf(b->buf + b->off, b->len, reg, + NFT_OUTPUT_JSON, 0, reg_type); + nft_buf_update(b, ret); + return nft_buf_put(b, "},"); + } + return 0; +} diff --git a/src/chain.c b/src/chain.c index a056bab..b67385e 100644 --- a/src/chain.c +++ b/src/chain.c @@ -27,6 +27,7 @@ #include <linux/netfilter_arp.h> #include <libnftnl/chain.h> +#include <buffer.h> struct nft_chain { struct list_head head; @@ -787,150 +788,41 @@ int nft_chain_parse_file(struct nft_chain *c, enum nft_parse_type type, } EXPORT_SYMBOL(nft_chain_parse_file); -static int nft_chain_snprintf_json(char *buf, size_t size, struct nft_chain *c) +static int nft_chain_export(char *buf, size_t size, struct nft_chain *c, + int type) { - int ret, len = size, offset = 0; - - ret = snprintf(buf, len, "{\"chain\":{"); - SNPRINTF_BUFFER_SIZE(ret, size, len, offset); - - ret = 0; - - if (c->flags & (1 << NFT_CHAIN_ATTR_NAME)) { - ret = snprintf(buf + offset, len, "\"name\":\"%s\",", c->name); - SNPRINTF_BUFFER_SIZE(ret, size, len, offset); - } - if (c->flags & (1 << NFT_CHAIN_ATTR_HANDLE)) { - ret = snprintf(buf + offset, len, "\"handle\":%"PRIu64",", - c->handle); - SNPRINTF_BUFFER_SIZE(ret, size, len, offset); - } - if (c->flags & (1 << NFT_CHAIN_ATTR_BYTES)) { - ret = snprintf(buf + offset, len, "\"bytes\":%"PRIu64",", - c->bytes); - SNPRINTF_BUFFER_SIZE(ret, size, len, offset); - } - if (c->flags & (1 << NFT_CHAIN_ATTR_PACKETS)) { - ret = snprintf(buf + offset, len, "\"packets\":%"PRIu64",", - c->packets); - SNPRINTF_BUFFER_SIZE(ret, size, len, offset); - } - if (c->flags & (1 << NFT_CHAIN_ATTR_FAMILY)) { - ret = snprintf(buf + offset, len, "\"family\":\"%s\",", - nft_family2str(c->family)); - SNPRINTF_BUFFER_SIZE(ret, size, len, offset); - } - if (c->flags & (1 << NFT_CHAIN_ATTR_FAMILY)) { - ret = snprintf(buf + offset, len, "\"table\":\"%s\",", - c->table); - SNPRINTF_BUFFER_SIZE(ret, size, len, offset); - } - if (c->flags & (1 << NFT_CHAIN_ATTR_USE)) { - ret = snprintf(buf + offset, len, "\"use\":%d,", c->use); - SNPRINTF_BUFFER_SIZE(ret, size, len, offset); - } - if (c->flags & (1 << NFT_CHAIN_ATTR_HOOKNUM)) { - if (c->flags & (1 << NFT_CHAIN_ATTR_TYPE)) { - ret = snprintf(buf + offset, len, "\"type\":\"%s\",", - c->type); - SNPRINTF_BUFFER_SIZE(ret, size, len, offset); - } + NFT_BUF_INIT(b, buf, size); - ret = snprintf(buf + offset, len, "\"hooknum\":\"%s\",", - nft_hooknum2str(c->family, c->hooknum)); - SNPRINTF_BUFFER_SIZE(ret, size, len, offset); - - if (c->flags & (1 << NFT_CHAIN_ATTR_PRIO)) { - ret = snprintf(buf + offset, len, "\"prio\":%d,", - c->prio); - SNPRINTF_BUFFER_SIZE(ret, size, len, offset); - } - if (c->flags & (1 << NFT_CHAIN_ATTR_POLICY)) { - ret = snprintf(buf + offset, len, "\"policy\":\"%s\",", - nft_verdict2str(c->policy)); - SNPRINTF_BUFFER_SIZE(ret, size, len, offset); - } - } - - /* If ret is not 0, some values are printed. So, It's necessary to - * delete the last comma character - */ - if (ret > 0) - offset--; - - ret = snprintf(buf + offset, len, "}}"); - SNPRINTF_BUFFER_SIZE(ret, size, len, offset); - - return offset; -} - -static int nft_chain_snprintf_xml(char *buf, size_t size, struct nft_chain *c) -{ - int ret, len = size, offset = 0; - - ret = snprintf(buf, len, "<chain>"); - SNPRINTF_BUFFER_SIZE(ret, size, len, offset); - - if (c->flags & (1 << NFT_CHAIN_ATTR_NAME)) { - ret = snprintf(buf + offset, len, "<name>%s</name>", c->name); - SNPRINTF_BUFFER_SIZE(ret, size, len, offset); - } - if (c->flags & (1 << NFT_CHAIN_ATTR_HANDLE)) { - ret = snprintf(buf + offset, len, "<handle>%"PRIu64"</handle>", - c->handle); - SNPRINTF_BUFFER_SIZE(ret, size, len, offset); - } - if (c->flags & (1 << NFT_CHAIN_ATTR_BYTES)) { - ret = snprintf(buf + offset, len, "<bytes>%"PRIu64"</bytes>", - c->bytes); - SNPRINTF_BUFFER_SIZE(ret, size, len, offset); - } - if (c->flags & (1 << NFT_CHAIN_ATTR_PACKETS)) { - ret = snprintf(buf + offset, len, "<packets>%"PRIu64"</packets>", - c->packets); - SNPRINTF_BUFFER_SIZE(ret, size, len, offset); - } - if (c->flags & (1 << NFT_CHAIN_ATTR_TABLE)) { - ret = snprintf(buf + offset, len, "<table>%s</table>", - c->table); - SNPRINTF_BUFFER_SIZE(ret, size, len, offset); - } - if (c->flags & (1 << NFT_CHAIN_ATTR_USE)) { - ret = snprintf(buf + offset, len, "<use>%u</use>", c->use); - SNPRINTF_BUFFER_SIZE(ret, size, len, offset); - } + nft_buf_open(&b, type, CHAIN); + if (c->flags & (1 << NFT_CHAIN_ATTR_NAME)) + nft_buf_str(&b, type, c->name, NAME); + if (c->flags & (1 << NFT_CHAIN_ATTR_HANDLE)) + nft_buf_u64(&b, type, c->handle, HANDLE); + if (c->flags & (1 << NFT_CHAIN_ATTR_BYTES)) + nft_buf_u64(&b, type, c->bytes, BYTES); + if (c->flags & (1 << NFT_CHAIN_ATTR_PACKETS)) + nft_buf_u64(&b, type, c->packets, PACKETS); + if (c->flags & (1 << NFT_CHAIN_ATTR_TABLE)) + nft_buf_str(&b, type, c->table, TABLE); + if (c->flags & (1 << NFT_CHAIN_ATTR_FAMILY)) + nft_buf_str(&b, type, nft_family2str(c->family), FAMILY); + if (c->flags & (1 << NFT_CHAIN_ATTR_USE)) + nft_buf_u32(&b, type, c->use, USE); if (c->flags & (1 << NFT_CHAIN_ATTR_HOOKNUM)) { - if (c->flags & (1 << NFT_CHAIN_ATTR_TYPE)) { - ret = snprintf(buf + offset, len, "<type>%s</type>", - c->type); - SNPRINTF_BUFFER_SIZE(ret, size, len, offset); - } - - ret = snprintf(buf + offset, len, "<hooknum>%s</hooknum>", - nft_hooknum2str(c->family, c->hooknum)); - SNPRINTF_BUFFER_SIZE(ret, size, len, offset); - - if (c->flags & (1 << NFT_CHAIN_ATTR_PRIO)) { - ret = snprintf(buf + offset, len, "<prio>%d</prio>", - c->prio); - SNPRINTF_BUFFER_SIZE(ret, size, len, offset); - } - if (c->flags & (1 << NFT_CHAIN_ATTR_POLICY)) { - ret = snprintf(buf + offset, len, "<policy>%s</policy>", - nft_verdict2str(c->policy)); - SNPRINTF_BUFFER_SIZE(ret, size, len, offset); - } - } - if (c->flags & (1 << NFT_CHAIN_ATTR_FAMILY)) { - ret = snprintf(buf + offset, len, "<family>%s</family>", - nft_family2str(c->family)); - SNPRINTF_BUFFER_SIZE(ret, size, len, offset); + if (c->flags & (1 << NFT_CHAIN_ATTR_TYPE)) + nft_buf_str(&b, type, c->type, TYPE); + if (c->flags & (1 << NFT_CHAIN_ATTR_HOOKNUM)) + nft_buf_str(&b, type, nft_hooknum2str(c->family, + c->hooknum), HOOKNUM); + if (c->flags & (1 << NFT_CHAIN_ATTR_PRIO)) + nft_buf_s32(&b, type, c->prio, PRIO); + if (c->flags & (1 << NFT_CHAIN_ATTR_POLICY)) + nft_buf_str(&b, type, nft_verdict2str(c->policy), POLICY); } - ret = snprintf(buf + offset, len, "</chain>"); - SNPRINTF_BUFFER_SIZE(ret, size, len, offset); + nft_buf_close(&b, type, CHAIN); - return offset; + return nft_buf_done(&b); } static int nft_chain_snprintf_default(char *buf, size_t size, @@ -963,15 +855,13 @@ int nft_chain_snprintf(char *buf, size_t size, struct nft_chain *c, ret = nft_event_header_snprintf(buf+offset, len, type, flags); SNPRINTF_BUFFER_SIZE(ret, size, len, offset); - switch(type) { + switch (type) { case NFT_OUTPUT_DEFAULT: ret = nft_chain_snprintf_default(buf+offset, len, c); break; case NFT_OUTPUT_XML: - ret = nft_chain_snprintf_xml(buf+offset, len, c); - break; case NFT_OUTPUT_JSON: - ret = nft_chain_snprintf_json(buf+offset, len, c); + ret = nft_chain_export(buf+offset, len, c, type); break; default: return -1; diff --git a/src/expr/bitwise.c b/src/expr/bitwise.c index b575c7a..a299cd4 100644 --- a/src/expr/bitwise.c +++ b/src/expr/bitwise.c @@ -22,6 +22,7 @@ #include <libnftnl/rule.h> #include "data_reg.h" #include "expr_ops.h" +#include <buffer.h> struct nft_expr_bitwise { enum nft_registers sreg; @@ -252,102 +253,24 @@ nft_rule_expr_bitwise_xml_parse(struct nft_rule_expr *e, mxml_node_t *tree, #endif } -static int nft_rule_expr_bitwise_snprintf_json(char *buf, size_t size, - struct nft_rule_expr *e) -{ - int len = size, offset = 0, ret; - struct nft_expr_bitwise *bitwise = nft_expr_data(e); - - if (e->flags & (1 << NFT_EXPR_BITWISE_SREG)) { - ret = snprintf(buf + offset, len, "\"sreg\":%u,", - bitwise->sreg); - SNPRINTF_BUFFER_SIZE(ret, size, len, offset); - } - if (e->flags & (1 << NFT_EXPR_BITWISE_DREG)) { - ret = snprintf(buf + offset, len, "\"dreg\":%u,", - bitwise->dreg); - SNPRINTF_BUFFER_SIZE(ret, size, len, offset); - } - if (e->flags & (1 << NFT_EXPR_BITWISE_LEN)) { - ret = snprintf(buf + offset, len, "\"len\":%u,", - bitwise->len); - SNPRINTF_BUFFER_SIZE(ret, size, len, offset); - } - if (e->flags & (1 << NFT_EXPR_BITWISE_MASK)) { - ret = snprintf(buf + offset, len, "\"mask\":{"); - SNPRINTF_BUFFER_SIZE(ret, size, len, offset); - - ret = nft_data_reg_snprintf(buf+offset, len, &bitwise->mask, - NFT_OUTPUT_JSON, 0, DATA_VALUE); - SNPRINTF_BUFFER_SIZE(ret, size, len, offset); - - ret = snprintf(buf + offset, len, "},"); - SNPRINTF_BUFFER_SIZE(ret, size, len, offset); - - } - if (e->flags & (1 << NFT_EXPR_BITWISE_XOR)) { - ret = snprintf(buf+offset, len, "\"xor\":{"); - SNPRINTF_BUFFER_SIZE(ret, size, len, offset); - - ret = nft_data_reg_snprintf(buf+offset, len, &bitwise->xor, - NFT_OUTPUT_JSON, 0, DATA_VALUE); - SNPRINTF_BUFFER_SIZE(ret, size, len, offset); - - ret = snprintf(buf+offset, len, "},"); - SNPRINTF_BUFFER_SIZE(ret, size, len, offset); - } - - if (offset > 0) - offset--; - - return offset; -} - -static int nft_rule_expr_bitwise_snprintf_xml(char *buf, size_t size, - struct nft_rule_expr *e) +static int nft_rule_expr_bitwise_export(char *buf, size_t size, + struct nft_rule_expr *e, int type) { struct nft_expr_bitwise *bitwise = nft_expr_data(e); - int len = size, offset = 0, ret; - - if (e->flags & (1 << NFT_EXPR_BITWISE_SREG)) { - ret = snprintf(buf + offset, len, "<sreg>%u</sreg>", - bitwise->sreg); - SNPRINTF_BUFFER_SIZE(ret, size, len, offset); - } - if (e->flags & (1 << NFT_EXPR_BITWISE_DREG)) { - ret = snprintf(buf + offset, len, "<dreg>%u</dreg>", - bitwise->dreg); - SNPRINTF_BUFFER_SIZE(ret, size, len, offset); - } - if (e->flags & (1 << NFT_EXPR_BITWISE_LEN)) { - ret = snprintf(buf + offset, len, "<len>%u</len>", - bitwise->len); - SNPRINTF_BUFFER_SIZE(ret, size, len, offset); - } - if (e->flags & (1 << NFT_EXPR_BITWISE_MASK)) { - ret = snprintf(buf + offset, len, "<mask>"); - SNPRINTF_BUFFER_SIZE(ret, size, len, offset); + NFT_BUF_INIT(b, buf, size); - ret = nft_data_reg_snprintf(buf + offset, len, &bitwise->mask, - NFT_OUTPUT_XML, 0, DATA_VALUE); - SNPRINTF_BUFFER_SIZE(ret, size, len, offset); - - ret = snprintf(buf + offset, len, "</mask>"); - SNPRINTF_BUFFER_SIZE(ret, size, len, offset); - } - if (e->flags & (1 << NFT_EXPR_BITWISE_XOR)) { - ret = snprintf(buf + offset, len, "<xor>"); - SNPRINTF_BUFFER_SIZE(ret, size, len, offset); - - ret = nft_data_reg_snprintf(buf + offset, len, &bitwise->xor, - NFT_OUTPUT_XML, 0, DATA_VALUE); - SNPRINTF_BUFFER_SIZE(ret, size, len, offset); - - ret = snprintf(buf + offset, len, "</xor>"); - SNPRINTF_BUFFER_SIZE(ret, size, len, offset); - } + if (e->flags & (1 << NFT_EXPR_BITWISE_SREG)) + nft_buf_u32(&b, type, bitwise->sreg, SREG); + if (e->flags & (1 << NFT_EXPR_BITWISE_DREG)) + nft_buf_u32(&b, type, bitwise->dreg, DREG); + if (e->flags & (1 << NFT_EXPR_BITWISE_LEN)) + nft_buf_u32(&b, type, bitwise->len, LEN); + if (e->flags & (1 << NFT_EXPR_BITWISE_MASK)) + nft_buf_reg(&b, type, &bitwise->mask, DATA_VALUE, MASK); + if (e->flags & (1 << NFT_EXPR_BITWISE_XOR)) + nft_buf_reg(&b, type, &bitwise->xor, DATA_VALUE, XOR); - return offset; + return nft_buf_done(&b); } static int nft_rule_expr_bitwise_snprintf_default(char *buf, size_t size, @@ -378,13 +301,12 @@ static int nft_rule_expr_bitwise_snprintf(char *buf, size_t size, uint32_t type, uint32_t flags, struct nft_rule_expr *e) { - switch(type) { + switch (type) { case NFT_OUTPUT_DEFAULT: return nft_rule_expr_bitwise_snprintf_default(buf, size, e); case NFT_OUTPUT_XML: - return nft_rule_expr_bitwise_snprintf_xml(buf, size, e); case NFT_OUTPUT_JSON: - return nft_rule_expr_bitwise_snprintf_json(buf, size, e); + return nft_rule_expr_bitwise_export(buf, size, e, type); default: break; } diff --git a/src/expr/byteorder.c b/src/expr/byteorder.c index ad28bc4..77680d2 100644 --- a/src/expr/byteorder.c +++ b/src/expr/byteorder.c @@ -22,6 +22,7 @@ #include <libnftnl/rule.h> #include "data_reg.h" #include "expr_ops.h" +#include <buffer.h> struct nft_expr_byteorder { enum nft_registers sreg; @@ -179,6 +180,14 @@ static char *expr_byteorder_str[] = { [NFT_BYTEORDER_NTOH] = "ntoh", }; +static const char *bo2str(uint32_t type) +{ + if (type > NFT_BYTEORDER_HTON) + return "unknown"; + + return expr_byteorder_str[type]; +} + static inline int nft_str2ntoh(const char *op) { if (strcmp(op, "ntoh") == 0) @@ -270,77 +279,24 @@ nft_rule_expr_byteorder_xml_parse(struct nft_rule_expr *e, mxml_node_t *tree, #endif } -static int nft_rule_expr_byteorder_snprintf_json(char *buf, size_t size, - struct nft_rule_expr *e) -{ - struct nft_expr_byteorder *byteorder = nft_expr_data(e); - int len = size, offset = 0, ret; - - if (e->flags & (1 << NFT_EXPR_BYTEORDER_SREG)) { - ret = snprintf(buf + offset, len, "\"sreg\":%u,", - byteorder->sreg); - SNPRINTF_BUFFER_SIZE(ret, size, len, offset); - } - if (e->flags & (1 << NFT_EXPR_BYTEORDER_DREG)) { - ret = snprintf(buf + offset, len, "\"dreg\":%u,", - byteorder->dreg); - SNPRINTF_BUFFER_SIZE(ret, size, len, offset); - } - if (e->flags & (1 << NFT_EXPR_BYTEORDER_OP)) { - ret = snprintf(buf + offset, len, "\"op\":\"%s\",", - expr_byteorder_str[byteorder->op]); - SNPRINTF_BUFFER_SIZE(ret, size, len, offset); - } - if (e->flags & (1 << NFT_EXPR_BYTEORDER_LEN)) { - ret = snprintf(buf + offset, len, "\"len\":%u,", - byteorder->len); - SNPRINTF_BUFFER_SIZE(ret, size, len, offset); - } - if (e->flags & (1 << NFT_EXPR_BYTEORDER_SIZE)) { - ret = snprintf(buf + offset, len, "\"size\":%u,", - byteorder->size); - SNPRINTF_BUFFER_SIZE(ret, size, len, offset); - } - - if (offset > 0) - offset--; - - return offset; -} - -static int nft_rule_expr_byteorder_snprintf_xml(char *buf, size_t size, - struct nft_rule_expr *e) +static int nft_rule_expr_byteorder_export(char *buf, size_t size, + struct nft_rule_expr *e, int type) { struct nft_expr_byteorder *byteorder = nft_expr_data(e); - int len = size, offset = 0, ret; - - if (e->flags & (1 << NFT_EXPR_BYTEORDER_SREG)) { - ret = snprintf(buf + offset, len, "<sreg>%u</sreg>", - byteorder->sreg); - SNPRINTF_BUFFER_SIZE(ret, size, len, offset); - } - if (e->flags & (1 << NFT_EXPR_BYTEORDER_DREG)) { - ret = snprintf(buf + offset, len, "<dreg>%u</dreg>", - byteorder->dreg); - SNPRINTF_BUFFER_SIZE(ret, size, len, offset); - } - if (e->flags & (1 << NFT_EXPR_BYTEORDER_OP)) { - ret = snprintf(buf + offset, len, "<op>%s</op>", - expr_byteorder_str[byteorder->op]); - SNPRINTF_BUFFER_SIZE(ret, size, len, offset); - } - if (e->flags & (1 << NFT_EXPR_BYTEORDER_LEN)) { - ret = snprintf(buf + offset, len, "<len>%u</len>", - byteorder->len); - SNPRINTF_BUFFER_SIZE(ret, size, len, offset); - } - if (e->flags & (1 << NFT_EXPR_BYTEORDER_SIZE)) { - ret = snprintf(buf + offset, len, "<size>%u</size>", - byteorder->size); - SNPRINTF_BUFFER_SIZE(ret, size, len, offset); - } - - return offset; + NFT_BUF_INIT(b, buf, size); + + if (e->flags & (1 << NFT_EXPR_BYTEORDER_SREG)) + nft_buf_u32(&b, type, byteorder->sreg, SREG); + if (e->flags & (1 << NFT_EXPR_BYTEORDER_DREG)) + nft_buf_u32(&b, type, byteorder->dreg, DREG); + if (e->flags & (1 << NFT_EXPR_BYTEORDER_OP)) + nft_buf_str(&b, type, bo2str(byteorder->op), OP); + if (e->flags & (1 << NFT_EXPR_BYTEORDER_LEN)) + nft_buf_u32(&b, type, byteorder->len, LEN); + if (e->flags & (1 << NFT_EXPR_BYTEORDER_SIZE)) + nft_buf_u32(&b, type, byteorder->size, SIZE); + + return nft_buf_done(&b); } static int nft_rule_expr_byteorder_snprintf_default(char *buf, size_t size, @@ -350,7 +306,7 @@ static int nft_rule_expr_byteorder_snprintf_default(char *buf, size_t size, int len = size, offset = 0, ret; ret = snprintf(buf, len, "reg %u = %s(reg %u, %u, %u) ", - byteorder->dreg, expr_byteorder_str[byteorder->op], + byteorder->dreg, bo2str(byteorder->op), byteorder->sreg, byteorder->size, byteorder->len); SNPRINTF_BUFFER_SIZE(ret, size, len, offset); @@ -361,13 +317,12 @@ static int nft_rule_expr_byteorder_snprintf(char *buf, size_t size, uint32_t type, uint32_t flags, struct nft_rule_expr *e) { - switch(type) { + switch (type) { case NFT_OUTPUT_DEFAULT: return nft_rule_expr_byteorder_snprintf_default(buf, size, e); case NFT_OUTPUT_XML: - return nft_rule_expr_byteorder_snprintf_xml(buf, size, e); case NFT_OUTPUT_JSON: - return nft_rule_expr_byteorder_snprintf_json(buf, size, e); + return nft_rule_expr_byteorder_export(buf, size, e, type); default: break; } diff --git a/src/expr/cmp.c b/src/expr/cmp.c index 6ecab7d..b186df0 100644 --- a/src/expr/cmp.c +++ b/src/expr/cmp.c @@ -23,6 +23,7 @@ #include <libnftnl/rule.h> #include "expr_ops.h" #include "data_reg.h" +#include <buffer.h> struct nft_expr_cmp { union nft_data_reg data; @@ -150,6 +151,14 @@ static char *expr_cmp_str[] = { [NFT_CMP_GTE] = "gte", }; +static const char *cmp2str(uint32_t op) +{ + if (op > NFT_CMP_GTE) + return "unknown"; + + return expr_cmp_str[op]; +} + static inline int nft_str2cmp(const char *op) { if (strcmp(op, "eq") == 0) @@ -238,51 +247,20 @@ static int nft_rule_expr_cmp_xml_parse(struct nft_rule_expr *e, mxml_node_t *tre #endif } -static int nft_rule_expr_cmp_snprintf_json(char *buf, size_t size, - struct nft_rule_expr *e) +static int nft_rule_expr_cmp_export(char *buf, size_t size, + struct nft_rule_expr *e, int type) { struct nft_expr_cmp *cmp = nft_expr_data(e); - int len = size, offset = 0, ret; + NFT_BUF_INIT(b, buf, size); - if (e->flags & (1 << NFT_EXPR_CMP_SREG)) { - ret = snprintf(buf + offset, len, "\"sreg\":%u,", cmp->sreg); - SNPRINTF_BUFFER_SIZE(ret, size, len, offset); - } - if (e->flags & (1 << NFT_EXPR_CMP_OP)) { - ret = snprintf(buf + offset, len, "\"op\":\"%s\",", - expr_cmp_str[cmp->op]); - SNPRINTF_BUFFER_SIZE(ret, size, len, offset); - } - ret = nft_data_reg_snprintf(buf + offset, len, &cmp->data, - NFT_OUTPUT_JSON, 0, DATA_VALUE); - SNPRINTF_BUFFER_SIZE(ret, size, len, offset); - - return offset; -} - -static int nft_rule_expr_cmp_snprintf_xml(char *buf, size_t size, - struct nft_rule_expr *e) -{ - struct nft_expr_cmp *cmp = nft_expr_data(e); - int len = size, offset = 0, ret; - - if (e->flags & (1 << NFT_EXPR_CMP_SREG)) { - ret = snprintf(buf, len, "<sreg>%u</sreg>", - cmp->sreg); - SNPRINTF_BUFFER_SIZE(ret, size, len, offset); - } - - if (e->flags & (1 << NFT_EXPR_CMP_SREG)) { - ret = snprintf(buf + offset, len, "<op>%s</op>", - expr_cmp_str[cmp->op]); - SNPRINTF_BUFFER_SIZE(ret, size, len, offset); - } - - ret = nft_data_reg_snprintf(buf + offset, len, &cmp->data, - NFT_OUTPUT_XML, 0, DATA_VALUE); - SNPRINTF_BUFFER_SIZE(ret, size, len, offset); + if (e->flags & (1 << NFT_EXPR_CMP_SREG)) + nft_buf_u32(&b, type, cmp->sreg, SREG); + if (e->flags & (1 << NFT_EXPR_CMP_OP)) + nft_buf_str(&b, type, cmp2str(cmp->op), OP); + if (e->flags & (1 << NFT_EXPR_CMP_DATA)) + nft_buf_reg(&b, type, &cmp->data, DATA_VALUE, DATA); - return offset; + return nft_buf_done(&b); } static int nft_rule_expr_cmp_snprintf_default(char *buf, size_t size, @@ -306,13 +284,12 @@ static int nft_rule_expr_cmp_snprintf(char *buf, size_t size, uint32_t type, uint32_t flags, struct nft_rule_expr *e) { - switch(type) { + switch (type) { case NFT_OUTPUT_DEFAULT: return nft_rule_expr_cmp_snprintf_default(buf, size, e); case NFT_OUTPUT_XML: - return nft_rule_expr_cmp_snprintf_xml(buf, size, e); case NFT_OUTPUT_JSON: - return nft_rule_expr_cmp_snprintf_json(buf, size, e); + return nft_rule_expr_cmp_export(buf, size, e, type); default: break; } diff --git a/src/expr/counter.c b/src/expr/counter.c index 82d1939..e9abc5b 100644 --- a/src/expr/counter.c +++ b/src/expr/counter.c @@ -22,6 +22,7 @@ #include <libnftnl/expr.h> #include <libnftnl/rule.h> #include "expr_ops.h" +#include <buffer.h> struct nft_expr_counter { uint64_t pkts; @@ -159,45 +160,19 @@ nft_rule_expr_counter_xml_parse(struct nft_rule_expr *e, mxml_node_t *tree, return -1; #endif } -static int nft_rule_expr_counter_snprintf_json(char *buf, size_t len, - struct nft_rule_expr *e) -{ - int ret, size = len, offset = 0; - struct nft_expr_counter *ctr = nft_expr_data(e); - if (e->flags & (1 << NFT_EXPR_CTR_PACKETS)) { - ret = snprintf(buf, len,"\"pkts\":%"PRIu64",", ctr->pkts); - SNPRINTF_BUFFER_SIZE(ret, size, len, offset); - } - if (e->flags & (1 << NFT_EXPR_CTR_BYTES)) { - ret = snprintf(buf + offset, len, "\"bytes\":%"PRIu64",", ctr->bytes); - SNPRINTF_BUFFER_SIZE(ret, size, len, offset); - } - - /* Remove the last comma characther */ - if (offset > 0) - offset--; - - return offset; -} - -static int nft_rule_expr_counter_snprintf_xml(char *buf, size_t len, - struct nft_rule_expr *e) +static int nft_rule_expr_counter_export(char *buf, size_t size, + struct nft_rule_expr *e, int type) { - int ret, size = len, offset = 0; struct nft_expr_counter *ctr = nft_expr_data(e); + NFT_BUF_INIT(b, buf, size); - if (e->flags & (1 << NFT_EXPR_CTR_PACKETS)) { - ret = snprintf(buf, len, "<pkts>%"PRIu64"</pkts>", ctr->pkts); - SNPRINTF_BUFFER_SIZE(ret, size, len, offset); - } - if (e->flags & (1 << NFT_EXPR_CTR_BYTES)) { - ret = snprintf(buf + offset, len, "<bytes>%"PRIu64"</bytes>", - ctr->bytes); - SNPRINTF_BUFFER_SIZE(ret, size, len, offset); - } + if (e->flags & (1 << NFT_EXPR_CTR_PACKETS)) + nft_buf_u64(&b, type, ctr->pkts, PKTS); + if (e->flags & (1 << NFT_EXPR_CTR_BYTES)) + nft_buf_u64(&b, type, ctr->bytes, BYTES); - return offset; + return nft_buf_done(&b); } static int nft_rule_expr_counter_snprintf_default(char *buf, size_t len, @@ -213,13 +188,12 @@ static int nft_rule_expr_counter_snprintf(char *buf, size_t len, uint32_t type, uint32_t flags, struct nft_rule_expr *e) { - switch(type) { + switch (type) { case NFT_OUTPUT_DEFAULT: return nft_rule_expr_counter_snprintf_default(buf, len, e); case NFT_OUTPUT_XML: - return nft_rule_expr_counter_snprintf_xml(buf, len, e); case NFT_OUTPUT_JSON: - return nft_rule_expr_counter_snprintf_json(buf, len, e); + return nft_rule_expr_counter_export(buf, len, e, type); default: break; } diff --git a/src/expr/ct.c b/src/expr/ct.c index d443c1e..12d96d5 100644 --- a/src/expr/ct.c +++ b/src/expr/ct.c @@ -21,6 +21,7 @@ #include <libnftnl/expr.h> #include <libnftnl/rule.h> #include "expr_ops.h" +#include <buffer.h> struct nft_expr_ct { enum nft_ct_keys key; @@ -310,66 +311,21 @@ err: } static int -nft_expr_ct_snprintf_json(char *buf, size_t size, struct nft_rule_expr *e) +nft_expr_ct_export(char *buf, size_t size, struct nft_rule_expr *e, int type) { - int ret, len = size, offset = 0; - struct nft_expr_ct *ct = nft_expr_data(e); - - if (e->flags & (1 << NFT_EXPR_CT_DREG)) { - ret = snprintf(buf+offset, len, "\"dreg\":%u,", ct->dreg); - SNPRINTF_BUFFER_SIZE(ret, size, len, offset); - } - - if (e->flags & (1 << NFT_EXPR_CT_SREG)) { - ret = snprintf(buf+offset, len, "\"sreg:\":%u,", ct->sreg); - SNPRINTF_BUFFER_SIZE(ret, size, len, offset); - } - - if (e->flags & (1 << NFT_EXPR_CT_KEY)) { - ret = snprintf(buf+offset, len, "\"key\":\"%s\",", - ctkey2str(ct->key)); - SNPRINTF_BUFFER_SIZE(ret, size, len, offset); - } - - if (nft_rule_expr_is_set(e, NFT_EXPR_CT_DIR)) { - ret = snprintf(buf+offset, len, "\"dir\":\"%s\",", - ctdir2str(ct->dir)); - SNPRINTF_BUFFER_SIZE(ret, size, len, offset); - } - - /* Remove the last separator characther */ - if (offset > 0) - offset--; - - return offset; -} - -static int -nft_expr_ct_snprintf_xml(char *buf, size_t size, struct nft_rule_expr *e) -{ - int ret, len = size, offset = 0; struct nft_expr_ct *ct = nft_expr_data(e); + NFT_BUF_INIT(b, buf, size); - if (e->flags & (1 << NFT_EXPR_CT_DREG)) { - ret = snprintf(buf + offset, len, "<dreg>%u</dreg>", ct->dreg); - SNPRINTF_BUFFER_SIZE(ret, size, len, offset); - } - if (e->flags & (1 << NFT_EXPR_CT_SREG)) { - ret = snprintf(buf + offset, len, "<sreg>%u</sreg>", ct->sreg); - SNPRINTF_BUFFER_SIZE(ret, size, len, offset); - } - if (e->flags & (1 << NFT_EXPR_CT_KEY)) { - ret = snprintf(buf + offset, len, "<key>%s</key>", - ctkey2str(ct->key)); - SNPRINTF_BUFFER_SIZE(ret, size, len, offset); - } - if (nft_rule_expr_is_set(e, NFT_EXPR_CT_DIR)) { - ret = snprintf(buf + offset, len, "<dir>%s</dir>", - ctdir2str(ct->dir)); - SNPRINTF_BUFFER_SIZE(ret, size, len, offset); - } + if (e->flags & (1 << NFT_EXPR_CT_SREG)) + nft_buf_u32(&b, type, ct->sreg, SREG); + if (e->flags & (1 << NFT_EXPR_CT_DREG)) + nft_buf_u32(&b, type, ct->dreg, DREG); + if (e->flags & (1 << NFT_EXPR_CT_KEY)) + nft_buf_str(&b, type, ctkey2str(ct->key), KEY); + if (e->flags & (1 << NFT_EXPR_CT_DIR)) + nft_buf_str(&b, type, ctdir2str(ct->dir), DIR); - return offset; + return nft_buf_done(&b); } static int @@ -403,13 +359,12 @@ static int nft_rule_expr_ct_snprintf(char *buf, size_t len, uint32_t type, uint32_t flags, struct nft_rule_expr *e) { - switch(type) { + switch (type) { case NFT_OUTPUT_DEFAULT: return nft_expr_ct_snprintf_default(buf, len, e); case NFT_OUTPUT_XML: - return nft_expr_ct_snprintf_xml(buf, len, e); case NFT_OUTPUT_JSON: - return nft_expr_ct_snprintf_json(buf, len, e); + return nft_expr_ct_export(buf, len, e, type); default: break; } diff --git a/src/expr/exthdr.c b/src/expr/exthdr.c index 369727c..2135148 100644 --- a/src/expr/exthdr.c +++ b/src/expr/exthdr.c @@ -25,6 +25,7 @@ #include <libnftnl/rule.h> #include "expr_ops.h" +#include <buffer.h> #ifndef IPPROTO_MH #define IPPROTO_MH 135 @@ -154,7 +155,7 @@ nft_rule_expr_exthdr_parse(struct nft_rule_expr *e, struct nlattr *attr) return 0; } -static const char *exthdr_type2str(uint32_t type) +static const char *type2str(uint32_t type) { switch (type) { case IPPROTO_HOPOPTS: @@ -262,65 +263,22 @@ nft_rule_expr_exthdr_xml_parse(struct nft_rule_expr *e, mxml_node_t *tree, #endif } -static int nft_rule_expr_exthdr_snprintf_json(char *buf, size_t len, - struct nft_rule_expr *e) +static int nft_rule_expr_exthdr_export(char *buf, size_t len, + struct nft_rule_expr *e, int type) { struct nft_expr_exthdr *exthdr = nft_expr_data(e); - int ret, size = len, offset = 0; + NFT_BUF_INIT(b, buf, len); - if (e->flags & (1 << NFT_EXPR_EXTHDR_DREG)) { - ret = snprintf(buf, len, "\"dreg\":%u,", exthdr->dreg); - SNPRINTF_BUFFER_SIZE(ret, size, len, offset); - } - if (e->flags & (1 << NFT_EXPR_EXTHDR_TYPE)) { - ret = snprintf(buf + offset, len, "\"exthdr_type\":\"%s\",", - exthdr_type2str(exthdr->type)); - SNPRINTF_BUFFER_SIZE(ret, size, len, offset); - } - if (e->flags & (1 << NFT_EXPR_EXTHDR_OFFSET)) { - ret = snprintf(buf + offset, len, "\"offset\":%u,", - exthdr->offset); - SNPRINTF_BUFFER_SIZE(ret, size, len, offset); - } - if (e->flags & (1 << NFT_EXPR_EXTHDR_LEN)) { - ret = snprintf(buf + offset, len, "\"len\":%u,", - exthdr->len); - SNPRINTF_BUFFER_SIZE(ret, size, len, offset); - } - /* Remove the last comma characther */ - if (offset > 0) - offset--; - - return offset; -} - -static int nft_rule_expr_exthdr_snprintf_xml(char *buf, size_t len, - struct nft_rule_expr *e) -{ - struct nft_expr_exthdr *exthdr = nft_expr_data(e); - int ret, size = len, offset = 0; - - if (e->flags & (1 << NFT_EXPR_EXTHDR_DREG)) { - ret = snprintf(buf, len, "<dreg>%u</dreg>", exthdr->dreg); - SNPRINTF_BUFFER_SIZE(ret, size, len, offset); - } - if (e->flags & (1 << NFT_EXPR_EXTHDR_TYPE)) { - ret = snprintf(buf + offset, len, - "<exthdr_type>%s</exthdr_type>", - exthdr_type2str(exthdr->type)); - SNPRINTF_BUFFER_SIZE(ret, size, len, offset); - } - if (e->flags & (1 << NFT_EXPR_EXTHDR_OFFSET)) { - ret = snprintf(buf + offset, len, "<offset>%u</offset>", - exthdr->offset); - SNPRINTF_BUFFER_SIZE(ret, size, len, offset); - } - if (e->flags & (1 << NFT_EXPR_EXTHDR_LEN)) { - ret = snprintf(buf + offset, len, "<len>%u</len>", exthdr->len); - SNPRINTF_BUFFER_SIZE(ret, size, len, offset); - } + if (e->flags & (1 << NFT_EXPR_EXTHDR_DREG)) + nft_buf_u32(&b, type, exthdr->dreg, DREG); + if (e->flags & (1 << NFT_EXPR_EXTHDR_TYPE)) + nft_buf_str(&b, type, type2str(exthdr->type), EXTHDR_TYPE); + if (e->flags & (1 << NFT_EXPR_EXTHDR_OFFSET)) + nft_buf_u32(&b, type, exthdr->offset, OFFSET); + if (e->flags & (1 << NFT_EXPR_EXTHDR_LEN)) + nft_buf_u32(&b, type, exthdr->len, LEN); - return offset; + return nft_buf_done(&b); } static int nft_rule_expr_exthdr_snprintf_default(char *buf, size_t len, @@ -337,13 +295,12 @@ static int nft_rule_expr_exthdr_snprintf(char *buf, size_t len, uint32_t type, uint32_t flags, struct nft_rule_expr *e) { - switch(type) { + switch (type) { case NFT_OUTPUT_DEFAULT: return nft_rule_expr_exthdr_snprintf_default(buf, len, e); case NFT_OUTPUT_XML: - return nft_rule_expr_exthdr_snprintf_xml(buf, len, e); case NFT_OUTPUT_JSON: - return nft_rule_expr_exthdr_snprintf_json(buf, len, e); + return nft_rule_expr_exthdr_export(buf, len, e, type); default: break; } diff --git a/src/expr/immediate.c b/src/expr/immediate.c index 5f54129..be70445 100644 --- a/src/expr/immediate.c +++ b/src/expr/immediate.c @@ -21,6 +21,7 @@ #include <libnftnl/rule.h> #include "expr_ops.h" #include "data_reg.h" +#include <buffer.h> struct nft_expr_immediate { union nft_data_reg data; @@ -248,63 +249,22 @@ nft_rule_expr_immediate_xml_parse(struct nft_rule_expr *e, mxml_node_t *tree, } static int -nft_rule_expr_immediate_snprintf_json(char *buf, size_t len, - struct nft_rule_expr *e, uint32_t flags) +nft_rule_expr_immediate_export(char *buf, size_t size, struct nft_rule_expr *e, + int type) { - int size = len, offset = 0, ret; struct nft_expr_immediate *imm = nft_expr_data(e); + NFT_BUF_INIT(b, buf, size); - if (e->flags & (1 << NFT_EXPR_IMM_DREG)) { - ret = snprintf(buf, len, "\"dreg\":%u,", imm->dreg); - SNPRINTF_BUFFER_SIZE(ret, size, len, offset); - } - if (e->flags & (1 << NFT_EXPR_IMM_DATA)) { - ret = nft_data_reg_snprintf(buf + offset, len, &imm->data, - NFT_OUTPUT_JSON, flags, DATA_VALUE); - SNPRINTF_BUFFER_SIZE(ret, size, len, offset); - - } else if (e->flags & (1 << NFT_EXPR_IMM_VERDICT)) { - ret = nft_data_reg_snprintf(buf + offset, len, &imm->data, - NFT_OUTPUT_JSON, flags, DATA_VERDICT); - SNPRINTF_BUFFER_SIZE(ret, size, len, offset); - - } else if (e->flags & (1 << NFT_EXPR_IMM_CHAIN)) { - ret = nft_data_reg_snprintf(buf + offset, len, &imm->data, - NFT_OUTPUT_JSON, flags, DATA_CHAIN); - SNPRINTF_BUFFER_SIZE(ret, size, len, offset); - } - - return offset; -} - -static int -nft_rule_expr_immediate_snprintf_xml(char *buf, size_t len, - struct nft_rule_expr *e, uint32_t flags) -{ - int size = len, offset = 0, ret; - struct nft_expr_immediate *imm = nft_expr_data(e); - - if (e->flags & (1 << NFT_EXPR_IMM_DREG)) { - ret = snprintf(buf, len, "<dreg>%u</dreg>", imm->dreg); - SNPRINTF_BUFFER_SIZE(ret, size, len, offset); - } - if (e->flags & (1 << NFT_EXPR_IMM_DATA)) { - ret = nft_data_reg_snprintf(buf + offset, len, &imm->data, - NFT_OUTPUT_XML, flags, DATA_VALUE); - SNPRINTF_BUFFER_SIZE(ret, size, len, offset); - - } else if (e->flags & (1 << NFT_EXPR_IMM_VERDICT)) { - ret = nft_data_reg_snprintf(buf + offset, len, &imm->data, - NFT_OUTPUT_XML, flags, DATA_VERDICT); - SNPRINTF_BUFFER_SIZE(ret, size, len, offset); - - } else if (e->flags & (1 << NFT_EXPR_IMM_CHAIN)) { - ret = nft_data_reg_snprintf(buf + offset, len, &imm->data, - NFT_OUTPUT_XML, flags, DATA_CHAIN); - SNPRINTF_BUFFER_SIZE(ret, size, len, offset); - } - - return offset; + if (e->flags & (1 << NFT_EXPR_IMM_DREG)) + nft_buf_u32(&b, type, imm->dreg, DREG); + if (e->flags & (1 << NFT_EXPR_IMM_DATA)) + nft_buf_reg(&b, type, &imm->data, DATA_VALUE, DATA); + if (e->flags & (1 << NFT_EXPR_IMM_VERDICT)) + nft_buf_reg(&b, type, &imm->data, DATA_VERDICT, DATA); + if (e->flags & (1 << NFT_EXPR_IMM_CHAIN)) + nft_buf_reg(&b, type, &imm->data, DATA_CHAIN, DATA); + + return nft_buf_done(&b); } static int @@ -344,9 +304,8 @@ nft_rule_expr_immediate_snprintf(char *buf, size_t len, uint32_t type, case NFT_OUTPUT_DEFAULT: return nft_rule_expr_immediate_snprintf_default(buf, len, e, flags); case NFT_OUTPUT_XML: - return nft_rule_expr_immediate_snprintf_xml(buf, len, e, flags); case NFT_OUTPUT_JSON: - return nft_rule_expr_immediate_snprintf_json(buf, len, e, flags); + return nft_rule_expr_immediate_export(buf, len, e, type); default: break; } diff --git a/src/expr/limit.c b/src/expr/limit.c index 68cfa37..375e6e0 100644 --- a/src/expr/limit.c +++ b/src/expr/limit.c @@ -22,6 +22,7 @@ #include <libnftnl/expr.h> #include <libnftnl/rule.h> #include "expr_ops.h" +#include <buffer.h> struct nft_expr_limit { uint64_t rate; @@ -169,48 +170,18 @@ static const char *get_unit(uint64_t u) return "error"; } -static int nft_rule_expr_limit_snprintf_xml(char *buf, size_t len, - struct nft_rule_expr *e) +static int nft_rule_expr_limit_export(char *buf, size_t size, + struct nft_rule_expr *e, int type) { struct nft_expr_limit *limit = nft_expr_data(e); - int ret, size = len, offset = 0; + NFT_BUF_INIT(b, buf, size); - if (e->flags & (1 << NFT_EXPR_LIMIT_RATE)) { - ret = snprintf(buf + offset, len, "<rate>%"PRIu64"</rate>", - limit->rate); - SNPRINTF_BUFFER_SIZE(ret, size, len, offset); - } - if (e->flags & (1 << NFT_EXPR_LIMIT_UNIT)) { - ret = snprintf(buf + offset, len, "<unit>%"PRIu64"</unit>", - limit->unit); - SNPRINTF_BUFFER_SIZE(ret, size, len, offset); - } - - return offset; -} - -static int nft_rule_expr_limit_snprintf_json(char *buf, size_t len, - struct nft_rule_expr *e) -{ - struct nft_expr_limit *limit = nft_expr_data(e); - int ret, size = len, offset = 0; - - if (e->flags & (1 << NFT_EXPR_LIMIT_RATE)) { - ret = snprintf(buf + offset, len, "\"rate\":%"PRIu64",", - limit->rate); - SNPRINTF_BUFFER_SIZE(ret, size, len, offset); - } - if (e->flags & (1 << NFT_EXPR_LIMIT_UNIT)) { - ret = snprintf(buf + offset, len, "\"unit\":%"PRIu64",", - limit->unit); - SNPRINTF_BUFFER_SIZE(ret, size, len, offset); - } - - /* Remove the last comma characther */ - if (offset > 0) - offset--; + if (e->flags & (1 << NFT_EXPR_LIMIT_RATE)) + nft_buf_u64(&b, type, limit->rate, RATE); + if (e->flags & (1 << NFT_EXPR_LIMIT_UNIT)) + nft_buf_u64(&b, type, limit->unit, UNIT); - return offset; + return nft_buf_done(&b); } static int nft_rule_expr_limit_snprintf_default(char *buf, size_t len, @@ -231,9 +202,8 @@ nft_rule_expr_limit_snprintf(char *buf, size_t len, uint32_t type, case NFT_OUTPUT_DEFAULT: return nft_rule_expr_limit_snprintf_default(buf, len, e); case NFT_OUTPUT_XML: - return nft_rule_expr_limit_snprintf_xml(buf, len, e); case NFT_OUTPUT_JSON: - return nft_rule_expr_limit_snprintf_json(buf, len, e); + return nft_rule_expr_limit_export(buf, len, e, type); default: break; } diff --git a/src/expr/log.c b/src/expr/log.c index 98481c9..0a324c4 100644 --- a/src/expr/log.c +++ b/src/expr/log.c @@ -21,6 +21,7 @@ #include <libnftnl/expr.h> #include <libnftnl/rule.h> #include "expr_ops.h" +#include <buffer.h> struct nft_expr_log { uint32_t snaplen; @@ -288,90 +289,28 @@ static int nft_rule_expr_log_snprintf_default(char *buf, size_t size, return offset; } -static int nft_rule_expr_log_snprintf_xml(char *buf, size_t size, - struct nft_rule_expr *e) +static int nft_rule_expr_log_export(char *buf, size_t size, + struct nft_rule_expr *e, int type) { - int ret, len = size, offset = 0; struct nft_expr_log *log = nft_expr_data(e); + NFT_BUF_INIT(b, buf, size); - if (e->flags & (1 << NFT_EXPR_LOG_PREFIX)) { - ret = snprintf(buf + offset, len, "<prefix>%s</prefix>", - log->prefix); - SNPRINTF_BUFFER_SIZE(ret, size, len, offset); - } - if (e->flags & (1 << NFT_EXPR_LOG_GROUP)) { - ret = snprintf(buf + offset, len, "<group>%u</group>", - log->group); - SNPRINTF_BUFFER_SIZE(ret, size, len, offset); - } - if (e->flags & (1 << NFT_EXPR_LOG_SNAPLEN)) { - ret = snprintf(buf + offset, len, "<snaplen>%u</snaplen>", - log->snaplen); - SNPRINTF_BUFFER_SIZE(ret, size, len, offset); - } - if (e->flags & (1 << NFT_EXPR_LOG_QTHRESHOLD)) { - ret = snprintf(buf + offset, len, "<qthreshold>%u</qthreshold>", - log->qthreshold); - SNPRINTF_BUFFER_SIZE(ret, size, len, offset); - } - if (e->flags & (1 << NFT_EXPR_LOG_LEVEL)) { - ret = snprintf(buf + offset, len, "<level>%u</level>", - log->level); - SNPRINTF_BUFFER_SIZE(ret, size, len, offset); - } - if (e->flags & (1 << NFT_EXPR_LOG_FLAGS)) { - ret = snprintf(buf + offset, len, "<flags>%u</flags>", - log->flags); - SNPRINTF_BUFFER_SIZE(ret, size, len, offset); - } - - return offset; -} - -static int nft_rule_expr_log_snprintf_json(char *buf, size_t len, - struct nft_rule_expr *e) -{ - int ret, size = len, offset = 0; - struct nft_expr_log *log = nft_expr_data(e); - - if (e->flags & (1 << NFT_EXPR_LOG_PREFIX)) { - ret = snprintf(buf + offset, len, "\"prefix\":\"%s\",", - log->prefix); - SNPRINTF_BUFFER_SIZE(ret, size, len, offset); - } - if (e->flags & (1 << NFT_EXPR_LOG_GROUP)) { - ret = snprintf(buf + offset, len, "\"group\":%u,", - log->group); - SNPRINTF_BUFFER_SIZE(ret, size, len, offset); - } - if (e->flags & (1 << NFT_EXPR_LOG_SNAPLEN)) { - ret = snprintf(buf + offset, len, "\"snaplen\":%u,", - log->snaplen); - SNPRINTF_BUFFER_SIZE(ret, size, len, offset); - } - if (e->flags & (1 << NFT_EXPR_LOG_QTHRESHOLD)) { - ret = snprintf(buf + offset, len, "\"qthreshold\":%u,", - log->qthreshold); - SNPRINTF_BUFFER_SIZE(ret, size, len, offset); - } - if (e->flags & (1 << NFT_EXPR_LOG_LEVEL)) { - ret = snprintf(buf + offset, len, "\"level\":%u,", - log->level); - SNPRINTF_BUFFER_SIZE(ret, size, len, offset); - } - if (e->flags & (1 << NFT_EXPR_LOG_FLAGS)) { - ret = snprintf(buf + offset, len, "\"flags\":%u,", - log->flags); - SNPRINTF_BUFFER_SIZE(ret, size, len, offset); - } - /* Remove the last comma characther */ - if (offset > 0) - offset--; + if (e->flags & (1 << NFT_EXPR_LOG_PREFIX)) + nft_buf_str(&b, type, log->prefix, PREFIX); + if (e->flags & (1 << NFT_EXPR_LOG_GROUP)) + nft_buf_u32(&b, type, log->group, GROUP); + if (e->flags & (1 << NFT_EXPR_LOG_SNAPLEN)) + nft_buf_u32(&b, type, log->snaplen, SNAPLEN); + if (e->flags & (1 << NFT_EXPR_LOG_QTHRESHOLD)) + nft_buf_u32(&b, type, log->qthreshold, QTHRESH); + if (e->flags & (1 << NFT_EXPR_LOG_LEVEL)) + nft_buf_u32(&b, type, log->level, LEVEL); + if (e->flags & (1 << NFT_EXPR_LOG_FLAGS)) + nft_buf_u32(&b, type, log->level, FLAGS); - return offset; + return nft_buf_done(&b); } - static int nft_rule_expr_log_snprintf(char *buf, size_t len, uint32_t type, uint32_t flags, struct nft_rule_expr *e) @@ -380,9 +319,8 @@ nft_rule_expr_log_snprintf(char *buf, size_t len, uint32_t type, case NFT_OUTPUT_DEFAULT: return nft_rule_expr_log_snprintf_default(buf, len, e); case NFT_OUTPUT_XML: - return nft_rule_expr_log_snprintf_xml(buf, len, e); case NFT_OUTPUT_JSON: - return nft_rule_expr_log_snprintf_json(buf, len, e); + return nft_rule_expr_log_export(buf, len, e, type); default: break; } diff --git a/src/expr/lookup.c b/src/expr/lookup.c index 625bc58..29daa30 100644 --- a/src/expr/lookup.c +++ b/src/expr/lookup.c @@ -22,6 +22,7 @@ #include <libnftnl/expr.h> #include "data_reg.h" #include "expr_ops.h" +#include <buffer.h> #ifndef IFNAMSIZ #define IFNAMSIZ 16 @@ -208,52 +209,20 @@ nft_rule_expr_lookup_xml_parse(struct nft_rule_expr *e, mxml_node_t *tree, } static int -nft_rule_expr_lookup_snprintf_json(char *buf, size_t size, - struct nft_rule_expr *e) +nft_rule_expr_lookup_export(char *buf, size_t size, + struct nft_rule_expr *e, int type) { - int len = size, offset = 0, ret; - struct nft_expr_lookup *l = nft_expr_data(e); - - if (e->flags & (1 << NFT_EXPR_LOOKUP_SET)) { - ret = snprintf(buf, len, "\"set\":\"%s\",", l->set_name); - SNPRINTF_BUFFER_SIZE(ret, size, len, offset); - } - if (e->flags & (1 << NFT_EXPR_LOOKUP_SREG)) { - ret = snprintf(buf + offset, len, "\"sreg\":%u,", l->sreg); - SNPRINTF_BUFFER_SIZE(ret, size, len, offset); - } - if (e->flags & (1 << NFT_EXPR_LOOKUP_DREG)) { - ret = snprintf(buf + offset, len, "\"dreg\":%u,", l->dreg); - SNPRINTF_BUFFER_SIZE(ret, size, len, offset); - } - /* Remove the last comma characther */ - if (offset > 0) - offset--; - - return offset; -} - -static int -nft_rule_expr_lookup_snprintf_xml(char *buf, size_t size, - struct nft_rule_expr *e) -{ - int len = size, offset = 0, ret; struct nft_expr_lookup *l = nft_expr_data(e); + NFT_BUF_INIT(b, buf, size); - if (e->flags & (1 << NFT_EXPR_LOOKUP_SET)) { - ret = snprintf(buf, len, "<set>%s</set>", l->set_name); - SNPRINTF_BUFFER_SIZE(ret, size, len, offset); - } - if (e->flags & (1 << NFT_EXPR_LOOKUP_SREG)) { - ret = snprintf(buf + offset, len, "<sreg>%u</sreg>", l->sreg); - SNPRINTF_BUFFER_SIZE(ret, size, len, offset); - } - if (e->flags & (1 << NFT_EXPR_LOOKUP_DREG)) { - ret = snprintf(buf + offset, len, "<dreg>%u</dreg>", l->dreg); - SNPRINTF_BUFFER_SIZE(ret, size, len, offset); - } + if (e->flags & (1 << NFT_EXPR_LOOKUP_SET)) + nft_buf_str(&b, type, l->set_name, SET); + if (e->flags & (1 << NFT_EXPR_LOOKUP_SREG)) + nft_buf_u32(&b, type, l->sreg, SREG); + if (e->flags & (1 << NFT_EXPR_LOOKUP_DREG)) + nft_buf_u32(&b, type, l->dreg, DREG); - return offset; + return nft_buf_done(&b); } static int @@ -284,9 +253,8 @@ nft_rule_expr_lookup_snprintf(char *buf, size_t size, uint32_t type, case NFT_OUTPUT_DEFAULT: return nft_rule_expr_lookup_snprintf_default(buf, size, e); case NFT_OUTPUT_XML: - return nft_rule_expr_lookup_snprintf_xml(buf, size, e); case NFT_OUTPUT_JSON: - return nft_rule_expr_lookup_snprintf_json(buf, size, e); + return nft_rule_expr_lookup_export(buf, size, e, type); default: break; } diff --git a/src/expr/masq.c b/src/expr/masq.c index b39a43a..869fd45 100644 --- a/src/expr/masq.c +++ b/src/expr/masq.c @@ -20,6 +20,7 @@ #include <libnftnl/expr.h> #include <libnftnl/rule.h> #include "expr_ops.h" +#include <buffer.h> struct nft_expr_masq { uint32_t flags; @@ -135,33 +136,16 @@ nft_rule_expr_masq_xml_parse(struct nft_rule_expr *e, mxml_node_t *tree, return -1; #endif } -static int nft_rule_expr_masq_snprintf_json(char *buf, size_t len, - struct nft_rule_expr *e) +static int nft_rule_expr_masq_export(char *buf, size_t size, + struct nft_rule_expr *e, int type) { - int ret, size = len, offset = 0; struct nft_expr_masq *masq = nft_expr_data(e); + NFT_BUF_INIT(b, buf, size); - if (e->flags & (1 << NFT_EXPR_MASQ_FLAGS)) { - ret = snprintf(buf + offset, len, "\"flags\":%u", masq->flags); - SNPRINTF_BUFFER_SIZE(ret, size, len, offset); - } - - return offset; -} - -static int nft_rule_expr_masq_snprintf_xml(char *buf, size_t len, - struct nft_rule_expr *e) -{ - int ret, size = len, offset = 0; - struct nft_expr_masq *masq = nft_expr_data(e); - - if (e->flags & (1 << NFT_EXPR_MASQ_FLAGS)) { - ret = snprintf(buf + offset, len, "<flags>%u</flags>", - masq->flags); - SNPRINTF_BUFFER_SIZE(ret, size, len, offset); - } + if (e->flags & (1 << NFT_EXPR_MASQ_FLAGS)) + nft_buf_u32(&b, type, masq->flags, FLAGS); - return offset; + return nft_buf_done(&b); } static int nft_rule_expr_masq_snprintf_default(char *buf, size_t len, @@ -182,9 +166,8 @@ static int nft_rule_expr_masq_snprintf(char *buf, size_t len, uint32_t type, case NFT_OUTPUT_DEFAULT: return nft_rule_expr_masq_snprintf_default(buf, len, e); case NFT_OUTPUT_XML: - return nft_rule_expr_masq_snprintf_xml(buf, len, e); case NFT_OUTPUT_JSON: - return nft_rule_expr_masq_snprintf_json(buf, len, e); + return nft_rule_expr_masq_export(buf, len, e, type); default: break; } diff --git a/src/expr/match.c b/src/expr/match.c index dc66585..26a368f 100644 --- a/src/expr/match.c +++ b/src/expr/match.c @@ -25,6 +25,7 @@ #include <libnftnl/rule.h> #include "expr_ops.h" +#include <buffer.h> /* From include/linux/netfilter/x_tables.h */ #define XT_EXTENSION_MAXNAMELEN 29 @@ -204,33 +205,16 @@ static int nft_rule_expr_match_xml_parse(struct nft_rule_expr *e, mxml_node_t *t #endif } -static int nft_rule_expr_match_snprintf_json(char *buf, size_t len, - struct nft_rule_expr *e) +static int nft_rule_expr_match_export(char *buf, size_t size, + struct nft_rule_expr *e, int type) { struct nft_expr_match *mt = nft_expr_data(e); - int ret, size = len, offset = 0; + NFT_BUF_INIT(b, buf, size); - if (e->flags & (1 << NFT_EXPR_MT_NAME)) { - ret = snprintf(buf, len, "\"name\":\"%s\"", mt->name); - SNPRINTF_BUFFER_SIZE(ret, size, len, offset); - } - - return offset; -} - -static int nft_rule_expr_match_snprintf_xml(char *buf, size_t len, - struct nft_rule_expr *e) -{ - struct nft_expr_match *mt = nft_expr_data(e); - int ret, size=len; - int offset = 0; - - if (e->flags & (1 << NFT_EXPR_MT_NAME)) { - ret = snprintf(buf, len, "<name>%s</name>", mt->name); - SNPRINTF_BUFFER_SIZE(ret, size, len, offset); - } + if (e->flags & (1 << NFT_EXPR_MT_NAME)) + nft_buf_str(&b, type, mt->name, NAME); - return offset; + return nft_buf_done(&b); } static int @@ -239,14 +223,13 @@ nft_rule_expr_match_snprintf(char *buf, size_t len, uint32_t type, { struct nft_expr_match *match = nft_expr_data(e); - switch(type) { + switch (type) { case NFT_OUTPUT_DEFAULT: return snprintf(buf, len, "name %s rev %u ", match->name, match->rev); case NFT_OUTPUT_XML: - return nft_rule_expr_match_snprintf_xml(buf, len, e); case NFT_OUTPUT_JSON: - return nft_rule_expr_match_snprintf_json(buf, len, e); + return nft_rule_expr_match_export(buf, len, e, type); default: break; } diff --git a/src/expr/meta.c b/src/expr/meta.c index 59cb55b..d1a6bbb 100644 --- a/src/expr/meta.c +++ b/src/expr/meta.c @@ -21,6 +21,7 @@ #include <libnftnl/expr.h> #include <libnftnl/rule.h> #include "expr_ops.h" +#include <buffer.h> #ifndef NFT_META_MAX #define NFT_META_MAX (NFT_META_CGROUP + 1) @@ -264,71 +265,32 @@ nft_rule_expr_meta_snprintf_default(char *buf, size_t len, return 0; } -static int -nft_rule_expr_meta_snprintf_xml(char *buf, size_t size, - struct nft_rule_expr *e) -{ - int ret, len = size, offset = 0; - struct nft_expr_meta *meta = nft_expr_data(e); - - if (e->flags & (1 << NFT_EXPR_META_DREG)) { - ret = snprintf(buf, len, "<dreg>%u</dreg>", meta->dreg); - SNPRINTF_BUFFER_SIZE(ret, size, len, offset); - } - if (e->flags & (1 << NFT_EXPR_META_KEY)) { - ret = snprintf(buf + offset, len, "<key>%s</key>", - meta_key2str(meta->key)); - SNPRINTF_BUFFER_SIZE(ret, size, len, offset); - } - if (e->flags & (1 << NFT_EXPR_META_SREG)) { - ret = snprintf(buf + offset, len, "<sreg>%u</sreg>", - meta->sreg); - SNPRINTF_BUFFER_SIZE(ret, size, len, offset); - } - - return offset; -} - -static int -nft_rule_expr_meta_snprintf_json(char *buf, size_t size, - struct nft_rule_expr *e) +static int nft_rule_expr_meta_export(char *buf, size_t size, + struct nft_rule_expr *e, int type) { - int ret, len = size, offset = 0; struct nft_expr_meta *meta = nft_expr_data(e); + NFT_BUF_INIT(b, buf, size); - if (e->flags & (1 << NFT_EXPR_META_DREG)) { - ret = snprintf(buf + offset, len, "\"dreg\":%u,", - meta->dreg); - SNPRINTF_BUFFER_SIZE(ret, size, len, offset); - } - if (e->flags & (1 << NFT_EXPR_META_KEY)) { - ret = snprintf(buf + offset, len, "\"key\":\"%s\",", - meta_key2str(meta->key)); - SNPRINTF_BUFFER_SIZE(ret, size, len, offset); - } - if (e->flags & (1 << NFT_EXPR_META_SREG)) { - ret = snprintf(buf + offset, len, "\"sreg\":%u,", - meta->sreg); - SNPRINTF_BUFFER_SIZE(ret, size, len, offset); - } - /* Remove the last comma separator */ - if (offset > 0) - offset--; + if (e->flags & (1 << NFT_EXPR_META_DREG)) + nft_buf_u32(&b, type, meta->dreg, DREG); + if (e->flags & (1 << NFT_EXPR_META_KEY)) + nft_buf_str(&b, type, meta_key2str(meta->key), KEY); + if (e->flags & (1 << NFT_EXPR_META_SREG)) + nft_buf_u32(&b, type, meta->sreg, SREG); - return offset; + return nft_buf_done(&b); } static int nft_rule_expr_meta_snprintf(char *buf, size_t len, uint32_t type, uint32_t flags, struct nft_rule_expr *e) { - switch(type) { + switch (type) { case NFT_OUTPUT_DEFAULT: return nft_rule_expr_meta_snprintf_default(buf, len, e); case NFT_OUTPUT_XML: - return nft_rule_expr_meta_snprintf_xml(buf, len, e); case NFT_OUTPUT_JSON: - return nft_rule_expr_meta_snprintf_json(buf, len, e); + return nft_rule_expr_meta_export(buf, len, e, type); default: break; } diff --git a/src/expr/nat.c b/src/expr/nat.c index 60623a6..c9e05af 100644 --- a/src/expr/nat.c +++ b/src/expr/nat.c @@ -1,4 +1,5 @@ /* + * (C) 2012-2014 Pablo Neira Ayuso <pablo@netfilter.org> * (C) 2012 Intel Corporation * * This program is free software; you can redistribute it and/or modify @@ -23,6 +24,7 @@ #include <libnftnl/expr.h> #include <libnftnl/rule.h> #include "expr_ops.h" +#include <buffer.h> struct nft_expr_nat { enum nft_registers sreg_addr_min; @@ -196,7 +198,7 @@ nft_rule_expr_nat_build(struct nlmsghdr *nlh, struct nft_rule_expr *e) mnl_attr_put_u32(nlh, NFTA_NAT_FLAGS, htonl(nat->flags)); } -static inline const char *nft_nat2str(uint16_t nat) +static inline const char *nat2str(uint16_t nat) { switch (nat) { case NFT_NAT_SNAT: @@ -329,85 +331,28 @@ static int nft_rule_expr_nat_xml_parse(struct nft_rule_expr *e, mxml_node_t *tre #endif } -static int -nft_rule_expr_nat_snprintf_json(char *buf, size_t size, - struct nft_rule_expr *e) +static int nft_rule_expr_nat_export(char *buf, size_t size, + struct nft_rule_expr *e, int type) { struct nft_expr_nat *nat = nft_expr_data(e); - int len = size, offset = 0, ret = 0; - - ret = snprintf(buf, len, "\"nat_type\":\"%s\",", - nft_nat2str(nat->type)); - SNPRINTF_BUFFER_SIZE(ret, size, len, offset); - - ret = snprintf(buf+offset, len, "\"family\":\"%s\",", - nft_family2str(nat->family)); - SNPRINTF_BUFFER_SIZE(ret, size, len, offset); - - if (e->flags & (1 << NFT_EXPR_NAT_REG_ADDR_MIN)) { - ret = snprintf(buf+offset, len, "\"sreg_addr_min\":%u," - "\"sreg_addr_max\":%u,", - nat->sreg_addr_min, nat->sreg_addr_max); - SNPRINTF_BUFFER_SIZE(ret, size, len, offset); - } - - if (e->flags & (1 << NFT_EXPR_NAT_REG_PROTO_MIN)) { - ret = snprintf(buf+offset, len, "\"sreg_proto_min\":%u," - "\"sreg_proto_max\":%u,", - nat->sreg_proto_min, nat->sreg_proto_max); - SNPRINTF_BUFFER_SIZE(ret, size, len, offset); - } - - if (e->flags & (1 << NFT_EXPR_NAT_FLAGS)) { - ret = snprintf(buf+offset, len, "\"flags\":%u,", nat->flags); - SNPRINTF_BUFFER_SIZE(ret, size, len, offset); - } - - /* Remove the last comma separator */ - if (offset > 0) - offset--; - - return offset; -} + NFT_BUF_INIT(b, buf, size); + if (e->flags & (1 << NFT_EXPR_NAT_TYPE)) + nft_buf_str(&b, type, nat2str(nat->type), NAT_TYPE); + if (e->flags & (1 << NFT_EXPR_NAT_FAMILY)) + nft_buf_str(&b, type, nft_family2str(nat->family), FAMILY); + if (e->flags & (1 << NFT_EXPR_NAT_REG_ADDR_MIN)) + nft_buf_u32(&b, type, nat->sreg_addr_min, SREG_ADDR_MIN); + if (e->flags & (1 << NFT_EXPR_NAT_REG_ADDR_MAX)) + nft_buf_u32(&b, type, nat->sreg_addr_max, SREG_ADDR_MAX); + if (e->flags & (1 << NFT_EXPR_NAT_REG_PROTO_MIN)) + nft_buf_u32(&b, type, nat->sreg_proto_min, SREG_PROTO_MIN); + if (e->flags & (1 << NFT_EXPR_NAT_REG_PROTO_MAX)) + nft_buf_u32(&b, type, nat->sreg_proto_max, SREG_PROTO_MAX); + if (e->flags & (1 << NFT_EXPR_NAT_FLAGS)) + nft_buf_u32(&b, type, nat->flags, FLAGS); -static int -nft_rule_expr_nat_snprintf_xml(char *buf, size_t size, - struct nft_rule_expr *e) -{ - struct nft_expr_nat *nat = nft_expr_data(e); - int len = size, offset = 0, ret = 0; - - ret = snprintf(buf, len, "<type>%s</type>", nft_nat2str(nat->type)); - SNPRINTF_BUFFER_SIZE(ret, size, len, offset); - - ret = snprintf(buf+offset, len, "<family>%s</family>", - nft_family2str(nat->family)); - SNPRINTF_BUFFER_SIZE(ret, size, len, offset); - - if (e->flags & (1 << NFT_EXPR_NAT_REG_ADDR_MIN)) { - ret = snprintf(buf+offset, len, - "<sreg_addr_min>%u</sreg_addr_min>" - "<sreg_addr_max>%u</sreg_addr_max>", - nat->sreg_addr_min, nat->sreg_addr_max); - SNPRINTF_BUFFER_SIZE(ret, size, len, offset); - } - - if (e->flags & (1 << NFT_EXPR_NAT_REG_PROTO_MIN)) { - ret = snprintf(buf+offset, len, - "<sreg_proto_min>%u</sreg_proto_min>" - "<sreg_proto_max>%u</sreg_proto_max>", - nat->sreg_proto_min, nat->sreg_proto_max); - SNPRINTF_BUFFER_SIZE(ret, size, len, offset); - } - - if (e->flags & (1 << NFT_EXPR_NAT_FLAGS)) { - ret = snprintf(buf+offset, len, "<flags>%u</flags>", - nat->flags); - SNPRINTF_BUFFER_SIZE(ret, size, len, offset); - } - - return offset; + return nft_buf_done(&b); } static int @@ -417,7 +362,7 @@ nft_rule_expr_nat_snprintf_default(char *buf, size_t size, struct nft_expr_nat *nat = nft_expr_data(e); int len = size, offset = 0, ret = 0; - ret = snprintf(buf, len, "%s ", nft_nat2str(nat->type)); + ret = snprintf(buf, len, "%s ", nat2str(nat->type)); SNPRINTF_BUFFER_SIZE(ret, size, len, offset); ret = snprintf(buf+offset, len, "%s ", nft_family2str(nat->family)); @@ -453,9 +398,8 @@ nft_rule_expr_nat_snprintf(char *buf, size_t size, uint32_t type, case NFT_OUTPUT_DEFAULT: return nft_rule_expr_nat_snprintf_default(buf, size, e); case NFT_OUTPUT_XML: - return nft_rule_expr_nat_snprintf_xml(buf, size, e); case NFT_OUTPUT_JSON: - return nft_rule_expr_nat_snprintf_json(buf, size, e); + return nft_rule_expr_nat_export(buf, size, e, type); default: break; } diff --git a/src/expr/payload.c b/src/expr/payload.c index 717cdac..1aa20bd 100644 --- a/src/expr/payload.c +++ b/src/expr/payload.c @@ -25,6 +25,7 @@ #include <libnftnl/rule.h> #include "expr_ops.h" +#include <buffer.h> struct nft_expr_payload { enum nft_registers dreg; @@ -161,34 +162,6 @@ static const char *base2str(enum nft_payload_bases base) return base2str_array[base]; } -static int -nft_rule_expr_payload_snprintf_json(char *buf, size_t len, uint32_t flags, - struct nft_rule_expr *e) -{ - struct nft_expr_payload *payload = nft_expr_data(e); - int size = len, offset = 0, ret; - - if (e->flags & (1 << NFT_EXPR_PAYLOAD_DREG)) { - ret = snprintf(buf, len, "\"dreg\":%u,", payload->dreg); - SNPRINTF_BUFFER_SIZE(ret, size, len, offset); - } - if (e->flags & (1 << NFT_EXPR_PAYLOAD_OFFSET)) { - ret = snprintf(buf + offset, len, "\"offset\":%u,", - payload->offset); - SNPRINTF_BUFFER_SIZE(ret, size, len, offset); - } - if (e->flags & (1 << NFT_EXPR_PAYLOAD_LEN)) { - ret = snprintf(buf + offset, len, "\"len\":%u,", payload->len); - SNPRINTF_BUFFER_SIZE(ret, size, len, offset); - } - if (e->flags & (1 << NFT_EXPR_PAYLOAD_BASE)) { - ret = snprintf(buf + offset, len, "\"base\":\"%s\"", - base2str(payload->base)); - SNPRINTF_BUFFER_SIZE(ret, size, len, offset); - } - return offset; -} - static inline int nft_str2base(const char *base) { if (strcmp(base, "link") == 0) @@ -277,33 +250,22 @@ nft_rule_expr_payload_xml_parse(struct nft_rule_expr *e, mxml_node_t *tree, #endif } -static int -nft_rule_expr_payload_snprintf_xml(char *buf, size_t len, uint32_t flags, - struct nft_rule_expr *e) +static int nft_rule_expr_payload_export(char *buf, size_t size, uint32_t flags, + struct nft_rule_expr *e, int type) { struct nft_expr_payload *payload = nft_expr_data(e); - int size = len, offset = 0, ret; + NFT_BUF_INIT(b, buf, size); - if (e->flags & (1 << NFT_EXPR_PAYLOAD_DREG)) { - ret = snprintf(buf, len, "<dreg>%u</dreg>", payload->dreg); - SNPRINTF_BUFFER_SIZE(ret, size, len, offset); - } - if (e->flags & (1 << NFT_EXPR_PAYLOAD_OFFSET)) { - ret = snprintf(buf + offset, len, "<offset>%u</offset>", - payload->offset); - SNPRINTF_BUFFER_SIZE(ret, size, len, offset); - } - if (e->flags & (1 << NFT_EXPR_PAYLOAD_LEN)) { - ret = snprintf(buf + offset, len, "<len>%u</len>", payload->len); - SNPRINTF_BUFFER_SIZE(ret, size, len, offset); - } - if (e->flags & (1 << NFT_EXPR_PAYLOAD_BASE)) { - ret = snprintf(buf + offset, len, "<base>%s</base>", - base2str(payload->base)); - SNPRINTF_BUFFER_SIZE(ret, size, len, offset); - } + if (e->flags & (1 << NFT_EXPR_PAYLOAD_DREG)) + nft_buf_u32(&b, type, payload->dreg, DREG); + if (e->flags & (1 << NFT_EXPR_PAYLOAD_OFFSET)) + nft_buf_u32(&b, type, payload->offset, OFFSET); + if (e->flags & (1 << NFT_EXPR_PAYLOAD_LEN)) + nft_buf_u32(&b, type, payload->len, LEN); + if (e->flags & (1 << NFT_EXPR_PAYLOAD_BASE)) + nft_buf_str(&b, type, base2str(payload->base), BASE); - return offset; + return nft_buf_done(&b); } static int @@ -312,15 +274,14 @@ nft_rule_expr_payload_snprintf(char *buf, size_t len, uint32_t type, { struct nft_expr_payload *payload = nft_expr_data(e); - switch(type) { + switch (type) { case NFT_OUTPUT_DEFAULT: return snprintf(buf, len, "load %ub @ %s header + %u => reg %u ", payload->len, base2str(payload->base), payload->offset, payload->dreg); case NFT_OUTPUT_XML: - return nft_rule_expr_payload_snprintf_xml(buf, len, flags, e); case NFT_OUTPUT_JSON: - return nft_rule_expr_payload_snprintf_json(buf, len, flags, e); + return nft_rule_expr_payload_export(buf, len, flags, e, type); default: break; } diff --git a/src/expr/queue.c b/src/expr/queue.c index 64eb3cb..a4f0b88 100644 --- a/src/expr/queue.c +++ b/src/expr/queue.c @@ -20,6 +20,7 @@ #include <libnftnl/expr.h> #include <libnftnl/rule.h> #include "expr_ops.h" +#include <buffer.h> struct nft_expr_queue { uint16_t queuenum; @@ -211,59 +212,20 @@ static int nft_rule_expr_queue_snprintf_default(char *buf, size_t len, return offset; } -static int nft_rule_expr_queue_snprintf_xml(char *buf, size_t len, - struct nft_rule_expr *e) +static int nft_rule_expr_queue_export(char *buf, size_t size, + struct nft_rule_expr *e, int type) { - int ret, size = len, offset = 0; - struct nft_expr_queue *queue = nft_expr_data(e); - - if (e->flags & (1 << NFT_EXPR_QUEUE_NUM)) { - ret = snprintf(buf + offset, len, "<num>%u</num>", - queue->queuenum); - SNPRINTF_BUFFER_SIZE(ret, size, len, offset); - } - - if (e->flags & (1 << NFT_EXPR_QUEUE_TOTAL)) { - ret = snprintf(buf + offset, len, "<total>%u</total>", - queue->queues_total); - SNPRINTF_BUFFER_SIZE(ret, size, len, offset); - } - if (e->flags & (1 << NFT_EXPR_QUEUE_FLAGS)) { - ret = snprintf(buf + offset, len, "<flags>%u</flags>", - queue->flags); - SNPRINTF_BUFFER_SIZE(ret, size, len, offset); - } - return offset; -} - -static int nft_rule_expr_queue_snprintf_json(char *buf, size_t len, - struct nft_rule_expr *e) -{ - int ret, size = len, offset = 0; struct nft_expr_queue *queue = nft_expr_data(e); + NFT_BUF_INIT(b, buf, size); - if (e->flags & (1 << NFT_EXPR_QUEUE_NUM)) { - ret = snprintf(buf + offset, len, "\"num\":%u,", - queue->queuenum); - SNPRINTF_BUFFER_SIZE(ret, size, len, offset); - } - - if (e->flags & (1 << NFT_EXPR_QUEUE_TOTAL)) { - ret = snprintf(buf + offset, len, "\"total\":%u,", - queue->queues_total); - SNPRINTF_BUFFER_SIZE(ret, size, len, offset); - } - if (e->flags & (1 << NFT_EXPR_QUEUE_FLAGS)) { - ret = snprintf(buf + offset, len, "\"flags\":%u,", - queue->flags); - SNPRINTF_BUFFER_SIZE(ret, size, len, offset); - } - - /* Remove the last comma characther */ - if (offset > 0) - offset--; + if (e->flags & (1 << NFT_EXPR_QUEUE_NUM)) + nft_buf_u32(&b, type, queue->queuenum, NUM); + if (e->flags & (1 << NFT_EXPR_QUEUE_TOTAL)) + nft_buf_u32(&b, type, queue->queues_total, TOTAL); + if (e->flags & (1 << NFT_EXPR_QUEUE_FLAGS)) + nft_buf_u32(&b, type, queue->flags, FLAGS); - return offset; + return nft_buf_done(&b); } static int @@ -271,13 +233,12 @@ nft_rule_expr_queue_snprintf(char *buf, size_t len, uint32_t type, uint32_t flags, struct nft_rule_expr *e) { - switch(type) { + switch (type) { case NFT_OUTPUT_DEFAULT: return nft_rule_expr_queue_snprintf_default(buf, len, e); case NFT_OUTPUT_XML: - return nft_rule_expr_queue_snprintf_xml(buf, len, e); case NFT_OUTPUT_JSON: - return nft_rule_expr_queue_snprintf_json(buf, len, e); + return nft_rule_expr_queue_export(buf, len, e, type); default: break; } diff --git a/src/expr/redir.c b/src/expr/redir.c index 98e8850..02cd3a6 100644 --- a/src/expr/redir.c +++ b/src/expr/redir.c @@ -20,6 +20,7 @@ #include <libnftnl/expr.h> #include <libnftnl/rule.h> #include "expr_ops.h" +#include <buffer.h> struct nft_expr_redir { enum nft_registers sreg_proto_min; @@ -184,60 +185,20 @@ nft_rule_expr_redir_xml_parse(struct nft_rule_expr *e, mxml_node_t *tree, #endif } -static int nft_rule_expr_redir_snprintf_json(char *buf, size_t len, - struct nft_rule_expr *e) +static int nft_rule_expr_redir_export(char *buf, size_t size, + struct nft_rule_expr *e, int type) { - int ret, size = len, offset = 0; struct nft_expr_redir *redir = nft_expr_data(e); + NFT_BUF_INIT(b, buf, size); - if (nft_rule_expr_is_set(e, NFT_EXPR_REDIR_REG_PROTO_MIN)) { - ret = snprintf(buf + offset, len, "\"sreg_proto_min\":%u,", - redir->sreg_proto_min); - SNPRINTF_BUFFER_SIZE(ret, size, len, offset); - } - - if (nft_rule_expr_is_set(e, NFT_EXPR_REDIR_REG_PROTO_MAX)) { - ret = snprintf(buf + offset, len, "\"sreg_proto_max\":%u,", - redir->sreg_proto_max); - SNPRINTF_BUFFER_SIZE(ret, size, len, offset); - } - - if (nft_rule_expr_is_set(e, NFT_EXPR_REDIR_FLAGS)) { - ret = snprintf(buf + offset, len, "\"flags\":%u", - redir->flags); - SNPRINTF_BUFFER_SIZE(ret, size, len, offset); - } - - return offset; -} - -static int nft_rule_expr_redir_snprintf_xml(char *buf, size_t len, - struct nft_rule_expr *e) -{ - int ret, size = len, offset = 0; - struct nft_expr_redir *redir = nft_expr_data(e); - - if (nft_rule_expr_is_set(e, NFT_EXPR_REDIR_REG_PROTO_MIN)) { - ret = snprintf(buf + offset, len, - "<sreg_proto_min>%u<sreg_proto_min>", - redir->sreg_proto_min); - SNPRINTF_BUFFER_SIZE(ret, size, len, offset); - } - - if (nft_rule_expr_is_set(e, NFT_EXPR_REDIR_REG_PROTO_MAX)) { - ret = snprintf(buf + offset, len, - "<sreg_proto_max>%u</sreg_proto_max>", - redir->sreg_proto_max); - SNPRINTF_BUFFER_SIZE(ret, size, len, offset); - } - - if (nft_rule_expr_is_set(e, NFT_EXPR_REDIR_FLAGS)) { - ret = snprintf(buf + offset, len, "<flags>%u</flags>", - redir->flags); - SNPRINTF_BUFFER_SIZE(ret, size, len, offset); - } + if (e->flags & (1 << NFT_EXPR_REDIR_REG_PROTO_MIN)) + nft_buf_u32(&b, type, redir->sreg_proto_min, SREG_PROTO_MIN); + if (e->flags & (1 << NFT_EXPR_REDIR_REG_PROTO_MAX)) + nft_buf_u32(&b, type, redir->sreg_proto_max, SREG_PROTO_MAX); + if (e->flags & (1 << NFT_EXPR_REDIR_FLAGS)) + nft_buf_u32(&b, type, redir->flags, FLAGS); - return offset; + return nft_buf_done(&b); } static int nft_rule_expr_redir_snprintf_default(char *buf, size_t len, @@ -275,9 +236,8 @@ nft_rule_expr_redir_snprintf(char *buf, size_t len, uint32_t type, case NFT_OUTPUT_DEFAULT: return nft_rule_expr_redir_snprintf_default(buf, len, e); case NFT_OUTPUT_XML: - return nft_rule_expr_redir_snprintf_xml(buf, len, e); case NFT_OUTPUT_JSON: - return nft_rule_expr_redir_snprintf_json(buf, len, e); + return nft_rule_expr_redir_export(buf, len, e, type); default: break; } diff --git a/src/expr/reject.c b/src/expr/reject.c index fb88cf5..fe18368 100644 --- a/src/expr/reject.c +++ b/src/expr/reject.c @@ -21,6 +21,7 @@ #include <libnftnl/expr.h> #include <libnftnl/rule.h> #include "expr_ops.h" +#include <buffer.h> struct nft_expr_reject { uint32_t type; @@ -170,60 +171,30 @@ static int nft_rule_expr_reject_snprintf_default(char *buf, size_t len, reject->type, reject->icmp_code); } -static int nft_rule_expr_reject_snprintf_xml(char *buf, size_t len, - struct nft_rule_expr *e) +static int nft_rule_expr_reject_export(char *buf, size_t size, + struct nft_rule_expr *e, int type) { - int ret, size = len, offset = 0; struct nft_expr_reject *reject = nft_expr_data(e); + NFT_BUF_INIT(b, buf, size); - if (e->flags & (1 << NFT_EXPR_REJECT_TYPE)) { - ret = snprintf(buf+offset, len, "<type>%u</type>", - reject->type); - SNPRINTF_BUFFER_SIZE(ret, size, len, offset); - } - if (e->flags & (1 << NFT_EXPR_REJECT_CODE)) { - ret = snprintf(buf+offset, len, "<code>%u</code>", - reject->icmp_code); - SNPRINTF_BUFFER_SIZE(ret, size, len, offset); - } - - return offset; -} - -static int nft_rule_expr_reject_snprintf_json(char *buf, size_t len, - struct nft_rule_expr *e) -{ - int ret, size = len, offset = 0; - struct nft_expr_reject *reject = nft_expr_data(e); - - if (e->flags & (1 << NFT_EXPR_REJECT_TYPE)) { - ret = snprintf(buf+offset, len, "\"type\":%u,", - reject->type); - SNPRINTF_BUFFER_SIZE(ret, size, len, offset); - } - if (e->flags & (1 << NFT_EXPR_REJECT_CODE)) { - ret = snprintf(buf+offset, len, "\"code\":%u,", - reject->icmp_code); - SNPRINTF_BUFFER_SIZE(ret, size, len, offset); - } - - if (offset > 0) - offset--; + if (e->flags & (1 << NFT_EXPR_REJECT_TYPE)) + nft_buf_u32(&b, type, reject->type, TYPE); + if (e->flags & (1 << NFT_EXPR_REJECT_CODE)) + nft_buf_u32(&b, type, reject->icmp_code, CODE); - return offset; + return nft_buf_done(&b); } static int nft_rule_expr_reject_snprintf(char *buf, size_t len, uint32_t type, uint32_t flags, struct nft_rule_expr *e) { - switch(type) { + switch (type) { case NFT_OUTPUT_DEFAULT: return nft_rule_expr_reject_snprintf_default(buf, len, e); case NFT_OUTPUT_XML: - return nft_rule_expr_reject_snprintf_xml(buf, len, e); case NFT_OUTPUT_JSON: - return nft_rule_expr_reject_snprintf_json(buf, len, e); + return nft_rule_expr_reject_export(buf, len, e, type); default: break; } diff --git a/src/expr/target.c b/src/expr/target.c index bfff513..a79bc9e 100644 --- a/src/expr/target.c +++ b/src/expr/target.c @@ -25,6 +25,7 @@ #include <libnftnl/rule.h> #include "expr_ops.h" +#include <buffer.h> /* From include/linux/netfilter/x_tables.h */ #define XT_EXTENSION_MAXNAMELEN 29 @@ -205,33 +206,16 @@ nft_rule_expr_target_xml_parse(struct nft_rule_expr *e, mxml_node_t *tree, #endif } -static int nft_rule_exp_target_snprintf_json(char *buf, size_t len, - struct nft_rule_expr *e) +static int nft_rule_exp_target_export(char *buf, size_t size, + struct nft_rule_expr *e, int type) { struct nft_expr_target *target = nft_expr_data(e); - int ret, size = len, offset = 0; + NFT_BUF_INIT(b, buf, size); - if (e->flags & (1 << NFT_EXPR_TG_NAME)) { - ret = snprintf(buf, len, "\"name\":\"%s\"", target->name); - SNPRINTF_BUFFER_SIZE(ret, size, len, offset); - } - - return offset; -} - -static int nft_rule_exp_target_snprintf_xml(char *buf, size_t len, - struct nft_rule_expr *e) -{ - struct nft_expr_target *target = nft_expr_data(e); - int ret, size=len; - int offset = 0; - - if (e->flags & (1 << NFT_EXPR_TG_NAME)) { - ret = snprintf(buf, len, "<name>%s</name>", target->name); - SNPRINTF_BUFFER_SIZE(ret, size, len, offset); - } + if (e->flags & (1 << NFT_EXPR_TG_NAME)) + nft_buf_str(&b, type, target->name, NAME); - return offset; + return nft_buf_done(&b); } static int @@ -240,14 +224,13 @@ nft_rule_expr_target_snprintf(char *buf, size_t len, uint32_t type, { struct nft_expr_target *target = nft_expr_data(e); - switch(type) { + switch (type) { case NFT_OUTPUT_DEFAULT: return snprintf(buf, len, "name %s rev %u ", target->name, target->rev); case NFT_OUTPUT_XML: - return nft_rule_exp_target_snprintf_xml(buf, len, e); case NFT_OUTPUT_JSON: - return nft_rule_exp_target_snprintf_json(buf, len, e); + return nft_rule_exp_target_export(buf, len, e, type); default: break; } diff --git a/src/table.c b/src/table.c index 53f6a4d..c93e6fb 100644 --- a/src/table.c +++ b/src/table.c @@ -24,6 +24,7 @@ #include <linux/netfilter/nf_tables.h> #include <libnftnl/table.h> +#include <buffer.h> struct nft_table { struct list_head head; @@ -391,75 +392,24 @@ int nft_table_parse_file(struct nft_table *t, enum nft_parse_type type, } EXPORT_SYMBOL(nft_table_parse_file); -static int nft_table_snprintf_json(char *buf, size_t size, struct nft_table *t) +static int nft_table_export(char *buf, size_t size, struct nft_table *t, + int type) { - int ret, len = size, offset = 0; - - ret = snprintf(buf, size, "{\"table\":{"); - SNPRINTF_BUFFER_SIZE(ret, size, len, offset); - ret = 0; - - if (t->flags & (1 << NFT_TABLE_ATTR_NAME)) { - ret = snprintf(buf + offset, size, "\"name\":\"%s\",", t->name); - SNPRINTF_BUFFER_SIZE(ret, size, len, offset); - } - if (t->flags & (1 << NFT_TABLE_ATTR_FAMILY)) { - ret = snprintf(buf + offset, size, "\"family\":\"%s\",", - nft_family2str(t->family)); - SNPRINTF_BUFFER_SIZE(ret, size, len, offset); - } - if (t->flags & (1 << NFT_TABLE_ATTR_FLAGS)) { - ret = snprintf(buf + offset, size, "\"flags\":%u,", - t->table_flags); - SNPRINTF_BUFFER_SIZE(ret, size, len, offset); - } - if (t->flags & (1 << NFT_TABLE_ATTR_USE)) { - ret = snprintf(buf + offset, size, "\"use\":%u,", t->use); - SNPRINTF_BUFFER_SIZE(ret, size, len, offset); - } - - /* If some values is set, ret is not 0. So, It's needed to remove the - * last comma characther - */ - if (ret > 0) - offset--; - - ret = snprintf(buf + offset, size, "}}"); - SNPRINTF_BUFFER_SIZE(ret, size, len, offset); - - return offset; -} - -static int nft_table_snprintf_xml(char *buf, size_t size, struct nft_table *t) -{ - int ret, len = size, offset = 0; - - ret = snprintf(buf, size, "<table>"); - SNPRINTF_BUFFER_SIZE(ret, size, len, offset); + NFT_BUF_INIT(b, buf, size); - if (t->flags & (1 << NFT_TABLE_ATTR_NAME)) { - ret = snprintf(buf + offset, size, "<name>%s</name>", t->name); - SNPRINTF_BUFFER_SIZE(ret, size, len, offset); - } - if (t->flags & (1 << NFT_TABLE_ATTR_FAMILY)) { - ret = snprintf(buf + offset, size, "<family>%s</family>", - nft_family2str(t->family)); - SNPRINTF_BUFFER_SIZE(ret, size, len, offset); - } - if (t->flags & (1 << NFT_TABLE_ATTR_FLAGS)) { - ret = snprintf(buf + offset, size, "<flags>%u</flags>", - t->table_flags); - SNPRINTF_BUFFER_SIZE(ret, size, len, offset); - } - if (t->flags & (1 << NFT_TABLE_ATTR_USE)) { - ret = snprintf(buf + offset, size, "<use>%u</use>", t->use); - SNPRINTF_BUFFER_SIZE(ret, size, len, offset); - } + nft_buf_open(&b, type, TABLE); + if (t->flags & (1 << NFT_TABLE_ATTR_NAME)) + nft_buf_str(&b, type, t->name, NAME); + if (t->flags & (1 << NFT_TABLE_ATTR_FAMILY)) + nft_buf_str(&b, type, nft_family2str(t->family), FAMILY); + if (t->flags & (1 << NFT_TABLE_ATTR_FLAGS)) + nft_buf_u32(&b, type, t->table_flags, FLAGS); + if (t->flags & (1 << NFT_TABLE_ATTR_USE)) + nft_buf_u32(&b, type, t->use, USE); - ret = snprintf(buf + offset, size, "</table>"); - SNPRINTF_BUFFER_SIZE(ret, size, len, offset); + nft_buf_close(&b, type, TABLE); - return offset; + return nft_buf_done(&b); } static int nft_table_snprintf_default(char *buf, size_t size, struct nft_table *t) @@ -477,15 +427,13 @@ int nft_table_snprintf(char *buf, size_t size, struct nft_table *t, ret = nft_event_header_snprintf(buf+offset, len, type, flags); SNPRINTF_BUFFER_SIZE(ret, size, len, offset); - switch(type) { + switch (type) { case NFT_OUTPUT_DEFAULT: ret = nft_table_snprintf_default(buf+offset, len, t); break; case NFT_OUTPUT_XML: - ret = nft_table_snprintf_xml(buf+offset, len, t); - break; case NFT_OUTPUT_JSON: - ret = nft_table_snprintf_json(buf+offset, len, t); + ret = nft_table_export(buf+offset, len, t, type); break; default: return -1; diff --git a/tests/jsonfiles/11-chain.json b/tests/jsonfiles/11-chain.json index 2610b79..731ed1f 100644 --- a/tests/jsonfiles/11-chain.json +++ b/tests/jsonfiles/11-chain.json @@ -1 +1 @@ -{"nftables":[{"chain":{"name":"input","handle":1,"bytes":1375696,"packets":4136,"family":"ip","table":"filter","use":0,"type":"filter","hooknum":"input","prio":0,"policy":"accept"}}]} +{"nftables":[{"chain":{"name":"input","handle":1,"bytes":1375696,"packets":4136,"table":"filter","family":"ip","use":0,"type":"filter","hooknum":"input","prio":0,"policy":"accept"}}]} diff --git a/tests/jsonfiles/12-chain.json b/tests/jsonfiles/12-chain.json index 3d15982..2d344eb 100644 --- a/tests/jsonfiles/12-chain.json +++ b/tests/jsonfiles/12-chain.json @@ -1 +1 @@ -{"nftables":[{"chain":{"name":"forward","handle":2,"bytes":0,"packets":0,"family":"ip","table":"filter","use":0,"type":"filter","hooknum":"forward","prio":0,"policy":"accept"}}]} +{"nftables":[{"chain":{"name":"forward","handle":2,"bytes":0,"packets":0,"table":"filter","family":"ip","use":0,"type":"filter","hooknum":"forward","prio":0,"policy":"accept"}}]} diff --git a/tests/jsonfiles/13-chain.json b/tests/jsonfiles/13-chain.json index e3a17f0..5a6ddd1 100644 --- a/tests/jsonfiles/13-chain.json +++ b/tests/jsonfiles/13-chain.json @@ -1 +1 @@ -{"nftables":[{"chain":{"name":"output","handle":3,"bytes":454786,"packets":2681,"family":"ip","table":"filter","use":0,"type":"filter","hooknum":"output","prio":0,"policy":"accept"}}]} +{"nftables":[{"chain":{"name":"output","handle":3,"bytes":454786,"packets":2681,"table":"filter","family":"ip","use":0,"type":"filter","hooknum":"output","prio":0,"policy":"accept"}}]} diff --git a/tests/xmlfiles/10-chain.xml b/tests/xmlfiles/10-chain.xml index 9c00eda..6ac54ab 100644 --- a/tests/xmlfiles/10-chain.xml +++ b/tests/xmlfiles/10-chain.xml @@ -1 +1 @@ -<nftables><chain><name>test</name><handle>0</handle><bytes>0</bytes><packets>0</packets><table>filter</table><type>filter</type><hooknum>input</hooknum><prio>0</prio><policy>accept</policy><family>ip</family></chain></nftables> +<nftables><chain><name>test</name><handle>0</handle><bytes>0</bytes><packets>0</packets><table>filter</table><family>ip</family><type>filter</type><hooknum>input</hooknum><prio>0</prio><policy>accept</policy></chain></nftables> diff --git a/tests/xmlfiles/11-chain.xml b/tests/xmlfiles/11-chain.xml index 3d9978e..34d99dd 100644 --- a/tests/xmlfiles/11-chain.xml +++ b/tests/xmlfiles/11-chain.xml @@ -1 +1 @@ -<nftables><chain><name>test</name><handle>0</handle><bytes>59</bytes><packets>1</packets><table>filter</table><type>filter</type><hooknum>forward</hooknum><prio>0</prio><policy>drop</policy><family>ip6</family></chain></nftables> +<nftables><chain><name>test</name><handle>0</handle><bytes>59</bytes><packets>1</packets><table>filter</table><family>ip6</family><type>filter</type><hooknum>forward</hooknum><prio>0</prio><policy>drop</policy></chain></nftables> diff --git a/tests/xmlfiles/12-chain.xml b/tests/xmlfiles/12-chain.xml index db0f56c..f53f252 100644 --- a/tests/xmlfiles/12-chain.xml +++ b/tests/xmlfiles/12-chain.xml @@ -1 +1 @@ -<nftables><chain><name>foo</name><handle>100</handle><bytes>59264154979</bytes><packets>2548796325</packets><table>nat</table><type>nat</type><hooknum>postrouting</hooknum><prio>0</prio><policy>accept</policy><family>ip</family></chain></nftables> +<nftables><chain><name>foo</name><handle>100</handle><bytes>59264154979</bytes><packets>2548796325</packets><table>nat</table><family>ip</family><type>nat</type><hooknum>postrouting</hooknum><prio>0</prio><policy>accept</policy></chain></nftables> |