diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/expr/bitwise.c | 33 | ||||
-rw-r--r-- | src/expr/cmp.c | 18 | ||||
-rw-r--r-- | src/expr/immediate.c | 47 | ||||
-rw-r--r-- | src/internal.h | 2 | ||||
-rw-r--r-- | src/mxml.c | 54 |
5 files changed, 74 insertions, 80 deletions
diff --git a/src/expr/bitwise.c b/src/expr/bitwise.c index e9176cd..67c120f 100644 --- a/src/expr/bitwise.c +++ b/src/expr/bitwise.c @@ -202,10 +202,7 @@ nft_rule_expr_bitwise_xml_parse(struct nft_rule_expr *e, mxml_node_t *tree) { #ifdef XML_PARSING struct nft_expr_bitwise *bitwise = (struct nft_expr_bitwise *)e->data; - mxml_node_t *node = NULL; - mxml_node_t *save = NULL; int32_t reg; - union nft_data_reg data_regtmp; reg = nft_mxml_reg_parse(tree, "sreg", MXML_DESCEND_FIRST); if (reg < 0) @@ -221,39 +218,15 @@ nft_rule_expr_bitwise_xml_parse(struct nft_rule_expr *e, mxml_node_t *tree) bitwise->dreg = reg; e->flags |= (1 << NFT_EXPR_BITWISE_DREG); - /* Get and set <mask> */ - node = mxmlFindElement(tree, tree, "mask", NULL, NULL, - MXML_DESCEND); - if (node == NULL) + if (nft_mxml_data_reg_parse(tree, "mask", + &bitwise->mask) != DATA_VALUE) return -1; - /* hack for mxmSaveAllocString to print just the current node */ - save = node->next; - node->next = NULL; - if (nft_data_reg_xml_parse(&data_regtmp, - mxmlSaveAllocString(node, MXML_NO_CALLBACK)) < 0) - return -1; - node->next = save; - - memcpy(&bitwise->mask.val, data_regtmp.val, data_regtmp.len); - bitwise->mask.len = data_regtmp.len; e->flags |= (1 << NFT_EXPR_BITWISE_MASK); - /* Get and set <xor> */ - node = mxmlFindElement(tree, tree, "xor", NULL, NULL, - MXML_DESCEND); - if (node == NULL) - return -1; - - /* hack for mxmSaveAllocString to print just the current node */ - save = node->next; - node->next = NULL; - if (nft_data_reg_xml_parse(&data_regtmp, - mxmlSaveAllocString(node, MXML_NO_CALLBACK)) < 0) + if (nft_mxml_data_reg_parse(tree, "xor", &bitwise->xor) != DATA_VALUE) return -1; - memcpy(&bitwise->xor.val, data_regtmp.val, data_regtmp.len); - bitwise->xor.len = data_regtmp.len; e->flags |= (1 << NFT_EXPR_BITWISE_XOR); /* Additional validation: mask and xor must use the same number of diff --git a/src/expr/cmp.c b/src/expr/cmp.c index 2115839..3f795bc 100644 --- a/src/expr/cmp.c +++ b/src/expr/cmp.c @@ -173,8 +173,6 @@ static int nft_rule_expr_cmp_xml_parse(struct nft_rule_expr *e, mxml_node_t *tre #ifdef XML_PARSING struct nft_expr_cmp *cmp = (struct nft_expr_cmp *)e->data; mxml_node_t *node = NULL; - mxml_node_t *save = NULL; - union nft_data_reg data_regtmp; int32_t reg; reg = nft_mxml_reg_parse(tree, "sreg", MXML_DESCEND_FIRST); @@ -207,22 +205,12 @@ static int nft_rule_expr_cmp_xml_parse(struct nft_rule_expr *e, mxml_node_t *tre } /* Get and set <cmpdata>. Is not mandatory */ - node = mxmlFindElement(tree, tree, "cmpdata", NULL, NULL, - MXML_DESCEND); + node = mxmlFindElement(tree, tree, "cmpdata", NULL, NULL, MXML_DESCEND); if (node != NULL) { - /* hack for mxmSaveAllocString to print just the current node */ - save = node->next; - node->next = NULL; - - if (nft_data_reg_xml_parse(&data_regtmp, - mxmlSaveAllocString(node, MXML_NO_CALLBACK)) < 0) { + if (nft_mxml_data_reg_parse(tree, "cmpdata", + &cmp->data) != DATA_VALUE) { return -1; } - - node->next = save; - - memcpy(&cmp->data.val, data_regtmp.val, data_regtmp.len); - cmp->data.len = data_regtmp.len; e->flags |= (1 << NFT_EXPR_CMP_DATA); } diff --git a/src/expr/immediate.c b/src/expr/immediate.c index c5757c6..847d0c4 100644 --- a/src/expr/immediate.c +++ b/src/expr/immediate.c @@ -200,9 +200,7 @@ nft_rule_expr_immediate_xml_parse(struct nft_rule_expr *e, mxml_node_t *tree) { #ifdef XML_PARSING struct nft_expr_immediate *imm = (struct nft_expr_immediate *)e->data; - mxml_node_t *node = NULL; - mxml_node_t *save = NULL; - union nft_data_reg data_regtmp; + int datareg_type; int32_t reg; reg = nft_mxml_reg_parse(tree, "dreg", MXML_DESCEND_FIRST); @@ -212,43 +210,22 @@ nft_rule_expr_immediate_xml_parse(struct nft_rule_expr *e, mxml_node_t *tree) imm->dreg = reg; e->flags |= (1 << NFT_EXPR_IMM_DREG); - /* Get and set <immdata>. Is mandatory */ - node = mxmlFindElement(tree, tree, "immdata", NULL, NULL, - MXML_DESCEND); - if (node == NULL) + datareg_type = nft_mxml_data_reg_parse(tree, "immdata", &imm->data); + if (datareg_type < 0) return -1; - /* hack for mxmSaveAllocString to print just the current node */ - save = node->next; - node->next = NULL; - - if (nft_data_reg_xml_parse(&data_regtmp, - mxmlSaveAllocString(node, MXML_NO_CALLBACK)) < 0) - return -1; - node->next = save; - - /* data_reg type switch */ - node = mxmlFindElement(tree, tree, "data_reg", NULL, NULL, - MXML_DESCEND); - if (node == NULL) - return -1; - - if (mxmlElementGetAttr(node, "type") == NULL) - return -1; - - if (strcmp(mxmlElementGetAttr(node, "type"), "value") == 0) { - memcpy(&imm->data.val, data_regtmp.val, data_regtmp.len); - imm->data.len = data_regtmp.len; + switch (datareg_type) { + case DATA_VALUE: e->flags |= (1 << NFT_EXPR_IMM_DATA); - } else if (strcmp(mxmlElementGetAttr(node, "type"), "verdict") == 0) { - imm->data.verdict = data_regtmp.verdict; + break; + case DATA_VERDICT: e->flags |= (1 << NFT_EXPR_IMM_VERDICT); - } else if (strcmp(mxmlElementGetAttr(node, "type"), "chain") == 0) { - if (imm->data.chain) - free(imm->data.chain); - - imm->data.chain = strdup(data_regtmp.chain); + break; + case DATA_CHAIN: e->flags |= (1 << NFT_EXPR_IMM_CHAIN); + break; + default: + return -1; } return 0; diff --git a/src/internal.h b/src/internal.h index b6df4dd..d5d41bd 100644 --- a/src/internal.h +++ b/src/internal.h @@ -17,6 +17,8 @@ #include <mxml.h> struct nft_rule_expr *nft_mxml_expr_parse(mxml_node_t *node); int nft_mxml_reg_parse(mxml_node_t *tree, const char *reg_name, uint32_t flags); +union nft_data_reg; +int nft_mxml_data_reg_parse(mxml_node_t *tree, const char *node_name, union nft_data_reg *data_reg); #endif #define NFT_TABLE_XML_VERSION 0 @@ -76,4 +76,58 @@ int nft_mxml_reg_parse(mxml_node_t *tree, const char *reg_name, uint32_t flags) err: return -1; } + +int nft_mxml_data_reg_parse(mxml_node_t *tree, const char *node_name, + union nft_data_reg *data_reg) +{ + mxml_node_t *node; + const char *type; + char *tmpstr = NULL; + int ret; + + node = mxmlFindElement(tree, tree, node_name, NULL, NULL, + MXML_DESCEND_FIRST); + if (node == NULL || node->child == NULL) { + errno = EINVAL; + goto err; + } + + tmpstr = mxmlSaveAllocString(node, MXML_NO_CALLBACK); + if (tmpstr == NULL) { + errno = ENOMEM; + goto err; + } + + ret = nft_data_reg_xml_parse(data_reg, tmpstr); + free(tmpstr); + + if (ret < 0) { + errno = EINVAL; + goto err; + } + + node = mxmlFindElement(node, node, "data_reg", NULL, NULL, + MXML_DESCEND); + if (node == NULL || node->child == NULL) { + errno = EINVAL; + goto err; + } + + type = mxmlElementGetAttr(node, "type"); + if (type == NULL) { + errno = EINVAL; + goto err; + } + + if (strcmp(type, "value") == 0) + return DATA_VALUE; + else if (strcmp(type, "verdict") == 0) + return DATA_VERDICT; + else if (strcmp(type, "chain") == 0) + return DATA_CHAIN; + else + errno = EINVAL; +err: + return -1; +} #endif |