From: Álvaro Neira Ayuso <alvaroneay@xxxxxxxxx> Add function for parsing chains in format JSON Signed-off-by: Alvaro Neira Ayuso <alvaroneay@xxxxxxxxx> --- include/libnftables/chain.h | 1 src/chain.c | 138 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 139 insertions(+) diff --git a/include/libnftables/chain.h b/include/libnftables/chain.h index 382947f..53fd407 100644 --- a/include/libnftables/chain.h +++ b/include/libnftables/chain.h @@ -52,6 +52,7 @@ enum { enum nft_chain_parse_type { NFT_CHAIN_PARSE_NONE = 0, NFT_CHAIN_PARSE_XML, + NFT_CHAIN_PARSE_JSON, NFT_CHAIN_PARSE_MAX }; diff --git a/src/chain.c b/src/chain.c index 1e07044..d9d41ee 100644 --- a/src/chain.c +++ b/src/chain.c @@ -468,6 +468,141 @@ int nft_chain_nlmsg_parse(const struct nlmsghdr *nlh, struct nft_chain *c) } EXPORT_SYMBOL(nft_chain_nlmsg_parse); +static int str2policy(const char *policy) +{ + if (strcmp("accept", policy) == 0) { + return NF_ACCEPT; + } else if (strcmp("drop", policy) == 0) { + return NF_DROP; + } else { + return -1; + } +} + +static int nft_chain_json_parse(struct nft_chain *c, char *json) +{ +#ifdef JSON_PARSING + json_t *root; + json_error_t error; + uint64_t val64; + uint32_t hooknum; + int32_t prio; + const char *valstr; + + /* Load the tree */ + root = json_loadb (json, strlen(json), 0, &error); + if (!root) { + errno = EINVAL; + return -1; + } + + root = json_object_get(root, "chain"); + if (root == NULL) { + errno = ERANGE; + return -1; + } + + if (nft_jansson_value_parse_val(root, "version", NFT_TYPE_U64, + &val64) == -1) + goto err; + + if (val64 != NFT_CHAIN_JSON_VERSION) + goto err; + + valstr = nft_jansson_value_parse_str(root, "name"); + if (valstr == NULL) + goto err; + + nft_chain_attr_set_str(c, NFT_CHAIN_ATTR_NAME, strdup(valstr)); + + if (nft_jansson_value_parse_val(root, "handle", NFT_TYPE_U64, + &val64) == -1) + goto err; + + nft_chain_attr_set_u64(c,NFT_CHAIN_ATTR_HANDLE, val64); + + if (nft_jansson_value_parse_val(root, "bytes", NFT_TYPE_U64, + &val64) == -1) + goto err; + + nft_chain_attr_set_u64(c, NFT_CHAIN_ATTR_BYTES, val64); + + if (nft_jansson_value_parse_val(root, "packets", NFT_TYPE_U64, + &val64) == -1) + goto err; + + if (val64 < 0) + goto err; + + nft_chain_attr_set_u64(c, NFT_CHAIN_ATTR_PACKETS, val64); + + root = json_object_get(root, "properties"); + + valstr = nft_jansson_value_parse_str(root, "family"); + + if (valstr == NULL) + goto err; + + if (nft_str2family(valstr) == -1) + goto err; + + nft_chain_attr_set_u32(c, NFT_CHAIN_ATTR_FAMILY, nft_str2family(valstr)); + + valstr = nft_jansson_value_parse_str(root, "table"); + + if (valstr == NULL) + goto err; + + nft_chain_attr_set_str(c, NFT_CHAIN_ATTR_TABLE, strdup(valstr)); + + if (nft_jansson_node_exist(root, "hooknum")) { + valstr = nft_jansson_value_parse_str(root, "type"); + + if (valstr == NULL) + goto err; + + nft_chain_attr_set_str(c, NFT_CHAIN_ATTR_TYPE, strdup(valstr)); + + if (nft_jansson_value_parse_val(root, "prio", NFT_TYPE_S32, + &prio) == -1) + goto err; + + nft_chain_attr_set_s32(c, NFT_CHAIN_ATTR_PRIO, prio); + + valstr = nft_jansson_value_parse_str(root, "hooknum"); + for (hooknum = 0; hooknum < NF_INET_NUMHOOKS; hooknum++) { + if (strcmp(valstr, hooknum2str_array[hooknum]) == 0) { + nft_chain_attr_set_u32(c, NFT_CHAIN_ATTR_HOOKNUM, + hooknum); + break; + } + } + + valstr = nft_jansson_value_parse_str(root, "policy"); + + if (valstr == NULL) + goto err; + + if (str2policy(valstr) == -1) + goto err; + + nft_chain_attr_set_u32(c, NFT_CHAIN_ATTR_POLICY, + str2policy(valstr)); + } + + free(root); + return 0; + +err: + free(root); + errno = ERANGE; + return -1; +#else + errno = EOPNOTSUPP; + return -1; +#endif +} + static int nft_chain_xml_parse(struct nft_chain *c, char *xml) { #ifdef XML_PARSING @@ -661,6 +796,9 @@ int nft_chain_parse(struct nft_chain *c, enum nft_chain_parse_type type, case NFT_CHAIN_PARSE_XML: ret = nft_chain_xml_parse(c, data); break; + case NFT_CHAIN_PARSE_JSON: + ret = nft_chain_json_parse(c, data); + break; default: ret = -1; errno = EOPNOTSUPP; -- To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html