diff options
Diffstat (limited to 'extensions/libxt_rateest.c')
-rw-r--r-- | extensions/libxt_rateest.c | 172 |
1 files changed, 84 insertions, 88 deletions
diff --git a/extensions/libxt_rateest.c b/extensions/libxt_rateest.c index ad0884e..fb24412 100644 --- a/extensions/libxt_rateest.c +++ b/extensions/libxt_rateest.c @@ -1,3 +1,8 @@ +/* + * Copyright (c) 2008-2013 Patrick McHardy <kaber@trash.net> + */ + +#include <stdbool.h> #include <stdio.h> #include <string.h> #include <stdlib.h> @@ -7,9 +12,6 @@ #include <xtables.h> #include <linux/netfilter/xt_rateest.h> -/* Ugly hack to pass info to final_check function. We should fix the API */ -static struct xt_rateest_match_info *rateest_info; - static void rateest_help(void) { printf( @@ -40,20 +42,20 @@ enum rateest_options { }; static const struct option rateest_opts[] = { - { "rateest1", 1, NULL, OPT_RATEEST1 }, - { "rateest", 1, NULL, OPT_RATEEST1 }, /* alias for absolute mode */ - { "rateest2", 1, NULL, OPT_RATEEST2 }, - { "rateest-bps1", 0, NULL, OPT_RATEEST_BPS1 }, - { "rateest-pps1", 0, NULL, OPT_RATEEST_PPS1 }, - { "rateest-bps2", 0, NULL, OPT_RATEEST_BPS2 }, - { "rateest-pps2", 0, NULL, OPT_RATEEST_PPS2 }, - { "rateest-bps", 0, NULL, OPT_RATEEST_BPS2 }, /* alias for absolute mode */ - { "rateest-pps", 0, NULL, OPT_RATEEST_PPS2 }, /* alias for absolute mode */ - { "rateest-delta", 0, NULL, OPT_RATEEST_DELTA }, - { "rateest-lt", 0, NULL, OPT_RATEEST_LT }, - { "rateest-gt", 0, NULL, OPT_RATEEST_GT }, - { "rateest-eq", 0, NULL, OPT_RATEEST_EQ }, - { .name = NULL } + {.name = "rateest1", .has_arg = true, .val = OPT_RATEEST1}, + {.name = "rateest", .has_arg = true, .val = OPT_RATEEST1}, /* alias for absolute mode */ + {.name = "rateest2", .has_arg = true, .val = OPT_RATEEST2}, + {.name = "rateest-bps1", .has_arg = false, .val = OPT_RATEEST_BPS1}, + {.name = "rateest-pps1", .has_arg = false, .val = OPT_RATEEST_PPS1}, + {.name = "rateest-bps2", .has_arg = false, .val = OPT_RATEEST_BPS2}, + {.name = "rateest-pps2", .has_arg = false, .val = OPT_RATEEST_PPS2}, + {.name = "rateest-bps", .has_arg = false, .val = OPT_RATEEST_BPS2}, /* alias for absolute mode */ + {.name = "rateest-pps", .has_arg = false, .val = OPT_RATEEST_PPS2}, /* alias for absolute mode */ + {.name = "rateest-delta", .has_arg = false, .val = OPT_RATEEST_DELTA}, + {.name = "rateest-lt", .has_arg = false, .val = OPT_RATEEST_LT}, + {.name = "rateest-gt", .has_arg = false, .val = OPT_RATEEST_GT}, + {.name = "rateest-eq", .has_arg = false, .val = OPT_RATEEST_EQ}, + XT_GETOPT_TABLEEND, }; /* Copied from iproute. See http://physics.nist.gov/cuu/Units/binary.html */ @@ -64,11 +66,11 @@ static const struct rate_suffix { { "bit", 1. }, { "Kibit", 1024. }, { "kbit", 1000. }, - { "mibit", 1024.*1024. }, + { "Mibit", 1024.*1024. }, { "mbit", 1000000. }, - { "gibit", 1024.*1024.*1024. }, + { "Gibit", 1024.*1024.*1024. }, { "gbit", 1000000000. }, - { "tibit", 1024.*1024.*1024.*1024. }, + { "Tibit", 1024.*1024.*1024.*1024. }, { "tbit", 1000000000000. }, { "Bps", 8. }, { "KiBps", 8.*1024. }, @@ -79,11 +81,11 @@ static const struct rate_suffix { { "GBps", 8000000000. }, { "TiBps", 8.*1024.*1024.*1024.*1024. }, { "TBps", 8000000000000. }, - { .name = NULL } + {NULL}, }; static int -rateest_get_rate(u_int32_t *rate, const char *str) +rateest_get_rate(uint32_t *rate, const char *str) { char *p; double bps = strtod(str, &p); @@ -114,11 +116,8 @@ rateest_parse(int c, char **argv, int invert, unsigned int *flags, struct xt_rateest_match_info *info = (void *)(*match)->data; unsigned int val; - rateest_info = info; - switch (c) { case OPT_RATEEST1: - xtables_check_inverse(optarg, &invert, &optind, 0, argv); if (invert) xtables_error(PARAMETER_PROBLEM, "rateest: rateest can't be inverted"); @@ -132,7 +131,6 @@ rateest_parse(int c, char **argv, int invert, unsigned int *flags, break; case OPT_RATEEST2: - xtables_check_inverse(optarg, &invert, &optind, 0, argv); if (invert) xtables_error(PARAMETER_PROBLEM, "rateest: rateest can't be inverted"); @@ -147,7 +145,6 @@ rateest_parse(int c, char **argv, int invert, unsigned int *flags, break; case OPT_RATEEST_BPS1: - xtables_check_inverse(optarg, &invert, &optind, 0, argv); if (invert) xtables_error(PARAMETER_PROBLEM, "rateest: rateest-bps can't be inverted"); @@ -171,7 +168,6 @@ rateest_parse(int c, char **argv, int invert, unsigned int *flags, break; case OPT_RATEEST_PPS1: - xtables_check_inverse(optarg, &invert, &optind, 0, argv); if (invert) xtables_error(PARAMETER_PROBLEM, "rateest: rateest-pps can't be inverted"); @@ -196,7 +192,6 @@ rateest_parse(int c, char **argv, int invert, unsigned int *flags, break; case OPT_RATEEST_BPS2: - xtables_check_inverse(optarg, &invert, &optind, 0, argv); if (invert) xtables_error(PARAMETER_PROBLEM, "rateest: rateest-bps can't be inverted"); @@ -220,7 +215,6 @@ rateest_parse(int c, char **argv, int invert, unsigned int *flags, break; case OPT_RATEEST_PPS2: - xtables_check_inverse(optarg, &invert, &optind, 0, argv); if (invert) xtables_error(PARAMETER_PROBLEM, "rateest: rateest-pps can't be inverted"); @@ -245,7 +239,6 @@ rateest_parse(int c, char **argv, int invert, unsigned int *flags, break; case OPT_RATEEST_DELTA: - xtables_check_inverse(optarg, &invert, &optind, 0, argv); if (invert) xtables_error(PARAMETER_PROBLEM, "rateest: rateest-delta can't be inverted"); @@ -259,8 +252,6 @@ rateest_parse(int c, char **argv, int invert, unsigned int *flags, break; case OPT_RATEEST_EQ: - xtables_check_inverse(optarg, &invert, &optind, 0, argv); - if (*flags & (1 << c)) xtables_error(PARAMETER_PROBLEM, "rateest: can't specify lt/gt/eq twice"); @@ -272,8 +263,6 @@ rateest_parse(int c, char **argv, int invert, unsigned int *flags, break; case OPT_RATEEST_LT: - xtables_check_inverse(optarg, &invert, &optind, 0, argv); - if (*flags & (1 << c)) xtables_error(PARAMETER_PROBLEM, "rateest: can't specify lt/gt/eq twice"); @@ -285,8 +274,6 @@ rateest_parse(int c, char **argv, int invert, unsigned int *flags, break; case OPT_RATEEST_GT: - xtables_check_inverse(optarg, &invert, &optind, 0, argv); - if (*flags & (1 << c)) xtables_error(PARAMETER_PROBLEM, "rateest: can't specify lt/gt/eq twice"); @@ -296,18 +283,14 @@ rateest_parse(int c, char **argv, int invert, unsigned int *flags, if (invert) info->flags |= XT_RATEEST_MATCH_INVERT; break; - - default: - return 0; } return 1; } -static void -rateest_final_check(unsigned int flags) +static void rateest_final_check(struct xt_fcheck_call *cb) { - struct xt_rateest_match_info *info = rateest_info; + struct xt_rateest_match_info *info = cb->data; if (info == NULL) xtables_error(PARAMETER_PROBLEM, "rateest match: " @@ -317,18 +300,18 @@ rateest_final_check(unsigned int flags) } static void -rateest_print_rate(u_int32_t rate, int numeric) +rateest_print_rate(uint32_t rate, int numeric) { double tmp = (double)rate*8; if (numeric) - printf("%u ", rate); + printf(" %u", rate); else if (tmp >= 1000.0*1000000.0) - printf("%.0fMbit ", tmp/1000000.0); + printf(" %.0fMbit", tmp/1000000.0); else if (tmp >= 1000.0 * 1000.0) - printf("%.0fKbit ", tmp/1000.0); + printf(" %.0fKbit", tmp/1000.0); else - printf("%.0fbit ", tmp); + printf(" %.0fbit", tmp); } static void @@ -336,17 +319,17 @@ rateest_print_mode(const struct xt_rateest_match_info *info, const char *prefix) { if (info->flags & XT_RATEEST_MATCH_INVERT) - printf("! "); + printf(" !"); switch (info->mode) { case XT_RATEEST_MATCH_EQ: - printf("%seq ", prefix); + printf(" %seq", prefix); break; case XT_RATEEST_MATCH_LT: - printf("%slt ", prefix); + printf(" %slt", prefix); break; case XT_RATEEST_MATCH_GT: - printf("%sgt ", prefix); + printf(" %sgt", prefix); break; default: exit(1); @@ -358,78 +341,91 @@ rateest_print(const void *ip, const struct xt_entry_match *match, int numeric) { const struct xt_rateest_match_info *info = (const void *)match->data; - printf("rateest match "); + printf(" rateest match "); - printf("%s ", info->name1); + printf("%s", info->name1); if (info->flags & XT_RATEEST_MATCH_DELTA) - printf("delta "); + printf(" delta"); if (info->flags & XT_RATEEST_MATCH_BPS) { - printf("bps "); + printf(" bps"); if (info->flags & XT_RATEEST_MATCH_DELTA) rateest_print_rate(info->bps1, numeric); if (info->flags & XT_RATEEST_MATCH_ABS) { - rateest_print_mode(info, ""); rateest_print_rate(info->bps2, numeric); + rateest_print_mode(info, ""); } } if (info->flags & XT_RATEEST_MATCH_PPS) { - printf("pps "); + printf(" pps"); if (info->flags & XT_RATEEST_MATCH_DELTA) - printf("%u ", info->pps1); + printf(" %u", info->pps1); if (info->flags & XT_RATEEST_MATCH_ABS) { rateest_print_mode(info, ""); - printf("%u ", info->pps2); + printf(" %u", info->pps2); } } if (info->flags & XT_RATEEST_MATCH_REL) { rateest_print_mode(info, ""); - printf("%s ", info->name2); - if (info->flags & XT_RATEEST_MATCH_DELTA) - printf("delta "); + printf(" %s", info->name2); if (info->flags & XT_RATEEST_MATCH_BPS) { - printf("bps "); + printf(" bps"); if (info->flags & XT_RATEEST_MATCH_DELTA) rateest_print_rate(info->bps2, numeric); } if (info->flags & XT_RATEEST_MATCH_PPS) { - printf("pps "); + printf(" pps"); if (info->flags & XT_RATEEST_MATCH_DELTA) - printf("%u ", info->pps2); + printf(" %u", info->pps2); } } } +static void __rateest_save_rate(const struct xt_rateest_match_info *info, + const char *name, uint32_t r1, uint32_t r2, + int numeric) +{ + if (info->flags & XT_RATEEST_MATCH_DELTA) { + printf(" --rateest-%s1", name); + rateest_print_rate(r1, numeric); + rateest_print_mode(info, "--rateest-"); + printf(" --rateest-%s2", name); + } else { + rateest_print_mode(info, "--rateest-"); + printf(" --rateest-%s", name); + } + + if (info->flags & (XT_RATEEST_MATCH_ABS|XT_RATEEST_MATCH_DELTA)) + rateest_print_rate(r2, numeric); +} + +static void rateest_save_rates(const struct xt_rateest_match_info *info) +{ + if (info->flags & XT_RATEEST_MATCH_BPS) + __rateest_save_rate(info, "bps", info->bps1, info->bps2, 0); + if (info->flags & XT_RATEEST_MATCH_PPS) + __rateest_save_rate(info, "pps", info->pps1, info->pps2, 1); +} + + static void rateest_save(const void *ip, const struct xt_entry_match *match) { const struct xt_rateest_match_info *info = (const void *)match->data; + if (info->flags & XT_RATEEST_MATCH_DELTA) + printf(" --rateest-delta"); + if (info->flags & XT_RATEEST_MATCH_REL) { - printf("--rateest1 %s ", info->name1); - if (info->flags & XT_RATEEST_MATCH_BPS) - printf("--rateest-bps "); - if (info->flags & XT_RATEEST_MATCH_PPS) - printf("--rateest-pps "); - rateest_print_mode(info, "--rateest-"); - printf("--rateest2 %s ", info->name2); - } else { - printf("--rateest %s ", info->name1); - if (info->flags & XT_RATEEST_MATCH_BPS) { - printf("--rateest-bps1 "); - rateest_print_rate(info->bps1, 0); - printf("--rateest-bps2 "); - rateest_print_rate(info->bps2, 0); - rateest_print_mode(info, "--rateest-"); - } - if (info->flags & XT_RATEEST_MATCH_PPS) { - printf("--rateest-pps "); - rateest_print_mode(info, "--rateest-"); - printf("%u ", info->pps2); - } + printf(" --rateest1 %s", info->name1); + rateest_save_rates(info); + printf(" --rateest2 %s", info->name2); + } else { /* XT_RATEEST_MATCH_ABS */ + printf(" --rateest %s", info->name1); + rateest_save_rates(info); } } @@ -441,7 +437,7 @@ static struct xtables_match rateest_mt_reg = { .userspacesize = XT_ALIGN(offsetof(struct xt_rateest_match_info, est1)), .help = rateest_help, .parse = rateest_parse, - .final_check = rateest_final_check, + .x6_fcheck = rateest_final_check, .print = rateest_print, .save = rateest_save, .extra_opts = rateest_opts, |