Beispiel #1
0
static int
nft_rule_expr_bitwise_json_parse(struct nft_rule_expr *e, json_t *root,
				 struct nft_parse_err *err)
{
#ifdef JSON_PARSING
	struct nft_expr_bitwise *bitwise = nft_expr_data(e);
	uint32_t reg, len;

	if (nft_jansson_parse_reg(root, "sreg", NFT_TYPE_U32, &reg, err) == 0)
		nft_rule_expr_set_u32(e, NFT_EXPR_BITWISE_SREG, reg);

	if (nft_jansson_parse_reg(root, "dreg", NFT_TYPE_U32, &reg, err) == 0)
		nft_rule_expr_set_u32(e, NFT_EXPR_BITWISE_DREG, reg);

	if (nft_jansson_parse_val(root, "len", NFT_TYPE_U32, &len, err) == 0)
		nft_rule_expr_set_u32(e, NFT_EXPR_BITWISE_LEN, len);

	if (nft_jansson_data_reg_parse(root, "mask", &bitwise->mask,
				       err) == DATA_VALUE)
		e->flags |= (1 << NFT_EXPR_BITWISE_MASK);

	if (nft_jansson_data_reg_parse(root, "xor", &bitwise->xor,
				       err) == DATA_VALUE)
		e->flags |= (1 << NFT_EXPR_BITWISE_XOR);

	if (bitwise->mask.len != bitwise->xor.len)
		return -1;

