/* ebt_limit
 *
 * Authors:
 * Tom Marshall <tommy@home.tig-grr.com>
 *
 * Mostly copied from iptables' limit match.
 *
 * September, 2003
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <getopt.h>
#include <errno.h>
#include "../include/ebtables_u.h"
#include <linux/netfilter_bridge/ebt_limit.h>

#define EBT_LIMIT_AVG	"3/hour"
#define EBT_LIMIT_BURST	5

static int string_to_number(const char *s, unsigned int min, unsigned int max,
   unsigned int *ret)
{
	long number;
	char *end;

	errno = 0;
	number = strtol(s, &end, 0);
	if (*end == '\0' && end != s) {
		if (errno != ERANGE && min <= number && number <= max) {
			*ret = number;
			return 0;
		}
	}
	return -1;
}

#define FLAG_LIMIT		0x01
#define FLAG_LIMIT_BURST	0x02
#define ARG_LIMIT		'1'
#define ARG_LIMIT_BURST		'2'

static const struct option opts[] =
{
	{ "limit",		required_argument, 0, ARG_LIMIT },
	{ "limit-burst",	required_argument, 0, ARG_LIMIT_BURST },
	{ 0 }
};

static void 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;
}

/* Initialize the match. */
static void init(struct ebt_entry_match *m)
{
	struct ebt_limit_info *r = (struct ebt_limit_info *)m->data;

	parse_rate(EBT_LIMIT_AVG, &r->avg);
	r->burst = EBT_LIMIT_BURST;
}

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

static int parse(int c, char **argv, int argc,
      const struct ebt_u_entry *entry,
      unsigned int *flags,
      struct ebt_entry_match **match)
{
	struct ebt_limit_info *r = (struct ebt_limit_info *)(*match)->data;
	unsigned int num;

	switch(c) {
	case ARG_LIMIT:
		ebt_check_option2(flags, FLAG_LIMIT);
		if (ebt_check_inverse2(optarg))
			ebt_print_error2("Unexpected `!' after --limit");
		if (!parse_rate(optarg, &r->avg))
			ebt_print_error2("bad rate `%s'", optarg);
		break;

	case ARG_LIMIT_BURST:
		ebt_check_option2(flags, FLAG_LIMIT_BURST);
		if (ebt_check_inverse2(optarg))
			ebt_print_error2("Unexpected `!' after --limit-burst");
		if (string_to_number(optarg, 0, 10000, &num) == -1)
			ebt_print_error2("bad --limit-burst `%s'", optarg);
		r->burst = num;
		break;

	default:
		return 0;
	}

	return 1;
}

static void final_check(const struct ebt_u_entry *entry,
   const struct ebt_entry_match *match, const char *name,
   unsigned int hookmask, unsigned int time)
{
}

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 },
	{ "min", EBT_LIMIT_SCALE*60 },
	{ "sec", 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 print(const struct ebt_u_entry *entry,
   const struct ebt_entry_match *match)
{
	struct ebt_limit_info *r = (struct ebt_limit_info *)match->data;

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

static int compare(const struct ebt_entry_match* m1,
   const struct ebt_entry_match *m2)
{
	struct ebt_limit_info* li1 = (struct ebt_limit_info*)m1->data;
	struct ebt_limit_info* li2 = (struct ebt_limit_info*)m2->data;

	if (li1->avg != li2->avg)
		return 0;

	if (li1->burst != li2->burst)
		return 0;

	return 1;
}

static struct ebt_u_match limit_match =
{
	.name		= "limit",
	.size		= sizeof(struct ebt_limit_info),
	.help		= print_help,
	.init		= init,
	.parse		= parse,
	.final_check	= final_check,
	.print		= print,
	.compare	= compare,
	.extra_ops	= opts,
};

static void _INIT(void)
{
	ebt_register_match(&limit_match);
}
