copy.c revision 8a44513648da0c5f5551f96b329cf56b66f5b303
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 12static void copy_attr_orig_ipv4_src(struct nf_conntrack *dest, 13 const struct nf_conntrack *orig) 14{ 15 dest->head.orig.src.v4 = orig->head.orig.src.v4; 16} 17 18static void copy_attr_orig_ipv4_dst(struct nf_conntrack *dest, 19 const struct nf_conntrack *orig) 20{ 21 dest->head.orig.dst.v4 = orig->head.orig.dst.v4; 22} 23 24static void copy_attr_repl_ipv4_src(struct nf_conntrack *dest, 25 const struct nf_conntrack *orig) 26{ 27 dest->repl.src.v4 = orig->repl.src.v4; 28} 29 30static void copy_attr_repl_ipv4_dst(struct nf_conntrack *dest, 31 const struct nf_conntrack *orig) 32{ 33 dest->repl.dst.v4 = orig->repl.dst.v4; 34} 35 36static void copy_attr_orig_ipv6_src(struct nf_conntrack *dest, 37 const struct nf_conntrack *orig) 38{ 39 memcpy(&dest->head.orig.src, 40 &orig->head.orig.src, 41 sizeof(union __nfct_address)); 42} 43 44static void copy_attr_orig_ipv6_dst(struct nf_conntrack *dest, 45 const struct nf_conntrack *orig) 46{ 47 memcpy(&dest->head.orig.dst, 48 &orig->head.orig.dst, 49 sizeof(union __nfct_address)); 50} 51 52static void copy_attr_repl_ipv6_src(struct nf_conntrack *dest, 53 const struct nf_conntrack *orig) 54{ 55 memcpy(&dest->repl.src, 56 &orig->repl.src, 57 sizeof(union __nfct_address)); 58} 59 60static void copy_attr_repl_ipv6_dst(struct nf_conntrack *dest, 61 const struct nf_conntrack *orig) 62{ 63 memcpy(&dest->repl.dst, 64 &orig->repl.dst, 65 sizeof(union __nfct_address)); 66} 67 68static void copy_attr_orig_port_src(struct nf_conntrack *dest, 69 const struct nf_conntrack *orig) 70{ 71 dest->head.orig.l4src.all = orig->head.orig.l4src.all; 72} 73 74static void copy_attr_orig_port_dst(struct nf_conntrack *dest, 75 const struct nf_conntrack *orig) 76{ 77 dest->head.orig.l4dst.all = orig->head.orig.l4dst.all; 78} 79 80static void copy_attr_repl_port_src(struct nf_conntrack *dest, 81 const struct nf_conntrack *orig) 82{ 83 dest->repl.l4src.all = orig->repl.l4src.all; 84} 85 86static void copy_attr_repl_port_dst(struct nf_conntrack *dest, 87 const struct nf_conntrack *orig) 88{ 89 dest->repl.l4dst.all = orig->repl.l4dst.all; 90} 91 92static void copy_attr_orig_zone(struct nf_conntrack *dest, 93 const struct nf_conntrack *orig) 94{ 95 dest->head.orig.zone = orig->head.orig.zone; 96} 97 98static void copy_attr_repl_zone(struct nf_conntrack *dest, 99 const struct nf_conntrack *orig) 100{ 101 dest->repl.zone = orig->repl.zone; 102} 103 104static void copy_attr_icmp_type(struct nf_conntrack *dest, 105 const struct nf_conntrack *orig) 106{ 107 dest->head.orig.l4dst.icmp.type = 108 orig->head.orig.l4dst.icmp.type; 109 110} 111 112static void copy_attr_icmp_code(struct nf_conntrack *dest, 113 const struct nf_conntrack *orig) 114{ 115 dest->head.orig.l4dst.icmp.code = 116 orig->head.orig.l4dst.icmp.code; 117 118} 119 120static void copy_attr_icmp_id(struct nf_conntrack *dest, 121 const struct nf_conntrack *orig) 122{ 123 dest->head.orig.l4src.icmp.id = 124 orig->head.orig.l4src.icmp.id; 125} 126 127static void copy_attr_orig_l3proto(struct nf_conntrack *dest, 128 const struct nf_conntrack *orig) 129{ 130 dest->head.orig.l3protonum = orig->head.orig.l3protonum; 131} 132 133static void copy_attr_repl_l3proto(struct nf_conntrack *dest, 134 const struct nf_conntrack *orig) 135{ 136 dest->repl.l3protonum = orig->repl.l3protonum; 137} 138 139static void copy_attr_orig_l4proto(struct nf_conntrack *dest, 140 const struct nf_conntrack *orig) 141{ 142 dest->head.orig.protonum = orig->head.orig.protonum; 143} 144 145static void copy_attr_repl_l4proto(struct nf_conntrack *dest, 146 const struct nf_conntrack *orig) 147{ 148 dest->repl.protonum = orig->repl.protonum; 149} 150 151static void copy_attr_master_ipv4_src(struct nf_conntrack *dest, 152 const struct nf_conntrack *orig) 153{ 154 dest->master.src.v4 = orig->master.src.v4; 155} 156 157static void copy_attr_master_ipv4_dst(struct nf_conntrack *dest, 158 const struct nf_conntrack *orig) 159{ 160 dest->master.dst.v4 = orig->master.dst.v4; 161} 162 163static void copy_attr_master_ipv6_src(struct nf_conntrack *dest, 164 const struct nf_conntrack *orig) 165{ 166 memcpy(&dest->master.src, &orig->master.src, 167 sizeof(union __nfct_address)); 168} 169 170static void copy_attr_master_ipv6_dst(struct nf_conntrack *dest, 171 const struct nf_conntrack *orig) 172{ 173 memcpy(&dest->master.dst, &orig->master.dst, 174 sizeof(union __nfct_address)); 175} 176 177static void copy_attr_master_port_src(struct nf_conntrack *dest, 178 const struct nf_conntrack *orig) 179{ 180 dest->master.l4src.all = orig->master.l4src.all; 181} 182 183static void copy_attr_master_port_dst(struct nf_conntrack *dest, 184 const struct nf_conntrack *orig) 185{ 186 dest->master.l4dst.all = orig->master.l4dst.all; 187} 188 189static void copy_attr_master_l3proto(struct nf_conntrack *dest, 190 const struct nf_conntrack *orig) 191{ 192 dest->master.l3protonum = orig->master.l3protonum; 193} 194 195static void copy_attr_master_l4proto(struct nf_conntrack *dest, 196 const struct nf_conntrack *orig) 197{ 198 dest->master.protonum = orig->master.protonum; 199} 200 201static void copy_attr_tcp_state(struct nf_conntrack *dest, 202 const struct nf_conntrack *orig) 203{ 204 dest->protoinfo.tcp.state = orig->protoinfo.tcp.state; 205} 206 207static void copy_attr_tcp_flags_orig(struct nf_conntrack *dest, 208 const struct nf_conntrack *orig) 209{ 210 dest->protoinfo.tcp.flags[__DIR_ORIG].value = 211 orig->protoinfo.tcp.flags[__DIR_ORIG].value; 212} 213 214static void copy_attr_tcp_flags_repl(struct nf_conntrack *dest, 215 const struct nf_conntrack *orig) 216{ 217 dest->protoinfo.tcp.flags[__DIR_REPL].value = 218 orig->protoinfo.tcp.flags[__DIR_REPL].value; 219} 220 221static void copy_attr_tcp_mask_orig(struct nf_conntrack *dest, 222 const struct nf_conntrack *orig) 223{ 224 dest->protoinfo.tcp.flags[__DIR_ORIG].mask = 225 orig->protoinfo.tcp.flags[__DIR_ORIG].mask; 226} 227 228static void copy_attr_tcp_mask_repl(struct nf_conntrack *dest, 229 const struct nf_conntrack *orig) 230{ 231 dest->protoinfo.tcp.flags[__DIR_REPL].mask = 232 orig->protoinfo.tcp.flags[__DIR_REPL].mask; 233} 234 235static void copy_attr_tcp_wscale_orig(struct nf_conntrack *dest, 236 const struct nf_conntrack *orig) 237{ 238 dest->protoinfo.tcp.wscale[__DIR_ORIG] = 239 orig->protoinfo.tcp.wscale[__DIR_ORIG]; 240} 241 242static void copy_attr_tcp_wscale_repl(struct nf_conntrack *dest, 243 const struct nf_conntrack *orig) 244{ 245 dest->protoinfo.tcp.wscale[__DIR_REPL] = 246 orig->protoinfo.tcp.wscale[__DIR_REPL]; 247} 248 249static void copy_attr_sctp_state(struct nf_conntrack *dest, 250 const struct nf_conntrack *orig) 251{ 252 dest->protoinfo.sctp.state = orig->protoinfo.sctp.state; 253} 254 255static void copy_attr_sctp_vtag_orig(struct nf_conntrack *dest, 256 const struct nf_conntrack *orig) 257{ 258 dest->protoinfo.sctp.vtag[__DIR_ORIG] = 259 orig->protoinfo.sctp.vtag[__DIR_ORIG]; 260} 261 262static void copy_attr_sctp_vtag_repl(struct nf_conntrack *dest, 263 const struct nf_conntrack *orig) 264{ 265 dest->protoinfo.sctp.vtag[__DIR_REPL] = 266 orig->protoinfo.sctp.vtag[__DIR_REPL]; 267} 268 269static void copy_attr_dccp_state(struct nf_conntrack *dest, 270 const struct nf_conntrack *orig) 271{ 272 dest->protoinfo.dccp.state = orig->protoinfo.dccp.state; 273} 274 275static void copy_attr_dccp_role(struct nf_conntrack *dest, 276 const struct nf_conntrack *orig) 277{ 278 dest->protoinfo.dccp.role = orig->protoinfo.dccp.role; 279} 280 281static void copy_attr_dccp_handshake_seq(struct nf_conntrack *dest, 282 const struct nf_conntrack *orig) 283{ 284 dest->protoinfo.dccp.handshake_seq = orig->protoinfo.dccp.handshake_seq; 285} 286 287static void copy_attr_snat_ipv4(struct nf_conntrack *dest, 288 const struct nf_conntrack *orig) 289{ 290 dest->snat.min_ip.v4 = orig->snat.min_ip.v4; 291} 292 293static void copy_attr_dnat_ipv4(struct nf_conntrack *dest, 294 const struct nf_conntrack *orig) 295{ 296 dest->dnat.min_ip.v4 = orig->dnat.min_ip.v4; 297} 298 299static void copy_attr_snat_ipv6(struct nf_conntrack *dest, 300 const struct nf_conntrack *orig) 301{ 302 memcpy(&dest->snat.min_ip.v6, &orig->snat.min_ip.v6, 303 sizeof(struct in6_addr)); 304} 305 306static void copy_attr_dnat_ipv6(struct nf_conntrack *dest, 307 const struct nf_conntrack *orig) 308{ 309 memcpy(&dest->dnat.min_ip.v6, &orig->dnat.min_ip.v6, 310 sizeof(struct in6_addr)); 311} 312 313static void copy_attr_snat_port(struct nf_conntrack *dest, 314 const struct nf_conntrack *orig) 315{ 316 dest->snat.l4min.all = orig->snat.l4min.all; 317} 318 319static void copy_attr_dnat_port(struct nf_conntrack *dest, 320 const struct nf_conntrack *orig) 321{ 322 dest->dnat.l4min.all = orig->dnat.l4min.all; 323} 324 325static void copy_attr_timeout(struct nf_conntrack *dest, 326 const struct nf_conntrack *orig) 327{ 328 dest->timeout = orig->timeout; 329} 330 331static void copy_attr_mark(struct nf_conntrack *dest, 332 const struct nf_conntrack *orig) 333{ 334 dest->mark = orig->mark; 335} 336 337static void copy_attr_secmark(struct nf_conntrack *dest, 338 const struct nf_conntrack *orig) 339{ 340 dest->secmark = orig->secmark; 341} 342 343static void copy_attr_orig_counter_packets(struct nf_conntrack *dest, 344 const struct nf_conntrack *orig) 345{ 346 dest->counters[__DIR_ORIG].packets = orig->counters[__DIR_ORIG].packets; 347} 348 349static void copy_attr_repl_counter_packets(struct nf_conntrack *dest, 350 const struct nf_conntrack *orig) 351{ 352 dest->counters[__DIR_REPL].packets = orig->counters[__DIR_REPL].packets; 353} 354 355static void copy_attr_orig_counter_bytes(struct nf_conntrack *dest, 356 const struct nf_conntrack *orig) 357{ 358 dest->counters[__DIR_ORIG].bytes = orig->counters[__DIR_ORIG].bytes; 359} 360 361static void copy_attr_repl_counter_bytes(struct nf_conntrack *dest, 362 const struct nf_conntrack *orig) 363{ 364 dest->counters[__DIR_REPL].bytes = orig->counters[__DIR_REPL].bytes; 365} 366 367static void copy_attr_status(struct nf_conntrack *dest, 368 const struct nf_conntrack *orig) 369{ 370 dest->status = orig->status; 371} 372 373static void copy_attr_use(struct nf_conntrack *dest, 374 const struct nf_conntrack *orig) 375{ 376 dest->use = orig->use; 377} 378 379static void copy_attr_id(struct nf_conntrack *dest, 380 const struct nf_conntrack *orig) 381{ 382 dest->id = orig->id; 383} 384 385static void copy_attr_orig_cor_pos(struct nf_conntrack *dest, 386 const struct nf_conntrack *orig) 387{ 388 dest->natseq[__DIR_ORIG].correction_pos = 389 orig->natseq[__DIR_ORIG].correction_pos; 390} 391 392static void copy_attr_orig_off_bfr(struct nf_conntrack *dest, 393 const struct nf_conntrack *orig) 394{ 395 dest->natseq[__DIR_ORIG].offset_before = 396 orig->natseq[__DIR_ORIG].offset_before; 397} 398 399static void copy_attr_orig_off_aft(struct nf_conntrack *dest, 400 const struct nf_conntrack *orig) 401{ 402 dest->natseq[__DIR_ORIG].offset_after = 403 orig->natseq[__DIR_ORIG].offset_after; 404} 405 406static void copy_attr_repl_cor_pos(struct nf_conntrack *dest, 407 const struct nf_conntrack *orig) 408{ 409 dest->natseq[__DIR_REPL].correction_pos = 410 orig->natseq[__DIR_REPL].correction_pos; 411} 412 413static void copy_attr_repl_off_bfr(struct nf_conntrack *dest, 414 const struct nf_conntrack *orig) 415{ 416 dest->natseq[__DIR_REPL].offset_before = 417 orig->natseq[__DIR_REPL].offset_before; 418} 419 420static void copy_attr_repl_off_aft(struct nf_conntrack *dest, 421 const struct nf_conntrack *orig) 422{ 423 dest->natseq[__DIR_REPL].offset_after = 424 orig->natseq[__DIR_REPL].offset_after; 425} 426 427static void copy_attr_helper_name(struct nf_conntrack *dest, 428 const struct nf_conntrack *orig) 429{ 430 strncpy(dest->helper_name, orig->helper_name, NFCT_HELPER_NAME_MAX); 431 dest->helper_name[NFCT_HELPER_NAME_MAX-1] = '\0'; 432} 433 434static void copy_attr_zone(struct nf_conntrack *dest, 435 const struct nf_conntrack *orig) 436{ 437 dest->zone = orig->zone; 438} 439 440static void copy_attr_secctx(struct nf_conntrack *dest, 441 const struct nf_conntrack *orig) 442{ 443 if (dest->secctx) { 444 free(dest->secctx); 445 dest->secctx = NULL; 446 } 447 if (orig->secctx) 448 dest->secctx = strdup(orig->secctx); 449} 450 451static void copy_attr_timestamp_start(struct nf_conntrack *dest, 452 const struct nf_conntrack *orig) 453{ 454 dest->timestamp.start = orig->timestamp.start; 455} 456 457static void copy_attr_timestamp_stop(struct nf_conntrack *dest, 458 const struct nf_conntrack *orig) 459{ 460 dest->timestamp.stop = orig->timestamp.stop; 461} 462 463static void copy_attr_help_info(struct nf_conntrack *dest, 464 const struct nf_conntrack *orig) 465{ 466 if (orig->helper_info == NULL) 467 return; 468 469 if (dest->helper_info != NULL) 470 free(dest->helper_info); 471 472 dest->helper_info = calloc(1, orig->helper_info_len); 473 if (dest->helper_info == NULL) 474 return; 475 476 memcpy(dest->helper_info, orig->helper_info, orig->helper_info_len); 477} 478 479static void* do_copy_attr_connlabels(struct nfct_bitmask *dest, 480 const struct nfct_bitmask *orig) 481{ 482 if (orig == NULL) 483 return dest; 484 if (dest) 485 nfct_bitmask_destroy(dest); 486 return nfct_bitmask_clone(orig); 487} 488 489static void copy_attr_connlabels(struct nf_conntrack *dest, 490 const struct nf_conntrack *orig) 491{ 492 dest->connlabels = do_copy_attr_connlabels(dest->connlabels, orig->connlabels); 493} 494 495static void copy_attr_connlabels_mask(struct nf_conntrack *dest, 496 const struct nf_conntrack *orig) 497{ 498 dest->connlabels_mask = do_copy_attr_connlabels(dest->connlabels_mask, orig->connlabels_mask); 499} 500 501const copy_attr copy_attr_array[ATTR_MAX] = { 502 [ATTR_ORIG_IPV4_SRC] = copy_attr_orig_ipv4_src, 503 [ATTR_ORIG_IPV4_DST] = copy_attr_orig_ipv4_dst, 504 [ATTR_REPL_IPV4_SRC] = copy_attr_repl_ipv4_src, 505 [ATTR_REPL_IPV4_DST] = copy_attr_repl_ipv4_dst, 506 [ATTR_ORIG_IPV6_SRC] = copy_attr_orig_ipv6_src, 507 [ATTR_ORIG_IPV6_DST] = copy_attr_orig_ipv6_dst, 508 [ATTR_REPL_IPV6_SRC] = copy_attr_repl_ipv6_src, 509 [ATTR_REPL_IPV6_DST] = copy_attr_repl_ipv6_dst, 510 [ATTR_ORIG_PORT_SRC] = copy_attr_orig_port_src, 511 [ATTR_ORIG_PORT_DST] = copy_attr_orig_port_dst, 512 [ATTR_REPL_PORT_SRC] = copy_attr_repl_port_src, 513 [ATTR_REPL_PORT_DST] = copy_attr_repl_port_dst, 514 [ATTR_ICMP_TYPE] = copy_attr_icmp_type, 515 [ATTR_ICMP_CODE] = copy_attr_icmp_code, 516 [ATTR_ICMP_ID] = copy_attr_icmp_id, 517 [ATTR_ORIG_L3PROTO] = copy_attr_orig_l3proto, 518 [ATTR_REPL_L3PROTO] = copy_attr_repl_l3proto, 519 [ATTR_ORIG_L4PROTO] = copy_attr_orig_l4proto, 520 [ATTR_REPL_L4PROTO] = copy_attr_repl_l4proto, 521 [ATTR_TCP_STATE] = copy_attr_tcp_state, 522 [ATTR_SNAT_IPV4] = copy_attr_snat_ipv4, 523 [ATTR_DNAT_IPV4] = copy_attr_dnat_ipv4, 524 [ATTR_SNAT_PORT] = copy_attr_snat_port, 525 [ATTR_DNAT_PORT] = copy_attr_dnat_port, 526 [ATTR_TIMEOUT] = copy_attr_timeout, 527 [ATTR_MARK] = copy_attr_mark, 528 [ATTR_ORIG_COUNTER_PACKETS] = copy_attr_orig_counter_packets, 529 [ATTR_ORIG_COUNTER_BYTES] = copy_attr_orig_counter_bytes, 530 [ATTR_REPL_COUNTER_PACKETS] = copy_attr_repl_counter_packets, 531 [ATTR_REPL_COUNTER_BYTES] = copy_attr_repl_counter_bytes, 532 [ATTR_USE] = copy_attr_use, 533 [ATTR_ID] = copy_attr_id, 534 [ATTR_STATUS] = copy_attr_status, 535 [ATTR_TCP_FLAGS_ORIG] = copy_attr_tcp_flags_orig, 536 [ATTR_TCP_FLAGS_REPL] = copy_attr_tcp_flags_repl, 537 [ATTR_TCP_MASK_ORIG] = copy_attr_tcp_mask_orig, 538 [ATTR_TCP_MASK_REPL] = copy_attr_tcp_mask_repl, 539 [ATTR_MASTER_IPV4_SRC] = copy_attr_master_ipv4_src, 540 [ATTR_MASTER_IPV4_DST] = copy_attr_master_ipv4_dst, 541 [ATTR_MASTER_IPV6_SRC] = copy_attr_master_ipv6_src, 542 [ATTR_MASTER_IPV6_DST] = copy_attr_master_ipv6_dst, 543 [ATTR_MASTER_PORT_SRC] = copy_attr_master_port_src, 544 [ATTR_MASTER_PORT_DST] = copy_attr_master_port_dst, 545 [ATTR_MASTER_L3PROTO] = copy_attr_master_l3proto, 546 [ATTR_MASTER_L4PROTO] = copy_attr_master_l4proto, 547 [ATTR_SECMARK] = copy_attr_secmark, 548 [ATTR_ORIG_NAT_SEQ_CORRECTION_POS] = copy_attr_orig_cor_pos, 549 [ATTR_ORIG_NAT_SEQ_OFFSET_BEFORE] = copy_attr_orig_off_bfr, 550 [ATTR_ORIG_NAT_SEQ_OFFSET_AFTER] = copy_attr_orig_off_aft, 551 [ATTR_REPL_NAT_SEQ_CORRECTION_POS] = copy_attr_repl_cor_pos, 552 [ATTR_REPL_NAT_SEQ_OFFSET_BEFORE] = copy_attr_repl_off_bfr, 553 [ATTR_REPL_NAT_SEQ_OFFSET_AFTER] = copy_attr_repl_off_aft, 554 [ATTR_SCTP_STATE] = copy_attr_sctp_state, 555 [ATTR_SCTP_VTAG_ORIG] = copy_attr_sctp_vtag_orig, 556 [ATTR_SCTP_VTAG_REPL] = copy_attr_sctp_vtag_repl, 557 [ATTR_HELPER_NAME] = copy_attr_helper_name, 558 [ATTR_DCCP_STATE] = copy_attr_dccp_state, 559 [ATTR_DCCP_ROLE] = copy_attr_dccp_role, 560 [ATTR_DCCP_HANDSHAKE_SEQ] = copy_attr_dccp_handshake_seq, 561 [ATTR_TCP_WSCALE_ORIG] = copy_attr_tcp_wscale_orig, 562 [ATTR_TCP_WSCALE_REPL] = copy_attr_tcp_wscale_repl, 563 [ATTR_ZONE] = copy_attr_zone, 564 [ATTR_ORIG_ZONE] = copy_attr_orig_zone, 565 [ATTR_REPL_ZONE] = copy_attr_repl_zone, 566 [ATTR_SECCTX] = copy_attr_secctx, 567 [ATTR_TIMESTAMP_START] = copy_attr_timestamp_start, 568 [ATTR_TIMESTAMP_STOP] = copy_attr_timestamp_stop, 569 [ATTR_HELPER_INFO] = copy_attr_help_info, 570 [ATTR_CONNLABELS] = copy_attr_connlabels, 571 [ATTR_CONNLABELS_MASK] = copy_attr_connlabels_mask, 572 [ATTR_SNAT_IPV6] = copy_attr_snat_ipv6, 573 [ATTR_DNAT_IPV6] = copy_attr_dnat_ipv6, 574}; 575 576/* this is used by nfct_copy() with the NFCT_CP_OVERRIDE flag set. */ 577void __copy_fast(struct nf_conntrack *ct1, const struct nf_conntrack *ct2) 578{ 579 memcpy(ct1, ct2, sizeof(*ct1)); 580 /* malloc'd attributes: don't free, do copy */ 581 ct1->secctx = NULL; 582 ct1->helper_info = NULL; 583 ct1->connlabels = NULL; 584 ct1->connlabels_mask = NULL; 585 586 copy_attr_secctx(ct1, ct2); 587 copy_attr_help_info(ct1, ct2); 588 copy_attr_connlabels(ct1, ct2); 589 copy_attr_connlabels_mask(ct1, ct2); 590} 591