/*
 * Shared library add-on to iptables to add IPVS matching.
 *
 * Detailed doc is in the kernel module source net/netfilter/xt_ipvs.c
 *
 * Author: Hannes Eder <heder@google.com>
 */
#include <stdbool.h>
#include <stdio.h>
#include <string.h>
#include <xtables.h>
#include <linux/ip_vs.h>
#include <linux/netfilter/xt_ipvs.h>

enum {
	/* For xt_ipvs: make sure this matches up with %XT_IPVS_*'s order */
	O_IPVS = 0,
	O_VPROTO,
	O_VADDR,
	O_VPORT,
	O_VDIR,
	O_VMETHOD,
	O_VPORTCTL,
};

#define s struct xt_ipvs_mtinfo
static const struct xt_option_entry ipvs_mt_opts[] = {
	{.name = "ipvs", .id = O_IPVS, .type = XTTYPE_NONE,
	 .flags = XTOPT_INVERT},
	{.name = "vproto", .id = O_VPROTO, .type = XTTYPE_PROTOCOL,
	 .flags = XTOPT_INVERT | XTOPT_PUT, XTOPT_POINTER(s, l4proto)},
	{.name = "vaddr", .id = O_VADDR, .type = XTTYPE_HOSTMASK,
	 .flags = XTOPT_INVERT},
	{.name = "vport", .id = O_VPORT, .type = XTTYPE_PORT,
	 .flags = XTOPT_NBO | XTOPT_INVERT | XTOPT_PUT,
	 XTOPT_POINTER(s, vport)},
	{.name = "vdir", .id = O_VDIR, .type = XTTYPE_STRING},
	{.name = "vmethod", .id = O_VMETHOD, .type = XTTYPE_STRING,
	 .flags = XTOPT_INVERT},
	{.name = "vportctl", .id = O_VPORTCTL, .type = XTTYPE_PORT,
	 .flags = XTOPT_NBO | XTOPT_INVERT | XTOPT_PUT,
	 XTOPT_POINTER(s, vportctl)},
	XTOPT_TABLEEND,
};
#undef s

static void ipvs_mt_help(void)
{
	printf(
"IPVS match options:\n"
"[!] --ipvs                      packet belongs to an IPVS connection\n"
"\n"
"Any of the following options implies --ipvs (even negated)\n"
"[!] --vproto protocol           VIP protocol to match; by number or name,\n"
"                                e.g. \"tcp\"\n"
"[!] --vaddr address[/mask]      VIP address to match\n"
"[!] --vport port                VIP port to match; by number or name,\n"
"                                e.g. \"http\"\n"
"    --vdir {ORIGINAL|REPLY}     flow direction of packet\n"
"[!] --vmethod {GATE|IPIP|MASQ}  IPVS forwarding method used\n"
"[!] --vportctl port             VIP port of the controlling connection to\n"
"                                match, e.g. 21 for FTP\n"
		);
}

static void ipvs_mt_parse(struct xt_option_call *cb)
{
	struct xt_ipvs_mtinfo *data = cb->data;

	xtables_option_parse(cb);
	switch (cb->entry->id) {
	case O_VADDR:
		memcpy(&data->vaddr, &cb->val.haddr, sizeof(cb->val.haddr));
		memcpy(&data->vmask, &cb->val.hmask, sizeof(cb->val.hmask));
		break;
	case O_VDIR:
		if (strcasecmp(cb->arg, "ORIGINAL") == 0) {
			data->bitmask |= XT_IPVS_DIR;
			data->invert   &= ~XT_IPVS_DIR;
		} else if (strcasecmp(cb->arg, "REPLY") == 0) {
			data->bitmask |= XT_IPVS_DIR;
			data->invert  |= XT_IPVS_DIR;
		} else {
			xtables_param_act(XTF_BAD_VALUE,
					  "ipvs", "--vdir", cb->arg);
		}
		break;
	case O_VMETHOD:
		if (strcasecmp(cb->arg, "GATE") == 0)
			data->fwd_method = IP_VS_CONN_F_DROUTE;
		else if (strcasecmp(cb->arg, "IPIP") == 0)
			data->fwd_method = IP_VS_CONN_F_TUNNEL;
		else if (strcasecmp(cb->arg, "MASQ") == 0)
			data->fwd_method = IP_VS_CONN_F_MASQ;
		else
			xtables_param_act(XTF_BAD_VALUE,
					  "ipvs", "--vmethod", cb->arg);
		break;
	}
	data->bitmask |= 1 << cb->entry->id;
	if (cb->invert)
		data->invert |= 1 << cb->entry->id;
}

static void ipvs_mt_check(struct xt_fcheck_call *cb)
{
	struct xt_ipvs_mtinfo *info = cb->data;

	if (cb->xflags == 0)
		xtables_error(PARAMETER_PROBLEM,
			      "IPVS: At least one option is required");
	if (info->bitmask & XT_IPVS_ONCE_MASK) {
		if (info->invert & XT_IPVS_IPVS_PROPERTY)
			xtables_error(PARAMETER_PROBLEM,
				      "! --ipvs cannot be together with"
				      " other options");
		info->bitmask |= XT_IPVS_IPVS_PROPERTY;
	}
}

