/* Shared library add-on to iptables to add CLUSTERIP target support. 
 * (C) 2003 by Harald Welte <laforge@gnumonks.org>
 *
 * Development of this code was funded by SuSE AG, http://www.suse.com/
 */
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <getopt.h>
#include <stddef.h>

#if defined(__GLIBC__) && __GLIBC__ == 2
#include <net/ethernet.h>
#else
#include <linux/if_ether.h>
#endif

#include <iptables.h>
#include <linux/netfilter_ipv4/ip_tables.h>
#include "../include/linux/netfilter_ipv4/ipt_CLUSTERIP.h"

static void CLUSTERIP_help(void)
{
	printf(
"CLUSTERIP target options:\n"
"  --new			 Create a new ClusterIP\n"
"  --hashmode <mode>		 Specify hashing mode\n"
"					sourceip\n"
"					sourceip-sourceport\n"
"					sourceip-sourceport-destport\n"
"  --clustermac <mac>		 Set clusterIP MAC address\n"
"  --total-nodes <num>		 Set number of total nodes in cluster\n"
"  --local-node <num>		 Set the local node number\n"
"  --hash-init <num>		 Set init value of the Jenkins hash\n");
}

#define	PARAM_NEW	0x0001
#define PARAM_HMODE	0x0002
#define PARAM_MAC	0x0004
#define PARAM_TOTALNODE	0x0008
#define PARAM_LOCALNODE	0x0010
#define PARAM_HASHINIT	0x0020

static const struct option CLUSTERIP_opts[] = {
	{ "new", 0, NULL, '1' },
	{ "hashmode", 1, NULL, '2' },
	{ "clustermac", 1, NULL, '3' },
	{ "total-nodes", 1, NULL, '4' },
	{ "local-node", 1, NULL, '5' },
	{ "hash-init", 1, NULL, '6' },
	{ .name = NULL }
};

static void
parse_mac(const char *mac, char *macbuf)
{
	unsigned int i = 0;

	if (strlen(mac) != ETH_ALEN*3-1)
		exit_error(PARAMETER_PROBLEM, "Bad mac address `%s'", mac);

	for (i = 0; i < ETH_ALEN; i++) {
		long number;
		char *end;

		number = strtol(mac + i*3, &end, 16);

		if (end == mac + i*3 + 2
		    && number >= 0
		    && number <= 255)
			macbuf[i] = number;
		else
			exit_error(PARAMETER_PROBLEM,
				   "Bad mac address `%s'", mac);
	}
}

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

	switch (c) {
		unsigned int num;
	case '1':
		cipinfo->flags |= CLUSTERIP_FLAG_NEW;
		if (*flags & PARAM_NEW)
			exit_error(PARAMETER_PROBLEM, "Can only specify `--new' once\n");
		*flags |= PARAM_NEW;
		break;
	case '2':
		if (!(*flags & PARAM_NEW))
			exit_error(PARAMETER_PROBLEM, "Can only specify hashmode combined with `--new'\n");
		if (*flags & PARAM_HMODE)
			exit_error(PARAMETER_PROBLEM, "Can only specify hashmode once\n");
		if (!strcmp(optarg, "sourceip"))
			cipinfo->hash_mode = CLUSTERIP_HASHMODE_SIP;
		else if (!strcmp(optarg, "sourceip-sourceport"))
			cipinfo->hash_mode = CLUSTERIP_HASHMODE_SIP_SPT;
		else if (!strcmp(optarg, "sourceip-sourceport-destport"))
			cipinfo->hash_mode = CLUSTERIP_HASHMODE_SIP_SPT_DPT;
		else
			exit_error(PARAMETER_PROBLEM, "Unknown hashmode `%s'\n",
				   optarg);
		*flags |= PARAM_HMODE;
		break;
	case '3':
		if (!(*flags & PARAM_NEW))
			exit_error(PARAMETER_PROBLEM, "Can only specify MAC combined with `--new'\n");
		if (*flags & PARAM_MAC)
			exit_error(PARAMETER_PROBLEM, "Can only specify MAC once\n");
		parse_mac(optarg, (char *)cipinfo->clustermac);
		if (!(cipinfo->clustermac[0] & 0x01))
			exit_error(PARAMETER_PROBLEM, "MAC has to be a multicast ethernet address\n");
		*flags |= PARAM_MAC;
		break;
	case '4':
		if (!(*flags & PARAM_NEW))
			exit_error(PARAMETER_PROBLEM, "Can only specify node number combined with `--new'\n");
		if (*flags & PARAM_TOTALNODE)
			exit_error(PARAMETER_PROBLEM, "Can only specify total node number once\n");
		if (string_to_number(optarg, 1, CLUSTERIP_MAX_NODES, &num) < 0)
			exit_error(PARAMETER_PROBLEM, "Unable to parse `%s'\n", optarg);
		cipinfo->num_total_nodes = (u_int16_t)num;
		*flags |= PARAM_TOTALNODE;
		break;
	case '5':
		if (!(*flags & PARAM_NEW))
			exit_error(PARAMETER_PROBLEM, "Can only specify node number combined with `--new'\n");
		if (*flags & PARAM_LOCALNODE)
			exit_error(PARAMETER_PROBLEM, "Can only specify local node number once\n");
		if (string_to_number(optarg, 1, CLUSTERIP_MAX_NODES, &num) < 0)
			exit_error(PARAMETER_PROBLEM, "Unable to parse `%s'\n", optarg);
		cipinfo->num_local_nodes = 1;
		cipinfo->local_nodes[0] = (u_int16_t)num;
		*flags |= PARAM_LOCALNODE;
		break;
	case '6':
		if (!(*flags & PARAM_NEW))
			exit_error(PARAMETER_PROBLEM, "Can only specify hash init value combined with `--new'\n");
		if (*flags & PARAM_HASHINIT)
			exit_error(PARAMETER_PROBLEM, "Can specify hash init value only once\n");
		if (string_to_number(optarg, 0, UINT_MAX, &num) < 0)
			exit_error(PARAMETER_PROBLEM, "Unable to parse `%s'\n", optarg);
		cipinfo->hash_initval = num;
		*flags |= PARAM_HASHINIT;
		break;
	default:
		return 0;
	}

	return 1;
}

