Home | History | Annotate | Download | only in conntrack
      1 /*
      2  * (C) 2005-2011 by Pablo Neira Ayuso <pablo (at) 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 
     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 
     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 
    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 
    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 
    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 
    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 
    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 
    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
    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
    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
    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 
    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
    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
    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 
    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