+++ /dev/null
-/*
- * Shared library add-on to iptables to add TCPOPTSTRIP target support.
- * Copyright (c) 2007 Sven Schnelle <svens@bitebene.org>
- * Copyright © CC Computer Consultants GmbH, 2007
- * Jan Engelhardt <jengelh@computergmbh.de>
- */
-#include <getopt.h>
-#include <stdbool.h>
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#include <xtables.h>
-#include <linux/netfilter/x_tables.h>
-#include <linux/netfilter/xt_TCPOPTSTRIP.h>
-#ifndef TCPOPT_MD5SIG
-# define TCPOPT_MD5SIG 19
-#endif
-
-enum {
- FLAG_STRIP = 1 << 0,
-};
-
-struct tcp_optionmap {
- const char *name, *desc;
- const unsigned int option;
-};
-
-static const struct option tcpoptstrip_tg_opts[] = {
- {.name = "strip-options", .has_arg = true, .val = 's'},
- { .name = NULL }
-};
-
-static const struct tcp_optionmap tcp_optionmap[] = {
- {"wscale", "Window scale", TCPOPT_WINDOW},
- {"mss", "Maximum Segment Size", TCPOPT_MAXSEG},
- {"sack-permitted", "SACK permitted", TCPOPT_SACK_PERMITTED},
- {"sack", "Selective ACK", TCPOPT_SACK},
- {"timestamp", "Timestamp", TCPOPT_TIMESTAMP},
- {"md5", "MD5 signature", TCPOPT_MD5SIG},
- { .name = NULL }
-};
-
-static void tcpoptstrip_tg_help(void)
-{
- const struct tcp_optionmap *w;
-
- printf(
-"TCPOPTSTRIP target options:\n"
-" --strip-options value strip specified TCP options denoted by value\n"
-" (separated by comma) from TCP header\n"
-" Instead of the numeric value, you can also use the following names:\n"
- );
-
- for (w = tcp_optionmap; w->name != NULL; ++w)
- printf(" %-14s strip \"%s\" option\n", w->name, w->desc);
-}
-
-static void tcpoptstrip_tg_init(struct xt_entry_target *t)
-{
- struct xt_tcpoptstrip_target_info *info = (void *)t->data;
-
- /* strictly necessary? play safe for now. */
- memset(info->strip_bmap, 0, sizeof(info->strip_bmap));
-}
-
-static void parse_list(struct xt_tcpoptstrip_target_info *info, char *arg)
-{
- unsigned int option;
- char *p;
- int i;
-
- while (true) {
- p = strchr(arg, ',');
- if (p != NULL)
- *p = '\0';
-
- option = 0;
- for (i = 0; tcp_optionmap[i].name != NULL; ++i)
- if (strcmp(tcp_optionmap[i].name, arg) == 0) {
- option = tcp_optionmap[i].option;
- break;
- }
-
- if (option == 0 && string_to_number(arg, 0, 255, &option) == -1)
- exit_error(PARAMETER_PROBLEM,
- "Bad TCP option value \"%s\"", arg);
-
- if (option < 2)
- exit_error(PARAMETER_PROBLEM,
- "Option value may not be 0 or 1");
-
- if (tcpoptstrip_test_bit(info->strip_bmap, option))
- exit_error(PARAMETER_PROBLEM,
- "Option \"%s\" already specified", arg);
-
- tcpoptstrip_set_bit(info->strip_bmap, option);
- if (p == NULL)
- break;
- arg = p + 1;
- }
-}
-
-static int tcpoptstrip_tg_parse(int c, char **argv, int invert,
- unsigned int *flags, const void *entry,
- struct xt_entry_target **target)
-{
- struct xt_tcpoptstrip_target_info *info = (void *)(*target)->data;
-
- switch (c) {
- case 's':
- if (*flags & FLAG_STRIP)
- exit_error(PARAMETER_PROBLEM,
- "You can specify --strip-options only once");
- parse_list(info, optarg);
- *flags |= FLAG_STRIP;
- return true;
- }
-
- return false;
-}
-
-static void tcpoptstrip_tg_check(unsigned int flags)
-{
- if (flags == 0)
- exit_error(PARAMETER_PROBLEM,
- "TCPOPTSTRIP: --strip-options parameter required");
-}
-
-static void
-tcpoptstrip_print_list(const struct xt_tcpoptstrip_target_info *info,
- bool numeric)
-{
- unsigned int i, j;
- const char *name;
- bool first = true;
-
- for (i = 0; i < 256; ++i) {
- if (!tcpoptstrip_test_bit(info->strip_bmap, i))
- continue;
- if (!first)
- printf(",");
-
- first = false;
- name = NULL;
- if (!numeric)
- for (j = 0; tcp_optionmap[j].name != NULL; ++j)
- if (tcp_optionmap[j].option == i)
- name = tcp_optionmap[j].name;
-
- if (name != NULL)
- printf("%s", name);
- else
- printf("%u", i);
- }
-}
-
-static void
-tcpoptstrip_tg_print(const void *ip, const struct xt_entry_target *target,
- int numeric)
-{
- const struct xt_tcpoptstrip_target_info *info =
- (const void *)target->data;
-
- printf("TCPOPTSTRIP options ");
- tcpoptstrip_print_list(info, numeric);
-}
-
-static void
-tcpoptstrip_tg_save(const void *ip, const struct xt_entry_target *target)
-{
- const struct xt_tcpoptstrip_target_info *info =
- (const void *)target->data;
-
- printf("--strip-options ");
- tcpoptstrip_print_list(info, true);
-}
-
-static struct xtables_target tcpoptstrip_tg_reg = {
- .version = XTABLES_VERSION,
- .name = "TCPOPTSTRIP",
- .family = AF_INET,
- .size = XT_ALIGN(sizeof(struct xt_tcpoptstrip_target_info)),
- .userspacesize = XT_ALIGN(sizeof(struct xt_tcpoptstrip_target_info)),
- .help = tcpoptstrip_tg_help,
- .init = tcpoptstrip_tg_init,
- .parse = tcpoptstrip_tg_parse,
- .final_check = tcpoptstrip_tg_check,
- .print = tcpoptstrip_tg_print,
- .save = tcpoptstrip_tg_save,
- .extra_opts = tcpoptstrip_tg_opts,
-};
-
-static struct xtables_target tcpoptstrip_tg6_reg = {
- .version = XTABLES_VERSION,
- .name = "TCPOPTSTRIP",
- .family = AF_INET6,
- .size = XT_ALIGN(sizeof(struct xt_tcpoptstrip_target_info)),
- .userspacesize = XT_ALIGN(sizeof(struct xt_tcpoptstrip_target_info)),
- .help = tcpoptstrip_tg_help,
- .init = tcpoptstrip_tg_init,
- .parse = tcpoptstrip_tg_parse,
- .final_check = tcpoptstrip_tg_check,
- .print = tcpoptstrip_tg_print,
- .save = tcpoptstrip_tg_save,
- .extra_opts = tcpoptstrip_tg_opts,
-};
-
-void _init(void)
-{
- xtables_register_target(&tcpoptstrip_tg_reg);
- xtables_register_target(&tcpoptstrip_tg6_reg);
-}