/*
 * (C) 2009 by Pablo Neira Ayuso <pablo@netfilter.org>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 */
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <getopt.h>
#include <stddef.h>

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

/* hack to keep for check */
static unsigned int total_nodes;
static unsigned int node_mask;

static void
cluster_help(void)
{
	printf(
"cluster match options:\n"
"  --cluster-total-nodes <num>		Set number of total nodes in cluster\n"
"  [!] --cluster-local-node <num>	Set the local node number\n"
"  [!] --cluster-local-nodemask <num>	Set the local node mask\n"
"  --cluster-hash-seed <num>		Set seed value of the Jenkins hash\n");
}

enum {
	CLUSTER_OPT_TOTAL_NODES,
	CLUSTER_OPT_LOCAL_NODE,
	CLUSTER_OPT_NODE_MASK,
	CLUSTER_OPT_HASH_SEED,
};

static const struct option cluster_opts[] = {
	{ "cluster-total-nodes", 	1, NULL, CLUSTER_OPT_TOTAL_NODES },
	{ "cluster-local-node", 	1, NULL, CLUSTER_OPT_LOCAL_NODE },
	{ "cluster-local-nodemask",	1, NULL, CLUSTER_OPT_NODE_MASK },
	{ "cluster-hash-seed",		1, NULL, CLUSTER_OPT_HASH_SEED },
	{ .name = NULL }
};

static int 
cluster_parse(int c, char **argv, int invert, unsigned int *flags,
	      const void *entry, struct xt_entry_match **match)
{
	struct xt_cluster_match_info *info = (void *)(*match)->data;
	unsigned int num;

	switch (c) {
	case CLUSTER_OPT_TOTAL_NODES:
		if (*flags & (1 << c)) {
			xtables_error(PARAMETER_PROBLEM,
				      "Can only specify "
				      "`--cluster-total-nodes' once");
		}
		if (!xtables_strtoui(optarg, NULL, &num, 1,
				     XT_CLUSTER_NODES_MAX)) {
			xtables_error(PARAMETER_PROBLEM,
				      "Unable to parse `%s' in "
				      "`--cluster-total-nodes'", optarg);
		}
		total_nodes = num;
		info->total_nodes = total_nodes = num;
		*flags |= 1 << c;
		break;
	case CLUSTER_OPT_LOCAL_NODE:
		if (*flags & (1 << c)) {
			xtables_error(PARAMETER_PROBLEM,
				      "Can only specify "
				      "`--cluster-local-node' once");
		}
		if (*flags & (1 << CLUSTER_OPT_NODE_MASK)) {
			xtables_error(PARAMETER_PROBLEM, "You cannot use "
				      "`--cluster-local-nodemask' and "
				      "`--cluster-local-node'");
		}
		xtables_check_inverse(optarg, &invert, &optind, 0);

		if (!xtables_strtoui(optarg, NULL, &num, 1,
				     XT_CLUSTER_NODES_MAX)) {
			xtables_error(PARAMETER_PROBLEM,
				      "Unable to parse `%s' in "
				      "`--cluster-local-node'", optarg);
		}
		if (invert)
			info->flags |= (1 << XT_CLUSTER_F_INV);

		info->node_mask = node_mask = (1 << (num - 1));
		*flags |= 1 << c;
		break;
	case CLUSTER_OPT_NODE_MASK:
		if (*flags & (1 << c)) {
			xtables_error(PARAMETER_PROBLEM,
				      "Can only specify "
				      "`--cluster-local-node' once");
		}
		if (*flags & (1 << CLUSTER_OPT_LOCAL_NODE)) {
			xtables_error(PARAMETER_PROBLEM, "You cannot use "
				      "`--cluster-local-nodemask' and "
				      "`--cluster-local-node'");
		}
		xtables_check_inverse(optarg, &invert, &optind, 0);

		if (!xtables_strtoui(optarg, NULL, &num, 1,
				     XT_CLUSTER_NODES_MAX)) {
			xtables_error(PARAMETER_PROBLEM,
				      "Unable to parse `%s' in "
				      "`--cluster-local-node'", optarg);
		}
		if (invert)
			info->flags |= (1 << XT_CLUSTER_F_INV);

		info->node_mask = node_mask = num;
		*flags |= 1 << c;
		break;

	case CLUSTER_OPT_HASH_SEED:
		if (*flags & (1 << c)) {
			xtables_error(PARAMETER_PROBLEM,
				      "Can only specify "
				      "`--cluster-hash-seed' once");
		}
		if (!xtables_strtoui(optarg, NULL, &num, 0, UINT32_MAX)) {
			xtables_error(PARAMETER_PROBLEM,
				      "Unable to parse `%s'", optarg);
		}
		info->hash_seed = num;
		*flags |= 1 << c;
		break;
	default:
		return 0;
	}

	return 1;
}

