/* Shared library add-on to ip6tables to add Dst header support. */
#include <stdio.h>
#include <netdb.h>
#include <string.h>
#include <stdlib.h>
#include <getopt.h>
#include <errno.h>
#include <xtables.h>
#include <linux/netfilter_ipv6/ip6t_opts.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>

static void dst_help(void)
{
	printf(
"dst match options:\n"
"[!] --dst-len length            total length of this header\n"
"  --dst-opts TYPE[:LEN][,TYPE[:LEN]...]\n"
"                                Options and its length (list, max: %d)\n",
IP6T_OPTS_OPTSNR);
}

static const struct option dst_opts[] = {
	{ .name = "dst-len",        .has_arg = 1, .val = '1' },
	{ .name = "dst-opts",       .has_arg = 1, .val = '2' },
	{ .name = "dst-not-strict", .has_arg = 1, .val = '3' },
	{ .name = NULL }
};

static u_int32_t
parse_opts_num(const char *idstr, const char *typestr)
{
	unsigned long int id;
	char* ep;

	id = strtoul(idstr, &ep, 0);

	if ( idstr == ep ) {
		xtables_error(PARAMETER_PROBLEM,
		           "dst: no valid digits in %s `%s'", typestr, idstr);
	}
	if ( id == ULONG_MAX  && errno == ERANGE ) {
		xtables_error(PARAMETER_PROBLEM,
			   "%s `%s' specified too big: would overflow",
			   typestr, idstr);
	}
	if ( *idstr != '\0'  && *ep != '\0' ) {
		xtables_error(PARAMETER_PROBLEM,
		           "dst: error parsing %s `%s'", typestr, idstr);
	}
	return id;
}

static int
parse_options(const char *optsstr, u_int16_t *opts)
{
        char *buffer, *cp, *next, *range;
        unsigned int i;
	
	buffer = strdup(optsstr);
        if (!buffer)
		xtables_error(OTHER_PROBLEM, "strdup failed");
			
        for (cp = buffer, i = 0; cp && i < IP6T_OPTS_OPTSNR; cp = next, i++)
        {
                next = strchr(cp, ',');

                if (next)
			*next++='\0';

                range = strchr(cp, ':');

                if (range) {
                        if (i == IP6T_OPTS_OPTSNR-1)
				xtables_error(PARAMETER_PROBLEM,
                                           "too many ports specified");
                        *range++ = '\0';
                }

		opts[i] = (parse_opts_num(cp, "opt") & 0xFF) << 8;
                if (range) {
			if (opts[i] == 0)
				xtables_error(PARAMETER_PROBLEM,
					"PAD0 hasn't got length");
			opts[i] |= parse_opts_num(range, "length") & 0xFF;
                } else
                        opts[i] |= (0x00FF);

#ifdef DEBUG
		printf("opts str: %s %s\n", cp, range);
		printf("opts opt: %04X\n", opts[i]);
#endif
	}

        if (cp)
		xtables_error(PARAMETER_PROBLEM, "too many addresses specified");

	free(buffer);

#ifdef DEBUG
	printf("addr nr: %d\n", i);
#endif

	return i;
}

static void dst_init(struct xt_entry_match *m)
{
	struct ip6t_opts *optinfo = (struct ip6t_opts *)m->data;

	optinfo->hdrlen = 0;
	optinfo->flags = 0;
	optinfo->invflags = 0;
	optinfo->optsnr = 0;
}

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

	switch (c) {
	case '1':
		if (*flags & IP6T_OPTS_LEN)
			xtables_error(PARAMETER_PROBLEM,
				   "Only one `--dst-len' allowed");
		xtables_check_inverse(optarg, &invert, &optind, 0);
		optinfo->hdrlen = parse_opts_num(argv[optind-1], "length");
		if (invert)
			optinfo->invflags |= IP6T_OPTS_INV_LEN;
		optinfo->flags |= IP6T_OPTS_LEN;
		*flags |= IP6T_OPTS_LEN;
		break;
	case '2':
		if (*flags & IP6T_OPTS_OPTS)
			xtables_error(PARAMETER_PROBLEM,
				   "Only one `--dst-opts' allowed");
                xtables_check_inverse(optarg, &invert, &optind, 0);
                if (invert)
			xtables_error(PARAMETER_PROBLEM,
				" '!' not allowed with `--dst-opts'");
		optinfo->optsnr = parse_options(argv[optind-1], optinfo->opts);
		optinfo->flags |= IP6T_OPTS_OPTS;
		*flags |= IP6T_OPTS_OPTS;
		break;
	case '3':
		if (*flags & IP6T_OPTS_NSTRICT)
			xtables_error(PARAMETER_PROBLEM,
				   "Only one `--dst-not-strict' allowed");
		if ( !(*flags & IP6T_OPTS_OPTS) )
			xtables_error(PARAMETER_PROBLEM,
				   "`--dst-opts ...' required before "
				   "`--dst-not-strict'");
		optinfo->flags |= IP6T_OPTS_NSTRICT;
		*flags |= IP6T_OPTS_NSTRICT;
		break;
	default:
		return 0;
	}

	return 1;
}

static void
print_options(unsigned int optsnr, u_int16_t *optsp)
{
	unsigned int i;

	for(i = 0; i < optsnr; i++) {
		printf("%d", (optsp[i] & 0xFF00) >> 8);

		if ((optsp[i] & 0x00FF) != 0x00FF)
			printf(":%d", (optsp[i] & 0x00FF));

		printf("%c", (i != optsnr - 1) ? ',' : ' ');
	}
}

static void dst_print(const void *ip, const struct xt_entry_match *match,
                      int numeric)
{
	const struct ip6t_opts *optinfo = (struct ip6t_opts *)match->data;

	printf("dst ");
	if (optinfo->flags & IP6T_OPTS_LEN)
		printf("length:%s%u ",
			optinfo->invflags & IP6T_OPTS_INV_LEN ? "!" : "",
			optinfo->hdrlen);

	if (optinfo->flags & IP6T_OPTS_OPTS)
		printf("opts ");

	print_options(optinfo->optsnr, (u_int16_t *)optinfo->opts);

	if (optinfo->flags & IP6T_OPTS_NSTRICT)
		printf("not-strict ");

	if (optinfo->invflags & ~IP6T_OPTS_INV_MASK)
		printf("Unknown invflags: 0x%X ",
		       optinfo->invflags & ~IP6T_OPTS_INV_MASK);
}

static void dst_save(const void *ip, const struct xt_entry_match *match)
{
	const struct ip6t_opts *optinfo = (struct ip6t_opts *)match->data;

	if (optinfo->flags & IP6T_OPTS_LEN) {
		printf("%s--dst-len %u ",
			(optinfo->invflags & IP6T_OPTS_INV_LEN) ? "! " : "", 
			optinfo->hdrlen);
	}

	if (optinfo->flags & IP6T_OPTS_OPTS)
		printf("--dst-opts ");

	print_options(optinfo->optsnr, (u_int16_t *)optinfo->opts);

	if (optinfo->flags & IP6T_OPTS_NSTRICT)
		printf("--dst-not-strict ");
}

static struct xtables_match dst_mt6_reg = {
	.name          = "dst",
	.version       = XTABLES_VERSION,
	.family        = NFPROTO_IPV6,
	.size          = XT_ALIGN(sizeof(struct ip6t_opts)),
	.userspacesize = XT_ALIGN(sizeof(struct ip6t_opts)),
	.help          = dst_help,
	.init          = dst_init,
	.parse         = dst_parse,
	.print         = dst_print,
	.save          = dst_save,
	.extra_opts    = dst_opts,
};

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