/* Shared library add-on to iptables to add devgroup matching support.
 *
 * Copyright (c) 2011 Patrick McHardy <kaber@trash.net>
 */
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
#include <xtables.h>
#include <linux/netfilter/xt_devgroup.h>

static void devgroup_help(void)
{
	printf(
"devgroup match options:\n"
"[!] --src-group value[/mask]	Match device group of incoming device\n"
"[!] --dst-group value[/mask]	Match device group of outgoing device\n"
		);
}

enum {
	O_SRC_GROUP = 0,
	O_DST_GROUP,
};

static const struct xt_option_entry devgroup_opts[] = {
	{.name = "src-group", .id = O_SRC_GROUP, .type = XTTYPE_STRING,
	 .flags = XTOPT_INVERT},
	{.name = "dst-group", .id = O_DST_GROUP, .type = XTTYPE_STRING,
	 .flags = XTOPT_INVERT},
	XTOPT_TABLEEND,
};

/* array of devgroups from /etc/iproute2/group */
static struct xtables_lmap *devgroups;

static void devgroup_init(struct xt_entry_match *match)
{
	const char file[] = "/etc/iproute2/group";
	devgroups = xtables_lmap_init(file);
	if (devgroups == NULL && errno != ENOENT)
		fprintf(stderr, "Warning: %s: %s\n", file, strerror(errno));
}

static void devgroup_parse_groupspec(const char *arg, unsigned int *group,
				     unsigned int *mask)
{
	char *end;
	bool ok;

	ok = xtables_strtoui(arg, &end, group, 0, UINT32_MAX);
	if (ok && (*end == '/' || *end == '\0')) {
		if (*end == '/')
			ok = xtables_strtoui(end + 1, NULL, mask,
			                     0, UINT32_MAX);
		else
			*mask = ~0U;
		if (!ok)
			xtables_error(PARAMETER_PROBLEM,
				      "Bad group value \"%s\"", arg);
	} else {
		*group = xtables_lmap_name2id(devgroups, arg);
		if (*group == -1)
			xtables_error(PARAMETER_PROBLEM,
				      "Device group \"%s\" not found", arg);
		*mask = ~0U;
	}
}

static void devgroup_parse(struct xt_option_call *cb)
{
	struct xt_devgroup_info *info = cb->data;
	unsigned int id, mask;

	xtables_option_parse(cb);
	switch (cb->entry->id) {
	case O_SRC_GROUP:
		devgroup_parse_groupspec(cb->arg, &id, &mask);
		info->src_group = id;
		info->src_mask  = mask;
		info->flags |= XT_DEVGROUP_MATCH_SRC;
		if (cb->invert)
			info->flags |= XT_DEVGROUP_INVERT_SRC;
		break;
	case O_DST_GROUP:
		devgroup_parse_groupspec(cb->arg, &id, &mask);
		info->dst_group = id;
		info->dst_mask  = mask;
		info->flags |= XT_DEVGROUP_MATCH_DST;
		if (cb->invert)
			info->flags |= XT_DEVGROUP_INVERT_DST;
		break;
	}
}

static void
print_devgroup(unsigned int id, unsigned int mask, int numeric)
{
	const char *name = NULL;

	if (mask != 0xffffffff)
		printf("0x%x/0x%x", id, mask);
	else {
		if (numeric == 0)
			name = xtables_lmap_id2name(devgroups, id);
		if (name)
			printf("%s", name);
		else
			printf("0x%x", id);
	}
}

static void devgroup_show(const char *pfx, const struct xt_devgroup_info *info,
			  int numeric)
{
	if (info->flags & XT_DEVGROUP_MATCH_SRC) {
		if (info->flags & XT_DEVGROUP_INVERT_SRC)
			printf(" !");
		printf(" %ssrc-group ", pfx);
		print_devgroup(info->src_group, info->src_mask, numeric);
	}

	if (info->flags & XT_DEVGROUP_MATCH_DST) {
		if (info->flags & XT_DEVGROUP_INVERT_DST)
			printf(" !");
		printf(" %sdst-group ", pfx);
		print_devgroup(info->dst_group, info->dst_mask, numeric);
	}
}

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

	devgroup_show("", info, numeric);
}

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

	devgroup_show("--", info, 0);
}

static void devgroup_check(struct xt_fcheck_call *cb)
{
	if (cb->xflags == 0)
		xtables_error(PARAMETER_PROBLEM,
			      "devgroup match: You must specify either "
			      "'--src-group' or '--dst-group'");
}

static void
print_devgroup_xlate(unsigned int id, uint32_t op,  unsigned int mask,
		     struct xt_xlate *xl, int numeric)
{
	const char *name = NULL;

	if (mask != 0xffffffff)
		xt_xlate_add(xl, "and 0x%x %s 0x%x", mask,
			   op == XT_OP_EQ ? "==" : "!=", id);
	else {
		if (numeric == 0)
			name = xtables_lmap_id2name(devgroups, id);

		xt_xlate_add(xl, "%s", op == XT_OP_EQ ? "" : "!= ");
		if (name)
			xt_xlate_add(xl, "%s", name);
		else
			xt_xlate_add(xl, "0x%x", id);
	}
}

static void devgroup_show_xlate(const struct xt_devgroup_info *info,
				struct xt_xlate *xl, int numeric)
{
	enum xt_op op = XT_OP_EQ;
	char *space = "";

	if (info->flags & XT_DEVGROUP_MATCH_SRC) {
		if (info->flags & XT_DEVGROUP_INVERT_SRC)
			op = XT_OP_NEQ;
		xt_xlate_add(xl, "iifgroup ");
		print_devgroup_xlate(info->src_group, op,
				     info->src_mask, xl, numeric);
		space = " ";
	}

	if (info->flags & XT_DEVGROUP_MATCH_DST) {
		if (info->flags & XT_DEVGROUP_INVERT_DST)
			op = XT_OP_NEQ;
		xt_xlate_add(xl, "%soifgroup ", space);
		print_devgroup_xlate(info->dst_group, op,
				     info->dst_mask, xl, numeric);
	}
}

static int devgroup_xlate(struct xt_xlate *xl,
			  const struct xt_xlate_mt_params *params)
{
	const struct xt_devgroup_info *info = (const void *)params->match->data;

	devgroup_show_xlate(info, xl, 0);

	return 1;
}

static struct xtables_match devgroup_mt_reg = {
	.name		= "devgroup",
	.version	= XTABLES_VERSION,
	.family		= NFPROTO_UNSPEC,
	.size		= XT_ALIGN(sizeof(struct xt_devgroup_info)),
	.userspacesize	= XT_ALIGN(sizeof(struct xt_devgroup_info)),
	.init		= devgroup_init,
	.help		= devgroup_help,
	.print		= devgroup_print,
	.save		= devgroup_save,
	.x6_parse	= devgroup_parse,
	.x6_fcheck	= devgroup_check,
	.x6_options	= devgroup_opts,
	.xlate		= devgroup_xlate,
};

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