10#include <netinet/in.h> 
   11#include <linux/netfilter/nfnetlink_conntrack.h> 
   12#include <linux/netfilter/nf_conntrack_common.h> 
   13#include <linux/netfilter/nf_conntrack_tcp.h> 
   15#include <netlink-private/netlink.h> 
   16#include <netlink/netfilter/nfnl.h> 
   17#include <netlink/netfilter/exp.h> 
   26#define EXP_ATTR_FAMILY                 (1UL << 0)  
   27#define EXP_ATTR_TIMEOUT                (1UL << 1)  
   28#define EXP_ATTR_ID                     (1UL << 2)  
   29#define EXP_ATTR_HELPER_NAME            (1UL << 3)  
   30#define EXP_ATTR_ZONE                   (1UL << 4)  
   31#define EXP_ATTR_FLAGS                  (1UL << 5)  
   32#define EXP_ATTR_CLASS                  (1UL << 6)  
   33#define EXP_ATTR_FN                     (1UL << 7)  
   35#define EXP_ATTR_EXPECT_IP_SRC          (1UL << 8) 
   36#define EXP_ATTR_EXPECT_IP_DST          (1UL << 9) 
   37#define EXP_ATTR_EXPECT_L4PROTO_NUM     (1UL << 10) 
   38#define EXP_ATTR_EXPECT_L4PROTO_PORTS   (1UL << 11) 
   39#define EXP_ATTR_EXPECT_L4PROTO_ICMP    (1UL << 12) 
   40#define EXP_ATTR_MASTER_IP_SRC          (1UL << 13) 
   41#define EXP_ATTR_MASTER_IP_DST          (1UL << 14) 
   42#define EXP_ATTR_MASTER_L4PROTO_NUM     (1UL << 15) 
   43#define EXP_ATTR_MASTER_L4PROTO_PORTS   (1UL << 16) 
   44#define EXP_ATTR_MASTER_L4PROTO_ICMP    (1UL << 17) 
   45#define EXP_ATTR_MASK_IP_SRC            (1UL << 18) 
   46#define EXP_ATTR_MASK_IP_DST            (1UL << 19) 
   47#define EXP_ATTR_MASK_L4PROTO_NUM       (1UL << 20) 
   48#define EXP_ATTR_MASK_L4PROTO_PORTS     (1UL << 21) 
   49#define EXP_ATTR_MASK_L4PROTO_ICMP      (1UL << 22) 
   50#define EXP_ATTR_NAT_IP_SRC             (1UL << 23) 
   51#define EXP_ATTR_NAT_IP_DST             (1UL << 24) 
   52#define EXP_ATTR_NAT_L4PROTO_NUM        (1UL << 25) 
   53#define EXP_ATTR_NAT_L4PROTO_PORTS      (1UL << 26) 
   54#define EXP_ATTR_NAT_L4PROTO_ICMP       (1UL << 27) 
   55#define EXP_ATTR_NAT_DIR                (1UL << 28) 
   58static void exp_free_data(
struct nl_object *c)
 
   60        struct nfnl_exp *exp = (
struct nfnl_exp *) c;
 
   75        free(exp->exp_helper_name);
 
   78static int exp_clone(
struct nl_object *_dst, 
struct nl_object *_src)
 
   80        struct nfnl_exp *dst = (
struct nfnl_exp *) _dst;
 
   81        struct nfnl_exp *src = (
struct nfnl_exp *) _src;
 
   84        dst->exp_helper_name = NULL;
 
   86        dst->exp_expect.src = NULL;
 
   87        dst->exp_expect.dst = NULL;
 
   88        dst->exp_master.src = NULL;
 
   89        dst->exp_master.dst = NULL;
 
   90        dst->exp_mask.src = NULL;
 
   91        dst->exp_mask.dst = NULL;
 
   92        dst->exp_nat.src = NULL;
 
   93        dst->exp_nat.dst = NULL;
 
   95        if (src->exp_expect.src) {
 
   99                dst->exp_expect.src = addr;
 
  102        if (src->exp_expect.dst) {
 
  106                dst->exp_expect.dst = addr;
 
  109        if (src->exp_master.src) {
 
  113                dst->exp_master.src = addr;
 
  116        if (src->exp_master.dst) {
 
  120                dst->exp_master.dst = addr;
 
  123        if (src->exp_mask.src) {
 
  127                dst->exp_mask.src = addr;
 
  130        if (src->exp_mask.dst) {
 
  134                dst->exp_mask.dst = addr;
 
  137        if (src->exp_nat.src) {
 
  141                dst->exp_nat.src = addr;
 
  144        if (src->exp_nat.dst) {
 
  148                dst->exp_nat.dst = addr;
 
  152                dst->exp_fn = strdup(src->exp_fn);
 
  154        if (src->exp_helper_name)
 
  155                dst->exp_helper_name = strdup(src->exp_helper_name);
 
  160static void dump_addr(
struct nl_dump_params *p, 
struct nl_addr *addr, 
int port)
 
  173static void dump_icmp(
struct nl_dump_params *p, 
struct nfnl_exp *exp, 
int tuple)
 
  175        if (nfnl_exp_test_icmp(exp, tuple)) {
 
  177                nl_dump(p, 
"icmp type %d ", nfnl_exp_get_icmp_type(exp, tuple));
 
  179                nl_dump(p, 
"code %d ", nfnl_exp_get_icmp_code(exp, tuple));
 
  181                nl_dump(p, 
"id %d ", nfnl_exp_get_icmp_id(exp, tuple));
 
  185static void exp_dump_tuples(
struct nfnl_exp *exp, 
struct nl_dump_params *p)
 
  187        struct nl_addr *tuple_src, *tuple_dst;
 
  188        int tuple_sport, tuple_dport;
 
  192        for (i = NFNL_EXP_TUPLE_EXPECT; i < NFNL_EXP_TUPLE_MAX; i++) {
 
  199                if (nfnl_exp_test_src(exp, i))
 
  200                        tuple_src = nfnl_exp_get_src(exp, i);
 
  201                if (nfnl_exp_test_dst(exp, i))
 
  202                        tuple_dst = nfnl_exp_get_dst(exp, i);
 
  205                if (nfnl_exp_test_l4protonum(exp, i)) {
 
  207                                nl_ip_proto2str(nfnl_exp_get_l4protonum(exp, i), buf, 
sizeof(buf)));
 
  210                if (nfnl_exp_test_ports(exp, i)) {
 
  211                        tuple_sport = nfnl_exp_get_src_port(exp, i);
 
  212                        tuple_dport = nfnl_exp_get_dst_port(exp, i);
 
  215                dump_addr(p, tuple_src, tuple_sport);
 
  216                dump_addr(p, tuple_dst, tuple_dport);
 
  217                dump_icmp(p, exp, 0);
 
  220        if (nfnl_exp_test_nat_dir(exp))
 
  221                nl_dump(p, 
"nat dir %u ", exp->exp_nat_dir);
 
  226static void exp_dump_line(
struct nl_object *a, 
struct nl_dump_params *p)
 
  228        struct nfnl_exp *exp = (
struct nfnl_exp *) a;
 
  232        exp_dump_tuples(exp, p);
 
  237static void exp_dump_details(
struct nl_object *a, 
struct nl_dump_params *p)
 
  239        struct nfnl_exp *exp = (
struct nfnl_exp *) a;
 
  245        nl_dump(p, 
"    id 0x%x ", exp->exp_id);
 
  246        nl_dump_line(p, 
"family %s ",
 
  247                nl_af2str(exp->exp_family, buf, 
sizeof(buf)));
 
  249        if (nfnl_exp_test_timeout(exp)) {
 
  250                uint64_t timeout_ms = nfnl_exp_get_timeout(exp) * 1000UL;
 
  255        if (nfnl_exp_test_helper_name(exp))
 
  256                nl_dump(p, 
"helper %s ", exp->exp_helper_name);
 
  258        if (nfnl_exp_test_fn(exp))
 
  259                nl_dump(p, 
"fn %s ", exp->exp_fn);
 
  261        if (nfnl_exp_test_class(exp))
 
  262                nl_dump(p, 
"class %u ", nfnl_exp_get_class(exp));
 
  264        if (nfnl_exp_test_zone(exp))
 
  265                nl_dump(p, 
"zone %u ", nfnl_exp_get_zone(exp));
 
  267        if (nfnl_exp_test_flags(exp))
 
  269#define PRINT_FLAG(str) \ 
  270        { nl_dump(p, "%s%s", fp++ ? "," : "", (str)); }
 
  272        if (exp->exp_flags & NF_CT_EXPECT_PERMANENT)
 
  273                PRINT_FLAG(
"PERMANENT");
 
  274        if (exp->exp_flags & NF_CT_EXPECT_INACTIVE)
 
  275                PRINT_FLAG(
"INACTIVE");
 
  276        if (exp->exp_flags & NF_CT_EXPECT_USERSPACE)
 
  277                PRINT_FLAG(
"USERSPACE");
 
  280        if (nfnl_exp_test_flags(exp))
 
  286static int exp_cmp_l4proto_ports (
union nfnl_exp_protodata *a, 
union nfnl_exp_protodata *b) {
 
  289        d = ( (a->port.src != b->port.src) ||
 
  290              (a->port.dst != b->port.dst) );
 
  295static int exp_cmp_l4proto_icmp (
union nfnl_exp_protodata *a, 
union nfnl_exp_protodata *b) {
 
  298        d = ( (a->icmp.code != b->icmp.code) ||
 
  299              (a->icmp.type != b->icmp.type) ||
 
  300              (a->icmp.id != b->icmp.id) );
 
  305static uint64_t exp_compare(
struct nl_object *_a, 
struct nl_object *_b,
 
  306                            uint64_t attrs, 
int flags)
 
  308        struct nfnl_exp *a = (
struct nfnl_exp *) _a;
 
  309        struct nfnl_exp *b = (
struct nfnl_exp *) _b;
 
  312#define EXP_DIFF(ATTR, EXPR) ATTR_DIFF(attrs, EXP_ATTR_##ATTR, a, b, EXPR) 
  313#define EXP_DIFF_VAL(ATTR, FIELD) EXP_DIFF(ATTR, a->FIELD != b->FIELD) 
  314#define EXP_DIFF_STRING(ATTR, FIELD) EXP_DIFF(ATTR, (strcmp(a->FIELD, b->FIELD) != 0)) 
  315#define EXP_DIFF_ADDR(ATTR, FIELD) \ 
  316                ((flags & LOOSE_COMPARISON) \ 
  317                ? EXP_DIFF(ATTR, nl_addr_cmp_prefix(a->FIELD, b->FIELD)) \ 
  318                : EXP_DIFF(ATTR, nl_addr_cmp(a->FIELD, b->FIELD))) 
  319#define EXP_DIFF_L4PROTO_PORTS(ATTR, FIELD) \ 
  320                EXP_DIFF(ATTR, exp_cmp_l4proto_ports(&(a->FIELD), &(b->FIELD))) 
  321#define EXP_DIFF_L4PROTO_ICMP(ATTR, FIELD) \ 
  322                EXP_DIFF(ATTR, exp_cmp_l4proto_icmp(&(a->FIELD), &(b->FIELD))) 
  324                diff |= EXP_DIFF_VAL(FAMILY,                    exp_family);
 
  325                diff |= EXP_DIFF_VAL(TIMEOUT,                   exp_timeout);
 
  326                diff |= EXP_DIFF_VAL(ID,                        exp_id);
 
  327                diff |= EXP_DIFF_VAL(ZONE,                      exp_zone);
 
  328                diff |= EXP_DIFF_VAL(CLASS,                     exp_class);
 
  329                diff |= EXP_DIFF_VAL(FLAGS,                     exp_flags);
 
  330                diff |= EXP_DIFF_VAL(NAT_DIR,                   exp_nat_dir);
 
  332                diff |= EXP_DIFF_STRING(FN,                     exp_fn);
 
  333                diff |= EXP_DIFF_STRING(HELPER_NAME,            exp_helper_name);
 
  335                diff |= EXP_DIFF_ADDR(EXPECT_IP_SRC,                    exp_expect.src);
 
  336                diff |= EXP_DIFF_ADDR(EXPECT_IP_DST,                    exp_expect.dst);
 
  337                diff |= EXP_DIFF_VAL(EXPECT_L4PROTO_NUM,                exp_expect.proto.l4protonum);
 
  338                diff |= EXP_DIFF_L4PROTO_PORTS(EXPECT_L4PROTO_PORTS,    exp_expect.proto.l4protodata);
 
  339                diff |= EXP_DIFF_L4PROTO_ICMP(EXPECT_L4PROTO_ICMP,      exp_expect.proto.l4protodata);
 
  341                diff |= EXP_DIFF_ADDR(MASTER_IP_SRC,                    exp_master.src);
 
  342                diff |= EXP_DIFF_ADDR(MASTER_IP_DST,                    exp_master.dst);
 
  343                diff |= EXP_DIFF_VAL(MASTER_L4PROTO_NUM,                exp_master.proto.l4protonum);
 
  344                diff |= EXP_DIFF_L4PROTO_PORTS(MASTER_L4PROTO_PORTS,    exp_master.proto.l4protodata);
 
  345                diff |= EXP_DIFF_L4PROTO_ICMP(MASTER_L4PROTO_ICMP,      exp_master.proto.l4protodata);
 
  347                diff |= EXP_DIFF_ADDR(MASK_IP_SRC,                      exp_mask.src);
 
  348                diff |= EXP_DIFF_ADDR(MASK_IP_DST,                      exp_mask.dst);
 
  349                diff |= EXP_DIFF_VAL(MASK_L4PROTO_NUM,                  exp_mask.proto.l4protonum);
 
  350                diff |= EXP_DIFF_L4PROTO_PORTS(MASK_L4PROTO_PORTS,      exp_mask.proto.l4protodata);
 
  351                diff |= EXP_DIFF_L4PROTO_ICMP(MASK_L4PROTO_ICMP,        exp_mask.proto.l4protodata);
 
  353                diff |= EXP_DIFF_ADDR(NAT_IP_SRC,                       exp_nat.src);
 
  354                diff |= EXP_DIFF_ADDR(NAT_IP_DST,                       exp_nat.dst);
 
  355                diff |= EXP_DIFF_VAL(NAT_L4PROTO_NUM,                   exp_nat.proto.l4protonum);
 
  356                diff |= EXP_DIFF_L4PROTO_PORTS(NAT_L4PROTO_PORTS,       exp_nat.proto.l4protodata);
 
  357                diff |= EXP_DIFF_L4PROTO_ICMP(NAT_L4PROTO_ICMP,         exp_nat.proto.l4protodata);
 
  361#undef EXP_DIFF_STRING 
  363#undef EXP_DIFF_L4PROTO_PORTS 
  364#undef EXP_DIFF_L4PROTO_ICMP 
  370static const struct trans_tbl exp_attrs[] = {
 
  371        __ADD(EXP_ATTR_FAMILY,                          family),
 
  372        __ADD(EXP_ATTR_TIMEOUT,                         timeout),
 
  373        __ADD(EXP_ATTR_ID,                              
id),
 
  374        __ADD(EXP_ATTR_HELPER_NAME,                     helpername),
 
  375        __ADD(EXP_ATTR_ZONE,                            zone),
 
  376        __ADD(EXP_ATTR_CLASS,                           
class),
 
  377        __ADD(EXP_ATTR_FLAGS,                           flags),
 
  378        __ADD(EXP_ATTR_FN,                              function),
 
  379        __ADD(EXP_ATTR_EXPECT_IP_SRC,                   expectipsrc),
 
  380        __ADD(EXP_ATTR_EXPECT_IP_DST,                   expectipdst),
 
  381        __ADD(EXP_ATTR_EXPECT_L4PROTO_NUM,              expectprotonum),
 
  382        __ADD(EXP_ATTR_EXPECT_L4PROTO_PORTS,            expectports),
 
  383        __ADD(EXP_ATTR_EXPECT_L4PROTO_ICMP,             expecticmp),
 
  384        __ADD(EXP_ATTR_MASTER_IP_SRC,                   masteripsrc),
 
  385        __ADD(EXP_ATTR_MASTER_IP_DST,                   masteripdst),
 
  386        __ADD(EXP_ATTR_MASTER_L4PROTO_NUM,              masterprotonum),
 
  387        __ADD(EXP_ATTR_MASTER_L4PROTO_PORTS,            masterports),
 
  388        __ADD(EXP_ATTR_MASTER_L4PROTO_ICMP,             mastericmp),
 
  389        __ADD(EXP_ATTR_MASK_IP_SRC,                     maskipsrc),
 
  390        __ADD(EXP_ATTR_MASK_IP_DST,                     maskipdst),
 
  391        __ADD(EXP_ATTR_MASK_L4PROTO_NUM,                maskprotonum),
 
  392        __ADD(EXP_ATTR_MASK_L4PROTO_PORTS,              maskports),
 
  393        __ADD(EXP_ATTR_MASK_L4PROTO_ICMP,               maskicmp),
 
  394        __ADD(EXP_ATTR_NAT_IP_SRC,                      natipsrc),
 
  395        __ADD(EXP_ATTR_NAT_IP_DST,                      natipdst),
 
  396        __ADD(EXP_ATTR_NAT_L4PROTO_NUM,                 natprotonum),
 
  397        __ADD(EXP_ATTR_NAT_L4PROTO_PORTS,               natports),
 
  398        __ADD(EXP_ATTR_NAT_L4PROTO_ICMP,                naticmp),
 
  399        __ADD(EXP_ATTR_NAT_DIR,                         natdir),
 
  402static char *exp_attrs2str(
int attrs, 
char *buf, 
size_t len)
 
  404        return __flags2str(attrs, buf, len, exp_attrs, ARRAY_SIZE(exp_attrs));
 
  412struct nfnl_exp *nfnl_exp_alloc(
void)
 
  417void nfnl_exp_get(
struct nfnl_exp *exp)
 
  422void nfnl_exp_put(
struct nfnl_exp *exp)
 
  434void nfnl_exp_set_family(
struct nfnl_exp *exp, uint8_t family)
 
  436        exp->exp_family = family;
 
  437        exp->ce_mask |= EXP_ATTR_FAMILY;
 
  440uint8_t nfnl_exp_get_family(
const struct nfnl_exp *exp)
 
  442        if (exp->ce_mask & EXP_ATTR_FAMILY)
 
  443                return exp->exp_family;
 
  448void nfnl_exp_set_flags(
struct nfnl_exp *exp, uint32_t flags)
 
  450        exp->exp_flags |= flags;
 
  451        exp->ce_mask |= EXP_ATTR_FLAGS;
 
  454int nfnl_exp_test_flags(
const struct nfnl_exp *exp)
 
  456        return !!(exp->ce_mask & EXP_ATTR_FLAGS);
 
  459void nfnl_exp_unset_flags(
struct nfnl_exp *exp, uint32_t flags)
 
  461        exp->exp_flags &= ~flags;
 
  462        exp->ce_mask |= EXP_ATTR_FLAGS;
 
  465uint32_t nfnl_exp_get_flags(
const struct nfnl_exp *exp)
 
  467        return exp->exp_flags;
 
  470static const struct trans_tbl flag_table[] = {
 
  471        __ADD(IPS_EXPECTED, expected),
 
  472        __ADD(IPS_SEEN_REPLY, seen_reply),
 
  473        __ADD(IPS_ASSURED, assured),
 
  476char * nfnl_exp_flags2str(
int flags, 
char *buf, 
size_t len)
 
  478        return __flags2str(flags, buf, len, flag_table,
 
  479                           ARRAY_SIZE(flag_table));
 
  482int nfnl_exp_str2flags(
const char *name)
 
  484        return __str2flags(name, flag_table, ARRAY_SIZE(flag_table));
 
  487void nfnl_exp_set_timeout(
struct nfnl_exp *exp, uint32_t timeout)
 
  489        exp->exp_timeout = timeout;
 
  490        exp->ce_mask |= EXP_ATTR_TIMEOUT;
 
  493int nfnl_exp_test_timeout(
const struct nfnl_exp *exp)
 
  495        return !!(exp->ce_mask & EXP_ATTR_TIMEOUT);
 
  498uint32_t nfnl_exp_get_timeout(
const struct nfnl_exp *exp)
 
  500        return exp->exp_timeout;
 
  503void nfnl_exp_set_id(
struct nfnl_exp *exp, uint32_t 
id)
 
  506        exp->ce_mask |= EXP_ATTR_ID;
 
  509int nfnl_exp_test_id(
const struct nfnl_exp *exp)
 
  511        return !!(exp->ce_mask & EXP_ATTR_ID);
 
  514uint32_t nfnl_exp_get_id(
const struct nfnl_exp *exp)
 
  519int nfnl_exp_set_helper_name(
struct nfnl_exp *exp, 
void *name)
 
  521        free(exp->exp_helper_name);
 
  522        exp->exp_helper_name = strdup(name);
 
  523        if (!exp->exp_helper_name)
 
  526        exp->ce_mask |= EXP_ATTR_HELPER_NAME;
 
  530int  nfnl_exp_test_helper_name(
const struct nfnl_exp *exp)
 
  532        return !!(exp->ce_mask & EXP_ATTR_HELPER_NAME);
 
  535const char * nfnl_exp_get_helper_name(
const struct nfnl_exp *exp)
 
  537        return exp->exp_helper_name;
 
  540void nfnl_exp_set_zone(
struct nfnl_exp *exp, uint16_t zone)
 
  542        exp->exp_zone = zone;
 
  543        exp->ce_mask |= EXP_ATTR_ZONE;
 
  546int nfnl_exp_test_zone(
const struct nfnl_exp *exp)
 
  548        return !!(exp->ce_mask & EXP_ATTR_ZONE);
 
  551uint16_t nfnl_exp_get_zone(
const struct nfnl_exp *exp)
 
  553        return exp->exp_zone;
 
  556void nfnl_exp_set_class(
struct nfnl_exp *exp, uint32_t 
class)
 
  558        exp->exp_class = 
class;
 
  559        exp->ce_mask |= EXP_ATTR_CLASS;
 
  562int nfnl_exp_test_class(
const struct nfnl_exp *exp)
 
  564        return !!(exp->ce_mask & EXP_ATTR_CLASS);
 
  567uint32_t nfnl_exp_get_class(
const struct nfnl_exp *exp)
 
  569        return exp->exp_class;
 
  572int nfnl_exp_set_fn(
struct nfnl_exp *exp, 
void *fn)
 
  575        exp->exp_fn = strdup(fn);
 
  579        exp->ce_mask |= EXP_ATTR_FN;
 
  583int nfnl_exp_test_fn(
const struct nfnl_exp *exp)
 
  585        return !!(exp->ce_mask & EXP_ATTR_FN);
 
  588const char * nfnl_exp_get_fn(
const struct nfnl_exp *exp)
 
  593void nfnl_exp_set_nat_dir(
struct nfnl_exp *exp, uint8_t nat_dir)
 
  595        exp->exp_nat_dir = nat_dir;
 
  596        exp->ce_mask |= EXP_ATTR_NAT_DIR;
 
  599int nfnl_exp_test_nat_dir(
const struct nfnl_exp *exp)
 
  601        return !!(exp->ce_mask & EXP_ATTR_NAT_DIR);
 
  604uint8_t nfnl_exp_get_nat_dir(
const struct nfnl_exp *exp)
 
  606        return exp->exp_nat_dir;
 
  609#define EXP_GET_TUPLE(e, t) \ 
  610        (t == NFNL_EXP_TUPLE_MASTER) ? \ 
  612        (t == NFNL_EXP_TUPLE_MASK) ? \ 
  614        (t == NFNL_EXP_TUPLE_NAT) ? \ 
  615                &(e->exp_nat) : &(exp->exp_expect) 
  617static int exp_get_src_attr(
int tuple)
 
  622                case NFNL_EXP_TUPLE_MASTER:
 
  623                        attr = EXP_ATTR_MASTER_IP_SRC;
 
  625                case NFNL_EXP_TUPLE_MASK:
 
  626                        attr = EXP_ATTR_MASK_IP_SRC;
 
  628                case NFNL_EXP_TUPLE_NAT:
 
  629                        attr = EXP_ATTR_NAT_IP_SRC;
 
  631                case NFNL_EXP_TUPLE_EXPECT:
 
  633                        attr = EXP_ATTR_EXPECT_IP_SRC;
 
  639static int exp_get_dst_attr(
int tuple)
 
  644                case NFNL_EXP_TUPLE_MASTER:
 
  645                        attr = EXP_ATTR_MASTER_IP_DST;
 
  647                case NFNL_EXP_TUPLE_MASK:
 
  648                        attr = EXP_ATTR_MASK_IP_DST;
 
  650                case NFNL_EXP_TUPLE_NAT:
 
  651                        attr = EXP_ATTR_NAT_IP_DST;
 
  653                case NFNL_EXP_TUPLE_EXPECT:
 
  655                        attr = EXP_ATTR_EXPECT_IP_DST;
 
  662static int exp_set_addr(
struct nfnl_exp *exp, 
struct nl_addr *addr,
 
  663                          int attr, 
struct nl_addr ** exp_addr)
 
  665        if (exp->ce_mask & EXP_ATTR_FAMILY) {
 
  666                if (addr->a_family != exp->exp_family)
 
  667                        return -NLE_AF_MISMATCH;
 
  669                nfnl_exp_set_family(exp, addr->a_family);
 
  676        exp->ce_mask |= attr;
 
  681int nfnl_exp_set_src(
struct nfnl_exp *exp, 
int tuple, 
struct nl_addr *addr)
 
  683        struct nfnl_exp_dir *dir = EXP_GET_TUPLE(exp, tuple);
 
  685        return exp_set_addr(exp, addr, exp_get_src_attr(tuple), &dir->src);
 
  688int nfnl_exp_set_dst(
struct nfnl_exp *exp, 
int tuple, 
struct nl_addr *addr)
 
  690        struct nfnl_exp_dir *dir = EXP_GET_TUPLE(exp, tuple);
 
  692        return exp_set_addr(exp, addr, exp_get_dst_attr(tuple), &dir->dst);
 
  695int nfnl_exp_test_src(
const struct nfnl_exp *exp, 
int tuple)
 
  697        return !!(exp->ce_mask & exp_get_src_attr(tuple));
 
  700int nfnl_exp_test_dst(
const struct nfnl_exp *exp, 
int tuple)
 
  702        return !!(exp->ce_mask & exp_get_dst_attr(tuple));
 
  705struct nl_addr *nfnl_exp_get_src(
const struct nfnl_exp *exp, 
int tuple)
 
  707        const struct nfnl_exp_dir *dir = EXP_GET_TUPLE(exp, tuple);
 
  709        if (!(exp->ce_mask & exp_get_src_attr(tuple)))
 
  714struct nl_addr *nfnl_exp_get_dst(
const struct nfnl_exp *exp, 
int tuple)
 
  716        const struct nfnl_exp_dir *dir = EXP_GET_TUPLE(exp, tuple);
 
  718        if (!(exp->ce_mask & exp_get_dst_attr(tuple)))
 
  723static int exp_get_l4protonum_attr(
int tuple)
 
  728                case NFNL_EXP_TUPLE_MASTER:
 
  729                        attr = EXP_ATTR_MASTER_L4PROTO_NUM;
 
  731                case NFNL_EXP_TUPLE_MASK:
 
  732                        attr = EXP_ATTR_MASK_L4PROTO_NUM;
 
  734                case NFNL_EXP_TUPLE_NAT:
 
  735                        attr = EXP_ATTR_NAT_L4PROTO_NUM;
 
  737                case NFNL_EXP_TUPLE_EXPECT:
 
  739                        attr = EXP_ATTR_EXPECT_L4PROTO_NUM;
 
  745void nfnl_exp_set_l4protonum(
struct nfnl_exp *exp, 
int tuple, uint8_t l4protonum)
 
  747        struct nfnl_exp_dir *dir = EXP_GET_TUPLE(exp, tuple);
 
  749        dir->proto.l4protonum = l4protonum;
 
  750        exp->ce_mask |= exp_get_l4protonum_attr(tuple);
 
  753int nfnl_exp_test_l4protonum(
const struct nfnl_exp *exp, 
int tuple)
 
  755        return !!(exp->ce_mask & exp_get_l4protonum_attr(tuple));
 
  758uint8_t nfnl_exp_get_l4protonum(
const struct nfnl_exp *exp, 
int tuple)
 
  760        const struct nfnl_exp_dir *dir = EXP_GET_TUPLE(exp, tuple);
 
  761        return dir->proto.l4protonum;
 
  764static int exp_get_l4ports_attr(
int tuple)
 
  769                case NFNL_EXP_TUPLE_MASTER:
 
  770                        attr = EXP_ATTR_MASTER_L4PROTO_PORTS;
 
  772                case NFNL_EXP_TUPLE_MASK:
 
  773                        attr = EXP_ATTR_MASK_L4PROTO_PORTS;
 
  775                case NFNL_EXP_TUPLE_NAT:
 
  776                        attr = EXP_ATTR_NAT_L4PROTO_PORTS;
 
  778                case NFNL_EXP_TUPLE_EXPECT:
 
  780                        attr = EXP_ATTR_EXPECT_L4PROTO_PORTS;
 
  786void nfnl_exp_set_ports(
struct nfnl_exp *exp, 
int tuple, uint16_t srcport, uint16_t dstport)
 
  788        struct nfnl_exp_dir *dir = EXP_GET_TUPLE(exp, tuple);
 
  790        dir->proto.l4protodata.port.src = srcport;
 
  791        dir->proto.l4protodata.port.dst = dstport;
 
  793        exp->ce_mask |= exp_get_l4ports_attr(tuple);
 
  796int nfnl_exp_test_ports(
const struct nfnl_exp *exp, 
int tuple)
 
  798        return !!(exp->ce_mask & exp_get_l4ports_attr(tuple));
 
  801uint16_t nfnl_exp_get_src_port(
const struct nfnl_exp *exp, 
int tuple)
 
  803        const struct nfnl_exp_dir *dir = EXP_GET_TUPLE(exp, tuple);
 
  804        return dir->proto.l4protodata.port.src;
 
  807uint16_t nfnl_exp_get_dst_port(
const struct nfnl_exp *exp, 
int tuple)
 
  809        const struct nfnl_exp_dir *dir = EXP_GET_TUPLE(exp, tuple);
 
  811        return dir->proto.l4protodata.port.dst;
 
  814static int exp_get_l4icmp_attr(
int tuple)
 
  819                case NFNL_EXP_TUPLE_MASTER:
 
  820                        attr = EXP_ATTR_MASTER_L4PROTO_ICMP;
 
  822                case NFNL_EXP_TUPLE_MASK:
 
  823                        attr = EXP_ATTR_MASK_L4PROTO_ICMP;
 
  825                case NFNL_EXP_TUPLE_NAT:
 
  826                        attr = EXP_ATTR_NAT_L4PROTO_ICMP;
 
  828                case NFNL_EXP_TUPLE_EXPECT:
 
  830                        attr = EXP_ATTR_EXPECT_L4PROTO_ICMP;
 
  836void nfnl_exp_set_icmp(
struct nfnl_exp *exp, 
int tuple, uint16_t 
id, uint8_t type, uint8_t code)
 
  838        struct nfnl_exp_dir *dir = EXP_GET_TUPLE(exp, tuple);
 
  840        dir->proto.l4protodata.icmp.id = id;
 
  841        dir->proto.l4protodata.icmp.type = type;
 
  842        dir->proto.l4protodata.icmp.code = code;
 
  844        exp->ce_mask |= exp_get_l4icmp_attr(tuple);
 
  847int nfnl_exp_test_icmp(
const struct nfnl_exp *exp, 
int tuple)
 
  849        int attr = exp_get_l4icmp_attr(tuple);
 
  850        return !!(exp->ce_mask & attr);
 
  853uint16_t nfnl_exp_get_icmp_id(
const struct nfnl_exp *exp, 
int tuple)
 
  855        const struct nfnl_exp_dir *dir = EXP_GET_TUPLE(exp, tuple);
 
  857        return dir->proto.l4protodata.icmp.id;
 
  860uint8_t nfnl_exp_get_icmp_type(
const struct nfnl_exp *exp, 
int tuple)
 
  862        const struct nfnl_exp_dir *dir = EXP_GET_TUPLE(exp, tuple);
 
  864        return dir->proto.l4protodata.icmp.type;
 
  867uint8_t nfnl_exp_get_icmp_code(
const struct nfnl_exp *exp, 
int tuple)
 
  869        const struct nfnl_exp_dir *dir = EXP_GET_TUPLE(exp, tuple);
 
  871        return dir->proto.l4protodata.icmp.code;
 
  876struct nl_object_ops exp_obj_ops = {
 
  877        .oo_name        = 
"netfilter/exp",
 
  878        .oo_size        = 
sizeof(
struct nfnl_exp),
 
  879        .oo_free_data   = exp_free_data,
 
  880        .oo_clone       = exp_clone,
 
  885        .oo_compare     = exp_compare,
 
  886        .oo_attrs2str   = exp_attrs2str,
 
struct nl_addr * nl_addr_get(struct nl_addr *addr)
Increase the reference counter of an abstract address.
 
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.
 
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_LINE
Dump object briefly on one line.
 
@ NL_DUMP_DETAILS
Dump all attributes but no statistics.