ct_obj.c revision 44d362409d5469aed47d19e7908d19bd194493a
144d362409d5469aed47d19e7908d19bd194493aThomas Graf/* 244d362409d5469aed47d19e7908d19bd194493aThomas Graf * lib/netfilter/ct_obj.c Conntrack Object 344d362409d5469aed47d19e7908d19bd194493aThomas Graf * 444d362409d5469aed47d19e7908d19bd194493aThomas Graf * This library is free software; you can redistribute it and/or 544d362409d5469aed47d19e7908d19bd194493aThomas Graf * modify it under the terms of the GNU Lesser General Public 644d362409d5469aed47d19e7908d19bd194493aThomas Graf * License as published by the Free Software Foundation version 2.1 744d362409d5469aed47d19e7908d19bd194493aThomas Graf * of the License. 844d362409d5469aed47d19e7908d19bd194493aThomas Graf * 944d362409d5469aed47d19e7908d19bd194493aThomas Graf * Copyright (c) 2003-2006 Thomas Graf <tgraf@suug.ch> 1044d362409d5469aed47d19e7908d19bd194493aThomas Graf * Copyright (c) 2007 Philip Craig <philipc@snapgear.com> 1144d362409d5469aed47d19e7908d19bd194493aThomas Graf * Copyright (c) 2007 Secure Computing Corporation 1244d362409d5469aed47d19e7908d19bd194493aThomas Graf */ 1344d362409d5469aed47d19e7908d19bd194493aThomas Graf 1444d362409d5469aed47d19e7908d19bd194493aThomas Graf#include <sys/types.h> 1544d362409d5469aed47d19e7908d19bd194493aThomas Graf#include <linux/netfilter/nfnetlink_conntrack.h> 1644d362409d5469aed47d19e7908d19bd194493aThomas Graf#include <linux/netfilter/nf_conntrack_common.h> 1744d362409d5469aed47d19e7908d19bd194493aThomas Graf#include <linux/netfilter/nf_conntrack_tcp.h> 1844d362409d5469aed47d19e7908d19bd194493aThomas Graf 1944d362409d5469aed47d19e7908d19bd194493aThomas Graf#include <netlink-local.h> 2044d362409d5469aed47d19e7908d19bd194493aThomas Graf#include <netlink/netfilter/nfnl.h> 2144d362409d5469aed47d19e7908d19bd194493aThomas Graf#include <netlink/netfilter/ct.h> 2244d362409d5469aed47d19e7908d19bd194493aThomas Graf 2344d362409d5469aed47d19e7908d19bd194493aThomas Graf/** @cond SKIP */ 2444d362409d5469aed47d19e7908d19bd194493aThomas Graf#define CT_ATTR_FAMILY (1UL << 0) 2544d362409d5469aed47d19e7908d19bd194493aThomas Graf#define CT_ATTR_PROTO (1UL << 1) 2644d362409d5469aed47d19e7908d19bd194493aThomas Graf 2744d362409d5469aed47d19e7908d19bd194493aThomas Graf#define CT_ATTR_TCP_STATE (1UL << 2) 2844d362409d5469aed47d19e7908d19bd194493aThomas Graf 2944d362409d5469aed47d19e7908d19bd194493aThomas Graf#define CT_ATTR_STATUS (1UL << 3) 3044d362409d5469aed47d19e7908d19bd194493aThomas Graf#define CT_ATTR_TIMEOUT (1UL << 4) 3144d362409d5469aed47d19e7908d19bd194493aThomas Graf#define CT_ATTR_MARK (1UL << 5) 3244d362409d5469aed47d19e7908d19bd194493aThomas Graf#define CT_ATTR_USE (1UL << 6) 3344d362409d5469aed47d19e7908d19bd194493aThomas Graf#define CT_ATTR_ID (1UL << 7) 3444d362409d5469aed47d19e7908d19bd194493aThomas Graf 3544d362409d5469aed47d19e7908d19bd194493aThomas Graf#define CT_ATTR_ORIG_SRC (1UL << 8) 3644d362409d5469aed47d19e7908d19bd194493aThomas Graf#define CT_ATTR_ORIG_DST (1UL << 9) 3744d362409d5469aed47d19e7908d19bd194493aThomas Graf#define CT_ATTR_ORIG_SRC_PORT (1UL << 10) 3844d362409d5469aed47d19e7908d19bd194493aThomas Graf#define CT_ATTR_ORIG_DST_PORT (1UL << 11) 3944d362409d5469aed47d19e7908d19bd194493aThomas Graf#define CT_ATTR_ORIG_ICMP_ID (1UL << 12) 4044d362409d5469aed47d19e7908d19bd194493aThomas Graf#define CT_ATTR_ORIG_ICMP_TYPE (1UL << 13) 4144d362409d5469aed47d19e7908d19bd194493aThomas Graf#define CT_ATTR_ORIG_ICMP_CODE (1UL << 14) 4244d362409d5469aed47d19e7908d19bd194493aThomas Graf#define CT_ATTR_ORIG_PACKETS (1UL << 15) 4344d362409d5469aed47d19e7908d19bd194493aThomas Graf#define CT_ATTR_ORIG_BYTES (1UL << 16) 4444d362409d5469aed47d19e7908d19bd194493aThomas Graf 4544d362409d5469aed47d19e7908d19bd194493aThomas Graf#define CT_ATTR_REPL_SRC (1UL << 17) 4644d362409d5469aed47d19e7908d19bd194493aThomas Graf#define CT_ATTR_REPL_DST (1UL << 18) 4744d362409d5469aed47d19e7908d19bd194493aThomas Graf#define CT_ATTR_REPL_SRC_PORT (1UL << 19) 4844d362409d5469aed47d19e7908d19bd194493aThomas Graf#define CT_ATTR_REPL_DST_PORT (1UL << 20) 4944d362409d5469aed47d19e7908d19bd194493aThomas Graf#define CT_ATTR_REPL_ICMP_ID (1UL << 21) 5044d362409d5469aed47d19e7908d19bd194493aThomas Graf#define CT_ATTR_REPL_ICMP_TYPE (1UL << 22) 5144d362409d5469aed47d19e7908d19bd194493aThomas Graf#define CT_ATTR_REPL_ICMP_CODE (1UL << 23) 5244d362409d5469aed47d19e7908d19bd194493aThomas Graf#define CT_ATTR_REPL_PACKETS (1UL << 24) 5344d362409d5469aed47d19e7908d19bd194493aThomas Graf#define CT_ATTR_REPL_BYTES (1UL << 25) 5444d362409d5469aed47d19e7908d19bd194493aThomas Graf/** @endcond */ 5544d362409d5469aed47d19e7908d19bd194493aThomas Graf 5644d362409d5469aed47d19e7908d19bd194493aThomas Grafstatic void ct_free_data(struct nl_object *c) 5744d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 5844d362409d5469aed47d19e7908d19bd194493aThomas Graf struct nfnl_ct *ct = (struct nfnl_ct *) c; 5944d362409d5469aed47d19e7908d19bd194493aThomas Graf 6044d362409d5469aed47d19e7908d19bd194493aThomas Graf if (ct == NULL) 6144d362409d5469aed47d19e7908d19bd194493aThomas Graf return; 6244d362409d5469aed47d19e7908d19bd194493aThomas Graf 6344d362409d5469aed47d19e7908d19bd194493aThomas Graf nl_addr_put(ct->ct_orig.src); 6444d362409d5469aed47d19e7908d19bd194493aThomas Graf nl_addr_put(ct->ct_orig.dst); 6544d362409d5469aed47d19e7908d19bd194493aThomas Graf nl_addr_put(ct->ct_repl.src); 6644d362409d5469aed47d19e7908d19bd194493aThomas Graf nl_addr_put(ct->ct_repl.dst); 6744d362409d5469aed47d19e7908d19bd194493aThomas Graf} 6844d362409d5469aed47d19e7908d19bd194493aThomas Graf 6944d362409d5469aed47d19e7908d19bd194493aThomas Grafstatic int ct_clone(struct nl_object *_dst, struct nl_object *_src) 7044d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 7144d362409d5469aed47d19e7908d19bd194493aThomas Graf struct nfnl_ct *dst = (struct nfnl_ct *) _dst; 7244d362409d5469aed47d19e7908d19bd194493aThomas Graf struct nfnl_ct *src = (struct nfnl_ct *) _src; 7344d362409d5469aed47d19e7908d19bd194493aThomas Graf struct nl_addr *addr; 7444d362409d5469aed47d19e7908d19bd194493aThomas Graf 7544d362409d5469aed47d19e7908d19bd194493aThomas Graf if (src->ct_orig.src) { 7644d362409d5469aed47d19e7908d19bd194493aThomas Graf addr = nl_addr_clone(src->ct_orig.src); 7744d362409d5469aed47d19e7908d19bd194493aThomas Graf if (!addr) 7844d362409d5469aed47d19e7908d19bd194493aThomas Graf goto errout; 7944d362409d5469aed47d19e7908d19bd194493aThomas Graf dst->ct_orig.src = addr; 8044d362409d5469aed47d19e7908d19bd194493aThomas Graf } 8144d362409d5469aed47d19e7908d19bd194493aThomas Graf 8244d362409d5469aed47d19e7908d19bd194493aThomas Graf if (src->ct_orig.dst) { 8344d362409d5469aed47d19e7908d19bd194493aThomas Graf addr = nl_addr_clone(src->ct_orig.dst); 8444d362409d5469aed47d19e7908d19bd194493aThomas Graf if (!addr) 8544d362409d5469aed47d19e7908d19bd194493aThomas Graf goto errout; 8644d362409d5469aed47d19e7908d19bd194493aThomas Graf dst->ct_orig.dst = addr; 8744d362409d5469aed47d19e7908d19bd194493aThomas Graf } 8844d362409d5469aed47d19e7908d19bd194493aThomas Graf 8944d362409d5469aed47d19e7908d19bd194493aThomas Graf if (src->ct_repl.src) { 9044d362409d5469aed47d19e7908d19bd194493aThomas Graf addr = nl_addr_clone(src->ct_repl.src); 9144d362409d5469aed47d19e7908d19bd194493aThomas Graf if (!addr) 9244d362409d5469aed47d19e7908d19bd194493aThomas Graf goto errout; 9344d362409d5469aed47d19e7908d19bd194493aThomas Graf dst->ct_repl.src = addr; 9444d362409d5469aed47d19e7908d19bd194493aThomas Graf } 9544d362409d5469aed47d19e7908d19bd194493aThomas Graf 9644d362409d5469aed47d19e7908d19bd194493aThomas Graf if (src->ct_repl.dst) { 9744d362409d5469aed47d19e7908d19bd194493aThomas Graf addr = nl_addr_clone(src->ct_repl.dst); 9844d362409d5469aed47d19e7908d19bd194493aThomas Graf if (!addr) 9944d362409d5469aed47d19e7908d19bd194493aThomas Graf goto errout; 10044d362409d5469aed47d19e7908d19bd194493aThomas Graf dst->ct_repl.dst = addr; 10144d362409d5469aed47d19e7908d19bd194493aThomas Graf } 10244d362409d5469aed47d19e7908d19bd194493aThomas Graf 10344d362409d5469aed47d19e7908d19bd194493aThomas Graf return 0; 10444d362409d5469aed47d19e7908d19bd194493aThomas Graferrout: 10544d362409d5469aed47d19e7908d19bd194493aThomas Graf return nl_get_errno(); 10644d362409d5469aed47d19e7908d19bd194493aThomas Graf} 10744d362409d5469aed47d19e7908d19bd194493aThomas Graf 10844d362409d5469aed47d19e7908d19bd194493aThomas Grafstatic void ct_dump_dir(struct nfnl_ct *ct, int repl, 10944d362409d5469aed47d19e7908d19bd194493aThomas Graf struct nl_dump_params *p) 11044d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 11144d362409d5469aed47d19e7908d19bd194493aThomas Graf struct nl_addr *addr; 11244d362409d5469aed47d19e7908d19bd194493aThomas Graf char addrbuf[64]; 11344d362409d5469aed47d19e7908d19bd194493aThomas Graf 11444d362409d5469aed47d19e7908d19bd194493aThomas Graf addr = nfnl_ct_get_src(ct, repl); 11544d362409d5469aed47d19e7908d19bd194493aThomas Graf if (addr) 11644d362409d5469aed47d19e7908d19bd194493aThomas Graf dp_dump(p, "src=%s ", 11744d362409d5469aed47d19e7908d19bd194493aThomas Graf nl_addr2str(addr, addrbuf, sizeof(addrbuf))); 11844d362409d5469aed47d19e7908d19bd194493aThomas Graf 11944d362409d5469aed47d19e7908d19bd194493aThomas Graf addr = nfnl_ct_get_dst(ct, repl); 12044d362409d5469aed47d19e7908d19bd194493aThomas Graf if (addr) 12144d362409d5469aed47d19e7908d19bd194493aThomas Graf dp_dump(p, "dst=%s ", 12244d362409d5469aed47d19e7908d19bd194493aThomas Graf nl_addr2str(addr, addrbuf, sizeof(addrbuf))); 12344d362409d5469aed47d19e7908d19bd194493aThomas Graf 12444d362409d5469aed47d19e7908d19bd194493aThomas Graf if (nfnl_ct_test_src_port(ct, repl)) 12544d362409d5469aed47d19e7908d19bd194493aThomas Graf dp_dump(p, "sport=%u ", ntohs(nfnl_ct_get_src_port(ct, repl))); 12644d362409d5469aed47d19e7908d19bd194493aThomas Graf if (nfnl_ct_test_dst_port(ct, repl)) 12744d362409d5469aed47d19e7908d19bd194493aThomas Graf dp_dump(p, "dport=%u ", ntohs(nfnl_ct_get_dst_port(ct, repl))); 12844d362409d5469aed47d19e7908d19bd194493aThomas Graf 12944d362409d5469aed47d19e7908d19bd194493aThomas Graf if (nfnl_ct_test_icmp_type(ct, repl)) 13044d362409d5469aed47d19e7908d19bd194493aThomas Graf dp_dump(p, "type=%d ", nfnl_ct_get_icmp_type(ct, repl)); 13144d362409d5469aed47d19e7908d19bd194493aThomas Graf if (nfnl_ct_test_icmp_type(ct, repl)) 13244d362409d5469aed47d19e7908d19bd194493aThomas Graf dp_dump(p, "code=%d ", nfnl_ct_get_icmp_code(ct, repl)); 13344d362409d5469aed47d19e7908d19bd194493aThomas Graf if (nfnl_ct_test_icmp_type(ct, repl)) 13444d362409d5469aed47d19e7908d19bd194493aThomas Graf dp_dump(p, "id=%d ", ntohs(nfnl_ct_get_icmp_id(ct, repl))); 13544d362409d5469aed47d19e7908d19bd194493aThomas Graf 13644d362409d5469aed47d19e7908d19bd194493aThomas Graf if (nfnl_ct_test_packets(ct, repl)) 13744d362409d5469aed47d19e7908d19bd194493aThomas Graf dp_dump(p, "packets=%llu ", nfnl_ct_get_packets(ct, repl)); 13844d362409d5469aed47d19e7908d19bd194493aThomas Graf if (nfnl_ct_test_bytes(ct, repl)) 13944d362409d5469aed47d19e7908d19bd194493aThomas Graf dp_dump(p, "bytes=%llu ", nfnl_ct_get_bytes(ct, repl)); 14044d362409d5469aed47d19e7908d19bd194493aThomas Graf} 14144d362409d5469aed47d19e7908d19bd194493aThomas Graf 14244d362409d5469aed47d19e7908d19bd194493aThomas Graf/* Compatible with /proc/net/nf_conntrack */ 14344d362409d5469aed47d19e7908d19bd194493aThomas Grafstatic int ct_dump(struct nl_object *a, struct nl_dump_params *p) 14444d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 14544d362409d5469aed47d19e7908d19bd194493aThomas Graf struct nfnl_ct *ct = (struct nfnl_ct *) a; 14644d362409d5469aed47d19e7908d19bd194493aThomas Graf char buf[64]; 14744d362409d5469aed47d19e7908d19bd194493aThomas Graf uint32_t status; 14844d362409d5469aed47d19e7908d19bd194493aThomas Graf uint8_t family; 14944d362409d5469aed47d19e7908d19bd194493aThomas Graf uint8_t proto; 15044d362409d5469aed47d19e7908d19bd194493aThomas Graf 15144d362409d5469aed47d19e7908d19bd194493aThomas Graf family = nfnl_ct_get_family(ct); 15244d362409d5469aed47d19e7908d19bd194493aThomas Graf dp_dump(p, "%-8s %u ", nl_af2str(family, buf, sizeof(buf)), family); 15344d362409d5469aed47d19e7908d19bd194493aThomas Graf 15444d362409d5469aed47d19e7908d19bd194493aThomas Graf if (nfnl_ct_test_proto(ct)) { 15544d362409d5469aed47d19e7908d19bd194493aThomas Graf proto = nfnl_ct_get_proto(ct); 15644d362409d5469aed47d19e7908d19bd194493aThomas Graf dp_dump(p, "%-8s %u ", 15744d362409d5469aed47d19e7908d19bd194493aThomas Graf nl_ip_proto2str(proto, buf, sizeof(buf)), proto); 15844d362409d5469aed47d19e7908d19bd194493aThomas Graf } 15944d362409d5469aed47d19e7908d19bd194493aThomas Graf 16044d362409d5469aed47d19e7908d19bd194493aThomas Graf if (nfnl_ct_test_timeout(ct)) 16144d362409d5469aed47d19e7908d19bd194493aThomas Graf dp_dump(p, "%ld ", nfnl_ct_get_timeout(ct)); 16244d362409d5469aed47d19e7908d19bd194493aThomas Graf 16344d362409d5469aed47d19e7908d19bd194493aThomas Graf if (nfnl_ct_test_tcp_state(ct)) 16444d362409d5469aed47d19e7908d19bd194493aThomas Graf dp_dump(p, "%s ", 16544d362409d5469aed47d19e7908d19bd194493aThomas Graf nfnl_ct_tcp_state2str(nfnl_ct_get_tcp_state(ct), 16644d362409d5469aed47d19e7908d19bd194493aThomas Graf buf, sizeof(buf))); 16744d362409d5469aed47d19e7908d19bd194493aThomas Graf 16844d362409d5469aed47d19e7908d19bd194493aThomas Graf ct_dump_dir(ct, 0, p); 16944d362409d5469aed47d19e7908d19bd194493aThomas Graf 17044d362409d5469aed47d19e7908d19bd194493aThomas Graf status = nfnl_ct_get_status(ct); 17144d362409d5469aed47d19e7908d19bd194493aThomas Graf if (!(status & IPS_SEEN_REPLY)) 17244d362409d5469aed47d19e7908d19bd194493aThomas Graf dp_dump(p, "[UNREPLIED] "); 17344d362409d5469aed47d19e7908d19bd194493aThomas Graf 17444d362409d5469aed47d19e7908d19bd194493aThomas Graf ct_dump_dir(ct, 1, p); 17544d362409d5469aed47d19e7908d19bd194493aThomas Graf 17644d362409d5469aed47d19e7908d19bd194493aThomas Graf if (status & IPS_ASSURED) 17744d362409d5469aed47d19e7908d19bd194493aThomas Graf dp_dump(p, "[ASSURED] "); 17844d362409d5469aed47d19e7908d19bd194493aThomas Graf 17944d362409d5469aed47d19e7908d19bd194493aThomas Graf if (nfnl_ct_test_mark(ct)) 18044d362409d5469aed47d19e7908d19bd194493aThomas Graf dp_dump(p, "mark=%u ", nfnl_ct_get_mark(ct)); 18144d362409d5469aed47d19e7908d19bd194493aThomas Graf 18244d362409d5469aed47d19e7908d19bd194493aThomas Graf if (nfnl_ct_test_use(ct)) 18344d362409d5469aed47d19e7908d19bd194493aThomas Graf dp_dump(p, "use=%u ", nfnl_ct_get_use(ct)); 18444d362409d5469aed47d19e7908d19bd194493aThomas Graf 18544d362409d5469aed47d19e7908d19bd194493aThomas Graf dp_dump(p, "\n"); 18644d362409d5469aed47d19e7908d19bd194493aThomas Graf 18744d362409d5469aed47d19e7908d19bd194493aThomas Graf return 1; 18844d362409d5469aed47d19e7908d19bd194493aThomas Graf} 18944d362409d5469aed47d19e7908d19bd194493aThomas Graf 19044d362409d5469aed47d19e7908d19bd194493aThomas Grafstatic int ct_compare(struct nl_object *_a, struct nl_object *_b, 19144d362409d5469aed47d19e7908d19bd194493aThomas Graf uint32_t attrs, int flags) 19244d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 19344d362409d5469aed47d19e7908d19bd194493aThomas Graf struct nfnl_ct *a = (struct nfnl_ct *) _a; 19444d362409d5469aed47d19e7908d19bd194493aThomas Graf struct nfnl_ct *b = (struct nfnl_ct *) _b; 19544d362409d5469aed47d19e7908d19bd194493aThomas Graf int diff = 0; 19644d362409d5469aed47d19e7908d19bd194493aThomas Graf 19744d362409d5469aed47d19e7908d19bd194493aThomas Graf#define CT_DIFF(ATTR, EXPR) ATTR_DIFF(attrs, CT_ATTR_##ATTR, a, b, EXPR) 19844d362409d5469aed47d19e7908d19bd194493aThomas Graf#define CT_DIFF_VAL(ATTR, FIELD) CT_DIFF(ATTR, a->FIELD != b->FIELD) 19944d362409d5469aed47d19e7908d19bd194493aThomas Graf#define CT_DIFF_ADDR(ATTR, FIELD) \ 20044d362409d5469aed47d19e7908d19bd194493aThomas Graf ((flags & LOOSE_FLAG_COMPARISON) \ 20144d362409d5469aed47d19e7908d19bd194493aThomas Graf ? CT_DIFF(ATTR, nl_addr_cmp_prefix(a->FIELD, b->FIELD)) \ 20244d362409d5469aed47d19e7908d19bd194493aThomas Graf : CT_DIFF(ATTR, nl_addr_cmp(a->FIELD, b->FIELD))) 20344d362409d5469aed47d19e7908d19bd194493aThomas Graf 20444d362409d5469aed47d19e7908d19bd194493aThomas Graf diff |= CT_DIFF_VAL(FAMILY, ct_family); 20544d362409d5469aed47d19e7908d19bd194493aThomas Graf diff |= CT_DIFF_VAL(PROTO, ct_proto); 20644d362409d5469aed47d19e7908d19bd194493aThomas Graf diff |= CT_DIFF_VAL(TCP_STATE, ct_protoinfo.tcp.state); 20744d362409d5469aed47d19e7908d19bd194493aThomas Graf diff |= CT_DIFF_VAL(STATUS, ct_status); 20844d362409d5469aed47d19e7908d19bd194493aThomas Graf diff |= CT_DIFF_VAL(TIMEOUT, ct_timeout); 20944d362409d5469aed47d19e7908d19bd194493aThomas Graf diff |= CT_DIFF_VAL(MARK, ct_mark); 21044d362409d5469aed47d19e7908d19bd194493aThomas Graf diff |= CT_DIFF_VAL(USE, ct_use); 21144d362409d5469aed47d19e7908d19bd194493aThomas Graf diff |= CT_DIFF_VAL(ID, ct_id); 21244d362409d5469aed47d19e7908d19bd194493aThomas Graf diff |= CT_DIFF_ADDR(ORIG_SRC, ct_orig.src); 21344d362409d5469aed47d19e7908d19bd194493aThomas Graf diff |= CT_DIFF_ADDR(ORIG_DST, ct_orig.dst); 21444d362409d5469aed47d19e7908d19bd194493aThomas Graf diff |= CT_DIFF_VAL(ORIG_SRC_PORT, ct_orig.proto.port.src); 21544d362409d5469aed47d19e7908d19bd194493aThomas Graf diff |= CT_DIFF_VAL(ORIG_DST_PORT, ct_orig.proto.port.dst); 21644d362409d5469aed47d19e7908d19bd194493aThomas Graf diff |= CT_DIFF_VAL(ORIG_ICMP_ID, ct_orig.proto.icmp.id); 21744d362409d5469aed47d19e7908d19bd194493aThomas Graf diff |= CT_DIFF_VAL(ORIG_ICMP_TYPE, ct_orig.proto.icmp.type); 21844d362409d5469aed47d19e7908d19bd194493aThomas Graf diff |= CT_DIFF_VAL(ORIG_ICMP_CODE, ct_orig.proto.icmp.code); 21944d362409d5469aed47d19e7908d19bd194493aThomas Graf diff |= CT_DIFF_VAL(ORIG_PACKETS, ct_orig.packets); 22044d362409d5469aed47d19e7908d19bd194493aThomas Graf diff |= CT_DIFF_VAL(ORIG_BYTES, ct_orig.bytes); 22144d362409d5469aed47d19e7908d19bd194493aThomas Graf diff |= CT_DIFF_ADDR(REPL_SRC, ct_repl.src); 22244d362409d5469aed47d19e7908d19bd194493aThomas Graf diff |= CT_DIFF_ADDR(ORIG_DST, ct_repl.dst); 22344d362409d5469aed47d19e7908d19bd194493aThomas Graf diff |= CT_DIFF_VAL(REPL_SRC_PORT, ct_repl.proto.port.src); 22444d362409d5469aed47d19e7908d19bd194493aThomas Graf diff |= CT_DIFF_VAL(REPL_DST_PORT, ct_repl.proto.port.dst); 22544d362409d5469aed47d19e7908d19bd194493aThomas Graf diff |= CT_DIFF_VAL(REPL_ICMP_ID, ct_repl.proto.icmp.id); 22644d362409d5469aed47d19e7908d19bd194493aThomas Graf diff |= CT_DIFF_VAL(REPL_ICMP_TYPE, ct_repl.proto.icmp.type); 22744d362409d5469aed47d19e7908d19bd194493aThomas Graf diff |= CT_DIFF_VAL(REPL_ICMP_CODE, ct_repl.proto.icmp.code); 22844d362409d5469aed47d19e7908d19bd194493aThomas Graf diff |= CT_DIFF_VAL(REPL_PACKETS, ct_repl.packets); 22944d362409d5469aed47d19e7908d19bd194493aThomas Graf diff |= CT_DIFF_VAL(REPL_BYTES, ct_repl.bytes); 23044d362409d5469aed47d19e7908d19bd194493aThomas Graf 23144d362409d5469aed47d19e7908d19bd194493aThomas Graf#undef CT_DIFF 23244d362409d5469aed47d19e7908d19bd194493aThomas Graf#undef CT_DIFF_VAL 23344d362409d5469aed47d19e7908d19bd194493aThomas Graf#undef CT_DIFF_ADDR 23444d362409d5469aed47d19e7908d19bd194493aThomas Graf 23544d362409d5469aed47d19e7908d19bd194493aThomas Graf return diff; 23644d362409d5469aed47d19e7908d19bd194493aThomas Graf} 23744d362409d5469aed47d19e7908d19bd194493aThomas Graf 23844d362409d5469aed47d19e7908d19bd194493aThomas Grafstatic struct trans_tbl ct_attrs[] = { 23944d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(CT_ATTR_FAMILY, family) 24044d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(CT_ATTR_PROTO, proto) 24144d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(CT_ATTR_TCP_STATE, tcpstate) 24244d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(CT_ATTR_STATUS, status) 24344d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(CT_ATTR_TIMEOUT, timeout) 24444d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(CT_ATTR_MARK, mark) 24544d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(CT_ATTR_USE, use) 24644d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(CT_ATTR_ID, id) 24744d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(CT_ATTR_ORIG_SRC, origsrc) 24844d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(CT_ATTR_ORIG_DST, origdst) 24944d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(CT_ATTR_ORIG_SRC_PORT, origsrcport) 25044d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(CT_ATTR_ORIG_DST_PORT, origdstport) 25144d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(CT_ATTR_ORIG_ICMP_ID, origicmpid) 25244d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(CT_ATTR_ORIG_ICMP_TYPE, origicmptype) 25344d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(CT_ATTR_ORIG_ICMP_CODE, origicmpcode) 25444d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(CT_ATTR_ORIG_PACKETS, origpackets) 25544d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(CT_ATTR_ORIG_BYTES, origbytes) 25644d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(CT_ATTR_REPL_SRC, replysrc) 25744d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(CT_ATTR_REPL_DST, replydst) 25844d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(CT_ATTR_REPL_SRC_PORT, replysrcport) 25944d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(CT_ATTR_REPL_DST_PORT, replydstport) 26044d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(CT_ATTR_REPL_ICMP_ID, replyicmpid) 26144d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(CT_ATTR_REPL_ICMP_TYPE, replyicmptype) 26244d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(CT_ATTR_REPL_ICMP_CODE, replyicmpcode) 26344d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(CT_ATTR_REPL_PACKETS, replypackets) 26444d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(CT_ATTR_REPL_BYTES, replybytes) 26544d362409d5469aed47d19e7908d19bd194493aThomas Graf}; 26644d362409d5469aed47d19e7908d19bd194493aThomas Graf 26744d362409d5469aed47d19e7908d19bd194493aThomas Grafstatic char *ct_attrs2str(int attrs, char *buf, size_t len) 26844d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 26944d362409d5469aed47d19e7908d19bd194493aThomas Graf return __flags2str(attrs, buf, len, ct_attrs, ARRAY_SIZE(ct_attrs)); 27044d362409d5469aed47d19e7908d19bd194493aThomas Graf} 27144d362409d5469aed47d19e7908d19bd194493aThomas Graf 27244d362409d5469aed47d19e7908d19bd194493aThomas Graf/** 27344d362409d5469aed47d19e7908d19bd194493aThomas Graf * @name Allocation/Freeing 27444d362409d5469aed47d19e7908d19bd194493aThomas Graf * @{ 27544d362409d5469aed47d19e7908d19bd194493aThomas Graf */ 27644d362409d5469aed47d19e7908d19bd194493aThomas Graf 27744d362409d5469aed47d19e7908d19bd194493aThomas Grafstruct nfnl_ct *nfnl_ct_alloc(void) 27844d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 27944d362409d5469aed47d19e7908d19bd194493aThomas Graf return (struct nfnl_ct *) nl_object_alloc(&ct_obj_ops); 28044d362409d5469aed47d19e7908d19bd194493aThomas Graf} 28144d362409d5469aed47d19e7908d19bd194493aThomas Graf 28244d362409d5469aed47d19e7908d19bd194493aThomas Grafvoid nfnl_ct_get(struct nfnl_ct *ct) 28344d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 28444d362409d5469aed47d19e7908d19bd194493aThomas Graf nl_object_get((struct nl_object *) ct); 28544d362409d5469aed47d19e7908d19bd194493aThomas Graf} 28644d362409d5469aed47d19e7908d19bd194493aThomas Graf 28744d362409d5469aed47d19e7908d19bd194493aThomas Grafvoid nfnl_ct_put(struct nfnl_ct *ct) 28844d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 28944d362409d5469aed47d19e7908d19bd194493aThomas Graf nl_object_put((struct nl_object *) ct); 29044d362409d5469aed47d19e7908d19bd194493aThomas Graf} 29144d362409d5469aed47d19e7908d19bd194493aThomas Graf 29244d362409d5469aed47d19e7908d19bd194493aThomas Graf/** @} */ 29344d362409d5469aed47d19e7908d19bd194493aThomas Graf 29444d362409d5469aed47d19e7908d19bd194493aThomas Graf/** 29544d362409d5469aed47d19e7908d19bd194493aThomas Graf * @name Attributes 29644d362409d5469aed47d19e7908d19bd194493aThomas Graf * @{ 29744d362409d5469aed47d19e7908d19bd194493aThomas Graf */ 29844d362409d5469aed47d19e7908d19bd194493aThomas Graf 29944d362409d5469aed47d19e7908d19bd194493aThomas Grafvoid nfnl_ct_set_family(struct nfnl_ct *ct, uint8_t family) 30044d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 30144d362409d5469aed47d19e7908d19bd194493aThomas Graf ct->ct_family = family; 30244d362409d5469aed47d19e7908d19bd194493aThomas Graf ct->ce_mask |= CT_ATTR_FAMILY; 30344d362409d5469aed47d19e7908d19bd194493aThomas Graf} 30444d362409d5469aed47d19e7908d19bd194493aThomas Graf 30544d362409d5469aed47d19e7908d19bd194493aThomas Grafuint8_t nfnl_ct_get_family(const struct nfnl_ct *ct) 30644d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 30744d362409d5469aed47d19e7908d19bd194493aThomas Graf if (ct->ce_mask & CT_ATTR_FAMILY) 30844d362409d5469aed47d19e7908d19bd194493aThomas Graf return ct->ct_family; 30944d362409d5469aed47d19e7908d19bd194493aThomas Graf else 31044d362409d5469aed47d19e7908d19bd194493aThomas Graf return AF_UNSPEC; 31144d362409d5469aed47d19e7908d19bd194493aThomas Graf} 31244d362409d5469aed47d19e7908d19bd194493aThomas Graf 31344d362409d5469aed47d19e7908d19bd194493aThomas Grafvoid nfnl_ct_set_proto(struct nfnl_ct *ct, uint8_t proto) 31444d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 31544d362409d5469aed47d19e7908d19bd194493aThomas Graf ct->ct_proto = proto; 31644d362409d5469aed47d19e7908d19bd194493aThomas Graf ct->ce_mask |= CT_ATTR_PROTO; 31744d362409d5469aed47d19e7908d19bd194493aThomas Graf} 31844d362409d5469aed47d19e7908d19bd194493aThomas Graf 31944d362409d5469aed47d19e7908d19bd194493aThomas Grafint nfnl_ct_test_proto(const struct nfnl_ct *ct) 32044d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 32144d362409d5469aed47d19e7908d19bd194493aThomas Graf return !!(ct->ce_mask & CT_ATTR_PROTO); 32244d362409d5469aed47d19e7908d19bd194493aThomas Graf} 32344d362409d5469aed47d19e7908d19bd194493aThomas Graf 32444d362409d5469aed47d19e7908d19bd194493aThomas Grafuint8_t nfnl_ct_get_proto(const struct nfnl_ct *ct) 32544d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 32644d362409d5469aed47d19e7908d19bd194493aThomas Graf return ct->ct_proto; 32744d362409d5469aed47d19e7908d19bd194493aThomas Graf} 32844d362409d5469aed47d19e7908d19bd194493aThomas Graf 32944d362409d5469aed47d19e7908d19bd194493aThomas Grafvoid nfnl_ct_set_tcp_state(struct nfnl_ct *ct, uint8_t state) 33044d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 33144d362409d5469aed47d19e7908d19bd194493aThomas Graf ct->ct_protoinfo.tcp.state = state; 33244d362409d5469aed47d19e7908d19bd194493aThomas Graf ct->ce_mask |= CT_ATTR_TCP_STATE; 33344d362409d5469aed47d19e7908d19bd194493aThomas Graf} 33444d362409d5469aed47d19e7908d19bd194493aThomas Graf 33544d362409d5469aed47d19e7908d19bd194493aThomas Grafint nfnl_ct_test_tcp_state(const struct nfnl_ct *ct) 33644d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 33744d362409d5469aed47d19e7908d19bd194493aThomas Graf return !!(ct->ce_mask & CT_ATTR_TCP_STATE); 33844d362409d5469aed47d19e7908d19bd194493aThomas Graf} 33944d362409d5469aed47d19e7908d19bd194493aThomas Graf 34044d362409d5469aed47d19e7908d19bd194493aThomas Grafuint8_t nfnl_ct_get_tcp_state(const struct nfnl_ct *ct) 34144d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 34244d362409d5469aed47d19e7908d19bd194493aThomas Graf return ct->ct_protoinfo.tcp.state; 34344d362409d5469aed47d19e7908d19bd194493aThomas Graf} 34444d362409d5469aed47d19e7908d19bd194493aThomas Graf 34544d362409d5469aed47d19e7908d19bd194493aThomas Grafstatic struct trans_tbl tcp_states[] = { 34644d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(TCP_CONNTRACK_NONE,NONE) 34744d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(TCP_CONNTRACK_SYN_SENT,SYN_SENT) 34844d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(TCP_CONNTRACK_SYN_RECV,SYN_RECV) 34944d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(TCP_CONNTRACK_ESTABLISHED,ESTABLISHED) 35044d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(TCP_CONNTRACK_FIN_WAIT,FIN_WAIT) 35144d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(TCP_CONNTRACK_CLOSE_WAIT,CLOSE_WAIT) 35244d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(TCP_CONNTRACK_LAST_ACK,LAST_ACK) 35344d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(TCP_CONNTRACK_TIME_WAIT,TIME_WAIT) 35444d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(TCP_CONNTRACK_CLOSE,CLOSE) 35544d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(TCP_CONNTRACK_LISTEN,LISTEN) 35644d362409d5469aed47d19e7908d19bd194493aThomas Graf}; 35744d362409d5469aed47d19e7908d19bd194493aThomas Graf 35844d362409d5469aed47d19e7908d19bd194493aThomas Grafchar *nfnl_ct_tcp_state2str(uint8_t state, char *buf, size_t len) 35944d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 36044d362409d5469aed47d19e7908d19bd194493aThomas Graf return __type2str(state, buf, len, tcp_states, ARRAY_SIZE(tcp_states)); 36144d362409d5469aed47d19e7908d19bd194493aThomas Graf} 36244d362409d5469aed47d19e7908d19bd194493aThomas Graf 36344d362409d5469aed47d19e7908d19bd194493aThomas Grafint nfnl_ct_str2tcp_state(const char *name) 36444d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 36544d362409d5469aed47d19e7908d19bd194493aThomas Graf return __str2type(name, tcp_states, ARRAY_SIZE(tcp_states)); 36644d362409d5469aed47d19e7908d19bd194493aThomas Graf} 36744d362409d5469aed47d19e7908d19bd194493aThomas Graf 36844d362409d5469aed47d19e7908d19bd194493aThomas Grafvoid nfnl_ct_set_status(struct nfnl_ct *ct, uint32_t status) 36944d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 37044d362409d5469aed47d19e7908d19bd194493aThomas Graf ct->ct_status = status; 37144d362409d5469aed47d19e7908d19bd194493aThomas Graf ct->ce_mask |= CT_ATTR_STATUS; 37244d362409d5469aed47d19e7908d19bd194493aThomas Graf} 37344d362409d5469aed47d19e7908d19bd194493aThomas Graf 37444d362409d5469aed47d19e7908d19bd194493aThomas Grafint nfnl_ct_test_status(const struct nfnl_ct *ct) 37544d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 37644d362409d5469aed47d19e7908d19bd194493aThomas Graf return !!(ct->ce_mask & CT_ATTR_STATUS); 37744d362409d5469aed47d19e7908d19bd194493aThomas Graf} 37844d362409d5469aed47d19e7908d19bd194493aThomas Graf 37944d362409d5469aed47d19e7908d19bd194493aThomas Grafuint32_t nfnl_ct_get_status(const struct nfnl_ct *ct) 38044d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 38144d362409d5469aed47d19e7908d19bd194493aThomas Graf return ct->ct_status; 38244d362409d5469aed47d19e7908d19bd194493aThomas Graf} 38344d362409d5469aed47d19e7908d19bd194493aThomas Graf 38444d362409d5469aed47d19e7908d19bd194493aThomas Grafvoid nfnl_ct_set_timeout(struct nfnl_ct *ct, uint32_t timeout) 38544d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 38644d362409d5469aed47d19e7908d19bd194493aThomas Graf ct->ct_timeout = timeout; 38744d362409d5469aed47d19e7908d19bd194493aThomas Graf ct->ce_mask |= CT_ATTR_TIMEOUT; 38844d362409d5469aed47d19e7908d19bd194493aThomas Graf} 38944d362409d5469aed47d19e7908d19bd194493aThomas Graf 39044d362409d5469aed47d19e7908d19bd194493aThomas Grafint nfnl_ct_test_timeout(const struct nfnl_ct *ct) 39144d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 39244d362409d5469aed47d19e7908d19bd194493aThomas Graf return !!(ct->ce_mask & CT_ATTR_TIMEOUT); 39344d362409d5469aed47d19e7908d19bd194493aThomas Graf} 39444d362409d5469aed47d19e7908d19bd194493aThomas Graf 39544d362409d5469aed47d19e7908d19bd194493aThomas Grafuint32_t nfnl_ct_get_timeout(const struct nfnl_ct *ct) 39644d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 39744d362409d5469aed47d19e7908d19bd194493aThomas Graf return ct->ct_timeout; 39844d362409d5469aed47d19e7908d19bd194493aThomas Graf} 39944d362409d5469aed47d19e7908d19bd194493aThomas Graf 40044d362409d5469aed47d19e7908d19bd194493aThomas Grafvoid nfnl_ct_set_mark(struct nfnl_ct *ct, uint32_t mark) 40144d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 40244d362409d5469aed47d19e7908d19bd194493aThomas Graf ct->ct_mark = mark; 40344d362409d5469aed47d19e7908d19bd194493aThomas Graf ct->ce_mask |= CT_ATTR_MARK; 40444d362409d5469aed47d19e7908d19bd194493aThomas Graf} 40544d362409d5469aed47d19e7908d19bd194493aThomas Graf 40644d362409d5469aed47d19e7908d19bd194493aThomas Grafint nfnl_ct_test_mark(const struct nfnl_ct *ct) 40744d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 40844d362409d5469aed47d19e7908d19bd194493aThomas Graf return !!(ct->ce_mask & CT_ATTR_MARK); 40944d362409d5469aed47d19e7908d19bd194493aThomas Graf} 41044d362409d5469aed47d19e7908d19bd194493aThomas Graf 41144d362409d5469aed47d19e7908d19bd194493aThomas Grafuint32_t nfnl_ct_get_mark(const struct nfnl_ct *ct) 41244d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 41344d362409d5469aed47d19e7908d19bd194493aThomas Graf return ct->ct_mark; 41444d362409d5469aed47d19e7908d19bd194493aThomas Graf} 41544d362409d5469aed47d19e7908d19bd194493aThomas Graf 41644d362409d5469aed47d19e7908d19bd194493aThomas Grafvoid nfnl_ct_set_use(struct nfnl_ct *ct, uint32_t use) 41744d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 41844d362409d5469aed47d19e7908d19bd194493aThomas Graf ct->ct_use = use; 41944d362409d5469aed47d19e7908d19bd194493aThomas Graf ct->ce_mask |= CT_ATTR_USE; 42044d362409d5469aed47d19e7908d19bd194493aThomas Graf} 42144d362409d5469aed47d19e7908d19bd194493aThomas Graf 42244d362409d5469aed47d19e7908d19bd194493aThomas Grafint nfnl_ct_test_use(const struct nfnl_ct *ct) 42344d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 42444d362409d5469aed47d19e7908d19bd194493aThomas Graf return !!(ct->ce_mask & CT_ATTR_USE); 42544d362409d5469aed47d19e7908d19bd194493aThomas Graf} 42644d362409d5469aed47d19e7908d19bd194493aThomas Graf 42744d362409d5469aed47d19e7908d19bd194493aThomas Grafuint32_t nfnl_ct_get_use(const struct nfnl_ct *ct) 42844d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 42944d362409d5469aed47d19e7908d19bd194493aThomas Graf return ct->ct_use; 43044d362409d5469aed47d19e7908d19bd194493aThomas Graf} 43144d362409d5469aed47d19e7908d19bd194493aThomas Graf 43244d362409d5469aed47d19e7908d19bd194493aThomas Grafvoid nfnl_ct_set_id(struct nfnl_ct *ct, uint32_t id) 43344d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 43444d362409d5469aed47d19e7908d19bd194493aThomas Graf ct->ct_id = id; 43544d362409d5469aed47d19e7908d19bd194493aThomas Graf ct->ce_mask |= CT_ATTR_ID; 43644d362409d5469aed47d19e7908d19bd194493aThomas Graf} 43744d362409d5469aed47d19e7908d19bd194493aThomas Graf 43844d362409d5469aed47d19e7908d19bd194493aThomas Grafint nfnl_ct_test_id(const struct nfnl_ct *ct) 43944d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 44044d362409d5469aed47d19e7908d19bd194493aThomas Graf return !!(ct->ce_mask & CT_ATTR_ID); 44144d362409d5469aed47d19e7908d19bd194493aThomas Graf} 44244d362409d5469aed47d19e7908d19bd194493aThomas Graf 44344d362409d5469aed47d19e7908d19bd194493aThomas Grafuint32_t nfnl_ct_get_id(const struct nfnl_ct *ct) 44444d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 44544d362409d5469aed47d19e7908d19bd194493aThomas Graf return ct->ct_id; 44644d362409d5469aed47d19e7908d19bd194493aThomas Graf} 44744d362409d5469aed47d19e7908d19bd194493aThomas Graf 44844d362409d5469aed47d19e7908d19bd194493aThomas Grafstatic int ct_set_addr(struct nfnl_ct *ct, struct nl_addr *addr, 44944d362409d5469aed47d19e7908d19bd194493aThomas Graf int attr, struct nl_addr ** ct_addr) 45044d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 45144d362409d5469aed47d19e7908d19bd194493aThomas Graf if (ct->ce_mask & CT_ATTR_FAMILY) { 45244d362409d5469aed47d19e7908d19bd194493aThomas Graf if (addr->a_family != ct->ct_family) 45344d362409d5469aed47d19e7908d19bd194493aThomas Graf return nl_error(EINVAL, "Address family mismatch"); 45444d362409d5469aed47d19e7908d19bd194493aThomas Graf } else 45544d362409d5469aed47d19e7908d19bd194493aThomas Graf nfnl_ct_set_family(ct, addr->a_family); 45644d362409d5469aed47d19e7908d19bd194493aThomas Graf 45744d362409d5469aed47d19e7908d19bd194493aThomas Graf if (*ct_addr) 45844d362409d5469aed47d19e7908d19bd194493aThomas Graf nl_addr_put(*ct_addr); 45944d362409d5469aed47d19e7908d19bd194493aThomas Graf 46044d362409d5469aed47d19e7908d19bd194493aThomas Graf nl_addr_get(addr); 46144d362409d5469aed47d19e7908d19bd194493aThomas Graf *ct_addr = addr; 46244d362409d5469aed47d19e7908d19bd194493aThomas Graf ct->ce_mask |= attr; 46344d362409d5469aed47d19e7908d19bd194493aThomas Graf 46444d362409d5469aed47d19e7908d19bd194493aThomas Graf return 0; 46544d362409d5469aed47d19e7908d19bd194493aThomas Graf} 46644d362409d5469aed47d19e7908d19bd194493aThomas Graf 46744d362409d5469aed47d19e7908d19bd194493aThomas Grafint nfnl_ct_set_src(struct nfnl_ct *ct, int repl, struct nl_addr *addr) 46844d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 46944d362409d5469aed47d19e7908d19bd194493aThomas Graf struct nfnl_ct_dir *dir = repl ? &ct->ct_repl : &ct->ct_orig; 47044d362409d5469aed47d19e7908d19bd194493aThomas Graf int attr = repl ? CT_ATTR_REPL_SRC : CT_ATTR_ORIG_SRC; 47144d362409d5469aed47d19e7908d19bd194493aThomas Graf return ct_set_addr(ct, addr, attr, &dir->src); 47244d362409d5469aed47d19e7908d19bd194493aThomas Graf} 47344d362409d5469aed47d19e7908d19bd194493aThomas Graf 47444d362409d5469aed47d19e7908d19bd194493aThomas Grafint nfnl_ct_set_dst(struct nfnl_ct *ct, int repl, struct nl_addr *addr) 47544d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 47644d362409d5469aed47d19e7908d19bd194493aThomas Graf struct nfnl_ct_dir *dir = repl ? &ct->ct_repl : &ct->ct_orig; 47744d362409d5469aed47d19e7908d19bd194493aThomas Graf int attr = repl ? CT_ATTR_REPL_DST : CT_ATTR_ORIG_DST; 47844d362409d5469aed47d19e7908d19bd194493aThomas Graf return ct_set_addr(ct, addr, attr, &dir->dst); 47944d362409d5469aed47d19e7908d19bd194493aThomas Graf} 48044d362409d5469aed47d19e7908d19bd194493aThomas Graf 48144d362409d5469aed47d19e7908d19bd194493aThomas Grafstruct nl_addr *nfnl_ct_get_src(const struct nfnl_ct *ct, int repl) 48244d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 48344d362409d5469aed47d19e7908d19bd194493aThomas Graf const struct nfnl_ct_dir *dir = repl ? &ct->ct_repl : &ct->ct_orig; 48444d362409d5469aed47d19e7908d19bd194493aThomas Graf int attr = repl ? CT_ATTR_REPL_SRC : CT_ATTR_ORIG_SRC; 48544d362409d5469aed47d19e7908d19bd194493aThomas Graf if (!(ct->ce_mask & attr)) 48644d362409d5469aed47d19e7908d19bd194493aThomas Graf return NULL; 48744d362409d5469aed47d19e7908d19bd194493aThomas Graf return dir->src; 48844d362409d5469aed47d19e7908d19bd194493aThomas Graf} 48944d362409d5469aed47d19e7908d19bd194493aThomas Graf 49044d362409d5469aed47d19e7908d19bd194493aThomas Grafstruct nl_addr *nfnl_ct_get_dst(const struct nfnl_ct *ct, int repl) 49144d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 49244d362409d5469aed47d19e7908d19bd194493aThomas Graf const struct nfnl_ct_dir *dir = repl ? &ct->ct_repl : &ct->ct_orig; 49344d362409d5469aed47d19e7908d19bd194493aThomas Graf int attr = repl ? CT_ATTR_REPL_DST : CT_ATTR_ORIG_DST; 49444d362409d5469aed47d19e7908d19bd194493aThomas Graf if (!(ct->ce_mask & attr)) 49544d362409d5469aed47d19e7908d19bd194493aThomas Graf return NULL; 49644d362409d5469aed47d19e7908d19bd194493aThomas Graf return dir->dst; 49744d362409d5469aed47d19e7908d19bd194493aThomas Graf} 49844d362409d5469aed47d19e7908d19bd194493aThomas Graf 49944d362409d5469aed47d19e7908d19bd194493aThomas Grafvoid nfnl_ct_set_src_port(struct nfnl_ct *ct, int repl, uint16_t port) 50044d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 50144d362409d5469aed47d19e7908d19bd194493aThomas Graf struct nfnl_ct_dir *dir = repl ? &ct->ct_repl : &ct->ct_orig; 50244d362409d5469aed47d19e7908d19bd194493aThomas Graf int attr = repl ? CT_ATTR_REPL_SRC_PORT : CT_ATTR_ORIG_SRC_PORT; 50344d362409d5469aed47d19e7908d19bd194493aThomas Graf 50444d362409d5469aed47d19e7908d19bd194493aThomas Graf dir->proto.port.src = port; 50544d362409d5469aed47d19e7908d19bd194493aThomas Graf ct->ce_mask |= attr; 50644d362409d5469aed47d19e7908d19bd194493aThomas Graf} 50744d362409d5469aed47d19e7908d19bd194493aThomas Graf 50844d362409d5469aed47d19e7908d19bd194493aThomas Grafint nfnl_ct_test_src_port(const struct nfnl_ct *ct, int repl) 50944d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 51044d362409d5469aed47d19e7908d19bd194493aThomas Graf int attr = repl ? CT_ATTR_REPL_SRC_PORT : CT_ATTR_ORIG_SRC_PORT; 51144d362409d5469aed47d19e7908d19bd194493aThomas Graf return !!(ct->ce_mask & attr); 51244d362409d5469aed47d19e7908d19bd194493aThomas Graf} 51344d362409d5469aed47d19e7908d19bd194493aThomas Graf 51444d362409d5469aed47d19e7908d19bd194493aThomas Grafuint16_t nfnl_ct_get_src_port(const struct nfnl_ct *ct, int repl) 51544d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 51644d362409d5469aed47d19e7908d19bd194493aThomas Graf const struct nfnl_ct_dir *dir = repl ? &ct->ct_repl : &ct->ct_orig; 51744d362409d5469aed47d19e7908d19bd194493aThomas Graf 51844d362409d5469aed47d19e7908d19bd194493aThomas Graf return dir->proto.port.src; 51944d362409d5469aed47d19e7908d19bd194493aThomas Graf} 52044d362409d5469aed47d19e7908d19bd194493aThomas Graf 52144d362409d5469aed47d19e7908d19bd194493aThomas Grafvoid nfnl_ct_set_dst_port(struct nfnl_ct *ct, int repl, uint16_t port) 52244d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 52344d362409d5469aed47d19e7908d19bd194493aThomas Graf struct nfnl_ct_dir *dir = repl ? &ct->ct_repl : &ct->ct_orig; 52444d362409d5469aed47d19e7908d19bd194493aThomas Graf int attr = repl ? CT_ATTR_REPL_DST_PORT : CT_ATTR_ORIG_DST_PORT; 52544d362409d5469aed47d19e7908d19bd194493aThomas Graf 52644d362409d5469aed47d19e7908d19bd194493aThomas Graf dir->proto.port.dst = port; 52744d362409d5469aed47d19e7908d19bd194493aThomas Graf ct->ce_mask |= attr; 52844d362409d5469aed47d19e7908d19bd194493aThomas Graf} 52944d362409d5469aed47d19e7908d19bd194493aThomas Graf 53044d362409d5469aed47d19e7908d19bd194493aThomas Grafint nfnl_ct_test_dst_port(const struct nfnl_ct *ct, int repl) 53144d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 53244d362409d5469aed47d19e7908d19bd194493aThomas Graf int attr = repl ? CT_ATTR_REPL_DST_PORT : CT_ATTR_ORIG_DST_PORT; 53344d362409d5469aed47d19e7908d19bd194493aThomas Graf return !!(ct->ce_mask & attr); 53444d362409d5469aed47d19e7908d19bd194493aThomas Graf} 53544d362409d5469aed47d19e7908d19bd194493aThomas Graf 53644d362409d5469aed47d19e7908d19bd194493aThomas Grafuint16_t nfnl_ct_get_dst_port(const struct nfnl_ct *ct, int repl) 53744d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 53844d362409d5469aed47d19e7908d19bd194493aThomas Graf const struct nfnl_ct_dir *dir = repl ? &ct->ct_repl : &ct->ct_orig; 53944d362409d5469aed47d19e7908d19bd194493aThomas Graf 54044d362409d5469aed47d19e7908d19bd194493aThomas Graf return dir->proto.port.dst; 54144d362409d5469aed47d19e7908d19bd194493aThomas Graf} 54244d362409d5469aed47d19e7908d19bd194493aThomas Graf 54344d362409d5469aed47d19e7908d19bd194493aThomas Grafvoid nfnl_ct_set_icmp_id(struct nfnl_ct *ct, int repl, uint16_t id) 54444d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 54544d362409d5469aed47d19e7908d19bd194493aThomas Graf struct nfnl_ct_dir *dir = repl ? &ct->ct_repl : &ct->ct_orig; 54644d362409d5469aed47d19e7908d19bd194493aThomas Graf int attr = repl ? CT_ATTR_REPL_ICMP_ID : CT_ATTR_ORIG_ICMP_ID; 54744d362409d5469aed47d19e7908d19bd194493aThomas Graf 54844d362409d5469aed47d19e7908d19bd194493aThomas Graf dir->proto.icmp.id = id; 54944d362409d5469aed47d19e7908d19bd194493aThomas Graf ct->ce_mask |= attr; 55044d362409d5469aed47d19e7908d19bd194493aThomas Graf} 55144d362409d5469aed47d19e7908d19bd194493aThomas Graf 55244d362409d5469aed47d19e7908d19bd194493aThomas Grafint nfnl_ct_test_icmp_id(const struct nfnl_ct *ct, int repl) 55344d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 55444d362409d5469aed47d19e7908d19bd194493aThomas Graf int attr = repl ? CT_ATTR_REPL_ICMP_ID : CT_ATTR_ORIG_ICMP_ID; 55544d362409d5469aed47d19e7908d19bd194493aThomas Graf return !!(ct->ce_mask & attr); 55644d362409d5469aed47d19e7908d19bd194493aThomas Graf} 55744d362409d5469aed47d19e7908d19bd194493aThomas Graf 55844d362409d5469aed47d19e7908d19bd194493aThomas Grafuint16_t nfnl_ct_get_icmp_id(const struct nfnl_ct *ct, int repl) 55944d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 56044d362409d5469aed47d19e7908d19bd194493aThomas Graf const struct nfnl_ct_dir *dir = repl ? &ct->ct_repl : &ct->ct_orig; 56144d362409d5469aed47d19e7908d19bd194493aThomas Graf 56244d362409d5469aed47d19e7908d19bd194493aThomas Graf return dir->proto.icmp.id; 56344d362409d5469aed47d19e7908d19bd194493aThomas Graf} 56444d362409d5469aed47d19e7908d19bd194493aThomas Graf 56544d362409d5469aed47d19e7908d19bd194493aThomas Grafvoid nfnl_ct_set_icmp_type(struct nfnl_ct *ct, int repl, uint8_t type) 56644d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 56744d362409d5469aed47d19e7908d19bd194493aThomas Graf struct nfnl_ct_dir *dir = repl ? &ct->ct_repl : &ct->ct_orig; 56844d362409d5469aed47d19e7908d19bd194493aThomas Graf int attr = repl ? CT_ATTR_REPL_ICMP_TYPE : CT_ATTR_ORIG_ICMP_TYPE; 56944d362409d5469aed47d19e7908d19bd194493aThomas Graf 57044d362409d5469aed47d19e7908d19bd194493aThomas Graf dir->proto.icmp.type = type; 57144d362409d5469aed47d19e7908d19bd194493aThomas Graf ct->ce_mask |= attr; 57244d362409d5469aed47d19e7908d19bd194493aThomas Graf} 57344d362409d5469aed47d19e7908d19bd194493aThomas Graf 57444d362409d5469aed47d19e7908d19bd194493aThomas Grafint nfnl_ct_test_icmp_type(const struct nfnl_ct *ct, int repl) 57544d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 57644d362409d5469aed47d19e7908d19bd194493aThomas Graf int attr = repl ? CT_ATTR_REPL_ICMP_TYPE : CT_ATTR_ORIG_ICMP_TYPE; 57744d362409d5469aed47d19e7908d19bd194493aThomas Graf return !!(ct->ce_mask & attr); 57844d362409d5469aed47d19e7908d19bd194493aThomas Graf} 57944d362409d5469aed47d19e7908d19bd194493aThomas Graf 58044d362409d5469aed47d19e7908d19bd194493aThomas Grafuint8_t nfnl_ct_get_icmp_type(const struct nfnl_ct *ct, int repl) 58144d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 58244d362409d5469aed47d19e7908d19bd194493aThomas Graf const struct nfnl_ct_dir *dir = repl ? &ct->ct_repl : &ct->ct_orig; 58344d362409d5469aed47d19e7908d19bd194493aThomas Graf 58444d362409d5469aed47d19e7908d19bd194493aThomas Graf return dir->proto.icmp.type; 58544d362409d5469aed47d19e7908d19bd194493aThomas Graf} 58644d362409d5469aed47d19e7908d19bd194493aThomas Graf 58744d362409d5469aed47d19e7908d19bd194493aThomas Grafvoid nfnl_ct_set_icmp_code(struct nfnl_ct *ct, int repl, uint8_t code) 58844d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 58944d362409d5469aed47d19e7908d19bd194493aThomas Graf struct nfnl_ct_dir *dir = repl ? &ct->ct_repl : &ct->ct_orig; 59044d362409d5469aed47d19e7908d19bd194493aThomas Graf int attr = repl ? CT_ATTR_REPL_ICMP_CODE : CT_ATTR_ORIG_ICMP_CODE; 59144d362409d5469aed47d19e7908d19bd194493aThomas Graf 59244d362409d5469aed47d19e7908d19bd194493aThomas Graf dir->proto.icmp.code = code; 59344d362409d5469aed47d19e7908d19bd194493aThomas Graf ct->ce_mask |= attr; 59444d362409d5469aed47d19e7908d19bd194493aThomas Graf} 59544d362409d5469aed47d19e7908d19bd194493aThomas Graf 59644d362409d5469aed47d19e7908d19bd194493aThomas Grafint nfnl_ct_test_icmp_code(const struct nfnl_ct *ct, int repl) 59744d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 59844d362409d5469aed47d19e7908d19bd194493aThomas Graf int attr = repl ? CT_ATTR_REPL_ICMP_CODE : CT_ATTR_ORIG_ICMP_CODE; 59944d362409d5469aed47d19e7908d19bd194493aThomas Graf return !!(ct->ce_mask & attr); 60044d362409d5469aed47d19e7908d19bd194493aThomas Graf} 60144d362409d5469aed47d19e7908d19bd194493aThomas Graf 60244d362409d5469aed47d19e7908d19bd194493aThomas Grafuint8_t nfnl_ct_get_icmp_code(const struct nfnl_ct *ct, int repl) 60344d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 60444d362409d5469aed47d19e7908d19bd194493aThomas Graf const struct nfnl_ct_dir *dir = repl ? &ct->ct_repl : &ct->ct_orig; 60544d362409d5469aed47d19e7908d19bd194493aThomas Graf 60644d362409d5469aed47d19e7908d19bd194493aThomas Graf return dir->proto.icmp.code; 60744d362409d5469aed47d19e7908d19bd194493aThomas Graf} 60844d362409d5469aed47d19e7908d19bd194493aThomas Graf 60944d362409d5469aed47d19e7908d19bd194493aThomas Grafvoid nfnl_ct_set_packets(struct nfnl_ct *ct, int repl, uint64_t packets) 61044d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 61144d362409d5469aed47d19e7908d19bd194493aThomas Graf struct nfnl_ct_dir *dir = repl ? &ct->ct_repl : &ct->ct_orig; 61244d362409d5469aed47d19e7908d19bd194493aThomas Graf int attr = repl ? CT_ATTR_REPL_PACKETS : CT_ATTR_ORIG_PACKETS; 61344d362409d5469aed47d19e7908d19bd194493aThomas Graf 61444d362409d5469aed47d19e7908d19bd194493aThomas Graf dir->packets = packets; 61544d362409d5469aed47d19e7908d19bd194493aThomas Graf ct->ce_mask |= attr; 61644d362409d5469aed47d19e7908d19bd194493aThomas Graf} 61744d362409d5469aed47d19e7908d19bd194493aThomas Graf 61844d362409d5469aed47d19e7908d19bd194493aThomas Grafint nfnl_ct_test_packets(const struct nfnl_ct *ct, int repl) 61944d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 62044d362409d5469aed47d19e7908d19bd194493aThomas Graf int attr = repl ? CT_ATTR_REPL_PACKETS : CT_ATTR_ORIG_PACKETS; 62144d362409d5469aed47d19e7908d19bd194493aThomas Graf return !!(ct->ce_mask & attr); 62244d362409d5469aed47d19e7908d19bd194493aThomas Graf} 62344d362409d5469aed47d19e7908d19bd194493aThomas Graf 62444d362409d5469aed47d19e7908d19bd194493aThomas Grafuint64_t nfnl_ct_get_packets(const struct nfnl_ct *ct, int repl) 62544d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 62644d362409d5469aed47d19e7908d19bd194493aThomas Graf const struct nfnl_ct_dir *dir = repl ? &ct->ct_repl : &ct->ct_orig; 62744d362409d5469aed47d19e7908d19bd194493aThomas Graf 62844d362409d5469aed47d19e7908d19bd194493aThomas Graf return dir->packets; 62944d362409d5469aed47d19e7908d19bd194493aThomas Graf} 63044d362409d5469aed47d19e7908d19bd194493aThomas Graf 63144d362409d5469aed47d19e7908d19bd194493aThomas Grafvoid nfnl_ct_set_bytes(struct nfnl_ct *ct, int repl, uint64_t bytes) 63244d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 63344d362409d5469aed47d19e7908d19bd194493aThomas Graf struct nfnl_ct_dir *dir = repl ? &ct->ct_repl : &ct->ct_orig; 63444d362409d5469aed47d19e7908d19bd194493aThomas Graf int attr = repl ? CT_ATTR_REPL_BYTES : CT_ATTR_ORIG_BYTES; 63544d362409d5469aed47d19e7908d19bd194493aThomas Graf 63644d362409d5469aed47d19e7908d19bd194493aThomas Graf dir->bytes = bytes; 63744d362409d5469aed47d19e7908d19bd194493aThomas Graf ct->ce_mask |= attr; 63844d362409d5469aed47d19e7908d19bd194493aThomas Graf} 63944d362409d5469aed47d19e7908d19bd194493aThomas Graf 64044d362409d5469aed47d19e7908d19bd194493aThomas Grafint nfnl_ct_test_bytes(const struct nfnl_ct *ct, int repl) 64144d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 64244d362409d5469aed47d19e7908d19bd194493aThomas Graf int attr = repl ? CT_ATTR_REPL_BYTES : CT_ATTR_ORIG_BYTES; 64344d362409d5469aed47d19e7908d19bd194493aThomas Graf return !!(ct->ce_mask & attr); 64444d362409d5469aed47d19e7908d19bd194493aThomas Graf} 64544d362409d5469aed47d19e7908d19bd194493aThomas Graf 64644d362409d5469aed47d19e7908d19bd194493aThomas Grafuint64_t nfnl_ct_get_bytes(const struct nfnl_ct *ct, int repl) 64744d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 64844d362409d5469aed47d19e7908d19bd194493aThomas Graf const struct nfnl_ct_dir *dir = repl ? &ct->ct_repl : &ct->ct_orig; 64944d362409d5469aed47d19e7908d19bd194493aThomas Graf 65044d362409d5469aed47d19e7908d19bd194493aThomas Graf return dir->bytes; 65144d362409d5469aed47d19e7908d19bd194493aThomas Graf} 65244d362409d5469aed47d19e7908d19bd194493aThomas Graf 65344d362409d5469aed47d19e7908d19bd194493aThomas Graf/** @} */ 65444d362409d5469aed47d19e7908d19bd194493aThomas Graf 65544d362409d5469aed47d19e7908d19bd194493aThomas Grafstruct nl_object_ops ct_obj_ops = { 65644d362409d5469aed47d19e7908d19bd194493aThomas Graf .oo_name = "netfilter/ct", 65744d362409d5469aed47d19e7908d19bd194493aThomas Graf .oo_size = sizeof(struct nfnl_ct), 65844d362409d5469aed47d19e7908d19bd194493aThomas Graf .oo_free_data = ct_free_data, 65944d362409d5469aed47d19e7908d19bd194493aThomas Graf .oo_clone = ct_clone, 66044d362409d5469aed47d19e7908d19bd194493aThomas Graf .oo_dump[NL_DUMP_BRIEF] = ct_dump, 66144d362409d5469aed47d19e7908d19bd194493aThomas Graf .oo_dump[NL_DUMP_FULL] = ct_dump, 66244d362409d5469aed47d19e7908d19bd194493aThomas Graf .oo_dump[NL_DUMP_STATS] = ct_dump, 66344d362409d5469aed47d19e7908d19bd194493aThomas Graf .oo_compare = ct_compare, 66444d362409d5469aed47d19e7908d19bd194493aThomas Graf .oo_attrs2str = ct_attrs2str, 66544d362409d5469aed47d19e7908d19bd194493aThomas Graf}; 66644d362409d5469aed47d19e7908d19bd194493aThomas Graf 66744d362409d5469aed47d19e7908d19bd194493aThomas Graf/** @} */ 668