	return 0;
#else
	errno = EOPNOTSUPP;
	return -1;
#endif
}
int main(int argc, char *argv[])
{
	struct nft_rule *a, *b;
	struct nft_rule_expr *ex;
	struct nlmsghdr *nlh;
	char buf[4096];
	struct nft_rule_expr_iter *iter_a, *iter_b;
	struct nft_rule_expr *rule_a, *rule_b;
	uint32_t chain_t = 0x12345678;
	uint32_t data_t = 0x12345678;

	a = nft_rule_alloc();
	b = nft_rule_alloc();
	if (a == NULL || b == NULL)
		print_err("OOM");
	ex = nft_rule_expr_alloc("immediate");
	if (ex == NULL)
		print_err("OOM");

	nft_rule_expr_set_u32(ex, NFT_EXPR_IMM_DREG, 0x1234568);
	nft_rule_expr_set(ex, NFT_EXPR_IMM_DATA, &chain_t, sizeof(chain_t));
	nft_rule_expr_set_u32(ex, NFT_EXPR_IMM_VERDICT, 0x12345678);
	nft_rule_expr_set(ex, NFT_EXPR_IMM_CHAIN, &data_t, sizeof(data_t));

	nft_rule_add_expr(a, ex);

	nlh = nft_rule_nlmsg_build_hdr(buf, NFT_MSG_NEWRULE, AF_INET, 0, 1234);
	nft_rule_nlmsg_build_payload(nlh, a);

	if (nft_rule_nlmsg_parse(nlh, b) < 0)
		print_err("parsing problems");

	iter_a = nft_rule_expr_iter_create(a);
	iter_b = nft_rule_expr_iter_create(b);
	if (iter_a == NULL || iter_b == NULL)
		print_err("OOM");

	rule_a = nft_rule_expr_iter_next(iter_a);
	rule_b = nft_rule_expr_iter_next(iter_b);
	if (rule_a == NULL || rule_b == NULL)
		print_err("OOM");

	cmp_nft_rule_expr(rule_a, rule_b);

	if (nft_rule_expr_iter_next(iter_a) != NULL ||
	    nft_rule_expr_iter_next(iter_b) != NULL)
		print_err("More 1 expr.");

	nft_rule_expr_iter_destroy(iter_a);
	nft_rule_expr_iter_destroy(iter_b);
	nft_rule_free(a);
	nft_rule_free(b);

	if (!test_ok)
		exit(EXIT_FAILURE);

	printf("%s: \033[32mOK\e[0m\n", argv[0]);
	return EXIT_SUCCESS;
}
int main(int argc, char *argv[])
{
	struct nft_rule *a, *b;
	struct nft_rule_expr *ex;
	struct nlmsghdr *nlh;
	char buf[4096];
	struct nft_rule_expr_iter *iter_a, *iter_b;
	struct nft_rule_expr *rule_a, *rule_b;

	a = nft_rule_alloc();
	b = nft_rule_alloc();
	if (a == NULL || b == NULL)
		print_err("OOM");
	ex = nft_rule_expr_alloc("exthdr");
	if (ex == NULL)
		print_err("OOM");

	nft_rule_expr_set_u32(ex, NFT_EXPR_EXTHDR_DREG, 0x12345678);
	nft_rule_expr_set_u32(ex, NFT_EXPR_EXTHDR_TYPE, 0x12);
	nft_rule_expr_set_u32(ex, NFT_EXPR_EXTHDR_OFFSET, 0x12345678);
	nft_rule_expr_set_u32(ex, NFT_EXPR_EXTHDR_LEN, 0x12345678);

	nft_rule_add_expr(a, ex);

	nlh = nft_rule_nlmsg_build_hdr(buf, NFT_MSG_NEWRULE, AF_INET, 0, 1234);
	nft_rule_nlmsg_build_payload(nlh, a);
	if (nft_rule_nlmsg_parse(nlh, b) < 0)
		print_err("parsing problems");

	iter_a = nft_rule_expr_iter_create(a);
	iter_b = nft_rule_expr_iter_create(b);
	if (iter_a == NULL || iter_b == NULL)
		print_err("OOM");

	rule_a = nft_rule_expr_iter_next(iter_a);
	rule_b = nft_rule_expr_iter_next(iter_b);
	if (rule_a == NULL || rule_b == NULL)
		print_err("OOM");

	cmp_nft_rule_expr(rule_a, rule_b);

	if (nft_rule_expr_iter_next(iter_a) != NULL ||
	    nft_rule_expr_iter_next(iter_b) != NULL)
		print_err("More 1 expr.");

	nft_rule_expr_iter_destroy(iter_a);
	nft_rule_expr_iter_destroy(iter_b);
	nft_rule_free(a);
	nft_rule_free(b);
	if (!test_ok)
		exit(EXIT_FAILURE);

	printf("%s: \033[32mOK\e[0m\n", argv[0]);
	return EXIT_SUCCESS;
}
Beispiel #4
0
static int nft_rule_expr_ct_xml_parse(struct nft_rule_expr *e, mxml_node_t *tree,
				      struct nft_parse_err *err)
{
#ifdef XML_PARSING
	const char *key_str, *dir_str;
	int key;
	uint8_t dir;
	uint32_t dreg, sreg;

	if (nft_mxml_reg_parse(tree, "dreg", &dreg, MXML_DESCEND_FIRST,
			       NFT_XML_OPT, err) == 0)
		nft_rule_expr_set_u32(e, NFT_EXPR_CT_DREG, dreg);

	if (nft_mxml_reg_parse(tree, "sreg", &sreg, MXML_DESCEND_FIRST,
			       NFT_XML_OPT, err) == 0)
		nft_rule_expr_set_u32(e, NFT_EXPR_CT_SREG, sreg);

	key_str = nft_mxml_str_parse(tree, "key", MXML_DESCEND_FIRST,
				     NFT_XML_MAND, err);
	if (key_str != NULL) {
		key = str2ctkey(key_str);
		if (key < 0)
			return -1;

		nft_rule_expr_set_u32(e, NFT_EXPR_CT_KEY, key);
	}
	dir_str = nft_mxml_str_parse(tree, "dir", MXML_DESCEND_FIRST,
				     NFT_XML_OPT, err);
	if (dir_str != NULL) {
		if (str2ctdir(dir_str, &dir) != 0) {
			err->node_name = "dir";
			err->error = NFT_PARSE_EBADTYPE;
			goto err;
		}
		nft_rule_expr_set_u8(e, NFT_EXPR_CT_DIR, dir);
	}

