On Thu, Jul 25, 2013 at 10:52:39PM +0200, Alvaro Neira wrote: > 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; > + } > +} Arturo just added nft_str2verdict, please use it. > + > +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); ^ no need for space there. > + if (!root) { if (root == NULL) for consistency with other code you sent. > + 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; You have to change nft_jansson_value_parse_str to set errno accordingly. Then you return -1; > + > + 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) val64 is uint64_t, so it cannot be negative. > + 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; return -1; instead. nft_jansson_value_parse_str should set errno accordingly. > + > + if (nft_str2family(valstr) == -1) > + goto err; return -1; nft_str2family already sets errno. > + > + 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; this should return EINVAL. > + 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 -- 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