summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJan Engelhardt <jengelh@medozas.de>2008-01-20 13:25:08 +0000
committerPatrick McHardy <kaber@trash.net>2008-01-20 13:25:08 +0000
commit36f2eadca556da9bb4979b3f67f38020e80ef7d2 (patch)
treebe21b6fafa6fd9e816aac132be6371103ccf0235
parent0720c1226381f5c71748673c43c12499f1f254c7 (diff)
libxt_TOS
Move libipt_TOS revision 0 to libxt_TOS revision 0 and add support for xt_TOS target revision 1. Signed-off-by: Jan Engelhardt <jengelh@computergmbh.de>
-rw-r--r--extensions/libipt_TOS.c159
-rw-r--r--extensions/libipt_TOS.man11
-rw-r--r--extensions/libxt_TOS.c257
-rw-r--r--extensions/libxt_TOS.man27
-rw-r--r--include/linux/netfilter/xt_DSCP.h5
5 files changed, 289 insertions, 170 deletions
diff --git a/extensions/libipt_TOS.c b/extensions/libipt_TOS.c
deleted file mode 100644
index 76632ff2..00000000
--- a/extensions/libipt_TOS.c
+++ /dev/null
@@ -1,159 +0,0 @@
-/* Shared library add-on to iptables to add TOS target support. */
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#include <getopt.h>
-
-#include <iptables.h>
-#include <linux/netfilter_ipv4/ip_tables.h>
-#include <linux/netfilter_ipv4/ipt_TOS.h>
-
-struct tosinfo {
- struct xt_entry_target t;
- struct ipt_tos_target_info tos;
-};
-
-/* TOS names and values. */
-static const
-struct TOS_value
-{
- unsigned char TOS;
- const char *name;
-} TOS_values[] = {
- { IPTOS_LOWDELAY, "Minimize-Delay" },
- { IPTOS_THROUGHPUT, "Maximize-Throughput" },
- { IPTOS_RELIABILITY, "Maximize-Reliability" },
- { IPTOS_MINCOST, "Minimize-Cost" },
- { IPTOS_NORMALSVC, "Normal-Service" },
-};
-
-/* Function which prints out usage message. */
-static void TOS_help(void)
-{
- unsigned int i;
-
- printf(
-"TOS target v%s options:\n"
-" --set-tos value Set Type of Service field to one of the\n"
-" following numeric or descriptive values:\n",
-IPTABLES_VERSION);
-
- for (i = 0; i < sizeof(TOS_values)/sizeof(struct TOS_value);i++)
- printf(" %s %u (0x%02x)\n",
- TOS_values[i].name,
- TOS_values[i].TOS,
- TOS_values[i].TOS);
- fputc('\n', stdout);
-}
-
-static const struct option TOS_opts[] = {
- { "set-tos", 1, NULL, '1' },
- { }
-};
-
-static void
-parse_tos(const char *s, struct ipt_tos_target_info *info)
-{
- unsigned int i, tos;
-
- if (string_to_number(s, 0, 255, &tos) != -1) {
- if (tos == IPTOS_LOWDELAY
- || tos == IPTOS_THROUGHPUT
- || tos == IPTOS_RELIABILITY
- || tos == IPTOS_MINCOST
- || tos == IPTOS_NORMALSVC) {
- info->tos = (u_int8_t )tos;
- return;
- }
- } else {
- for (i = 0; i<sizeof(TOS_values)/sizeof(struct TOS_value); i++)
- if (strcasecmp(s,TOS_values[i].name) == 0) {
- info->tos = TOS_values[i].TOS;
- return;
- }
- }
- exit_error(PARAMETER_PROBLEM, "Bad TOS value `%s'", s);
-}
-
-/* Function which parses command options; returns true if it
- ate an option */
-static int TOS_parse(int c, char **argv, int invert, unsigned int *flags,
- const void *entry, struct xt_entry_target **target)
-{
- struct ipt_tos_target_info *tosinfo
- = (struct ipt_tos_target_info *)(*target)->data;
-
- switch (c) {
- case '1':
- if (*flags)
- exit_error(PARAMETER_PROBLEM,
- "TOS target: Cant specify --set-tos twice");
- parse_tos(optarg, tosinfo);
- *flags = 1;
- break;
-
- default:
- return 0;
- }
-
- return 1;
-}
-
-static void TOS_check(unsigned int flags)
-{
- if (!flags)
- exit_error(PARAMETER_PROBLEM,
- "TOS target: Parameter --set-tos is required");
-}
-
-static void
-print_tos(u_int8_t tos, int numeric)
-{
- unsigned int i;
-
- if (!numeric) {
- for (i = 0; i<sizeof(TOS_values)/sizeof(struct TOS_value); i++)
- if (TOS_values[i].TOS == tos) {
- printf("%s ", TOS_values[i].name);
- return;
- }
- }
- printf("0x%02x ", tos);
-}
-
-/* Prints out the targinfo. */
-static void TOS_print(const void *ip, const struct xt_entry_target *target,
- int numeric)
-{
- const struct ipt_tos_target_info *tosinfo =
- (const struct ipt_tos_target_info *)target->data;
- printf("TOS set ");
- print_tos(tosinfo->tos, numeric);
-}
-
-/* Saves the union ipt_targinfo in parsable form to stdout. */
-static void TOS_save(const void *ip, const struct xt_entry_target *target)
-{
- const struct ipt_tos_target_info *tosinfo =
- (const struct ipt_tos_target_info *)target->data;
-
- printf("--set-tos 0x%02x ", tosinfo->tos);
-}
-
-static struct iptables_target tos_target = {
- .name = "TOS",
- .version = IPTABLES_VERSION,
- .size = IPT_ALIGN(sizeof(struct ipt_tos_target_info)),
- .userspacesize = IPT_ALIGN(sizeof(struct ipt_tos_target_info)),
- .help = TOS_help,
- .parse = TOS_parse,
- .final_check = TOS_check,
- .print = TOS_print,
- .save = TOS_save,
- .extra_opts = TOS_opts,
-};
-
-void _init(void)
-{
- register_target(&tos_target);
-}
diff --git a/extensions/libipt_TOS.man b/extensions/libipt_TOS.man
deleted file mode 100644
index c31b068d..00000000
--- a/extensions/libipt_TOS.man
+++ /dev/null
@@ -1,11 +0,0 @@
-This is used to set the 8-bit Type of Service field in the IP header.
-It is only valid in the
-.B mangle
-table.
-.TP
-.BI "--set-tos " "tos"
-You can use a numeric TOS values, or use
-.nf
- iptables -j TOS -h
-.fi
-to see the list of valid TOS names.
diff --git a/extensions/libxt_TOS.c b/extensions/libxt_TOS.c
new file mode 100644
index 00000000..74ec2b52
--- /dev/null
+++ b/extensions/libxt_TOS.c
@@ -0,0 +1,257 @@
+/*
+ * Shared library add-on to iptables to add TOS target support
+ *
+ * Copyright © CC Computer Consultants GmbH, 2007
+ * Contact: Jan Engelhardt <jengelh@computergmbh.de>
+ */
+#include <getopt.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <xtables.h>
+#include <linux/netfilter/xt_DSCP.h>
+#include <linux/netfilter_ipv4/ipt_TOS.h>
+#include "tos_values.c"
+
+enum {
+ FLAG_TOS = 1 << 0,
+};
+
+static const struct option tos_tg_opts_v0[] = {
+ {.name = "set-tos", .has_arg = true, .val = '='},
+ {},
+};
+
+static const struct option tos_tg_opts[] = {
+ {.name = "set-tos", .has_arg = true, .val = '='},
+ {.name = "and-tos", .has_arg = true, .val = '&'},
+ {.name = "or-tos", .has_arg = true, .val = '|'},
+ {.name = "xor-tos", .has_arg = true, .val = '^'},
+ {},
+};
+
+static void tos_tg_help_v0(void)
+{
+ const struct tos_symbol_info *symbol;
+
+ printf(
+"TOS target options:\n"
+" --set-tos value Set Type of Service/Priority field to value\n"
+" --set-tos symbol Set TOS field (IPv4 only) by symbol\n"
+" Accepted symbolic names for value are:\n");
+
+ for (symbol = tos_symbol_names; symbol->name != NULL; ++symbol)
+ printf(" (0x%02x) %2u %s\n",
+ symbol->value, symbol->value, symbol->name);
+
+ printf("\n");
+}
+
+static void tos_tg_help(void)
+{
+ const struct tos_symbol_info *symbol;
+
+ printf(
+"TOS target v%s options:\n"
+" --set-tos value[/mask] Set Type of Service/Priority field to value\n"
+" (Zero out bits in mask and XOR value into TOS)\n"
+" --set-tos symbol Set TOS field (IPv4 only) by symbol\n"
+" (this zeroes the 4-bit Precedence part!)\n"
+" Accepted symbolic names for value are:\n",
+IPTABLES_VERSION);
+
+ for (symbol = tos_symbol_names; symbol->name != NULL; ++symbol)
+ printf(" (0x%02x) %2u %s\n",
+ symbol->value, symbol->value, symbol->name);
+
+ printf(
+"\n"
+" --and-tos bits Binary AND the TOS value with bits\n"
+" --or-tos bits Binary OR the TOS value with bits\n"
+" --xor-tos bits Binary XOR the TOS value with bits\n"
+);
+}
+
+static int tos_tg_parse_v0(int c, char **argv, int invert, unsigned int *flags,
+ const void *entry, struct xt_entry_target **target)
+{
+ struct ipt_tos_target_info *info = (void *)(*target)->data;
+ struct tos_value_mask tvm;
+
+ switch (c) {
+ case '=':
+ param_act(P_ONLY_ONCE, "TOS", "--set-tos", *flags & FLAG_TOS);
+ param_act(P_NO_INVERT, "TOS", "--set-tos", invert);
+ if (!tos_parse_symbolic(optarg, &tvm, 0xFF))
+ param_act(P_BAD_VALUE, "TOS", "--set-tos", optarg);
+ if (tvm.mask != 0xFF)
+ exit_error(PARAMETER_PROBLEM, "tos match: Your kernel "
+ "is too old to support anything besides "
+ "/0xFF as a mask.");
+ info->tos = tvm.value;
+ *flags |= FLAG_TOS;
+ return true;
+ }
+
+ return false;
+}
+
+static int tos_tg_parse(int c, char **argv, int invert, unsigned int *flags,
+ const void *entry, struct xt_entry_target **target)
+{
+ struct xt_tos_target_info *info = (void *)(*target)->data;
+ struct tos_value_mask tvm;
+ unsigned int bits;
+
+ switch (c) {
+ case '=': /* --set-tos */
+ param_act(P_ONLY_ONCE, "TOS", "--set-tos", *flags & FLAG_TOS);
+ param_act(P_NO_INVERT, "TOS", "--set-tos", invert);
+ if (!tos_parse_symbolic(optarg, &tvm, 0x3F))
+ param_act(P_BAD_VALUE, "TOS", "--set-tos", optarg);
+ info->tos_value = tvm.value;
+ info->tos_mask = tvm.mask;
+ break;
+
+ case '&': /* --and-tos */
+ param_act(P_ONLY_ONCE, "TOS", "--and-tos", *flags & FLAG_TOS);
+ param_act(P_NO_INVERT, "TOS", "--and-tos", invert);
+ if (!strtonum(optarg, NULL, &bits, 0, 0xFF))
+ param_act(P_BAD_VALUE, "TOS", "--and-tos", optarg);
+ info->tos_value = 0;
+ info->tos_mask = ~bits;
+ break;
+
+ case '|': /* --or-tos */
+ param_act(P_ONLY_ONCE, "TOS", "--or-tos", *flags & FLAG_TOS);
+ param_act(P_NO_INVERT, "TOS", "--or-tos", invert);
+ if (!strtonum(optarg, NULL, &bits, 0, 0xFF))
+ param_act(P_BAD_VALUE, "TOS", "--or-tos", optarg);
+ info->tos_value = bits;
+ info->tos_mask = bits;
+ break;
+
+ case '^': /* --xor-tos */
+ param_act(P_ONLY_ONCE, "TOS", "--xor-tos", *flags & FLAG_TOS);
+ param_act(P_NO_INVERT, "TOS", "--xor-tos", invert);
+ if (!strtonum(optarg, NULL, &bits, 0, 0xFF))
+ param_act(P_BAD_VALUE, "TOS", "--xor-tos", optarg);
+ info->tos_value = bits;
+ info->tos_mask = 0;
+ break;
+
+ default:
+ return false;
+ }
+
+ *flags |= FLAG_TOS;
+ return true;
+}
+
+static void tos_tg_check(unsigned int flags)
+{
+ if (flags == 0)
+ exit_error(PARAMETER_PROBLEM,
+ "TOS: The --set-tos parameter is required");
+}
+
+static void tos_tg_print_v0(const void *ip,
+ const struct xt_entry_target *target, int numeric)
+{
+ const struct ipt_tos_target_info *info = (const void *)target->data;
+
+ printf("TOS set ");
+ if (numeric || !tos_try_print_symbolic("", info->tos, 0xFF))
+ printf("0x%02x ", info->tos);
+}
+
+static void tos_tg_print(const void *ip, const struct xt_entry_target *target,
+ int numeric)
+{
+ const struct xt_tos_target_info *info = (const void *)target->data;
+
+ if (numeric)
+ printf("TOS set 0x%02x/0x%02x ",
+ info->tos_value, info->tos_mask);
+ else if (tos_try_print_symbolic("TOS set ",
+ info->tos_value, info->tos_mask))
+ /* already printed by call */
+ return;
+ else if (info->tos_value == 0)
+ printf("TOS and 0x%02x ",
+ (unsigned int)(u_int8_t)~info->tos_mask);
+ else if (info->tos_value == info->tos_mask)
+ printf("TOS or 0x%02x ", info->tos_value);
+ else if (info->tos_mask == 0)
+ printf("TOS xor 0x%02x ", info->tos_value);
+ else
+ printf("TOS set 0x%02x/0x%02x ",
+ info->tos_value, info->tos_mask);
+}
+
+static void tos_tg_save_v0(const void *ip, const struct xt_entry_target *target)
+{
+ const struct ipt_tos_target_info *info = (const void *)target->data;
+
+ printf("--set-tos 0x%02x ", info->tos);
+}
+
+static void tos_tg_save(const void *ip, const struct xt_entry_target *target)
+{
+ const struct xt_tos_target_info *info = (const void *)target->data;
+
+ printf("--set-tos 0x%02x/0x%02x ", info->tos_value, info->tos_mask);
+}
+
+static struct xtables_target tos_tg_reg_v0 = {
+ .version = IPTABLES_VERSION,
+ .name = "TOS",
+ .revision = 0,
+ .family = AF_INET,
+ .size = XT_ALIGN(sizeof(struct xt_tos_target_info)),
+ .userspacesize = XT_ALIGN(sizeof(struct xt_tos_target_info)),
+ .help = tos_tg_help_v0,
+ .parse = tos_tg_parse_v0,
+ .final_check = tos_tg_check,
+ .print = tos_tg_print_v0,
+ .save = tos_tg_save_v0,
+ .extra_opts = tos_tg_opts_v0,
+};
+
+static struct xtables_target tos_tg_reg = {
+ .version = IPTABLES_VERSION,
+ .name = "TOS",
+ .revision = 1,
+ .family = AF_INET,
+ .size = XT_ALIGN(sizeof(struct xt_tos_target_info)),
+ .userspacesize = XT_ALIGN(sizeof(struct xt_tos_target_info)),
+ .help = tos_tg_help,
+ .parse = tos_tg_parse,
+ .final_check = tos_tg_check,
+ .print = tos_tg_print,
+ .save = tos_tg_save,
+ .extra_opts = tos_tg_opts,
+};
+
+static struct xtables_target tos_tg6_reg = {
+ .version = IPTABLES_VERSION,
+ .name = "TOS",
+ .family = AF_INET6,
+ .revision = 1,
+ .size = XT_ALIGN(sizeof(struct xt_tos_target_info)),
+ .userspacesize = XT_ALIGN(sizeof(struct xt_tos_target_info)),
+ .help = tos_tg_help,
+ .parse = tos_tg_parse,
+ .final_check = tos_tg_check,
+ .print = tos_tg_print,
+ .save = tos_tg_save,
+ .extra_opts = tos_tg_opts,
+};
+
+void _init(void)
+{
+ xtables_register_target(&tos_tg_reg_v0);
+ xtables_register_target(&tos_tg_reg);
+ xtables_register_target(&tos_tg6_reg);
+}
diff --git a/extensions/libxt_TOS.man b/extensions/libxt_TOS.man
new file mode 100644
index 00000000..d9b774aa
--- /dev/null
+++ b/extensions/libxt_TOS.man
@@ -0,0 +1,27 @@
+This module sets the Type of Service field in the IPv4 header (including the
+'precedence' bits) or the Priority field in the IPv6 header. Note that TOS
+shares the same bits as DSCP and ECN. The TOS target is only valid in the
+\fBmangle\fR table.
+.TP
+\fB--set-tos\fR \fIvalue\fR[\fB/\fR\fImask\fR]
+Zeroes out the bits given by \fImask\fR and XORs \fIvalue\fR into the
+TOS/Priority field. If \fImask\fR is omitted, 0xFF is assumed.
+.TP
+\fB--set-tos\fR \fIsymbol\fR
+You can specify a symbolic name when using the TOS target for IPv4. It implies
+a mask of 0xFF. The list of recognized TOS names can be obtained by calling
+iptables with \fB-j TOS -h\fR.
+.PP
+The following mnemonics are available:
+.TP
+\fB--and-tos\fR \fIbits\fR
+Binary AND the TOS value with \fIbits\fR. (Mnemonic for \fB--set-tos
+0/\fR\fIinvbits\fR, where \fIinvbits\fR is the binary negation of \fIbits\fR.)
+.TP
+\fB--or-tos\fR \fIbits\fR
+Binary OR the TOS value with \fIbits\fR. (Mnemonic for \fB--set-tos\fR
+\fIbits\fR\fB/\fR\fIbits\fR.)
+.TP
+\fB--xor-tos\fR \fIbits\fR
+Binary XOR the TOS value with \fIbits\fR. (Mnemonic for \fB--set-tos\fR
+\fIbits\fR\fB/0\fR.)
diff --git a/include/linux/netfilter/xt_DSCP.h b/include/linux/netfilter/xt_DSCP.h
index 3c7c9639..14da1968 100644
--- a/include/linux/netfilter/xt_DSCP.h
+++ b/include/linux/netfilter/xt_DSCP.h
@@ -17,4 +17,9 @@ struct xt_DSCP_info {
u_int8_t dscp;
};
+struct xt_tos_target_info {
+ u_int8_t tos_value;
+ u_int8_t tos_mask;
+};
+
#endif /* _XT_DSCP_TARGET_H */