12#include "internal/internal.h"
13#include <libmnl/libmnl.h>
18nfct_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) {
46nfct_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);
119nfct_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)
149nfct_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);
243static 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)
268nfct_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);
302nfct_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)
329nfct_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);
376nfct_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)
400nfct_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);
429nfct_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)
453nfct_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);
478nfct_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)
499nfct_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);
518static 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)
543nfct_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);
593nfct_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)
614nfct_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);
664nfct_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)
683nfct_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 snprintf(ct->helper_name, NFCT_HELPER_NAME_MAX,
"%s",
694 mnl_attr_get_str(tb[CTA_HELP_NAME]));
695 set_bit(ATTR_HELPER_NAME, ct->head.set);
697 if (!tb[CTA_HELP_INFO])
700 ct->helper_info_len = mnl_attr_get_payload_len(tb[CTA_HELP_INFO]);
701 ct->helper_info = calloc(1, ct->helper_info_len);
702 if (ct->helper_info == NULL)
705 memcpy(ct->helper_info, mnl_attr_get_payload(tb[CTA_HELP_INFO]),
706 ct->helper_info_len);
707 set_bit(ATTR_HELPER_INFO, ct->head.set);
713nfct_parse_secctx_attr_cb(
const struct nlattr *attr,
void *data)
715 const struct nlattr **tb = data;
716 int type = mnl_attr_get_type(attr);
718 if (mnl_attr_type_valid(attr, CTA_SECCTX_MAX) < 0)
722 case CTA_SECCTX_NAME:
723 if (mnl_attr_validate(attr, MNL_TYPE_STRING) < 0)
732nfct_parse_secctx(
const struct nlattr *attr,
struct nf_conntrack *ct)
734 struct nlattr *tb[CTA_SECCTX_MAX+1] = {};
736 if (mnl_attr_parse_nested(attr, nfct_parse_secctx_attr_cb, tb) < 0)
739 if (!tb[CTA_SECCTX_NAME])
742 ct->secctx = strdup(NFA_DATA(tb[CTA_SECCTX_NAME]));
744 set_bit(ATTR_SECCTX, ct->head.set);
750nfct_parse_timestamp_attr_cb(
const struct nlattr *attr,
void *data)
752 const struct nlattr **tb = data;
753 int type = mnl_attr_get_type(attr);
755 if (mnl_attr_type_valid(attr, CTA_TIMESTAMP_MAX) < 0)
759 case CTA_TIMESTAMP_START:
760 case CTA_TIMESTAMP_STOP:
761 if (mnl_attr_validate(attr, MNL_TYPE_U64) < 0)
770nfct_parse_timestamp(
const struct nlattr *attr,
struct nf_conntrack *ct)
772 struct nlattr *tb[CTA_TIMESTAMP_MAX+1] = {};
774 if (mnl_attr_parse_nested(attr, nfct_parse_timestamp_attr_cb, tb) < 0)
777 if (tb[CTA_TIMESTAMP_START]) {
778 ct->timestamp.start =
779 be64toh(mnl_attr_get_u64(tb[CTA_TIMESTAMP_START]));
780 set_bit(ATTR_TIMESTAMP_START, ct->head.set);
782 if (tb[CTA_TIMESTAMP_STOP]) {
784 be64toh(mnl_attr_get_u64(tb[CTA_TIMESTAMP_STOP]));
785 set_bit(ATTR_TIMESTAMP_STOP, ct->head.set);
791static int nfct_parse_labels(
const struct nlattr *attr,
struct nf_conntrack *ct)
793 uint16_t len = mnl_attr_get_payload_len(attr);
794 struct nfct_bitmask *mask;
800 mask = nfct_bitmask_new((len * CHAR_BIT) - 1);
803 bits = mnl_attr_get_payload(attr);
805 memcpy(mask->bits, bits, len);
810static int nfct_parse_synproxy_attr_cb(
const struct nlattr *attr,
void *data)
812 int type = mnl_attr_get_type(attr);
813 const struct nlattr **tb = data;
815 if (mnl_attr_type_valid(attr, CTA_SYNPROXY_MAX) < 0)
819 case CTA_SYNPROXY_ISN:
820 case CTA_SYNPROXY_ITS:
821 case CTA_SYNPROXY_TSOFF:
822 if (mnl_attr_validate(attr, MNL_TYPE_U32) < 0)
830static int nfct_parse_synproxy(
const struct nlattr *attr,
831 struct nf_conntrack *ct)
833 struct nlattr *tb[CTA_SYNPROXY + 1] = {};
835 if (mnl_attr_parse_nested(attr, nfct_parse_synproxy_attr_cb, tb) < 0)
838 if (tb[CTA_SYNPROXY_ISN]) {
840 ntohl(mnl_attr_get_u32(tb[CTA_SYNPROXY_ISN]));
841 set_bit(ATTR_SYNPROXY_ISN, ct->head.set);
844 if (tb[CTA_SYNPROXY_ITS]) {
846 ntohl(mnl_attr_get_u32(tb[CTA_SYNPROXY_ITS]));
847 set_bit(ATTR_SYNPROXY_ITS, ct->head.set);
850 if (tb[CTA_SYNPROXY_TSOFF]) {
852 ntohl(mnl_attr_get_u32(tb[CTA_SYNPROXY_TSOFF]));
853 set_bit(ATTR_SYNPROXY_TSOFF, ct->head.set);
860nfct_parse_conntrack_attr_cb(
const struct nlattr *attr,
void *data)
862 const struct nlattr **tb = data;
863 int type = mnl_attr_get_type(attr);
865 if (mnl_attr_type_valid(attr, CTA_MAX) < 0)
870 case CTA_TUPLE_REPLY:
871 case CTA_TUPLE_MASTER:
872 case CTA_NAT_SEQ_ADJ_ORIG:
873 case CTA_NAT_SEQ_ADJ_REPLY:
875 case CTA_COUNTERS_ORIG:
876 case CTA_COUNTERS_REPLY:
880 if (mnl_attr_validate(attr, MNL_TYPE_NESTED) < 0)
889 if (mnl_attr_validate(attr, MNL_TYPE_U32) < 0)
893 if (mnl_attr_validate(attr, MNL_TYPE_U16) < 0)
906nfct_payload_parse(
const void *payload,
size_t payload_len,
907 uint16_t l3num,
struct nf_conntrack *ct)
909 struct nlattr *tb[CTA_MAX+1] = {};
911 if (mnl_attr_parse_payload(payload, payload_len,
912 nfct_parse_conntrack_attr_cb, tb) < 0)
915 if (tb[CTA_TUPLE_ORIG]) {
916 ct->head.orig.l3protonum = l3num;
917 set_bit(ATTR_ORIG_L3PROTO, ct->head.set);
919 if (nfct_parse_tuple(tb[CTA_TUPLE_ORIG], &ct->head.orig,
920 __DIR_ORIG, ct->head.set) < 0)
924 if (tb[CTA_TUPLE_REPLY]) {
925 ct->repl.l3protonum = l3num;
926 set_bit(ATTR_REPL_L3PROTO, ct->head.set);
928 if (nfct_parse_tuple(tb[CTA_TUPLE_REPLY], &ct->repl,
929 __DIR_REPL, ct->head.set) < 0)
933 if (tb[CTA_TUPLE_MASTER]) {
934 ct->master.l3protonum = l3num;
935 set_bit(ATTR_MASTER_L3PROTO, ct->head.set);
937 if (nfct_parse_tuple(tb[CTA_TUPLE_MASTER], &ct->master,
938 __DIR_MASTER, ct->head.set) < 0)
942 if (tb[CTA_NAT_SEQ_ADJ_ORIG]) {
943 if (nfct_parse_nat_seq(tb[CTA_NAT_SEQ_ADJ_ORIG],
948 if (tb[CTA_NAT_SEQ_ADJ_REPLY]) {
949 if (nfct_parse_nat_seq(tb[CTA_NAT_SEQ_ADJ_REPLY],
954 if (tb[CTA_STATUS]) {
955 ct->status = ntohl(mnl_attr_get_u32(tb[CTA_STATUS]));
956 set_bit(ATTR_STATUS, ct->head.set);
959 if (tb[CTA_PROTOINFO]) {
960 if (nfct_parse_protoinfo(tb[CTA_PROTOINFO], ct) < 0)
964 if (tb[CTA_TIMEOUT]) {
965 ct->timeout = ntohl(mnl_attr_get_u32(tb[CTA_TIMEOUT]));
966 set_bit(ATTR_TIMEOUT, ct->head.set);
970 ct->mark = ntohl(mnl_attr_get_u32(tb[CTA_MARK]));
971 set_bit(ATTR_MARK, ct->head.set);
974 if (tb[CTA_SECMARK]) {
975 ct->secmark = ntohl(mnl_attr_get_u32(tb[CTA_SECMARK]));
976 set_bit(ATTR_SECMARK, ct->head.set);
979 if (tb[CTA_COUNTERS_ORIG]) {
980 if (nfct_parse_counters(tb[CTA_COUNTERS_ORIG],
985 if (tb[CTA_COUNTERS_REPLY]) {
986 if (nfct_parse_counters(tb[CTA_COUNTERS_REPLY],
992 ct->use = ntohl(mnl_attr_get_u32(tb[CTA_USE]));
993 set_bit(ATTR_USE, ct->head.set);
997 ct->id = ntohl(mnl_attr_get_u32(tb[CTA_ID]));
998 set_bit(ATTR_ID, ct->head.set);
1002 if (nfct_parse_helper(tb[CTA_HELP], ct) < 0)
1007 ct->zone = ntohs(mnl_attr_get_u16(tb[CTA_ZONE]));
1008 set_bit(ATTR_ZONE, ct->head.set);
1011 if (tb[CTA_SECCTX]) {
1012 if (nfct_parse_secctx(tb[CTA_SECCTX], ct) < 0)
1016 if (tb[CTA_TIMESTAMP]) {
1017 if (nfct_parse_timestamp(tb[CTA_TIMESTAMP], ct) < 0)
1021 if (tb[CTA_LABELS]) {
1022 if (nfct_parse_labels(tb[CTA_LABELS], ct) < 0)
1027 if (tb[CTA_SYNPROXY]) {
1028 if (nfct_parse_synproxy(tb[CTA_SYNPROXY], ct) < 0)
1035int nfct_nlmsg_parse(
const struct nlmsghdr *nlh,
struct nf_conntrack *ct)
1037 struct nfgenmsg *nfhdr = mnl_nlmsg_get_payload(nlh);
1039 return nfct_payload_parse((uint8_t *)nfhdr +
sizeof(
struct nfgenmsg),
1040 mnl_nlmsg_get_payload_len(nlh) -
sizeof(
struct nfgenmsg),
1041 nfhdr->nfgen_family, ct);
void nfct_set_attr(struct nf_conntrack *ct, const enum nf_conntrack_attr type, const void *value)