libxt_CT.c revision e8f32983048d6aa4a908b6a92da55fa71c859623
19fdbaa71452edaac9d5906716c15937f670341faPatrick McHardy#include <stdio.h>
29fdbaa71452edaac9d5906716c15937f670341faPatrick McHardy#include <string.h>
39fdbaa71452edaac9d5906716c15937f670341faPatrick McHardy#include <xtables.h>
49fdbaa71452edaac9d5906716c15937f670341faPatrick McHardy#include <linux/netfilter/nf_conntrack_common.h>
59fdbaa71452edaac9d5906716c15937f670341faPatrick McHardy#include <linux/netfilter/xt_CT.h>
69fdbaa71452edaac9d5906716c15937f670341faPatrick McHardy
79fdbaa71452edaac9d5906716c15937f670341faPatrick McHardystatic void ct_help(void)
89fdbaa71452edaac9d5906716c15937f670341faPatrick McHardy{
99fdbaa71452edaac9d5906716c15937f670341faPatrick McHardy	printf(
109fdbaa71452edaac9d5906716c15937f670341faPatrick McHardy"CT target options:\n"
119fdbaa71452edaac9d5906716c15937f670341faPatrick McHardy" --notrack			Don't track connection\n"
129fdbaa71452edaac9d5906716c15937f670341faPatrick McHardy" --helper name			Use conntrack helper 'name' for connection\n"
1389b6c32f88be47e83c3f6e7f8fee812088cb8c22Jan Engelhardt" --ctevents event[,event...]	Generate specified conntrack events for connection\n"
149fdbaa71452edaac9d5906716c15937f670341faPatrick McHardy" --expevents event[,event...]	Generate specified expectation events for connection\n"
159fdbaa71452edaac9d5906716c15937f670341faPatrick McHardy" --zone ID			Assign/Lookup connection in zone ID\n"
169fdbaa71452edaac9d5906716c15937f670341faPatrick McHardy	);
179fdbaa71452edaac9d5906716c15937f670341faPatrick McHardy}
189fdbaa71452edaac9d5906716c15937f670341faPatrick McHardy
19e8f32983048d6aa4a908b6a92da55fa71c859623Pablo Neira Ayusostatic void ct_help_v1(void)
20e8f32983048d6aa4a908b6a92da55fa71c859623Pablo Neira Ayuso{
21e8f32983048d6aa4a908b6a92da55fa71c859623Pablo Neira Ayuso	printf(
22e8f32983048d6aa4a908b6a92da55fa71c859623Pablo Neira Ayuso"CT target options:\n"
23e8f32983048d6aa4a908b6a92da55fa71c859623Pablo Neira Ayuso" --notrack			Don't track connection\n"
24e8f32983048d6aa4a908b6a92da55fa71c859623Pablo Neira Ayuso" --helper name			Use conntrack helper 'name' for connection\n"
25e8f32983048d6aa4a908b6a92da55fa71c859623Pablo Neira Ayuso" --timeout name 		Use timeout policy 'name' for connection\n"
26e8f32983048d6aa4a908b6a92da55fa71c859623Pablo Neira Ayuso" --ctevents event[,event...]	Generate specified conntrack events for connection\n"
27e8f32983048d6aa4a908b6a92da55fa71c859623Pablo Neira Ayuso" --expevents event[,event...]	Generate specified expectation events for connection\n"
28e8f32983048d6aa4a908b6a92da55fa71c859623Pablo Neira Ayuso" --zone ID			Assign/Lookup connection in zone ID\n"
29e8f32983048d6aa4a908b6a92da55fa71c859623Pablo Neira Ayuso	);
30e8f32983048d6aa4a908b6a92da55fa71c859623Pablo Neira Ayuso}
31e8f32983048d6aa4a908b6a92da55fa71c859623Pablo Neira Ayuso
32a05562e1e2fb2e18f34d29ec57c4217a3014d1f2Jan Engelhardtenum {
33a05562e1e2fb2e18f34d29ec57c4217a3014d1f2Jan Engelhardt	O_NOTRACK = 0,
34a05562e1e2fb2e18f34d29ec57c4217a3014d1f2Jan Engelhardt	O_HELPER,
35e8f32983048d6aa4a908b6a92da55fa71c859623Pablo Neira Ayuso	O_TIMEOUT,
36a05562e1e2fb2e18f34d29ec57c4217a3014d1f2Jan Engelhardt	O_CTEVENTS,
37a05562e1e2fb2e18f34d29ec57c4217a3014d1f2Jan Engelhardt	O_EXPEVENTS,
38a05562e1e2fb2e18f34d29ec57c4217a3014d1f2Jan Engelhardt	O_ZONE,
399fdbaa71452edaac9d5906716c15937f670341faPatrick McHardy};
409fdbaa71452edaac9d5906716c15937f670341faPatrick McHardy
41a05562e1e2fb2e18f34d29ec57c4217a3014d1f2Jan Engelhardt#define s struct xt_ct_target_info
42a05562e1e2fb2e18f34d29ec57c4217a3014d1f2Jan Engelhardtstatic const struct xt_option_entry ct_opts[] = {
43a05562e1e2fb2e18f34d29ec57c4217a3014d1f2Jan Engelhardt	{.name = "notrack", .id = O_NOTRACK, .type = XTTYPE_NONE},
44a05562e1e2fb2e18f34d29ec57c4217a3014d1f2Jan Engelhardt	{.name = "helper", .id = O_HELPER, .type = XTTYPE_STRING,
45a05562e1e2fb2e18f34d29ec57c4217a3014d1f2Jan Engelhardt	 .flags = XTOPT_PUT, XTOPT_POINTER(s, helper)},
46a05562e1e2fb2e18f34d29ec57c4217a3014d1f2Jan Engelhardt	{.name = "ctevents", .id = O_CTEVENTS, .type = XTTYPE_STRING},
47a05562e1e2fb2e18f34d29ec57c4217a3014d1f2Jan Engelhardt	{.name = "expevents", .id = O_EXPEVENTS, .type = XTTYPE_STRING},
48a05562e1e2fb2e18f34d29ec57c4217a3014d1f2Jan Engelhardt	{.name = "zone", .id = O_ZONE, .type = XTTYPE_UINT16,
49a05562e1e2fb2e18f34d29ec57c4217a3014d1f2Jan Engelhardt	 .flags = XTOPT_PUT, XTOPT_POINTER(s, zone)},
50a05562e1e2fb2e18f34d29ec57c4217a3014d1f2Jan Engelhardt	XTOPT_TABLEEND,
519fdbaa71452edaac9d5906716c15937f670341faPatrick McHardy};
52a05562e1e2fb2e18f34d29ec57c4217a3014d1f2Jan Engelhardt#undef s
539fdbaa71452edaac9d5906716c15937f670341faPatrick McHardy
54e8f32983048d6aa4a908b6a92da55fa71c859623Pablo Neira Ayuso#define s struct xt_ct_target_info_v1
55e8f32983048d6aa4a908b6a92da55fa71c859623Pablo Neira Ayusostatic const struct xt_option_entry ct_opts_v1[] = {
56e8f32983048d6aa4a908b6a92da55fa71c859623Pablo Neira Ayuso	{.name = "notrack", .id = O_NOTRACK, .type = XTTYPE_NONE},
57e8f32983048d6aa4a908b6a92da55fa71c859623Pablo Neira Ayuso	{.name = "helper", .id = O_HELPER, .type = XTTYPE_STRING,
58e8f32983048d6aa4a908b6a92da55fa71c859623Pablo Neira Ayuso	 .flags = XTOPT_PUT, XTOPT_POINTER(s, helper)},
59e8f32983048d6aa4a908b6a92da55fa71c859623Pablo Neira Ayuso	{.name = "timeout", .id = O_TIMEOUT, .type = XTTYPE_STRING,
60e8f32983048d6aa4a908b6a92da55fa71c859623Pablo Neira Ayuso	 .flags = XTOPT_PUT, XTOPT_POINTER(s, timeout)},
61e8f32983048d6aa4a908b6a92da55fa71c859623Pablo Neira Ayuso	{.name = "ctevents", .id = O_CTEVENTS, .type = XTTYPE_STRING},
62e8f32983048d6aa4a908b6a92da55fa71c859623Pablo Neira Ayuso	{.name = "expevents", .id = O_EXPEVENTS, .type = XTTYPE_STRING},
63e8f32983048d6aa4a908b6a92da55fa71c859623Pablo Neira Ayuso	{.name = "zone", .id = O_ZONE, .type = XTTYPE_UINT16,
64e8f32983048d6aa4a908b6a92da55fa71c859623Pablo Neira Ayuso	 .flags = XTOPT_PUT, XTOPT_POINTER(s, zone)},
65e8f32983048d6aa4a908b6a92da55fa71c859623Pablo Neira Ayuso	XTOPT_TABLEEND,
66e8f32983048d6aa4a908b6a92da55fa71c859623Pablo Neira Ayuso};
67e8f32983048d6aa4a908b6a92da55fa71c859623Pablo Neira Ayuso#undef s
68e8f32983048d6aa4a908b6a92da55fa71c859623Pablo Neira Ayuso
699fdbaa71452edaac9d5906716c15937f670341faPatrick McHardystruct event_tbl {
709fdbaa71452edaac9d5906716c15937f670341faPatrick McHardy	const char	*name;
719fdbaa71452edaac9d5906716c15937f670341faPatrick McHardy	unsigned int	event;
729fdbaa71452edaac9d5906716c15937f670341faPatrick McHardy};
739fdbaa71452edaac9d5906716c15937f670341faPatrick McHardy
749fdbaa71452edaac9d5906716c15937f670341faPatrick McHardystatic const struct event_tbl ct_event_tbl[] = {
759fdbaa71452edaac9d5906716c15937f670341faPatrick McHardy	{ "new",		IPCT_NEW },
769fdbaa71452edaac9d5906716c15937f670341faPatrick McHardy	{ "related",		IPCT_RELATED },
779fdbaa71452edaac9d5906716c15937f670341faPatrick McHardy	{ "destroy",		IPCT_DESTROY },
789fdbaa71452edaac9d5906716c15937f670341faPatrick McHardy	{ "reply",		IPCT_REPLY },
799fdbaa71452edaac9d5906716c15937f670341faPatrick McHardy	{ "assured",		IPCT_ASSURED },
809fdbaa71452edaac9d5906716c15937f670341faPatrick McHardy	{ "protoinfo",		IPCT_PROTOINFO },
819fdbaa71452edaac9d5906716c15937f670341faPatrick McHardy	{ "helper",		IPCT_HELPER },
829fdbaa71452edaac9d5906716c15937f670341faPatrick McHardy	{ "mark",		IPCT_MARK },
839fdbaa71452edaac9d5906716c15937f670341faPatrick McHardy	{ "natseqinfo",		IPCT_NATSEQADJ },
849fdbaa71452edaac9d5906716c15937f670341faPatrick McHardy	{ "secmark",		IPCT_SECMARK },
859fdbaa71452edaac9d5906716c15937f670341faPatrick McHardy};
869fdbaa71452edaac9d5906716c15937f670341faPatrick McHardy
879fdbaa71452edaac9d5906716c15937f670341faPatrick McHardystatic const struct event_tbl exp_event_tbl[] = {
889fdbaa71452edaac9d5906716c15937f670341faPatrick McHardy	{ "new",		IPEXP_NEW },
899fdbaa71452edaac9d5906716c15937f670341faPatrick McHardy};
909fdbaa71452edaac9d5906716c15937f670341faPatrick McHardy
919fdbaa71452edaac9d5906716c15937f670341faPatrick McHardystatic uint32_t ct_parse_events(const struct event_tbl *tbl, unsigned int size,
929fdbaa71452edaac9d5906716c15937f670341faPatrick McHardy				const char *events)
939fdbaa71452edaac9d5906716c15937f670341faPatrick McHardy{
949fdbaa71452edaac9d5906716c15937f670341faPatrick McHardy	char str[strlen(events) + 1], *e = str, *t;
959fdbaa71452edaac9d5906716c15937f670341faPatrick McHardy	unsigned int mask = 0, i;
969fdbaa71452edaac9d5906716c15937f670341faPatrick McHardy
979fdbaa71452edaac9d5906716c15937f670341faPatrick McHardy	strcpy(str, events);
989fdbaa71452edaac9d5906716c15937f670341faPatrick McHardy	while ((t = strsep(&e, ","))) {
999fdbaa71452edaac9d5906716c15937f670341faPatrick McHardy		for (i = 0; i < size; i++) {
100bed2ba957d545b50c3eae6fb28fc0decadbc0dcbPablo Neira Ayuso			if (strcmp(t, tbl[i].name))
1019fdbaa71452edaac9d5906716c15937f670341faPatrick McHardy				continue;
102bed2ba957d545b50c3eae6fb28fc0decadbc0dcbPablo Neira Ayuso			mask |= 1 << tbl[i].event;
1039fdbaa71452edaac9d5906716c15937f670341faPatrick McHardy			break;
1049fdbaa71452edaac9d5906716c15937f670341faPatrick McHardy		}
1059fdbaa71452edaac9d5906716c15937f670341faPatrick McHardy
1069fdbaa71452edaac9d5906716c15937f670341faPatrick McHardy		if (i == size)
1079fdbaa71452edaac9d5906716c15937f670341faPatrick McHardy			xtables_error(PARAMETER_PROBLEM, "Unknown event type \"%s\"", t);
1089fdbaa71452edaac9d5906716c15937f670341faPatrick McHardy	}
1099fdbaa71452edaac9d5906716c15937f670341faPatrick McHardy
1109fdbaa71452edaac9d5906716c15937f670341faPatrick McHardy	return mask;
1119fdbaa71452edaac9d5906716c15937f670341faPatrick McHardy}
1129fdbaa71452edaac9d5906716c15937f670341faPatrick McHardy
1139fdbaa71452edaac9d5906716c15937f670341faPatrick McHardystatic void ct_print_events(const char *pfx, const struct event_tbl *tbl,
1149fdbaa71452edaac9d5906716c15937f670341faPatrick McHardy			    unsigned int size, uint32_t mask)
1159fdbaa71452edaac9d5906716c15937f670341faPatrick McHardy{
1169fdbaa71452edaac9d5906716c15937f670341faPatrick McHardy	const char *sep = "";
1179fdbaa71452edaac9d5906716c15937f670341faPatrick McHardy	unsigned int i;
1189fdbaa71452edaac9d5906716c15937f670341faPatrick McHardy
11973866357e4a7a0fdc1b293bf8863fee2bd56da9eJan Engelhardt	printf(" %s ", pfx);
1209fdbaa71452edaac9d5906716c15937f670341faPatrick McHardy	for (i = 0; i < size; i++) {
1219fdbaa71452edaac9d5906716c15937f670341faPatrick McHardy		if (mask & (1 << tbl[i].event)) {
1229fdbaa71452edaac9d5906716c15937f670341faPatrick McHardy			printf("%s%s", sep, tbl[i].name);
1239fdbaa71452edaac9d5906716c15937f670341faPatrick McHardy			sep = ",";
1249fdbaa71452edaac9d5906716c15937f670341faPatrick McHardy		}
1259fdbaa71452edaac9d5906716c15937f670341faPatrick McHardy	}
1269fdbaa71452edaac9d5906716c15937f670341faPatrick McHardy}
1279fdbaa71452edaac9d5906716c15937f670341faPatrick McHardy
128a05562e1e2fb2e18f34d29ec57c4217a3014d1f2Jan Engelhardtstatic void ct_parse(struct xt_option_call *cb)
1299fdbaa71452edaac9d5906716c15937f670341faPatrick McHardy{
130a05562e1e2fb2e18f34d29ec57c4217a3014d1f2Jan Engelhardt	struct xt_ct_target_info *info = cb->data;
1319fdbaa71452edaac9d5906716c15937f670341faPatrick McHardy
132a05562e1e2fb2e18f34d29ec57c4217a3014d1f2Jan Engelhardt	xtables_option_parse(cb);
133a05562e1e2fb2e18f34d29ec57c4217a3014d1f2Jan Engelhardt	switch (cb->entry->id) {
134a05562e1e2fb2e18f34d29ec57c4217a3014d1f2Jan Engelhardt	case O_NOTRACK:
1359fdbaa71452edaac9d5906716c15937f670341faPatrick McHardy		info->flags |= XT_CT_NOTRACK;
1369fdbaa71452edaac9d5906716c15937f670341faPatrick McHardy		break;
137a05562e1e2fb2e18f34d29ec57c4217a3014d1f2Jan Engelhardt	case O_CTEVENTS:
138a05562e1e2fb2e18f34d29ec57c4217a3014d1f2Jan Engelhardt		info->ct_events = ct_parse_events(ct_event_tbl, ARRAY_SIZE(ct_event_tbl), cb->arg);
1399fdbaa71452edaac9d5906716c15937f670341faPatrick McHardy		break;
140a05562e1e2fb2e18f34d29ec57c4217a3014d1f2Jan Engelhardt	case O_EXPEVENTS:
141a05562e1e2fb2e18f34d29ec57c4217a3014d1f2Jan Engelhardt		info->exp_events = ct_parse_events(exp_event_tbl, ARRAY_SIZE(exp_event_tbl), cb->arg);
1429fdbaa71452edaac9d5906716c15937f670341faPatrick McHardy		break;
1439fdbaa71452edaac9d5906716c15937f670341faPatrick McHardy	}
1449fdbaa71452edaac9d5906716c15937f670341faPatrick McHardy}
1459fdbaa71452edaac9d5906716c15937f670341faPatrick McHardy
146e8f32983048d6aa4a908b6a92da55fa71c859623Pablo Neira Ayusostatic void ct_parse_v1(struct xt_option_call *cb)
147e8f32983048d6aa4a908b6a92da55fa71c859623Pablo Neira Ayuso{
148e8f32983048d6aa4a908b6a92da55fa71c859623Pablo Neira Ayuso	struct xt_ct_target_info_v1 *info = cb->data;
149e8f32983048d6aa4a908b6a92da55fa71c859623Pablo Neira Ayuso
150e8f32983048d6aa4a908b6a92da55fa71c859623Pablo Neira Ayuso	xtables_option_parse(cb);
151e8f32983048d6aa4a908b6a92da55fa71c859623Pablo Neira Ayuso	switch (cb->entry->id) {
152e8f32983048d6aa4a908b6a92da55fa71c859623Pablo Neira Ayuso	case O_NOTRACK:
153e8f32983048d6aa4a908b6a92da55fa71c859623Pablo Neira Ayuso		info->flags |= XT_CT_NOTRACK;
154e8f32983048d6aa4a908b6a92da55fa71c859623Pablo Neira Ayuso		break;
155e8f32983048d6aa4a908b6a92da55fa71c859623Pablo Neira Ayuso	case O_CTEVENTS:
156e8f32983048d6aa4a908b6a92da55fa71c859623Pablo Neira Ayuso		info->ct_events = ct_parse_events(ct_event_tbl,
157e8f32983048d6aa4a908b6a92da55fa71c859623Pablo Neira Ayuso						  ARRAY_SIZE(ct_event_tbl),
158e8f32983048d6aa4a908b6a92da55fa71c859623Pablo Neira Ayuso						  cb->arg);
159e8f32983048d6aa4a908b6a92da55fa71c859623Pablo Neira Ayuso		break;
160e8f32983048d6aa4a908b6a92da55fa71c859623Pablo Neira Ayuso	case O_EXPEVENTS:
161e8f32983048d6aa4a908b6a92da55fa71c859623Pablo Neira Ayuso		info->exp_events = ct_parse_events(exp_event_tbl,
162e8f32983048d6aa4a908b6a92da55fa71c859623Pablo Neira Ayuso						   ARRAY_SIZE(exp_event_tbl),
163e8f32983048d6aa4a908b6a92da55fa71c859623Pablo Neira Ayuso						   cb->arg);
164e8f32983048d6aa4a908b6a92da55fa71c859623Pablo Neira Ayuso		break;
165e8f32983048d6aa4a908b6a92da55fa71c859623Pablo Neira Ayuso	}
166e8f32983048d6aa4a908b6a92da55fa71c859623Pablo Neira Ayuso}
167e8f32983048d6aa4a908b6a92da55fa71c859623Pablo Neira Ayuso
1689fdbaa71452edaac9d5906716c15937f670341faPatrick McHardystatic void ct_print(const void *ip, const struct xt_entry_target *target, int numeric)
1699fdbaa71452edaac9d5906716c15937f670341faPatrick McHardy{
1709fdbaa71452edaac9d5906716c15937f670341faPatrick McHardy	const struct xt_ct_target_info *info =
1719fdbaa71452edaac9d5906716c15937f670341faPatrick McHardy		(const struct xt_ct_target_info *)target->data;
1729fdbaa71452edaac9d5906716c15937f670341faPatrick McHardy
17373866357e4a7a0fdc1b293bf8863fee2bd56da9eJan Engelhardt	printf(" CT");
1749fdbaa71452edaac9d5906716c15937f670341faPatrick McHardy	if (info->flags & XT_CT_NOTRACK)
17573866357e4a7a0fdc1b293bf8863fee2bd56da9eJan Engelhardt		printf(" notrack");
1769fdbaa71452edaac9d5906716c15937f670341faPatrick McHardy	if (info->helper[0])
17773866357e4a7a0fdc1b293bf8863fee2bd56da9eJan Engelhardt		printf(" helper %s", info->helper);
1789fdbaa71452edaac9d5906716c15937f670341faPatrick McHardy	if (info->ct_events)
1799fdbaa71452edaac9d5906716c15937f670341faPatrick McHardy		ct_print_events("ctevents", ct_event_tbl,
1809fdbaa71452edaac9d5906716c15937f670341faPatrick McHardy				ARRAY_SIZE(ct_event_tbl), info->ct_events);
1819fdbaa71452edaac9d5906716c15937f670341faPatrick McHardy	if (info->exp_events)
1829fdbaa71452edaac9d5906716c15937f670341faPatrick McHardy		ct_print_events("expevents", exp_event_tbl,
1839fdbaa71452edaac9d5906716c15937f670341faPatrick McHardy				ARRAY_SIZE(exp_event_tbl), info->exp_events);
1849f27e6b6f8638bde93e9901e999287ad5118f17cPatrick McHardy	if (info->zone)
1859f27e6b6f8638bde93e9901e999287ad5118f17cPatrick McHardy		printf("zone %u ", info->zone);
1869fdbaa71452edaac9d5906716c15937f670341faPatrick McHardy}
1879fdbaa71452edaac9d5906716c15937f670341faPatrick McHardy
188e8f32983048d6aa4a908b6a92da55fa71c859623Pablo Neira Ayusostatic void
189e8f32983048d6aa4a908b6a92da55fa71c859623Pablo Neira Ayusoct_print_v1(const void *ip, const struct xt_entry_target *target, int numeric)
190e8f32983048d6aa4a908b6a92da55fa71c859623Pablo Neira Ayuso{
191e8f32983048d6aa4a908b6a92da55fa71c859623Pablo Neira Ayuso	const struct xt_ct_target_info_v1 *info =
192e8f32983048d6aa4a908b6a92da55fa71c859623Pablo Neira Ayuso		(const struct xt_ct_target_info_v1 *)target->data;
193e8f32983048d6aa4a908b6a92da55fa71c859623Pablo Neira Ayuso
194e8f32983048d6aa4a908b6a92da55fa71c859623Pablo Neira Ayuso	printf(" CT");
195e8f32983048d6aa4a908b6a92da55fa71c859623Pablo Neira Ayuso	if (info->flags & XT_CT_NOTRACK)
196e8f32983048d6aa4a908b6a92da55fa71c859623Pablo Neira Ayuso		printf(" notrack");
197e8f32983048d6aa4a908b6a92da55fa71c859623Pablo Neira Ayuso	if (info->helper[0])
198e8f32983048d6aa4a908b6a92da55fa71c859623Pablo Neira Ayuso		printf(" helper %s", info->helper);
199e8f32983048d6aa4a908b6a92da55fa71c859623Pablo Neira Ayuso	if (info->timeout[0])
200e8f32983048d6aa4a908b6a92da55fa71c859623Pablo Neira Ayuso		printf(" timeout %s", info->timeout);
201e8f32983048d6aa4a908b6a92da55fa71c859623Pablo Neira Ayuso	if (info->ct_events)
202e8f32983048d6aa4a908b6a92da55fa71c859623Pablo Neira Ayuso		ct_print_events("ctevents", ct_event_tbl,
203e8f32983048d6aa4a908b6a92da55fa71c859623Pablo Neira Ayuso				ARRAY_SIZE(ct_event_tbl), info->ct_events);
204e8f32983048d6aa4a908b6a92da55fa71c859623Pablo Neira Ayuso	if (info->exp_events)
205e8f32983048d6aa4a908b6a92da55fa71c859623Pablo Neira Ayuso		ct_print_events("expevents", exp_event_tbl,
206e8f32983048d6aa4a908b6a92da55fa71c859623Pablo Neira Ayuso				ARRAY_SIZE(exp_event_tbl), info->exp_events);
207e8f32983048d6aa4a908b6a92da55fa71c859623Pablo Neira Ayuso	if (info->zone)
208e8f32983048d6aa4a908b6a92da55fa71c859623Pablo Neira Ayuso		printf("zone %u ", info->zone);
209e8f32983048d6aa4a908b6a92da55fa71c859623Pablo Neira Ayuso}
210e8f32983048d6aa4a908b6a92da55fa71c859623Pablo Neira Ayuso
2119fdbaa71452edaac9d5906716c15937f670341faPatrick McHardystatic void ct_save(const void *ip, const struct xt_entry_target *target)
2129fdbaa71452edaac9d5906716c15937f670341faPatrick McHardy{
2139fdbaa71452edaac9d5906716c15937f670341faPatrick McHardy	const struct xt_ct_target_info *info =
2149fdbaa71452edaac9d5906716c15937f670341faPatrick McHardy		(const struct xt_ct_target_info *)target->data;
2159fdbaa71452edaac9d5906716c15937f670341faPatrick McHardy
2169fdbaa71452edaac9d5906716c15937f670341faPatrick McHardy	if (info->flags & XT_CT_NOTRACK)
21773866357e4a7a0fdc1b293bf8863fee2bd56da9eJan Engelhardt		printf(" --notrack");
2189fdbaa71452edaac9d5906716c15937f670341faPatrick McHardy	if (info->helper[0])
21973866357e4a7a0fdc1b293bf8863fee2bd56da9eJan Engelhardt		printf(" --helper %s", info->helper);
2209fdbaa71452edaac9d5906716c15937f670341faPatrick McHardy	if (info->ct_events)
2219fdbaa71452edaac9d5906716c15937f670341faPatrick McHardy		ct_print_events("--ctevents", ct_event_tbl,
2229fdbaa71452edaac9d5906716c15937f670341faPatrick McHardy				ARRAY_SIZE(ct_event_tbl), info->ct_events);
2239fdbaa71452edaac9d5906716c15937f670341faPatrick McHardy	if (info->exp_events)
2249fdbaa71452edaac9d5906716c15937f670341faPatrick McHardy		ct_print_events("--expevents", exp_event_tbl,
2259fdbaa71452edaac9d5906716c15937f670341faPatrick McHardy				ARRAY_SIZE(exp_event_tbl), info->exp_events);
2269f27e6b6f8638bde93e9901e999287ad5118f17cPatrick McHardy	if (info->zone)
22773866357e4a7a0fdc1b293bf8863fee2bd56da9eJan Engelhardt		printf(" --zone %u", info->zone);
2289fdbaa71452edaac9d5906716c15937f670341faPatrick McHardy}
2299fdbaa71452edaac9d5906716c15937f670341faPatrick McHardy
230e8f32983048d6aa4a908b6a92da55fa71c859623Pablo Neira Ayusostatic void ct_save_v1(const void *ip, const struct xt_entry_target *target)
231e8f32983048d6aa4a908b6a92da55fa71c859623Pablo Neira Ayuso{
232e8f32983048d6aa4a908b6a92da55fa71c859623Pablo Neira Ayuso	const struct xt_ct_target_info_v1 *info =
233e8f32983048d6aa4a908b6a92da55fa71c859623Pablo Neira Ayuso		(const struct xt_ct_target_info_v1 *)target->data;
234e8f32983048d6aa4a908b6a92da55fa71c859623Pablo Neira Ayuso
235e8f32983048d6aa4a908b6a92da55fa71c859623Pablo Neira Ayuso	if (info->flags & XT_CT_NOTRACK)
236e8f32983048d6aa4a908b6a92da55fa71c859623Pablo Neira Ayuso		printf(" --notrack");
237e8f32983048d6aa4a908b6a92da55fa71c859623Pablo Neira Ayuso	if (info->helper[0])
238e8f32983048d6aa4a908b6a92da55fa71c859623Pablo Neira Ayuso		printf(" --helper %s", info->helper);
239e8f32983048d6aa4a908b6a92da55fa71c859623Pablo Neira Ayuso	if (info->timeout[0])
240e8f32983048d6aa4a908b6a92da55fa71c859623Pablo Neira Ayuso		printf(" --timeout %s", info->timeout);
241e8f32983048d6aa4a908b6a92da55fa71c859623Pablo Neira Ayuso	if (info->ct_events)
242e8f32983048d6aa4a908b6a92da55fa71c859623Pablo Neira Ayuso		ct_print_events("--ctevents", ct_event_tbl,
243e8f32983048d6aa4a908b6a92da55fa71c859623Pablo Neira Ayuso				ARRAY_SIZE(ct_event_tbl), info->ct_events);
244e8f32983048d6aa4a908b6a92da55fa71c859623Pablo Neira Ayuso	if (info->exp_events)
245e8f32983048d6aa4a908b6a92da55fa71c859623Pablo Neira Ayuso		ct_print_events("--expevents", exp_event_tbl,
246e8f32983048d6aa4a908b6a92da55fa71c859623Pablo Neira Ayuso				ARRAY_SIZE(exp_event_tbl), info->exp_events);
247e8f32983048d6aa4a908b6a92da55fa71c859623Pablo Neira Ayuso	if (info->zone)
248e8f32983048d6aa4a908b6a92da55fa71c859623Pablo Neira Ayuso		printf(" --zone %u", info->zone);
249e8f32983048d6aa4a908b6a92da55fa71c859623Pablo Neira Ayuso}
250e8f32983048d6aa4a908b6a92da55fa71c859623Pablo Neira Ayuso
251e8f32983048d6aa4a908b6a92da55fa71c859623Pablo Neira Ayusostatic struct xtables_target ct_target_reg[] = {
252e8f32983048d6aa4a908b6a92da55fa71c859623Pablo Neira Ayuso	{
253e8f32983048d6aa4a908b6a92da55fa71c859623Pablo Neira Ayuso		.family		= NFPROTO_UNSPEC,
254e8f32983048d6aa4a908b6a92da55fa71c859623Pablo Neira Ayuso		.name		= "CT",
255e8f32983048d6aa4a908b6a92da55fa71c859623Pablo Neira Ayuso		.version	= XTABLES_VERSION,
256e8f32983048d6aa4a908b6a92da55fa71c859623Pablo Neira Ayuso		.size		= XT_ALIGN(sizeof(struct xt_ct_target_info)),
257e8f32983048d6aa4a908b6a92da55fa71c859623Pablo Neira Ayuso		.userspacesize	= offsetof(struct xt_ct_target_info, ct),
258e8f32983048d6aa4a908b6a92da55fa71c859623Pablo Neira Ayuso		.help		= ct_help,
259e8f32983048d6aa4a908b6a92da55fa71c859623Pablo Neira Ayuso		.print		= ct_print,
260e8f32983048d6aa4a908b6a92da55fa71c859623Pablo Neira Ayuso		.save		= ct_save,
261e8f32983048d6aa4a908b6a92da55fa71c859623Pablo Neira Ayuso		.x6_parse	= ct_parse,
262e8f32983048d6aa4a908b6a92da55fa71c859623Pablo Neira Ayuso		.x6_options	= ct_opts,
263e8f32983048d6aa4a908b6a92da55fa71c859623Pablo Neira Ayuso	},
264e8f32983048d6aa4a908b6a92da55fa71c859623Pablo Neira Ayuso	{
265e8f32983048d6aa4a908b6a92da55fa71c859623Pablo Neira Ayuso		.family		= NFPROTO_UNSPEC,
266e8f32983048d6aa4a908b6a92da55fa71c859623Pablo Neira Ayuso		.name		= "CT",
267e8f32983048d6aa4a908b6a92da55fa71c859623Pablo Neira Ayuso		.revision	= 1,
268e8f32983048d6aa4a908b6a92da55fa71c859623Pablo Neira Ayuso		.version	= XTABLES_VERSION,
269e8f32983048d6aa4a908b6a92da55fa71c859623Pablo Neira Ayuso		.size		= XT_ALIGN(sizeof(struct xt_ct_target_info_v1)),
270e8f32983048d6aa4a908b6a92da55fa71c859623Pablo Neira Ayuso		.userspacesize	= offsetof(struct xt_ct_target_info_v1, ct),
271e8f32983048d6aa4a908b6a92da55fa71c859623Pablo Neira Ayuso		.help		= ct_help_v1,
272e8f32983048d6aa4a908b6a92da55fa71c859623Pablo Neira Ayuso		.print		= ct_print_v1,
273e8f32983048d6aa4a908b6a92da55fa71c859623Pablo Neira Ayuso		.save		= ct_save_v1,
274e8f32983048d6aa4a908b6a92da55fa71c859623Pablo Neira Ayuso		.x6_parse	= ct_parse_v1,
275e8f32983048d6aa4a908b6a92da55fa71c859623Pablo Neira Ayuso		.x6_options	= ct_opts_v1,
276e8f32983048d6aa4a908b6a92da55fa71c859623Pablo Neira Ayuso	},
2779fdbaa71452edaac9d5906716c15937f670341faPatrick McHardy};
2789fdbaa71452edaac9d5906716c15937f670341faPatrick McHardy
2799fdbaa71452edaac9d5906716c15937f670341faPatrick McHardyvoid _init(void)
2809fdbaa71452edaac9d5906716c15937f670341faPatrick McHardy{
281e8f32983048d6aa4a908b6a92da55fa71c859623Pablo Neira Ayuso	xtables_register_targets(ct_target_reg, ARRAY_SIZE(ct_target_reg));
2829fdbaa71452edaac9d5906716c15937f670341faPatrick McHardy}
283