From 36f2eadca556da9bb4979b3f67f38020e80ef7d2 Mon Sep 17 00:00:00 2001 From: Jan Engelhardt Date: Sun, 20 Jan 2008 13:25:08 +0000 Subject: 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 --- extensions/libxt_TOS.c | 257 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 257 insertions(+) create mode 100644 extensions/libxt_TOS.c (limited to 'extensions/libxt_TOS.c') 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 + */ +#include +#include +#include +#include + +#include +#include +#include +#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); +} -- cgit v1.2.3