/* Shamelessly copied from libxt_conntrack.c */
static void ipvs_mt_dump_addr(const union nf_inet_addr *addr,
			      const union nf_inet_addr *mask,
			      unsigned int family, bool numeric)
{
	if (family == NFPROTO_IPV4) {
		if (!numeric && addr->ip == 0) {
			printf(" anywhere");
			return;
		}
		if (numeric)
			printf(" %s%s",
			       xtables_ipaddr_to_numeric(&addr->in),
			       xtables_ipmask_to_numeric(&mask->in));
		else
			printf(" %s%s",
			       xtables_ipaddr_to_anyname(&addr->in),
			       xtables_ipmask_to_numeric(&mask->in));
	} else if (family == NFPROTO_IPV6) {
		if (!numeric && addr->ip6[0] == 0 && addr->ip6[1] == 0 &&
		    addr->ip6[2] == 0 && addr->ip6[3] == 0) {
			printf(" anywhere");
			return;
		}
		if (numeric)
			printf(" %s%s",
			       xtables_ip6addr_to_numeric(&addr->in6),
			       xtables_ip6mask_to_numeric(&mask->in6));
		else
			printf(" %s%s",
			       xtables_ip6addr_to_anyname(&addr->in6),
			       xtables_ip6mask_to_numeric(&mask->in6));
	}
}

static void ipvs_mt_dump(const void *ip, const struct xt_ipvs_mtinfo *data,
			 unsigned int family, bool numeric, const char *prefix)
{
	if (data->bitmask == XT_IPVS_IPVS_PROPERTY) {
		if (data->invert & XT_IPVS_IPVS_PROPERTY)
			printf(" !");
		printf(" %sipvs", prefix);
	}

	if (data->bitmask & XT_IPVS_PROTO) {
		if (data->invert & XT_IPVS_PROTO)
			printf(" !");
		printf(" %svproto %u", prefix, data->l4proto);
	}

	if (data->bitmask & XT_IPVS_VADDR) {
		if (data->invert & XT_IPVS_VADDR)
			printf(" !");

		printf(" %svaddr", prefix);
		ipvs_mt_dump_addr(&data->vaddr, &data->vmask, family, numeric);
	}

	if (data->bitmask & XT_IPVS_VPORT) {
		if (data->invert & XT_IPVS_VPORT)
			printf(" !");

		printf(" %svport %u", prefix, ntohs(data->vport));
	}

	if (data->bitmask & XT_IPVS_DIR) {
		if (data->invert & XT_IPVS_DIR)
			printf(" %svdir REPLY", prefix);
		else
			printf(" %svdir ORIGINAL", prefix);
	}

	if (data->bitmask & XT_IPVS_METHOD) {
		if (data->invert & XT_IPVS_METHOD)
			printf(" !");

		printf(" %svmethod", prefix);
		switch (data->fwd_method) {
		case IP_VS_CONN_F_DROUTE:
			printf(" GATE");
			break;
		case IP_VS_CONN_F_TUNNEL:
			printf(" IPIP");
			break;
		case IP_VS_CONN_F_MASQ:
			printf(" MASQ");
			break;
		default:
			/* Hu? */
			printf(" UNKNOWN");
			break;
		}
	}

	if (data->bitmask & XT_IPVS_VPORTCTL) {
		if (data->invert & XT_IPVS_VPORTCTL)
			printf(" !");

		printf(" %svportctl %u", prefix, ntohs(data->vportctl));
	}
}

static void ipvs_mt4_print(const void *ip, const struct xt_entry_match *match,
			   int numeric)
{
	const struct xt_ipvs_mtinfo *data = (const void *)match->data;
	ipvs_mt_dump(ip, data, NFPROTO_IPV4, numeric, "");
}

static void ipvs_mt6_print(const void *ip, const struct xt_entry_match *match,
			   int numeric)
{
	const struct xt_ipvs_mtinfo *data = (const void *)match->data;
	ipvs_mt_dump(ip, data, NFPROTO_IPV6, numeric, "");
}

static void ipvs_mt4_save(const void *ip, const struct xt_entry_match *match)
{
	const struct xt_ipvs_mtinfo *data = (const void *)match->data;
	ipvs_mt_dump(ip, data, NFPROTO_IPV4, true, "--");
}

static void ipvs_mt6_save(const void *ip, const struct xt_entry_match *match)
{
	const struct xt_ipvs_mtinfo *data = (const void *)match->data;
	ipvs_mt_dump(ip, data, NFPROTO_IPV6, true, "--");
}

static struct xtables_match ipvs_matches_reg[] = {
	{
		.version       = XTABLES_VERSION,
		.name          = "ipvs",
		.revision      = 0,
		.family        = NFPROTO_IPV4,
		.size          = XT_ALIGN(sizeof(struct xt_ipvs_mtinfo)),
		.userspacesize = XT_ALIGN(sizeof(struct xt_ipvs_mtinfo)),
		.help          = ipvs_mt_help,
		.x6_parse      = ipvs_mt_parse,
		.x6_fcheck     = ipvs_mt_check,
		.print         = ipvs_mt4_print,
		.save          = ipvs_mt4_save,
		.x6_options    = ipvs_mt_opts,
	},
	{
		.version       = XTABLES_VERSION,
		.name          = "ipvs",
		.revision      = 0,
		.family        = NFPROTO_IPV6,
		.size          = XT_ALIGN(sizeof(struct xt_ipvs_mtinfo)),
		.userspacesize = XT_ALIGN(sizeof(struct xt_ipvs_mtinfo)),
		.help          = ipvs_mt_help,
		.x6_parse      = ipvs_mt_parse,
		.x6_fcheck     = ipvs_mt_check,
		.print         = ipvs_mt6_print,
		.save          = ipvs_mt6_save,
		.x6_options    = ipvs_mt_opts,
	},
};

void _init(void)
{
	xtables_register_matches(ipvs_matches_reg,
				 ARRAY_SIZE(ipvs_matches_reg));
}
