/* 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 <getopt.h>
#include <ip6tables.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <netdb.h>
#include <sys/types.h>

#include <linux/netfilter_ipv6/ip6_tables.h>
#include <linux/netfilter_ipv6/ip6t_ipv6header.h>

/* This maybe required 
#include <linux/in.h>
#include <linux/in6.h>
*/


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

struct numflag {
	u_int8_t proto;
	u_int8_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 char *
proto_to_name(u_int8_t proto, int nolookup)
{
        unsigned int i;

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

        for (i = 0; i < sizeof(chain_protos)/sizeof(struct pprot); i++)
                if (chain_protos[i].num == proto)
                        return chain_protos[i].name;

        return NULL;
}

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

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

        	if (i == sizeof(chain_protos)/sizeof(struct pprot))
        		exit_error(PARAMETER_PROBLEM,
        			"unknown header `%s' specified",
        			s);
        }

        return (u_int16_t)proto;
}

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

	for (i = 0;
		i < sizeof(chain_flags)/sizeof(struct numflag);
		i++) {
			if (proto == chain_flags[i].proto){
				flag = chain_flags[i].flag;
				break;
			}
	}

	if (i == sizeof(chain_flags)/sizeof(struct numflag))
		exit_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,proto\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 option ipv6header_opts[] = {
	{ "header", 1, NULL, '1' },
	{ "soft", 0, NULL, '2' },
	{ .name = NULL }
};

static void ipv6header_init(struct xt_entry_match *m)
{
	struct ip6t_ipv6header_info *info = (struct ip6t_ipv6header_info *)m->data;

	info->matchflags = 0x00;
	info->invflags = 0x00;
	info->modeflag = 0x00;
}

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;
}

#define IPV6_HDR_HEADER	0x01
#define IPV6_HDR_SOFT	0x02

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

	switch (c) {
		case '1' : 
			/* Parse the provided header names */
			if (*flags & IPV6_HDR_HEADER)
				exit_error(PARAMETER_PROBLEM,
					"Only one `--header' allowed");

			check_inverse(optarg, &invert, &optind, 0);

			if (! (info->matchflags = parse_header(argv[optind-1])) )
				exit_error(PARAMETER_PROBLEM, "ip6t_ipv6header: cannot parse header names");

			if (invert) 
				info->invflags |= 0xFF;
			*flags |= IPV6_HDR_HEADER;
			break;
		case '2' : 
			/* Soft-mode requested? */
			if (*flags & IPV6_HDR_SOFT)
				exit_error(PARAMETER_PROBLEM,
					"Only one `--soft' allowed");

			info->modeflag |= 0xFF;
			*flags |= IPV6_HDR_SOFT;
			break;
		default:
			return 0;
	}

	return 1;
}

static void ipv6header_check(unsigned int flags)
{
	if (!flags) exit_error(PARAMETER_PROBLEM, "ip6t_ipv6header: no options specified");
}

static void
print_header(u_int8_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);
                        printf(" ");
                }
        }

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

	return;
}

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("--header ");
	printf("%s", info->invflags ? "!" : "");
	print_header(info->matchflags);
	printf(" ");
	if (info->modeflag)
		printf("--soft ");

	return;
}

static struct xtables_match ipv6header_mt6_reg = {
	.name		= "ipv6header",
	.version	= XTABLES_VERSION,
	.family		= PF_INET6,
	.size		= XT_ALIGN(sizeof(struct ip6t_ipv6header_info)),
	.userspacesize	= XT_ALIGN(sizeof(struct ip6t_ipv6header_info)),
	.help		= ipv6header_help,
	.init		= ipv6header_init,
	.parse		= ipv6header_parse,
	.final_check	= ipv6header_check,
	.print		= ipv6header_print,
	.save		= ipv6header_save,
	.extra_opts	= ipv6header_opts,
};

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