]> git.ipfire.org Git - thirdparty/libnftnl.git/commitdiff
expr: basic support for printing nft_data_reg in XML format
authorArturo Borrero Gonzalez <arturo.borrero.glez@gmail.com>
Sun, 7 Apr 2013 22:30:22 +0000 (22:30 +0000)
committerPablo Neira Ayuso <pablo@netfilter.org>
Thu, 18 Apr 2013 23:35:33 +0000 (01:35 +0200)
nft_data_reg now is printed in XML according to what it contains

<data> nodes have been also renamed.

Arturo Borrero Gonzalez says:

====================
cmp is using <cmpdata> <cmpdata> has <data_reg></data_reg> which
can also be redundant.

But all around the XML printing (including sets, an incoming patch)
i've been nesting the data_reg into another XML node, so you could
easily see (also the XML parser) the difference between (for example.
in set) nft_set_elem->key and nft_set_elem->data.

As I needed to nest in nft_set_elem I decided to follow a constant
line and do nest all data_reg.
====================

Signed-off-by: Arturo Borrero Gonzalez <arturo.borrero.glez@gmail.com>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
src/expr/bitwise.c
src/expr/cmp.c
src/expr/data_reg.c
src/expr/data_reg.h
src/expr/immediate.c

index ac89cbaaf51106620c57b4e7d6a5c11c6b11ad8a..052144e7206acf60efe45450916eae38fdd1fb0f 100644 (file)
@@ -199,29 +199,26 @@ static int
 nft_rule_expr_bitwise_snprintf_xml(char *buf, size_t size,
                                   struct nft_expr_bitwise *bitwise)
 {
-       int len = size, offset = 0, ret, i;
+       int len = size, offset = 0, ret;
 
        ret = snprintf(buf, len, "\t\t<sreg>%u</sreg> "
                                        "<dreg>%u</dreg> ",
-                       bitwise->sreg, bitwise->dreg);
+                      bitwise->sreg, bitwise->dreg);
        SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
 
        ret = snprintf(buf+offset, len, "<mask>");
        SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
 
-       for (i=0; i<bitwise->mask.len/sizeof(uint32_t); i++) {
-               ret = snprintf(buf+offset, len, "%.8x ",
-                               bitwise->mask.val[i]);
-               SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
-       }
+       ret = nft_data_reg_snprintf(buf+offset, len, &bitwise->mask,
+                                   NFT_RULE_O_XML, 0, DATA_VALUE);
+       SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
 
        ret = snprintf(buf+offset, len, "</mask> <xor>");
        SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
 
-       for (i=0; i<bitwise->xor.len/sizeof(uint32_t); i++) {
-               ret = snprintf(buf+offset, len, "%.8x ", bitwise->xor.val[i]);
-               SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
-       }
+       ret = nft_data_reg_snprintf(buf+offset, len, &bitwise->xor,
+                                   NFT_RULE_O_XML, 0, DATA_VALUE);
+       SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
 
        ret = snprintf(buf+offset, len, "</xor> ");
        SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
@@ -231,29 +228,27 @@ nft_rule_expr_bitwise_snprintf_xml(char *buf, size_t size,
 
 static int
 nft_rule_expr_bitwise_snprintf_default(char *buf, size_t size,
-                                       struct nft_expr_bitwise *bitwise)
+                                      struct nft_expr_bitwise *bitwise)
 {
-       int len = size, offset = 0, ret, i;
+       int len = size, offset = 0, ret;
 
        ret = snprintf(buf, len, "sreg=%u dreg=%u ",
-                       bitwise->sreg, bitwise->dreg);
+                      bitwise->sreg, bitwise->dreg);
        SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
 
        ret = snprintf(buf+offset, len, " mask=");
        SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
 
-       for (i=0; i<bitwise->mask.len/sizeof(uint32_t); i++) {
-               ret = snprintf(buf+offset, len, "%.8x ", bitwise->mask.val[i]);
-               SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
-       }
+       ret = nft_data_reg_snprintf(buf+offset, len, &bitwise->mask,
+                                   NFT_RULE_O_DEFAULT, 0, DATA_VALUE);
+       SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
 
        ret = snprintf(buf+offset, len, " xor=");
        SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
 
