/* Shared library add-on to iptables for NFQ
 *
 * (C) 2005 by Harald Welte <laforge@netfilter.org>
 *
 * This program is distributed under the terms of GNU GPL v2, 1991
 *
 */
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <getopt.h>

#include <xtables.h>
#include <linux/netfilter/x_tables.h>
#include <linux/netfilter/xt_NFQUEUE.h>

static void NFQUEUE_help(void)
{
	printf(
"NFQUEUE target options\n"
"  --queue-num value		Send packet to QUEUE number <value>.\n"
"  		                Valid queue numbers are 0-65535\n"
);
}

static void NFQUEUE_help_v1(void)
{
	NFQUEUE_help();
	printf(
"  --queue-balance first:last	Balance flows between queues <value> to <value>.\n");
}

static const struct option NFQUEUE_opts[] = {
	{ "queue-num", 1, NULL, 'F' },
	{ "queue-balance", 1, NULL, 'B' },
	{ .name = NULL }
};

static void exit_badqueue(const char *s)
{
	xtables_error(PARAMETER_PROBLEM, "Invalid queue number `%s'\n", s);
}

static void
parse_num(const char *s, struct xt_NFQ_info *tinfo)
{
	unsigned int num;

	if (!xtables_strtoui(s, NULL, &num, 0, UINT16_MAX))
		exit_badqueue(s);

	tinfo->queuenum = num;
}

static int
NFQUEUE_parse(int c, char **argv, int invert, unsigned int *flags,
              const void *entry, struct xt_entry_target **target)
{
	struct xt_NFQ_info *tinfo
		= (struct xt_NFQ_info *)(*target)->data;

	switch (c) {
	case 'F':
		if (*flags)
			xtables_error(PARAMETER_PROBLEM, "NFQUEUE target: "
				   "Only use --queue-num ONCE!");
		parse_num(optarg, tinfo);
		break;
	case 'B':
		xtables_error(PARAMETER_PROBLEM, "NFQUEUE target: "
				   "--queue-balance not supported (kernel too old?)");
	default:
		return 0;
	}

	return 1;
}

static int
NFQUEUE_parse_v1(int c, char **argv, int invert, unsigned int *flags,
                 const void *entry, struct xt_entry_target **target)
{
	struct xt_NFQ_info_v1 *info = (void *)(*target)->data;
	char *colon;
	unsigned int firstqueue, lastqueue;

	switch (c) {
	case 'F': /* fallthrough */
	case 'B':
		if (*flags)
			xtables_error(PARAMETER_PROBLEM, "NFQUEUE target: "
				   "Only use --queue-num ONCE!");

		if (!xtables_strtoui(optarg, &colon, &firstqueue, 0, UINT16_MAX))
			exit_badqueue(optarg);

		info->queuenum = firstqueue;

		if (c == 'F') {
			if (*colon)
				exit_badqueue(optarg);
			break;
		}

		if (*colon != ':')
			xtables_error(PARAMETER_PROBLEM, "Bad range \"%s\"", optarg);

		if (!xtables_strtoui(colon + 1, NULL, &lastqueue, 1, UINT16_MAX))
			exit_badqueue(optarg);

		if (firstqueue >= lastqueue)
			xtables_error(PARAMETER_PROBLEM, "%u should be less than %u",
							firstqueue, lastqueue);
		info->queues_total = lastqueue - firstqueue + 1;
		break;
	default:
		return 0;
	}

	return 1;
}

static void NFQUEUE_print(const void *ip,
                          const struct xt_entry_target *target, int numeric)
{
	const struct xt_NFQ_info *tinfo =
		(const struct xt_NFQ_info *)target->data;
	printf("NFQUEUE num %u", tinfo->queuenum);
}

static void NFQUEUE_print_v1(const void *ip,
                             const struct xt_entry_target *target, int numeric)
{
	const struct xt_NFQ_info_v1 *tinfo = (const void *)target->data;
	unsigned int last = tinfo->queues_total;

	if (last > 1) {
		last += tinfo->queuenum - 1;
		printf("NFQUEUE balance %u:%u", tinfo->queuenum, last);
	} else {
		printf("NFQUEUE num %u", tinfo->queuenum);
	}
}

static void NFQUEUE_save(const void *ip, const struct xt_entry_target *target)
{
	const struct xt_NFQ_info *tinfo =
		(const struct xt_NFQ_info *)target->data;

	printf("--queue-num %u ", tinfo->queuenum);
}

static void NFQUEUE_save_v1(const void *ip, const struct xt_entry_target *target)
{
	const struct xt_NFQ_info_v1 *tinfo = (const void *)target->data;
	unsigned int last = tinfo->queues_total;

	if (last > 1) {
		last += tinfo->queuenum - 1;
		printf("--queue-balance %u:%u ", tinfo->queuenum, last);
	} else {
		printf("--queue-num %u ", tinfo->queuenum);
	}
}

static void NFQUEUE_init_v1(struct xt_entry_target *t)
{
	struct xt_NFQ_info_v1 *tinfo = (void *)t->data;
	tinfo->queues_total = 1;
}

static struct xtables_target nfqueue_target = {
	.family		= NFPROTO_UNSPEC,
	.name		= "NFQUEUE",
	.version	= XTABLES_VERSION,
	.size		= XT_ALIGN(sizeof(struct xt_NFQ_info)),
	.userspacesize	= XT_ALIGN(sizeof(struct xt_NFQ_info)),
	.help		= NFQUEUE_help,
	.parse		= NFQUEUE_parse,
	.print		= NFQUEUE_print,
	.save		= NFQUEUE_save,
	.extra_opts	= NFQUEUE_opts
};

static struct xtables_target nfqueue_target_v1 = {
	.family		= NFPROTO_UNSPEC,
	.revision	= 1,
	.name		= "NFQUEUE",
	.version	= XTABLES_VERSION,
	.size		= XT_ALIGN(sizeof(struct xt_NFQ_info_v1)),
	.userspacesize	= XT_ALIGN(sizeof(struct xt_NFQ_info_v1)),
	.help		= NFQUEUE_help_v1,
	.init		= NFQUEUE_init_v1,
	.parse		= NFQUEUE_parse_v1,
	.print		= NFQUEUE_print_v1,
	.save		= NFQUEUE_save_v1,
	.extra_opts	= NFQUEUE_opts,
};

void _init(void)
{
	xtables_register_target(&nfqueue_target);
	xtables_register_target(&nfqueue_target_v1);
}
