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, ®, err) == 0) nft_rule_expr_set_u32(e, NFT_EXPR_BITWISE_SREG, reg); if (nft_jansson_parse_reg(root, "dreg", NFT_TYPE_U32, ®, 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; }
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 }
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 }
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, ®, err) == 0) nft_rule_expr_set_u32(e, NFT_EXPR_CT_DREG, reg); if (nft_jansson_parse_reg(root, "sreg", NFT_TYPE_U32, ®, 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 }
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 }
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 }
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, ®, 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, ®, 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, ®, 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, ®, 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 }
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", ®_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", ®_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", ®_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", ®_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 }
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 }
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 }