static void exp_dump_tuples(struct nfnl_exp *exp, struct nl_dump_params *p) { struct nl_addr *tuple_src, *tuple_dst; int tuple_sport, tuple_dport; int i = 0; char buf[64]; for (i = NFNL_EXP_TUPLE_EXPECT; i < NFNL_EXP_TUPLE_MAX; i++) { tuple_src = NULL; tuple_dst = NULL; tuple_sport = 0; tuple_dport = 0; // Test needed for NAT case if (nfnl_exp_test_src(exp, i)) tuple_src = nfnl_exp_get_src(exp, i); if (nfnl_exp_test_dst(exp, i)) tuple_dst = nfnl_exp_get_dst(exp, i); // Don't have tests for individual ports/types/codes/ids, if (nfnl_exp_test_l4protonum(exp, i)) { nl_dump(p, "%s ", nl_ip_proto2str(nfnl_exp_get_l4protonum(exp, i), buf, sizeof(buf))); } if (nfnl_exp_test_ports(exp, i)) { tuple_sport = nfnl_exp_get_src_port(exp, i); tuple_dport = nfnl_exp_get_dst_port(exp, i); } dump_addr(p, tuple_src, tuple_sport); dump_addr(p, tuple_dst, tuple_dport); dump_icmp(p, exp, 0); } if (nfnl_exp_test_nat_dir(exp)) nl_dump(p, "nat dir %s ", exp->exp_nat_dir); }
static int nfnl_exp_build_tuple(struct nl_msg *msg, const struct nfnl_exp *exp, int cta) { struct nlattr *tuple, *ip, *proto; struct nl_addr *addr; int family; family = nfnl_exp_get_family(exp); int type = exp_get_tuple_attr(cta); if (cta == CTA_EXPECT_NAT) tuple = nla_nest_start(msg, CTA_EXPECT_NAT_TUPLE); else tuple = nla_nest_start(msg, cta); if (!tuple) goto nla_put_failure; ip = nla_nest_start(msg, CTA_TUPLE_IP); if (!ip) goto nla_put_failure; addr = nfnl_exp_get_src(exp, type); if (addr) NLA_PUT_ADDR(msg, family == AF_INET ? CTA_IP_V4_SRC : CTA_IP_V6_SRC, addr); addr = nfnl_exp_get_dst(exp, type); if (addr) NLA_PUT_ADDR(msg, family == AF_INET ? CTA_IP_V4_DST : CTA_IP_V6_DST, addr); nla_nest_end(msg, ip); proto = nla_nest_start(msg, CTA_TUPLE_PROTO); if (!proto) goto nla_put_failure; if (nfnl_exp_test_l4protonum(exp, type)) NLA_PUT_U8(msg, CTA_PROTO_NUM, nfnl_exp_get_l4protonum(exp, type)); if (nfnl_exp_test_ports(exp, type)) { NLA_PUT_U16(msg, CTA_PROTO_SRC_PORT, htons(nfnl_exp_get_src_port(exp, type))); NLA_PUT_U16(msg, CTA_PROTO_DST_PORT, htons(nfnl_exp_get_dst_port(exp, type))); } if (nfnl_exp_test_icmp(exp, type)) { NLA_PUT_U16(msg, CTA_PROTO_ICMP_ID, htons(nfnl_exp_get_icmp_id(exp, type))); NLA_PUT_U8(msg, CTA_PROTO_ICMP_TYPE, nfnl_exp_get_icmp_type(exp, type)); NLA_PUT_U8(msg, CTA_PROTO_ICMP_CODE, nfnl_exp_get_icmp_code(exp, type)); } nla_nest_end(msg, proto); nla_nest_end(msg, tuple); return 0; nla_put_failure: return -NLE_MSGSIZE; }