/* 
 * Shared library add-on to iptables to match 
 * packets by their type (BROADCAST, UNICAST, MULTICAST). 
 *
 * Michal Ludvig <michal@logix.cz>
 */
#include <stdio.h>
#include <netdb.h>
#include <string.h>
#include <stdlib.h>
#include <getopt.h>
#if defined(__GLIBC__) && __GLIBC__ == 2
#include <net/ethernet.h>
#else
#include <linux/if_ether.h>
#endif
#include <xtables.h>
#include <linux/if_packet.h>
#include <linux/netfilter/xt_pkttype.h>

#define	PKTTYPE_VERSION	"0.1"

struct pkttypes {
	const char *name;
	unsigned char pkttype;
	unsigned char printhelp;
	const char *help;
};

static const struct pkttypes supported_types[] = {
	{"unicast", PACKET_HOST, 1, "to us"},
	{"broadcast", PACKET_BROADCAST, 1, "to all"},
	{"multicast", PACKET_MULTICAST, 1, "to group"},
/*
	{"otherhost", PACKET_OTHERHOST, 1, "to someone else"},
	{"outgoing", PACKET_OUTGOING, 1, "outgoing of any type"},
*/
	/* aliases */
	{"bcast", PACKET_BROADCAST, 0, NULL},
	{"mcast", PACKET_MULTICAST, 0, NULL},
	{"host", PACKET_HOST, 0, NULL}
};

static void print_types(void)
{
	unsigned int	i;
	
	printf("Valid packet types:\n");
	for (i = 0; i < sizeof(supported_types)/sizeof(struct pkttypes); i++)
	{
		if(supported_types[i].printhelp == 1)
			printf("\t%-14s\t\t%s\n", supported_types[i].name, supported_types[i].help);
	}
	printf("\n");
}

static void pkttype_help(void)
{
	printf(
"pkttype match options:\n"
"[!] --pkt-type packettype    match packet type\n");
	print_types();
}

static const struct option pkttype_opts[] = {
	{"pkt-type", 1, NULL, '1'},
	{ .name = NULL }
};

static void parse_pkttype(const char *pkttype, struct xt_pkttype_info *info)
{
	unsigned int	i;
	
	for (i = 0; i < sizeof(supported_types)/sizeof(struct pkttypes); i++)
	{
		if(strcasecmp(pkttype, supported_types[i].name)==0)
		{
			info->pkttype=supported_types[i].pkttype;
			return;
		}
	}
	
	exit_error(PARAMETER_PROBLEM, "Bad packet type '%s'", pkttype);
}

static int pkttype_parse(int c, char **argv, int invert, unsigned int *flags,
                         const void *entry, struct xt_entry_match **match)
{
	struct xt_pkttype_info *info = (struct xt_pkttype_info *)(*match)->data;
	
	switch(c)
	{
		case '1':
			check_inverse(optarg, &invert, &optind, 0);
			parse_pkttype(argv[optind-1], info);
			if(invert)
				info->invert=1;
			*flags=1;
			break;

		default: 
			return 0;
	}

	return 1;
}

static void pkttype_check(unsigned int flags)
{
	if (!flags)
		exit_error(PARAMETER_PROBLEM, "You must specify `--pkt-type'");
}

static void print_pkttype(struct xt_pkttype_info *info)
{
	unsigned int	i;
	
	for (i = 0; i < sizeof(supported_types)/sizeof(struct pkttypes); i++)
	{
		if(supported_types[i].pkttype==info->pkttype)
		{
			printf("%s ", supported_types[i].name);
			return;
		}
	}

	printf("%d ", info->pkttype);	/* in case we didn't find an entry in named-packtes */
}

static void pkttype_print(const void *ip, const struct xt_entry_match *match,
                          int numeric)
{
	struct xt_pkttype_info *info = (struct xt_pkttype_info *)match->data;
	
	printf("PKTTYPE %s= ", info->invert?"!":"");
	print_pkttype(info);
}

static void pkttype_save(const void *ip, const struct xt_entry_match *match)
{
	struct xt_pkttype_info *info = (struct xt_pkttype_info *)match->data;
	
	printf("--pkt-type %s", info->invert?"! ":"");
	print_pkttype(info);
}

static struct xtables_match pkttype_match = {
	.family		= AF_UNSPEC,
	.name		= "pkttype",
	.version	= XTABLES_VERSION,
	.size		= XT_ALIGN(sizeof(struct xt_pkttype_info)),
	.userspacesize	= XT_ALIGN(sizeof(struct xt_pkttype_info)),
	.help		= pkttype_help,
	.parse		= pkttype_parse,
	.final_check	= pkttype_check,
	.print		= pkttype_print,
	.save		= pkttype_save,
	.extra_opts	= pkttype_opts,
};

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