summaryrefslogtreecommitdiffstats
path: root/src/expr/data_reg.c
diff options
context:
space:
mode:
authorPablo Neira Ayuso <pablo@netfilter.org>2014-02-03 14:04:42 +0100
committerPablo Neira Ayuso <pablo@netfilter.org>2014-02-03 18:43:13 +0100
commit29fd6a1df9f6c80d155a7a73b8514a68dc9cd22d (patch)
tree9dc15a3e19a6ff36ae9ee3d38c7b8190b73f0a72 /src/expr/data_reg.c
parent16871a3615edcf358d688a8d079b1e7b20053fb1 (diff)
parent076fd1e66e7f1bc3b2bd91f3efb84080da26fb9c (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.c232
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, &reg->len) < 0)
- return -1;
+ if (nft_jansson_parse_val(data, "len", NFT_TYPE_U8, &reg->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,
- &reg->val[i], NFT_TYPE_U32) != 0)
- return -1;
+ &reg->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,
- &reg->len, NFT_TYPE_U8, NFT_XML_MAND) != 0)
+ &reg->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, &reg->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;
}