/* Shared library add-on to ip6tables to add Hop-by-Hop 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/in6.h>*/
#include <linux/netfilter_ipv6/ip6t_opts.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>

#define DEBUG		0

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

static const struct option hbh_opts[] = {
	{ "hbh-len", 1, NULL, '1' },
	{ "hbh-opts", 1, NULL, '2' },
	{ "hbh-not-strict", 1, NULL, '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,
			   "hbh: 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,
			   "hbh: 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 has not got length");
			opts[i] |= parse_opts_num(range, "length") & 0xFF;
                } else {
                        opts[i] |= (0x00FF);
		}

#if 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);

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

	return i;
}

static void hbh_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 hbh_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 `--hbh-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 `--hbh-opts' allowed");
                xtables_check_inverse(optarg, &invert, &optind, 0);
                if (invert)
			xtables_error(PARAMETER_PROBLEM,
				" '!' not allowed with `--hbh-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 `--hbh-not-strict' allowed");
		if ( !(*flags & IP6T_OPTS_OPTS) )
			xtables_error(PARAMETER_PROBLEM,
				   "`--hbh-opts ...' required before `--hbh-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 hbh_print(const void *ip, const struct xt_entry_match *match,
                      int numeric)
{
	const struct ip6t_opts *optinfo = (struct ip6t_opts *)match->data;

	printf("hbh ");
	if (optinfo->flags & IP6T_OPTS_LEN) {
		printf("length");
		printf(":%s", optinfo->invflags & IP6T_OPTS_INV_LEN ? "!" : "");
		printf("%u", optinfo->hdrlen);
		printf(" ");
	}
	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 hbh_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--hbh-len %u ",
			(optinfo->invflags & IP6T_OPTS_INV_LEN) ? "! " : "", 
			optinfo->hdrlen);
	}

	if (optinfo->flags & IP6T_OPTS_OPTS)
		printf("--hbh-opts ");
	print_options(optinfo->optsnr, (u_int16_t *)optinfo->opts);
	if (optinfo->flags & IP6T_OPTS_NSTRICT)
		printf("--hbh-not-strict ");
}

static struct xtables_match hbh_mt6_reg = {
	.name 		= "hbh",
	.version	= XTABLES_VERSION,
	.family		= NFPROTO_IPV6,
	.size		= XT_ALIGN(sizeof(struct ip6t_opts)),
	.userspacesize	= XT_ALIGN(sizeof(struct ip6t_opts)),
	.help		= hbh_help,
	.init		= hbh_init,
	.parse		= hbh_parse,
	.print		= hbh_print,
	.save		= hbh_save,
	.extra_opts	= hbh_opts,
};

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