	return 0;
err:
	errno = EINVAL;
	return -1;
#else
	errno = EOPNOTSUPP;
	return -1;
#endif
}
Beispiel #5
0
static int nft_rule_expr_log_xml_parse(struct nft_rule_expr *e,
				       mxml_node_t *tree,
				       struct nft_parse_err *err)
{
#ifdef XML_PARSING
	const char *prefix;
	uint32_t snaplen, level, flags;
	uint16_t group, qthreshold;

	prefix = nft_mxml_str_parse(tree, "prefix", MXML_DESCEND_FIRST,
				    NFT_XML_MAND, err);
	if (prefix != NULL)
		nft_rule_expr_set_str(e, NFT_EXPR_LOG_PREFIX, prefix);

	if (nft_mxml_num_parse(tree, "group", MXML_DESCEND_FIRST, BASE_DEC,
			       &group, NFT_TYPE_U16, NFT_XML_MAND, err) == 0)
		nft_rule_expr_set_u16(e, NFT_EXPR_LOG_GROUP, group);

	if (nft_mxml_num_parse(tree, "snaplen", MXML_DESCEND_FIRST, BASE_DEC,
			       &snaplen, NFT_TYPE_U32, NFT_XML_MAND, err) == 0)
		nft_rule_expr_set_u32(e, NFT_EXPR_LOG_SNAPLEN, snaplen);

	if (nft_mxml_num_parse(tree, "qthreshold", MXML_DESCEND_FIRST, BASE_DEC,
			       &qthreshold, NFT_TYPE_U16, NFT_XML_MAND,
			       err) == 0)
		nft_rule_expr_set_u16(e, NFT_EXPR_LOG_QTHRESHOLD, qthreshold);

	if (nft_mxml_num_parse(tree, "level", MXML_DESCEND_FIRST, BASE_DEC,
			       &level, NFT_TYPE_U16, NFT_XML_MAND,
			       err) == 0)
		nft_rule_expr_set_u32(e, NFT_EXPR_LOG_LEVEL, level);

	if (nft_mxml_num_parse(tree, "flags", MXML_DESCEND_FIRST, BASE_DEC,
			       &flags, NFT_TYPE_U16, NFT_XML_MAND,
			       err) == 0)
		nft_rule_expr_set_u32(e, NFT_EXPR_LOG_FLAGS, flags);

	return 0;
#else
	errno = EOPNOTSUPP;
	return -1;
#endif
}
Beispiel #6
0
static int nft_rule_expr_ct_json_parse(struct nft_rule_expr *e, json_t *root,
				       struct nft_parse_err *err)
{
#ifdef JSON_PARSING
	const char *key_str, *dir_str;
	uint32_t reg;
	uint8_t dir;
	int key;

	if (nft_jansson_parse_reg(root, "dreg", NFT_TYPE_U32, &reg, err) == 0)
		nft_rule_expr_set_u32(e, NFT_EXPR_CT_DREG, reg);

	if (nft_jansson_parse_reg(root, "sreg", NFT_TYPE_U32, &reg, err) == 0)
		nft_rule_expr_set_u32(e, NFT_EXPR_CT_SREG, reg);

	key_str = nft_jansson_parse_str(root, "key", err);
	if (key_str != NULL) {
		key = str2ctkey(key_str);
		if (key < 0)
			return -1;

		nft_rule_expr_set_u32(e, NFT_EXPR_CT_KEY, key);
	}

	dir_str = nft_jansson_parse_str(root, "dir", err);
	if (dir_str != NULL) {
		if (str2ctdir(dir_str, &dir) != 0) {
			err->node_name = "dir";
			err->error = NFT_PARSE_EBADTYPE;
			goto err;
		}
		nft_rule_expr_set_u8(e, NFT_EXPR_CT_DIR, dir);
	}