static void
cluster_check(unsigned int flags)
{
	if ((flags & ((1 << CLUSTER_OPT_TOTAL_NODES) |
		      (1 << CLUSTER_OPT_LOCAL_NODE) |
		      (1 << CLUSTER_OPT_HASH_SEED)))
		== ((1 << CLUSTER_OPT_TOTAL_NODES) |
		    (1 << CLUSTER_OPT_LOCAL_NODE) |
		    (1 << CLUSTER_OPT_HASH_SEED))) {
		if (node_mask >= (1ULL << total_nodes)) {
			xtables_error(PARAMETER_PROBLEM,
				      "cluster match: "
				      "`--cluster-local-node' "
				      "must be <= `--cluster-total-nodes'");
		}
		return;
	}
	if ((flags & ((1 << CLUSTER_OPT_TOTAL_NODES) |
		      (1 << CLUSTER_OPT_NODE_MASK) |
		      (1 << CLUSTER_OPT_HASH_SEED)))
		== ((1 << CLUSTER_OPT_TOTAL_NODES) |
		    (1 << CLUSTER_OPT_NODE_MASK) |
		    (1 << CLUSTER_OPT_HASH_SEED))) {
		if (node_mask >= (1ULL << total_nodes)) {
			xtables_error(PARAMETER_PROBLEM,
				      "cluster match: "
				      "`--cluster-local-nodemask' too big "
				      "for `--cluster-total-nodes'");
		}
		return;
	}
	if (!(flags & (1 << CLUSTER_OPT_TOTAL_NODES))) {
		xtables_error(PARAMETER_PROBLEM,
			      "cluster match: `--cluster-total-nodes' "
			      "is missing");
	}
	if (!(flags & (1 << CLUSTER_OPT_HASH_SEED))) {
		xtables_error(PARAMETER_PROBLEM,
			      "cluster match: `--cluster-hash-seed' "
			      "is missing");
	}
	if (!(flags & ((1 << (CLUSTER_OPT_LOCAL_NODE) |
		       (1 << (CLUSTER_OPT_NODE_MASK)))))) {
		xtables_error(PARAMETER_PROBLEM,
			      "cluster match: `--cluster-local-node' or"
			      "`--cluster-local-nodemask' is missing");
	}
}

static void
cluster_print(const void *ip, const struct xt_entry_match *match, int numeric)
{
	const struct xt_cluster_match_info *info = (void *)match->data;

	printf("cluster ");
	if (info->flags & XT_CLUSTER_F_INV)
		printf("!node_mask=0x%08x ", info->node_mask);
	else
		printf("node_mask=0x%08x ", info->node_mask);

	printf("total_nodes=%u hash_seed=0x%08x ", 
		info->total_nodes, info->hash_seed);
}

static void
cluster_save(const void *ip, const struct xt_entry_match *match)
{
	const struct xt_cluster_match_info *info = (void *)match->data;

	if (info->flags & XT_CLUSTER_F_INV)
		printf("! --cluster-local-nodemask 0x%08x ", info->node_mask);
	else
		printf("--cluster-local-nodemask 0x%08x ", info->node_mask);

	printf("--cluster-total-nodes %u --cluster-hash-seed 0x%08x ",
		info->total_nodes, info->hash_seed);
}

static struct xtables_match cluster_mt_reg = {
	.family		= NFPROTO_UNSPEC,
	.name		= "cluster",
	.version	= XTABLES_VERSION,
	.size		= XT_ALIGN(sizeof(struct xt_cluster_match_info)),
	.userspacesize  = XT_ALIGN(sizeof(struct xt_cluster_match_info)),
 	.help		= cluster_help,
	.parse		= cluster_parse,
	.final_check	= cluster_check,
	.print		= cluster_print,
	.save		= cluster_save,
	.extra_opts	= cluster_opts,
};

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