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