	return 0;
err:
	errno = EINVAL;
	return -1;
#else
	errno = EOPNOTSUPP;
	return -1;
#endif
}
Beispiel #7
0
static int
nft_rule_expr_byteorder_xml_parse(struct nft_rule_expr *e, mxml_node_t *tree,
				  struct nft_parse_err *err)
{
#ifdef XML_PARSING
	const char *op;
	int32_t ntoh;
	uint32_t sreg, dreg, len, size;

	if (nft_mxml_reg_parse(tree, "sreg", &sreg, MXML_DESCEND_FIRST,
			       NFT_XML_MAND, err) == 0)
		nft_rule_expr_set_u32(e, NFT_EXPR_BYTEORDER_SREG, sreg);

	if (nft_mxml_reg_parse(tree, "dreg", &dreg, MXML_DESCEND, NFT_XML_MAND,
			       err) == 0)
		nft_rule_expr_set_u32(e, NFT_EXPR_BYTEORDER_DREG, dreg);

	op = nft_mxml_str_parse(tree, "op", MXML_DESCEND_FIRST, NFT_XML_MAND,
				err);
	if (op != NULL) {
		ntoh = nft_str2ntoh(op);
		if (ntoh < 0)
			return -1;

		nft_rule_expr_set_u32(e, NFT_EXPR_BYTEORDER_OP, ntoh);
	}

	if (nft_mxml_num_parse(tree, "len", MXML_DESCEND_FIRST, BASE_DEC,
			       &len, NFT_TYPE_U32, NFT_XML_MAND, err) == 0)
		nft_rule_expr_set_u32(e, NFT_EXPR_BYTEORDER_LEN, len);

	if (nft_mxml_num_parse(tree, "size", MXML_DESCEND_FIRST, BASE_DEC,
			       &size, NFT_TYPE_U32, NFT_XML_MAND, err) == 0)
		nft_rule_expr_set_u32(e, NFT_EXPR_BYTEORDER_SIZE, size);

	return 0;
#else
	errno = EOPNOTSUPP;
	return -1;
#endif
}
Beispiel #8
0
static int
nft_rule_expr_bitwise_xml_parse(struct nft_rule_expr *e, mxml_node_t *tree,
				struct nft_parse_err *err)
{
#ifdef XML_PARSING
	struct nft_expr_bitwise *bitwise = nft_expr_data(e);
	uint32_t sreg, dreg, len;

	if (nft_mxml_reg_parse(tree, "sreg", &sreg, MXML_DESCEND_FIRST,
			       NFT_XML_MAND, err) == 0)
		nft_rule_expr_set_u32(e, NFT_EXPR_BITWISE_SREG, sreg);

	if (nft_mxml_reg_parse(tree, "dreg", &dreg, MXML_DESCEND_FIRST,
			       NFT_XML_MAND, err) == 0)
		nft_rule_expr_set_u32(e, NFT_EXPR_BITWISE_DREG, dreg);

	if (nft_mxml_num_parse(tree, "len", MXML_DESCEND_FIRST, BASE_DEC,
			       &len, NFT_TYPE_U32, NFT_XML_MAND, err) == 0)
		nft_rule_expr_set_u32(e, NFT_EXPR_BITWISE_LEN, len);

	if (nft_mxml_data_reg_parse(tree, "mask", &bitwise->mask, NFT_XML_MAND,
				    err) == DATA_VALUE)
		e->flags |= (1 << NFT_EXPR_BITWISE_MASK);

	if (nft_mxml_data_reg_parse(tree, "xor", &bitwise->xor, NFT_XML_MAND,
				    err) == DATA_VALUE)
		e->flags |= (1 << NFT_EXPR_BITWISE_XOR);

	/* Additional validation: mask and xor must use the same number of
	 * data registers.
	 */
	if (bitwise->mask.len != bitwise->xor.len)
		return -1;

	return 0;
#else
	errno = EOPNOTSUPP;
	return -1;
#endif
}
Beispiel #9
0
static int nft_rule_expr_nat_json_parse(struct nft_rule_expr *e, json_t *root,
					struct nft_parse_err *err)
{
#ifdef JSON_PARSING
	const char *nat_type, *family_str;
	uint32_t reg, flags;
	int val32;

