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