16 #include <sys/types.h> 17 #include <netinet/in.h> 18 #include <linux/netfilter/nfnetlink_conntrack.h> 19 #include <linux/netfilter/nf_conntrack_common.h> 20 #include <linux/netfilter/nf_conntrack_tcp.h> 22 #include <netlink-private/netlink.h> 23 #include <netlink/netfilter/nfnl.h> 24 #include <netlink/netfilter/exp.h> 33 #define EXP_ATTR_FAMILY (1UL << 0) // 8-bit 34 #define EXP_ATTR_TIMEOUT (1UL << 1) // 32-bit 35 #define EXP_ATTR_ID (1UL << 2) // 32-bit 36 #define EXP_ATTR_HELPER_NAME (1UL << 3) // string 37 #define EXP_ATTR_ZONE (1UL << 4) // 16-bit 38 #define EXP_ATTR_FLAGS (1UL << 5) // 32-bit 39 #define EXP_ATTR_CLASS (1UL << 6) // 32-bit 40 #define EXP_ATTR_FN (1UL << 7) // String 42 #define EXP_ATTR_EXPECT_IP_SRC (1UL << 8) 43 #define EXP_ATTR_EXPECT_IP_DST (1UL << 9) 44 #define EXP_ATTR_EXPECT_L4PROTO_NUM (1UL << 10) 45 #define EXP_ATTR_EXPECT_L4PROTO_PORTS (1UL << 11) 46 #define EXP_ATTR_EXPECT_L4PROTO_ICMP (1UL << 12) 47 #define EXP_ATTR_MASTER_IP_SRC (1UL << 13) 48 #define EXP_ATTR_MASTER_IP_DST (1UL << 14) 49 #define EXP_ATTR_MASTER_L4PROTO_NUM (1UL << 15) 50 #define EXP_ATTR_MASTER_L4PROTO_PORTS (1UL << 16) 51 #define EXP_ATTR_MASTER_L4PROTO_ICMP (1UL << 17) 52 #define EXP_ATTR_MASK_IP_SRC (1UL << 18) 53 #define EXP_ATTR_MASK_IP_DST (1UL << 19) 54 #define EXP_ATTR_MASK_L4PROTO_NUM (1UL << 20) 55 #define EXP_ATTR_MASK_L4PROTO_PORTS (1UL << 21) 56 #define EXP_ATTR_MASK_L4PROTO_ICMP (1UL << 22) 57 #define EXP_ATTR_NAT_IP_SRC (1UL << 23) 58 #define EXP_ATTR_NAT_IP_DST (1UL << 24) 59 #define EXP_ATTR_NAT_L4PROTO_NUM (1UL << 25) 60 #define EXP_ATTR_NAT_L4PROTO_PORTS (1UL << 26) 61 #define EXP_ATTR_NAT_L4PROTO_ICMP (1UL << 27) 62 #define EXP_ATTR_NAT_DIR (1UL << 28) 65 static void exp_free_data(
struct nl_object *c)
67 struct nfnl_exp *exp = (
struct nfnl_exp *) c;
82 free(exp->exp_helper_name);
85 static int exp_clone(
struct nl_object *_dst,
struct nl_object *_src)
87 struct nfnl_exp *dst = (
struct nfnl_exp *) _dst;
88 struct nfnl_exp *src = (
struct nfnl_exp *) _src;
92 if (src->exp_expect.src) {
96 dst->exp_expect.src = addr;
99 if (src->exp_expect.dst) {
103 dst->exp_expect.dst = addr;
107 if (src->exp_master.src) {
111 dst->exp_master.src = addr;
114 if (src->exp_master.dst) {
118 dst->exp_master.dst = addr;
122 if (src->exp_mask.src) {
126 dst->exp_mask.src = addr;
129 if (src->exp_mask.dst) {
133 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);
160 static void dump_addr(
struct nl_dump_params *p,
struct nl_addr *addr,
int port)
173 static 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));
185 static 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 %s ", exp->exp_nat_dir);
226 static 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);
237 static 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))
286 static 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) );
295 static 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) );
305 static 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 370 static 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),
402 static char *exp_attrs2str(
int attrs,
char *buf,
size_t len)
404 return __flags2str(attrs, buf, len, exp_attrs, ARRAY_SIZE(exp_attrs));
412 struct nfnl_exp *nfnl_exp_alloc(
void)
417 void nfnl_exp_get(
struct nfnl_exp *exp)
422 void nfnl_exp_put(
struct nfnl_exp *exp)
434 void nfnl_exp_set_family(
struct nfnl_exp *exp, uint8_t family)
436 exp->exp_family = family;
437 exp->ce_mask |= EXP_ATTR_FAMILY;
440 uint8_t nfnl_exp_get_family(
const struct nfnl_exp *exp)
442 if (exp->ce_mask & EXP_ATTR_FAMILY)
443 return exp->exp_family;
448 void nfnl_exp_set_flags(
struct nfnl_exp *exp, uint32_t flags)
450 exp->exp_flags |= flags;
451 exp->ce_mask |= EXP_ATTR_FLAGS;
454 int nfnl_exp_test_flags(
const struct nfnl_exp *exp)
456 return !!(exp->ce_mask & EXP_ATTR_FLAGS);
459 void nfnl_exp_unset_flags(
struct nfnl_exp *exp, uint32_t flags)
461 exp->exp_flags &= ~flags;
462 exp->ce_mask |= EXP_ATTR_FLAGS;
465 uint32_t nfnl_exp_get_flags(
const struct nfnl_exp *exp)
467 return exp->exp_flags;
470 static const struct trans_tbl flag_table[] = {
471 __ADD(IPS_EXPECTED, expected),
472 __ADD(IPS_SEEN_REPLY, seen_reply),
473 __ADD(IPS_ASSURED, assured),
476 char * nfnl_exp_flags2str(
int flags,
char *buf,
size_t len)
478 return __flags2str(flags, buf, len, flag_table,
479 ARRAY_SIZE(flag_table));
482 int nfnl_exp_str2flags(
const char *name)
484 return __str2flags(name, flag_table, ARRAY_SIZE(flag_table));
487 void nfnl_exp_set_timeout(
struct nfnl_exp *exp, uint32_t timeout)
489 exp->exp_timeout = timeout;
490 exp->ce_mask |= EXP_ATTR_TIMEOUT;
493 int nfnl_exp_test_timeout(
const struct nfnl_exp *exp)
495 return !!(exp->ce_mask & EXP_ATTR_TIMEOUT);
498 uint32_t nfnl_exp_get_timeout(
const struct nfnl_exp *exp)
500 return exp->exp_timeout;
503 void nfnl_exp_set_id(
struct nfnl_exp *exp, uint32_t
id)
506 exp->ce_mask |= EXP_ATTR_ID;
509 int nfnl_exp_test_id(
const struct nfnl_exp *exp)
511 return !!(exp->ce_mask & EXP_ATTR_ID);
514 uint32_t nfnl_exp_get_id(
const struct nfnl_exp *exp)
519 int 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;
530 int nfnl_exp_test_helper_name(
const struct nfnl_exp *exp)
532 return !!(exp->ce_mask & EXP_ATTR_HELPER_NAME);
535 const char * nfnl_exp_get_helper_name(
const struct nfnl_exp *exp)
537 return exp->exp_helper_name;
540 void nfnl_exp_set_zone(
struct nfnl_exp *exp, uint16_t zone)
542 exp->exp_zone = zone;
543 exp->ce_mask |= EXP_ATTR_ZONE;
546 int nfnl_exp_test_zone(
const struct nfnl_exp *exp)
548 return !!(exp->ce_mask & EXP_ATTR_ZONE);
551 uint16_t nfnl_exp_get_zone(
const struct nfnl_exp *exp)
553 return exp->exp_zone;
556 void nfnl_exp_set_class(
struct nfnl_exp *exp, uint32_t
class)
558 exp->exp_class =
class;
559 exp->ce_mask |= EXP_ATTR_CLASS;
562 int nfnl_exp_test_class(
const struct nfnl_exp *exp)
564 return !!(exp->ce_mask & EXP_ATTR_CLASS);
567 uint32_t nfnl_exp_get_class(
const struct nfnl_exp *exp)
569 return exp->exp_class;
572 int nfnl_exp_set_fn(
struct nfnl_exp *exp,
void *fn)
575 exp->exp_fn = strdup(fn);
579 exp->ce_mask |= EXP_ATTR_FN;
583 int nfnl_exp_test_fn(
const struct nfnl_exp *exp)
585 return !!(exp->ce_mask & EXP_ATTR_FN);
588 const char * nfnl_exp_get_fn(
const struct nfnl_exp *exp)
593 void 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;
599 int nfnl_exp_test_nat_dir(
const struct nfnl_exp *exp)
601 return !!(exp->ce_mask & EXP_ATTR_NAT_DIR);
604 uint8_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) 617 static 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;
639 static 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;
662 static 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;
681 int 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);
688 int 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);
695 int nfnl_exp_test_src(
const struct nfnl_exp *exp,
int tuple)
697 return !!(exp->ce_mask & exp_get_src_attr(tuple));
700 int nfnl_exp_test_dst(
const struct nfnl_exp *exp,
int tuple)
702 return !!(exp->ce_mask & exp_get_dst_attr(tuple));
705 struct 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)))
714 struct 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)))
723 static 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;
745 void 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);
753 int nfnl_exp_test_l4protonum(
const struct nfnl_exp *exp,
int tuple)
755 return !!(exp->ce_mask & exp_get_l4protonum_attr(tuple));
758 uint8_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;
764 static 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;
786 void 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);
796 int nfnl_exp_test_ports(
const struct nfnl_exp *exp,
int tuple)
798 return !!(exp->ce_mask & exp_get_l4ports_attr(tuple));
801 uint16_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;
807 uint16_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;
814 static 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;
836 void 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);
847 int 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);
853 uint16_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;
860 uint8_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;
867 uint8_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;
876 struct 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_clone(const struct nl_addr *addr)
Clone existing abstract address object.
Dump object briefly on one line.
void nl_new_line(struct nl_dump_params *params)
Handle a new line while dumping.
struct nl_object * nl_object_alloc(struct nl_object_ops *ops)
Allocate a new object of kind specified by the operations handle.
void nl_object_get(struct nl_object *obj)
Acquire a reference on a object.
char * nl_msec2str(uint64_t msec, char *buf, size_t len)
Convert milliseconds to a character string.
struct nl_addr * nl_addr_get(struct nl_addr *addr)
Increase the reference counter of an abstract address.
Dump all attributes but no statistics.
void nl_object_put(struct nl_object *obj)
Release a reference from an object.
void nl_addr_put(struct nl_addr *addr)
Decrease the reference counter of an abstract address.
void nl_dump(struct nl_dump_params *params, const char *fmt,...)
Dump a formatted character string.
char * nl_addr2str(const struct nl_addr *addr, char *buf, size_t size)
Convert abstract address object to character string.