2 * Shared library add-on to iptables to add TCPOPTSTRIP target support.
3 * Copyright (c) 2007 Sven Schnelle <svens@bitebene.org>
4 * Copyright © CC Computer Consultants GmbH, 2007
5 * Jan Engelhardt <jengelh@computergmbh.de>
13 #include <linux/netfilter/x_tables.h>
14 #include <linux/netfilter/xt_TCPOPTSTRIP.h>
16 # define TCPOPT_MD5SIG 19
23 struct tcp_optionmap {
24 const char *name, *desc;
25 const unsigned int option;
28 static const struct option tcpoptstrip_tg_opts[] = {
29 {.name = "strip-options", .has_arg = true, .val = 's'},
33 static const struct tcp_optionmap tcp_optionmap[] = {
34 {"wscale", "Window scale", TCPOPT_WINDOW},
35 {"mss", "Maximum Segment Size", TCPOPT_MAXSEG},
36 {"sack-permitted", "SACK permitted", TCPOPT_SACK_PERMITTED},
37 {"sack", "Selective ACK", TCPOPT_SACK},
38 {"timestamp", "Timestamp", TCPOPT_TIMESTAMP},
39 {"md5", "MD5 signature", TCPOPT_MD5SIG},
43 static void tcpoptstrip_tg_help(void)
45 const struct tcp_optionmap *w;
48 "TCPOPTSTRIP target options:\n"
49 " --strip-options value strip specified TCP options denoted by value\n"
50 " (separated by comma) from TCP header\n"
51 " Instead of the numeric value, you can also use the following names:\n"
54 for (w = tcp_optionmap; w->name != NULL; ++w)
55 printf(" %-14s strip \"%s\" option\n", w->name, w->desc);
58 static void tcpoptstrip_tg_init(struct xt_entry_target *t)
60 struct xt_tcpoptstrip_target_info *info = (void *)t->data;
62 /* strictly necessary? play safe for now. */
63 memset(info->strip_bmap, 0, sizeof(info->strip_bmap));
66 static void parse_list(struct xt_tcpoptstrip_target_info *info, char *arg)
78 for (i = 0; tcp_optionmap[i].name != NULL; ++i)
79 if (strcmp(tcp_optionmap[i].name, arg) == 0) {
80 option = tcp_optionmap[i].option;
84 if (option == 0 && string_to_number(arg, 0, 255, &option) == -1)
85 exit_error(PARAMETER_PROBLEM,
86 "Bad TCP option value \"%s\"", arg);
89 exit_error(PARAMETER_PROBLEM,
90 "Option value may not be 0 or 1");
92 if (tcpoptstrip_test_bit(info->strip_bmap, option))
93 exit_error(PARAMETER_PROBLEM,
94 "Option \"%s\" already specified", arg);
96 tcpoptstrip_set_bit(info->strip_bmap, option);
103 static int tcpoptstrip_tg_parse(int c, char **argv, int invert,
104 unsigned int *flags, const void *entry,
105 struct xt_entry_target **target)
107 struct xt_tcpoptstrip_target_info *info = (void *)(*target)->data;
111 if (*flags & FLAG_STRIP)
112 exit_error(PARAMETER_PROBLEM,
113 "You can specify --strip-options only once");
114 parse_list(info, optarg);
115 *flags |= FLAG_STRIP;
122 static void tcpoptstrip_tg_check(unsigned int flags)
125 exit_error(PARAMETER_PROBLEM,
126 "TCPOPTSTRIP: --strip-options parameter required");
130 tcpoptstrip_print_list(const struct xt_tcpoptstrip_target_info *info,
137 for (i = 0; i < 256; ++i) {
138 if (!tcpoptstrip_test_bit(info->strip_bmap, i))
146 for (j = 0; tcp_optionmap[j].name != NULL; ++j)
147 if (tcp_optionmap[j].option == i)
148 name = tcp_optionmap[j].name;
158 tcpoptstrip_tg_print(const void *ip, const struct xt_entry_target *target,
161 const struct xt_tcpoptstrip_target_info *info =
162 (const void *)target->data;
164 printf("TCPOPTSTRIP options ");
165 tcpoptstrip_print_list(info, numeric);
169 tcpoptstrip_tg_save(const void *ip, const struct xt_entry_target *target)
171 const struct xt_tcpoptstrip_target_info *info =
172 (const void *)target->data;
174 printf("--strip-options ");
175 tcpoptstrip_print_list(info, true);
178 static struct xtables_target tcpoptstrip_tg_reg = {
179 .version = XTABLES_VERSION,
180 .name = "TCPOPTSTRIP",
182 .size = XT_ALIGN(sizeof(struct xt_tcpoptstrip_target_info)),
183 .userspacesize = XT_ALIGN(sizeof(struct xt_tcpoptstrip_target_info)),
184 .help = tcpoptstrip_tg_help,
185 .init = tcpoptstrip_tg_init,
186 .parse = tcpoptstrip_tg_parse,
187 .final_check = tcpoptstrip_tg_check,
188 .print = tcpoptstrip_tg_print,
189 .save = tcpoptstrip_tg_save,
190 .extra_opts = tcpoptstrip_tg_opts,
193 static struct xtables_target tcpoptstrip_tg6_reg = {
194 .version = XTABLES_VERSION,
195 .name = "TCPOPTSTRIP",
197 .size = XT_ALIGN(sizeof(struct xt_tcpoptstrip_target_info)),
198 .userspacesize = XT_ALIGN(sizeof(struct xt_tcpoptstrip_target_info)),
199 .help = tcpoptstrip_tg_help,
200 .init = tcpoptstrip_tg_init,
201 .parse = tcpoptstrip_tg_parse,
202 .final_check = tcpoptstrip_tg_check,
203 .print = tcpoptstrip_tg_print,
204 .save = tcpoptstrip_tg_save,
205 .extra_opts = tcpoptstrip_tg_opts,
210 xtables_register_target(&tcpoptstrip_tg_reg);
211 xtables_register_target(&tcpoptstrip_tg6_reg);