/* Shared library add-on to iptables to add bridge port matching support. */
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <getopt.h>
#include <ctype.h>
#include <xtables.h>
#include <linux/netfilter/xt_physdev.h>
#if defined(__GLIBC__) && __GLIBC__ == 2
#include <net/ethernet.h>
#else
#include <linux/if_ether.h>
#endif

static void physdev_help(void)
{
	printf(
"physdev match options:\n"
" [!] --physdev-in inputname[+]		bridge port name ([+] for wildcard)\n"
" [!] --physdev-out outputname[+]	bridge port name ([+] for wildcard)\n"
" [!] --physdev-is-in			arrived on a bridge device\n"
" [!] --physdev-is-out			will leave on a bridge device\n"
" [!] --physdev-is-bridged		it's a bridged packet\n");
}

static const struct option physdev_opts[] = {
	{ "physdev-in", 1, NULL, '1' },
	{ "physdev-out", 1, NULL, '2' },
	{ "physdev-is-in", 0, NULL, '3' },
	{ "physdev-is-out", 0, NULL, '4' },
	{ "physdev-is-bridged", 0, NULL, '5' },
	{ .name = NULL }
};

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

	switch (c) {
	case '1':
		if (*flags & XT_PHYSDEV_OP_IN)
			goto multiple_use;
		check_inverse(optarg, &invert, &optind, 0);
		parse_interface(argv[optind-1], info->physindev,
				(unsigned char *)info->in_mask);
		if (invert)
			info->invert |= XT_PHYSDEV_OP_IN;
		info->bitmask |= XT_PHYSDEV_OP_IN;
		*flags |= XT_PHYSDEV_OP_IN;
		break;

	case '2':
		if (*flags & XT_PHYSDEV_OP_OUT)
			goto multiple_use;
		check_inverse(optarg, &invert, &optind, 0);
		parse_interface(argv[optind-1], info->physoutdev,
				(unsigned char *)info->out_mask);
		if (invert)
			info->invert |= XT_PHYSDEV_OP_OUT;
		info->bitmask |= XT_PHYSDEV_OP_OUT;
		*flags |= XT_PHYSDEV_OP_OUT;
		break;

	case '3':
		if (*flags & XT_PHYSDEV_OP_ISIN)
			goto multiple_use;
		check_inverse(optarg, &invert, &optind, 0);
		info->bitmask |= XT_PHYSDEV_OP_ISIN;
		if (invert)
			info->invert |= XT_PHYSDEV_OP_ISIN;
		*flags |= XT_PHYSDEV_OP_ISIN;
		break;

	case '4':
		if (*flags & XT_PHYSDEV_OP_ISOUT)
			goto multiple_use;
		check_inverse(optarg, &invert, &optind, 0);
		info->bitmask |= XT_PHYSDEV_OP_ISOUT;
		if (invert)
			info->invert |= XT_PHYSDEV_OP_ISOUT;
		*flags |= XT_PHYSDEV_OP_ISOUT;
		break;

	case '5':
		if (*flags & XT_PHYSDEV_OP_BRIDGED)
			goto multiple_use;
		check_inverse(optarg, &invert, &optind, 0);
		if (invert)
			info->invert |= XT_PHYSDEV_OP_BRIDGED;
		*flags |= XT_PHYSDEV_OP_BRIDGED;
		info->bitmask |= XT_PHYSDEV_OP_BRIDGED;
		break;

	default:
		return 0;
	}

	return 1;
multiple_use:
	exit_error(PARAMETER_PROBLEM,
	   "multiple use of the same physdev option is not allowed");

}

static void physdev_check(unsigned int flags)
{
	if (flags == 0)
		exit_error(PARAMETER_PROBLEM, "PHYSDEV: no physdev option specified");
}

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

	printf("PHYSDEV match");
	if (info->bitmask & XT_PHYSDEV_OP_ISIN)
		printf("%s --physdev-is-in",
		       info->invert & XT_PHYSDEV_OP_ISIN ? " !":"");
	if (info->bitmask & XT_PHYSDEV_OP_IN)
		printf("%s --physdev-in %s",
		(info->invert & XT_PHYSDEV_OP_IN) ? " !":"", info->physindev);

	if (info->bitmask & XT_PHYSDEV_OP_ISOUT)
		printf("%s --physdev-is-out",
		       info->invert & XT_PHYSDEV_OP_ISOUT ? " !":"");
	if (info->bitmask & XT_PHYSDEV_OP_OUT)
		printf("%s --physdev-out %s",
		(info->invert & XT_PHYSDEV_OP_OUT) ? " !":"", info->physoutdev);
	if (info->bitmask & XT_PHYSDEV_OP_BRIDGED)
		printf("%s --physdev-is-bridged",
		       info->invert & XT_PHYSDEV_OP_BRIDGED ? " !":"");
	printf(" ");
}

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

	if (info->bitmask & XT_PHYSDEV_OP_ISIN)
		printf("%s--physdev-is-in ",
		       (info->invert & XT_PHYSDEV_OP_ISIN) ? "! " : "");
	if (info->bitmask & XT_PHYSDEV_OP_IN)
		printf("%s--physdev-in %s ",
		       (info->invert & XT_PHYSDEV_OP_IN) ? "! " : "",
		       info->physindev);

	if (info->bitmask & XT_PHYSDEV_OP_ISOUT)
		printf("%s--physdev-is-out ",
		       (info->invert & XT_PHYSDEV_OP_ISOUT) ? "! " : "");
	if (info->bitmask & XT_PHYSDEV_OP_OUT)
		printf("%s--physdev-out %s ",
		       (info->invert & XT_PHYSDEV_OP_OUT) ? "! " : "",
		       info->physoutdev);
	if (info->bitmask & XT_PHYSDEV_OP_BRIDGED)
		printf("%s--physdev-is-bridged ",
		       (info->invert & XT_PHYSDEV_OP_BRIDGED) ? "! " : "");
}

static struct xtables_match physdev_match = {
	.family		= AF_INET,
	.name		= "physdev",
	.version	= XTABLES_VERSION,
	.size		= XT_ALIGN(sizeof(struct xt_physdev_info)),
	.userspacesize	= XT_ALIGN(sizeof(struct xt_physdev_info)),
	.help		= physdev_help,
	.parse		= physdev_parse,
	.final_check	= physdev_check,
	.print		= physdev_print,
	.save		= physdev_save,
	.extra_opts	= physdev_opts,
};

static struct xtables_match physdev_match6 = {
	.family		= AF_INET6,
	.name		= "physdev",
	.version	= XTABLES_VERSION,
	.size		= XT_ALIGN(sizeof(struct xt_physdev_info)),
	.userspacesize	= XT_ALIGN(sizeof(struct xt_physdev_info)),
	.help		= physdev_help,
	.parse		= physdev_parse,
	.final_check	= physdev_check,
	.print		= physdev_print,
	.save		= physdev_save,
	.extra_opts	= physdev_opts,
};

void _init(void)
{
	xtables_register_match(&physdev_match);
	xtables_register_match(&physdev_match6);
}