-       for (i=0; i<bitwise->xor.len/sizeof(uint32_t); i++) {
-               ret = snprintf(buf+offset, len, "%.8x ", bitwise->xor.val[i]);
-               SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
-       }
+       ret = nft_data_reg_snprintf(buf+offset, len, &bitwise->xor,
+                                   NFT_RULE_O_DEFAULT, 0, DATA_VALUE);
+       SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
 
        return offset;
 }
index 429f02417e3ace5e2cec080e5e56ac4d1a67310d..6b5a3a2160c9bf4b5ff2f1aa2e695a529994acc3 100644 (file)
@@ -169,18 +169,17 @@ static char *expr_cmp_str[] = {
 static int
 nft_rule_expr_cmp_snprintf_xml(char *buf, size_t size, struct nft_expr_cmp *cmp)
 {
-       int len = size, offset = 0, ret, i;
+       int len = size, offset = 0, ret;
 
-       ret = snprintf(buf, len, "\t\t<sreg>%u</sreg> <op>%s</op> <data>",
-                       cmp->sreg, expr_cmp_str[cmp->op]);
+       ret = snprintf(buf, len, "\t\t<sreg>%u</sreg> <op>%s</op> <cmpdata>",
+                      cmp->sreg, expr_cmp_str[cmp->op]);
        SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
 
-       for (i=0; i<cmp->data.len/sizeof(uint32_t); i++) {
-               ret = snprintf(buf+offset, len, "%.8x ", cmp->data.val[i]);
-               SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
-       }
+       ret = nft_data_reg_snprintf(buf+offset, len, &cmp->data,
+                                   NFT_RULE_O_XML, 0, DATA_VALUE);
+       SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
 
-       ret = snprintf(buf+offset, len, "</data> ");
+       ret = snprintf(buf+offset, len, "</cmpdata> ");
        SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
 
        return offset;
@@ -190,16 +189,16 @@ static int
 nft_rule_expr_cmp_snprintf_default(char *buf, size_t size,
                                   struct nft_expr_cmp *cmp)
 {
-       int len = size, offset = 0, ret, i;
+       int len = size, offset = 0, ret;
 
        ret = snprintf(buf, len, "sreg=%u op=%s data=",
-                       cmp->sreg, expr_cmp_str[cmp->op]);
+                      cmp->sreg, expr_cmp_str[cmp->op]);
+       SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
+
+       ret = nft_data_reg_snprintf(buf+offset, len, &cmp->data,
+                                   NFT_RULE_O_DEFAULT, 0, DATA_VALUE);
        SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
 
-       for (i=0; i<cmp->data.len/sizeof(uint32_t); i++) {
-               ret = snprintf(buf+offset, len, "%.8x ", cmp->data.val[i]);
-               SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
-       }
        return offset;
 }
 
index 5b146958cabc1e358f521688d7e6603de36daf04..78c7d4902fffa8a389deaf9976fc2e56f8647446 100644 (file)
 #include <linux/netfilter.h>
 #include <linux/netfilter/nf_tables.h>
 #include <libnftables/expr.h>
+#include <libnftables/rule.h>
 #include "expr_ops.h"
 #include "data_reg.h"
 #include "internal.h"
 
+static int nft_data_reg_value_snprintf_xml(char *buf, size_t size,
+                                          union nft_data_reg *reg,
+                                          uint32_t flags)
+{
+       int len = size, offset = 0, ret, i, j;
+       uint8_t *tmp;
+       int data_len = reg->len/sizeof(uint32_t);
+
+       ret = snprintf(buf, len, "<data_reg type=\"value\" >");
+       SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
+
+       ret = snprintf(buf+offset, len, "<len>%d</len>", data_len);
+       SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
+
+       for (i=0; i<data_len; i++) {
+               ret = snprintf(buf+offset, len, "<data%d>0x", i);
+               SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
+
+               tmp = (uint8_t *)&reg->val[i];
+
+               for (j=0; j<sizeof(int); j++) {
+                       ret = snprintf(buf+offset, len, "%.02x", tmp[j]);
+                       SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
+               }
+
+               ret = snprintf(buf+offset, len, "</data%d>", i);
+               SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
+       }
+
+       ret = snprintf(buf+offset, len, "</data_reg>");
+       SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
+
+       return offset;
+}
+
+static int
+nft_data_reg_value_snprintf_default(char *buf, size_t size,
+                                   union nft_data_reg *reg, uint32_t flags)
+{
+       int len = size, offset = 0, ret, i;
+
+       for (i=0; i<reg->len/sizeof(uint32_t); i++) {
+               ret = snprintf(buf+offset, len, "0x%.8x ", reg->val[i]);
+               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)
+{
+       switch(reg_type) {
+       case DATA_VALUE:
+               switch(output_format) {
+               case NFT_RULE_O_XML:
+                       return nft_data_reg_value_snprintf_xml(buf, size,
+                                                              reg, flags);
+               case NFT_RULE_O_DEFAULT:
+                       return nft_data_reg_value_snprintf_default(buf, size,
+                                                                  reg, flags);
+               default:
+                       break;
+               }
+       case DATA_VERDICT:
+               switch(output_format) {
+               case NFT_RULE_O_XML:
+                       return snprintf(buf, size,
+                                       "<data_reg type=\"verdict\" >"
+                                               "<verdict>%d</verdict>"
+                                       "</data_reg>", reg->verdict);
+               case NFT_RULE_O_DEFAULT:
+                       return snprintf(buf, size, "verdict=%d", reg->verdict);
+               default:
+                       break;
+               }
+       case DATA_CHAIN:
+               switch(output_format) {
+               case NFT_RULE_O_XML:
+                       return snprintf(buf, size,
+                                       "<data_reg type=\"chain\" >"
+                                               "<chain>%s</chain>"
+                                       "</data_reg>", reg->chain);
+               case NFT_RULE_O_DEFAULT:
+                       return snprintf(buf, size, "chain=%s", reg->chain);
+               default:
+                       break;
+               }
+       default:
+               break;
+       }
+       return -1;
+}
+
 static int nft_data_parse_cb(const struct nlattr *attr, void *data)
 {
        const struct nlattr **tb = data;
index 00eab6304ec00fd83e1527a2428b83e0cea7f494..1552c1e572ce75e46d9c2067ecb3282950fd8e65 100644 (file)
@@ -18,6 +18,9 @@ union nft_data_reg {
        };
 };
 
+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);
+int nft_data_reg_xml_parse(union nft_data_reg *reg, char *xml);
 int nft_parse_data(union nft_data_reg *data, struct nlattr *attr, int *type);
 
 #endif
index 496cbfdc6e1c2f5a2ba7ef347d32817a20724675..082db76955a729f510005e8a51c36b7754a082ea 100644 (file)
@@ -196,19 +196,77 @@ nft_rule_expr_immediate_parse(struct nft_rule_expr *e, struct nlattr *attr)
 }
 
 static int
