/* ebt_ulog
 *
 * Authors:
 * Bart De Schuymer <bdschuym@pandora.be>
 *
 * November, 2004
 */

#define __need_time_t
#define __need_suseconds_t
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <getopt.h>
#include "../include/ebtables_u.h"
#include <sys/time.h>
#include <linux/netfilter_bridge/ebt_ulog.h>

#define CP_NO_LIMIT_S "default_cprange"
#define CP_NO_LIMIT_N 0

#define ULOG_PREFIX     '1'
#define ULOG_NLGROUP    '2'
#define ULOG_CPRANGE    '3'
#define ULOG_QTHRESHOLD '4'
#define ULOG_ULOG       '5'
static const struct option opts[] =
{
	{ "ulog-prefix"    , required_argument, 0, ULOG_PREFIX     },
	{ "ulog-nlgroup"   , required_argument, 0, ULOG_NLGROUP    },
	{ "ulog-cprange"   , required_argument, 0, ULOG_CPRANGE    },
	{ "ulog-qthreshold", required_argument, 0, ULOG_QTHRESHOLD },
	{ "ulog"           , no_argument      , 0, ULOG_ULOG       },
	{ 0 }
};

static void print_help()
{
	printf(
"ulog options:\n"
"--ulog                : use the default ulog parameters\n"
"--ulog-prefix prefix  : max %d characters (default is no prefix)\n"
"--ulog-nlgroup group  : 0 < group number < %d (default = %d)\n"
"--ulog-cprange range  : max copy range (default is " CP_NO_LIMIT_S ")\n"
"--ulog-qthreshold     : 0 < queueing threshold < %d (default = %d)\n",
	EBT_ULOG_PREFIX_LEN - 1, EBT_ULOG_MAXNLGROUPS + 1,
	EBT_ULOG_DEFAULT_NLGROUP + 1, EBT_ULOG_MAX_QLEN + 1,
	EBT_ULOG_DEFAULT_QTHRESHOLD);
}

static void init(struct ebt_entry_watcher *watcher)
{
	struct ebt_ulog_info *uloginfo = (struct ebt_ulog_info *)watcher->data;

	uloginfo->prefix[0] = '\0';
	uloginfo->nlgroup = EBT_ULOG_DEFAULT_NLGROUP;
	uloginfo->cprange = CP_NO_LIMIT_N; /* Use default netlink buffer size */
	uloginfo->qthreshold = EBT_ULOG_DEFAULT_QTHRESHOLD;
}

#define OPT_PREFIX     0x01
#define OPT_NLGROUP    0x02
#define OPT_CPRANGE    0x04
#define OPT_QTHRESHOLD 0x08
#define OPT_ULOG       0x10
static int parse(int c, char **argv, int argc, const struct ebt_u_entry *entry,
   unsigned int *flags, struct ebt_entry_watcher **watcher)
{
	struct ebt_ulog_info *uloginfo;
	unsigned int i;
	char *end;

	uloginfo = (struct ebt_ulog_info *)(*watcher)->data;
	switch (c) {
	case ULOG_PREFIX:
		if (ebt_check_inverse2(optarg))
			goto inverse_invalid;
		ebt_check_option2(flags, OPT_PREFIX);
		if (strlen(optarg) > EBT_ULOG_PREFIX_LEN - 1)
			ebt_print_error("Prefix too long for ulog-prefix");
		strcpy(uloginfo->prefix, optarg);
		break;

	case ULOG_NLGROUP:
		if (ebt_check_inverse2(optarg))
			goto inverse_invalid;
		ebt_check_option2(flags, OPT_NLGROUP);
		i = strtoul(optarg, &end, 10);
		if (*end != '\0')
			ebt_print_error2("Problem with ulog-nlgroup: %s", optarg);
		if (i < 1 || i > EBT_ULOG_MAXNLGROUPS)
			ebt_print_error2("the ulog-nlgroup number must be between 1 and 32");
		uloginfo->nlgroup = i - 1;
		break;

	case ULOG_CPRANGE:
		if (ebt_check_inverse2(optarg))
			goto inverse_invalid;
		ebt_check_option2(flags, OPT_CPRANGE);
		i = strtoul(optarg, &end, 10);
		if (*end != '\0') {
			if (strcasecmp(optarg, CP_NO_LIMIT_S))
				ebt_print_error2("Problem with ulog-cprange: %s", optarg);
			i = CP_NO_LIMIT_N;
		}
		uloginfo->cprange = i;
		break;

	case ULOG_QTHRESHOLD:
		if (ebt_check_inverse2(optarg))
			goto inverse_invalid;
		ebt_check_option2(flags, OPT_QTHRESHOLD);
		i = strtoul(optarg, &end, 10);
		if (*end != '\0')
			ebt_print_error2("Problem with ulog-qthreshold: %s", optarg);
		if (i > EBT_ULOG_MAX_QLEN)
			ebt_print_error2("ulog-qthreshold argument %d exceeds the maximum of %d", i, EBT_ULOG_MAX_QLEN);
		uloginfo->qthreshold = i;
		break;
	case ULOG_ULOG:
		if (ebt_check_inverse(optarg))
			goto inverse_invalid;
		ebt_check_option2(flags, OPT_ULOG);
		break;

	default:
		return 0;
	}
	return 1;

inverse_invalid:
	ebt_print_error("The use of '!' makes no sense for the ulog watcher");
	return 1;
}

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

static void print(const struct ebt_u_entry *entry,
   const struct ebt_entry_watcher *watcher)
{
	struct ebt_ulog_info *uloginfo = (struct ebt_ulog_info *)watcher->data;

	printf("--ulog-prefix \"%s\" --ulog-nlgroup %d --ulog-cprange ",
	       uloginfo->prefix, uloginfo->nlgroup + 1);
	if (uloginfo->cprange == CP_NO_LIMIT_N)
		printf(CP_NO_LIMIT_S);
	else
		printf("%d", uloginfo->cprange);
	printf(" --ulog-qthreshold %d ", uloginfo->qthreshold);
}

static int compare(const struct ebt_entry_watcher *w1,
   const struct ebt_entry_watcher *w2)
{
	struct ebt_ulog_info *uloginfo1 = (struct ebt_ulog_info *)w1->data;
	struct ebt_ulog_info *uloginfo2 = (struct ebt_ulog_info *)w2->data;

	if (uloginfo1->nlgroup != uloginfo2->nlgroup ||
	    uloginfo1->cprange != uloginfo2->cprange ||
	    uloginfo1->qthreshold != uloginfo2->qthreshold ||
	    strcmp(uloginfo1->prefix, uloginfo2->prefix))
		return 0;
	return 1;
}

static struct ebt_u_watcher ulog_watcher =
{
	.name		= "ulog",
	.size		= sizeof(struct ebt_ulog_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_watcher(&ulog_watcher);
}
