• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
__parse_ip(const struct nfattr * attr,struct __nfct_tuple * tuple,const int dir,uint32_t * set)16 static 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 
__parse_proto(const struct nfattr * attr,struct __nfct_tuple * tuple,const int dir,uint32_t * set)88 static 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 
__parse_tuple(const struct nfattr * attr,struct __nfct_tuple * tuple,int dir,uint32_t * set)181 void __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 
__parse_protoinfo_tcp(const struct nfattr * attr,struct nf_conntrack * ct)208 static 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 
__parse_protoinfo_sctp(const struct nfattr * attr,struct nf_conntrack * ct)252 static 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 
__parse_protoinfo_dccp(const struct nfattr * attr,struct nf_conntrack * ct)279 static 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 
__parse_protoinfo(const struct nfattr * attr,struct nf_conntrack * ct)306 static 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 
__parse_counters(const struct nfattr * attr,struct nf_conntrack * ct,int dir)323 static 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 
380 static void
__parse_nat_seq(const struct nfattr * attr,struct nf_conntrack * ct,int dir)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 
427 static void
__parse_helper(const struct nfattr * attr,struct nf_conntrack * ct)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 
443 static void
__parse_secctx(const struct nfattr * attr,struct nf_conntrack * ct)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 
__parse_message_type(const struct nlmsghdr * nlh)457 int __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 
474 static void
__parse_timestamp(const struct nfattr * attr,struct nf_conntrack * ct)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 
494 static void
__parse_labels(const struct nfattr * attr,struct nf_conntrack * ct)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 
__parse_conntrack(const struct nlmsghdr * nlh,struct nfattr * cda[],struct nf_conntrack * ct)510 void __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