12 #include "internal/internal.h"
13 #include <libmnl/libmnl.h>
18 nfct_parse_ip_attr_cb(
const struct nlattr *attr,
void *data)
20 const struct nlattr **tb = data;
21 int type = mnl_attr_get_type(attr);
24 if (mnl_attr_type_valid(attr, CTA_IP_MAX) < 0)
30 if (mnl_attr_validate(attr, MNL_TYPE_U32) < 0)
35 if (mnl_attr_validate2(attr, MNL_TYPE_UNSPEC,
36 sizeof(
struct in6_addr)) < 0) {
46 nfct_parse_ip(
const struct nlattr *attr,
struct __nfct_tuple *tuple,
47 const int dir, uint32_t *set)
49 struct nlattr *tb[CTA_IP_MAX+1] = {};
51 if (mnl_attr_parse_nested(attr, nfct_parse_ip_attr_cb, tb) < 0)
54 if (tb[CTA_IP_V4_SRC]) {
55 tuple->src.v4 = mnl_attr_get_u32(tb[CTA_IP_V4_SRC]);
58 set_bit(ATTR_ORIG_IPV4_SRC, set);
61 set_bit(ATTR_REPL_IPV4_SRC, set);
64 set_bit(ATTR_MASTER_IPV4_SRC, set);
69 if (tb[CTA_IP_V4_DST]) {
70 tuple->dst.v4 = mnl_attr_get_u32(tb[CTA_IP_V4_DST]);
73 set_bit(ATTR_ORIG_IPV4_DST, set);
76 set_bit(ATTR_REPL_IPV4_DST, set);
79 set_bit(ATTR_MASTER_IPV4_DST, set);
84 if (tb[CTA_IP_V6_SRC]) {
85 memcpy(&tuple->src.v6, mnl_attr_get_payload(tb[CTA_IP_V6_SRC]),
86 sizeof(
struct in6_addr));
89 set_bit(ATTR_ORIG_IPV6_SRC, set);
92 set_bit(ATTR_REPL_IPV6_SRC, set);
95 set_bit(ATTR_MASTER_IPV6_SRC, set);
100 if (tb[CTA_IP_V6_DST]) {
101 memcpy(&tuple->dst.v6, mnl_attr_get_payload(tb[CTA_IP_V6_DST]),
102 sizeof(
struct in6_addr));
105 set_bit(ATTR_ORIG_IPV6_DST, set);
108 set_bit(ATTR_REPL_IPV6_DST, set);
111 set_bit(ATTR_MASTER_IPV6_DST, set);
119 nfct_parse_proto_attr_cb(
const struct nlattr *attr,
void *data)
121 const struct nlattr **tb = data;
122 int type = mnl_attr_get_type(attr);
124 if (mnl_attr_type_valid(attr, CTA_PROTO_MAX) < 0)
128 case CTA_PROTO_SRC_PORT:
129 case CTA_PROTO_DST_PORT:
130 case CTA_PROTO_ICMP_ID:
131 case CTA_PROTO_ICMPV6_ID:
132 if (mnl_attr_validate(attr, MNL_TYPE_U16) < 0)
136 case CTA_PROTO_ICMP_TYPE:
137 case CTA_PROTO_ICMP_CODE:
138 case CTA_PROTO_ICMPV6_TYPE:
139 case CTA_PROTO_ICMPV6_CODE:
140 if (mnl_attr_validate(attr, MNL_TYPE_U8) < 0)
149 nfct_parse_proto(
const struct nlattr *attr,
struct __nfct_tuple *tuple,
150 const int dir, uint32_t *set)
152 struct nlattr *tb[CTA_PROTO_MAX+1] = {};
154 if (mnl_attr_parse_nested(attr, nfct_parse_proto_attr_cb, tb) < 0)
157 if (tb[CTA_PROTO_NUM]) {
158 tuple->protonum = mnl_attr_get_u8(tb[CTA_PROTO_NUM]);
161 set_bit(ATTR_ORIG_L4PROTO, set);
164 set_bit(ATTR_REPL_L4PROTO, set);
167 set_bit(ATTR_MASTER_L4PROTO, set);
172 if (tb[CTA_PROTO_SRC_PORT]) {
173 tuple->l4src.tcp.port =
174 mnl_attr_get_u16(tb[CTA_PROTO_SRC_PORT]);
177 set_bit(ATTR_ORIG_PORT_SRC, set);
180 set_bit(ATTR_REPL_PORT_SRC, set);
183 set_bit(ATTR_MASTER_PORT_SRC, set);
188 if (tb[CTA_PROTO_DST_PORT]) {
189 tuple->l4dst.tcp.port =
190 mnl_attr_get_u16(tb[CTA_PROTO_DST_PORT]);
193 set_bit(ATTR_ORIG_PORT_DST, set);
196 set_bit(ATTR_REPL_PORT_DST, set);
199 set_bit(ATTR_MASTER_PORT_DST, set);
204 if (tb[CTA_PROTO_ICMP_TYPE]) {
205 tuple->l4dst.icmp.type =
206 mnl_attr_get_u8(tb[CTA_PROTO_ICMP_TYPE]);
207 set_bit(ATTR_ICMP_TYPE, set);
210 if (tb[CTA_PROTO_ICMP_CODE]) {
211 tuple->l4dst.icmp.code =
212 mnl_attr_get_u8(tb[CTA_PROTO_ICMP_CODE]);
213 set_bit(ATTR_ICMP_CODE, set);
216 if (tb[CTA_PROTO_ICMP_ID]) {
217 tuple->l4src.icmp.id =
218 mnl_attr_get_u16(tb[CTA_PROTO_ICMP_ID]);
219 set_bit(ATTR_ICMP_ID, set);
222 if (tb[CTA_PROTO_ICMPV6_TYPE]) {
223 tuple->l4dst.icmp.type =
224 mnl_attr_get_u8(tb[CTA_PROTO_ICMPV6_TYPE]);
225 set_bit(ATTR_ICMP_TYPE, set);
228 if (tb[CTA_PROTO_ICMPV6_CODE]) {
229 tuple->l4dst.icmp.code =
230 mnl_attr_get_u8(tb[CTA_PROTO_ICMPV6_CODE]);
231 set_bit(ATTR_ICMP_CODE, set);
234 if (tb[CTA_PROTO_ICMPV6_ID]) {
235 tuple->l4src.icmp.id =
236 mnl_attr_get_u16(tb[CTA_PROTO_ICMPV6_ID]);
237 set_bit(ATTR_ICMP_ID, set);
243 static int nfct_parse_tuple_attr_cb(
const struct nlattr *attr,
void *data)
245 const struct nlattr **tb = data;
246 int type = mnl_attr_get_type(attr);
248 if (mnl_attr_type_valid(attr, CTA_TUPLE_MAX) < 0)
253 case CTA_TUPLE_PROTO:
254 if (mnl_attr_validate(attr, MNL_TYPE_NESTED) < 0)
258 if (mnl_attr_validate(attr, MNL_TYPE_U16) < 0)
268 nfct_parse_tuple(
const struct nlattr *attr,
struct __nfct_tuple *tuple,
269 int dir, uint32_t *set)
271 struct nlattr *tb[CTA_TUPLE_MAX+1] = {};
273 if (mnl_attr_parse_nested(attr, nfct_parse_tuple_attr_cb, tb) < 0)
276 if (tb[CTA_TUPLE_IP]) {
277 if (nfct_parse_ip(tb[CTA_TUPLE_IP], tuple, dir, set) < 0)
281 if (tb[CTA_TUPLE_PROTO]) {
282 if (nfct_parse_proto(tb[CTA_TUPLE_PROTO], tuple, dir, set) < 0)
286 if (tb[CTA_TUPLE_ZONE]) {
287 tuple->zone = ntohs(mnl_attr_get_u16(tb[CTA_TUPLE_ZONE]));
290 set_bit(ATTR_ORIG_ZONE, set);
293 set_bit(ATTR_REPL_ZONE, set);
302 nfct_parse_pinfo_tcp_attr_cb(
const struct nlattr *attr,
void *data)
304 const struct nlattr **tb = data;
305 int type = mnl_attr_get_type(attr);
307 if (mnl_attr_type_valid(attr, CTA_PROTOINFO_TCP_MAX) < 0)
311 case CTA_PROTOINFO_TCP_STATE:
312 case CTA_PROTOINFO_TCP_WSCALE_ORIGINAL:
313 case CTA_PROTOINFO_TCP_WSCALE_REPLY:
314 if (mnl_attr_validate(attr, MNL_TYPE_U8) < 0)
317 case CTA_PROTOINFO_TCP_FLAGS_ORIGINAL:
318 case CTA_PROTOINFO_TCP_FLAGS_REPLY:
319 if (mnl_attr_validate2(attr, MNL_TYPE_UNSPEC,
320 sizeof(
struct nf_ct_tcp_flags)) < 0) {
330 nfct_parse_protoinfo_tcp(
const struct nlattr *attr,
struct nf_conntrack *ct)
332 struct nlattr *tb[CTA_PROTOINFO_TCP_MAX+1] = {};
334 if (mnl_attr_parse_nested(attr, nfct_parse_pinfo_tcp_attr_cb, tb) < 0)
337 if (tb[CTA_PROTOINFO_TCP_STATE]) {
338 ct->protoinfo.tcp.state =
339 mnl_attr_get_u8(tb[CTA_PROTOINFO_TCP_STATE]);
340 set_bit(ATTR_TCP_STATE, ct->head.set);
343 if (tb[CTA_PROTOINFO_TCP_WSCALE_ORIGINAL]) {
344 memcpy(&ct->protoinfo.tcp.wscale[__DIR_ORIG],
345 mnl_attr_get_payload(tb[CTA_PROTOINFO_TCP_WSCALE_ORIGINAL]),
347 set_bit(ATTR_TCP_WSCALE_ORIG, ct->head.set);
350 if (tb[CTA_PROTOINFO_TCP_WSCALE_REPLY]) {
351 memcpy(&ct->protoinfo.tcp.wscale[__DIR_REPL],
352 mnl_attr_get_payload(tb[CTA_PROTOINFO_TCP_WSCALE_REPLY]),
354 set_bit(ATTR_TCP_WSCALE_REPL, ct->head.set);
357 if (tb[CTA_PROTOINFO_TCP_FLAGS_ORIGINAL]) {
358 memcpy(&ct->protoinfo.tcp.flags[0],
359 mnl_attr_get_payload(tb[CTA_PROTOINFO_TCP_FLAGS_ORIGINAL]),
360 sizeof(
struct nf_ct_tcp_flags));
361 set_bit(ATTR_TCP_FLAGS_ORIG, ct->head.set);
362 set_bit(ATTR_TCP_MASK_ORIG, ct->head.set);
365 if (tb[CTA_PROTOINFO_TCP_FLAGS_REPLY]) {
366 memcpy(&ct->protoinfo.tcp.flags[1],
367 mnl_attr_get_payload(tb[CTA_PROTOINFO_TCP_FLAGS_REPLY]),
368 sizeof(
struct nf_ct_tcp_flags));
369 set_bit(ATTR_TCP_FLAGS_REPL, ct->head.set);
370 set_bit(ATTR_TCP_MASK_REPL, ct->head.set);
377 nfct_parse_pinfo_sctp_attr_cb(
const struct nlattr *attr,
void *data)
379 const struct nlattr **tb = data;
380 int type = mnl_attr_get_type(attr);
382 if (mnl_attr_type_valid(attr, CTA_PROTOINFO_SCTP_MAX) < 0)
386 case CTA_PROTOINFO_SCTP_STATE:
387 if (mnl_attr_validate(attr, MNL_TYPE_U8) < 0)
390 case CTA_PROTOINFO_SCTP_VTAG_ORIGINAL:
391 case CTA_PROTOINFO_SCTP_VTAG_REPLY:
392 if (mnl_attr_validate(attr, MNL_TYPE_U32) < 0)
401 nfct_parse_protoinfo_sctp(
const struct nlattr *attr,
struct nf_conntrack *ct)
403 struct nlattr *tb[CTA_PROTOINFO_SCTP_MAX+1] = {};
405 if (mnl_attr_parse_nested(attr, nfct_parse_pinfo_sctp_attr_cb, tb) < 0)
408 if (tb[CTA_PROTOINFO_SCTP_STATE]) {
409 ct->protoinfo.sctp.state =
410 mnl_attr_get_u8(tb[CTA_PROTOINFO_SCTP_STATE]);
411 set_bit(ATTR_SCTP_STATE, ct->head.set);
414 if (tb[CTA_PROTOINFO_SCTP_VTAG_ORIGINAL]) {
415 ct->protoinfo.sctp.vtag[__DIR_ORIG] =
416 ntohl(mnl_attr_get_u32(tb[CTA_PROTOINFO_SCTP_VTAG_ORIGINAL]));
417 set_bit(ATTR_SCTP_VTAG_ORIG, ct->head.set);
420 if (tb[CTA_PROTOINFO_SCTP_VTAG_REPLY]) {
421 ct->protoinfo.sctp.vtag[__DIR_REPL] =
422 ntohl(mnl_attr_get_u32(tb[CTA_PROTOINFO_SCTP_VTAG_REPLY]));
423 set_bit(ATTR_SCTP_VTAG_REPL, ct->head.set);
430 nfct_parse_pinfo_dccp_attr_cb(
const struct nlattr *attr,
void *data)
432 const struct nlattr **tb = data;
433 int type = mnl_attr_get_type(attr);
435 if (mnl_attr_type_valid(attr, CTA_PROTOINFO_DCCP_MAX) < 0)
439 case CTA_PROTOINFO_DCCP_STATE:
440 case CTA_PROTOINFO_DCCP_ROLE:
441 if (mnl_attr_validate(attr, MNL_TYPE_U8) < 0)
444 case CTA_PROTOINFO_DCCP_HANDSHAKE_SEQ:
445 if (mnl_attr_validate(attr, MNL_TYPE_U64) < 0)
454 nfct_parse_protoinfo_dccp(
const struct nlattr *attr,
struct nf_conntrack *ct)
456 struct nlattr *tb[CTA_PROTOINFO_DCCP_MAX+1] = {};
458 if (mnl_attr_parse_nested(attr, nfct_parse_pinfo_dccp_attr_cb, tb) < 0)
461 if (tb[CTA_PROTOINFO_DCCP_STATE]) {
462 ct->protoinfo.dccp.state = mnl_attr_get_u8(tb[CTA_PROTOINFO_DCCP_STATE]);
463 set_bit(ATTR_DCCP_STATE, ct->head.set);
465 if (tb[CTA_PROTOINFO_DCCP_ROLE]) {
466 ct->protoinfo.dccp.role = mnl_attr_get_u8(tb[CTA_PROTOINFO_DCCP_ROLE]);
467 set_bit(ATTR_DCCP_ROLE, ct->head.set);
469 if (tb[CTA_PROTOINFO_DCCP_HANDSHAKE_SEQ]) {
470 ct->protoinfo.dccp.handshake_seq = be64toh(
471 mnl_attr_get_u64(tb[CTA_PROTOINFO_DCCP_HANDSHAKE_SEQ]));
472 set_bit(ATTR_DCCP_HANDSHAKE_SEQ, ct->head.set);
479 nfct_parse_protoinfo_attr_cb(
const struct nlattr *attr,
void *data)
481 const struct nlattr **tb = data;
482 int type = mnl_attr_get_type(attr);
484 if (mnl_attr_type_valid(attr, CTA_PROTOINFO_TCP_MAX) < 0)
488 case CTA_PROTOINFO_TCP:
489 case CTA_PROTOINFO_SCTP:
490 case CTA_PROTOINFO_DCCP:
491 if (mnl_attr_validate(attr, MNL_TYPE_NESTED) < 0)
500 nfct_parse_protoinfo(
const struct nlattr *attr,
struct nf_conntrack *ct)
502 struct nlattr *tb[CTA_PROTOINFO_MAX+1] = {};
504 if (mnl_attr_parse_nested(attr, nfct_parse_protoinfo_attr_cb, tb) < 0)
507 if (tb[CTA_PROTOINFO_TCP])
508 nfct_parse_protoinfo_tcp(tb[CTA_PROTOINFO_TCP], ct);
510 if (tb[CTA_PROTOINFO_SCTP])
511 nfct_parse_protoinfo_sctp(tb[CTA_PROTOINFO_SCTP], ct);
513 if (tb[CTA_PROTOINFO_DCCP])
514 nfct_parse_protoinfo_dccp(tb[CTA_PROTOINFO_DCCP], ct);
519 static int nfct_parse_counters_attr_cb(
const struct nlattr *attr,
void *data)
521 const struct nlattr **tb = data;
522 int type = mnl_attr_get_type(attr);
524 if (mnl_attr_type_valid(attr, CTA_COUNTERS_MAX) < 0)
528 case CTA_COUNTERS_PACKETS:
529 case CTA_COUNTERS_BYTES:
530 if (mnl_attr_validate(attr, MNL_TYPE_U64) < 0)
533 case CTA_COUNTERS32_PACKETS:
534 case CTA_COUNTERS32_BYTES:
535 if (mnl_attr_validate(attr, MNL_TYPE_U32) < 0)
544 nfct_parse_counters(
const struct nlattr *attr,
struct nf_conntrack *ct,
547 struct nlattr *tb[CTA_COUNTERS_MAX+1] = {};
549 if (mnl_attr_parse_nested(attr, nfct_parse_counters_attr_cb, tb) < 0)
552 if (tb[CTA_COUNTERS_PACKETS] || tb[CTA_COUNTERS32_PACKETS]) {
553 if (tb[CTA_COUNTERS32_PACKETS]) {
554 ct->counters[dir].packets =
555 ntohl(mnl_attr_get_u32(tb[CTA_COUNTERS32_PACKETS]));
557 if (tb[CTA_COUNTERS_PACKETS]) {
558 ct->counters[dir].packets =
559 be64toh(mnl_attr_get_u64(tb[CTA_COUNTERS_PACKETS]));
563 set_bit(ATTR_ORIG_COUNTER_PACKETS, ct->head.set);
566 set_bit(ATTR_REPL_COUNTER_PACKETS, ct->head.set);
570 if (tb[CTA_COUNTERS_BYTES] || tb[CTA_COUNTERS32_BYTES]) {
571 if (tb[CTA_COUNTERS32_BYTES]) {
572 ct->counters[dir].bytes =
573 ntohl(mnl_attr_get_u32(tb[CTA_COUNTERS32_BYTES]));
575 if (tb[CTA_COUNTERS_BYTES]) {
576 ct->counters[dir].bytes =
577 be64toh(mnl_attr_get_u64(tb[CTA_COUNTERS_BYTES]));
582 set_bit(ATTR_ORIG_COUNTER_BYTES, ct->head.set);
585 set_bit(ATTR_REPL_COUNTER_BYTES, ct->head.set);
594 nfct_parse_nat_seq_attr_cb(
const struct nlattr *attr,
void *data)
596 const struct nlattr **tb = data;
597 int type = mnl_attr_get_type(attr);
599 if (mnl_attr_type_valid(attr, CTA_NAT_SEQ_MAX) < 0)
603 case CTA_NAT_SEQ_CORRECTION_POS:
604 case CTA_NAT_SEQ_OFFSET_BEFORE:
605 case CTA_NAT_SEQ_OFFSET_AFTER:
606 if (mnl_attr_validate(attr, MNL_TYPE_U32) < 0)
615 nfct_parse_nat_seq(
const struct nlattr *attr,
struct nf_conntrack *ct,
int dir)
617 struct nlattr *tb[CTA_NAT_SEQ_MAX+1] = {};
619 if (mnl_attr_parse_nested(attr, nfct_parse_nat_seq_attr_cb, tb) < 0)
622 if (tb[CTA_NAT_SEQ_CORRECTION_POS]) {
623 ct->natseq[dir].correction_pos =
624 ntohl(mnl_attr_get_u32(tb[CTA_NAT_SEQ_CORRECTION_POS]));
627 set_bit(ATTR_ORIG_NAT_SEQ_CORRECTION_POS, ct->head.set);
630 set_bit(ATTR_REPL_NAT_SEQ_CORRECTION_POS, ct->head.set);
635 if (tb[CTA_NAT_SEQ_OFFSET_BEFORE]) {
636 ct->natseq[dir].offset_before =
637 ntohl(mnl_attr_get_u32(tb[CTA_NAT_SEQ_OFFSET_BEFORE]));
640 set_bit(ATTR_ORIG_NAT_SEQ_OFFSET_BEFORE, ct->head.set);
643 set_bit(ATTR_REPL_NAT_SEQ_OFFSET_BEFORE, ct->head.set);
648 if (tb[CTA_NAT_SEQ_OFFSET_AFTER]) {
649 ct->natseq[dir].offset_after =
650 ntohl(mnl_attr_get_u32(tb[CTA_NAT_SEQ_OFFSET_AFTER]));
653 set_bit(ATTR_ORIG_NAT_SEQ_OFFSET_AFTER, ct->head.set);
656 set_bit(ATTR_REPL_NAT_SEQ_OFFSET_AFTER, ct->head.set);
665 nfct_parse_helper_attr_cb(
const struct nlattr *attr,
void *data)
667 const struct nlattr **tb = data;
668 int type = mnl_attr_get_type(attr);
670 if (mnl_attr_type_valid(attr, CTA_HELP_MAX) < 0)
675 if (mnl_attr_validate(attr, MNL_TYPE_STRING) < 0)
684 nfct_parse_helper(
const struct nlattr *attr,
struct nf_conntrack *ct)
686 struct nlattr *tb[CTA_HELP_MAX+1] = {};
688 if (mnl_attr_parse_nested(attr, nfct_parse_helper_attr_cb, tb) < 0)
691 if (!tb[CTA_HELP_NAME])
694 strncpy(ct->helper_name, mnl_attr_get_str(tb[CTA_HELP_NAME]),
695 NFCT_HELPER_NAME_MAX);
696 ct->helper_name[NFCT_HELPER_NAME_MAX-1] =
'\0';
697 set_bit(ATTR_HELPER_NAME, ct->head.set);
699 if (!tb[CTA_HELP_INFO])
702 ct->helper_info_len = mnl_attr_get_payload_len(tb[CTA_HELP_INFO]);
703 ct->helper_info = calloc(1, ct->helper_info_len);
704 if (ct->helper_info == NULL)
707 memcpy(ct->helper_info, mnl_attr_get_payload(tb[CTA_HELP_INFO]),
708 ct->helper_info_len);
709 set_bit(ATTR_HELPER_INFO, ct->head.set);
715 nfct_parse_secctx_attr_cb(
const struct nlattr *attr,
void *data)
717 const struct nlattr **tb = data;
718 int type = mnl_attr_get_type(attr);
720 if (mnl_attr_type_valid(attr, CTA_SECCTX_MAX) < 0)
724 case CTA_SECCTX_NAME:
725 if (mnl_attr_validate(attr, MNL_TYPE_STRING) < 0)
734 nfct_parse_secctx(
const struct nlattr *attr,
struct nf_conntrack *ct)
736 struct nlattr *tb[CTA_SECCTX_MAX+1] = {};
738 if (mnl_attr_parse_nested(attr, nfct_parse_secctx_attr_cb, tb) < 0)
741 if (!tb[CTA_SECCTX_NAME])
744 ct->secctx = strdup(NFA_DATA(tb[CTA_SECCTX_NAME]));
746 set_bit(ATTR_SECCTX, ct->head.set);
752 nfct_parse_timestamp_attr_cb(
const struct nlattr *attr,
void *data)
754 const struct nlattr **tb = data;
755 int type = mnl_attr_get_type(attr);
757 if (mnl_attr_type_valid(attr, CTA_TIMESTAMP_MAX) < 0)
761 case CTA_TIMESTAMP_START:
762 case CTA_TIMESTAMP_STOP:
763 if (mnl_attr_validate(attr, MNL_TYPE_U64) < 0)
772 nfct_parse_timestamp(
const struct nlattr *attr,
struct nf_conntrack *ct)
774 struct nlattr *tb[CTA_TIMESTAMP_MAX+1] = {};
776 if (mnl_attr_parse_nested(attr, nfct_parse_timestamp_attr_cb, tb) < 0)
779 if (tb[CTA_TIMESTAMP_START]) {
780 ct->timestamp.start =
781 be64toh(mnl_attr_get_u64(tb[CTA_TIMESTAMP_START]));
782 set_bit(ATTR_TIMESTAMP_START, ct->head.set);
784 if (tb[CTA_TIMESTAMP_STOP]) {
786 be64toh(mnl_attr_get_u64(tb[CTA_TIMESTAMP_STOP]));
787 set_bit(ATTR_TIMESTAMP_STOP, ct->head.set);
793 static int nfct_parse_labels(
const struct nlattr *attr,
struct nf_conntrack *ct)
795 uint16_t len = mnl_attr_get_payload_len(attr);
796 struct nfct_bitmask *mask;
802 mask = nfct_bitmask_new((len * CHAR_BIT) - 1);
805 bits = mnl_attr_get_payload(attr);
807 memcpy(mask->bits, bits, len);
813 nfct_parse_conntrack_attr_cb(
const struct nlattr *attr,
void *data)
815 const struct nlattr **tb = data;
816 int type = mnl_attr_get_type(attr);
818 if (mnl_attr_type_valid(attr, CTA_MAX) < 0)
823 case CTA_TUPLE_REPLY:
824 case CTA_TUPLE_MASTER:
825 case CTA_NAT_SEQ_ADJ_ORIG:
826 case CTA_NAT_SEQ_ADJ_REPLY:
828 case CTA_COUNTERS_ORIG:
829 case CTA_COUNTERS_REPLY:
833 if (mnl_attr_validate(attr, MNL_TYPE_NESTED) < 0)
842 if (mnl_attr_validate(attr, MNL_TYPE_U32) < 0)
846 if (mnl_attr_validate(attr, MNL_TYPE_U16) < 0)
859 nfct_payload_parse(
const void *payload,
size_t payload_len,
860 uint16_t l3num,
struct nf_conntrack *ct)
862 struct nlattr *tb[CTA_MAX+1] = {};
864 if (mnl_attr_parse_payload(payload, payload_len,
865 nfct_parse_conntrack_attr_cb, tb) < 0)
868 if (tb[CTA_TUPLE_ORIG]) {
869 ct->head.orig.l3protonum = l3num;
870 set_bit(ATTR_ORIG_L3PROTO, ct->head.set);
872 if (nfct_parse_tuple(tb[CTA_TUPLE_ORIG], &ct->head.orig,
873 __DIR_ORIG, ct->head.set) < 0)
877 if (tb[CTA_TUPLE_REPLY]) {
878 ct->repl.l3protonum = l3num;
879 set_bit(ATTR_REPL_L3PROTO, ct->head.set);
881 if (nfct_parse_tuple(tb[CTA_TUPLE_REPLY], &ct->repl,
882 __DIR_REPL, ct->head.set) < 0)
886 if (tb[CTA_TUPLE_MASTER]) {
887 ct->master.l3protonum = l3num;
888 set_bit(ATTR_MASTER_L3PROTO, ct->head.set);
890 if (nfct_parse_tuple(tb[CTA_TUPLE_MASTER], &ct->master,
891 __DIR_MASTER, ct->head.set) < 0)
895 if (tb[CTA_NAT_SEQ_ADJ_ORIG]) {
896 if (nfct_parse_nat_seq(tb[CTA_NAT_SEQ_ADJ_ORIG],
901 if (tb[CTA_NAT_SEQ_ADJ_REPLY]) {
902 if (nfct_parse_nat_seq(tb[CTA_NAT_SEQ_ADJ_REPLY],
907 if (tb[CTA_STATUS]) {
908 ct->status = ntohl(mnl_attr_get_u32(tb[CTA_STATUS]));
909 set_bit(ATTR_STATUS, ct->head.set);
912 if (tb[CTA_PROTOINFO]) {
913 if (nfct_parse_protoinfo(tb[CTA_PROTOINFO], ct) < 0)
917 if (tb[CTA_TIMEOUT]) {
918 ct->timeout = ntohl(mnl_attr_get_u32(tb[CTA_TIMEOUT]));
919 set_bit(ATTR_TIMEOUT, ct->head.set);
923 ct->mark = ntohl(mnl_attr_get_u32(tb[CTA_MARK]));
924 set_bit(ATTR_MARK, ct->head.set);
927 if (tb[CTA_SECMARK]) {
928 ct->secmark = ntohl(mnl_attr_get_u32(tb[CTA_SECMARK]));
929 set_bit(ATTR_SECMARK, ct->head.set);
932 if (tb[CTA_COUNTERS_ORIG]) {
933 if (nfct_parse_counters(tb[CTA_COUNTERS_ORIG],
938 if (tb[CTA_COUNTERS_REPLY]) {
939 if (nfct_parse_counters(tb[CTA_COUNTERS_REPLY],
945 ct->use = ntohl(mnl_attr_get_u32(tb[CTA_USE]));
946 set_bit(ATTR_USE, ct->head.set);
950 ct->id = ntohl(mnl_attr_get_u32(tb[CTA_ID]));
951 set_bit(ATTR_ID, ct->head.set);
955 if (nfct_parse_helper(tb[CTA_HELP], ct) < 0)
960 ct->zone = ntohs(mnl_attr_get_u16(tb[CTA_ZONE]));
961 set_bit(ATTR_ZONE, ct->head.set);
964 if (tb[CTA_SECCTX]) {
965 if (nfct_parse_secctx(tb[CTA_SECCTX], ct) < 0)
969 if (tb[CTA_TIMESTAMP]) {
970 if (nfct_parse_timestamp(tb[CTA_TIMESTAMP], ct) < 0)
974 if (tb[CTA_LABELS]) {
975 if (nfct_parse_labels(tb[CTA_LABELS], ct) < 0)
983 int nfct_nlmsg_parse(
const struct nlmsghdr *nlh,
struct nf_conntrack *ct)
985 struct nfgenmsg *nfhdr = mnl_nlmsg_get_payload(nlh);
987 return nfct_payload_parse((uint8_t *)nfhdr +
sizeof(
struct nfgenmsg),
988 mnl_nlmsg_get_payload_len(nlh) -
sizeof(
struct nfgenmsg),
989 nfhdr->nfgen_family, ct);
void nfct_set_attr(struct nf_conntrack *ct, const enum nf_conntrack_attr type, const void *value)