diff options
author | HyungKyu Song <hk76.song@samsung.com> | 2013-02-16 00:06:47 +0900 |
---|---|---|
committer | HyungKyu Song <hk76.song@samsung.com> | 2013-02-16 00:06:47 +0900 |
commit | ebceb903d97f38aa6f4110c455367492c8b94f6c (patch) | |
tree | 5d21c5f26a156067e733c9faa79782ecc26196e9 /extensions/libxt_TOS.c | |
parent | dbc5ef4889caa206f4d47d83345357780ceef73e (diff) | |
download | iptables-ebceb903d97f38aa6f4110c455367492c8b94f6c.tar.gz iptables-ebceb903d97f38aa6f4110c455367492c8b94f6c.tar.bz2 iptables-ebceb903d97f38aa6f4110c455367492c8b94f6c.zip |
Diffstat (limited to 'extensions/libxt_TOS.c')
-rw-r--r-- | extensions/libxt_TOS.c | 245 |
1 files changed, 245 insertions, 0 deletions
diff --git a/extensions/libxt_TOS.c b/extensions/libxt_TOS.c new file mode 100644 index 0000000..dc60cc0 --- /dev/null +++ b/extensions/libxt_TOS.c @@ -0,0 +1,245 @@ +/* + * 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 <netinet/in.h> + +#include <xtables.h> +#include <linux/netfilter/xt_DSCP.h> +#include "tos_values.c" + +struct ipt_tos_target_info { + u_int8_t tos; +}; + +enum { + FLAG_TOS = 1 << 0, +}; + +static const struct option tos_tg_opts_v0[] = { + {.name = "set-tos", .has_arg = true, .val = '='}, + { .name = NULL } +}; + +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 = '^'}, + { .name = NULL } +}; + +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", +XTABLES_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 '=': + xtables_param_act(XTF_ONLY_ONCE, "TOS", "--set-tos", *flags & FLAG_TOS); + xtables_param_act(XTF_NO_INVERT, "TOS", "--set-tos", invert); + if (!tos_parse_symbolic(optarg, &tvm, 0xFF)) + xtables_param_act(XTF_BAD_VALUE, "TOS", "--set-tos", optarg); + if (tvm.mask != 0xFF) + xtables_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 */ + xtables_param_act(XTF_ONLY_ONCE, "TOS", "--set-tos", *flags & FLAG_TOS); + xtables_param_act(XTF_NO_INVERT, "TOS", "--set-tos", invert); + if (!tos_parse_symbolic(optarg, &tvm, 0x3F)) + xtables_param_act(XTF_BAD_VALUE, "TOS", "--set-tos", optarg); + info->tos_value = tvm.value; + info->tos_mask = tvm.mask; + break; + + case '&': /* --and-tos */ + xtables_param_act(XTF_ONLY_ONCE, "TOS", "--and-tos", *flags & FLAG_TOS); + xtables_param_act(XTF_NO_INVERT, "TOS", "--and-tos", invert); + if (!xtables_strtoui(optarg, NULL, &bits, 0, UINT8_MAX)) + xtables_param_act(XTF_BAD_VALUE, "TOS", "--and-tos", optarg); + info->tos_value = 0; + info->tos_mask = ~bits; + break; + + case '|': /* --or-tos */ + xtables_param_act(XTF_ONLY_ONCE, "TOS", "--or-tos", *flags & FLAG_TOS); + xtables_param_act(XTF_NO_INVERT, "TOS", "--or-tos", invert); + if (!xtables_strtoui(optarg, NULL, &bits, 0, UINT8_MAX)) + xtables_param_act(XTF_BAD_VALUE, "TOS", "--or-tos", optarg); + info->tos_value = bits; + info->tos_mask = bits; + break; + + case '^': /* --xor-tos */ + xtables_param_act(XTF_ONLY_ONCE, "TOS", "--xor-tos", *flags & FLAG_TOS); + xtables_param_act(XTF_NO_INVERT, "TOS", "--xor-tos", invert); + if (!xtables_strtoui(optarg, NULL, &bits, 0, UINT8_MAX)) + xtables_param_act(XTF_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) + xtables_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[] = { + { + .version = XTABLES_VERSION, + .name = "TOS", + .revision = 0, + .family = NFPROTO_IPV4, + .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, + }, + { + .version = XTABLES_VERSION, + .name = "TOS", + .revision = 1, + .family = NFPROTO_UNSPEC, + .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_targets(tos_tg_reg, ARRAY_SIZE(tos_tg_reg)); +} |