summaryrefslogtreecommitdiffstats
path: root/extensions/libxt_limit.c
diff options
context:
space:
mode:
Diffstat (limited to 'extensions/libxt_limit.c')
-rw-r--r--extensions/libxt_limit.c102
1 files changed, 88 insertions, 14 deletions
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));
}