1/*
2 * (C) 2005-2011 by Pablo Neira Ayuso <pablo@netfilter.org>
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 */
9
10#include "internal/internal.h"
11#include <limits.h>
12#include <libmnl/libmnl.h>
13
14static void __parse_ip(const struct nfattr *attr,
15		       struct __nfct_tuple *tuple,
16		       const int dir,
17		       uint32_t *set)
18{
19	struct nfattr *tb[CTA_IP_MAX];
20
21        nfnl_parse_nested(tb, CTA_IP_MAX, attr);
22
23	if (tb[CTA_IP_V4_SRC-1]) {
24		tuple->src.v4 = *(uint32_t *)NFA_DATA(tb[CTA_IP_V4_SRC-1]);
25		switch(dir) {
26		case __DIR_ORIG:
27			set_bit(ATTR_ORIG_IPV4_SRC, set);
28			break;
29		case __DIR_REPL:
30			set_bit(ATTR_REPL_IPV4_SRC, set);
31			break;
32		case __DIR_MASTER:
33			set_bit(ATTR_MASTER_IPV4_SRC, set);
34			break;
35		}
36	}
37
38	if (tb[CTA_IP_V4_DST-1]) {
39		tuple->dst.v4 = *(uint32_t *)NFA_DATA(tb[CTA_IP_V4_DST-1]);
40		switch(dir) {
41		case __DIR_ORIG:
42			set_bit(ATTR_ORIG_IPV4_DST, set);
43			break;
44		case __DIR_REPL:
45			set_bit(ATTR_REPL_IPV4_DST, set);
46			break;
47		case __DIR_MASTER:
48			set_bit(ATTR_MASTER_IPV4_DST, set);
49			break;
50		}
51	}
52
53	if (tb[CTA_IP_V6_SRC-1]) {
54		memcpy(&tuple->src.v6, NFA_DATA(tb[CTA_IP_V6_SRC-1]),
55		       sizeof(struct in6_addr));
56		switch(dir) {
57		case __DIR_ORIG:
58			set_bit(ATTR_ORIG_IPV6_SRC, set);
59			break;
60		case __DIR_REPL:
61			set_bit(ATTR_REPL_IPV6_SRC, set);
62			break;
63		case __DIR_MASTER:
64			set_bit(ATTR_MASTER_IPV6_SRC, set);
65			break;
66		}
67	}
68
69	if (tb[CTA_IP_V6_DST-1]) {
70		memcpy(&tuple->dst.v6, NFA_DATA(tb[CTA_IP_V6_DST-1]),
71		       sizeof(struct in6_addr));
72		switch(dir) {
73		case __DIR_ORIG:
74			set_bit(ATTR_ORIG_IPV6_DST, set);
75			break;
76		case __DIR_REPL:
77			set_bit(ATTR_REPL_IPV6_DST, set);
78			break;
79		case __DIR_MASTER:
80			set_bit(ATTR_MASTER_IPV6_DST, set);
81			break;
82		}
83	}
84}
85
86static void __parse_proto(const struct nfattr *attr,
87			  struct __nfct_tuple *tuple,
88		   const int dir,
89		   uint32_t *set)
90{
91	struct nfattr *tb[CTA_PROTO_MAX];
92
93	nfnl_parse_nested(tb, CTA_PROTO_MAX, attr);
94
95	if (tb[CTA_PROTO_NUM-1]) {
96		tuple->protonum = *(uint8_t *)NFA_DATA(tb[CTA_PROTO_NUM-1]);
97		switch(dir) {
98		case __DIR_ORIG:
99			set_bit(ATTR_ORIG_L4PROTO, set);
100			break;
101		case __DIR_REPL:
102			set_bit(ATTR_REPL_L4PROTO, set);
103			break;
104		case __DIR_MASTER:
105			set_bit(ATTR_MASTER_L4PROTO, set);
106			break;
107		}
108	}
109
110	if (tb[CTA_PROTO_SRC_PORT-1]) {
111		tuple->l4src.tcp.port =
112			*(uint16_t *)NFA_DATA(tb[CTA_PROTO_SRC_PORT-1]);
113		switch(dir) {
114		case __DIR_ORIG:
115			set_bit(ATTR_ORIG_PORT_SRC, set);
116			break;
117		case __DIR_REPL:
118			set_bit(ATTR_REPL_PORT_SRC, set);
119			break;
120		case __DIR_MASTER:
121			set_bit(ATTR_MASTER_PORT_SRC, set);
122			break;
123		}
124	}
125
126	if (tb[CTA_PROTO_DST_PORT-1]) {
127		tuple->l4dst.tcp.port =
128			*(uint16_t *)NFA_DATA(tb[CTA_PROTO_DST_PORT-1]);
129		switch(dir) {
130		case __DIR_ORIG:
131			set_bit(ATTR_ORIG_PORT_DST, set);
132			break;
133		case __DIR_REPL:
134			set_bit(ATTR_REPL_PORT_DST, set);
135			break;
136		case __DIR_MASTER:
137			set_bit(ATTR_MASTER_PORT_DST, set);
138			break;
139		}
140	}
141
142	if (tb[CTA_PROTO_ICMP_TYPE-1]) {
143		tuple->l4dst.icmp.type =
144			*(uint8_t *)NFA_DATA(tb[CTA_PROTO_ICMP_TYPE-1]);
145		set_bit(ATTR_ICMP_TYPE, set);
146	}
147
148	if (tb[CTA_PROTO_ICMP_CODE-1]) {
149		tuple->l4dst.icmp.code =
150			*(uint8_t *)NFA_DATA(tb[CTA_PROTO_ICMP_CODE-1]);
151		set_bit(ATTR_ICMP_CODE, set);
152	}
153
154	if (tb[CTA_PROTO_ICMP_ID-1]) {
155		tuple->l4src.icmp.id =
156			*(uint16_t *)NFA_DATA(tb[CTA_PROTO_ICMP_ID-1]);
157		set_bit(ATTR_ICMP_ID, set);
158	}
159
160	if (tb[CTA_PROTO_ICMPV6_TYPE-1]) {
161		tuple->l4dst.icmp.type =
162			*(uint8_t *)NFA_DATA(tb[CTA_PROTO_ICMPV6_TYPE-1]);
163		set_bit(ATTR_ICMP_TYPE, set);
164	}
165
166	if (tb[CTA_PROTO_ICMPV6_CODE-1]) {
167		tuple->l4dst.icmp.code =
168			*(uint8_t *)NFA_DATA(tb[CTA_PROTO_ICMPV6_CODE-1]);
169		set_bit(ATTR_ICMP_CODE, set);
170	}
171
172	if (tb[CTA_PROTO_ICMPV6_ID-1]) {
173		tuple->l4src.icmp.id =
174			*(uint16_t *)NFA_DATA(tb[CTA_PROTO_ICMPV6_ID-1]);
175		set_bit(ATTR_ICMP_ID, set);
176	}
177}
178
179void __parse_tuple(const struct nfattr *attr,
180		   struct __nfct_tuple *tuple,
181		   int dir,
182		   uint32_t *set)
183{
184	struct nfattr *tb[CTA_TUPLE_MAX];
185
186	nfnl_parse_nested(tb, CTA_TUPLE_MAX, attr);
187
188	if (tb[CTA_TUPLE_IP-1])
189		__parse_ip(tb[CTA_TUPLE_IP-1], tuple, dir, set);
190	if (tb[CTA_TUPLE_PROTO-1])
191		__parse_proto(tb[CTA_TUPLE_PROTO-1], tuple, dir, set);
192
193	if (tb[CTA_TUPLE_ZONE-1]) {
194		tuple->zone = ntohs(*(uint16_t *)NFA_DATA(tb[CTA_TUPLE_ZONE-1]));
195		switch(dir) {
196		case __DIR_ORIG:
197			set_bit(ATTR_ORIG_ZONE, set);
198			break;
199		case __DIR_REPL:
200			set_bit(ATTR_REPL_ZONE, set);
201			break;
202		}
203	}
204}
205
206static void __parse_protoinfo_tcp(const struct nfattr *attr,
207				  struct nf_conntrack *ct)
208{
209	struct nfattr *tb[CTA_PROTOINFO_TCP_MAX];
210
211	nfnl_parse_nested(tb, CTA_PROTOINFO_TCP_MAX, attr);
212
213	if (tb[CTA_PROTOINFO_TCP_STATE-1]) {
214                ct->protoinfo.tcp.state =
215                        *(uint8_t *)NFA_DATA(tb[CTA_PROTOINFO_TCP_STATE-1]);
216		set_bit(ATTR_TCP_STATE, ct->head.set);
217	}
218
219	if (tb[CTA_PROTOINFO_TCP_WSCALE_ORIGINAL-1]) {
220		memcpy(&ct->protoinfo.tcp.wscale[__DIR_ORIG],
221		       NFA_DATA(tb[CTA_PROTOINFO_TCP_WSCALE_ORIGINAL-1]),
222		       sizeof(uint8_t));
223		set_bit(ATTR_TCP_WSCALE_ORIG, ct->head.set);
224	}
225
226	if (tb[CTA_PROTOINFO_TCP_WSCALE_REPLY-1]) {
227		memcpy(&ct->protoinfo.tcp.wscale[__DIR_REPL],
228		       NFA_DATA(tb[CTA_PROTOINFO_TCP_WSCALE_REPLY-1]),
229		       sizeof(uint8_t));
230		set_bit(ATTR_TCP_WSCALE_REPL, ct->head.set);
231	}
232
233	if (tb[CTA_PROTOINFO_TCP_FLAGS_ORIGINAL-1]) {
234		memcpy(&ct->protoinfo.tcp.flags[0],
235		       NFA_DATA(tb[CTA_PROTOINFO_TCP_FLAGS_ORIGINAL-1]),
236		       sizeof(struct nf_ct_tcp_flags));
237		set_bit(ATTR_TCP_FLAGS_ORIG, ct->head.set);
238		set_bit(ATTR_TCP_MASK_ORIG, ct->head.set);
239	}
240
241	if (tb[CTA_PROTOINFO_TCP_FLAGS_REPLY-1]) {
242		memcpy(&ct->protoinfo.tcp.flags[1],
243		       NFA_DATA(tb[CTA_PROTOINFO_TCP_FLAGS_REPLY-1]),
244		       sizeof(struct nf_ct_tcp_flags));
245		set_bit(ATTR_TCP_FLAGS_REPL, ct->head.set);
246		set_bit(ATTR_TCP_MASK_REPL, ct->head.set);
247	}
248}
249
250static void __parse_protoinfo_sctp(const struct nfattr *attr,
251				   struct nf_conntrack *ct)
252{
253	struct nfattr *tb[CTA_PROTOINFO_SCTP_MAX];
254
255	nfnl_parse_nested(tb, CTA_PROTOINFO_SCTP_MAX, attr);
256
257	if (tb[CTA_PROTOINFO_SCTP_STATE-1]) {
258                ct->protoinfo.sctp.state =
259                        *(uint8_t *)NFA_DATA(tb[CTA_PROTOINFO_SCTP_STATE-1]);
260		set_bit(ATTR_SCTP_STATE, ct->head.set);
261	}
262
263	if (tb[CTA_PROTOINFO_SCTP_VTAG_ORIGINAL-1]) {
264		ct->protoinfo.sctp.vtag[__DIR_ORIG] =
265			ntohl(*(uint32_t *)NFA_DATA(tb[CTA_PROTOINFO_SCTP_VTAG_ORIGINAL-1]));
266		set_bit(ATTR_SCTP_VTAG_ORIG, ct->head.set);
267	}
268
269	if (tb[CTA_PROTOINFO_SCTP_VTAG_REPLY-1]) {
270		ct->protoinfo.sctp.vtag[__DIR_REPL] =
271			ntohl(*(uint32_t *)NFA_DATA(tb[CTA_PROTOINFO_SCTP_VTAG_REPLY-1]));
272		set_bit(ATTR_SCTP_VTAG_REPL, ct->head.set);
273	}
274
275}
276
277static void __parse_protoinfo_dccp(const struct nfattr *attr,
278				   struct nf_conntrack *ct)
279{
280	struct nfattr *tb[CTA_PROTOINFO_DCCP_MAX];
281
282	nfnl_parse_nested(tb, CTA_PROTOINFO_DCCP_MAX, attr);
283
284	if (tb[CTA_PROTOINFO_DCCP_STATE-1]) {
285                ct->protoinfo.dccp.state =
286                        *(uint8_t *)NFA_DATA(tb[CTA_PROTOINFO_DCCP_STATE-1]);
287		set_bit(ATTR_DCCP_STATE, ct->head.set);
288	}
289	if (tb[CTA_PROTOINFO_DCCP_ROLE-1]) {
290                ct->protoinfo.dccp.role =
291                        *(uint8_t *)NFA_DATA(tb[CTA_PROTOINFO_DCCP_ROLE-1]);
292		set_bit(ATTR_DCCP_ROLE, ct->head.set);
293	}
294	if (tb[CTA_PROTOINFO_DCCP_HANDSHAKE_SEQ-1]) {
295		uint64_t tmp;
296		memcpy(&tmp,
297		       NFA_DATA(tb[CTA_PROTOINFO_DCCP_HANDSHAKE_SEQ-1]),
298		       sizeof(tmp));
299		ct->protoinfo.dccp.handshake_seq = __be64_to_cpu(tmp);
300		set_bit(ATTR_DCCP_HANDSHAKE_SEQ, ct->head.set);
301	}
302}
303
304static void __parse_protoinfo(const struct nfattr *attr,
305			      struct nf_conntrack *ct)
306{
307	struct nfattr *tb[CTA_PROTOINFO_MAX];
308
309	nfnl_parse_nested(tb, CTA_PROTOINFO_MAX, attr);
310
311	if (tb[CTA_PROTOINFO_TCP-1])
312		__parse_protoinfo_tcp(tb[CTA_PROTOINFO_TCP-1], ct);
313
314	if (tb[CTA_PROTOINFO_SCTP-1])
315		__parse_protoinfo_sctp(tb[CTA_PROTOINFO_SCTP-1], ct);
316
317	if (tb[CTA_PROTOINFO_DCCP-1])
318		__parse_protoinfo_dccp(tb[CTA_PROTOINFO_DCCP-1], ct);
319}
320
321static void __parse_counters(const struct nfattr *attr,
322			     struct nf_conntrack *ct,
323			     int dir)
324{
325	struct nfattr *tb[CTA_COUNTERS_MAX];
326
327	nfnl_parse_nested(tb, CTA_COUNTERS_MAX, attr);
328	if (tb[CTA_COUNTERS_PACKETS-1] || tb[CTA_COUNTERS32_PACKETS-1]) {
329
330		if (tb[CTA_COUNTERS32_PACKETS-1])
331			ct->counters[dir].packets
332				= ntohl(*(uint32_t *)
333					NFA_DATA(tb[CTA_COUNTERS32_PACKETS-1]));
334
335		if (tb[CTA_COUNTERS_PACKETS-1]) {
336			uint64_t tmp;
337			memcpy(&tmp,
338			       NFA_DATA(tb[CTA_COUNTERS_PACKETS-1]),
339			       sizeof(tmp));
340			ct->counters[dir].packets = __be64_to_cpu(tmp);
341		}
342
343		switch(dir) {
344		case __DIR_ORIG:
345			set_bit(ATTR_ORIG_COUNTER_PACKETS, ct->head.set);
346			break;
347		case __DIR_REPL:
348			set_bit(ATTR_REPL_COUNTER_PACKETS, ct->head.set);
349			break;
350		}
351	}
352	if (tb[CTA_COUNTERS_BYTES-1] || tb[CTA_COUNTERS32_BYTES-1]) {
353
354		if (tb[CTA_COUNTERS32_BYTES-1])
355			ct->counters[dir].bytes
356				= ntohl(*(uint32_t *)
357					NFA_DATA(tb[CTA_COUNTERS32_BYTES-1]));
358
359		if (tb[CTA_COUNTERS_BYTES-1]) {
360			uint64_t tmp;
361			memcpy(&tmp,
362			       NFA_DATA(tb[CTA_COUNTERS_BYTES-1]),
363			       sizeof(tmp));
364			ct->counters[dir].bytes = __be64_to_cpu(tmp);
365		}
366
367		switch(dir) {
368		case __DIR_ORIG:
369			set_bit(ATTR_ORIG_COUNTER_BYTES, ct->head.set);
370			break;
371		case __DIR_REPL:
372			set_bit(ATTR_REPL_COUNTER_BYTES, ct->head.set);
373			break;
374		}
375	}
376}
377
378static void
379__parse_nat_seq(const struct nfattr *attr, struct nf_conntrack *ct, int dir)
380{
381	struct nfattr *tb[CTA_NAT_SEQ_MAX];
382
383	nfnl_parse_nested(tb, CTA_NAT_SEQ_MAX, attr);
384
385	if (tb[CTA_NAT_SEQ_CORRECTION_POS-1]) {
386		ct->natseq[dir].correction_pos =
387			ntohl(*(uint32_t *)NFA_DATA(tb[CTA_NAT_SEQ_CORRECTION_POS-1]));
388		switch(dir) {
389		case __DIR_ORIG:
390			set_bit(ATTR_ORIG_NAT_SEQ_CORRECTION_POS, ct->head.set);
391			break;
392		case __DIR_REPL:
393			set_bit(ATTR_REPL_NAT_SEQ_CORRECTION_POS, ct->head.set);
394			break;
395		}
396	}
397
398	if (tb[CTA_NAT_SEQ_OFFSET_BEFORE-1]) {
399		ct->natseq[dir].offset_before =
400		ntohl(*(uint32_t *)NFA_DATA(tb[CTA_NAT_SEQ_OFFSET_BEFORE-1]));
401		switch(dir) {
402		case __DIR_ORIG:
403			set_bit(ATTR_ORIG_NAT_SEQ_OFFSET_BEFORE, ct->head.set);
404			break;
405		case __DIR_REPL:
406			set_bit(ATTR_REPL_NAT_SEQ_OFFSET_BEFORE, ct->head.set);
407			break;
408		}
409	}
410
411	if (tb[CTA_NAT_SEQ_OFFSET_AFTER-1]) {
412		ct->natseq[dir].offset_after =
413		ntohl(*(uint32_t *)NFA_DATA(tb[CTA_NAT_SEQ_OFFSET_AFTER-1]));
414		switch(dir) {
415		case __DIR_ORIG:
416			set_bit(ATTR_ORIG_NAT_SEQ_OFFSET_AFTER, ct->head.set);
417			break;
418		case __DIR_REPL:
419			set_bit(ATTR_REPL_NAT_SEQ_OFFSET_AFTER, ct->head.set);
420			break;
421		}
422	}
423}
424
425static void
426__parse_helper(const struct nfattr *attr, struct nf_conntrack *ct)
427{
428	struct nfattr *tb[CTA_HELP_MAX];
429
430	nfnl_parse_nested(tb, CTA_HELP_MAX, attr);
431	if (!tb[CTA_HELP_NAME-1])
432		return;
433
434	strncpy(ct->helper_name,
435		NFA_DATA(tb[CTA_HELP_NAME-1]),
436		NFCT_HELPER_NAME_MAX);
437	ct->helper_name[NFCT_HELPER_NAME_MAX-1] = '\0';
438	set_bit(ATTR_HELPER_NAME, ct->head.set);
439}
440
441static void
442__parse_secctx(const struct nfattr *attr, struct nf_conntrack *ct)
443{
444	struct nfattr *tb[CTA_SECCTX_MAX];
445
446	nfnl_parse_nested(tb, CTA_SECCTX_MAX, attr);
447	if (!tb[CTA_SECCTX_NAME-1])
448		return;
449
450	ct->secctx = strdup(NFA_DATA(tb[CTA_SECCTX_NAME-1]));
451	if (ct->secctx)
452		set_bit(ATTR_SECCTX, ct->head.set);
453}
454
455int __parse_message_type(const struct nlmsghdr *nlh)
456{
457	uint16_t type = NFNL_MSG_TYPE(nlh->nlmsg_type);
458	uint16_t flags = nlh->nlmsg_flags;
459	int ret = NFCT_T_UNKNOWN;
460
461	if (type == IPCTNL_MSG_CT_NEW) {
462		if (flags & (NLM_F_CREATE|NLM_F_EXCL))
463			ret = NFCT_T_NEW;
464		else
465			ret = NFCT_T_UPDATE;
466	} else if (type == IPCTNL_MSG_CT_DELETE)
467		ret = NFCT_T_DESTROY;
468
469	return ret;
470}
471
472static void
473__parse_timestamp(const struct nfattr *attr, struct nf_conntrack *ct)
474{
475	struct nfattr *tb[CTA_TIMESTAMP_MAX];
476
477	nfnl_parse_nested(tb, CTA_TIMESTAMP_MAX, attr);
478	if (tb[CTA_TIMESTAMP_START-1]) {
479		uint64_t tmp;
480		memcpy(&tmp, NFA_DATA(tb[CTA_TIMESTAMP_START-1]), sizeof(tmp));
481		ct->timestamp.start = __be64_to_cpu(tmp);
482		set_bit(ATTR_TIMESTAMP_START, ct->head.set);
483	}
484	if (tb[CTA_TIMESTAMP_STOP-1]) {
485		uint64_t tmp;
486		memcpy(&tmp, NFA_DATA(tb[CTA_TIMESTAMP_STOP-1]), sizeof(tmp));
487		ct->timestamp.stop = __be64_to_cpu(tmp);
488		set_bit(ATTR_TIMESTAMP_STOP, ct->head.set);
489	}
490}
491
492static void
493__parse_labels(const struct nfattr *attr, struct nf_conntrack *ct)
494{
495	struct nfct_bitmask *mask;
496	uint16_t len;
497
498	len = NFA_PAYLOAD(attr);
499	if (len) {
500		mask = nfct_bitmask_new((len * CHAR_BIT) - 1);
501		if (!mask)
502			return;
503		memcpy(mask->bits, NFA_DATA(attr), len);
504		nfct_set_attr(ct, ATTR_CONNLABELS, mask);
505	}
506}
507
508void __parse_conntrack(const struct nlmsghdr *nlh,
509		       struct nfattr *cda[],
510		       struct nf_conntrack *ct)
511{
512	struct nfgenmsg *nfhdr = NLMSG_DATA(nlh);
513
514	if (cda[CTA_TUPLE_ORIG-1]) {
515		ct->head.orig.l3protonum = nfhdr->nfgen_family;
516		set_bit(ATTR_ORIG_L3PROTO, ct->head.set);
517
518		__parse_tuple(cda[CTA_TUPLE_ORIG-1],
519			      &ct->head.orig, __DIR_ORIG, ct->head.set);
520	}
521
522	if (cda[CTA_TUPLE_REPLY-1]) {
523		ct->repl.l3protonum = nfhdr->nfgen_family;
524		set_bit(ATTR_REPL_L3PROTO, ct->head.set);
525
526		__parse_tuple(cda[CTA_TUPLE_REPLY-1],
527			      &ct->repl, __DIR_REPL, ct->head.set);
528	}
529
530	if (cda[CTA_TUPLE_MASTER-1]) {
531		ct->master.l3protonum = nfhdr->nfgen_family;
532		set_bit(ATTR_MASTER_L3PROTO, ct->head.set);
533
534		__parse_tuple(cda[CTA_TUPLE_MASTER-1],
535			      &ct->master, __DIR_MASTER, ct->head.set);
536	}
537
538	if (cda[CTA_NAT_SEQ_ADJ_ORIG-1])
539		__parse_nat_seq(cda[CTA_NAT_SEQ_ADJ_ORIG-1], ct, __DIR_ORIG);
540
541	if (cda[CTA_NAT_SEQ_ADJ_REPLY-1])
542		__parse_nat_seq(cda[CTA_NAT_SEQ_ADJ_REPLY-1], ct, __DIR_REPL);
543
544	if (cda[CTA_STATUS-1]) {
545		ct->status = ntohl(*(uint32_t *)NFA_DATA(cda[CTA_STATUS-1]));
546		set_bit(ATTR_STATUS, ct->head.set);
547	}
548
549	if (cda[CTA_PROTOINFO-1])
550		__parse_protoinfo(cda[CTA_PROTOINFO-1], ct);
551
552	if (cda[CTA_TIMEOUT-1]) {
553		ct->timeout = ntohl(*(uint32_t *)NFA_DATA(cda[CTA_TIMEOUT-1]));
554		set_bit(ATTR_TIMEOUT, ct->head.set);
555	}
556
557	if (cda[CTA_MARK-1]) {
558		ct->mark = ntohl(*(uint32_t *)NFA_DATA(cda[CTA_MARK-1]));
559		set_bit(ATTR_MARK, ct->head.set);
560	}
561
562	if (cda[CTA_SECMARK-1]) {
563		ct->secmark = ntohl(*(uint32_t *)NFA_DATA(cda[CTA_SECMARK-1]));
564		set_bit(ATTR_SECMARK, ct->head.set);
565	}
566
567	if (cda[CTA_COUNTERS_ORIG-1])
568		__parse_counters(cda[CTA_COUNTERS_ORIG-1], ct, __DIR_ORIG);
569
570	if (cda[CTA_COUNTERS_REPLY-1])
571		__parse_counters(cda[CTA_COUNTERS_REPLY-1], ct, __DIR_REPL);
572
573	if (cda[CTA_USE-1]) {
574		ct->use = ntohl(*(uint32_t *)NFA_DATA(cda[CTA_USE-1]));
575		set_bit(ATTR_USE, ct->head.set);
576	}
577
578	if (cda[CTA_ID-1]) {
579		ct->id = ntohl(*(uint32_t *)NFA_DATA(cda[CTA_ID-1]));
580		set_bit(ATTR_ID, ct->head.set);
581	}
582
583	if (cda[CTA_HELP-1])
584		__parse_helper(cda[CTA_HELP-1], ct);
585
586	if (cda[CTA_ZONE-1]) {
587		ct->zone = ntohs(*(uint16_t *)NFA_DATA(cda[CTA_ZONE-1]));
588		set_bit(ATTR_ZONE, ct->head.set);
589	}
590
591	if (cda[CTA_SECCTX-1])
592		__parse_secctx(cda[CTA_SECCTX-1], ct);
593
594	if (cda[CTA_TIMESTAMP-1])
595		__parse_timestamp(cda[CTA_TIMESTAMP-1], ct);
596
597	if (cda[CTA_LABELS-1])
598		__parse_labels(cda[CTA_LABELS-1], ct);
599}
600