/*
 * IPv6 Hop Limit matching module
 * Maciej Soltysiak <solt@dns.toxicfilms.tv>
 * Based on HW's ttl match
 * This program is released under the terms of GNU GPL
 * Cleanups by Stephane Ouellette <ouellettes@videotron.ca>
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <getopt.h>
#include <xtables.h>

#include <linux/netfilter_ipv6/ip6t_hl.h>

static void hl_help(void)
{
	printf(
"hl match options:\n"
"[!] --hl-eq value	Match hop limit value\n"
"  --hl-lt value	Match HL < value\n"
"  --hl-gt value	Match HL > value\n");
}

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

	xtables_check_inverse(optarg, &invert, &optind, 0);
	value = atoi(argv[optind-1]);

	if (*flags) 
		xtables_error(PARAMETER_PROBLEM,
				"Can't specify HL option twice");

	if (!optarg)
		xtables_error(PARAMETER_PROBLEM,
				"hl: You must specify a value");
	switch (c) {
		case '2':
			if (invert)
				info->mode = IP6T_HL_NE;
			else
				info->mode = IP6T_HL_EQ;

			/* is 0 allowed? */
			info->hop_limit = value;
			*flags = 1;

			break;
		case '3':
			if (invert) 
				xtables_error(PARAMETER_PROBLEM,
						"hl: unexpected `!'");

			info->mode = IP6T_HL_LT;
			info->hop_limit = value;
			*flags = 1;

			break;
		case '4':
			if (invert)
				xtables_error(PARAMETER_PROBLEM,
						"hl: unexpected `!'");

			info->mode = IP6T_HL_GT;
			info->hop_limit = value;
			*flags = 1;

			break;
		default:
			return 0;
	}

	return 1;
}

static void hl_check(unsigned int flags)
{
	if (!flags) 
		xtables_error(PARAMETER_PROBLEM,
			"HL match: You must specify one of "
			"`--hl-eq', `--hl-lt', `--hl-gt'");
}

static void hl_print(const void *ip, const struct xt_entry_match *match,
                     int numeric)
{
	static const char *op[] = {
		[IP6T_HL_EQ] = "==",
		[IP6T_HL_NE] = "!=",
		[IP6T_HL_LT] = "<",
		[IP6T_HL_GT] = ">" };

	const struct ip6t_hl_info *info = 
		(struct ip6t_hl_info *) match->data;

	printf("HL match HL %s %u ", op[info->mode], info->hop_limit);
}

static void hl_save(const void *ip, const struct xt_entry_match *match)
{
	static const char *const op[] = {
		[IP6T_HL_EQ] = "--hl-eq",
		[IP6T_HL_NE] = "! --hl-eq",
		[IP6T_HL_LT] = "--hl-lt",
		[IP6T_HL_GT] = "--hl-gt" };

	const struct ip6t_hl_info *info =
		(struct ip6t_hl_info *) match->data;

	printf("%s %u ", op[info->mode], info->hop_limit);
}

static const struct option hl_opts[] = {
	{ .name = "hl",    .has_arg = 1, .val = '2' },
	{ .name = "hl-eq", .has_arg = 1, .val = '2' },
	{ .name = "hl-lt", .has_arg = 1, .val = '3' },
	{ .name = "hl-gt", .has_arg = 1, .val = '4' },
	{ .name = NULL }
};

static struct xtables_match hl_mt6_reg = {
	.name          = "hl",
	.version       = XTABLES_VERSION,
	.family        = NFPROTO_IPV6,
	.size          = XT_ALIGN(sizeof(struct ip6t_hl_info)),
	.userspacesize = XT_ALIGN(sizeof(struct ip6t_hl_info)),
	.help          = hl_help,
	.parse         = hl_parse,
	.final_check   = hl_check,
	.print         = hl_print,
	.save          = hl_save,
	.extra_opts    = hl_opts,
};


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