	nat_type = nft_jansson_parse_str(root, "nat_type", err);
	if (nat_type == NULL)
		return -1;

	val32 = nft_str2nat(nat_type);
	if (val32 < 0)
		return -1;

	nft_rule_expr_set_u32(e, NFT_EXPR_NAT_TYPE, val32);

	family_str = nft_jansson_parse_str(root, "family", err);
	if (family_str == NULL)
		return -1;

	val32 = nft_str2family(family_str);
	if (val32 < 0)
		return -1;

	nft_rule_expr_set_u32(e, NFT_EXPR_NAT_FAMILY, val32);

	if (nft_jansson_parse_reg(root, "sreg_addr_min", NFT_TYPE_U32,
				  &reg, err) == 0)
		nft_rule_expr_set_u32(e, NFT_EXPR_NAT_REG_ADDR_MIN, reg);

	if (nft_jansson_parse_reg(root, "sreg_addr_max", NFT_TYPE_U32,
				  &reg, err) == 0)
		nft_rule_expr_set_u32(e, NFT_EXPR_NAT_REG_ADDR_MAX, reg);

	if (nft_jansson_parse_reg(root, "sreg_proto_min", NFT_TYPE_U32,
				  &reg, err) == 0)
		nft_rule_expr_set_u32(e, NFT_EXPR_NAT_REG_PROTO_MIN, reg);

	if (nft_jansson_parse_reg(root, "sreg_proto_max", NFT_TYPE_U32,
				  &reg, err) == 0)
		nft_rule_expr_set_u32(e, NFT_EXPR_NAT_REG_PROTO_MAX, reg);

	if (nft_jansson_parse_val(root, "flags", NFT_TYPE_U32,
				  &flags, err) == 0)
		nft_rule_expr_set_u32(e, NFT_EXPR_NAT_FLAGS, flags);

	return 0;
#else
	errno = EOPNOTSUPP;
	return -1;
#endif
}
Beispiel #10
0
static int nft_rule_expr_nat_xml_parse(struct nft_rule_expr *e, mxml_node_t *tree,
				       struct nft_parse_err *err)
{
#ifdef XML_PARSING
	const char *nat_type;
	uint32_t family, nat_type_value, flags;
	uint32_t reg_addr_min, reg_addr_max;
	uint32_t reg_proto_min, reg_proto_max;

	nat_type = nft_mxml_str_parse(tree, "nat_type", MXML_DESCEND_FIRST,
				      NFT_XML_MAND, err);
	if (nat_type == NULL)
		return -1;

	nat_type_value = nft_str2nat(nat_type);
	if (nat_type_value < 0)
		return -1;
	nft_rule_expr_set_u32(e, NFT_EXPR_NAT_TYPE, nat_type_value);

	family = nft_mxml_family_parse(tree, "family", MXML_DESCEND_FIRST,
				       NFT_XML_MAND, err);
	if (family < 0) {
		mxmlDelete(tree);
		return -1;
	}
	nft_rule_expr_set_u32(e, NFT_EXPR_NAT_FAMILY, family);

	if (nft_mxml_reg_parse(tree, "sreg_addr_min", &reg_addr_min,
			       MXML_DESCEND, NFT_XML_MAND, err) == 0)
		nft_rule_expr_set_u32(e, NFT_EXPR_NAT_REG_ADDR_MIN, reg_addr_min);

	if (nft_mxml_reg_parse(tree, "sreg_addr_max", &reg_addr_max,
			       MXML_DESCEND, NFT_XML_MAND, err) == 0)
		nft_rule_expr_set_u32(e, NFT_EXPR_NAT_REG_ADDR_MAX, reg_addr_max);

	if (nft_mxml_reg_parse(tree, "sreg_proto_min", &reg_proto_min,
			       MXML_DESCEND, NFT_XML_MAND, err) == 0)
		nft_rule_expr_set_u32(e, NFT_EXPR_NAT_REG_PROTO_MIN, reg_proto_min);

