int __build_expect(struct nfnl_subsys_handle *ssh, struct nfnlhdr *req, size_t size, u_int16_t type, u_int16_t flags, const struct nf_expect *exp) { u_int8_t l3num; if (test_bit(ATTR_ORIG_L3PROTO, exp->master.set)) l3num = exp->master.orig.l3protonum; else if (test_bit(ATTR_ORIG_L3PROTO, exp->expected.set)) l3num = exp->expected.orig.l3protonum; else return -1; memset(req, 0, size); nfnl_fill_hdr(ssh, &req->nlh, 0, l3num, 0, type, flags); if (test_bit(ATTR_EXP_EXPECTED, exp->set)) { __build_tuple(req, size, &exp->expected.orig, CTA_EXPECT_TUPLE); } if (test_bit(ATTR_EXP_MASTER, exp->set)) { __build_tuple(req, size, &exp->master.orig, CTA_EXPECT_MASTER); } if (test_bit(ATTR_EXP_MASK, exp->set)) { __build_tuple(req, size, &exp->mask.orig, CTA_EXPECT_MASK); } if (test_bit(ATTR_EXP_TIMEOUT, exp->set)) __build_timeout(req, size, exp); if (test_bit(ATTR_EXP_FLAGS, exp->set)) __build_flags(req, size, exp); if (test_bit(ATTR_EXP_ZONE, exp->set)) __build_zone(req, size, exp); if (test_bit(ATTR_EXP_HELPER_NAME, exp->set)) __build_helper_name(req, size, exp); return 0; }
int __build_conntrack(struct nfnl_subsys_handle *ssh, struct nfnlhdr *req, size_t size, u_int16_t type, u_int16_t flags, const struct nf_conntrack *ct) { u_int8_t l3num = ct->head.orig.l3protonum; if (!test_bit(ATTR_ORIG_L3PROTO, ct->head.set)) { errno = EINVAL; return -1; } memset(req, 0, size); nfnl_fill_hdr(ssh, &req->nlh, 0, l3num, 0, type, flags); if (test_bit(ATTR_ORIG_IPV4_SRC, ct->head.set) || test_bit(ATTR_ORIG_IPV4_DST, ct->head.set) || test_bit(ATTR_ORIG_IPV6_SRC, ct->head.set) || test_bit(ATTR_ORIG_IPV6_DST, ct->head.set) || test_bit(ATTR_ORIG_PORT_SRC, ct->head.set) || test_bit(ATTR_ORIG_PORT_DST, ct->head.set) || test_bit(ATTR_ORIG_L3PROTO, ct->head.set) || test_bit(ATTR_ORIG_L4PROTO, ct->head.set) || test_bit(ATTR_ICMP_TYPE, ct->head.set) || test_bit(ATTR_ICMP_CODE, ct->head.set) || test_bit(ATTR_ICMP_ID, ct->head.set)) __build_tuple(req, size, &ct->head.orig, CTA_TUPLE_ORIG); if (test_bit(ATTR_REPL_IPV4_SRC, ct->head.set) || test_bit(ATTR_REPL_IPV4_DST, ct->head.set) || test_bit(ATTR_REPL_IPV6_SRC, ct->head.set) || test_bit(ATTR_REPL_IPV6_DST, ct->head.set) || test_bit(ATTR_REPL_PORT_SRC, ct->head.set) || test_bit(ATTR_REPL_PORT_DST, ct->head.set) || test_bit(ATTR_REPL_L3PROTO, ct->head.set) || test_bit(ATTR_REPL_L4PROTO, ct->head.set)) __build_tuple(req, size, &ct->repl, CTA_TUPLE_REPLY); if (test_bit(ATTR_MASTER_IPV4_SRC, ct->head.set) || test_bit(ATTR_MASTER_IPV4_DST, ct->head.set) || test_bit(ATTR_MASTER_IPV6_SRC, ct->head.set) || test_bit(ATTR_MASTER_IPV6_DST, ct->head.set) || test_bit(ATTR_MASTER_PORT_SRC, ct->head.set) || test_bit(ATTR_MASTER_PORT_DST, ct->head.set) || test_bit(ATTR_MASTER_L3PROTO, ct->head.set) || test_bit(ATTR_MASTER_L4PROTO, ct->head.set)) __build_tuple(req, size, &ct->master, CTA_TUPLE_MASTER); if (test_bit(ATTR_STATUS, ct->head.set)) __build_status(req, size, ct); else { /* build IPS_CONFIRMED if we're creating a new conntrack */ if (type == IPCTNL_MSG_CT_NEW && flags & NLM_F_CREATE) __build_status(req, size, ct); } if (test_bit(ATTR_TIMEOUT, ct->head.set)) __build_timeout(req, size, ct); if (test_bit(ATTR_MARK, ct->head.set)) __build_mark(req, size, ct); if (test_bit(ATTR_SECMARK, ct->head.set)) __build_secmark(req, size, ct); __build_protoinfo(req, size, ct); if (test_bit(ATTR_SNAT_IPV4, ct->head.set) && test_bit(ATTR_SNAT_PORT, ct->head.set)) __build_snat(req, size, ct); else if (test_bit(ATTR_SNAT_IPV4, ct->head.set)) __build_snat_ipv4(req, size, ct); else if (test_bit(ATTR_SNAT_PORT, ct->head.set)) __build_snat_port(req, size, ct); if (test_bit(ATTR_DNAT_IPV4, ct->head.set) && test_bit(ATTR_DNAT_PORT, ct->head.set)) __build_dnat(req, size, ct); else if (test_bit(ATTR_DNAT_IPV4, ct->head.set)) __build_dnat_ipv4(req, size, ct); else if (test_bit(ATTR_DNAT_PORT, ct->head.set)) __build_dnat_port(req, size, ct); if (test_bit(ATTR_ORIG_NAT_SEQ_CORRECTION_POS, ct->head.set) && test_bit(ATTR_ORIG_NAT_SEQ_OFFSET_BEFORE, ct->head.set) && test_bit(ATTR_ORIG_NAT_SEQ_OFFSET_AFTER, ct->head.set)) __build_nat_seq_adj(req, size, ct, __DIR_ORIG); if (test_bit(ATTR_REPL_NAT_SEQ_CORRECTION_POS, ct->head.set) && test_bit(ATTR_REPL_NAT_SEQ_OFFSET_BEFORE, ct->head.set) && test_bit(ATTR_REPL_NAT_SEQ_OFFSET_AFTER, ct->head.set)) __build_nat_seq_adj(req, size, ct, __DIR_REPL); if (test_bit(ATTR_HELPER_NAME, ct->head.set)) __build_helper_name(req, size, ct); if (test_bit(ATTR_ZONE, ct->head.set)) __build_zone(req, size, ct); return 0; }