diff options
Diffstat (limited to 'extensions')
-rw-r--r-- | extensions/libebt_limit.c | 205 | ||||
-rw-r--r-- | extensions/libxt_limit.c | 102 |
2 files changed, 88 insertions, 219 deletions
diff --git a/extensions/libebt_limit.c b/extensions/libebt_limit.c deleted file mode 100644 index e8da2a15..00000000 --- a/extensions/libebt_limit.c +++ /dev/null @@ -1,205 +0,0 @@ -/* ebt_limit - * - * Authors: - * Tom Marshall <tommy@home.tig-grr.com> - * - * Mostly copied from iptables' limit match. - * - * September, 2003 - * - * Translated to use libxtables for ebtables-compat in 2015 by - * Arturo Borrero Gonzalez <arturo@debian.org> - */ - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <getopt.h> -#include <errno.h> -#include <xtables.h> -#include <linux/netfilter_bridge/ebt_limit.h> -#include "iptables/nft.h" -#include "iptables/nft-bridge.h" - -#define EBT_LIMIT_AVG "3/hour" -#define EBT_LIMIT_BURST 5 - -#define FLAG_LIMIT 0x01 -#define FLAG_LIMIT_BURST 0x02 -#define ARG_LIMIT '1' -#define ARG_LIMIT_BURST '2' - -static const struct option brlimit_opts[] = -{ - { .name = "limit", .has_arg = true, .val = ARG_LIMIT }, - { .name = "limit-burst",.has_arg = true, .val = ARG_LIMIT_BURST }, - XT_GETOPT_TABLEEND, -}; - -static void brlimit_print_help(void) -{ - printf( -"limit options:\n" -"--limit avg : max average match rate: default "EBT_LIMIT_AVG"\n" -" [Packets per second unless followed by \n" -" /sec /minute /hour /day postfixes]\n" -"--limit-burst number : number to match in a burst, -1 < number < 10001,\n" -" default %u\n", EBT_LIMIT_BURST); -} - -static int parse_rate(const char *rate, uint32_t *val) -{ - const char *delim; - uint32_t r; - uint32_t mult = 1; /* Seconds by default. */ - - delim = strchr(rate, '/'); - if (delim) { - if (strlen(delim+1) == 0) - return 0; - - if (strncasecmp(delim+1, "second", strlen(delim+1)) == 0) - mult = 1; - else if (strncasecmp(delim+1, "minute", strlen(delim+1)) == 0) - mult = 60; - else if (strncasecmp(delim+1, "hour", strlen(delim+1)) == 0) - mult = 60*60; - else if (strncasecmp(delim+1, "day", strlen(delim+1)) == 0) - mult = 24*60*60; - else - return 0; - } - r = atoi(rate); - if (!r) - return 0; - - /* This would get mapped to infinite (1/day is minimum they - can specify, so we're ok at that end). */ - if (r / mult > EBT_LIMIT_SCALE) - return 0; - - *val = EBT_LIMIT_SCALE * mult / r; - return 1; -} - -static void brlimit_init(struct xt_entry_match *match) -{ - struct ebt_limit_info *r = (struct ebt_limit_info *)match->data; - - parse_rate(EBT_LIMIT_AVG, &r->avg); - r->burst = EBT_LIMIT_BURST; -} - -static int brlimit_parse(int c, char **argv, int invert, unsigned int *flags, - const void *entry, struct xt_entry_match **match) -{ - struct ebt_limit_info *r = (struct ebt_limit_info *)(*match)->data; - uintmax_t num; - - switch (c) { - case ARG_LIMIT: - EBT_CHECK_OPTION(flags, FLAG_LIMIT); - if (invert) - xtables_error(PARAMETER_PROBLEM, - "Unexpected `!' after --limit"); - if (!parse_rate(optarg, &r->avg)) - xtables_error(PARAMETER_PROBLEM, - "bad rate `%s'", optarg); - break; - case ARG_LIMIT_BURST: - EBT_CHECK_OPTION(flags, FLAG_LIMIT_BURST); - if (invert) - xtables_error(PARAMETER_PROBLEM, - "Unexpected `!' after --limit-burst"); - if (!xtables_strtoul(optarg, NULL, &num, 0, 10000)) - xtables_error(PARAMETER_PROBLEM, - "bad --limit-burst `%s'", optarg); - r->burst = num; - break; - default: - return 0; - } - - return 1; -} - -struct rates -{ - const char *name; - uint32_t mult; -}; - -static struct rates g_rates[] = -{ - { "day", EBT_LIMIT_SCALE*24*60*60 }, - { "hour", EBT_LIMIT_SCALE*60*60 }, - { "minute", EBT_LIMIT_SCALE*60 }, - { "second", EBT_LIMIT_SCALE } -}; - -static void print_rate(uint32_t period) -{ - unsigned int i; - - for (i = 1; i < sizeof(g_rates)/sizeof(struct rates); i++) - if (period > g_rates[i].mult || - g_rates[i].mult/period < g_rates[i].mult%period) - break; - - printf("%u/%s ", g_rates[i-1].mult / period, g_rates[i-1].name); -} - -static void brlimit_print(const void *ip, const struct xt_entry_match *match, - int numeric) -{ - struct ebt_limit_info *r = (struct ebt_limit_info *)match->data; - - printf("--limit "); - print_rate(r->avg); - printf("--limit-burst %u ", r->burst); -} - -static void print_rate_xlate(struct xt_xlate *xl, uint32_t period) -{ - unsigned int i; - - for (i = 1; i < sizeof(g_rates)/sizeof(struct rates); i++) - if (period > g_rates[i].mult || - g_rates[i].mult/period < g_rates[i].mult%period) - break; - - xt_xlate_add(xl, "%u/%s ", g_rates[i-1].mult / period, g_rates[i-1].name); -} - -static int brlimit_xlate(struct xt_xlate *xl, - const struct xt_xlate_mt_params *params) -{ - const struct ebt_limit_info *r = (const void *)params->match->data; - - xt_xlate_add(xl, "limit rate "); - print_rate_xlate(xl, r->avg); - if (r->burst != 0) - xt_xlate_add(xl, "burst %u packets ", r->burst); - - return 1; -} - -static struct xtables_match brlimit_match = { - .name = "limit", - .revision = 0, - .version = XTABLES_VERSION, - .family = NFPROTO_BRIDGE, - .size = XT_ALIGN(sizeof(struct ebt_limit_info)), - .userspacesize = offsetof(struct ebt_limit_info, prev), - .init = brlimit_init, - .help = brlimit_print_help, - .parse = brlimit_parse, - .print = brlimit_print, - .xlate = brlimit_xlate, - .extra_opts = brlimit_opts, -}; - -void _init(void) -{ - xtables_register_match(&brlimit_match); -} diff --git a/extensions/libxt_limit.c b/extensions/libxt_limit.c index c8ddca87..124bda29 100644 --- a/extensions/libxt_limit.c +++ b/extensions/libxt_limit.c @@ -6,6 +6,8 @@ #define _BSD_SOURCE 1 #define _DEFAULT_SOURCE 1 #define _ISOC99_SOURCE 1 +#include <errno.h> +#include <getopt.h> #include <math.h> #include <stdio.h> #include <string.h> @@ -13,6 +15,8 @@ #include <xtables.h> #include <linux/netfilter/x_tables.h> #include <linux/netfilter/xt_limit.h> +#include "iptables/nft.h" +#include "iptables/nft-bridge.h" #define XT_LIMIT_AVG "3/hour" #define XT_LIMIT_BURST 5 @@ -191,22 +195,92 @@ static int limit_xlate(struct xt_xlate *xl, return 1; } -static struct xtables_match limit_match = { - .family = NFPROTO_UNSPEC, - .name = "limit", - .version = XTABLES_VERSION, - .size = XT_ALIGN(sizeof(struct xt_rateinfo)), - .userspacesize = offsetof(struct xt_rateinfo, prev), - .help = limit_help, - .init = limit_init, - .x6_parse = limit_parse, - .print = limit_print, - .save = limit_save, - .x6_options = limit_opts, - .xlate = limit_xlate, +#define FLAG_LIMIT 0x01 +#define FLAG_LIMIT_BURST 0x02 +#define ARG_LIMIT '1' +#define ARG_LIMIT_BURST '2' + +static int brlimit_parse(int c, char **argv, int invert, unsigned int *flags, + const void *entry, struct xt_entry_match **match) +{ + struct xt_rateinfo *r = (struct xt_rateinfo *)(*match)->data; + uintmax_t num; + + switch (c) { + case ARG_LIMIT: + EBT_CHECK_OPTION(flags, FLAG_LIMIT); + if (invert) + xtables_error(PARAMETER_PROBLEM, + "Unexpected `!' after --limit"); + if (!parse_rate(optarg, &r->avg)) + xtables_error(PARAMETER_PROBLEM, + "bad rate `%s'", optarg); + break; + case ARG_LIMIT_BURST: + EBT_CHECK_OPTION(flags, FLAG_LIMIT_BURST); + if (invert) + xtables_error(PARAMETER_PROBLEM, + "Unexpected `!' after --limit-burst"); + if (!xtables_strtoul(optarg, NULL, &num, 0, 10000)) + xtables_error(PARAMETER_PROBLEM, + "bad --limit-burst `%s'", optarg); + r->burst = num; + break; + default: + return 0; + } + + return 1; +} + +static void brlimit_print(const void *ip, const struct xt_entry_match *match, + int numeric) +{ + const struct xt_rateinfo *r = (struct xt_rateinfo *)match->data; + + printf("--limit"); + print_rate(r->avg); + printf(" --limit-burst %u ", r->burst); +} + +static const struct option brlimit_opts[] = +{ + { .name = "limit", .has_arg = true, .val = ARG_LIMIT }, + { .name = "limit-burst",.has_arg = true, .val = ARG_LIMIT_BURST }, + XT_GETOPT_TABLEEND, +}; + +static struct xtables_match limit_match[] = { + { + .family = NFPROTO_UNSPEC, + .name = "limit", + .version = XTABLES_VERSION, + .size = XT_ALIGN(sizeof(struct xt_rateinfo)), + .userspacesize = offsetof(struct xt_rateinfo, prev), + .help = limit_help, + .init = limit_init, + .x6_parse = limit_parse, + .print = limit_print, + .save = limit_save, + .x6_options = limit_opts, + .xlate = limit_xlate, + }, + { + .family = NFPROTO_BRIDGE, + .name = "limit", + .version = XTABLES_VERSION, + .size = XT_ALIGN(sizeof(struct xt_rateinfo)), + .userspacesize = offsetof(struct xt_rateinfo, prev), + .help = limit_help, + .init = limit_init, + .parse = brlimit_parse, + .print = brlimit_print, + .extra_opts = brlimit_opts, + .xlate = limit_xlate, + }, }; void _init(void) { - xtables_register_match(&limit_match); + xtables_register_matches(limit_match, ARRAY_SIZE(limit_match)); } |