static void CLUSTERIP_check(unsigned int flags)
{
	if (flags == 0)
		return;

	if ((flags & (PARAM_NEW|PARAM_HMODE|PARAM_MAC|PARAM_TOTALNODE|PARAM_LOCALNODE))
		== (PARAM_NEW|PARAM_HMODE|PARAM_MAC|PARAM_TOTALNODE|PARAM_LOCALNODE))
		return;

	exit_error(PARAMETER_PROBLEM, "CLUSTERIP target: Invalid parameter combination\n");
}

static char *hashmode2str(enum clusterip_hashmode mode)
{
	char *retstr;
	switch (mode) {
		case CLUSTERIP_HASHMODE_SIP:
			retstr = "sourceip";
			break;
		case CLUSTERIP_HASHMODE_SIP_SPT:
			retstr = "sourceip-sourceport";
			break;
		case CLUSTERIP_HASHMODE_SIP_SPT_DPT:
			retstr = "sourceip-sourceport-destport";
			break;
		default:
			retstr = "unknown-error";
			break;
	}
	return retstr;
}

static char *mac2str(const u_int8_t mac[ETH_ALEN])
{
	static char buf[ETH_ALEN*3];
	sprintf(buf, "%02X:%02X:%02X:%02X:%02X:%02X",
		mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
	return buf;
}
			

/* Prints out the targinfo. */
static void CLUSTERIP_print(const void *ip,
                            const struct xt_entry_target *target, int numeric)
{
	const struct ipt_clusterip_tgt_info *cipinfo =
		(const struct ipt_clusterip_tgt_info *)target->data;
	
	if (!cipinfo->flags & CLUSTERIP_FLAG_NEW) {
		printf("CLUSTERIP");
		return;
	}

	printf("CLUSTERIP hashmode=%s clustermac=%s total_nodes=%u local_node=%u hash_init=%u", 
		hashmode2str(cipinfo->hash_mode),
		mac2str(cipinfo->clustermac),
		cipinfo->num_total_nodes,
		cipinfo->local_nodes[0],
		cipinfo->hash_initval);
}

/* Saves the union ipt_targinfo in parsable form to stdout. */
static void CLUSTERIP_save(const void *ip, const struct xt_entry_target *target)
{
	const struct ipt_clusterip_tgt_info *cipinfo =
		(const struct ipt_clusterip_tgt_info *)target->data;

	/* if this is not a new entry, we don't need to save target
	 * parameters */
	if (!cipinfo->flags & CLUSTERIP_FLAG_NEW)
		return;

	printf("--new --hashmode %s --clustermac %s --total-nodes %d --local-node %d --hash-init %u",
	       hashmode2str(cipinfo->hash_mode),
	       mac2str(cipinfo->clustermac),
	       cipinfo->num_total_nodes,
	       cipinfo->local_nodes[0],
	       cipinfo->hash_initval);
}

static struct xtables_target clusterip_tg_reg = {
	.name		= "CLUSTERIP",
	.version	= XTABLES_VERSION,
	.family		= PF_INET,
	.size		= XT_ALIGN(sizeof(struct ipt_clusterip_tgt_info)),
	.userspacesize	= offsetof(struct ipt_clusterip_tgt_info, config),
 	.help		= CLUSTERIP_help,
	.parse		= CLUSTERIP_parse,
	.final_check	= CLUSTERIP_check,
	.print		= CLUSTERIP_print,
	.save		= CLUSTERIP_save,
	.extra_opts	= CLUSTERIP_opts,
};

void _init(void)
{
	xtables_register_target(&clusterip_tg_reg);
}
