diff options
author | Pablo Neira Ayuso <pablo@netfilter.org> | 2014-02-03 14:04:42 +0100 |
---|---|---|
committer | Pablo Neira Ayuso <pablo@netfilter.org> | 2014-02-03 18:43:13 +0100 |
commit | 29fd6a1df9f6c80d155a7a73b8514a68dc9cd22d (patch) | |
tree | 9dc15a3e19a6ff36ae9ee3d38c7b8190b73f0a72 /src/expr/data_reg.c | |
parent | 16871a3615edcf358d688a8d079b1e7b20053fb1 (diff) | |
parent | 076fd1e66e7f1bc3b2bd91f3efb84080da26fb9c (diff) |
Merge branch 'master' into next-3.14
This patch includes changes to adapt this branch to the library
rename that happened in the master branch.
Conflicts:
src/Makefile.am
src/expr/cmp.c
src/expr/ct.c
src/expr/data_reg.c
src/expr/meta.c
tests/jsonfiles/01-table.json
tests/jsonfiles/02-table.json
tests/jsonfiles/64-ruleset.json
tests/xmlfiles/01-table.xml
tests/xmlfiles/02-table.xml
Diffstat (limited to 'src/expr/data_reg.c')
-rw-r--r-- | src/expr/data_reg.c | 232 |
1 files changed, 137 insertions, 95 deletions
diff --git a/src/expr/data_reg.c b/src/expr/data_reg.c index a198c67..0523cb7 100644 --- a/src/expr/data_reg.c +++ b/src/expr/data_reg.c @@ -18,82 +18,85 @@ #include <netinet/in.h> #include <libmnl/libmnl.h> -#include <libnftables/expr.h> -#include <libnftables/rule.h> -#include "internal.h" - #include <linux/netfilter.h> #include <linux/netfilter/nf_tables.h> +#include <libnftnl/expr.h> +#include <libnftnl/rule.h> +#include "expr_ops.h" +#include "data_reg.h" +#include "internal.h" #ifdef JSON_PARSING -static int nft_data_reg_verdict_json_parse(union nft_data_reg *reg, json_t *data) +static int nft_data_reg_verdict_json_parse(union nft_data_reg *reg, json_t *data, + struct nft_parse_err *err) { int verdict; const char *verdict_str; + const char *chain; - verdict_str = nft_jansson_parse_str(data, "verdict"); + verdict_str = nft_jansson_parse_str(data, "verdict", err); if (verdict_str == NULL) - return -1; + return DATA_NONE; - verdict = nft_str2verdict(verdict_str); - if (verdict < 0) + if (nft_str2verdict(verdict_str, &verdict) != 0) { + err->node_name = "verdict"; + err->error = NFT_PARSE_EBADTYPE; + errno = EINVAL; return -1; + } reg->verdict = (uint32_t)verdict; - return 0; -} + if (nft_jansson_node_exist(data, "chain")) { + chain = nft_jansson_parse_str(data, "chain", err); + if (chain == NULL) + return DATA_NONE; -static int nft_data_reg_chain_json_parse(union nft_data_reg *reg, json_t *data) -{ - reg->chain = strdup(nft_jansson_parse_str(data, "chain")); - if (reg->chain == NULL) { - return -1; + reg->chain = strdup(chain); } - return 0; + return DATA_VERDICT; } -static int nft_data_reg_value_json_parse(union nft_data_reg *reg, json_t *data) +static int nft_data_reg_value_json_parse(union nft_data_reg *reg, json_t *data, + struct nft_parse_err *err) { int i; char node_name[6]; - if (nft_jansson_parse_val(data, "len", NFT_TYPE_U8, ®->len) < 0) - return -1; + if (nft_jansson_parse_val(data, "len", NFT_TYPE_U8, ®->len, err) < 0) + return DATA_NONE; for (i = 0; i < div_round_up(reg->len, sizeof(uint32_t)); i++) { sprintf(node_name, "data%d", i); if (nft_jansson_str2num(data, node_name, BASE_HEX, - ®->val[i], NFT_TYPE_U32) != 0) - return -1; + ®->val[i], NFT_TYPE_U32, err) != 0) + return DATA_NONE; } - return 0; + return DATA_VALUE; } #endif -int nft_data_reg_json_parse(union nft_data_reg *reg, json_t *data) +int nft_data_reg_json_parse(union nft_data_reg *reg, json_t *data, + struct nft_parse_err *err) { #ifdef JSON_PARSING const char *type; - type = nft_jansson_parse_str(data, "type"); + type = nft_jansson_parse_str(data, "type", err); if (type == NULL) return -1; /* Select what type of parsing is needed */ - if (strcmp(type, "value") == 0) { - return nft_data_reg_value_json_parse(reg, data); - } else if (strcmp(type, "verdict") == 0) { - return nft_data_reg_verdict_json_parse(reg, data); - } else if (strcmp(type, "chain") == 0) { - return nft_data_reg_chain_json_parse(reg, data); - } + if (strcmp(type, "value") == 0) + return nft_data_reg_value_json_parse(reg, data, err); + else if (strcmp(type, "verdict") == 0) + return nft_data_reg_verdict_json_parse(reg, data, err); - return 0; + return DATA_NONE; #else errno = EOPNOTSUPP; return -1; @@ -102,44 +105,42 @@ int nft_data_reg_json_parse(union nft_data_reg *reg, json_t *data) #ifdef XML_PARSING static int nft_data_reg_verdict_xml_parse(union nft_data_reg *reg, - mxml_node_t *tree) + mxml_node_t *tree, + struct nft_parse_err *err) { int verdict; const char *verdict_str; + const char *chain; verdict_str = nft_mxml_str_parse(tree, "verdict", MXML_DESCEND_FIRST, - NFT_XML_MAND); + NFT_XML_MAND, err); if (verdict_str == NULL) return DATA_NONE; - verdict = nft_str2verdict(verdict_str); - if (verdict < 0) + if (nft_str2verdict(verdict_str, &verdict) != 0) { + err->node_name = "verdict"; + err->error = NFT_PARSE_EBADTYPE; + errno = EINVAL; return DATA_NONE; + } reg->verdict = (uint32_t)verdict; - return DATA_VERDICT; -} - -static int nft_data_reg_chain_xml_parse(union nft_data_reg *reg, - mxml_node_t *tree) -{ - const char *chain; - chain = nft_mxml_str_parse(tree, "chain", MXML_DESCEND_FIRST, - NFT_XML_MAND); - if (chain == NULL) - return DATA_NONE; + NFT_XML_OPT, err); + if (chain != NULL) { + if (reg->chain) + xfree(reg->chain); - if (reg->chain) - xfree(reg->chain); + reg->chain = strdup(chain); + } - reg->chain = strdup(chain); - return DATA_CHAIN; + return DATA_VERDICT; } static int nft_data_reg_value_xml_parse(union nft_data_reg *reg, - mxml_node_t *tree) + mxml_node_t *tree, + struct nft_parse_err *err) { int i; char node_name[6]; @@ -155,7 +156,7 @@ static int nft_data_reg_value_xml_parse(union nft_data_reg *reg, */ if (nft_mxml_num_parse(tree, "len", MXML_DESCEND_FIRST, BASE_DEC, - ®->len, NFT_TYPE_U8, NFT_XML_MAND) != 0) + ®->len, NFT_TYPE_U8, NFT_XML_MAND, err) != 0) return DATA_NONE; /* Get and set <dataN> */ @@ -164,7 +165,7 @@ static int nft_data_reg_value_xml_parse(union nft_data_reg *reg, if (nft_mxml_num_parse(tree, node_name, MXML_DESCEND_FIRST, BASE_HEX, ®->val[i], NFT_TYPE_U32, - NFT_XML_MAND) != 0) + NFT_XML_MAND, err) != 0) return DATA_NONE; } @@ -172,7 +173,8 @@ static int nft_data_reg_value_xml_parse(union nft_data_reg *reg, } #endif -int nft_data_reg_xml_parse(union nft_data_reg *reg, mxml_node_t *tree) +int nft_data_reg_xml_parse(union nft_data_reg *reg, mxml_node_t *tree, + struct nft_parse_err *err) { #ifdef XML_PARSING const char *type; @@ -180,26 +182,25 @@ int nft_data_reg_xml_parse(union nft_data_reg *reg, mxml_node_t *tree) node = mxmlFindElement(tree, tree, "data_reg", "type", NULL, MXML_DESCEND_FIRST); - if (node == NULL) { - errno = EINVAL; - return DATA_NONE; - } + if (node == NULL) + goto err; type = mxmlElementGetAttr(node, "type"); - if (type == NULL) { - errno = EINVAL; - return DATA_NONE; - } + if (type == NULL) + goto err; if (strcmp(type, "value") == 0) - return nft_data_reg_value_xml_parse(reg, node); + return nft_data_reg_value_xml_parse(reg, node, err); else if (strcmp(type, "verdict") == 0) - return nft_data_reg_verdict_xml_parse(reg, node); - else if (strcmp(type, "chain") == 0) - return nft_data_reg_chain_xml_parse(reg, node); + return nft_data_reg_verdict_xml_parse(reg, node, err); return DATA_NONE; +err: + errno = EINVAL; + err->node_name = "data_reg"; + err->error = NFT_PARSE_EMISSINGNODE; + return DATA_NONE; #else errno = EOPNOTSUPP; return -1; @@ -293,6 +294,67 @@ nft_data_reg_value_snprintf_default(char *buf, size_t size, return offset; } +static int +nft_data_reg_verdict_snprintf_def(char *buf, size_t size, + union nft_data_reg *reg, uint32_t flags) +{ + int len = size, offset = 0, ret = 0; + + ret = snprintf(buf, size, "%s ", nft_verdict2str(reg->verdict)); + SNPRINTF_BUFFER_SIZE(ret, size, len, offset); + + if (reg->chain != NULL) { + ret = snprintf(buf+offset, size, "-> %s ", reg->chain); + SNPRINTF_BUFFER_SIZE(ret, size, len, offset); + } + + return offset; +} + +static int +nft_data_reg_verdict_snprintf_xml(char *buf, size_t size, + union nft_data_reg *reg, uint32_t flags) +{ + int len = size, offset = 0, ret = 0; + + ret = snprintf(buf, size, "<data_reg type=\"verdict\">" + "<verdict>%s</verdict>", nft_verdict2str(reg->verdict)); + SNPRINTF_BUFFER_SIZE(ret, size, len, offset); + + if (reg->chain != NULL) { + ret = snprintf(buf+offset, size, "<chain>%s</chain>", + reg->chain); + SNPRINTF_BUFFER_SIZE(ret, size, len, offset); + } + + ret = snprintf(buf+offset, size, "</data_reg>"); + SNPRINTF_BUFFER_SIZE(ret, size, len, offset); + + return offset; +} + +static int +nft_data_reg_verdict_snprintf_json(char *buf, size_t size, + union nft_data_reg *reg, uint32_t flags) +{ + int len = size, offset = 0, ret = 0; + + ret = snprintf(buf, size, "\"data_reg\":{\"type\":\"verdict\"," + "\"verdict\":\"%s\"", nft_verdict2str(reg->verdict)); + SNPRINTF_BUFFER_SIZE(ret, size, len, offset); + + if (reg->chain != NULL) { + ret = snprintf(buf+offset, size, ",\"chain\":\"%s\"", + reg->chain); + SNPRINTF_BUFFER_SIZE(ret, size, len, offset); + } + + ret = snprintf(buf+offset, size, "}"); + SNPRINTF_BUFFER_SIZE(ret, size, len, offset); + + return offset; +} + int nft_data_reg_snprintf(char *buf, size_t size, union nft_data_reg *reg, uint32_t output_format, uint32_t flags, int reg_type) { @@ -312,44 +374,24 @@ int nft_data_reg_snprintf(char *buf, size_t size, union nft_data_reg *reg, break; } case DATA_VERDICT: - switch(output_format) { - case NFT_OUTPUT_DEFAULT: - return snprintf(buf, size, "%d ", reg->verdict); - case NFT_OUTPUT_XML: - return snprintf(buf, size, - "<data_reg type=\"verdict\">" - "<verdict>%s</verdict>" - "</data_reg>", - nft_verdict2str(reg->verdict)); - case NFT_OUTPUT_JSON: - return snprintf(buf, size, - "\"data_reg\":{" - "\"type\":\"verdict\"," - "\"verdict\":\"%s\"" - "}", nft_verdict2str(reg->verdict)); - default: - break; - } case DATA_CHAIN: switch(output_format) { case NFT_OUTPUT_DEFAULT: - return snprintf(buf, size, "%s ", reg->chain); + return nft_data_reg_verdict_snprintf_def(buf, size, + reg, flags); case NFT_OUTPUT_XML: - return snprintf(buf, size, - "<data_reg type=\"chain\">" - "<chain>%s</chain>" - "</data_reg>", reg->chain); + return nft_data_reg_verdict_snprintf_xml(buf, size, + reg, flags); case NFT_OUTPUT_JSON: - return snprintf(buf, size, - "\"data_reg\":{\"type\":\"chain\"," - "\"chain\":\"%s\"" - "}", reg->chain); + return nft_data_reg_verdict_snprintf_json(buf, size, + reg, flags); default: break; } default: break; } + return -1; } |