-nft_rule_expr_immediate_snprintf(char *buf, size_t len, uint32_t type,
-                                uint32_t flags, struct nft_rule_expr *e)
+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 = (struct nft_expr_immediate *)e->data;
+
+       ret = snprintf(buf, len, "\t\t<dreg>%u</dreg>"
+                               "\n\t\t<immediatedata>", 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_RULE_O_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_RULE_O_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_RULE_O_XML, flags, DATA_CHAIN);
+               SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
+       }
+
+       ret = snprintf(buf+offset, len, "</immediatedata>");
+       SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
+
+       return offset;
+}
+
+static int
+nft_rule_expr_immediate_snprintf_default(char *buf, size_t len,
+                               struct nft_rule_expr *e, uint32_t flags)
 {
+       int size = len, offset = 0, ret;
        struct nft_expr_immediate *imm = (struct nft_expr_immediate *)e->data;
 
+       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_RULE_O_DEFAULT, 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_RULE_O_DEFAULT, 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_RULE_O_DEFAULT, flags, DATA_CHAIN);
+               SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
+       }
+
+       return offset;
+}
+
+static int
+nft_rule_expr_immediate_snprintf(char *buf, size_t len, uint32_t type,
+                                uint32_t flags, struct nft_rule_expr *e)
+{
        switch(type) {
        case NFT_RULE_O_XML:
-               return snprintf(buf, len, "\t\t<dreg>%u</dreg>"
-                                         " <data>%u</data> ",
-                               imm->dreg, imm->data.val[0]);
+               return nft_rule_expr_immediate_snprintf_xml(buf, len, e, flags);
        case NFT_RULE_O_DEFAULT:
-               return snprintf(buf, len, "dreg=%u data=%u ",
-                               imm->dreg, imm->data.val[0]);
+               return nft_rule_expr_immediate_snprintf_default(buf, len, e, flags);
        default:
                break;
        }