/* 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>
 */
#define _BSD_SOURCE 1
#define _DEFAULT_SOURCE 1
#define _ISOC99_SOURCE 1
#include <math.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <xtables.h>
#include <linux/netfilter/x_tables.h>
#include <linux/netfilter/xt_limit.h>

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

enum {
	O_LIMIT = 0,
	O_BURST,
};

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 xt_option_entry limit_opts[] = {
	{.name = "limit", .id = O_LIMIT, .type = XTTYPE_STRING},
	{.name = "limit-burst", .id = O_BURST, .type = XTTYPE_UINT32,
	 .flags = XTOPT_PUT, XTOPT_POINTER(struct xt_rateinfo, burst),
	 .min = 0, .max = 10000},
	XTOPT_TABLEEND,
};

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;

	*val = XT_LIMIT_SCALE * mult / r;
	if (*val == 0)
		/*
		 * The rate maps to infinity. (1/day is the minimum they can
		 * specify, so we are ok at that end).
		 */
		xtables_error(PARAMETER_PROBLEM, "Rate too fast \"%s\"\n", rate);
	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 void limit_parse(struct xt_option_call *cb)
{
	struct xt_rateinfo *r = cb->data;

	xtables_option_parse(cb);
	switch (cb->entry->id) {
	case O_LIMIT:
		if (!parse_rate(cb->arg, &r->avg))
			xtables_error(PARAMETER_PROBLEM,
				   "bad rate \"%s\"'", cb->arg);
		break;
	}
	if (cb->invert)
		xtables_error(PARAMETER_PROBLEM,
			   "limit does not support invert");
}

static const struct rates
{
	const char *name;
	uint32_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(uint32_t period)
{
	unsigned int i;

	if (period == 0) {
		printf(" %f", INFINITY);
		return;
	}

	for (i = 1; i < ARRAY_SIZE(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)
{
	const struct xt_rateinfo *r = (const void *)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)
{
	const struct xt_rateinfo *r = (const void *)match->data;

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

static const struct rates rates_xlate[] = {
	{ "day",	XT_LIMIT_SCALE * 24 * 60 * 60 },
	{ "hour",	XT_LIMIT_SCALE * 60 * 60 },
	{ "minute",	XT_LIMIT_SCALE * 60 },
	{ "second",	XT_LIMIT_SCALE }
};

static void print_rate_xlate(uint32_t period, struct xt_xlate *xl)
{
	unsigned int i;

	if (period == 0) {
		xt_xlate_add(xl, " %f", INFINITY);
		return;
	}

	for (i = 1; i < ARRAY_SIZE(rates); ++i)
		if (period > rates_xlate[i].mult ||
		    rates_xlate[i].mult / period < rates_xlate[i].mult % period)
			break;

	xt_xlate_add(xl, " %u/%s", rates_xlate[i - 1].mult / period,
		   rates_xlate[i - 1].name);
}

static int limit_xlate(struct xt_xlate *xl,
		       const struct xt_xlate_mt_params *params)
{
	const struct xt_rateinfo *r = (const void *)params->match->data;

	xt_xlate_add(xl, "limit rate");
	print_rate_xlate(r->avg, xl);
	if (r->burst != 0)
		xt_xlate_add(xl, " burst %u packets", r->burst);

	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,
};

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