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 * 98a3efffa5b3fde252675239914118664d36a2c24Thomas Graf * Copyright (c) 2003-2008 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) 788a3efffa5b3fde252675239914118664d36a2c24Thomas Graf return -NLE_NOMEM; 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) 858a3efffa5b3fde252675239914118664d36a2c24Thomas Graf return -NLE_NOMEM; 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) 928a3efffa5b3fde252675239914118664d36a2c24Thomas Graf return -NLE_NOMEM; 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) 998a3efffa5b3fde252675239914118664d36a2c24Thomas Graf return -NLE_NOMEM; 10044d362409d5469aed47d19e7908d19bd194493aThomas Graf dst->ct_repl.dst = addr; 10144d362409d5469aed47d19e7908d19bd194493aThomas Graf } 10244d362409d5469aed47d19e7908d19bd194493aThomas Graf 10344d362409d5469aed47d19e7908d19bd194493aThomas Graf return 0; 10444d362409d5469aed47d19e7908d19bd194493aThomas Graf} 10544d362409d5469aed47d19e7908d19bd194493aThomas Graf 106337fbd24cad1f5cf9c8b4287a75f2c69f088adceThomas Grafstatic void dump_addr(struct nl_dump_params *p, struct nl_addr *addr, int port) 10744d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 108337fbd24cad1f5cf9c8b4287a75f2c69f088adceThomas Graf char buf[64]; 10944d362409d5469aed47d19e7908d19bd194493aThomas Graf 11044d362409d5469aed47d19e7908d19bd194493aThomas Graf if (addr) 111337fbd24cad1f5cf9c8b4287a75f2c69f088adceThomas Graf nl_dump(p, "%s", nl_addr2str(addr, buf, sizeof(buf))); 11244d362409d5469aed47d19e7908d19bd194493aThomas Graf 113337fbd24cad1f5cf9c8b4287a75f2c69f088adceThomas Graf if (port) 114337fbd24cad1f5cf9c8b4287a75f2c69f088adceThomas Graf nl_dump(p, ":%u ", port); 115337fbd24cad1f5cf9c8b4287a75f2c69f088adceThomas Graf else if (addr) 116337fbd24cad1f5cf9c8b4287a75f2c69f088adceThomas Graf nl_dump(p, " "); 117337fbd24cad1f5cf9c8b4287a75f2c69f088adceThomas Graf} 118337fbd24cad1f5cf9c8b4287a75f2c69f088adceThomas Graf 119337fbd24cad1f5cf9c8b4287a75f2c69f088adceThomas Grafstatic void dump_icmp(struct nl_dump_params *p, struct nfnl_ct *ct, int reply) 120337fbd24cad1f5cf9c8b4287a75f2c69f088adceThomas Graf{ 121337fbd24cad1f5cf9c8b4287a75f2c69f088adceThomas Graf if (nfnl_ct_test_icmp_type(ct, reply)) 122337fbd24cad1f5cf9c8b4287a75f2c69f088adceThomas Graf nl_dump(p, "icmp type %d ", nfnl_ct_get_icmp_type(ct, reply)); 123337fbd24cad1f5cf9c8b4287a75f2c69f088adceThomas Graf 124337fbd24cad1f5cf9c8b4287a75f2c69f088adceThomas Graf if (nfnl_ct_test_icmp_type(ct, reply)) 125337fbd24cad1f5cf9c8b4287a75f2c69f088adceThomas Graf nl_dump(p, "code %d ", nfnl_ct_get_icmp_code(ct, reply)); 126337fbd24cad1f5cf9c8b4287a75f2c69f088adceThomas Graf 127337fbd24cad1f5cf9c8b4287a75f2c69f088adceThomas Graf if (nfnl_ct_test_icmp_type(ct, reply)) 128337fbd24cad1f5cf9c8b4287a75f2c69f088adceThomas Graf nl_dump(p, "id %d ", nfnl_ct_get_icmp_id(ct, reply)); 129337fbd24cad1f5cf9c8b4287a75f2c69f088adceThomas Graf} 130337fbd24cad1f5cf9c8b4287a75f2c69f088adceThomas Graf 131337fbd24cad1f5cf9c8b4287a75f2c69f088adceThomas Grafstatic void ct_dump_tuples(struct nfnl_ct *ct, struct nl_dump_params *p) 132337fbd24cad1f5cf9c8b4287a75f2c69f088adceThomas Graf{ 133337fbd24cad1f5cf9c8b4287a75f2c69f088adceThomas Graf struct nl_addr *orig_src, *orig_dst, *reply_src, *reply_dst; 134337fbd24cad1f5cf9c8b4287a75f2c69f088adceThomas Graf int orig_sport = 0, orig_dport = 0, reply_sport = 0, reply_dport = 0; 135337fbd24cad1f5cf9c8b4287a75f2c69f088adceThomas Graf int sync = 0; 136337fbd24cad1f5cf9c8b4287a75f2c69f088adceThomas Graf 137337fbd24cad1f5cf9c8b4287a75f2c69f088adceThomas Graf orig_src = nfnl_ct_get_src(ct, 0); 138337fbd24cad1f5cf9c8b4287a75f2c69f088adceThomas Graf orig_dst = nfnl_ct_get_dst(ct, 0); 139337fbd24cad1f5cf9c8b4287a75f2c69f088adceThomas Graf reply_src = nfnl_ct_get_src(ct, 1); 140337fbd24cad1f5cf9c8b4287a75f2c69f088adceThomas Graf reply_dst = nfnl_ct_get_dst(ct, 1); 14144d362409d5469aed47d19e7908d19bd194493aThomas Graf 142337fbd24cad1f5cf9c8b4287a75f2c69f088adceThomas Graf if (nfnl_ct_test_src_port(ct, 0)) 143337fbd24cad1f5cf9c8b4287a75f2c69f088adceThomas Graf orig_sport = nfnl_ct_get_src_port(ct, 0); 14444d362409d5469aed47d19e7908d19bd194493aThomas Graf 145337fbd24cad1f5cf9c8b4287a75f2c69f088adceThomas Graf if (nfnl_ct_test_dst_port(ct, 0)) 146337fbd24cad1f5cf9c8b4287a75f2c69f088adceThomas Graf orig_dport = nfnl_ct_get_dst_port(ct, 0); 14744d362409d5469aed47d19e7908d19bd194493aThomas Graf 148337fbd24cad1f5cf9c8b4287a75f2c69f088adceThomas Graf if (nfnl_ct_test_src_port(ct, 1)) 149337fbd24cad1f5cf9c8b4287a75f2c69f088adceThomas Graf reply_sport = nfnl_ct_get_src_port(ct, 1); 150337fbd24cad1f5cf9c8b4287a75f2c69f088adceThomas Graf 151337fbd24cad1f5cf9c8b4287a75f2c69f088adceThomas Graf if (nfnl_ct_test_dst_port(ct, 1)) 152337fbd24cad1f5cf9c8b4287a75f2c69f088adceThomas Graf reply_dport = nfnl_ct_get_dst_port(ct, 1); 153337fbd24cad1f5cf9c8b4287a75f2c69f088adceThomas Graf 154337fbd24cad1f5cf9c8b4287a75f2c69f088adceThomas Graf if (orig_src && orig_dst && reply_src && reply_dst && 155337fbd24cad1f5cf9c8b4287a75f2c69f088adceThomas Graf orig_sport == reply_dport && orig_dport == reply_sport && 156337fbd24cad1f5cf9c8b4287a75f2c69f088adceThomas Graf !nl_addr_cmp(orig_src, reply_dst) && 157337fbd24cad1f5cf9c8b4287a75f2c69f088adceThomas Graf !nl_addr_cmp(orig_dst, reply_src)) 158337fbd24cad1f5cf9c8b4287a75f2c69f088adceThomas Graf sync = 1; 159337fbd24cad1f5cf9c8b4287a75f2c69f088adceThomas Graf 160337fbd24cad1f5cf9c8b4287a75f2c69f088adceThomas Graf dump_addr(p, orig_src, orig_sport); 161337fbd24cad1f5cf9c8b4287a75f2c69f088adceThomas Graf nl_dump(p, sync ? "<-> " : "-> "); 162337fbd24cad1f5cf9c8b4287a75f2c69f088adceThomas Graf dump_addr(p, orig_dst, orig_dport); 163337fbd24cad1f5cf9c8b4287a75f2c69f088adceThomas Graf dump_icmp(p, ct, 0); 164337fbd24cad1f5cf9c8b4287a75f2c69f088adceThomas Graf 165337fbd24cad1f5cf9c8b4287a75f2c69f088adceThomas Graf if (!sync) { 166337fbd24cad1f5cf9c8b4287a75f2c69f088adceThomas Graf dump_addr(p, reply_src, reply_sport); 167337fbd24cad1f5cf9c8b4287a75f2c69f088adceThomas Graf nl_dump(p, "<- "); 168337fbd24cad1f5cf9c8b4287a75f2c69f088adceThomas Graf dump_addr(p, reply_dst, reply_dport); 169337fbd24cad1f5cf9c8b4287a75f2c69f088adceThomas Graf dump_icmp(p, ct, 1); 170337fbd24cad1f5cf9c8b4287a75f2c69f088adceThomas Graf } 17144d362409d5469aed47d19e7908d19bd194493aThomas Graf} 17244d362409d5469aed47d19e7908d19bd194493aThomas Graf 17344d362409d5469aed47d19e7908d19bd194493aThomas Graf/* Compatible with /proc/net/nf_conntrack */ 174d84430702496f617c01c5e2d27d0e82e02390bb7Thomas Grafstatic void ct_dump_line(struct nl_object *a, struct nl_dump_params *p) 17544d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 17644d362409d5469aed47d19e7908d19bd194493aThomas Graf struct nfnl_ct *ct = (struct nfnl_ct *) a; 17744d362409d5469aed47d19e7908d19bd194493aThomas Graf char buf[64]; 17844d362409d5469aed47d19e7908d19bd194493aThomas Graf 179d84430702496f617c01c5e2d27d0e82e02390bb7Thomas Graf nl_new_line(p); 180d84430702496f617c01c5e2d27d0e82e02390bb7Thomas Graf 181337fbd24cad1f5cf9c8b4287a75f2c69f088adceThomas Graf if (nfnl_ct_test_proto(ct)) 182337fbd24cad1f5cf9c8b4287a75f2c69f088adceThomas Graf nl_dump(p, "%s ", 183337fbd24cad1f5cf9c8b4287a75f2c69f088adceThomas Graf nl_ip_proto2str(nfnl_ct_get_proto(ct), buf, sizeof(buf))); 18444d362409d5469aed47d19e7908d19bd194493aThomas Graf 18544d362409d5469aed47d19e7908d19bd194493aThomas Graf if (nfnl_ct_test_tcp_state(ct)) 186337fbd24cad1f5cf9c8b4287a75f2c69f088adceThomas Graf nl_dump(p, "%s ", 18744d362409d5469aed47d19e7908d19bd194493aThomas Graf nfnl_ct_tcp_state2str(nfnl_ct_get_tcp_state(ct), 18844d362409d5469aed47d19e7908d19bd194493aThomas Graf buf, sizeof(buf))); 18944d362409d5469aed47d19e7908d19bd194493aThomas Graf 190337fbd24cad1f5cf9c8b4287a75f2c69f088adceThomas Graf ct_dump_tuples(ct, p); 19144d362409d5469aed47d19e7908d19bd194493aThomas Graf 192337fbd24cad1f5cf9c8b4287a75f2c69f088adceThomas Graf if (nfnl_ct_test_mark(ct) && nfnl_ct_get_mark(ct)) 193337fbd24cad1f5cf9c8b4287a75f2c69f088adceThomas Graf nl_dump(p, "mark %u ", nfnl_ct_get_mark(ct)); 19444d362409d5469aed47d19e7908d19bd194493aThomas Graf 195337fbd24cad1f5cf9c8b4287a75f2c69f088adceThomas Graf nl_dump(p, "\n"); 196337fbd24cad1f5cf9c8b4287a75f2c69f088adceThomas Graf} 19744d362409d5469aed47d19e7908d19bd194493aThomas Graf 198d84430702496f617c01c5e2d27d0e82e02390bb7Thomas Grafstatic void ct_dump_details(struct nl_object *a, struct nl_dump_params *p) 199337fbd24cad1f5cf9c8b4287a75f2c69f088adceThomas Graf{ 200337fbd24cad1f5cf9c8b4287a75f2c69f088adceThomas Graf struct nfnl_ct *ct = (struct nfnl_ct *) a; 201337fbd24cad1f5cf9c8b4287a75f2c69f088adceThomas Graf char buf[64]; 202337fbd24cad1f5cf9c8b4287a75f2c69f088adceThomas Graf int fp = 0; 203337fbd24cad1f5cf9c8b4287a75f2c69f088adceThomas Graf 204d84430702496f617c01c5e2d27d0e82e02390bb7Thomas Graf ct_dump_line(a, p); 205337fbd24cad1f5cf9c8b4287a75f2c69f088adceThomas Graf 206337fbd24cad1f5cf9c8b4287a75f2c69f088adceThomas Graf nl_dump(p, " id 0x%x ", ct->ct_id); 207337fbd24cad1f5cf9c8b4287a75f2c69f088adceThomas Graf nl_dump_line(p, "family %s ", 208337fbd24cad1f5cf9c8b4287a75f2c69f088adceThomas Graf nl_af2str(ct->ct_family, buf, sizeof(buf))); 20944d362409d5469aed47d19e7908d19bd194493aThomas Graf 21044d362409d5469aed47d19e7908d19bd194493aThomas Graf if (nfnl_ct_test_use(ct)) 211337fbd24cad1f5cf9c8b4287a75f2c69f088adceThomas Graf nl_dump(p, "refcnt %u ", nfnl_ct_get_use(ct)); 21244d362409d5469aed47d19e7908d19bd194493aThomas Graf 213337fbd24cad1f5cf9c8b4287a75f2c69f088adceThomas Graf if (nfnl_ct_test_timeout(ct)) { 214337fbd24cad1f5cf9c8b4287a75f2c69f088adceThomas Graf uint64_t timeout_ms = nfnl_ct_get_timeout(ct) * 1000UL; 215337fbd24cad1f5cf9c8b4287a75f2c69f088adceThomas Graf nl_dump(p, "timeout %s ", 216337fbd24cad1f5cf9c8b4287a75f2c69f088adceThomas Graf nl_msec2str(timeout_ms, buf, sizeof(buf))); 217337fbd24cad1f5cf9c8b4287a75f2c69f088adceThomas Graf } 21844d362409d5469aed47d19e7908d19bd194493aThomas Graf 219337fbd24cad1f5cf9c8b4287a75f2c69f088adceThomas Graf if (ct->ct_status) 220337fbd24cad1f5cf9c8b4287a75f2c69f088adceThomas Graf nl_dump(p, "<"); 221337fbd24cad1f5cf9c8b4287a75f2c69f088adceThomas Graf 222337fbd24cad1f5cf9c8b4287a75f2c69f088adceThomas Graf#define PRINT_FLAG(str) \ 223337fbd24cad1f5cf9c8b4287a75f2c69f088adceThomas Graf { nl_dump(p, "%s%s", fp++ ? "," : "", (str)); } 224337fbd24cad1f5cf9c8b4287a75f2c69f088adceThomas Graf 225337fbd24cad1f5cf9c8b4287a75f2c69f088adceThomas Graf if (ct->ct_status & IPS_EXPECTED) 226337fbd24cad1f5cf9c8b4287a75f2c69f088adceThomas Graf PRINT_FLAG("EXPECTED"); 227337fbd24cad1f5cf9c8b4287a75f2c69f088adceThomas Graf if (!(ct->ct_status & IPS_SEEN_REPLY)) 228337fbd24cad1f5cf9c8b4287a75f2c69f088adceThomas Graf PRINT_FLAG("NOREPLY"); 229337fbd24cad1f5cf9c8b4287a75f2c69f088adceThomas Graf if (ct->ct_status & IPS_ASSURED) 230337fbd24cad1f5cf9c8b4287a75f2c69f088adceThomas Graf PRINT_FLAG("ASSURED"); 231337fbd24cad1f5cf9c8b4287a75f2c69f088adceThomas Graf if (!(ct->ct_status & IPS_CONFIRMED)) 232337fbd24cad1f5cf9c8b4287a75f2c69f088adceThomas Graf PRINT_FLAG("NOTSENT"); 233337fbd24cad1f5cf9c8b4287a75f2c69f088adceThomas Graf if (ct->ct_status & IPS_SRC_NAT) 234337fbd24cad1f5cf9c8b4287a75f2c69f088adceThomas Graf PRINT_FLAG("SNAT"); 235337fbd24cad1f5cf9c8b4287a75f2c69f088adceThomas Graf if (ct->ct_status & IPS_DST_NAT) 236337fbd24cad1f5cf9c8b4287a75f2c69f088adceThomas Graf PRINT_FLAG("DNAT"); 237337fbd24cad1f5cf9c8b4287a75f2c69f088adceThomas Graf if (ct->ct_status & IPS_SEQ_ADJUST) 238337fbd24cad1f5cf9c8b4287a75f2c69f088adceThomas Graf PRINT_FLAG("SEQADJUST"); 239337fbd24cad1f5cf9c8b4287a75f2c69f088adceThomas Graf if (!(ct->ct_status & IPS_SRC_NAT_DONE)) 240337fbd24cad1f5cf9c8b4287a75f2c69f088adceThomas Graf PRINT_FLAG("SNAT_INIT"); 241337fbd24cad1f5cf9c8b4287a75f2c69f088adceThomas Graf if (!(ct->ct_status & IPS_DST_NAT_DONE)) 242337fbd24cad1f5cf9c8b4287a75f2c69f088adceThomas Graf PRINT_FLAG("DNAT_INIT"); 243337fbd24cad1f5cf9c8b4287a75f2c69f088adceThomas Graf if (ct->ct_status & IPS_DYING) 244337fbd24cad1f5cf9c8b4287a75f2c69f088adceThomas Graf PRINT_FLAG("DYING"); 245337fbd24cad1f5cf9c8b4287a75f2c69f088adceThomas Graf if (ct->ct_status & IPS_FIXED_TIMEOUT) 246337fbd24cad1f5cf9c8b4287a75f2c69f088adceThomas Graf PRINT_FLAG("FIXED_TIMEOUT"); 247337fbd24cad1f5cf9c8b4287a75f2c69f088adceThomas Graf#undef PRINT_FLAG 248337fbd24cad1f5cf9c8b4287a75f2c69f088adceThomas Graf 249337fbd24cad1f5cf9c8b4287a75f2c69f088adceThomas Graf if (ct->ct_status) 250337fbd24cad1f5cf9c8b4287a75f2c69f088adceThomas Graf nl_dump(p, ">"); 251337fbd24cad1f5cf9c8b4287a75f2c69f088adceThomas Graf nl_dump(p, "\n"); 252337fbd24cad1f5cf9c8b4287a75f2c69f088adceThomas Graf} 253337fbd24cad1f5cf9c8b4287a75f2c69f088adceThomas Graf 254d84430702496f617c01c5e2d27d0e82e02390bb7Thomas Grafstatic void ct_dump_stats(struct nl_object *a, struct nl_dump_params *p) 255337fbd24cad1f5cf9c8b4287a75f2c69f088adceThomas Graf{ 256337fbd24cad1f5cf9c8b4287a75f2c69f088adceThomas Graf struct nfnl_ct *ct = (struct nfnl_ct *) a; 257337fbd24cad1f5cf9c8b4287a75f2c69f088adceThomas Graf double res; 258337fbd24cad1f5cf9c8b4287a75f2c69f088adceThomas Graf char *unit; 259337fbd24cad1f5cf9c8b4287a75f2c69f088adceThomas Graf 260d84430702496f617c01c5e2d27d0e82e02390bb7Thomas Graf ct_dump_details(a, p); 261d84430702496f617c01c5e2d27d0e82e02390bb7Thomas Graf 262d84430702496f617c01c5e2d27d0e82e02390bb7Thomas Graf nl_dump_line(p, " # packets volume\n"); 263337fbd24cad1f5cf9c8b4287a75f2c69f088adceThomas Graf 264337fbd24cad1f5cf9c8b4287a75f2c69f088adceThomas Graf res = nl_cancel_down_bytes(nfnl_ct_get_bytes(ct, 1), &unit); 265d84430702496f617c01c5e2d27d0e82e02390bb7Thomas Graf nl_dump_line(p, " rx %10llu %7.2f %s\n", 266337fbd24cad1f5cf9c8b4287a75f2c69f088adceThomas Graf nfnl_ct_get_packets(ct, 1), res, unit); 267337fbd24cad1f5cf9c8b4287a75f2c69f088adceThomas Graf 268337fbd24cad1f5cf9c8b4287a75f2c69f088adceThomas Graf res = nl_cancel_down_bytes(nfnl_ct_get_bytes(ct, 0), &unit); 269d84430702496f617c01c5e2d27d0e82e02390bb7Thomas Graf nl_dump_line(p, " tx %10llu %7.2f %s\n", 270337fbd24cad1f5cf9c8b4287a75f2c69f088adceThomas Graf nfnl_ct_get_packets(ct, 0), res, unit); 27144d362409d5469aed47d19e7908d19bd194493aThomas Graf} 27244d362409d5469aed47d19e7908d19bd194493aThomas Graf 27344d362409d5469aed47d19e7908d19bd194493aThomas Grafstatic int ct_compare(struct nl_object *_a, struct nl_object *_b, 27444d362409d5469aed47d19e7908d19bd194493aThomas Graf uint32_t attrs, int flags) 27544d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 27644d362409d5469aed47d19e7908d19bd194493aThomas Graf struct nfnl_ct *a = (struct nfnl_ct *) _a; 27744d362409d5469aed47d19e7908d19bd194493aThomas Graf struct nfnl_ct *b = (struct nfnl_ct *) _b; 27844d362409d5469aed47d19e7908d19bd194493aThomas Graf int diff = 0; 27944d362409d5469aed47d19e7908d19bd194493aThomas Graf 28044d362409d5469aed47d19e7908d19bd194493aThomas Graf#define CT_DIFF(ATTR, EXPR) ATTR_DIFF(attrs, CT_ATTR_##ATTR, a, b, EXPR) 28144d362409d5469aed47d19e7908d19bd194493aThomas Graf#define CT_DIFF_VAL(ATTR, FIELD) CT_DIFF(ATTR, a->FIELD != b->FIELD) 28244d362409d5469aed47d19e7908d19bd194493aThomas Graf#define CT_DIFF_ADDR(ATTR, FIELD) \ 283535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf ((flags & LOOSE_COMPARISON) \ 28444d362409d5469aed47d19e7908d19bd194493aThomas Graf ? CT_DIFF(ATTR, nl_addr_cmp_prefix(a->FIELD, b->FIELD)) \ 28544d362409d5469aed47d19e7908d19bd194493aThomas Graf : CT_DIFF(ATTR, nl_addr_cmp(a->FIELD, b->FIELD))) 28644d362409d5469aed47d19e7908d19bd194493aThomas Graf 28744d362409d5469aed47d19e7908d19bd194493aThomas Graf diff |= CT_DIFF_VAL(FAMILY, ct_family); 28844d362409d5469aed47d19e7908d19bd194493aThomas Graf diff |= CT_DIFF_VAL(PROTO, ct_proto); 28944d362409d5469aed47d19e7908d19bd194493aThomas Graf diff |= CT_DIFF_VAL(TCP_STATE, ct_protoinfo.tcp.state); 29044d362409d5469aed47d19e7908d19bd194493aThomas Graf diff |= CT_DIFF_VAL(TIMEOUT, ct_timeout); 29144d362409d5469aed47d19e7908d19bd194493aThomas Graf diff |= CT_DIFF_VAL(MARK, ct_mark); 29244d362409d5469aed47d19e7908d19bd194493aThomas Graf diff |= CT_DIFF_VAL(USE, ct_use); 29344d362409d5469aed47d19e7908d19bd194493aThomas Graf diff |= CT_DIFF_VAL(ID, ct_id); 29444d362409d5469aed47d19e7908d19bd194493aThomas Graf diff |= CT_DIFF_ADDR(ORIG_SRC, ct_orig.src); 29544d362409d5469aed47d19e7908d19bd194493aThomas Graf diff |= CT_DIFF_ADDR(ORIG_DST, ct_orig.dst); 29644d362409d5469aed47d19e7908d19bd194493aThomas Graf diff |= CT_DIFF_VAL(ORIG_SRC_PORT, ct_orig.proto.port.src); 29744d362409d5469aed47d19e7908d19bd194493aThomas Graf diff |= CT_DIFF_VAL(ORIG_DST_PORT, ct_orig.proto.port.dst); 29844d362409d5469aed47d19e7908d19bd194493aThomas Graf diff |= CT_DIFF_VAL(ORIG_ICMP_ID, ct_orig.proto.icmp.id); 29944d362409d5469aed47d19e7908d19bd194493aThomas Graf diff |= CT_DIFF_VAL(ORIG_ICMP_TYPE, ct_orig.proto.icmp.type); 30044d362409d5469aed47d19e7908d19bd194493aThomas Graf diff |= CT_DIFF_VAL(ORIG_ICMP_CODE, ct_orig.proto.icmp.code); 30144d362409d5469aed47d19e7908d19bd194493aThomas Graf diff |= CT_DIFF_VAL(ORIG_PACKETS, ct_orig.packets); 30244d362409d5469aed47d19e7908d19bd194493aThomas Graf diff |= CT_DIFF_VAL(ORIG_BYTES, ct_orig.bytes); 30344d362409d5469aed47d19e7908d19bd194493aThomas Graf diff |= CT_DIFF_ADDR(REPL_SRC, ct_repl.src); 304104e158bd578bceacf37ba24dd1a1a907fc53d05Philip Craig diff |= CT_DIFF_ADDR(REPL_DST, ct_repl.dst); 30544d362409d5469aed47d19e7908d19bd194493aThomas Graf diff |= CT_DIFF_VAL(REPL_SRC_PORT, ct_repl.proto.port.src); 30644d362409d5469aed47d19e7908d19bd194493aThomas Graf diff |= CT_DIFF_VAL(REPL_DST_PORT, ct_repl.proto.port.dst); 30744d362409d5469aed47d19e7908d19bd194493aThomas Graf diff |= CT_DIFF_VAL(REPL_ICMP_ID, ct_repl.proto.icmp.id); 30844d362409d5469aed47d19e7908d19bd194493aThomas Graf diff |= CT_DIFF_VAL(REPL_ICMP_TYPE, ct_repl.proto.icmp.type); 30944d362409d5469aed47d19e7908d19bd194493aThomas Graf diff |= CT_DIFF_VAL(REPL_ICMP_CODE, ct_repl.proto.icmp.code); 31044d362409d5469aed47d19e7908d19bd194493aThomas Graf diff |= CT_DIFF_VAL(REPL_PACKETS, ct_repl.packets); 31144d362409d5469aed47d19e7908d19bd194493aThomas Graf diff |= CT_DIFF_VAL(REPL_BYTES, ct_repl.bytes); 31244d362409d5469aed47d19e7908d19bd194493aThomas Graf 313535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf if (flags & LOOSE_COMPARISON) 314cbe8902265ccc9f6aa6453aeb3a2a4631ed0eb01Philip Craig diff |= CT_DIFF(STATUS, (a->ct_status ^ b->ct_status) & 315cbe8902265ccc9f6aa6453aeb3a2a4631ed0eb01Philip Craig b->ct_status_mask); 316cbe8902265ccc9f6aa6453aeb3a2a4631ed0eb01Philip Craig else 317cbe8902265ccc9f6aa6453aeb3a2a4631ed0eb01Philip Craig diff |= CT_DIFF(STATUS, a->ct_status != b->ct_status); 318cbe8902265ccc9f6aa6453aeb3a2a4631ed0eb01Philip Craig 31944d362409d5469aed47d19e7908d19bd194493aThomas Graf#undef CT_DIFF 32044d362409d5469aed47d19e7908d19bd194493aThomas Graf#undef CT_DIFF_VAL 32144d362409d5469aed47d19e7908d19bd194493aThomas Graf#undef CT_DIFF_ADDR 32244d362409d5469aed47d19e7908d19bd194493aThomas Graf 32344d362409d5469aed47d19e7908d19bd194493aThomas Graf return diff; 32444d362409d5469aed47d19e7908d19bd194493aThomas Graf} 32544d362409d5469aed47d19e7908d19bd194493aThomas Graf 32644d362409d5469aed47d19e7908d19bd194493aThomas Grafstatic struct trans_tbl ct_attrs[] = { 32744d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(CT_ATTR_FAMILY, family) 32844d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(CT_ATTR_PROTO, proto) 32944d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(CT_ATTR_TCP_STATE, tcpstate) 33044d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(CT_ATTR_STATUS, status) 33144d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(CT_ATTR_TIMEOUT, timeout) 33244d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(CT_ATTR_MARK, mark) 33344d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(CT_ATTR_USE, use) 33444d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(CT_ATTR_ID, id) 33544d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(CT_ATTR_ORIG_SRC, origsrc) 33644d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(CT_ATTR_ORIG_DST, origdst) 33744d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(CT_ATTR_ORIG_SRC_PORT, origsrcport) 33844d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(CT_ATTR_ORIG_DST_PORT, origdstport) 33944d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(CT_ATTR_ORIG_ICMP_ID, origicmpid) 34044d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(CT_ATTR_ORIG_ICMP_TYPE, origicmptype) 34144d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(CT_ATTR_ORIG_ICMP_CODE, origicmpcode) 34244d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(CT_ATTR_ORIG_PACKETS, origpackets) 34344d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(CT_ATTR_ORIG_BYTES, origbytes) 34444d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(CT_ATTR_REPL_SRC, replysrc) 34544d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(CT_ATTR_REPL_DST, replydst) 34644d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(CT_ATTR_REPL_SRC_PORT, replysrcport) 34744d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(CT_ATTR_REPL_DST_PORT, replydstport) 34844d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(CT_ATTR_REPL_ICMP_ID, replyicmpid) 34944d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(CT_ATTR_REPL_ICMP_TYPE, replyicmptype) 35044d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(CT_ATTR_REPL_ICMP_CODE, replyicmpcode) 35144d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(CT_ATTR_REPL_PACKETS, replypackets) 35244d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(CT_ATTR_REPL_BYTES, replybytes) 35344d362409d5469aed47d19e7908d19bd194493aThomas Graf}; 35444d362409d5469aed47d19e7908d19bd194493aThomas Graf 35544d362409d5469aed47d19e7908d19bd194493aThomas Grafstatic char *ct_attrs2str(int attrs, char *buf, size_t len) 35644d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 35744d362409d5469aed47d19e7908d19bd194493aThomas Graf return __flags2str(attrs, buf, len, ct_attrs, ARRAY_SIZE(ct_attrs)); 35844d362409d5469aed47d19e7908d19bd194493aThomas Graf} 35944d362409d5469aed47d19e7908d19bd194493aThomas Graf 36044d362409d5469aed47d19e7908d19bd194493aThomas Graf/** 36144d362409d5469aed47d19e7908d19bd194493aThomas Graf * @name Allocation/Freeing 36244d362409d5469aed47d19e7908d19bd194493aThomas Graf * @{ 36344d362409d5469aed47d19e7908d19bd194493aThomas Graf */ 36444d362409d5469aed47d19e7908d19bd194493aThomas Graf 36544d362409d5469aed47d19e7908d19bd194493aThomas Grafstruct nfnl_ct *nfnl_ct_alloc(void) 36644d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 36744d362409d5469aed47d19e7908d19bd194493aThomas Graf return (struct nfnl_ct *) nl_object_alloc(&ct_obj_ops); 36844d362409d5469aed47d19e7908d19bd194493aThomas Graf} 36944d362409d5469aed47d19e7908d19bd194493aThomas Graf 37044d362409d5469aed47d19e7908d19bd194493aThomas Grafvoid nfnl_ct_get(struct nfnl_ct *ct) 37144d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 37244d362409d5469aed47d19e7908d19bd194493aThomas Graf nl_object_get((struct nl_object *) ct); 37344d362409d5469aed47d19e7908d19bd194493aThomas Graf} 37444d362409d5469aed47d19e7908d19bd194493aThomas Graf 37544d362409d5469aed47d19e7908d19bd194493aThomas Grafvoid nfnl_ct_put(struct nfnl_ct *ct) 37644d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 37744d362409d5469aed47d19e7908d19bd194493aThomas Graf nl_object_put((struct nl_object *) ct); 37844d362409d5469aed47d19e7908d19bd194493aThomas Graf} 37944d362409d5469aed47d19e7908d19bd194493aThomas Graf 38044d362409d5469aed47d19e7908d19bd194493aThomas Graf/** @} */ 38144d362409d5469aed47d19e7908d19bd194493aThomas Graf 38244d362409d5469aed47d19e7908d19bd194493aThomas Graf/** 38344d362409d5469aed47d19e7908d19bd194493aThomas Graf * @name Attributes 38444d362409d5469aed47d19e7908d19bd194493aThomas Graf * @{ 38544d362409d5469aed47d19e7908d19bd194493aThomas Graf */ 38644d362409d5469aed47d19e7908d19bd194493aThomas Graf 38744d362409d5469aed47d19e7908d19bd194493aThomas Grafvoid nfnl_ct_set_family(struct nfnl_ct *ct, uint8_t family) 38844d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 38944d362409d5469aed47d19e7908d19bd194493aThomas Graf ct->ct_family = family; 39044d362409d5469aed47d19e7908d19bd194493aThomas Graf ct->ce_mask |= CT_ATTR_FAMILY; 39144d362409d5469aed47d19e7908d19bd194493aThomas Graf} 39244d362409d5469aed47d19e7908d19bd194493aThomas Graf 39344d362409d5469aed47d19e7908d19bd194493aThomas Grafuint8_t nfnl_ct_get_family(const struct nfnl_ct *ct) 39444d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 39544d362409d5469aed47d19e7908d19bd194493aThomas Graf if (ct->ce_mask & CT_ATTR_FAMILY) 39644d362409d5469aed47d19e7908d19bd194493aThomas Graf return ct->ct_family; 39744d362409d5469aed47d19e7908d19bd194493aThomas Graf else 39844d362409d5469aed47d19e7908d19bd194493aThomas Graf return AF_UNSPEC; 39944d362409d5469aed47d19e7908d19bd194493aThomas Graf} 40044d362409d5469aed47d19e7908d19bd194493aThomas Graf 40144d362409d5469aed47d19e7908d19bd194493aThomas Grafvoid nfnl_ct_set_proto(struct nfnl_ct *ct, uint8_t proto) 40244d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 40344d362409d5469aed47d19e7908d19bd194493aThomas Graf ct->ct_proto = proto; 40444d362409d5469aed47d19e7908d19bd194493aThomas Graf ct->ce_mask |= CT_ATTR_PROTO; 40544d362409d5469aed47d19e7908d19bd194493aThomas Graf} 40644d362409d5469aed47d19e7908d19bd194493aThomas Graf 40744d362409d5469aed47d19e7908d19bd194493aThomas Grafint nfnl_ct_test_proto(const struct nfnl_ct *ct) 40844d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 40944d362409d5469aed47d19e7908d19bd194493aThomas Graf return !!(ct->ce_mask & CT_ATTR_PROTO); 41044d362409d5469aed47d19e7908d19bd194493aThomas Graf} 41144d362409d5469aed47d19e7908d19bd194493aThomas Graf 41244d362409d5469aed47d19e7908d19bd194493aThomas Grafuint8_t nfnl_ct_get_proto(const struct nfnl_ct *ct) 41344d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 41444d362409d5469aed47d19e7908d19bd194493aThomas Graf return ct->ct_proto; 41544d362409d5469aed47d19e7908d19bd194493aThomas Graf} 41644d362409d5469aed47d19e7908d19bd194493aThomas Graf 41744d362409d5469aed47d19e7908d19bd194493aThomas Grafvoid nfnl_ct_set_tcp_state(struct nfnl_ct *ct, uint8_t state) 41844d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 41944d362409d5469aed47d19e7908d19bd194493aThomas Graf ct->ct_protoinfo.tcp.state = state; 42044d362409d5469aed47d19e7908d19bd194493aThomas Graf ct->ce_mask |= CT_ATTR_TCP_STATE; 42144d362409d5469aed47d19e7908d19bd194493aThomas Graf} 42244d362409d5469aed47d19e7908d19bd194493aThomas Graf 42344d362409d5469aed47d19e7908d19bd194493aThomas Grafint nfnl_ct_test_tcp_state(const struct nfnl_ct *ct) 42444d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 42544d362409d5469aed47d19e7908d19bd194493aThomas Graf return !!(ct->ce_mask & CT_ATTR_TCP_STATE); 42644d362409d5469aed47d19e7908d19bd194493aThomas Graf} 42744d362409d5469aed47d19e7908d19bd194493aThomas Graf 42844d362409d5469aed47d19e7908d19bd194493aThomas Grafuint8_t nfnl_ct_get_tcp_state(const struct nfnl_ct *ct) 42944d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 43044d362409d5469aed47d19e7908d19bd194493aThomas Graf return ct->ct_protoinfo.tcp.state; 43144d362409d5469aed47d19e7908d19bd194493aThomas Graf} 43244d362409d5469aed47d19e7908d19bd194493aThomas Graf 43344d362409d5469aed47d19e7908d19bd194493aThomas Grafstatic struct trans_tbl tcp_states[] = { 43444d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(TCP_CONNTRACK_NONE,NONE) 43544d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(TCP_CONNTRACK_SYN_SENT,SYN_SENT) 43644d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(TCP_CONNTRACK_SYN_RECV,SYN_RECV) 43744d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(TCP_CONNTRACK_ESTABLISHED,ESTABLISHED) 43844d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(TCP_CONNTRACK_FIN_WAIT,FIN_WAIT) 43944d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(TCP_CONNTRACK_CLOSE_WAIT,CLOSE_WAIT) 44044d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(TCP_CONNTRACK_LAST_ACK,LAST_ACK) 44144d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(TCP_CONNTRACK_TIME_WAIT,TIME_WAIT) 44244d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(TCP_CONNTRACK_CLOSE,CLOSE) 44344d362409d5469aed47d19e7908d19bd194493aThomas Graf __ADD(TCP_CONNTRACK_LISTEN,LISTEN) 44444d362409d5469aed47d19e7908d19bd194493aThomas Graf}; 44544d362409d5469aed47d19e7908d19bd194493aThomas Graf 44644d362409d5469aed47d19e7908d19bd194493aThomas Grafchar *nfnl_ct_tcp_state2str(uint8_t state, char *buf, size_t len) 44744d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 44844d362409d5469aed47d19e7908d19bd194493aThomas Graf return __type2str(state, buf, len, tcp_states, ARRAY_SIZE(tcp_states)); 44944d362409d5469aed47d19e7908d19bd194493aThomas Graf} 45044d362409d5469aed47d19e7908d19bd194493aThomas Graf 45144d362409d5469aed47d19e7908d19bd194493aThomas Grafint nfnl_ct_str2tcp_state(const char *name) 45244d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 45344d362409d5469aed47d19e7908d19bd194493aThomas Graf return __str2type(name, tcp_states, ARRAY_SIZE(tcp_states)); 45444d362409d5469aed47d19e7908d19bd194493aThomas Graf} 45544d362409d5469aed47d19e7908d19bd194493aThomas Graf 45644d362409d5469aed47d19e7908d19bd194493aThomas Grafvoid nfnl_ct_set_status(struct nfnl_ct *ct, uint32_t status) 45744d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 458cbe8902265ccc9f6aa6453aeb3a2a4631ed0eb01Philip Craig ct->ct_status_mask |= status; 459cbe8902265ccc9f6aa6453aeb3a2a4631ed0eb01Philip Craig ct->ct_status |= status; 46044d362409d5469aed47d19e7908d19bd194493aThomas Graf ct->ce_mask |= CT_ATTR_STATUS; 46144d362409d5469aed47d19e7908d19bd194493aThomas Graf} 46244d362409d5469aed47d19e7908d19bd194493aThomas Graf 463cbe8902265ccc9f6aa6453aeb3a2a4631ed0eb01Philip Craigvoid nfnl_ct_unset_status(struct nfnl_ct *ct, uint32_t status) 46444d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 465cbe8902265ccc9f6aa6453aeb3a2a4631ed0eb01Philip Craig ct->ct_status_mask |= status; 466cbe8902265ccc9f6aa6453aeb3a2a4631ed0eb01Philip Craig ct->ct_status &= ~status; 467cbe8902265ccc9f6aa6453aeb3a2a4631ed0eb01Philip Craig ct->ce_mask |= CT_ATTR_STATUS; 46844d362409d5469aed47d19e7908d19bd194493aThomas Graf} 46944d362409d5469aed47d19e7908d19bd194493aThomas Graf 47044d362409d5469aed47d19e7908d19bd194493aThomas Grafuint32_t nfnl_ct_get_status(const struct nfnl_ct *ct) 47144d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 47244d362409d5469aed47d19e7908d19bd194493aThomas Graf return ct->ct_status; 47344d362409d5469aed47d19e7908d19bd194493aThomas Graf} 47444d362409d5469aed47d19e7908d19bd194493aThomas Graf 475337fbd24cad1f5cf9c8b4287a75f2c69f088adceThomas Grafstatic struct trans_tbl status_flags[] = { 476337fbd24cad1f5cf9c8b4287a75f2c69f088adceThomas Graf __ADD(IPS_EXPECTED, expected) 477337fbd24cad1f5cf9c8b4287a75f2c69f088adceThomas Graf __ADD(IPS_SEEN_REPLY, seen_reply) 478337fbd24cad1f5cf9c8b4287a75f2c69f088adceThomas Graf __ADD(IPS_ASSURED, assured) 479337fbd24cad1f5cf9c8b4287a75f2c69f088adceThomas Graf __ADD(IPS_CONFIRMED, confirmed) 480337fbd24cad1f5cf9c8b4287a75f2c69f088adceThomas Graf __ADD(IPS_SRC_NAT, snat) 481337fbd24cad1f5cf9c8b4287a75f2c69f088adceThomas Graf __ADD(IPS_DST_NAT, dnat) 482337fbd24cad1f5cf9c8b4287a75f2c69f088adceThomas Graf __ADD(IPS_SEQ_ADJUST, seqadjust) 483337fbd24cad1f5cf9c8b4287a75f2c69f088adceThomas Graf __ADD(IPS_SRC_NAT_DONE, snat_done) 484337fbd24cad1f5cf9c8b4287a75f2c69f088adceThomas Graf __ADD(IPS_DST_NAT_DONE, dnat_done) 485337fbd24cad1f5cf9c8b4287a75f2c69f088adceThomas Graf __ADD(IPS_DYING, dying) 486337fbd24cad1f5cf9c8b4287a75f2c69f088adceThomas Graf __ADD(IPS_FIXED_TIMEOUT, fixed_timeout) 487337fbd24cad1f5cf9c8b4287a75f2c69f088adceThomas Graf}; 488337fbd24cad1f5cf9c8b4287a75f2c69f088adceThomas Graf 489337fbd24cad1f5cf9c8b4287a75f2c69f088adceThomas Grafchar * nfnl_ct_status2str(int flags, char *buf, size_t len) 490337fbd24cad1f5cf9c8b4287a75f2c69f088adceThomas Graf{ 491337fbd24cad1f5cf9c8b4287a75f2c69f088adceThomas Graf return __flags2str(flags, buf, len, status_flags, 492337fbd24cad1f5cf9c8b4287a75f2c69f088adceThomas Graf ARRAY_SIZE(status_flags)); 493337fbd24cad1f5cf9c8b4287a75f2c69f088adceThomas Graf} 494337fbd24cad1f5cf9c8b4287a75f2c69f088adceThomas Graf 495337fbd24cad1f5cf9c8b4287a75f2c69f088adceThomas Grafint nfnl_ct_str2status(const char *name) 496337fbd24cad1f5cf9c8b4287a75f2c69f088adceThomas Graf{ 497337fbd24cad1f5cf9c8b4287a75f2c69f088adceThomas Graf return __str2flags(name, status_flags, ARRAY_SIZE(status_flags)); 498337fbd24cad1f5cf9c8b4287a75f2c69f088adceThomas Graf} 499337fbd24cad1f5cf9c8b4287a75f2c69f088adceThomas Graf 50044d362409d5469aed47d19e7908d19bd194493aThomas Grafvoid nfnl_ct_set_timeout(struct nfnl_ct *ct, uint32_t timeout) 50144d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 50244d362409d5469aed47d19e7908d19bd194493aThomas Graf ct->ct_timeout = timeout; 50344d362409d5469aed47d19e7908d19bd194493aThomas Graf ct->ce_mask |= CT_ATTR_TIMEOUT; 50444d362409d5469aed47d19e7908d19bd194493aThomas Graf} 50544d362409d5469aed47d19e7908d19bd194493aThomas Graf 50644d362409d5469aed47d19e7908d19bd194493aThomas Grafint nfnl_ct_test_timeout(const struct nfnl_ct *ct) 50744d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 50844d362409d5469aed47d19e7908d19bd194493aThomas Graf return !!(ct->ce_mask & CT_ATTR_TIMEOUT); 50944d362409d5469aed47d19e7908d19bd194493aThomas Graf} 51044d362409d5469aed47d19e7908d19bd194493aThomas Graf 51144d362409d5469aed47d19e7908d19bd194493aThomas Grafuint32_t nfnl_ct_get_timeout(const struct nfnl_ct *ct) 51244d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 51344d362409d5469aed47d19e7908d19bd194493aThomas Graf return ct->ct_timeout; 51444d362409d5469aed47d19e7908d19bd194493aThomas Graf} 51544d362409d5469aed47d19e7908d19bd194493aThomas Graf 51644d362409d5469aed47d19e7908d19bd194493aThomas Grafvoid nfnl_ct_set_mark(struct nfnl_ct *ct, uint32_t mark) 51744d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 51844d362409d5469aed47d19e7908d19bd194493aThomas Graf ct->ct_mark = mark; 51944d362409d5469aed47d19e7908d19bd194493aThomas Graf ct->ce_mask |= CT_ATTR_MARK; 52044d362409d5469aed47d19e7908d19bd194493aThomas Graf} 52144d362409d5469aed47d19e7908d19bd194493aThomas Graf 52244d362409d5469aed47d19e7908d19bd194493aThomas Grafint nfnl_ct_test_mark(const struct nfnl_ct *ct) 52344d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 52444d362409d5469aed47d19e7908d19bd194493aThomas Graf return !!(ct->ce_mask & CT_ATTR_MARK); 52544d362409d5469aed47d19e7908d19bd194493aThomas Graf} 52644d362409d5469aed47d19e7908d19bd194493aThomas Graf 52744d362409d5469aed47d19e7908d19bd194493aThomas Grafuint32_t nfnl_ct_get_mark(const struct nfnl_ct *ct) 52844d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 52944d362409d5469aed47d19e7908d19bd194493aThomas Graf return ct->ct_mark; 53044d362409d5469aed47d19e7908d19bd194493aThomas Graf} 53144d362409d5469aed47d19e7908d19bd194493aThomas Graf 53244d362409d5469aed47d19e7908d19bd194493aThomas Grafvoid nfnl_ct_set_use(struct nfnl_ct *ct, uint32_t use) 53344d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 53444d362409d5469aed47d19e7908d19bd194493aThomas Graf ct->ct_use = use; 53544d362409d5469aed47d19e7908d19bd194493aThomas Graf ct->ce_mask |= CT_ATTR_USE; 53644d362409d5469aed47d19e7908d19bd194493aThomas Graf} 53744d362409d5469aed47d19e7908d19bd194493aThomas Graf 53844d362409d5469aed47d19e7908d19bd194493aThomas Grafint nfnl_ct_test_use(const struct nfnl_ct *ct) 53944d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 54044d362409d5469aed47d19e7908d19bd194493aThomas Graf return !!(ct->ce_mask & CT_ATTR_USE); 54144d362409d5469aed47d19e7908d19bd194493aThomas Graf} 54244d362409d5469aed47d19e7908d19bd194493aThomas Graf 54344d362409d5469aed47d19e7908d19bd194493aThomas Grafuint32_t nfnl_ct_get_use(const struct nfnl_ct *ct) 54444d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 54544d362409d5469aed47d19e7908d19bd194493aThomas Graf return ct->ct_use; 54644d362409d5469aed47d19e7908d19bd194493aThomas Graf} 54744d362409d5469aed47d19e7908d19bd194493aThomas Graf 54844d362409d5469aed47d19e7908d19bd194493aThomas Grafvoid nfnl_ct_set_id(struct nfnl_ct *ct, uint32_t id) 54944d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 55044d362409d5469aed47d19e7908d19bd194493aThomas Graf ct->ct_id = id; 55144d362409d5469aed47d19e7908d19bd194493aThomas Graf ct->ce_mask |= CT_ATTR_ID; 55244d362409d5469aed47d19e7908d19bd194493aThomas Graf} 55344d362409d5469aed47d19e7908d19bd194493aThomas Graf 55444d362409d5469aed47d19e7908d19bd194493aThomas Grafint nfnl_ct_test_id(const struct nfnl_ct *ct) 55544d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 55644d362409d5469aed47d19e7908d19bd194493aThomas Graf return !!(ct->ce_mask & CT_ATTR_ID); 55744d362409d5469aed47d19e7908d19bd194493aThomas Graf} 55844d362409d5469aed47d19e7908d19bd194493aThomas Graf 55944d362409d5469aed47d19e7908d19bd194493aThomas Grafuint32_t nfnl_ct_get_id(const struct nfnl_ct *ct) 56044d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 56144d362409d5469aed47d19e7908d19bd194493aThomas Graf return ct->ct_id; 56244d362409d5469aed47d19e7908d19bd194493aThomas Graf} 56344d362409d5469aed47d19e7908d19bd194493aThomas Graf 56444d362409d5469aed47d19e7908d19bd194493aThomas Grafstatic int ct_set_addr(struct nfnl_ct *ct, struct nl_addr *addr, 56544d362409d5469aed47d19e7908d19bd194493aThomas Graf int attr, struct nl_addr ** ct_addr) 56644d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 56744d362409d5469aed47d19e7908d19bd194493aThomas Graf if (ct->ce_mask & CT_ATTR_FAMILY) { 56844d362409d5469aed47d19e7908d19bd194493aThomas Graf if (addr->a_family != ct->ct_family) 5698a3efffa5b3fde252675239914118664d36a2c24Thomas Graf return -NLE_AF_MISMATCH; 57044d362409d5469aed47d19e7908d19bd194493aThomas Graf } else 57144d362409d5469aed47d19e7908d19bd194493aThomas Graf nfnl_ct_set_family(ct, addr->a_family); 57244d362409d5469aed47d19e7908d19bd194493aThomas Graf 57344d362409d5469aed47d19e7908d19bd194493aThomas Graf if (*ct_addr) 57444d362409d5469aed47d19e7908d19bd194493aThomas Graf nl_addr_put(*ct_addr); 57544d362409d5469aed47d19e7908d19bd194493aThomas Graf 57644d362409d5469aed47d19e7908d19bd194493aThomas Graf nl_addr_get(addr); 57744d362409d5469aed47d19e7908d19bd194493aThomas Graf *ct_addr = addr; 57844d362409d5469aed47d19e7908d19bd194493aThomas Graf ct->ce_mask |= attr; 57944d362409d5469aed47d19e7908d19bd194493aThomas Graf 58044d362409d5469aed47d19e7908d19bd194493aThomas Graf return 0; 58144d362409d5469aed47d19e7908d19bd194493aThomas Graf} 58244d362409d5469aed47d19e7908d19bd194493aThomas Graf 58344d362409d5469aed47d19e7908d19bd194493aThomas Grafint nfnl_ct_set_src(struct nfnl_ct *ct, int repl, struct nl_addr *addr) 58444d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 58544d362409d5469aed47d19e7908d19bd194493aThomas Graf struct nfnl_ct_dir *dir = repl ? &ct->ct_repl : &ct->ct_orig; 58644d362409d5469aed47d19e7908d19bd194493aThomas Graf int attr = repl ? CT_ATTR_REPL_SRC : CT_ATTR_ORIG_SRC; 58744d362409d5469aed47d19e7908d19bd194493aThomas Graf return ct_set_addr(ct, addr, attr, &dir->src); 58844d362409d5469aed47d19e7908d19bd194493aThomas Graf} 58944d362409d5469aed47d19e7908d19bd194493aThomas Graf 59044d362409d5469aed47d19e7908d19bd194493aThomas Grafint nfnl_ct_set_dst(struct nfnl_ct *ct, int repl, struct nl_addr *addr) 59144d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 59244d362409d5469aed47d19e7908d19bd194493aThomas Graf struct nfnl_ct_dir *dir = repl ? &ct->ct_repl : &ct->ct_orig; 59344d362409d5469aed47d19e7908d19bd194493aThomas Graf int attr = repl ? CT_ATTR_REPL_DST : CT_ATTR_ORIG_DST; 59444d362409d5469aed47d19e7908d19bd194493aThomas Graf return ct_set_addr(ct, addr, attr, &dir->dst); 59544d362409d5469aed47d19e7908d19bd194493aThomas Graf} 59644d362409d5469aed47d19e7908d19bd194493aThomas Graf 59744d362409d5469aed47d19e7908d19bd194493aThomas Grafstruct nl_addr *nfnl_ct_get_src(const struct nfnl_ct *ct, int repl) 59844d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 59944d362409d5469aed47d19e7908d19bd194493aThomas Graf const struct nfnl_ct_dir *dir = repl ? &ct->ct_repl : &ct->ct_orig; 60044d362409d5469aed47d19e7908d19bd194493aThomas Graf int attr = repl ? CT_ATTR_REPL_SRC : CT_ATTR_ORIG_SRC; 60144d362409d5469aed47d19e7908d19bd194493aThomas Graf if (!(ct->ce_mask & attr)) 60244d362409d5469aed47d19e7908d19bd194493aThomas Graf return NULL; 60344d362409d5469aed47d19e7908d19bd194493aThomas Graf return dir->src; 60444d362409d5469aed47d19e7908d19bd194493aThomas Graf} 60544d362409d5469aed47d19e7908d19bd194493aThomas Graf 60644d362409d5469aed47d19e7908d19bd194493aThomas Grafstruct nl_addr *nfnl_ct_get_dst(const struct nfnl_ct *ct, int repl) 60744d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 60844d362409d5469aed47d19e7908d19bd194493aThomas Graf const struct nfnl_ct_dir *dir = repl ? &ct->ct_repl : &ct->ct_orig; 60944d362409d5469aed47d19e7908d19bd194493aThomas Graf int attr = repl ? CT_ATTR_REPL_DST : CT_ATTR_ORIG_DST; 61044d362409d5469aed47d19e7908d19bd194493aThomas Graf if (!(ct->ce_mask & attr)) 61144d362409d5469aed47d19e7908d19bd194493aThomas Graf return NULL; 61244d362409d5469aed47d19e7908d19bd194493aThomas Graf return dir->dst; 61344d362409d5469aed47d19e7908d19bd194493aThomas Graf} 61444d362409d5469aed47d19e7908d19bd194493aThomas Graf 61544d362409d5469aed47d19e7908d19bd194493aThomas Grafvoid nfnl_ct_set_src_port(struct nfnl_ct *ct, int repl, uint16_t port) 61644d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 61744d362409d5469aed47d19e7908d19bd194493aThomas Graf struct nfnl_ct_dir *dir = repl ? &ct->ct_repl : &ct->ct_orig; 61844d362409d5469aed47d19e7908d19bd194493aThomas Graf int attr = repl ? CT_ATTR_REPL_SRC_PORT : CT_ATTR_ORIG_SRC_PORT; 61944d362409d5469aed47d19e7908d19bd194493aThomas Graf 62044d362409d5469aed47d19e7908d19bd194493aThomas Graf dir->proto.port.src = port; 62144d362409d5469aed47d19e7908d19bd194493aThomas Graf ct->ce_mask |= attr; 62244d362409d5469aed47d19e7908d19bd194493aThomas Graf} 62344d362409d5469aed47d19e7908d19bd194493aThomas Graf 62444d362409d5469aed47d19e7908d19bd194493aThomas Grafint nfnl_ct_test_src_port(const struct nfnl_ct *ct, int repl) 62544d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 62644d362409d5469aed47d19e7908d19bd194493aThomas Graf int attr = repl ? CT_ATTR_REPL_SRC_PORT : CT_ATTR_ORIG_SRC_PORT; 62744d362409d5469aed47d19e7908d19bd194493aThomas Graf return !!(ct->ce_mask & attr); 62844d362409d5469aed47d19e7908d19bd194493aThomas Graf} 62944d362409d5469aed47d19e7908d19bd194493aThomas Graf 63044d362409d5469aed47d19e7908d19bd194493aThomas Grafuint16_t nfnl_ct_get_src_port(const struct nfnl_ct *ct, int repl) 63144d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 63244d362409d5469aed47d19e7908d19bd194493aThomas Graf const struct nfnl_ct_dir *dir = repl ? &ct->ct_repl : &ct->ct_orig; 63344d362409d5469aed47d19e7908d19bd194493aThomas Graf 63444d362409d5469aed47d19e7908d19bd194493aThomas Graf return dir->proto.port.src; 63544d362409d5469aed47d19e7908d19bd194493aThomas Graf} 63644d362409d5469aed47d19e7908d19bd194493aThomas Graf 63744d362409d5469aed47d19e7908d19bd194493aThomas Grafvoid nfnl_ct_set_dst_port(struct nfnl_ct *ct, int repl, uint16_t port) 63844d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 63944d362409d5469aed47d19e7908d19bd194493aThomas Graf struct nfnl_ct_dir *dir = repl ? &ct->ct_repl : &ct->ct_orig; 64044d362409d5469aed47d19e7908d19bd194493aThomas Graf int attr = repl ? CT_ATTR_REPL_DST_PORT : CT_ATTR_ORIG_DST_PORT; 64144d362409d5469aed47d19e7908d19bd194493aThomas Graf 64244d362409d5469aed47d19e7908d19bd194493aThomas Graf dir->proto.port.dst = port; 64344d362409d5469aed47d19e7908d19bd194493aThomas Graf ct->ce_mask |= attr; 64444d362409d5469aed47d19e7908d19bd194493aThomas Graf} 64544d362409d5469aed47d19e7908d19bd194493aThomas Graf 64644d362409d5469aed47d19e7908d19bd194493aThomas Grafint nfnl_ct_test_dst_port(const struct nfnl_ct *ct, int repl) 64744d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 64844d362409d5469aed47d19e7908d19bd194493aThomas Graf int attr = repl ? CT_ATTR_REPL_DST_PORT : CT_ATTR_ORIG_DST_PORT; 64944d362409d5469aed47d19e7908d19bd194493aThomas Graf return !!(ct->ce_mask & attr); 65044d362409d5469aed47d19e7908d19bd194493aThomas Graf} 65144d362409d5469aed47d19e7908d19bd194493aThomas Graf 65244d362409d5469aed47d19e7908d19bd194493aThomas Grafuint16_t nfnl_ct_get_dst_port(const struct nfnl_ct *ct, int repl) 65344d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 65444d362409d5469aed47d19e7908d19bd194493aThomas Graf const struct nfnl_ct_dir *dir = repl ? &ct->ct_repl : &ct->ct_orig; 65544d362409d5469aed47d19e7908d19bd194493aThomas Graf 65644d362409d5469aed47d19e7908d19bd194493aThomas Graf return dir->proto.port.dst; 65744d362409d5469aed47d19e7908d19bd194493aThomas Graf} 65844d362409d5469aed47d19e7908d19bd194493aThomas Graf 65944d362409d5469aed47d19e7908d19bd194493aThomas Grafvoid nfnl_ct_set_icmp_id(struct nfnl_ct *ct, int repl, uint16_t id) 66044d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 66144d362409d5469aed47d19e7908d19bd194493aThomas Graf struct nfnl_ct_dir *dir = repl ? &ct->ct_repl : &ct->ct_orig; 66244d362409d5469aed47d19e7908d19bd194493aThomas Graf int attr = repl ? CT_ATTR_REPL_ICMP_ID : CT_ATTR_ORIG_ICMP_ID; 66344d362409d5469aed47d19e7908d19bd194493aThomas Graf 66444d362409d5469aed47d19e7908d19bd194493aThomas Graf dir->proto.icmp.id = id; 66544d362409d5469aed47d19e7908d19bd194493aThomas Graf ct->ce_mask |= attr; 66644d362409d5469aed47d19e7908d19bd194493aThomas Graf} 66744d362409d5469aed47d19e7908d19bd194493aThomas Graf 66844d362409d5469aed47d19e7908d19bd194493aThomas Grafint nfnl_ct_test_icmp_id(const struct nfnl_ct *ct, int repl) 66944d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 67044d362409d5469aed47d19e7908d19bd194493aThomas Graf int attr = repl ? CT_ATTR_REPL_ICMP_ID : CT_ATTR_ORIG_ICMP_ID; 67144d362409d5469aed47d19e7908d19bd194493aThomas Graf return !!(ct->ce_mask & attr); 67244d362409d5469aed47d19e7908d19bd194493aThomas Graf} 67344d362409d5469aed47d19e7908d19bd194493aThomas Graf 67444d362409d5469aed47d19e7908d19bd194493aThomas Grafuint16_t nfnl_ct_get_icmp_id(const struct nfnl_ct *ct, int repl) 67544d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 67644d362409d5469aed47d19e7908d19bd194493aThomas Graf const struct nfnl_ct_dir *dir = repl ? &ct->ct_repl : &ct->ct_orig; 67744d362409d5469aed47d19e7908d19bd194493aThomas Graf 67844d362409d5469aed47d19e7908d19bd194493aThomas Graf return dir->proto.icmp.id; 67944d362409d5469aed47d19e7908d19bd194493aThomas Graf} 68044d362409d5469aed47d19e7908d19bd194493aThomas Graf 68144d362409d5469aed47d19e7908d19bd194493aThomas Grafvoid nfnl_ct_set_icmp_type(struct nfnl_ct *ct, int repl, uint8_t type) 68244d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 68344d362409d5469aed47d19e7908d19bd194493aThomas Graf struct nfnl_ct_dir *dir = repl ? &ct->ct_repl : &ct->ct_orig; 68444d362409d5469aed47d19e7908d19bd194493aThomas Graf int attr = repl ? CT_ATTR_REPL_ICMP_TYPE : CT_ATTR_ORIG_ICMP_TYPE; 68544d362409d5469aed47d19e7908d19bd194493aThomas Graf 68644d362409d5469aed47d19e7908d19bd194493aThomas Graf dir->proto.icmp.type = type; 68744d362409d5469aed47d19e7908d19bd194493aThomas Graf ct->ce_mask |= attr; 68844d362409d5469aed47d19e7908d19bd194493aThomas Graf} 68944d362409d5469aed47d19e7908d19bd194493aThomas Graf 69044d362409d5469aed47d19e7908d19bd194493aThomas Grafint nfnl_ct_test_icmp_type(const struct nfnl_ct *ct, int repl) 69144d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 69244d362409d5469aed47d19e7908d19bd194493aThomas Graf int attr = repl ? CT_ATTR_REPL_ICMP_TYPE : CT_ATTR_ORIG_ICMP_TYPE; 69344d362409d5469aed47d19e7908d19bd194493aThomas Graf return !!(ct->ce_mask & attr); 69444d362409d5469aed47d19e7908d19bd194493aThomas Graf} 69544d362409d5469aed47d19e7908d19bd194493aThomas Graf 69644d362409d5469aed47d19e7908d19bd194493aThomas Grafuint8_t nfnl_ct_get_icmp_type(const struct nfnl_ct *ct, int repl) 69744d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 69844d362409d5469aed47d19e7908d19bd194493aThomas Graf const struct nfnl_ct_dir *dir = repl ? &ct->ct_repl : &ct->ct_orig; 69944d362409d5469aed47d19e7908d19bd194493aThomas Graf 70044d362409d5469aed47d19e7908d19bd194493aThomas Graf return dir->proto.icmp.type; 70144d362409d5469aed47d19e7908d19bd194493aThomas Graf} 70244d362409d5469aed47d19e7908d19bd194493aThomas Graf 70344d362409d5469aed47d19e7908d19bd194493aThomas Grafvoid nfnl_ct_set_icmp_code(struct nfnl_ct *ct, int repl, uint8_t code) 70444d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 70544d362409d5469aed47d19e7908d19bd194493aThomas Graf struct nfnl_ct_dir *dir = repl ? &ct->ct_repl : &ct->ct_orig; 70644d362409d5469aed47d19e7908d19bd194493aThomas Graf int attr = repl ? CT_ATTR_REPL_ICMP_CODE : CT_ATTR_ORIG_ICMP_CODE; 70744d362409d5469aed47d19e7908d19bd194493aThomas Graf 70844d362409d5469aed47d19e7908d19bd194493aThomas Graf dir->proto.icmp.code = code; 70944d362409d5469aed47d19e7908d19bd194493aThomas Graf ct->ce_mask |= attr; 71044d362409d5469aed47d19e7908d19bd194493aThomas Graf} 71144d362409d5469aed47d19e7908d19bd194493aThomas Graf 71244d362409d5469aed47d19e7908d19bd194493aThomas Grafint nfnl_ct_test_icmp_code(const struct nfnl_ct *ct, int repl) 71344d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 71444d362409d5469aed47d19e7908d19bd194493aThomas Graf int attr = repl ? CT_ATTR_REPL_ICMP_CODE : CT_ATTR_ORIG_ICMP_CODE; 71544d362409d5469aed47d19e7908d19bd194493aThomas Graf return !!(ct->ce_mask & attr); 71644d362409d5469aed47d19e7908d19bd194493aThomas Graf} 71744d362409d5469aed47d19e7908d19bd194493aThomas Graf 71844d362409d5469aed47d19e7908d19bd194493aThomas Grafuint8_t nfnl_ct_get_icmp_code(const struct nfnl_ct *ct, int repl) 71944d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 72044d362409d5469aed47d19e7908d19bd194493aThomas Graf const struct nfnl_ct_dir *dir = repl ? &ct->ct_repl : &ct->ct_orig; 72144d362409d5469aed47d19e7908d19bd194493aThomas Graf 72244d362409d5469aed47d19e7908d19bd194493aThomas Graf return dir->proto.icmp.code; 72344d362409d5469aed47d19e7908d19bd194493aThomas Graf} 72444d362409d5469aed47d19e7908d19bd194493aThomas Graf 72544d362409d5469aed47d19e7908d19bd194493aThomas Grafvoid nfnl_ct_set_packets(struct nfnl_ct *ct, int repl, uint64_t packets) 72644d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 72744d362409d5469aed47d19e7908d19bd194493aThomas Graf struct nfnl_ct_dir *dir = repl ? &ct->ct_repl : &ct->ct_orig; 72844d362409d5469aed47d19e7908d19bd194493aThomas Graf int attr = repl ? CT_ATTR_REPL_PACKETS : CT_ATTR_ORIG_PACKETS; 72944d362409d5469aed47d19e7908d19bd194493aThomas Graf 73044d362409d5469aed47d19e7908d19bd194493aThomas Graf dir->packets = packets; 73144d362409d5469aed47d19e7908d19bd194493aThomas Graf ct->ce_mask |= attr; 73244d362409d5469aed47d19e7908d19bd194493aThomas Graf} 73344d362409d5469aed47d19e7908d19bd194493aThomas Graf 73444d362409d5469aed47d19e7908d19bd194493aThomas Grafint nfnl_ct_test_packets(const struct nfnl_ct *ct, int repl) 73544d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 73644d362409d5469aed47d19e7908d19bd194493aThomas Graf int attr = repl ? CT_ATTR_REPL_PACKETS : CT_ATTR_ORIG_PACKETS; 73744d362409d5469aed47d19e7908d19bd194493aThomas Graf return !!(ct->ce_mask & attr); 73844d362409d5469aed47d19e7908d19bd194493aThomas Graf} 73944d362409d5469aed47d19e7908d19bd194493aThomas Graf 74044d362409d5469aed47d19e7908d19bd194493aThomas Grafuint64_t nfnl_ct_get_packets(const struct nfnl_ct *ct, int repl) 74144d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 74244d362409d5469aed47d19e7908d19bd194493aThomas Graf const struct nfnl_ct_dir *dir = repl ? &ct->ct_repl : &ct->ct_orig; 74344d362409d5469aed47d19e7908d19bd194493aThomas Graf 74444d362409d5469aed47d19e7908d19bd194493aThomas Graf return dir->packets; 74544d362409d5469aed47d19e7908d19bd194493aThomas Graf} 74644d362409d5469aed47d19e7908d19bd194493aThomas Graf 74744d362409d5469aed47d19e7908d19bd194493aThomas Grafvoid nfnl_ct_set_bytes(struct nfnl_ct *ct, int repl, uint64_t bytes) 74844d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 74944d362409d5469aed47d19e7908d19bd194493aThomas Graf struct nfnl_ct_dir *dir = repl ? &ct->ct_repl : &ct->ct_orig; 75044d362409d5469aed47d19e7908d19bd194493aThomas Graf int attr = repl ? CT_ATTR_REPL_BYTES : CT_ATTR_ORIG_BYTES; 75144d362409d5469aed47d19e7908d19bd194493aThomas Graf 75244d362409d5469aed47d19e7908d19bd194493aThomas Graf dir->bytes = bytes; 75344d362409d5469aed47d19e7908d19bd194493aThomas Graf ct->ce_mask |= attr; 75444d362409d5469aed47d19e7908d19bd194493aThomas Graf} 75544d362409d5469aed47d19e7908d19bd194493aThomas Graf 75644d362409d5469aed47d19e7908d19bd194493aThomas Grafint nfnl_ct_test_bytes(const struct nfnl_ct *ct, int repl) 75744d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 75844d362409d5469aed47d19e7908d19bd194493aThomas Graf int attr = repl ? CT_ATTR_REPL_BYTES : CT_ATTR_ORIG_BYTES; 75944d362409d5469aed47d19e7908d19bd194493aThomas Graf return !!(ct->ce_mask & attr); 76044d362409d5469aed47d19e7908d19bd194493aThomas Graf} 76144d362409d5469aed47d19e7908d19bd194493aThomas Graf 76244d362409d5469aed47d19e7908d19bd194493aThomas Grafuint64_t nfnl_ct_get_bytes(const struct nfnl_ct *ct, int repl) 76344d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 76444d362409d5469aed47d19e7908d19bd194493aThomas Graf const struct nfnl_ct_dir *dir = repl ? &ct->ct_repl : &ct->ct_orig; 76544d362409d5469aed47d19e7908d19bd194493aThomas Graf 76644d362409d5469aed47d19e7908d19bd194493aThomas Graf return dir->bytes; 76744d362409d5469aed47d19e7908d19bd194493aThomas Graf} 76844d362409d5469aed47d19e7908d19bd194493aThomas Graf 76944d362409d5469aed47d19e7908d19bd194493aThomas Graf/** @} */ 77044d362409d5469aed47d19e7908d19bd194493aThomas Graf 77144d362409d5469aed47d19e7908d19bd194493aThomas Grafstruct nl_object_ops ct_obj_ops = { 77244d362409d5469aed47d19e7908d19bd194493aThomas Graf .oo_name = "netfilter/ct", 77344d362409d5469aed47d19e7908d19bd194493aThomas Graf .oo_size = sizeof(struct nfnl_ct), 77444d362409d5469aed47d19e7908d19bd194493aThomas Graf .oo_free_data = ct_free_data, 77544d362409d5469aed47d19e7908d19bd194493aThomas Graf .oo_clone = ct_clone, 776d84430702496f617c01c5e2d27d0e82e02390bb7Thomas Graf .oo_dump = { 777d84430702496f617c01c5e2d27d0e82e02390bb7Thomas Graf [NL_DUMP_LINE] = ct_dump_line, 778d84430702496f617c01c5e2d27d0e82e02390bb7Thomas Graf [NL_DUMP_DETAILS] = ct_dump_details, 779d84430702496f617c01c5e2d27d0e82e02390bb7Thomas Graf [NL_DUMP_STATS] = ct_dump_stats, 780d84430702496f617c01c5e2d27d0e82e02390bb7Thomas Graf }, 78144d362409d5469aed47d19e7908d19bd194493aThomas Graf .oo_compare = ct_compare, 78244d362409d5469aed47d19e7908d19bd194493aThomas Graf .oo_attrs2str = ct_attrs2str, 78344d362409d5469aed47d19e7908d19bd194493aThomas Graf}; 78444d362409d5469aed47d19e7908d19bd194493aThomas Graf 78544d362409d5469aed47d19e7908d19bd194493aThomas Graf/** @} */ 786