/* Shared library add-on to iptables to add limit support.
 *
 * Jérôme de Vivie   <devivie@info.enserb.u-bordeaux.fr>
 * Hervé Eychenne    <rv@wallfire.org>
 */

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <getopt.h>
#include <xtables.h>
#include <stddef.h>
#include <linux/netfilter/x_tables.h>
/* For 64bit kernel / 32bit userspace */
#include <linux/netfilter/xt_limit.h>

#define XT_LIMIT_AVG	"3/hour"
#define XT_LIMIT_BURST	5

static void limit_help(void)
{
	printf(
"limit match options:\n"
"--limit avg			max average match rate: default "XT_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, default %u\n",
XT_LIMIT_BURST);
}

static const struct option limit_opts[] = {
	{ "limit", 1, NULL, '%' },
	{ "limit-burst", 1, NULL, '$' },
	{ .name = NULL }
};

static
int parse_rate(const char *rate, u_int32_t *val)
{
	const char *delim;
	u_int32_t r;
	u_int32_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 > XT_LIMIT_SCALE)
		xtables_error(PARAMETER_PROBLEM, "Rate too fast \"%s\"\n", rate);

	*val = XT_LIMIT_SCALE * mult / r;
	return 1;
}

static void limit_init(struct xt_entry_match *m)
{
	struct xt_rateinfo *r = (struct xt_rateinfo *)m->data;

	parse_rate(XT_LIMIT_AVG, &r->avg);
	r->burst = XT_LIMIT_BURST;

}

/* FIXME: handle overflow:
	if (r->avg*r->burst/r->burst != r->avg)
		xtables_error(PARAMETER_PROBLEM,
			   "Sorry: burst too large for that avg rate.\n");
*/

static int
limit_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;
	unsigned int num;

	switch(c) {
	case '%':
		if (xtables_check_inverse(argv[optind-1], &invert, &optind, 0)) break;
		if (!parse_rate(optarg, &r->avg))
			xtables_error(PARAMETER_PROBLEM,
				   "bad rate `%s'", optarg);
		break;

	case '$':
		if (xtables_check_inverse(argv[optind-1], &invert, &optind, 0)) break;
		if (!xtables_strtoui(optarg, NULL, &num, 0, 10000))
			xtables_error(PARAMETER_PROBLEM,
				   "bad --limit-burst `%s'", optarg);
		r->burst = num;
		break;

	default:
		return 0;
	}

	if (invert)
		xtables_error(PARAMETER_PROBLEM,
			   "limit does not support invert");

	return 1;
}

static const struct rates
{
	const char *name;
	u_int32_t mult;
} rates[] = { { "day", XT_LIMIT_SCALE*24*60*60 },
	      { "hour", XT_LIMIT_SCALE*60*60 },
	      { "min", XT_LIMIT_SCALE*60 },
	      { "sec", XT_LIMIT_SCALE } };

static void print_rate(u_int32_t period)
{
	unsigned int i;

	for (i = 1; i < sizeof(rates)/sizeof(struct rates); i++) {
		if (period > rates[i].mult
            || rates[i].mult/period < rates[i].mult%period)
			break;
	}

	printf("%u/%s ", rates[i-1].mult / period, rates[i-1].name);
}

static void
limit_print(const void *ip, const struct xt_entry_match *match, int numeric)
{
	struct xt_rateinfo *r = (struct xt_rateinfo *)match->data;
	printf("limit: avg "); print_rate(r->avg);
	printf("burst %u ", r->burst);
}

static void limit_save(const void *ip, const struct xt_entry_match *match)
{
	struct xt_rateinfo *r = (struct xt_rateinfo *)match->data;

	printf("--limit "); print_rate(r->avg);
	if (r->burst != XT_LIMIT_BURST)
		printf("--limit-burst %u ", r->burst);
}

static struct xtables_match limit_match = {
	.family		= AF_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,
	.parse		= limit_parse,
	.print		= limit_print,
	.save		= limit_save,
	.extra_opts	= limit_opts,
};

void _init(void)
{
	xtables_register_match(&limit_match);
}
