9#include <linux/netfilter/nfnetlink_conntrack.h> 
   10#include <linux/netfilter/nf_conntrack_common.h> 
   11#include <linux/netfilter/nf_conntrack_tcp.h> 
   13#include <netlink-private/netlink.h> 
   14#include <netlink/netfilter/nfnl.h> 
   15#include <netlink/netfilter/ct.h> 
   18#define CT_ATTR_FAMILY          (1UL << 0) 
   19#define CT_ATTR_PROTO           (1UL << 1) 
   21#define CT_ATTR_TCP_STATE       (1UL << 2) 
   23#define CT_ATTR_STATUS          (1UL << 3) 
   24#define CT_ATTR_TIMEOUT         (1UL << 4) 
   25#define CT_ATTR_MARK            (1UL << 5) 
   26#define CT_ATTR_USE             (1UL << 6) 
   27#define CT_ATTR_ID              (1UL << 7) 
   29#define CT_ATTR_ORIG_SRC        (1UL << 8) 
   30#define CT_ATTR_ORIG_DST        (1UL << 9) 
   31#define CT_ATTR_ORIG_SRC_PORT   (1UL << 10) 
   32#define CT_ATTR_ORIG_DST_PORT   (1UL << 11) 
   33#define CT_ATTR_ORIG_ICMP_ID    (1UL << 12) 
   34#define CT_ATTR_ORIG_ICMP_TYPE  (1UL << 13) 
   35#define CT_ATTR_ORIG_ICMP_CODE  (1UL << 14) 
   36#define CT_ATTR_ORIG_PACKETS    (1UL << 15) 
   37#define CT_ATTR_ORIG_BYTES      (1UL << 16) 
   39#define CT_ATTR_REPL_SRC        (1UL << 17) 
   40#define CT_ATTR_REPL_DST        (1UL << 18) 
   41#define CT_ATTR_REPL_SRC_PORT   (1UL << 19) 
   42#define CT_ATTR_REPL_DST_PORT   (1UL << 20) 
   43#define CT_ATTR_REPL_ICMP_ID    (1UL << 21) 
   44#define CT_ATTR_REPL_ICMP_TYPE  (1UL << 22) 
   45#define CT_ATTR_REPL_ICMP_CODE  (1UL << 23) 
   46#define CT_ATTR_REPL_PACKETS    (1UL << 24) 
   47#define CT_ATTR_REPL_BYTES      (1UL << 25) 
   48#define CT_ATTR_TIMESTAMP       (1UL << 26) 
   49#define CT_ATTR_ZONE    (1UL << 27) 
   52static void ct_free_data(
struct nl_object *c)
 
   54        struct nfnl_ct *ct = (
struct nfnl_ct *) c;
 
   65static int ct_clone(
struct nl_object *_dst, 
struct nl_object *_src)
 
   67        struct nfnl_ct *dst = (
struct nfnl_ct *) _dst;
 
   68        struct nfnl_ct *src = (
struct nfnl_ct *) _src;
 
   71        dst->ct_orig.src = NULL;
 
   72        dst->ct_orig.dst = NULL;
 
   73        dst->ct_repl.src = NULL;
 
   74        dst->ct_repl.dst = NULL;
 
   76        if (src->ct_orig.src) {
 
   80                dst->ct_orig.src = addr;
 
   83        if (src->ct_orig.dst) {
 
   87                dst->ct_orig.dst = addr;
 
   90        if (src->ct_repl.src) {
 
   94                dst->ct_repl.src = addr;
 
   97        if (src->ct_repl.dst) {
 
  101                dst->ct_repl.dst = addr;
 
  107static void dump_addr(
struct nl_dump_params *p, 
struct nl_addr *addr, 
int port)
 
  120static void dump_icmp(
struct nl_dump_params *p, 
struct nfnl_ct *ct, 
int reply)
 
  122        if (nfnl_ct_test_icmp_type(ct, reply))
 
  123                nl_dump(p, 
"icmp type %d ", nfnl_ct_get_icmp_type(ct, reply));
 
  125        if (nfnl_ct_test_icmp_code(ct, reply))
 
  126                nl_dump(p, 
"code %d ", nfnl_ct_get_icmp_code(ct, reply));
 
  128        if (nfnl_ct_test_icmp_id(ct, reply))
 
  129                nl_dump(p, 
"id %d ", nfnl_ct_get_icmp_id(ct, reply));
 
  132static void ct_dump_tuples(
struct nfnl_ct *ct, 
struct nl_dump_params *p)
 
  134        struct nl_addr *orig_src, *orig_dst, *reply_src, *reply_dst;
 
  135        int orig_sport = 0, orig_dport = 0, reply_sport = 0, reply_dport = 0;
 
  138        orig_src = nfnl_ct_get_src(ct, 0);
 
  139        orig_dst = nfnl_ct_get_dst(ct, 0);
 
  140        reply_src = nfnl_ct_get_src(ct, 1);
 
  141        reply_dst = nfnl_ct_get_dst(ct, 1);
 
  143        if (nfnl_ct_test_src_port(ct, 0))
 
  144                orig_sport = nfnl_ct_get_src_port(ct, 0);
 
  146        if (nfnl_ct_test_dst_port(ct, 0))
 
  147                orig_dport = nfnl_ct_get_dst_port(ct, 0);
 
  149        if (nfnl_ct_test_src_port(ct, 1))
 
  150                reply_sport = nfnl_ct_get_src_port(ct, 1);
 
  152        if (nfnl_ct_test_dst_port(ct, 1))
 
  153                reply_dport = nfnl_ct_get_dst_port(ct, 1);
 
  155        if (orig_src && orig_dst && reply_src && reply_dst &&
 
  156            orig_sport == reply_dport && orig_dport == reply_sport &&
 
  161        dump_addr(p, orig_src, orig_sport);
 
  162        nl_dump(p, sync ? 
"<-> " : 
"-> ");
 
  163        dump_addr(p, orig_dst, orig_dport);
 
  167                dump_addr(p, reply_src, reply_sport);
 
  169                dump_addr(p, reply_dst, reply_dport);
 
  175static void ct_dump_line(
struct nl_object *a, 
struct nl_dump_params *p)
 
  177        struct nfnl_ct *ct = (
struct nfnl_ct *) a;
 
  182        if (nfnl_ct_test_proto(ct))
 
  184                  nl_ip_proto2str(nfnl_ct_get_proto(ct), buf, 
sizeof(buf)));
 
  186        if (nfnl_ct_test_tcp_state(ct))
 
  188                        nfnl_ct_tcp_state2str(nfnl_ct_get_tcp_state(ct),
 
  191        ct_dump_tuples(ct, p);
 
  193        if (nfnl_ct_test_mark(ct) && nfnl_ct_get_mark(ct))
 
  194                nl_dump(p, 
"mark %u ", nfnl_ct_get_mark(ct));
 
  196        if (nfnl_ct_test_zone(ct))
 
  197                nl_dump(p, 
"zone %hu ", nfnl_ct_get_zone(ct));
 
  199        if (nfnl_ct_test_timestamp(ct)) {
 
  201                int64_t delta_time = tstamp->stop - tstamp->start;
 
  204                        delta_time /= NSEC_PER_SEC;
 
  207                nl_dump(p, 
"delta-time %llu ", (
long long unsigned)delta_time);
 
  213static void ct_dump_details(
struct nl_object *a, 
struct nl_dump_params *p)
 
  215        struct nfnl_ct *ct = (
struct nfnl_ct *) a;
 
  221        nl_dump(p, 
"    id 0x%x ", ct->ct_id);
 
  222        if (ct->ce_mask & CT_ATTR_FAMILY)
 
  223                nl_dump_line(p, 
"family %s ",
 
  224                        nl_af2str(ct->ct_family, buf, 
sizeof(buf)));
 
  226        if (nfnl_ct_test_use(ct))
 
  227                nl_dump(p, 
"refcnt %u ", nfnl_ct_get_use(ct));
 
  229        if (nfnl_ct_test_timeout(ct)) {
 
  230                uint64_t timeout_ms = nfnl_ct_get_timeout(ct) * 1000UL;
 
  238#define PRINT_FLAG(str) \ 
  239        { nl_dump(p, "%s%s", fp++ ? "," : "", (str)); }
 
  241        if (ct->ct_status & IPS_EXPECTED)
 
  242                PRINT_FLAG(
"EXPECTED");
 
  243        if (!(ct->ct_status & IPS_SEEN_REPLY))
 
  244                PRINT_FLAG(
"NOREPLY");
 
  245        if (ct->ct_status & IPS_ASSURED)
 
  246                PRINT_FLAG(
"ASSURED");
 
  247        if (!(ct->ct_status & IPS_CONFIRMED))
 
  248                PRINT_FLAG(
"NOTSENT");
 
  249        if (ct->ct_status & IPS_SRC_NAT)
 
  251        if (ct->ct_status & IPS_DST_NAT)
 
  253        if (ct->ct_status & IPS_SEQ_ADJUST)
 
  254                PRINT_FLAG(
"SEQADJUST");
 
  255        if (!(ct->ct_status & IPS_SRC_NAT_DONE))
 
  256                PRINT_FLAG(
"SNAT_INIT");
 
  257        if (!(ct->ct_status & IPS_DST_NAT_DONE))
 
  258                PRINT_FLAG(
"DNAT_INIT");
 
  259        if (ct->ct_status & IPS_DYING)
 
  261        if (ct->ct_status & IPS_FIXED_TIMEOUT)
 
  262                PRINT_FLAG(
"FIXED_TIMEOUT");
 
  270static void ct_dump_stats(
struct nl_object *a, 
struct nl_dump_params *p)
 
  272        struct nfnl_ct *ct = (
struct nfnl_ct *) a;
 
  276        const char * 
const names[] = {
"rx", 
"tx"};
 
  279        ct_dump_details(a, p);
 
  281        if (!nfnl_ct_test_bytes(ct, 0) ||
 
  282            !nfnl_ct_test_packets(ct, 0) ||
 
  283            !nfnl_ct_test_bytes(ct, 1) ||
 
  284            !nfnl_ct_test_packets(ct, 1))
 
  286                nl_dump_line(p, 
"    Statistics are not available.\n");
 
  287                nl_dump_line(p, 
"    Please set sysctl net.netfilter.nf_conntrack_acct=1\n");
 
  288                nl_dump_line(p, 
"    (Require kernel 2.6.27)\n");
 
  292        nl_dump_line(p, 
"        # packets      volume\n");
 
  293        for (i=0; i<=1; i++) {
 
  295                packets = nfnl_ct_get_packets(ct, i);
 
  296                nl_dump_line(p, 
"    %s %10" PRIu64  
" %7.2f %s\n", names[i], packets, res, unit);
 
  300static uint64_t ct_compare(
struct nl_object *_a, 
struct nl_object *_b,
 
  301                           uint64_t attrs, 
int flags)
 
  303        struct nfnl_ct *a = (
struct nfnl_ct *) _a;
 
  304        struct nfnl_ct *b = (
struct nfnl_ct *) _b;
 
  307#define CT_DIFF(ATTR, EXPR) ATTR_DIFF(attrs, CT_ATTR_##ATTR, a, b, EXPR) 
  308#define CT_DIFF_VAL(ATTR, FIELD) CT_DIFF(ATTR, a->FIELD != b->FIELD) 
  309#define CT_DIFF_ADDR(ATTR, FIELD) \ 
  310        ((flags & LOOSE_COMPARISON) \ 
  311                ? CT_DIFF(ATTR, nl_addr_cmp_prefix(a->FIELD, b->FIELD)) \ 
  312                : CT_DIFF(ATTR, nl_addr_cmp(a->FIELD, b->FIELD))) 
  314        diff |= CT_DIFF_VAL(FAMILY,             ct_family);
 
  315        diff |= CT_DIFF_VAL(PROTO,              ct_proto);
 
  316        diff |= CT_DIFF_VAL(TCP_STATE,          ct_protoinfo.tcp.state);
 
  317        diff |= CT_DIFF_VAL(TIMEOUT,            ct_timeout);
 
  318        diff |= CT_DIFF_VAL(MARK,               ct_mark);
 
  319        diff |= CT_DIFF_VAL(USE,                ct_use);
 
  320        diff |= CT_DIFF_VAL(ID,                 ct_id);
 
  321        diff |= CT_DIFF_ADDR(ORIG_SRC,          ct_orig.src);
 
  322        diff |= CT_DIFF_ADDR(ORIG_DST,          ct_orig.dst);
 
  323        diff |= CT_DIFF_VAL(ORIG_SRC_PORT,      ct_orig.proto.port.src);
 
  324        diff |= CT_DIFF_VAL(ORIG_DST_PORT,      ct_orig.proto.port.dst);
 
  325        diff |= CT_DIFF_VAL(ORIG_ICMP_ID,       ct_orig.proto.icmp.id);
 
  326        diff |= CT_DIFF_VAL(ORIG_ICMP_TYPE,     ct_orig.proto.icmp.type);
 
  327        diff |= CT_DIFF_VAL(ORIG_ICMP_CODE,     ct_orig.proto.icmp.code);
 
  328        diff |= CT_DIFF_VAL(ORIG_PACKETS,       ct_orig.packets);
 
  329        diff |= CT_DIFF_VAL(ORIG_BYTES,         ct_orig.bytes);
 
  330        diff |= CT_DIFF_ADDR(REPL_SRC,          ct_repl.src);
 
  331        diff |= CT_DIFF_ADDR(REPL_DST,          ct_repl.dst);
 
  332        diff |= CT_DIFF_VAL(REPL_SRC_PORT,      ct_repl.proto.port.src);
 
  333        diff |= CT_DIFF_VAL(REPL_DST_PORT,      ct_repl.proto.port.dst);
 
  334        diff |= CT_DIFF_VAL(REPL_ICMP_ID,       ct_repl.proto.icmp.id);
 
  335        diff |= CT_DIFF_VAL(REPL_ICMP_TYPE,     ct_repl.proto.icmp.type);
 
  336        diff |= CT_DIFF_VAL(REPL_ICMP_CODE,     ct_repl.proto.icmp.code);
 
  337        diff |= CT_DIFF_VAL(REPL_PACKETS,       ct_repl.packets);
 
  338        diff |= CT_DIFF_VAL(REPL_BYTES,         ct_repl.bytes);
 
  340        if (flags & LOOSE_COMPARISON)
 
  341                diff |= CT_DIFF(STATUS, (a->ct_status ^ b->ct_status) &
 
  344                diff |= CT_DIFF(STATUS, a->ct_status != b->ct_status);
 
  353static const struct trans_tbl ct_attrs[] = {
 
  354        __ADD(CT_ATTR_FAMILY,           family),
 
  355        __ADD(CT_ATTR_PROTO,            proto),
 
  356        __ADD(CT_ATTR_TCP_STATE,        tcpstate),
 
  357        __ADD(CT_ATTR_STATUS,           status),
 
  358        __ADD(CT_ATTR_TIMEOUT,          timeout),
 
  359        __ADD(CT_ATTR_MARK,             mark),
 
  360        __ADD(CT_ATTR_USE,              use),
 
  361        __ADD(CT_ATTR_ID,               
id),
 
  362        __ADD(CT_ATTR_ORIG_SRC,         origsrc),
 
  363        __ADD(CT_ATTR_ORIG_DST,         origdst),
 
  364        __ADD(CT_ATTR_ORIG_SRC_PORT,    origsrcport),
 
  365        __ADD(CT_ATTR_ORIG_DST_PORT,    origdstport),
 
  366        __ADD(CT_ATTR_ORIG_ICMP_ID,     origicmpid),
 
  367        __ADD(CT_ATTR_ORIG_ICMP_TYPE,   origicmptype),
 
  368        __ADD(CT_ATTR_ORIG_ICMP_CODE,   origicmpcode),
 
  369        __ADD(CT_ATTR_ORIG_PACKETS,     origpackets),
 
  370        __ADD(CT_ATTR_ORIG_BYTES,       origbytes),
 
  371        __ADD(CT_ATTR_REPL_SRC,         replysrc),
 
  372        __ADD(CT_ATTR_REPL_DST,         replydst),
 
  373        __ADD(CT_ATTR_REPL_SRC_PORT,    replysrcport),
 
  374        __ADD(CT_ATTR_REPL_DST_PORT,    replydstport),
 
  375        __ADD(CT_ATTR_REPL_ICMP_ID,     replyicmpid),
 
  376        __ADD(CT_ATTR_REPL_ICMP_TYPE,   replyicmptype),
 
  377        __ADD(CT_ATTR_REPL_ICMP_CODE,   replyicmpcode),
 
  378        __ADD(CT_ATTR_REPL_PACKETS,     replypackets),
 
  379        __ADD(CT_ATTR_REPL_BYTES,       replybytes),
 
  382static char *ct_attrs2str(
int attrs, 
char *buf, 
size_t len)
 
  384        return __flags2str(attrs, buf, len, ct_attrs, ARRAY_SIZE(ct_attrs));
 
  392struct nfnl_ct *nfnl_ct_alloc(
void)
 
  397void nfnl_ct_get(
struct nfnl_ct *ct)
 
  402void nfnl_ct_put(
struct nfnl_ct *ct)
 
  414void nfnl_ct_set_family(
struct nfnl_ct *ct, uint8_t family)
 
  416        ct->ct_family = family;
 
  417        ct->ce_mask |= CT_ATTR_FAMILY;
 
  420uint8_t nfnl_ct_get_family(
const struct nfnl_ct *ct)
 
  422        if (ct->ce_mask & CT_ATTR_FAMILY)
 
  423                return ct->ct_family;
 
  428void nfnl_ct_set_proto(
struct nfnl_ct *ct, uint8_t proto)
 
  430        ct->ct_proto = proto;
 
  431        ct->ce_mask |= CT_ATTR_PROTO;
 
  434int nfnl_ct_test_proto(
const struct nfnl_ct *ct)
 
  436        return !!(ct->ce_mask & CT_ATTR_PROTO);
 
  439uint8_t nfnl_ct_get_proto(
const struct nfnl_ct *ct)
 
  444void nfnl_ct_set_tcp_state(
struct nfnl_ct *ct, uint8_t state)
 
  446        ct->ct_protoinfo.tcp.state = state;
 
  447        ct->ce_mask |= CT_ATTR_TCP_STATE;
 
  450int nfnl_ct_test_tcp_state(
const struct nfnl_ct *ct)
 
  452        return !!(ct->ce_mask & CT_ATTR_TCP_STATE);
 
  455uint8_t nfnl_ct_get_tcp_state(
const struct nfnl_ct *ct)
 
  457        return ct->ct_protoinfo.tcp.state;
 
  460static const struct trans_tbl tcp_states[] = {
 
  461        __ADD(TCP_CONNTRACK_NONE,NONE),
 
  462        __ADD(TCP_CONNTRACK_SYN_SENT,SYN_SENT),
 
  463        __ADD(TCP_CONNTRACK_SYN_RECV,SYN_RECV),
 
  464        __ADD(TCP_CONNTRACK_ESTABLISHED,ESTABLISHED),
 
  465        __ADD(TCP_CONNTRACK_FIN_WAIT,FIN_WAIT),
 
  466        __ADD(TCP_CONNTRACK_CLOSE_WAIT,CLOSE_WAIT),
 
  467        __ADD(TCP_CONNTRACK_LAST_ACK,LAST_ACK),
 
  468        __ADD(TCP_CONNTRACK_TIME_WAIT,TIME_WAIT),
 
  469        __ADD(TCP_CONNTRACK_CLOSE,CLOSE),
 
  470        __ADD(TCP_CONNTRACK_LISTEN,LISTEN),
 
  473char *nfnl_ct_tcp_state2str(uint8_t state, 
char *buf, 
size_t len)
 
  475        return __type2str(state, buf, len, tcp_states, ARRAY_SIZE(tcp_states));
 
  478int nfnl_ct_str2tcp_state(
const char *name)
 
  480        return __str2type(name, tcp_states, ARRAY_SIZE(tcp_states));
 
  483void nfnl_ct_set_status(
struct nfnl_ct *ct, uint32_t status)
 
  485        ct->ct_status_mask |= status;
 
  486        ct->ct_status |= status;
 
  487        ct->ce_mask |= CT_ATTR_STATUS;
 
  490void nfnl_ct_unset_status(
struct nfnl_ct *ct, uint32_t status)
 
  492        ct->ct_status_mask |= status;
 
  493        ct->ct_status &= ~status;
 
  494        ct->ce_mask |= CT_ATTR_STATUS;
 
  497int nfnl_ct_test_status(
const struct nfnl_ct *ct)
 
  499        return !!(ct->ce_mask & CT_ATTR_STATUS);
 
  502uint32_t nfnl_ct_get_status(
const struct nfnl_ct *ct)
 
  504        return ct->ct_status;
 
  507static const struct trans_tbl status_flags[] = {
 
  508        __ADD(IPS_EXPECTED, expected),
 
  509        __ADD(IPS_SEEN_REPLY, seen_reply),
 
  510        __ADD(IPS_ASSURED, assured),
 
  511        __ADD(IPS_CONFIRMED, confirmed),
 
  512        __ADD(IPS_SRC_NAT, snat),
 
  513        __ADD(IPS_DST_NAT, dnat),
 
  514        __ADD(IPS_SEQ_ADJUST, seqadjust),
 
  515        __ADD(IPS_SRC_NAT_DONE, snat_done),
 
  516        __ADD(IPS_DST_NAT_DONE, dnat_done),
 
  517        __ADD(IPS_DYING, dying),
 
  518        __ADD(IPS_FIXED_TIMEOUT, fixed_timeout),
 
  521char * nfnl_ct_status2str(
int flags, 
char *buf, 
size_t len)
 
  523        return __flags2str(flags, buf, len, status_flags,
 
  524                           ARRAY_SIZE(status_flags));
 
  527int nfnl_ct_str2status(
const char *name)
 
  529        return __str2flags(name, status_flags, ARRAY_SIZE(status_flags));
 
  532void nfnl_ct_set_timeout(
struct nfnl_ct *ct, uint32_t timeout)
 
  534        ct->ct_timeout = timeout;
 
  535        ct->ce_mask |= CT_ATTR_TIMEOUT;
 
  538int nfnl_ct_test_timeout(
const struct nfnl_ct *ct)
 
  540        return !!(ct->ce_mask & CT_ATTR_TIMEOUT);
 
  543uint32_t nfnl_ct_get_timeout(
const struct nfnl_ct *ct)
 
  545        return ct->ct_timeout;
 
  548void nfnl_ct_set_mark(
struct nfnl_ct *ct, uint32_t mark)
 
  551        ct->ce_mask |= CT_ATTR_MARK;
 
  554int nfnl_ct_test_mark(
const struct nfnl_ct *ct)
 
  556        return !!(ct->ce_mask & CT_ATTR_MARK);
 
  559uint32_t nfnl_ct_get_mark(
const struct nfnl_ct *ct)
 
  564void nfnl_ct_set_use(
struct nfnl_ct *ct, uint32_t use)
 
  567        ct->ce_mask |= CT_ATTR_USE;
 
  570int nfnl_ct_test_use(
const struct nfnl_ct *ct)
 
  572        return !!(ct->ce_mask & CT_ATTR_USE);
 
  575uint32_t nfnl_ct_get_use(
const struct nfnl_ct *ct)
 
  580void nfnl_ct_set_id(
struct nfnl_ct *ct, uint32_t 
id)
 
  583        ct->ce_mask |= CT_ATTR_ID;
 
  586int nfnl_ct_test_id(
const struct nfnl_ct *ct)
 
  588        return !!(ct->ce_mask & CT_ATTR_ID);
 
  591uint32_t nfnl_ct_get_id(
const struct nfnl_ct *ct)
 
  596void nfnl_ct_set_zone(
struct nfnl_ct *ct, uint16_t zone)
 
  599        ct->ce_mask |= CT_ATTR_ZONE;
 
  602int nfnl_ct_test_zone(
const struct nfnl_ct *ct)
 
  604        return !!(ct->ce_mask & CT_ATTR_ZONE);
 
  607uint16_t nfnl_ct_get_zone(
const struct nfnl_ct *ct)
 
  612static int ct_set_addr(
struct nfnl_ct *ct, 
struct nl_addr *addr,
 
  613                int attr, 
struct nl_addr ** ct_addr)
 
  615        if (ct->ce_mask & CT_ATTR_FAMILY) {
 
  616                if (addr->a_family != ct->ct_family)
 
  617                        return -NLE_AF_MISMATCH;
 
  619                nfnl_ct_set_family(ct, addr->a_family);
 
  631int nfnl_ct_set_src(
struct nfnl_ct *ct, 
int repl, 
struct nl_addr *addr)
 
  633        struct nfnl_ct_dir *dir = repl ? &ct->ct_repl : &ct->ct_orig;
 
  634        int attr = repl ? CT_ATTR_REPL_SRC : CT_ATTR_ORIG_SRC;
 
  635        return ct_set_addr(ct, addr, attr, &dir->src);
 
  638int nfnl_ct_set_dst(
struct nfnl_ct *ct, 
int repl, 
struct nl_addr *addr)
 
  640        struct nfnl_ct_dir *dir = repl ? &ct->ct_repl : &ct->ct_orig;
 
  641        int attr = repl ? CT_ATTR_REPL_DST : CT_ATTR_ORIG_DST;
 
  642        return ct_set_addr(ct, addr, attr, &dir->dst);
 
  645struct nl_addr *nfnl_ct_get_src(
const struct nfnl_ct *ct, 
int repl)
 
  647        const struct nfnl_ct_dir *dir = repl ? &ct->ct_repl : &ct->ct_orig;
 
  648        int attr = repl ? CT_ATTR_REPL_SRC : CT_ATTR_ORIG_SRC;
 
  649        if (!(ct->ce_mask & attr))
 
  654struct nl_addr *nfnl_ct_get_dst(
const struct nfnl_ct *ct, 
int repl)
 
  656        const struct nfnl_ct_dir *dir = repl ? &ct->ct_repl : &ct->ct_orig;
 
  657        int attr = repl ? CT_ATTR_REPL_DST : CT_ATTR_ORIG_DST;
 
  658        if (!(ct->ce_mask & attr))
 
  663void nfnl_ct_set_src_port(
struct nfnl_ct *ct, 
int repl, uint16_t port)
 
  665        struct nfnl_ct_dir *dir = repl ? &ct->ct_repl : &ct->ct_orig;
 
  666        int attr = repl ? CT_ATTR_REPL_SRC_PORT : CT_ATTR_ORIG_SRC_PORT;
 
  668        dir->proto.port.src = port;
 
  672int nfnl_ct_test_src_port(
const struct nfnl_ct *ct, 
int repl)
 
  674        int attr = repl ? CT_ATTR_REPL_SRC_PORT : CT_ATTR_ORIG_SRC_PORT;
 
  675        return !!(ct->ce_mask & attr);
 
  678uint16_t nfnl_ct_get_src_port(
const struct nfnl_ct *ct, 
int repl)
 
  680        const struct nfnl_ct_dir *dir = repl ? &ct->ct_repl : &ct->ct_orig;
 
  682        return dir->proto.port.src;
 
  685void nfnl_ct_set_dst_port(
struct nfnl_ct *ct, 
int repl, uint16_t port)
 
  687        struct nfnl_ct_dir *dir = repl ? &ct->ct_repl : &ct->ct_orig;
 
  688        int attr = repl ? CT_ATTR_REPL_DST_PORT : CT_ATTR_ORIG_DST_PORT;
 
  690        dir->proto.port.dst = port;
 
  694int nfnl_ct_test_dst_port(
const struct nfnl_ct *ct, 
int repl)
 
  696        int attr = repl ? CT_ATTR_REPL_DST_PORT : CT_ATTR_ORIG_DST_PORT;
 
  697        return !!(ct->ce_mask & attr);
 
  700uint16_t nfnl_ct_get_dst_port(
const struct nfnl_ct *ct, 
int repl)
 
  702        const struct nfnl_ct_dir *dir = repl ? &ct->ct_repl : &ct->ct_orig;
 
  704        return dir->proto.port.dst;
 
  707void nfnl_ct_set_icmp_id(
struct nfnl_ct *ct, 
int repl, uint16_t 
id)
 
  709        struct nfnl_ct_dir *dir = repl ? &ct->ct_repl : &ct->ct_orig;
 
  710        int attr = repl ? CT_ATTR_REPL_ICMP_ID : CT_ATTR_ORIG_ICMP_ID;
 
  712        dir->proto.icmp.id = id;
 
  716int nfnl_ct_test_icmp_id(
const struct nfnl_ct *ct, 
int repl)
 
  718        int attr = repl ? CT_ATTR_REPL_ICMP_ID : CT_ATTR_ORIG_ICMP_ID;
 
  719        return !!(ct->ce_mask & attr);
 
  722uint16_t nfnl_ct_get_icmp_id(
const struct nfnl_ct *ct, 
int repl)
 
  724        const struct nfnl_ct_dir *dir = repl ? &ct->ct_repl : &ct->ct_orig;
 
  726        return dir->proto.icmp.id;
 
  729void nfnl_ct_set_icmp_type(
struct nfnl_ct *ct, 
int repl, uint8_t type)
 
  731        struct nfnl_ct_dir *dir = repl ? &ct->ct_repl : &ct->ct_orig;
 
  732        int attr = repl ? CT_ATTR_REPL_ICMP_TYPE : CT_ATTR_ORIG_ICMP_TYPE;
 
  734        dir->proto.icmp.type = type;
 
  738int nfnl_ct_test_icmp_type(
const struct nfnl_ct *ct, 
int repl)
 
  740        int attr = repl ? CT_ATTR_REPL_ICMP_TYPE : CT_ATTR_ORIG_ICMP_TYPE;
 
  741        return !!(ct->ce_mask & attr);
 
  744uint8_t nfnl_ct_get_icmp_type(
const struct nfnl_ct *ct, 
int repl)
 
  746        const struct nfnl_ct_dir *dir = repl ? &ct->ct_repl : &ct->ct_orig;
 
  748        return dir->proto.icmp.type;
 
  751void nfnl_ct_set_icmp_code(
struct nfnl_ct *ct, 
int repl, uint8_t code)
 
  753        struct nfnl_ct_dir *dir = repl ? &ct->ct_repl : &ct->ct_orig;
 
  754        int attr = repl ? CT_ATTR_REPL_ICMP_CODE : CT_ATTR_ORIG_ICMP_CODE;
 
  756        dir->proto.icmp.code = code;
 
  760int nfnl_ct_test_icmp_code(
const struct nfnl_ct *ct, 
int repl)
 
  762        int attr = repl ? CT_ATTR_REPL_ICMP_CODE : CT_ATTR_ORIG_ICMP_CODE;
 
  763        return !!(ct->ce_mask & attr);
 
  766uint8_t nfnl_ct_get_icmp_code(
const struct nfnl_ct *ct, 
int repl)
 
  768        const struct nfnl_ct_dir *dir = repl ? &ct->ct_repl : &ct->ct_orig;
 
  770        return dir->proto.icmp.code;
 
  773void nfnl_ct_set_packets(
struct nfnl_ct *ct, 
int repl, uint64_t packets)
 
  775        struct nfnl_ct_dir *dir = repl ? &ct->ct_repl : &ct->ct_orig;
 
  776        int attr = repl ? CT_ATTR_REPL_PACKETS : CT_ATTR_ORIG_PACKETS;
 
  778        dir->packets = packets;
 
  782int nfnl_ct_test_packets(
const struct nfnl_ct *ct, 
int repl)
 
  784        int attr = repl ? CT_ATTR_REPL_PACKETS : CT_ATTR_ORIG_PACKETS;
 
  785        return !!(ct->ce_mask & attr);
 
  788uint64_t nfnl_ct_get_packets(
const struct nfnl_ct *ct, 
int repl)
 
  790        const struct nfnl_ct_dir *dir = repl ? &ct->ct_repl : &ct->ct_orig;
 
  795void nfnl_ct_set_bytes(
struct nfnl_ct *ct, 
int repl, uint64_t bytes)
 
  797        struct nfnl_ct_dir *dir = repl ? &ct->ct_repl : &ct->ct_orig;
 
  798        int attr = repl ? CT_ATTR_REPL_BYTES : CT_ATTR_ORIG_BYTES;
 
  804int nfnl_ct_test_bytes(
const struct nfnl_ct *ct, 
int repl)
 
  806        int attr = repl ? CT_ATTR_REPL_BYTES : CT_ATTR_ORIG_BYTES;
 
  807        return !!(ct->ce_mask & attr);
 
  810uint64_t nfnl_ct_get_bytes(
const struct nfnl_ct *ct, 
int repl)
 
  812        const struct nfnl_ct_dir *dir = repl ? &ct->ct_repl : &ct->ct_orig;
 
  817void nfnl_ct_set_timestamp(
struct nfnl_ct *ct, uint64_t start, uint64_t stop)
 
  819        ct->ct_tstamp.start = start;
 
  820        ct->ct_tstamp.stop = stop;
 
  821        ct->ce_mask |= CT_ATTR_TIMESTAMP;
 
  824int nfnl_ct_test_timestamp(
const struct nfnl_ct *ct)
 
  826        return !!(ct->ce_mask & CT_ATTR_TIMESTAMP);
 
  831        return &ct->ct_tstamp;
 
  836struct nl_object_ops ct_obj_ops = {
 
  837        .oo_name                = 
"netfilter/ct",
 
  838        .oo_size                = 
sizeof(
struct nfnl_ct),
 
  839        .oo_free_data           = ct_free_data,
 
  840        .oo_clone               = ct_clone,
 
  846        .oo_compare             = ct_compare,
 
  847        .oo_attrs2str           = ct_attrs2str,
 
struct nl_addr * nl_addr_get(struct nl_addr *addr)
Increase the reference counter of an abstract address.
 
int nl_addr_cmp(const struct nl_addr *a, const struct nl_addr *b)
Compare abstract addresses.
 
struct nl_addr * nl_addr_clone(const struct nl_addr *addr)
Clone existing abstract address object.
 
char * nl_addr2str(const struct nl_addr *addr, char *buf, size_t size)
Convert abstract address object to character string.
 
void nl_addr_put(struct nl_addr *addr)
Decrease the reference counter of an abstract address.
 
void nl_object_put(struct nl_object *obj)
Release a reference from an object.
 
void nl_object_get(struct nl_object *obj)
Acquire a reference on a object.
 
struct nl_object * nl_object_alloc(struct nl_object_ops *ops)
Allocate a new object of kind specified by the operations handle.
 
void nl_dump(struct nl_dump_params *params, const char *fmt,...)
Dump a formatted character string.
 
double nl_cancel_down_bytes(unsigned long long l, char **unit)
Cancel down a byte counter.
 
void nl_new_line(struct nl_dump_params *params)
Handle a new line while dumping.
 
char * nl_msec2str(uint64_t msec, char *buf, size_t len)
Convert milliseconds to a character string.
 
@ NL_DUMP_STATS
Dump all attributes including statistics.
 
@ NL_DUMP_LINE
Dump object briefly on one line.
 
@ NL_DUMP_DETAILS
Dump all attributes but no statistics.