/* ipv6header match - matches IPv6 packets based
on whether they contain certain headers */

/* Original idea: Brad Chapman 
 * Rewritten by: Andras Kis-Szabo <kisza@sch.bme.hu> */
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <netdb.h>
#include <xtables.h>
#include <linux/netfilter_ipv6/ip6t_ipv6header.h>

enum {
	O_HEADER = 0,
	O_SOFT,
};

/* A few hardcoded protocols for 'all' and in case the user has no
 *    /etc/protocols */
struct pprot {
	char *name;
	uint8_t num;
};

struct numflag {
	uint8_t proto;
	uint8_t flag;
};

static const struct pprot chain_protos[] = {
	{ "hop-by-hop", IPPROTO_HOPOPTS },
	{ "protocol", IPPROTO_RAW },
	{ "hop", IPPROTO_HOPOPTS },
	{ "dst", IPPROTO_DSTOPTS },
	{ "route", IPPROTO_ROUTING },
	{ "frag", IPPROTO_FRAGMENT },
	{ "auth", IPPROTO_AH },
	{ "esp", IPPROTO_ESP },
	{ "none", IPPROTO_NONE },
	{ "prot", IPPROTO_RAW },
	{ "0", IPPROTO_HOPOPTS },
	{ "60", IPPROTO_DSTOPTS },
	{ "43", IPPROTO_ROUTING },
	{ "44", IPPROTO_FRAGMENT },
	{ "51", IPPROTO_AH },
	{ "50", IPPROTO_ESP },
	{ "59", IPPROTO_NONE },
	{ "255", IPPROTO_RAW },
	/* { "all", 0 }, */
};

static const struct numflag chain_flags[] = {
	{ IPPROTO_HOPOPTS, MASK_HOPOPTS },
	{ IPPROTO_DSTOPTS, MASK_DSTOPTS },
	{ IPPROTO_ROUTING, MASK_ROUTING },
	{ IPPROTO_FRAGMENT, MASK_FRAGMENT },
	{ IPPROTO_AH, MASK_AH },
	{ IPPROTO_ESP, MASK_ESP },
	{ IPPROTO_NONE, MASK_NONE },
	{ IPPROTO_RAW, MASK_PROTO },
};

static const char *
proto_to_name(uint8_t proto, int nolookup)
{
        unsigned int i;

        if (proto && !nolookup) {
		const struct protoent *pent = getprotobynumber(proto);
                if (pent)
                        return pent->p_name;
        }

        for (i = 0; i < ARRAY_SIZE(chain_protos); ++i)
                if (chain_protos[i].num == proto)
                        return chain_protos[i].name;

        return NULL;
}

static uint16_t
name_to_proto(const char *s)
{
        unsigned int proto=0;
	const struct protoent *pent;

        if ((pent = getprotobyname(s)))
        	proto = pent->p_proto;
        else {
        	unsigned int i;
        	for (i = 0; i < ARRAY_SIZE(chain_protos); ++i)
        		if (strcmp(s, chain_protos[i].name) == 0) {
        			proto = chain_protos[i].num;
        			break;
        		}

		if (i == ARRAY_SIZE(chain_protos))
			xtables_error(PARAMETER_PROBLEM,
        			"unknown header `%s' specified",
        			s);
        }

        return proto;
}

static unsigned int 
add_proto_to_mask(int proto){
	unsigned int i=0, flag=0;

	for (i = 0; i < ARRAY_SIZE(chain_flags); ++i)
			if (proto == chain_flags[i].proto){
				flag = chain_flags[i].flag;
				break;
			}

	if (i == ARRAY_SIZE(chain_flags))
		xtables_error(PARAMETER_PROBLEM,
		"unknown header `%d' specified",
		proto);
	
	return flag;
}	

static void ipv6header_help(void)
{
	printf(
"ipv6header match options:\n"
"[!] --header headers     Type of header to match, by name\n"
"                         names: hop,dst,route,frag,auth,esp,none,prot\n"
"                    long names: hop-by-hop,ipv6-opts,ipv6-route,\n"
"                                ipv6-frag,ah,esp,ipv6-nonxt,protocol\n"
"                       numbers: 0,60,43,44,51,50,59\n"
"--soft                    The header CONTAINS the specified extensions\n");
}

static const struct xt_option_entry ipv6header_opts[] = {
	{.name = "header", .id = O_HEADER, .type = XTTYPE_STRING,
	 .flags = XTOPT_MAND | XTOPT_INVERT},
	{.name = "soft", .id = O_SOFT, .type = XTTYPE_NONE},
	XTOPT_TABLEEND,
};

static unsigned int
parse_header(const char *flags) {
        unsigned int ret = 0;
        char *ptr;
        char *buffer;

        buffer = strdup(flags);

        for (ptr = strtok(buffer, ","); ptr; ptr = strtok(NULL, ",")) 
		ret |= add_proto_to_mask(name_to_proto(ptr));
                
        free(buffer);
        return ret;
}

static void ipv6header_parse(struct xt_option_call *cb)
{
	struct ip6t_ipv6header_info *info = cb->data;

	xtables_option_parse(cb);
	switch (cb->entry->id) {
	case O_HEADER:
		if (!(info->matchflags = parse_header(cb->arg)))
			xtables_error(PARAMETER_PROBLEM, "ip6t_ipv6header: cannot parse header names");
		if (cb->invert) 
			info->invflags |= 0xFF;
		break;
	case O_SOFT:
		info->modeflag |= 0xFF;
		break;
	}
}

static void
print_header(uint8_t flags){
        int have_flag = 0;

        while (flags) {
                unsigned int i;

                for (i = 0; (flags & chain_flags[i].flag) == 0; i++);

                if (have_flag)
                        printf(",");

                printf("%s", proto_to_name(chain_flags[i].proto,0));
                have_flag = 1;

                flags &= ~chain_flags[i].flag;
        }

        if (!have_flag)
                printf("NONE");
}

static void ipv6header_print(const void *ip,
                             const struct xt_entry_match *match, int numeric)
{
	const struct ip6t_ipv6header_info *info = (const struct ip6t_ipv6header_info *)match->data;
	printf(" ipv6header");

        if (info->matchflags || info->invflags) {
		printf(" flags:%s", info->invflags ? "!" : "");
                if (numeric)
			printf("0x%02X", info->matchflags);
                else {
                        print_header(info->matchflags);
                }
        }

	if (info->modeflag)
		printf(" soft");
}

static void ipv6header_save(const void *ip, const struct xt_entry_match *match)
{

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

	printf("%s --header ", info->invflags ? " !" : "");
	print_header(info->matchflags);
	if (info->modeflag)
		printf(" --soft");
}

static struct xtables_match ipv6header_mt6_reg = {
	.name		= "ipv6header",
	.version	= XTABLES_VERSION,
	.family		= NFPROTO_IPV6,
	.size		= XT_ALIGN(sizeof(struct ip6t_ipv6header_info)),
	.userspacesize	= XT_ALIGN(sizeof(struct ip6t_ipv6header_info)),
	.help		= ipv6header_help,
	.print		= ipv6header_print,
	.save		= ipv6header_save,
	.x6_parse	= ipv6header_parse,
	.x6_options	= ipv6header_opts,
};

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