112
119
static char commands_v_options[NUMBER_OF_CMD][NUMBER_OF_OPT] =
113
120
/* Well, it's better than "Re: Linux vs FreeBSD" */
115
/* s d r q p t u z e x y k l a m i f*/
116
/*CT_LIST*/ {2,2,2,2,2,0,0,2,0,0,0,0,0,0,2,2,2},
117
/*CT_CREATE*/ {2,2,2,2,1,1,1,0,0,0,0,0,0,2,2,0,0},
118
/*CT_UPDATE*/ {2,2,2,2,1,2,2,0,0,0,0,0,0,0,2,2,0},
119
/*CT_DELETE*/ {2,2,2,2,2,0,0,0,0,0,0,0,0,0,0,2,0},
120
/*CT_GET*/ {2,2,2,2,1,0,0,0,0,0,0,0,0,0,0,2,0},
121
/*CT_FLUSH*/ {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
122
/*CT_EVENT*/ {2,2,2,2,2,0,0,0,2,0,0,0,0,0,2,0,0},
123
/*VERSION*/ {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
124
/*HELP*/ {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
125
/*EXP_LIST*/ {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2},
126
/*EXP_CREATE*/{1,1,2,2,1,1,2,0,0,1,1,1,1,0,0,0,0},
127
/*EXP_DELETE*/{1,1,2,2,1,0,0,0,0,0,0,0,0,0,0,0,0},
128
/*EXP_GET*/ {1,1,2,2,1,0,0,0,0,0,0,0,0,0,0,0,0},
129
/*EXP_FLUSH*/ {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
130
/*EXP_EVENT*/ {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
122
/* s d r q p t u z e [ ] { } a m i f n g o c */
123
/*CT_LIST*/ {2,2,2,2,2,0,0,2,0,0,0,0,0,0,2,2,2,2,2,2,2},
124
/*CT_CREATE*/ {2,2,2,2,1,1,1,0,0,0,0,0,0,2,2,0,0,2,2,0,2},
125
/*CT_UPDATE*/ {2,2,2,2,1,2,2,0,0,0,0,0,0,0,2,2,0,0,0,0,2},
126
/*CT_DELETE*/ {2,2,2,2,2,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0},
127
/*CT_GET*/ {2,2,2,2,1,0,0,0,0,0,0,0,0,0,0,2,0,0,0,2,0},
128
/*CT_FLUSH*/ {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
129
/*CT_EVENT*/ {2,2,2,2,2,0,0,0,2,0,0,0,0,0,2,0,0,2,2,2,2},
130
/*VERSION*/ {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
131
/*HELP*/ {0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
132
/*EXP_LIST*/ {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,0,0,0,0},
133
/*EXP_CREATE*/{1,1,2,2,1,1,2,0,0,1,1,1,1,0,0,0,0,0,0,0,0},
134
/*EXP_DELETE*/{1,1,2,2,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
135
/*EXP_GET*/ {1,1,2,2,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
136
/*EXP_FLUSH*/ {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
137
/*EXP_EVENT*/ {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
133
static char *lib_dir = CONNTRACK_LIB_DIR;
135
140
static LIST_HEAD(proto_list);
142
static unsigned int options;
144
#define CT_COMPARISON (CT_OPT_PROTO | CT_OPT_ORIG | CT_OPT_REPL | CT_OPT_MARK |\
137
147
void register_proto(struct ctproto_handler *h)
139
149
if (strcmp(h->version, VERSION) != 0) {
457
460
/* Shamelessly stolen from libipt_DNAT ;). Ranges expected in network order. */
459
nat_parse(char *arg, int portok, struct nfct_nat *range)
462
nat_parse(char *arg, int portok, struct nf_conntrack *obj, int type)
461
char *colon, *dash, *error;
462
struct addr_parse parse;
465
union ct_address parse;
464
memset(range, 0, sizeof(range));
465
467
colon = strchr(arg, ':');
471
473
exit_error(PARAMETER_PROBLEM,
472
474
"Need TCP or UDP with port specification");
474
port = atoi(colon+1);
475
if (port == 0 || port > 65535)
476
port = (uint16_t)atoi(colon+1);
476
478
exit_error(PARAMETER_PROBLEM,
477
479
"Port `%s' not valid\n", colon+1);
479
481
error = strchr(colon+1, ':');
481
483
exit_error(PARAMETER_PROBLEM,
482
"Invalid port:port syntax - use dash\n");
484
dash = strchr(colon, '-');
486
range->l4min.tcp.port
487
= range->l4max.tcp.port
492
maxport = atoi(dash + 1);
493
if (maxport == 0 || maxport > 65535)
494
exit_error(PARAMETER_PROBLEM,
495
"Port `%s' not valid\n", dash+1);
497
/* People are stupid. */
498
exit_error(PARAMETER_PROBLEM,
499
"Port range `%s' funky\n", colon+1);
500
range->l4min.tcp.port = htons(port);
501
range->l4max.tcp.port = htons(maxport);
503
/* Starts with a colon? No IP info... */
484
"Invalid port:port syntax\n");
486
if (type == CT_OPT_SRC_NAT)
487
nfct_set_attr_u16(obj, ATTR_SNAT_PORT, port);
488
else if (type == CT_OPT_DST_NAT)
489
nfct_set_attr_u16(obj, ATTR_DNAT_PORT, port);
509
dash = strchr(arg, '-');
510
if (colon && dash && dash > colon)
516
if (__parse_inetaddr(arg, &parse) != AF_INET)
492
if (parse_addr(arg, &parse) != AF_INET)
519
range->min_ip = parse.addr.s_addr;
521
if (__parse_inetaddr(dash+1, &parse) != AF_INET)
523
range->max_ip = parse.addr.s_addr;
525
range->max_ip = parse.addr.s_addr;
495
if (type == CT_OPT_SRC_NAT)
496
nfct_set_attr_u32(obj, ATTR_SNAT_IPV4, parse.v4);
497
else if (type == CT_OPT_DST_NAT)
498
nfct_set_attr_u32(obj, ATTR_DNAT_IPV4, parse.v4);
528
static void event_sighandler(int s)
501
static void __attribute__((noreturn))
502
event_sighandler(int s)
530
504
fprintf(stdout, "Now closing conntrack event dumping...\n");
570
546
" -f, --family proto\t\tLayer 3 Protocol, eg. 'ipv6'\n"
571
547
" -t, --timeout timeout\t\tSet timeout\n"
572
548
" -u, --status status\t\tSet status, eg. ASSURED\n"
573
" -i, --id [id]\t\t\tShow or set conntrack ID\n"
577
void usage(char *prog) {
578
fprintf(stdout, "Tool to manipulate conntrack and expectations. Version %s\n", VERSION);
555
fprintf(stdout, "Command line interface for the connection "
556
"tracking system. Version %s\n", VERSION);
579
557
fprintf(stdout, "Usage: %s [commands] [options]\n", prog);
581
559
fprintf(stdout, "\n%s", usage_commands);
582
560
fprintf(stdout, "\n%s", usage_tables);
583
561
fprintf(stdout, "\n%s", usage_conntrack_parameters);
584
562
fprintf(stdout, "\n%s", usage_expectation_parameters);
585
fprintf(stdout, "\n%s", usage_parameters);
588
#define CT_COMPARISON (CT_OPT_PROTO | CT_OPT_ORIG | CT_OPT_REPL | CT_OPT_MARK)
590
static struct nfct_tuple orig, reply, mask;
591
static struct nfct_tuple exptuple;
563
fprintf(stdout, "\n%s\n", usage_parameters);
566
static unsigned int output_mask;
568
static int event_cb(enum nf_conntrack_msg_type type,
569
struct nf_conntrack *ct,
573
struct nf_conntrack *obj = data;
574
unsigned int output_type = NFCT_O_DEFAULT;
575
unsigned int output_flags = 0;
577
if (options & CT_OPT_SRC_NAT && options & CT_OPT_DST_NAT) {
578
if (!nfct_getobjopt(ct, NFCT_GOPT_IS_SNAT) &&
579
!nfct_getobjopt(ct, NFCT_GOPT_IS_DNAT))
580
return NFCT_CB_CONTINUE;
581
} else if (options & CT_OPT_SRC_NAT &&
582
!nfct_getobjopt(ct, NFCT_GOPT_IS_SNAT)) {
583
return NFCT_CB_CONTINUE;
584
} else if (options & CT_OPT_DST_NAT &&
585
!nfct_getobjopt(ct, NFCT_GOPT_IS_DNAT)) {
586
return NFCT_CB_CONTINUE;
589
if (options & CT_COMPARISON && !nfct_compare(obj, ct))
590
return NFCT_CB_CONTINUE;
592
if (output_mask & _O_XML)
593
output_type = NFCT_O_XML;
594
if (output_mask & _O_EXT)
595
output_flags = NFCT_OF_SHOW_LAYER3;
596
if (output_mask & _O_TMS) {
597
if (!(output_mask & _O_XML)) {
599
gettimeofday(&tv, NULL);
600
printf("[%-8ld.%-6ld]\t", tv.tv_sec, tv.tv_usec);
602
output_flags |= NFCT_OF_TIME;
605
nfct_snprintf(buf, 1024, ct, type, output_type, output_flags);
609
return NFCT_CB_CONTINUE;
612
static int dump_cb(enum nf_conntrack_msg_type type,
613
struct nf_conntrack *ct,
617
struct nf_conntrack *obj = data;
618
unsigned int output_type = NFCT_O_DEFAULT;
619
unsigned int output_flags = 0;
621
if (options & CT_OPT_SRC_NAT && options & CT_OPT_DST_NAT) {
622
if (!nfct_getobjopt(ct, NFCT_GOPT_IS_SNAT) &&
623
!nfct_getobjopt(ct, NFCT_GOPT_IS_DNAT))
624
return NFCT_CB_CONTINUE;
625
} else if (options & CT_OPT_SRC_NAT &&
626
!nfct_getobjopt(ct, NFCT_GOPT_IS_SNAT)) {
627
return NFCT_CB_CONTINUE;
628
} else if (options & CT_OPT_DST_NAT &&
629
!nfct_getobjopt(ct, NFCT_GOPT_IS_DNAT)) {
630
return NFCT_CB_CONTINUE;
633
if (options & CT_COMPARISON && !nfct_compare(obj, ct))
634
return NFCT_CB_CONTINUE;
636
if (output_mask & _O_XML)
637
output_type = NFCT_O_XML;
638
if (output_mask & _O_EXT)
639
output_flags = NFCT_OF_SHOW_LAYER3;
641
nfct_snprintf(buf, 1024, ct, NFCT_T_UNKNOWN, output_type, output_flags);
644
return NFCT_CB_CONTINUE;
647
static int dump_exp_cb(enum nf_conntrack_msg_type type,
648
struct nf_expect *exp,
653
nfexp_snprintf(buf, 1024, exp, NFCT_T_UNKNOWN, NFCT_O_DEFAULT, 0);
656
return NFCT_CB_CONTINUE;
592
659
static struct ctproto_handler *h;
593
static union nfct_protoinfo proto;
594
static struct nfct_nat range;
595
static struct nfct_conntrack *ct;
596
static struct nfct_expect *exp;
597
static unsigned long timeout;
598
static unsigned int status;
599
static unsigned int mark;
600
static unsigned int id = NFCT_ANY_ID;
601
static struct nfct_conntrack_compare cmp;
603
661
int main(int argc, char *argv[])
606
unsigned int command = 0, options = 0;
607
unsigned int type = 0, event_mask = 0;
608
unsigned int l3flags = 0, l4flags = 0, metaflags = 0;
664
unsigned int type = 0, event_mask = 0, l4flags = 0, status = 0;
610
666
int family = AF_UNSPEC;
611
struct nfct_conntrack_compare *pcmp;
613
while ((c = getopt_long(argc, argv,
614
"L::I::U::D::G::E::F::hVs:d:r:q:p:t:u:e:a:z[:]:{:}:m:i::f:",
615
opts, NULL)) != -1) {
667
char __obj[nfct_maxsize()];
668
char __exptuple[nfct_maxsize()];
669
char __mask[nfct_maxsize()];
670
struct nf_conntrack *obj = (struct nf_conntrack *)(void*) __obj;
671
struct nf_conntrack *exptuple = (struct nf_conntrack *)(void*) __exptuple;
672
struct nf_conntrack *mask = (struct nf_conntrack *)(void*) __mask;
673
char __exp[nfexp_maxsize()];
674
struct nf_expect *exp = (struct nf_expect *)(void*) __exp;
677
unsigned int command = 0;
679
memset(__obj, 0, sizeof(__obj));
680
memset(__exptuple, 0, sizeof(__exptuple));
681
memset(__mask, 0, sizeof(__mask));
682
memset(__exp, 0, sizeof(__exp));
688
while ((c = getopt_long(argc, argv, "L::I::U::D::G::E::F::hVs:d:r:q:"
689
"p:t:u:e:a:z[:]:{:}:m:i::f:o:n::"
691
opts, NULL)) != -1) {
618
694
type = check_type(argc, argv);
674
750
options |= CT_OPT_ORIG_SRC;
677
parse_inetaddr(optarg, &orig.src);
678
set_family(&family, orig.l3protonum);
679
if (orig.l3protonum == AF_INET)
680
l3flags |= IPV4_ORIG_SRC;
681
else if (orig.l3protonum == AF_INET6)
682
l3flags |= IPV6_ORIG_SRC;
754
l3protonum = parse_addr(optarg, &ad);
755
set_family(&family, l3protonum);
756
if (l3protonum == AF_INET) {
757
nfct_set_attr_u32(obj,
760
} else if (l3protonum == AF_INET6) {
765
nfct_set_attr_u8(obj, ATTR_ORIG_L3PROTO, l3protonum);
686
768
options |= CT_OPT_ORIG_DST;
689
parse_inetaddr(optarg, &orig.dst);
690
set_family(&family, orig.l3protonum);
691
if (orig.l3protonum == AF_INET)
692
l3flags |= IPV4_ORIG_DST;
693
else if (orig.l3protonum == AF_INET6)
694
l3flags |= IPV6_ORIG_DST;
772
l3protonum = parse_addr(optarg, &ad);
773
set_family(&family, l3protonum);
774
if (l3protonum == AF_INET) {
775
nfct_set_attr_u32(obj,
778
} else if (l3protonum == AF_INET6) {
783
nfct_set_attr_u8(obj, ATTR_ORIG_L3PROTO, l3protonum);
698
786
options |= CT_OPT_REPL_SRC;
701
parse_inetaddr(optarg, &reply.src);
702
set_family(&family, reply.l3protonum);
703
if (orig.l3protonum == AF_INET)
704
l3flags |= IPV4_REPL_SRC;
705
else if (orig.l3protonum == AF_INET6)
706
l3flags |= IPV6_REPL_SRC;
790
l3protonum = parse_addr(optarg, &ad);
791
set_family(&family, l3protonum);
792
if (l3protonum == AF_INET) {
793
nfct_set_attr_u32(obj,
796
} else if (l3protonum == AF_INET6) {
801
nfct_set_attr_u8(obj, ATTR_REPL_L3PROTO, l3protonum);
710
804
options |= CT_OPT_REPL_DST;
713
parse_inetaddr(optarg, &reply.dst);
714
set_family(&family, reply.l3protonum);
715
if (orig.l3protonum == AF_INET)
716
l3flags |= IPV4_REPL_DST;
717
else if (orig.l3protonum == AF_INET6)
718
l3flags |= IPV6_REPL_DST;
808
l3protonum = parse_addr(optarg, &ad);
809
set_family(&family, l3protonum);
810
if (l3protonum == AF_INET) {
811
nfct_set_attr_u32(obj,
814
} else if (l3protonum == AF_INET6) {
819
nfct_set_attr_u8(obj, ATTR_REPL_L3PROTO, l3protonum);
722
822
options |= CT_OPT_PROTO;
723
823
h = findproto(optarg);
725
825
exit_error(PARAMETER_PROBLEM, "proto needed\n");
726
orig.protonum = h->protonum;
727
reply.protonum = h->protonum;
728
exptuple.protonum = h->protonum;
729
mask.protonum = h->protonum;
730
opts = merge_options(opts, h->opts,
827
nfct_set_attr_u8(obj, ATTR_ORIG_L4PROTO, h->protonum);
828
nfct_set_attr_u8(obj, ATTR_REPL_L4PROTO, h->protonum);
829
nfct_set_attr_u8(exptuple,
832
nfct_set_attr_u8(mask,
835
opts = merge_options(opts, h->opts, &h->option_offset);
837
exit_error(EXIT_FAILURE, "out of memory\n");
734
840
options |= CT_OPT_TIMEOUT;
736
timeout = atol(optarg);
844
nfct_set_attr_u32(obj, ATTR_TIMEOUT, atol(optarg));
845
nfexp_set_attr_u32(exp, ATTR_EXP_TIMEOUT, atol(optarg));
754
864
options |= CT_OPT_MASK_SRC;
757
parse_inetaddr(optarg, &mask.src);
758
set_family(&family, mask.l3protonum);
868
l3protonum = parse_addr(optarg, &ad);
869
set_family(&family, l3protonum);
870
if (l3protonum == AF_INET) {
871
nfct_set_attr_u32(mask,
874
} else if (l3protonum == AF_INET6) {
879
nfct_set_attr_u8(mask, ATTR_ORIG_L3PROTO, l3protonum);
762
882
options |= CT_OPT_MASK_DST;
765
parse_inetaddr(optarg, &mask.dst);
766
set_family(&family, mask.l3protonum);
886
l3protonum = parse_addr(optarg, &ad);
887
set_family(&family, l3protonum);
888
if (l3protonum == AF_INET) {
889
nfct_set_attr_u32(mask,
892
} else if (l3protonum == AF_INET6) {
897
nfct_set_attr_u8(mask, ATTR_ORIG_L3PROTO, l3protonum);
770
900
options |= CT_OPT_EXP_SRC;
772
exptuple.l3protonum =
773
parse_inetaddr(optarg, &exptuple.src);
774
set_family(&family, exptuple.l3protonum);
904
l3protonum = parse_addr(optarg, &ad);
905
set_family(&family, l3protonum);
906
if (l3protonum == AF_INET) {
907
nfct_set_attr_u32(exptuple,
910
} else if (l3protonum == AF_INET6) {
911
nfct_set_attr(exptuple,
915
nfct_set_attr_u8(exptuple,
778
920
options |= CT_OPT_EXP_DST;
780
exptuple.l3protonum =
781
parse_inetaddr(optarg, &exptuple.dst);
782
set_family(&family, exptuple.l3protonum);
924
l3protonum = parse_addr(optarg, &ad);
925
set_family(&family, l3protonum);
926
if (l3protonum == AF_INET) {
927
nfct_set_attr_u32(exptuple,
930
} else if (l3protonum == AF_INET6) {
931
nfct_set_attr(exptuple,
935
nfct_set_attr_u8(exptuple,
786
options |= CT_OPT_NATRANGE;
787
set_family(&family, AF_INET);
788
nat_parse(optarg, 1, &range);
940
fprintf(stderr, "warning: ignoring --nat-range, "
941
"use --src-nat or --dst-nat instead.\n");
944
options |= CT_OPT_SRC_NAT;
947
set_family(&family, AF_INET);
948
nat_parse(optarg, 1, obj, CT_OPT_SRC_NAT);
951
options |= CT_OPT_DST_NAT;
954
set_family(&family, AF_INET);
955
nat_parse(optarg, 1, obj, CT_OPT_DST_NAT);
791
957
options |= CT_OPT_MARK;
793
metaflags |= NFCT_MARK;
797
options |= CT_OPT_ID;
800
else if (optind < argc && argv[optind][0] != '-'
801
&& argv[optind][0] != '!')
960
nfct_set_attr_u32(obj, ATTR_MARK, atol(optarg));
963
options |= CT_OPT_SECMARK;
966
nfct_set_attr_u32(obj, ATTR_SECMARK, atol(optarg));
970
"warning: ignoring --id. deprecated option.\n");
809
973
options |= CT_OPT_FAMILY;
810
974
if (strncmp(optarg, "ipv4", strlen("ipv4")) == 0)
894
1039
cth = nfct_open(EXPECT, 0);
896
1041
exit_error(OTHER_PROBLEM, "Can't open handler");
897
if (options & CT_OPT_ID)
898
nfct_register_callback(cth,
899
nfct_default_expect_display_id,
902
nfct_register_callback(cth,
903
nfct_default_expect_display,
905
res = nfct_dump_expect_list(cth, family);
1043
nfexp_callback_register(cth, NFCT_T_ALL, dump_exp_cb, NULL);
1044
res = nfexp_query(cth, NFCT_Q_DUMP, &family);
906
1045
nfct_close(cth);
910
if ((options & CT_OPT_ORIG)
911
&& !(options & CT_OPT_REPL)) {
912
reply.l3protonum = orig.l3protonum;
913
memcpy(&reply.src, &orig.dst, sizeof(reply.src));
914
memcpy(&reply.dst, &orig.src, sizeof(reply.dst));
915
} else if (!(options & CT_OPT_ORIG)
916
&& (options & CT_OPT_REPL)) {
917
orig.l3protonum = reply.l3protonum;
918
memcpy(&orig.src, &reply.dst, sizeof(orig.src));
919
memcpy(&orig.dst, &reply.src, sizeof(orig.dst));
921
if (options & CT_OPT_NATRANGE)
922
ct = nfct_conntrack_alloc(&orig, &reply, timeout,
923
&proto, status, mark, id,
926
ct = nfct_conntrack_alloc(&orig, &reply, timeout,
927
&proto, status, mark, id,
930
exit_error(OTHER_PROBLEM, "Not Enough memory");
1049
if ((options & CT_OPT_ORIG) && !(options & CT_OPT_REPL))
1050
nfct_setobjopt(obj, NFCT_SOPT_SETUP_REPLY);
1051
else if (!(options & CT_OPT_ORIG) && (options & CT_OPT_REPL))
1052
nfct_setobjopt(obj, NFCT_SOPT_SETUP_ORIGINAL);
932
1054
cth = nfct_open(CONNTRACK, 0);
934
nfct_conntrack_free(ct);
935
1056
exit_error(OTHER_PROBLEM, "Can't open handler");
937
res = nfct_create_conntrack(cth, ct);
1058
res = nfct_query(cth, NFCT_Q_CREATE, obj);
938
1059
nfct_close(cth);
939
nfct_conntrack_free(ct);
942
1062
case EXP_CREATE:
943
if (options & CT_OPT_ORIG)
944
exp = nfct_expect_alloc(&orig, &exptuple,
946
else if (options & CT_OPT_REPL)
947
exp = nfct_expect_alloc(&reply, &exptuple,
950
exit_error(OTHER_PROBLEM, "Not enough memory");
1063
nfexp_set_attr(exp, ATTR_EXP_MASTER, obj);
1064
nfexp_set_attr(exp, ATTR_EXP_EXPECTED, exptuple);
1065
nfexp_set_attr(exp, ATTR_EXP_MASK, mask);
952
1067
cth = nfct_open(EXPECT, 0);
954
nfct_expect_free(exp);
955
1069
exit_error(OTHER_PROBLEM, "Can't open handler");
957
res = nfct_create_expectation(cth, exp);
958
nfct_expect_free(exp);
1071
res = nfexp_query(cth, NFCT_Q_CREATE, exp);
959
1072
nfct_close(cth);
963
if ((options & CT_OPT_ORIG)
964
&& !(options & CT_OPT_REPL)) {
965
reply.l3protonum = orig.l3protonum;
966
memcpy(&reply.src, &orig.dst, sizeof(reply.src));
967
memcpy(&reply.dst, &orig.src, sizeof(reply.dst));
968
} else if (!(options & CT_OPT_ORIG)
969
&& (options & CT_OPT_REPL)) {
970
orig.l3protonum = reply.l3protonum;
971
memcpy(&orig.src, &reply.dst, sizeof(orig.src));
972
memcpy(&orig.dst, &reply.src, sizeof(orig.dst));
974
ct = nfct_conntrack_alloc(&orig, &reply, timeout,
975
&proto, status, mark, id,
978
exit_error(OTHER_PROBLEM, "Not enough memory");
1076
if ((options & CT_OPT_ORIG) && !(options & CT_OPT_REPL))
1077
nfct_setobjopt(obj, NFCT_SOPT_SETUP_REPLY);
1078
else if (!(options & CT_OPT_ORIG) && (options & CT_OPT_REPL))
1079
nfct_setobjopt(obj, NFCT_SOPT_SETUP_ORIGINAL);
980
1081
cth = nfct_open(CONNTRACK, 0);
982
nfct_conntrack_free(ct);
983
1083
exit_error(OTHER_PROBLEM, "Can't open handler");
985
res = nfct_update_conntrack(cth, ct);
986
nfct_conntrack_free(ct);
1085
res = nfct_query(cth, NFCT_Q_UPDATE, obj);
987
1086
nfct_close(cth);