8
#include <linux/netfilter/nf_conntrack_common.h>
9
#include <linux/netfilter/xt_CT.h>
11
static void ct_help(void)
14
"CT target options:\n"
15
" --notrack Don't track connection\n"
16
" --helper name Use conntrack helper 'name' for connection\n"
17
" --ctevents event[,event...] Generate specified conntrack events for connection\n"
18
" --expevents event[,event...] Generate specified expectation events for connection\n"
19
" --zone ID Assign/Lookup connection in zone ID\n"
26
CT_OPT_CTEVENTS = 0x4,
27
CT_OPT_EXPEVENTS = 0x8,
31
static const struct option ct_opts[] = {
32
{.name = "notrack", .has_arg = false, .val = CT_OPT_NOTRACK},
33
{.name = "helper", .has_arg = true, .val = CT_OPT_HELPER},
34
{.name = "ctevents", .has_arg = true, .val = CT_OPT_CTEVENTS},
35
{.name = "expevents", .has_arg = true, .val = CT_OPT_EXPEVENTS},
36
{.name = "zone", .has_arg = true, .val = CT_OPT_ZONE},
45
static const struct event_tbl ct_event_tbl[] = {
47
{ "related", IPCT_RELATED },
48
{ "destroy", IPCT_DESTROY },
49
{ "reply", IPCT_REPLY },
50
{ "assured", IPCT_ASSURED },
51
{ "protoinfo", IPCT_PROTOINFO },
52
{ "helper", IPCT_HELPER },
53
{ "mark", IPCT_MARK },
54
{ "natseqinfo", IPCT_NATSEQADJ },
55
{ "secmark", IPCT_SECMARK },
58
static const struct event_tbl exp_event_tbl[] = {
62
static uint32_t ct_parse_events(const struct event_tbl *tbl, unsigned int size,
65
char str[strlen(events) + 1], *e = str, *t;
66
unsigned int mask = 0, i;
69
while ((t = strsep(&e, ","))) {
70
for (i = 0; i < size; i++) {
71
if (strcmp(t, tbl[i].name))
73
mask |= 1 << tbl[i].event;
78
xtables_error(PARAMETER_PROBLEM, "Unknown event type \"%s\"", t);
84
static void ct_print_events(const char *pfx, const struct event_tbl *tbl,
85
unsigned int size, uint32_t mask)
91
for (i = 0; i < size; i++) {
92
if (mask & (1 << tbl[i].event)) {
93
printf("%s%s", sep, tbl[i].name);
100
static int ct_parse(int c, char **argv, int invert, unsigned int *flags,
101
const void *entry, struct xt_entry_target **target)
103
struct xt_ct_target_info *info = (struct xt_ct_target_info *)(*target)->data;
108
xtables_param_act(XTF_ONLY_ONCE, "CT", "--notrack", *flags & CT_OPT_NOTRACK);
109
info->flags |= XT_CT_NOTRACK;
112
xtables_param_act(XTF_ONLY_ONCE, "CT", "--helper", *flags & CT_OPT_HELPER);
113
strncpy(info->helper, optarg, sizeof(info->helper));
114
info->helper[sizeof(info->helper) - 1] = '\0';
116
case CT_OPT_CTEVENTS:
117
xtables_param_act(XTF_ONLY_ONCE, "CT", "--ctevents", *flags & CT_OPT_CTEVENTS);
118
info->ct_events = ct_parse_events(ct_event_tbl, ARRAY_SIZE(ct_event_tbl), optarg);
120
case CT_OPT_EXPEVENTS:
121
xtables_param_act(XTF_ONLY_ONCE, "CT", "--expevents", *flags & CT_OPT_EXPEVENTS);
122
info->exp_events = ct_parse_events(exp_event_tbl, ARRAY_SIZE(exp_event_tbl), optarg);
125
xtables_param_act(XTF_ONLY_ONCE, "CT", "--zone", *flags & CT_OPT_ZONE);
126
if (!xtables_strtoui(optarg, NULL, &zone, 0, UINT16_MAX))
127
xtables_error(PARAMETER_PROBLEM, "Bad zone value \"%s\"", optarg);
138
static void ct_print(const void *ip, const struct xt_entry_target *target, int numeric)
140
const struct xt_ct_target_info *info =
141
(const struct xt_ct_target_info *)target->data;
144
if (info->flags & XT_CT_NOTRACK)
147
printf("helper %s ", info->helper);
149
ct_print_events("ctevents", ct_event_tbl,
150
ARRAY_SIZE(ct_event_tbl), info->ct_events);
151
if (info->exp_events)
152
ct_print_events("expevents", exp_event_tbl,
153
ARRAY_SIZE(exp_event_tbl), info->exp_events);
155
printf("zone %u ", info->zone);
158
static void ct_save(const void *ip, const struct xt_entry_target *target)
160
const struct xt_ct_target_info *info =
161
(const struct xt_ct_target_info *)target->data;
163
if (info->flags & XT_CT_NOTRACK)
164
printf("--notrack ");
166
printf("--helper %s ", info->helper);
168
ct_print_events("--ctevents", ct_event_tbl,
169
ARRAY_SIZE(ct_event_tbl), info->ct_events);
170
if (info->exp_events)
171
ct_print_events("--expevents", exp_event_tbl,
172
ARRAY_SIZE(exp_event_tbl), info->exp_events);
174
printf("--zone %u ", info->zone);
177
static struct xtables_target ct_target = {
178
.family = NFPROTO_UNSPEC,
180
.version = XTABLES_VERSION,
181
.size = XT_ALIGN(sizeof(struct xt_ct_target_info)),
182
.userspacesize = offsetof(struct xt_ct_target_info, ct),
187
.extra_opts = ct_opts,
192
xtables_register_target(&ct_target);