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