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 <netinet/tcp.h>
14 #include <linux/netfilter/x_tables.h>
15 #include <linux/netfilter/xt_TCPOPTSTRIP.h>
17 # define TCPOPT_MD5SIG 19
24 struct tcp_optionmap
{
25 const char *name
, *desc
;
26 const unsigned int option
;
29 static const struct option tcpoptstrip_tg_opts
[] = {
30 {.name
= "strip-options", .has_arg
= true, .val
= 's'},
34 static const struct tcp_optionmap tcp_optionmap
[] = {
35 {"wscale", "Window scale", TCPOPT_WINDOW
},
36 {"mss", "Maximum Segment Size", TCPOPT_MAXSEG
},
37 {"sack-permitted", "SACK permitted", TCPOPT_SACK_PERMITTED
},
38 {"sack", "Selective ACK", TCPOPT_SACK
},
39 {"timestamp", "Timestamp", TCPOPT_TIMESTAMP
},
40 {"md5", "MD5 signature", TCPOPT_MD5SIG
},
44 static void tcpoptstrip_tg_help(void)
46 const struct tcp_optionmap
*w
;
49 "TCPOPTSTRIP target options:\n"
50 " --strip-options value strip specified TCP options denoted by value\n"
51 " (separated by comma) from TCP header\n"
52 " Instead of the numeric value, you can also use the following names:\n"
55 for (w
= tcp_optionmap
; w
->name
!= NULL
; ++w
)
56 printf(" %-14s strip \"%s\" option\n", w
->name
, w
->desc
);
59 static void tcpoptstrip_tg_init(struct xt_entry_target
*t
)
61 struct xt_tcpoptstrip_target_info
*info
= (void *)t
->data
;
63 /* strictly necessary? play safe for now. */
64 memset(info
->strip_bmap
, 0, sizeof(info
->strip_bmap
));
67 static void parse_list(struct xt_tcpoptstrip_target_info
*info
, char *arg
)
79 for (i
= 0; tcp_optionmap
[i
].name
!= NULL
; ++i
)
80 if (strcmp(tcp_optionmap
[i
].name
, arg
) == 0) {
81 option
= tcp_optionmap
[i
].option
;
86 !xtables_strtoui(arg
, NULL
, &option
, 0, UINT8_MAX
))
87 xtables_error(PARAMETER_PROBLEM
,
88 "Bad TCP option value \"%s\"", arg
);
91 xtables_error(PARAMETER_PROBLEM
,
92 "Option value may not be 0 or 1");
94 if (tcpoptstrip_test_bit(info
->strip_bmap
, option
))
95 xtables_error(PARAMETER_PROBLEM
,
96 "Option \"%s\" already specified", arg
);
98 tcpoptstrip_set_bit(info
->strip_bmap
, option
);
105 static int tcpoptstrip_tg_parse(int c
, char **argv
, int invert
,
106 unsigned int *flags
, const void *entry
,
107 struct xt_entry_target
**target
)
109 struct xt_tcpoptstrip_target_info
*info
= (void *)(*target
)->data
;
113 if (*flags
& FLAG_STRIP
)
114 xtables_error(PARAMETER_PROBLEM
,
115 "You can specify --strip-options only once");
116 parse_list(info
, optarg
);
117 *flags
|= FLAG_STRIP
;
124 static void tcpoptstrip_tg_check(unsigned int flags
)
127 xtables_error(PARAMETER_PROBLEM
,
128 "TCPOPTSTRIP: --strip-options parameter required");
132 tcpoptstrip_print_list(const struct xt_tcpoptstrip_target_info
*info
,
139 for (i
= 0; i
< 256; ++i
) {
140 if (!tcpoptstrip_test_bit(info
->strip_bmap
, i
))
148 for (j
= 0; tcp_optionmap
[j
].name
!= NULL
; ++j
)
149 if (tcp_optionmap
[j
].option
== i
)
150 name
= tcp_optionmap
[j
].name
;
160 tcpoptstrip_tg_print(const void *ip
, const struct xt_entry_target
*target
,
163 const struct xt_tcpoptstrip_target_info
*info
=
164 (const void *)target
->data
;
166 printf("TCPOPTSTRIP options ");
167 tcpoptstrip_print_list(info
, numeric
);
171 tcpoptstrip_tg_save(const void *ip
, const struct xt_entry_target
*target
)
173 const struct xt_tcpoptstrip_target_info
*info
=
174 (const void *)target
->data
;
176 printf("--strip-options ");
177 tcpoptstrip_print_list(info
, true);
180 static struct xtables_target tcpoptstrip_tg_reg
= {
181 .version
= XTABLES_VERSION
,
182 .name
= "TCPOPTSTRIP",
183 .family
= NFPROTO_IPV4
,
184 .size
= XT_ALIGN(sizeof(struct xt_tcpoptstrip_target_info
)),
185 .userspacesize
= XT_ALIGN(sizeof(struct xt_tcpoptstrip_target_info
)),
186 .help
= tcpoptstrip_tg_help
,
187 .init
= tcpoptstrip_tg_init
,
188 .parse
= tcpoptstrip_tg_parse
,
189 .final_check
= tcpoptstrip_tg_check
,
190 .print
= tcpoptstrip_tg_print
,
191 .save
= tcpoptstrip_tg_save
,
192 .extra_opts
= tcpoptstrip_tg_opts
,
195 static struct xtables_target tcpoptstrip_tg6_reg
= {
196 .version
= XTABLES_VERSION
,
197 .name
= "TCPOPTSTRIP",
198 .family
= NFPROTO_IPV6
,
199 .size
= XT_ALIGN(sizeof(struct xt_tcpoptstrip_target_info
)),
200 .userspacesize
= XT_ALIGN(sizeof(struct xt_tcpoptstrip_target_info
)),
201 .help
= tcpoptstrip_tg_help
,
202 .init
= tcpoptstrip_tg_init
,
203 .parse
= tcpoptstrip_tg_parse
,
204 .final_check
= tcpoptstrip_tg_check
,
205 .print
= tcpoptstrip_tg_print
,
206 .save
= tcpoptstrip_tg_save
,
207 .extra_opts
= tcpoptstrip_tg_opts
,
212 xtables_register_target(&tcpoptstrip_tg_reg
);
213 xtables_register_target(&tcpoptstrip_tg6_reg
);