static void test_nfct_cmp_api(struct nf_conntrack *ct1, struct nf_conntrack *ct2) { int i; printf("== test cmp API ==\n"); test_nfct_cmp_attr(ATTR_ZONE); test_nfct_cmp_attr(ATTR_ORIG_ZONE); test_nfct_cmp_attr(ATTR_REPL_ZONE); test_nfct_cmp_attr(ATTR_MARK); assert(nfct_cmp(ct1, ct2, NFCT_CMP_ALL) == 1); assert(nfct_cmp(ct1, ct2, NFCT_CMP_ALL|NFCT_CMP_STRICT) == 0); nfct_copy(ct1, ct2, NFCT_CP_OVERRIDE); assert(nfct_cmp(ct1, ct2, NFCT_CMP_ALL) == 1); assert(nfct_cmp(ct1, ct2, NFCT_CMP_ALL|NFCT_CMP_STRICT) == 1); for (i=0; i < ATTR_MAX ; i++) { nfct_attr_unset(ct1, i); assert(nfct_cmp(ct1, ct2, NFCT_CMP_ALL) == 1); assert(nfct_cmp(ct1, ct2, NFCT_CMP_ALL|NFCT_CMP_STRICT) == 0); assert(nfct_cmp(ct1, ct2, NFCT_CMP_ALL|NFCT_CMP_MASK) == 1); } nfct_copy(ct1, ct2, NFCT_CP_OVERRIDE); for (i=0; i < ATTR_MAX ; i++) { nfct_attr_unset(ct2, i); assert(nfct_cmp(ct1, ct2, NFCT_CMP_ALL) == 1); assert(nfct_cmp(ct1, ct2, NFCT_CMP_ALL|NFCT_CMP_STRICT) == 0); assert(nfct_cmp(ct1, ct2, NFCT_CMP_ALL|NFCT_CMP_MASK) == 0); } for (i=0; i < ATTR_MAX ; i++) assert(test_nfct_cmp_api_single(ct1, ct2, i) == 0); nfct_copy(ct2, ct1, NFCT_CP_OVERRIDE); for (i=0; i < ATTR_MAX ; i++) { nfct_attr_unset(ct1, i); nfct_attr_unset(ct2, i); assert(nfct_cmp(ct1, ct2, NFCT_CMP_ALL) == 1); assert(nfct_cmp(ct1, ct2, NFCT_CMP_ALL|NFCT_CMP_STRICT) == 1); assert(nfct_cmp(ct1, ct2, NFCT_CMP_ALL|NFCT_CMP_MASK) == 1); } nfct_destroy(ct1); nfct_destroy(ct2); }
/* if the handle has no callback, check for existence, otherwise, update */ int nl_get_conntrack(struct nfct_handle *h, const struct nf_conntrack *ct) { int ret = 1; struct nf_conntrack *tmp; tmp = nfct_new(); if (tmp == NULL) return -1; /* use the original tuple to check if it is there */ nfct_copy(tmp, ct, NFCT_CP_ORIG); if (nfct_query(h, NFCT_Q_GET, tmp) == -1) ret = (errno == ENOENT) ? 0 : -1; nfct_destroy(tmp); return ret; }
static int test_nfct_cmp_api_single(struct nf_conntrack *ct1, struct nf_conntrack *ct2, int attr) { char data[256]; struct nfct_bitmask *b; int bit; if (attr_is_readonly(attr)) return 0; switch (attr) { case ATTR_SECMARK: /* obsolete */ return 0; /* FIXME: not implemented comparators: */ case ATTR_SNAT_IPV4: case ATTR_DNAT_IPV4: case ATTR_SNAT_PORT: case ATTR_DNAT_PORT: case ATTR_TCP_FLAGS_ORIG: case ATTR_TCP_FLAGS_REPL: case ATTR_TCP_MASK_ORIG: case ATTR_TCP_MASK_REPL: case ATTR_MASTER_IPV4_SRC: case ATTR_MASTER_IPV4_DST: case ATTR_MASTER_IPV6_SRC: case ATTR_MASTER_IPV6_DST: case ATTR_MASTER_PORT_SRC: case ATTR_MASTER_PORT_DST: case ATTR_MASTER_L3PROTO: case ATTR_MASTER_L4PROTO: case ATTR_ORIG_NAT_SEQ_CORRECTION_POS: case ATTR_ORIG_NAT_SEQ_OFFSET_BEFORE: case ATTR_ORIG_NAT_SEQ_OFFSET_AFTER: case ATTR_REPL_NAT_SEQ_CORRECTION_POS: case ATTR_REPL_NAT_SEQ_OFFSET_BEFORE: case ATTR_REPL_NAT_SEQ_OFFSET_AFTER: case ATTR_SCTP_VTAG_ORIG: case ATTR_SCTP_VTAG_REPL: case ATTR_HELPER_NAME: case ATTR_DCCP_ROLE: case ATTR_DCCP_HANDSHAKE_SEQ: case ATTR_TCP_WSCALE_ORIG: case ATTR_TCP_WSCALE_REPL: case ATTR_HELPER_INFO: return 0; /* XXX */ default: break; } if (attr >= ATTR_SCTP_STATE) { nfct_set_attr_u8(ct1, ATTR_REPL_L4PROTO, IPPROTO_SCTP); nfct_set_attr_u8(ct1, ATTR_L4PROTO, IPPROTO_SCTP); } else if (attr >= ATTR_TCP_FLAGS_ORIG) { nfct_set_attr_u8(ct1, ATTR_REPL_L4PROTO, IPPROTO_TCP); nfct_set_attr_u8(ct1, ATTR_L4PROTO, IPPROTO_TCP); } else if (attr >= ATTR_ICMP_CODE) { nfct_set_attr_u8(ct1, ATTR_REPL_L4PROTO, IPPROTO_ICMP); nfct_set_attr_u8(ct1, ATTR_L4PROTO, IPPROTO_ICMP); } else if (attr >= ATTR_ORIG_PORT_SRC) { nfct_set_attr_u8(ct1, ATTR_REPL_L4PROTO, IPPROTO_TCP); nfct_set_attr_u8(ct1, ATTR_L4PROTO, IPPROTO_TCP); } nfct_copy(ct2, ct1, NFCT_CP_OVERRIDE); memset(data, 42, sizeof(data)); assert(nfct_attr_is_set(ct1, attr)); assert(nfct_attr_is_set(ct2, attr)); switch (attr) { case ATTR_CONNLABELS: case ATTR_CONNLABELS_MASK: b = (void *) nfct_get_attr(ct1, attr); assert(b); b = nfct_bitmask_clone(b); assert(b); bit = nfct_bitmask_maxbit(b); if (nfct_bitmask_test_bit(b, bit)) { nfct_bitmask_unset_bit(b, bit); assert(!nfct_bitmask_test_bit(b, bit)); } else { nfct_bitmask_set_bit(b, bit); assert(nfct_bitmask_test_bit(b, bit)); } assert(nfct_cmp(ct1, ct2, NFCT_CMP_ALL) == 1); nfct_set_attr(ct2, attr, b); break; case ATTR_HELPER_INFO: nfct_set_attr_l(ct2, attr, "test", 4); break; default: nfct_set_attr(ct2, attr, data); break; } if (nfct_cmp(ct1, ct2, NFCT_CMP_ALL) != 0) { fprintf(stderr, "nfct_cmp assert failure for attr %d\n", attr); fprintf(stderr, "%p, %p, %x, %x\n", nfct_get_attr(ct1, attr), nfct_get_attr(ct2, attr), nfct_get_attr_u32(ct1, attr), nfct_get_attr_u32(ct2, attr)); return -1; } if (nfct_cmp(ct1, ct2, NFCT_CMP_ALL|NFCT_CMP_STRICT) != 0) { fprintf(stderr, "nfct_cmp strict assert failure for attr %d\n", attr); return -1; } return 0; }