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)
329 nfct_parse_protoinfo_tcp(
const struct nlattr *attr,
struct nf_conntrack *ct)
331 struct nlattr *tb[CTA_PROTOINFO_TCP_MAX+1] = {};
333 if (mnl_attr_parse_nested(attr, nfct_parse_pinfo_tcp_attr_cb, tb) < 0)
336 if (tb[CTA_PROTOINFO_TCP_STATE]) {
337 ct->protoinfo.tcp.state =
338 mnl_attr_get_u8(tb[CTA_PROTOINFO_TCP_STATE]);
339 set_bit(ATTR_TCP_STATE, ct->head.set);
342 if (tb[CTA_PROTOINFO_TCP_WSCALE_ORIGINAL]) {
343 memcpy(&ct->protoinfo.tcp.wscale[__DIR_ORIG],
344 mnl_attr_get_payload(tb[CTA_PROTOINFO_TCP_WSCALE_ORIGINAL]),
346 set_bit(ATTR_TCP_WSCALE_ORIG, ct->head.set);
349 if (tb[CTA_PROTOINFO_TCP_WSCALE_REPLY]) {
350 memcpy(&ct->protoinfo.tcp.wscale[__DIR_REPL],
351 mnl_attr_get_payload(tb[CTA_PROTOINFO_TCP_WSCALE_REPLY]),
353 set_bit(ATTR_TCP_WSCALE_REPL, ct->head.set);
356 if (tb[CTA_PROTOINFO_TCP_FLAGS_ORIGINAL]) {
357 memcpy(&ct->protoinfo.tcp.flags[0],
358 mnl_attr_get_payload(tb[CTA_PROTOINFO_TCP_FLAGS_ORIGINAL]),
359 sizeof(
struct nf_ct_tcp_flags));
360 set_bit(ATTR_TCP_FLAGS_ORIG, ct->head.set);
361 set_bit(ATTR_TCP_MASK_ORIG, ct->head.set);
364 if (tb[CTA_PROTOINFO_TCP_FLAGS_REPLY]) {
365 memcpy(&ct->protoinfo.tcp.flags[1],
366 mnl_attr_get_payload(tb[CTA_PROTOINFO_TCP_FLAGS_REPLY]),
367 sizeof(
struct nf_ct_tcp_flags));
368 set_bit(ATTR_TCP_FLAGS_REPL, ct->head.set);
369 set_bit(ATTR_TCP_MASK_REPL, ct->head.set);
376 nfct_parse_pinfo_sctp_attr_cb(
const struct nlattr *attr,
void *data)
378 const struct nlattr **tb = data;
379 int type = mnl_attr_get_type(attr);
381 if (mnl_attr_type_valid(attr, CTA_PROTOINFO_SCTP_MAX) < 0)
385 case CTA_PROTOINFO_SCTP_STATE:
386 if (mnl_attr_validate(attr, MNL_TYPE_U8) < 0)
389 case CTA_PROTOINFO_SCTP_VTAG_ORIGINAL:
390 case CTA_PROTOINFO_SCTP_VTAG_REPLY:
391 if (mnl_attr_validate(attr, MNL_TYPE_U32) < 0)
400 nfct_parse_protoinfo_sctp(
const struct nlattr *attr,
struct nf_conntrack *ct)
402 struct nlattr *tb[CTA_PROTOINFO_SCTP_MAX+1] = {};
404 if (mnl_attr_parse_nested(attr, nfct_parse_pinfo_sctp_attr_cb, tb) < 0)
407 if (tb[CTA_PROTOINFO_SCTP_STATE]) {
408 ct->protoinfo.sctp.state =
409 mnl_attr_get_u8(tb[CTA_PROTOINFO_SCTP_STATE]);
410 set_bit(ATTR_SCTP_STATE, ct->head.set);
413 if (tb[CTA_PROTOINFO_SCTP_VTAG_ORIGINAL]) {
414 ct->protoinfo.sctp.vtag[__DIR_ORIG] =
415 ntohl(mnl_attr_get_u32(tb[CTA_PROTOINFO_SCTP_VTAG_ORIGINAL]));
416 set_bit(ATTR_SCTP_VTAG_ORIG, ct->head.set);
419 if (tb[CTA_PROTOINFO_SCTP_VTAG_REPLY]) {
420 ct->protoinfo.sctp.vtag[__DIR_REPL] =
421 ntohl(mnl_attr_get_u32(tb[CTA_PROTOINFO_SCTP_VTAG_REPLY]));
422 set_bit(ATTR_SCTP_VTAG_REPL, ct->head.set);
429 nfct_parse_pinfo_dccp_attr_cb(
const struct nlattr *attr,
void *data)
431 const struct nlattr **tb = data;
432 int type = mnl_attr_get_type(attr);
434 if (mnl_attr_type_valid(attr, CTA_PROTOINFO_DCCP_MAX) < 0)
438 case CTA_PROTOINFO_DCCP_STATE:
439 case CTA_PROTOINFO_DCCP_ROLE:
440 if (mnl_attr_validate(attr, MNL_TYPE_U8) < 0)
443 case CTA_PROTOINFO_DCCP_HANDSHAKE_SEQ:
444 if (mnl_attr_validate(attr, MNL_TYPE_U64) < 0)
453 nfct_parse_protoinfo_dccp(
const struct nlattr *attr,
struct nf_conntrack *ct)
455 struct nlattr *tb[CTA_PROTOINFO_DCCP_MAX+1] = {};
457 if (mnl_attr_parse_nested(attr, nfct_parse_pinfo_dccp_attr_cb, tb) < 0)
460 if (tb[CTA_PROTOINFO_DCCP_STATE]) {
461 ct->protoinfo.dccp.state = mnl_attr_get_u8(tb[CTA_PROTOINFO_DCCP_STATE]);
462 set_bit(ATTR_DCCP_STATE, ct->head.set);
464 if (tb[CTA_PROTOINFO_DCCP_ROLE]) {
465 ct->protoinfo.dccp.role = mnl_attr_get_u8(tb[CTA_PROTOINFO_DCCP_ROLE]);
466 set_bit(ATTR_DCCP_ROLE, ct->head.set);
468 if (tb[CTA_PROTOINFO_DCCP_HANDSHAKE_SEQ]) {
469 ct->protoinfo.dccp.handshake_seq = be64toh(
470 mnl_attr_get_u64(tb[CTA_PROTOINFO_DCCP_HANDSHAKE_SEQ]));
471 set_bit(ATTR_DCCP_HANDSHAKE_SEQ, ct->head.set);
478 nfct_parse_protoinfo_attr_cb(
const struct nlattr *attr,
void *data)
480 const struct nlattr **tb = data;
481 int type = mnl_attr_get_type(attr);
483 if (mnl_attr_type_valid(attr, CTA_PROTOINFO_TCP_MAX) < 0)
487 case CTA_PROTOINFO_TCP:
488 case CTA_PROTOINFO_SCTP:
489 case CTA_PROTOINFO_DCCP:
490 if (mnl_attr_validate(attr, MNL_TYPE_NESTED) < 0)
499 nfct_parse_protoinfo(
const struct nlattr *attr,
struct nf_conntrack *ct)
501 struct nlattr *tb[CTA_PROTOINFO_MAX+1] = {};
503 if (mnl_attr_parse_nested(attr, nfct_parse_protoinfo_attr_cb, tb) < 0)
506 if (tb[CTA_PROTOINFO_TCP])
507 nfct_parse_protoinfo_tcp(tb[CTA_PROTOINFO_TCP], ct);
509 if (tb[CTA_PROTOINFO_SCTP])
510 nfct_parse_protoinfo_sctp(tb[CTA_PROTOINFO_SCTP], ct);
512 if (tb[CTA_PROTOINFO_DCCP])
513 nfct_parse_protoinfo_dccp(tb[CTA_PROTOINFO_DCCP], ct);
518 static int nfct_parse_counters_attr_cb(
const struct nlattr *attr,
void *data)
520 const struct nlattr **tb = data;
521 int type = mnl_attr_get_type(attr);
523 if (mnl_attr_type_valid(attr, CTA_COUNTERS_MAX) < 0)
527 case CTA_COUNTERS_PACKETS:
528 case CTA_COUNTERS_BYTES:
529 if (mnl_attr_validate(attr, MNL_TYPE_U64) < 0)
532 case CTA_COUNTERS32_PACKETS:
533 case CTA_COUNTERS32_BYTES:
534 if (mnl_attr_validate(attr, MNL_TYPE_U32) < 0)
543 nfct_parse_counters(
const struct nlattr *attr,
struct nf_conntrack *ct,
546 struct nlattr *tb[CTA_COUNTERS_MAX+1] = {};
548 if (mnl_attr_parse_nested(attr, nfct_parse_counters_attr_cb, tb) < 0)
551 if (tb[CTA_COUNTERS_PACKETS] || tb[CTA_COUNTERS32_PACKETS]) {
552 if (tb[CTA_COUNTERS32_PACKETS]) {
553 ct->counters[dir].packets =
554 ntohl(mnl_attr_get_u32(tb[CTA_COUNTERS32_PACKETS]));
556 if (tb[CTA_COUNTERS_PACKETS]) {
557 ct->counters[dir].packets =
558 be64toh(mnl_attr_get_u64(tb[CTA_COUNTERS_PACKETS]));
562 set_bit(ATTR_ORIG_COUNTER_PACKETS, ct->head.set);
565 set_bit(ATTR_REPL_COUNTER_PACKETS, ct->head.set);
569 if (tb[CTA_COUNTERS_BYTES] || tb[CTA_COUNTERS32_BYTES]) {
570 if (tb[CTA_COUNTERS32_BYTES]) {
571 ct->counters[dir].bytes =
572 ntohl(mnl_attr_get_u32(tb[CTA_COUNTERS32_BYTES]));
574 if (tb[CTA_COUNTERS_BYTES]) {
575 ct->counters[dir].bytes =
576 be64toh(mnl_attr_get_u64(tb[CTA_COUNTERS_BYTES]));
581 set_bit(ATTR_ORIG_COUNTER_BYTES, ct->head.set);
584 set_bit(ATTR_REPL_COUNTER_BYTES, ct->head.set);
593 nfct_parse_nat_seq_attr_cb(
const struct nlattr *attr,
void *data)
595 const struct nlattr **tb = data;
596 int type = mnl_attr_get_type(attr);
598 if (mnl_attr_type_valid(attr, CTA_NAT_SEQ_MAX) < 0)
602 case CTA_NAT_SEQ_CORRECTION_POS:
603 case CTA_NAT_SEQ_OFFSET_BEFORE:
604 case CTA_NAT_SEQ_OFFSET_AFTER:
605 if (mnl_attr_validate(attr, MNL_TYPE_U32) < 0)
614 nfct_parse_nat_seq(
const struct nlattr *attr,
struct nf_conntrack *ct,
int dir)
616 struct nlattr *tb[CTA_NAT_SEQ_MAX+1] = {};
618 if (mnl_attr_parse_nested(attr, nfct_parse_nat_seq_attr_cb, tb) < 0)
621 if (tb[CTA_NAT_SEQ_CORRECTION_POS]) {
622 ct->natseq[dir].correction_pos =
623 ntohl(mnl_attr_get_u32(tb[CTA_NAT_SEQ_CORRECTION_POS]));
626 set_bit(ATTR_ORIG_NAT_SEQ_CORRECTION_POS, ct->head.set);
629 set_bit(ATTR_REPL_NAT_SEQ_CORRECTION_POS, ct->head.set);
634 if (tb[CTA_NAT_SEQ_OFFSET_BEFORE]) {
635 ct->natseq[dir].offset_before =
636 ntohl(mnl_attr_get_u32(tb[CTA_NAT_SEQ_OFFSET_BEFORE]));
639 set_bit(ATTR_ORIG_NAT_SEQ_OFFSET_BEFORE, ct->head.set);
642 set_bit(ATTR_REPL_NAT_SEQ_OFFSET_BEFORE, ct->head.set);
647 if (tb[CTA_NAT_SEQ_OFFSET_AFTER]) {
648 ct->natseq[dir].offset_after =
649 ntohl(mnl_attr_get_u32(tb[CTA_NAT_SEQ_OFFSET_AFTER]));
652 set_bit(ATTR_ORIG_NAT_SEQ_OFFSET_AFTER, ct->head.set);
655 set_bit(ATTR_REPL_NAT_SEQ_OFFSET_AFTER, ct->head.set);
664 nfct_parse_helper_attr_cb(
const struct nlattr *attr,
void *data)
666 const struct nlattr **tb = data;
667 int type = mnl_attr_get_type(attr);
669 if (mnl_attr_type_valid(attr, CTA_HELP_MAX) < 0)
674 if (mnl_attr_validate(attr, MNL_TYPE_STRING) < 0)
683 nfct_parse_helper(
const struct nlattr *attr,
struct nf_conntrack *ct)
685 struct nlattr *tb[CTA_HELP_MAX+1] = {};
687 if (mnl_attr_parse_nested(attr, nfct_parse_helper_attr_cb, tb) < 0)
690 if (!tb[CTA_HELP_NAME])
693 strncpy(ct->helper_name, mnl_attr_get_str(tb[CTA_HELP_NAME]),
694 NFCT_HELPER_NAME_MAX);
695 ct->helper_name[NFCT_HELPER_NAME_MAX-1] =
'\0';
696 set_bit(ATTR_HELPER_NAME, ct->head.set);
698 if (!tb[CTA_HELP_INFO])
701 ct->helper_info_len = mnl_attr_get_payload_len(tb[CTA_HELP_INFO]);
702 ct->helper_info = calloc(1, ct->helper_info_len);
703 if (ct->helper_info == NULL)
706 memcpy(ct->helper_info, mnl_attr_get_payload(tb[CTA_HELP_INFO]),
707 ct->helper_info_len);
708 set_bit(ATTR_HELPER_INFO, ct->head.set);
714 nfct_parse_secctx_attr_cb(
const struct nlattr *attr,
void *data)
716 const struct nlattr **tb = data;
717 int type = mnl_attr_get_type(attr);
719 if (mnl_attr_type_valid(attr, CTA_SECCTX_MAX) < 0)
723 case CTA_SECCTX_NAME:
724 if (mnl_attr_validate(attr, MNL_TYPE_STRING) < 0)
733 nfct_parse_secctx(
const struct nlattr *attr,
struct nf_conntrack *ct)
735 struct nlattr *tb[CTA_SECCTX_MAX+1] = {};
737 if (mnl_attr_parse_nested(attr, nfct_parse_secctx_attr_cb, tb) < 0)
740 if (!tb[CTA_SECCTX_NAME])
743 ct->secctx = strdup(NFA_DATA(tb[CTA_SECCTX_NAME]));
745 set_bit(ATTR_SECCTX, ct->head.set);
751 nfct_parse_timestamp_attr_cb(
const struct nlattr *attr,
void *data)
753 const struct nlattr **tb = data;
754 int type = mnl_attr_get_type(attr);
756 if (mnl_attr_type_valid(attr, CTA_TIMESTAMP_MAX) < 0)
760 case CTA_TIMESTAMP_START:
761 case CTA_TIMESTAMP_STOP:
762 if (mnl_attr_validate(attr, MNL_TYPE_U64) < 0)
771 nfct_parse_timestamp(
const struct nlattr *attr,
struct nf_conntrack *ct)
773 struct nlattr *tb[CTA_TIMESTAMP_MAX+1] = {};
775 if (mnl_attr_parse_nested(attr, nfct_parse_timestamp_attr_cb, tb) < 0)
778 if (tb[CTA_TIMESTAMP_START]) {
779 ct->timestamp.start =
780 be64toh(mnl_attr_get_u64(tb[CTA_TIMESTAMP_START]));
781 set_bit(ATTR_TIMESTAMP_START, ct->head.set);
783 if (tb[CTA_TIMESTAMP_STOP]) {
785 be64toh(mnl_attr_get_u64(tb[CTA_TIMESTAMP_STOP]));
786 set_bit(ATTR_TIMESTAMP_STOP, ct->head.set);
792 static int nfct_parse_labels(
const struct nlattr *attr,
struct nf_conntrack *ct)
794 uint16_t len = mnl_attr_get_payload_len(attr);
795 struct nfct_bitmask *mask;
801 mask = nfct_bitmask_new((len * CHAR_BIT) - 1);
804 bits = mnl_attr_get_payload(attr);
806 memcpy(mask->bits, bits, len);
811 static int nfct_parse_synproxy_attr_cb(
const struct nlattr *attr,
void *data)
813 int type = mnl_attr_get_type(attr);
814 const struct nlattr **tb = data;
816 if (mnl_attr_type_valid(attr, CTA_SYNPROXY_MAX) < 0)
820 case CTA_SYNPROXY_ISN:
821 case CTA_SYNPROXY_ITS:
822 case CTA_SYNPROXY_TSOFF:
823 if (mnl_attr_validate(attr, MNL_TYPE_U32) < 0)
831 static int nfct_parse_synproxy(
const struct nlattr *attr,
832 struct nf_conntrack *ct)
834 struct nlattr *tb[CTA_SYNPROXY + 1] = {};
836 if (mnl_attr_parse_nested(attr, nfct_parse_synproxy_attr_cb, tb) < 0)
839 if (tb[CTA_SYNPROXY_ISN]) {
841 ntohl(mnl_attr_get_u32(tb[CTA_SYNPROXY_ISN]));
842 set_bit(ATTR_SYNPROXY_ISN, ct->head.set);
845 if (tb[CTA_SYNPROXY_ITS]) {
847 ntohl(mnl_attr_get_u32(tb[CTA_SYNPROXY_ITS]));
848 set_bit(ATTR_SYNPROXY_ITS, ct->head.set);
851 if (tb[CTA_SYNPROXY_TSOFF]) {
853 ntohl(mnl_attr_get_u32(tb[CTA_SYNPROXY_TSOFF]));
854 set_bit(ATTR_SYNPROXY_TSOFF, ct->head.set);
861 nfct_parse_conntrack_attr_cb(
const struct nlattr *attr,
void *data)
863 const struct nlattr **tb = data;
864 int type = mnl_attr_get_type(attr);
866 if (mnl_attr_type_valid(attr, CTA_MAX) < 0)
871 case CTA_TUPLE_REPLY:
872 case CTA_TUPLE_MASTER:
873 case CTA_NAT_SEQ_ADJ_ORIG:
874 case CTA_NAT_SEQ_ADJ_REPLY:
876 case CTA_COUNTERS_ORIG:
877 case CTA_COUNTERS_REPLY:
881 if (mnl_attr_validate(attr, MNL_TYPE_NESTED) < 0)
890 if (mnl_attr_validate(attr, MNL_TYPE_U32) < 0)
894 if (mnl_attr_validate(attr, MNL_TYPE_U16) < 0)
907 nfct_payload_parse(
const void *payload,
size_t payload_len,
908 uint16_t l3num,
struct nf_conntrack *ct)
910 struct nlattr *tb[CTA_MAX+1] = {};
912 if (mnl_attr_parse_payload(payload, payload_len,
913 nfct_parse_conntrack_attr_cb, tb) < 0)
916 if (tb[CTA_TUPLE_ORIG]) {
917 ct->head.orig.l3protonum = l3num;
918 set_bit(ATTR_ORIG_L3PROTO, ct->head.set);
920 if (nfct_parse_tuple(tb[CTA_TUPLE_ORIG], &ct->head.orig,
921 __DIR_ORIG, ct->head.set) < 0)
925 if (tb[CTA_TUPLE_REPLY]) {
926 ct->repl.l3protonum = l3num;
927 set_bit(ATTR_REPL_L3PROTO, ct->head.set);
929 if (nfct_parse_tuple(tb[CTA_TUPLE_REPLY], &ct->repl,
930 __DIR_REPL, ct->head.set) < 0)
934 if (tb[CTA_TUPLE_MASTER]) {
935 ct->master.l3protonum = l3num;
936 set_bit(ATTR_MASTER_L3PROTO, ct->head.set);
938 if (nfct_parse_tuple(tb[CTA_TUPLE_MASTER], &ct->master,
939 __DIR_MASTER, ct->head.set) < 0)
943 if (tb[CTA_NAT_SEQ_ADJ_ORIG]) {
944 if (nfct_parse_nat_seq(tb[CTA_NAT_SEQ_ADJ_ORIG],
949 if (tb[CTA_NAT_SEQ_ADJ_REPLY]) {
950 if (nfct_parse_nat_seq(tb[CTA_NAT_SEQ_ADJ_REPLY],
955 if (tb[CTA_STATUS]) {
956 ct->status = ntohl(mnl_attr_get_u32(tb[CTA_STATUS]));
957 set_bit(ATTR_STATUS, ct->head.set);
960 if (tb[CTA_PROTOINFO]) {
961 if (nfct_parse_protoinfo(tb[CTA_PROTOINFO], ct) < 0)
965 if (tb[CTA_TIMEOUT]) {
966 ct->timeout = ntohl(mnl_attr_get_u32(tb[CTA_TIMEOUT]));
967 set_bit(ATTR_TIMEOUT, ct->head.set);
971 ct->mark = ntohl(mnl_attr_get_u32(tb[CTA_MARK]));
972 set_bit(ATTR_MARK, ct->head.set);
975 if (tb[CTA_SECMARK]) {
976 ct->secmark = ntohl(mnl_attr_get_u32(tb[CTA_SECMARK]));
977 set_bit(ATTR_SECMARK, ct->head.set);
980 if (tb[CTA_COUNTERS_ORIG]) {
981 if (nfct_parse_counters(tb[CTA_COUNTERS_ORIG],
986 if (tb[CTA_COUNTERS_REPLY]) {
987 if (nfct_parse_counters(tb[CTA_COUNTERS_REPLY],
993 ct->use = ntohl(mnl_attr_get_u32(tb[CTA_USE]));
994 set_bit(ATTR_USE, ct->head.set);
998 ct->id = ntohl(mnl_attr_get_u32(tb[CTA_ID]));
999 set_bit(ATTR_ID, ct->head.set);
1003 if (nfct_parse_helper(tb[CTA_HELP], ct) < 0)
1008 ct->zone = ntohs(mnl_attr_get_u16(tb[CTA_ZONE]));
1009 set_bit(ATTR_ZONE, ct->head.set);
1012 if (tb[CTA_SECCTX]) {
1013 if (nfct_parse_secctx(tb[CTA_SECCTX], ct) < 0)
1017 if (tb[CTA_TIMESTAMP]) {
1018 if (nfct_parse_timestamp(tb[CTA_TIMESTAMP], ct) < 0)
1022 if (tb[CTA_LABELS]) {
1023 if (nfct_parse_labels(tb[CTA_LABELS], ct) < 0)
1028 if (tb[CTA_SYNPROXY]) {
1029 if (nfct_parse_synproxy(tb[CTA_SYNPROXY], ct) < 0)
1036 int nfct_nlmsg_parse(
const struct nlmsghdr *nlh,
struct nf_conntrack *ct)
1038 struct nfgenmsg *nfhdr = mnl_nlmsg_get_payload(nlh);
1040 return nfct_payload_parse((uint8_t *)nfhdr +
sizeof(
struct nfgenmsg),
1041 mnl_nlmsg_get_payload_len(nlh) -
sizeof(
struct nfgenmsg),
1042 nfhdr->nfgen_family, ct);
void nfct_set_attr(struct nf_conntrack *ct, const enum nf_conntrack_attr type, const void *value)