15 #include <sys/types.h>
16 #include <netinet/in.h>
17 #include <linux/netfilter/nfnetlink_conntrack.h>
18 #include <linux/netfilter/nf_conntrack_common.h>
19 #include <linux/netfilter/nf_conntrack_tcp.h>
21 #include <netlink-private/netlink.h>
22 #include <netlink/netfilter/nfnl.h>
23 #include <netlink/netfilter/exp.h>
32 #define EXP_ATTR_FAMILY (1UL << 0) // 8-bit
33 #define EXP_ATTR_TIMEOUT (1UL << 1) // 32-bit
34 #define EXP_ATTR_ID (1UL << 2) // 32-bit
35 #define EXP_ATTR_HELPER_NAME (1UL << 3) // string
36 #define EXP_ATTR_ZONE (1UL << 4) // 16-bit
37 #define EXP_ATTR_FLAGS (1UL << 5) // 32-bit
38 #define EXP_ATTR_CLASS (1UL << 6) // 32-bit
39 #define EXP_ATTR_FN (1UL << 7) // String
41 #define EXP_ATTR_EXPECT_IP_SRC (1UL << 8)
42 #define EXP_ATTR_EXPECT_IP_DST (1UL << 9)
43 #define EXP_ATTR_EXPECT_L4PROTO_NUM (1UL << 10)
44 #define EXP_ATTR_EXPECT_L4PROTO_PORTS (1UL << 11)
45 #define EXP_ATTR_EXPECT_L4PROTO_ICMP (1UL << 12)
46 #define EXP_ATTR_MASTER_IP_SRC (1UL << 13)
47 #define EXP_ATTR_MASTER_IP_DST (1UL << 14)
48 #define EXP_ATTR_MASTER_L4PROTO_NUM (1UL << 15)
49 #define EXP_ATTR_MASTER_L4PROTO_PORTS (1UL << 16)
50 #define EXP_ATTR_MASTER_L4PROTO_ICMP (1UL << 17)
51 #define EXP_ATTR_MASK_IP_SRC (1UL << 18)
52 #define EXP_ATTR_MASK_IP_DST (1UL << 19)
53 #define EXP_ATTR_MASK_L4PROTO_NUM (1UL << 20)
54 #define EXP_ATTR_MASK_L4PROTO_PORTS (1UL << 21)
55 #define EXP_ATTR_MASK_L4PROTO_ICMP (1UL << 22)
56 #define EXP_ATTR_NAT_IP_SRC (1UL << 23)
57 #define EXP_ATTR_NAT_IP_DST (1UL << 24)
58 #define EXP_ATTR_NAT_L4PROTO_NUM (1UL << 25)
59 #define EXP_ATTR_NAT_L4PROTO_PORTS (1UL << 26)
60 #define EXP_ATTR_NAT_L4PROTO_ICMP (1UL << 27)
61 #define EXP_ATTR_NAT_DIR (1UL << 28)
64 static void exp_free_data(
struct nl_object *c)
66 struct nfnl_exp *exp = (
struct nfnl_exp *) c;
81 free(exp->exp_helper_name);
84 static int exp_clone(
struct nl_object *_dst,
struct nl_object *_src)
86 struct nfnl_exp *dst = (
struct nfnl_exp *) _dst;
87 struct nfnl_exp *src = (
struct nfnl_exp *) _src;
91 if (src->exp_expect.src) {
95 dst->exp_expect.src = addr;
98 if (src->exp_expect.dst) {
102 dst->exp_expect.dst = addr;
106 if (src->exp_master.src) {
110 dst->exp_master.src = addr;
113 if (src->exp_master.dst) {
117 dst->exp_master.dst = addr;
121 if (src->exp_mask.src) {
125 dst->exp_mask.src = addr;
128 if (src->exp_mask.dst) {
132 dst->exp_mask.dst = addr;
136 if (src->exp_nat.src) {
140 dst->exp_nat.src = addr;
143 if (src->exp_nat.dst) {
147 dst->exp_nat.dst = addr;
151 dst->exp_fn = strdup(src->exp_fn);
153 if (src->exp_helper_name)
154 dst->exp_helper_name = strdup(src->exp_helper_name);
159 static void dump_addr(
struct nl_dump_params *p,
struct nl_addr *addr,
int port)
172 static void dump_icmp(
struct nl_dump_params *p,
struct nfnl_exp *exp,
int tuple)
174 if (nfnl_exp_test_icmp(exp, tuple)) {
176 nl_dump(p,
"icmp type %d ", nfnl_exp_get_icmp_type(exp, tuple));
178 nl_dump(p,
"code %d ", nfnl_exp_get_icmp_code(exp, tuple));
180 nl_dump(p,
"id %d ", nfnl_exp_get_icmp_id(exp, tuple));
184 static void exp_dump_tuples(
struct nfnl_exp *exp,
struct nl_dump_params *p)
186 struct nl_addr *tuple_src, *tuple_dst;
187 int tuple_sport, tuple_dport;
191 for (i = NFNL_EXP_TUPLE_EXPECT; i < NFNL_EXP_TUPLE_MAX; i++) {
198 if (nfnl_exp_test_src(exp, i))
199 tuple_src = nfnl_exp_get_src(exp, i);
200 if (nfnl_exp_test_dst(exp, i))
201 tuple_dst = nfnl_exp_get_dst(exp, i);
204 if (nfnl_exp_test_l4protonum(exp, i)) {
206 nl_ip_proto2str(nfnl_exp_get_l4protonum(exp, i), buf,
sizeof(buf)));
209 if (nfnl_exp_test_ports(exp, i)) {
210 tuple_sport = nfnl_exp_get_src_port(exp, i);
211 tuple_dport = nfnl_exp_get_dst_port(exp, i);
214 dump_addr(p, tuple_src, tuple_sport);
215 dump_addr(p, tuple_dst, tuple_dport);
216 dump_icmp(p, exp, 0);
219 if (nfnl_exp_test_nat_dir(exp))
220 nl_dump(p,
"nat dir %s ", exp->exp_nat_dir);
225 static void exp_dump_line(
struct nl_object *a,
struct nl_dump_params *p)
227 struct nfnl_exp *exp = (
struct nfnl_exp *) a;
231 exp_dump_tuples(exp, p);
236 static void exp_dump_details(
struct nl_object *a,
struct nl_dump_params *p)
238 struct nfnl_exp *exp = (
struct nfnl_exp *) a;
244 nl_dump(p,
" id 0x%x ", exp->exp_id);
245 nl_dump_line(p,
"family %s ",
246 nl_af2str(exp->exp_family, buf,
sizeof(buf)));
248 if (nfnl_exp_test_timeout(exp)) {
249 uint64_t timeout_ms = nfnl_exp_get_timeout(exp) * 1000UL;
254 if (nfnl_exp_test_helper_name(exp))
255 nl_dump(p,
"helper %s ", exp->exp_helper_name);
257 if (nfnl_exp_test_fn(exp))
258 nl_dump(p,
"fn %s ", exp->exp_fn);
260 if (nfnl_exp_test_class(exp))
261 nl_dump(p,
"class %u ", nfnl_exp_get_class(exp));
263 if (nfnl_exp_test_zone(exp))
264 nl_dump(p,
"zone %u ", nfnl_exp_get_zone(exp));
266 if (nfnl_exp_test_flags(exp))
268 #define PRINT_FLAG(str) \
269 { nl_dump(p, "%s%s", fp++ ? "," : "", (str)); }
271 if (exp->exp_flags & NF_CT_EXPECT_PERMANENT)
272 PRINT_FLAG(
"PERMANENT");
273 if (exp->exp_flags & NF_CT_EXPECT_INACTIVE)
274 PRINT_FLAG(
"INACTIVE");
275 if (exp->exp_flags & NF_CT_EXPECT_USERSPACE)
276 PRINT_FLAG(
"USERSPACE");
279 if (nfnl_exp_test_flags(exp))
285 static int exp_cmp_l4proto_ports (
union nfnl_exp_protodata *a,
union nfnl_exp_protodata *b) {
288 d = ( (a->port.src != b->port.src) ||
289 (a->port.dst != b->port.dst) );
294 static int exp_cmp_l4proto_icmp (
union nfnl_exp_protodata *a,
union nfnl_exp_protodata *b) {
297 d = ( (a->icmp.code != b->icmp.code) ||
298 (a->icmp.type != b->icmp.type) ||
299 (a->icmp.id != b->icmp.id) );
304 static int exp_compare(
struct nl_object *_a,
struct nl_object *_b,
305 uint32_t attrs,
int flags)
307 struct nfnl_exp *a = (
struct nfnl_exp *) _a;
308 struct nfnl_exp *b = (
struct nfnl_exp *) _b;
311 #define EXP_DIFF(ATTR, EXPR) ATTR_DIFF(attrs, EXP_ATTR_##ATTR, a, b, EXPR)
312 #define EXP_DIFF_VAL(ATTR, FIELD) EXP_DIFF(ATTR, a->FIELD != b->FIELD)
313 #define EXP_DIFF_STRING(ATTR, FIELD) EXP_DIFF(ATTR, (strcmp(a->FIELD, b->FIELD) != 0))
314 #define EXP_DIFF_ADDR(ATTR, FIELD) \
315 ((flags & LOOSE_COMPARISON) \
316 ? EXP_DIFF(ATTR, nl_addr_cmp_prefix(a->FIELD, b->FIELD)) \
317 : EXP_DIFF(ATTR, nl_addr_cmp(a->FIELD, b->FIELD)))
318 #define EXP_DIFF_L4PROTO_PORTS(ATTR, FIELD) \
319 EXP_DIFF(ATTR, exp_cmp_l4proto_ports(&(a->FIELD), &(b->FIELD)))
320 #define EXP_DIFF_L4PROTO_ICMP(ATTR, FIELD) \
321 EXP_DIFF(ATTR, exp_cmp_l4proto_icmp(&(a->FIELD), &(b->FIELD)))
323 diff |= EXP_DIFF_VAL(FAMILY, exp_family);
324 diff |= EXP_DIFF_VAL(TIMEOUT, exp_timeout);
325 diff |= EXP_DIFF_VAL(ID, exp_id);
326 diff |= EXP_DIFF_VAL(ZONE, exp_zone);
327 diff |= EXP_DIFF_VAL(CLASS, exp_class);
328 diff |= EXP_DIFF_VAL(FLAGS, exp_flags);
329 diff |= EXP_DIFF_VAL(NAT_DIR, exp_nat_dir);
331 diff |= EXP_DIFF_STRING(FN, exp_fn);
332 diff |= EXP_DIFF_STRING(HELPER_NAME, exp_helper_name);
334 diff |= EXP_DIFF_ADDR(EXPECT_IP_SRC, exp_expect.src);
335 diff |= EXP_DIFF_ADDR(EXPECT_IP_DST, exp_expect.dst);
336 diff |= EXP_DIFF_VAL(EXPECT_L4PROTO_NUM, exp_expect.proto.l4protonum);
337 diff |= EXP_DIFF_L4PROTO_PORTS(EXPECT_L4PROTO_PORTS, exp_expect.proto.l4protodata);
338 diff |= EXP_DIFF_L4PROTO_ICMP(EXPECT_L4PROTO_ICMP, exp_expect.proto.l4protodata);
340 diff |= EXP_DIFF_ADDR(MASTER_IP_SRC, exp_master.src);
341 diff |= EXP_DIFF_ADDR(MASTER_IP_DST, exp_master.dst);
342 diff |= EXP_DIFF_VAL(MASTER_L4PROTO_NUM, exp_master.proto.l4protonum);
343 diff |= EXP_DIFF_L4PROTO_PORTS(MASTER_L4PROTO_PORTS, exp_master.proto.l4protodata);
344 diff |= EXP_DIFF_L4PROTO_ICMP(MASTER_L4PROTO_ICMP, exp_master.proto.l4protodata);
346 diff |= EXP_DIFF_ADDR(MASK_IP_SRC, exp_mask.src);
347 diff |= EXP_DIFF_ADDR(MASK_IP_DST, exp_mask.dst);
348 diff |= EXP_DIFF_VAL(MASK_L4PROTO_NUM, exp_mask.proto.l4protonum);
349 diff |= EXP_DIFF_L4PROTO_PORTS(MASK_L4PROTO_PORTS, exp_mask.proto.l4protodata);
350 diff |= EXP_DIFF_L4PROTO_ICMP(MASK_L4PROTO_ICMP, exp_mask.proto.l4protodata);
352 diff |= EXP_DIFF_ADDR(NAT_IP_SRC, exp_nat.src);
353 diff |= EXP_DIFF_ADDR(NAT_IP_DST, exp_nat.dst);
354 diff |= EXP_DIFF_VAL(NAT_L4PROTO_NUM, exp_nat.proto.l4protonum);
355 diff |= EXP_DIFF_L4PROTO_PORTS(NAT_L4PROTO_PORTS, exp_nat.proto.l4protodata);
356 diff |= EXP_DIFF_L4PROTO_ICMP(NAT_L4PROTO_ICMP, exp_nat.proto.l4protodata);
360 #undef EXP_DIFF_STRING
362 #undef EXP_DIFF_L4PROTO_PORTS
363 #undef EXP_DIFF_L4PROTO_ICMP
369 static const struct trans_tbl exp_attrs[] = {
370 __ADD(EXP_ATTR_FAMILY, family)
371 __ADD(EXP_ATTR_TIMEOUT, timeout)
372 __ADD(EXP_ATTR_ID,
id)
373 __ADD(EXP_ATTR_HELPER_NAME, helpername)
374 __ADD(EXP_ATTR_ZONE, zone)
375 __ADD(EXP_ATTR_CLASS, class)
376 __ADD(EXP_ATTR_FLAGS, flags)
377 __ADD(EXP_ATTR_FN, function)
378 __ADD(EXP_ATTR_EXPECT_IP_SRC, expectipsrc)
379 __ADD(EXP_ATTR_EXPECT_IP_DST, expectipdst)
380 __ADD(EXP_ATTR_EXPECT_L4PROTO_NUM, expectprotonum)
381 __ADD(EXP_ATTR_EXPECT_L4PROTO_PORTS, expectports)
382 __ADD(EXP_ATTR_EXPECT_L4PROTO_ICMP, expecticmp)
383 __ADD(EXP_ATTR_MASTER_IP_SRC, masteripsrc)
384 __ADD(EXP_ATTR_MASTER_IP_DST, masteripdst)
385 __ADD(EXP_ATTR_MASTER_L4PROTO_NUM, masterprotonum)
386 __ADD(EXP_ATTR_MASTER_L4PROTO_PORTS, masterports)
387 __ADD(EXP_ATTR_MASTER_L4PROTO_ICMP, mastericmp)
388 __ADD(EXP_ATTR_MASK_IP_SRC, maskipsrc)
389 __ADD(EXP_ATTR_MASK_IP_DST, maskipdst)
390 __ADD(EXP_ATTR_MASK_L4PROTO_NUM, maskprotonum)
391 __ADD(EXP_ATTR_MASK_L4PROTO_PORTS, maskports)
392 __ADD(EXP_ATTR_MASK_L4PROTO_ICMP, maskicmp)
393 __ADD(EXP_ATTR_NAT_IP_SRC, natipsrc)
394 __ADD(EXP_ATTR_NAT_IP_DST, natipdst)
395 __ADD(EXP_ATTR_NAT_L4PROTO_NUM, natprotonum)
396 __ADD(EXP_ATTR_NAT_L4PROTO_PORTS, natports)
397 __ADD(EXP_ATTR_NAT_L4PROTO_ICMP, naticmp)
398 __ADD(EXP_ATTR_NAT_DIR, natdir)
401 static
char *exp_attrs2str(
int attrs,
char *buf,
size_t len)
403 return __flags2str(attrs, buf, len, exp_attrs, ARRAY_SIZE(exp_attrs));
411 struct nfnl_exp *nfnl_exp_alloc(
void)
416 void nfnl_exp_get(
struct nfnl_exp *exp)
421 void nfnl_exp_put(
struct nfnl_exp *exp)
433 void nfnl_exp_set_family(
struct nfnl_exp *exp, uint8_t family)
435 exp->exp_family = family;
436 exp->ce_mask |= EXP_ATTR_FAMILY;
439 uint8_t nfnl_exp_get_family(
const struct nfnl_exp *exp)
441 if (exp->ce_mask & EXP_ATTR_FAMILY)
442 return exp->exp_family;
447 void nfnl_exp_set_flags(
struct nfnl_exp *exp, uint32_t flags)
449 exp->exp_flags |= flags;
450 exp->ce_mask |= EXP_ATTR_FLAGS;
453 int nfnl_exp_test_flags(
const struct nfnl_exp *exp)
455 return !!(exp->ce_mask & EXP_ATTR_FLAGS);
458 void nfnl_exp_unset_flags(
struct nfnl_exp *exp, uint32_t flags)
460 exp->exp_flags &= ~flags;
461 exp->ce_mask |= EXP_ATTR_FLAGS;
464 uint32_t nfnl_exp_get_flags(
const struct nfnl_exp *exp)
466 return exp->exp_flags;
469 static const struct trans_tbl flag_table[] = {
470 __ADD(IPS_EXPECTED, expected)
471 __ADD(IPS_SEEN_REPLY, seen_reply)
472 __ADD(IPS_ASSURED, assured)
475 char * nfnl_exp_flags2str(
int flags,
char *buf,
size_t len)
477 return __flags2str(flags, buf, len, flag_table,
478 ARRAY_SIZE(flag_table));
481 int nfnl_exp_str2flags(
const char *name)
483 return __str2flags(name, flag_table, ARRAY_SIZE(flag_table));
486 void nfnl_exp_set_timeout(
struct nfnl_exp *exp, uint32_t timeout)
488 exp->exp_timeout = timeout;
489 exp->ce_mask |= EXP_ATTR_TIMEOUT;
492 int nfnl_exp_test_timeout(
const struct nfnl_exp *exp)
494 return !!(exp->ce_mask & EXP_ATTR_TIMEOUT);
497 uint32_t nfnl_exp_get_timeout(
const struct nfnl_exp *exp)
499 return exp->exp_timeout;
502 void nfnl_exp_set_id(
struct nfnl_exp *exp, uint32_t
id)
505 exp->ce_mask |= EXP_ATTR_ID;
508 int nfnl_exp_test_id(
const struct nfnl_exp *exp)
510 return !!(exp->ce_mask & EXP_ATTR_ID);
513 uint32_t nfnl_exp_get_id(
const struct nfnl_exp *exp)
518 int nfnl_exp_set_helper_name(
struct nfnl_exp *exp,
void *name)
520 free(exp->exp_helper_name);
521 exp->exp_helper_name = strdup(name);
522 if (!exp->exp_helper_name)
525 exp->ce_mask |= EXP_ATTR_HELPER_NAME;
529 int nfnl_exp_test_helper_name(
const struct nfnl_exp *exp)
531 return !!(exp->ce_mask & EXP_ATTR_HELPER_NAME);
534 const char * nfnl_exp_get_helper_name(
const struct nfnl_exp *exp)
536 return exp->exp_helper_name;
539 void nfnl_exp_set_zone(
struct nfnl_exp *exp, uint16_t zone)
541 exp->exp_zone = zone;
542 exp->ce_mask |= EXP_ATTR_ZONE;
545 int nfnl_exp_test_zone(
const struct nfnl_exp *exp)
547 return !!(exp->ce_mask & EXP_ATTR_ZONE);
550 uint16_t nfnl_exp_get_zone(
const struct nfnl_exp *exp)
552 return exp->exp_zone;
555 void nfnl_exp_set_class(
struct nfnl_exp *exp, uint32_t
class)
557 exp->exp_class =
class;
558 exp->ce_mask |= EXP_ATTR_CLASS;
561 int nfnl_exp_test_class(
const struct nfnl_exp *exp)
563 return !!(exp->ce_mask & EXP_ATTR_CLASS);
566 uint32_t nfnl_exp_get_class(
const struct nfnl_exp *exp)
568 return exp->exp_class;
571 int nfnl_exp_set_fn(
struct nfnl_exp *exp,
void *fn)
574 exp->exp_fn = strdup(fn);
578 exp->ce_mask |= EXP_ATTR_FN;
582 int nfnl_exp_test_fn(
const struct nfnl_exp *exp)
584 return !!(exp->ce_mask & EXP_ATTR_FN);
587 const char * nfnl_exp_get_fn(
const struct nfnl_exp *exp)
592 void nfnl_exp_set_nat_dir(
struct nfnl_exp *exp, uint8_t nat_dir)
594 exp->exp_nat_dir = nat_dir;
595 exp->ce_mask |= EXP_ATTR_NAT_DIR;
598 int nfnl_exp_test_nat_dir(
const struct nfnl_exp *exp)
600 return !!(exp->ce_mask & EXP_ATTR_NAT_DIR);
603 uint8_t nfnl_exp_get_nat_dir(
const struct nfnl_exp *exp)
605 return exp->exp_nat_dir;
608 #define EXP_GET_TUPLE(e, t) \
609 (t == NFNL_EXP_TUPLE_MASTER) ? \
611 (t == NFNL_EXP_TUPLE_MASK) ? \
613 (t == NFNL_EXP_TUPLE_NAT) ? \
614 &(e->exp_nat) : &(exp->exp_expect)
616 static int exp_get_src_attr(
int tuple)
621 case NFNL_EXP_TUPLE_MASTER:
622 attr = EXP_ATTR_MASTER_IP_SRC;
624 case NFNL_EXP_TUPLE_MASK:
625 attr = EXP_ATTR_MASK_IP_SRC;
627 case NFNL_EXP_TUPLE_NAT:
628 attr = EXP_ATTR_NAT_IP_SRC;
630 case NFNL_EXP_TUPLE_EXPECT:
632 attr = EXP_ATTR_EXPECT_IP_SRC;
638 static int exp_get_dst_attr(
int tuple)
643 case NFNL_EXP_TUPLE_MASTER:
644 attr = EXP_ATTR_MASTER_IP_DST;
646 case NFNL_EXP_TUPLE_MASK:
647 attr = EXP_ATTR_MASK_IP_DST;
649 case NFNL_EXP_TUPLE_NAT:
650 attr = EXP_ATTR_NAT_IP_DST;
652 case NFNL_EXP_TUPLE_EXPECT:
654 attr = EXP_ATTR_EXPECT_IP_DST;
661 static int exp_set_addr(
struct nfnl_exp *exp,
struct nl_addr *addr,
662 int attr,
struct nl_addr ** exp_addr)
664 if (exp->ce_mask & EXP_ATTR_FAMILY) {
665 if (addr->a_family != exp->exp_family)
666 return -NLE_AF_MISMATCH;
668 nfnl_exp_set_family(exp, addr->a_family);
675 exp->ce_mask |= attr;
680 int nfnl_exp_set_src(
struct nfnl_exp *exp,
int tuple,
struct nl_addr *addr)
682 struct nfnl_exp_dir *dir = EXP_GET_TUPLE(exp, tuple);
684 return exp_set_addr(exp, addr, exp_get_src_attr(tuple), &dir->src);
687 int nfnl_exp_set_dst(
struct nfnl_exp *exp,
int tuple,
struct nl_addr *addr)
689 struct nfnl_exp_dir *dir = EXP_GET_TUPLE(exp, tuple);
691 return exp_set_addr(exp, addr, exp_get_dst_attr(tuple), &dir->dst);
694 int nfnl_exp_test_src(
const struct nfnl_exp *exp,
int tuple)
696 return !!(exp->ce_mask & exp_get_src_attr(tuple));
699 int nfnl_exp_test_dst(
const struct nfnl_exp *exp,
int tuple)
701 return !!(exp->ce_mask & exp_get_dst_attr(tuple));
704 struct nl_addr *nfnl_exp_get_src(
const struct nfnl_exp *exp,
int tuple)
706 const struct nfnl_exp_dir *dir = EXP_GET_TUPLE(exp, tuple);
708 if (!(exp->ce_mask & exp_get_src_attr(tuple)))
713 struct nl_addr *nfnl_exp_get_dst(
const struct nfnl_exp *exp,
int tuple)
715 const struct nfnl_exp_dir *dir = EXP_GET_TUPLE(exp, tuple);
717 if (!(exp->ce_mask & exp_get_dst_attr(tuple)))
722 static int exp_get_l4protonum_attr(
int tuple)
727 case NFNL_EXP_TUPLE_MASTER:
728 attr = EXP_ATTR_MASTER_L4PROTO_NUM;
730 case NFNL_EXP_TUPLE_MASK:
731 attr = EXP_ATTR_MASK_L4PROTO_NUM;
733 case NFNL_EXP_TUPLE_NAT:
734 attr = EXP_ATTR_NAT_L4PROTO_NUM;
736 case NFNL_EXP_TUPLE_EXPECT:
738 attr = EXP_ATTR_EXPECT_L4PROTO_NUM;
744 void nfnl_exp_set_l4protonum(
struct nfnl_exp *exp,
int tuple, uint8_t l4protonum)
746 struct nfnl_exp_dir *dir = EXP_GET_TUPLE(exp, tuple);
748 dir->proto.l4protonum = l4protonum;
749 exp->ce_mask |= exp_get_l4protonum_attr(tuple);
752 int nfnl_exp_test_l4protonum(
const struct nfnl_exp *exp,
int tuple)
754 return !!(exp->ce_mask & exp_get_l4protonum_attr(tuple));
757 uint8_t nfnl_exp_get_l4protonum(
const struct nfnl_exp *exp,
int tuple)
759 const struct nfnl_exp_dir *dir = EXP_GET_TUPLE(exp, tuple);
760 return dir->proto.l4protonum;
763 static int exp_get_l4ports_attr(
int tuple)
768 case NFNL_EXP_TUPLE_MASTER:
769 attr = EXP_ATTR_MASTER_L4PROTO_PORTS;
771 case NFNL_EXP_TUPLE_MASK:
772 attr = EXP_ATTR_MASK_L4PROTO_PORTS;
774 case NFNL_EXP_TUPLE_NAT:
775 attr = EXP_ATTR_NAT_L4PROTO_PORTS;
777 case NFNL_EXP_TUPLE_EXPECT:
779 attr = EXP_ATTR_EXPECT_L4PROTO_PORTS;
785 void nfnl_exp_set_ports(
struct nfnl_exp *exp,
int tuple, uint16_t srcport, uint16_t dstport)
787 struct nfnl_exp_dir *dir = EXP_GET_TUPLE(exp, tuple);
789 dir->proto.l4protodata.port.src = srcport;
790 dir->proto.l4protodata.port.dst = dstport;
792 exp->ce_mask |= exp_get_l4ports_attr(tuple);
795 int nfnl_exp_test_ports(
const struct nfnl_exp *exp,
int tuple)
797 return !!(exp->ce_mask & exp_get_l4ports_attr(tuple));
800 uint16_t nfnl_exp_get_src_port(
const struct nfnl_exp *exp,
int tuple)
802 const struct nfnl_exp_dir *dir = EXP_GET_TUPLE(exp, tuple);
803 return dir->proto.l4protodata.port.src;
806 uint16_t nfnl_exp_get_dst_port(
const struct nfnl_exp *exp,
int tuple)
808 const struct nfnl_exp_dir *dir = EXP_GET_TUPLE(exp, tuple);
810 return dir->proto.l4protodata.port.dst;
813 static int exp_get_l4icmp_attr(
int tuple)
818 case NFNL_EXP_TUPLE_MASTER:
819 attr = EXP_ATTR_MASTER_L4PROTO_ICMP;
821 case NFNL_EXP_TUPLE_MASK:
822 attr = EXP_ATTR_MASK_L4PROTO_ICMP;
824 case NFNL_EXP_TUPLE_NAT:
825 attr = EXP_ATTR_NAT_L4PROTO_ICMP;
827 case NFNL_EXP_TUPLE_EXPECT:
829 attr = EXP_ATTR_EXPECT_L4PROTO_ICMP;
835 void nfnl_exp_set_icmp(
struct nfnl_exp *exp,
int tuple, uint16_t
id, uint8_t type, uint8_t code)
837 struct nfnl_exp_dir *dir = EXP_GET_TUPLE(exp, tuple);
839 dir->proto.l4protodata.icmp.id = id;
840 dir->proto.l4protodata.icmp.type = type;
841 dir->proto.l4protodata.icmp.code = code;
843 exp->ce_mask |= exp_get_l4icmp_attr(tuple);
846 int nfnl_exp_test_icmp(
const struct nfnl_exp *exp,
int tuple)
848 int attr = exp_get_l4icmp_attr(tuple);
849 return !!(exp->ce_mask & attr);
852 uint16_t nfnl_exp_get_icmp_id(
const struct nfnl_exp *exp,
int tuple)
854 const struct nfnl_exp_dir *dir = EXP_GET_TUPLE(exp, tuple);
856 return dir->proto.l4protodata.icmp.id;
859 uint8_t nfnl_exp_get_icmp_type(
const struct nfnl_exp *exp,
int tuple)
861 const struct nfnl_exp_dir *dir = EXP_GET_TUPLE(exp, tuple);
863 return dir->proto.l4protodata.icmp.type;
866 uint8_t nfnl_exp_get_icmp_code(
const struct nfnl_exp *exp,
int tuple)
868 const struct nfnl_exp_dir *dir = EXP_GET_TUPLE(exp, tuple);
870 return dir->proto.l4protodata.icmp.code;
875 struct nl_object_ops exp_obj_ops = {
876 .oo_name =
"netfilter/exp",
877 .oo_size =
sizeof(
struct nfnl_exp),
878 .oo_free_data = exp_free_data,
879 .oo_clone = exp_clone,
884 .oo_compare = exp_compare,
885 .oo_attrs2str = exp_attrs2str,