/* Shared library add-on to iptables to add connmark matching support.
 *
 * (C) 2002,2004 MARA Systems AB <http://www.marasystems.com>
 * by Henrik Nordstrom <hno@marasystems.com>
 *
 * Version 1.1
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */
#include <stdio.h>
#include <netdb.h>
#include <string.h>
#include <stdlib.h>
#include <getopt.h>

#include <xtables.h>
#include <linux/netfilter/xt_connmark.h>

enum {
	F_MARK = 1 << 0,
};

static void connmark_mt_help(void)
{
	printf(
"connmark match options:\n"
"[!] --mark value[/mask]    Match ctmark value with optional mask\n");
}

static const struct option connmark_mt_opts[] = {
	{.name = "mark", .has_arg = true, .val = '1'},
	{ .name = NULL }
};

static int
connmark_mt_parse(int c, char **argv, int invert, unsigned int *flags,
                  const void *entry, struct xt_entry_match **match)
{
	struct xt_connmark_mtinfo1 *info = (void *)(*match)->data;
	unsigned int mark, mask = UINT32_MAX;
	char *end;

	switch (c) {
	case '1': /* --mark */
		xtables_param_act(XTF_ONLY_ONCE, "connmark", "--mark", *flags & F_MARK);
		if (!xtables_strtoui(optarg, &end, &mark, 0, UINT32_MAX))
			xtables_param_act(XTF_BAD_VALUE, "connmark", "--mark", optarg);
		if (*end == '/')
			if (!xtables_strtoui(end + 1, &end, &mask, 0, UINT32_MAX))
				xtables_param_act(XTF_BAD_VALUE, "connmark", "--mark", optarg);
		if (*end != '\0')
			xtables_param_act(XTF_BAD_VALUE, "connmark", "--mark", optarg);

		if (invert)
			info->invert = true;
		info->mark = mark;
		info->mask = mask;
		*flags    |= F_MARK;
		return true;
	}
	return false;
}

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

	switch (c) {
		char *end;
	case '1':
		xtables_check_inverse(optarg, &invert, &optind, 0);

		markinfo->mark = strtoul(optarg, &end, 0);
		markinfo->mask = 0xffffffffUL;
		
		if (*end == '/')
			markinfo->mask = strtoul(end+1, &end, 0);

		if (*end != '\0' || end == optarg)
			xtables_error(PARAMETER_PROBLEM, "Bad MARK value \"%s\"", optarg);
		if (invert)
			markinfo->invert = 1;
		*flags = 1;
		break;

	default:
		return 0;
	}
	return 1;
}

static void print_mark(unsigned int mark, unsigned int mask)
{
	if (mask != 0xffffffffU)
		printf("0x%x/0x%x ", mark, mask);
	else
		printf("0x%x ", mark);
}

static void connmark_mt_check(unsigned int flags)
{
	if (flags == 0)
		xtables_error(PARAMETER_PROBLEM,
		           "connmark: The --mark option is required");
}

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

	printf("CONNMARK match ");
	if (info->invert)
		printf("!");
	print_mark(info->mark, info->mask);
}

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

	printf("connmark match ");
	if (info->invert)
		printf("!");
	print_mark(info->mark, info->mask);
}

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

	if (info->invert)
		printf("! ");

	printf("--mark ");
	print_mark(info->mark, info->mask);
}

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

	if (info->invert)
		printf("! ");

	printf("--mark ");
	print_mark(info->mark, info->mask);
}

static struct xtables_match connmark_mt_reg_v0 = {
	.family		= NFPROTO_IPV4,
	.name		= "connmark",
	.revision	= 0,
	.version	= XTABLES_VERSION,
	.size		= XT_ALIGN(sizeof(struct xt_connmark_info)),
	.userspacesize	= XT_ALIGN(sizeof(struct xt_connmark_info)),
	.help		= connmark_mt_help,
	.parse		= connmark_parse,
	.final_check	= connmark_mt_check,
	.print		= connmark_print,
	.save		= connmark_save,
	.extra_opts	= connmark_mt_opts,
};

static struct xtables_match connmark_mt6_reg_v0 = {
	.family		= NFPROTO_IPV6,
	.name		= "connmark",
	.revision	= 0,
	.version	= XTABLES_VERSION,
	.size		= XT_ALIGN(sizeof(struct xt_connmark_info)),
	.userspacesize	= XT_ALIGN(sizeof(struct xt_connmark_info)),
	.help		= connmark_mt_help,
	.parse		= connmark_parse,
	.final_check	= connmark_mt_check,
	.print		= connmark_print,
	.save		= connmark_save,
	.extra_opts	= connmark_mt_opts,
};

static struct xtables_match connmark_mt_reg = {
	.version        = XTABLES_VERSION,
	.name           = "connmark",
	.revision       = 1,
	.family         = NFPROTO_IPV4,
	.size           = XT_ALIGN(sizeof(struct xt_connmark_mtinfo1)),
	.userspacesize  = XT_ALIGN(sizeof(struct xt_connmark_mtinfo1)),
	.help           = connmark_mt_help,
	.parse          = connmark_mt_parse,
	.final_check    = connmark_mt_check,
	.print          = connmark_mt_print,
	.save           = connmark_mt_save,
	.extra_opts     = connmark_mt_opts,
};

static struct xtables_match connmark_mt6_reg = {
	.version        = XTABLES_VERSION,
	.name           = "connmark",
	.revision       = 1,
	.family         = NFPROTO_IPV6,
	.size           = XT_ALIGN(sizeof(struct xt_connmark_mtinfo1)),
	.userspacesize  = XT_ALIGN(sizeof(struct xt_connmark_mtinfo1)),
	.help           = connmark_mt_help,
	.parse          = connmark_mt_parse,
	.final_check    = connmark_mt_check,
	.print          = connmark_mt_print,
	.save           = connmark_mt_save,
	.extra_opts     = connmark_mt_opts,
};

void _init(void)
{
	xtables_register_match(&connmark_mt_reg_v0);
	xtables_register_match(&connmark_mt6_reg_v0);
	xtables_register_match(&connmark_mt_reg);
	xtables_register_match(&connmark_mt6_reg);
}