	if (nft_mxml_reg_parse(tree, "sreg_proto_max", &reg_proto_max,
			       MXML_DESCEND, NFT_XML_MAND, err) == 0)
		nft_rule_expr_set_u32(e, NFT_EXPR_NAT_REG_PROTO_MAX, reg_proto_max);

	if (nft_mxml_num_parse(tree, "flags", MXML_DESCEND, BASE_DEC, &flags,
			       NFT_TYPE_U32, NFT_XML_MAND, err) == 0)
		nft_rule_expr_set_u32(e, NFT_EXPR_NAT_FLAGS, flags);

	return 0;
#else
	errno = EOPNOTSUPP;
	return -1;
#endif
}
Beispiel #11
0
static int nft_rule_expr_log_json_parse(struct nft_rule_expr *e, json_t *root,
					struct nft_parse_err *err)
{
#ifdef JSON_PARSING
	const char *prefix;
	uint32_t snaplen, level, flags;
	uint16_t group, qthreshold;

	prefix = nft_jansson_parse_str(root, "prefix", err);
	if (prefix != NULL)
		nft_rule_expr_set_str(e, NFT_EXPR_LOG_PREFIX, prefix);

	if (nft_jansson_parse_val(root, "group", NFT_TYPE_U16, &group,
				  err) == 0)
		nft_rule_expr_set_u16(e, NFT_EXPR_LOG_GROUP, group);

	if (nft_jansson_parse_val(root, "snaplen", NFT_TYPE_U32, &snaplen,
				  err) == 0)
		nft_rule_expr_set_u32(e, NFT_EXPR_LOG_SNAPLEN, snaplen);

	if (nft_jansson_parse_val(root, "qthreshold", NFT_TYPE_U16,
				  &qthreshold, err) == 0)
		nft_rule_expr_set_u16(e, NFT_EXPR_LOG_QTHRESHOLD, qthreshold);

	if (nft_jansson_parse_val(root, "level", NFT_TYPE_U32, &level,
				  err) == 0)
		nft_rule_expr_set_u32(e, NFT_EXPR_LOG_LEVEL, level);

	if (nft_jansson_parse_val(root, "flags", NFT_TYPE_U32, &flags,
				  err) == 0)
		nft_rule_expr_set_u32(e, NFT_EXPR_LOG_FLAGS, flags);

	return 0;
#else
	errno = EOPNOTSUPP;
	return -1;
#endif
}
Beispiel #12
0
static int
nft_rule_expr_byteorder_json_parse(struct nft_rule_expr *e, json_t *root,
				   struct nft_parse_err *err)
{
#ifdef JSON_PARSING
	const char *op;
	uint32_t sreg, dreg, len, size;
	int ntoh;

	if (nft_jansson_parse_reg(root, "sreg", NFT_TYPE_U32, &sreg, err) == 0)
		nft_rule_expr_set_u32(e, NFT_EXPR_BYTEORDER_SREG, sreg);

	if (nft_jansson_parse_reg(root, "dreg", NFT_TYPE_U32, &dreg, err) == 0)
		nft_rule_expr_set_u32(e, NFT_EXPR_BYTEORDER_DREG, dreg);

	op = nft_jansson_parse_str(root, "op", err);
	if (op != NULL) {
		ntoh = nft_str2ntoh(op);
		if (ntoh < 0)
			return -1;

		nft_rule_expr_set_u32(e, NFT_EXPR_BYTEORDER_OP, ntoh);
	}

	if (nft_jansson_parse_val(root, "len", NFT_TYPE_U32, &len, err) == 0)
		nft_rule_expr_set_u32(e, NFT_EXPR_BYTEORDER_LEN, len);

	if (nft_jansson_parse_val(root, "size", NFT_TYPE_U32, &size, err) == 0)
		nft_rule_expr_set_u32(e, NFT_EXPR_BYTEORDER_SIZE, size);

	return 0;
#else
	errno = EOPNOTSUPP;
	return -1;
#endif
}