/* ebt_nflog
 *
 * Authors:
 * Peter Warasin <peter@endian.com>
 *
 *  February, 2008
 *
 * Based on:
 *  ebt_ulog.c, (C) 2004, Bart De Schuymer <bdschuym@pandora.be>
 *  libxt_NFLOG.c
 */

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

enum {
	NFLOG_GROUP = 0x1,
	NFLOG_PREFIX = 0x2,
	NFLOG_RANGE = 0x4,
	NFLOG_THRESHOLD = 0x8,
	NFLOG_NFLOG = 0x16,
};

static const struct option nflog_opts[] = {
	{"nflog-group", required_argument, NULL, NFLOG_GROUP},
	{"nflog-prefix", required_argument, NULL, NFLOG_PREFIX},
	{"nflog-range", required_argument, NULL, NFLOG_RANGE},
	{"nflog-threshold", required_argument, NULL, NFLOG_THRESHOLD},
	{"nflog", no_argument, NULL, NFLOG_NFLOG},
	{.name = NULL}
};

static void nflog_help()
{
	printf("nflog options:\n"
	       "--nflog               : use the default nflog parameters\n"
	       "--nflog-prefix prefix : Prefix string for log message\n"
	       "--nflog-group group   : NETLINK group used for logging\n"
	       "--nflog-range range   : Number of byte to copy\n"
	       "--nflog-threshold     : Message threshold of"
	       "in-kernel queue\n");
}

static void init(struct ebt_entry_watcher *watcher)
{
	struct ebt_nflog_info *info = (struct ebt_nflog_info *)watcher->data;

	info->prefix[0] = '\0';
	info->group = EBT_NFLOG_DEFAULT_GROUP;
	info->threshold = EBT_NFLOG_DEFAULT_THRESHOLD;
}

static int nflog_parse(int c, char **argv, int argc,
		       const struct ebt_u_entry *entry, unsigned int *flags,
		       struct ebt_entry_watcher **watcher)
{
	struct ebt_nflog_info *info;
	unsigned int i;
	char *end;

	info = (struct ebt_nflog_info *)(*watcher)->data;
	switch (c) {
	case NFLOG_PREFIX:
		if (ebt_check_inverse2(optarg))
			goto inverse_invalid;
		ebt_check_option2(flags, NFLOG_PREFIX);
		if (strlen(optarg) > EBT_NFLOG_PREFIX_SIZE - 1)
			ebt_print_error("Prefix too long for nflog-prefix");
		strcpy(info->prefix, optarg);
		break;

	case NFLOG_GROUP:
		if (ebt_check_inverse2(optarg))
			goto inverse_invalid;
		ebt_check_option2(flags, NFLOG_GROUP);
		i = strtoul(optarg, &end, 10);
		if (*end != '\0')
			ebt_print_error2("--nflog-group must be a number!");
		info->group = i;
		break;

	case NFLOG_RANGE:
		if (ebt_check_inverse2(optarg))
			goto inverse_invalid;
		ebt_check_option2(flags, NFLOG_RANGE);
		i = strtoul(optarg, &end, 10);
		if (*end != '\0')
			ebt_print_error2("--nflog-range must be a number!");
		info->len = i;
		break;

	case NFLOG_THRESHOLD:
		if (ebt_check_inverse2(optarg))
			goto inverse_invalid;
		ebt_check_option2(flags, NFLOG_THRESHOLD);
		i = strtoul(optarg, &end, 10);
		if (*end != '\0')
			ebt_print_error2("--nflog-threshold must be a number!");
		info->threshold = i;
		break;
	case NFLOG_NFLOG:
		if (ebt_check_inverse(optarg))
			goto inverse_invalid;
		ebt_check_option2(flags, NFLOG_NFLOG);
		break;

	default:
		return 0;
	}
	return 1;

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

static void nflog_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 nflog_print(const struct ebt_u_entry *entry,
			const struct ebt_entry_watcher *watcher)
{
	struct ebt_nflog_info *info = (struct ebt_nflog_info *)watcher->data;

	if (info->prefix[0] != '\0')
		printf("--nflog-prefix \"%s\"", info->prefix);
	if (info->group)
		printf("--nflog-group %d ", info->group);
	if (info->len)
		printf("--nflog-range %d", info->len);
	if (info->threshold != EBT_NFLOG_DEFAULT_THRESHOLD)
		printf(" --nflog-threshold %d ", info->threshold);
}

static int nflog_compare(const struct ebt_entry_watcher *w1,
			 const struct ebt_entry_watcher *w2)
{
	struct ebt_nflog_info *info1 = (struct ebt_nflog_info *)w1->data;
	struct ebt_nflog_info *info2 = (struct ebt_nflog_info *)w2->data;

	if (info1->group != info2->group ||
	    info1->len != info2->len ||
	    info1->threshold != info2->threshold ||
	    strcmp(info1->prefix, info2->prefix))
		return 0;
	return 1;
}

static struct ebt_u_watcher nflog_watcher = {
	.name = "nflog",
	.size = sizeof(struct ebt_nflog_info),
	.help = nflog_help,
	.init = init,
	.parse = nflog_parse,
	.final_check = nflog_final_check,
	.print = nflog_print,
	.compare = nflog_compare,
	.extra_ops = nflog_opts,
};

static void _INIT(void)
{
	ebt_register_watcher(&nflog_watcher);
}
