/* 
   Shared library add-on to iptables to add match support for every Nth packet
   
   This file is distributed under the terms of the GNU General Public
   License (GPL). Copies of the GPL can be obtained from:
   ftp://prep.ai.mit.edu/pub/gnu/GPL

   2001-07-17 Fabrice MARIE <fabrice@celestix.com> : initial development.
   2001-09-20 Richard Wagner (rwagner@cloudnet.com)
        * added support for multiple counters
        * added support for matching on individual packets
          in the counter cycle

*/

#include <stdio.h>
#include <netdb.h>
#include <string.h>
#include <stdlib.h>
#include <syslog.h>
#include <getopt.h>
#include <iptables.h>
#include <linux/netfilter_ipv4/ip_tables.h>
#include <linux/netfilter_ipv4/ipt_nth.h>


/* Function which prints out usage message. */
static void
help(void)
{
	printf(
"nth v%s options:\n"
"   --every     Nth              Match every Nth packet\n"
"  [--counter]  num              Use counter 0-%u (default:0)\n"
"  [--start]    num              Initialize the counter at the number 'num'\n"
"                                instead of 0. Must be between 0 and Nth-1\n"
"  [--packet]   num              Match on 'num' packet. Must be between 0\n"
"                                and Nth-1.\n\n"
"                                If --packet is used for a counter than\n"
"                                there must be Nth number of --packet\n"
"                                rules, covering all values between 0 and\n"
"                                Nth-1 inclusively.\n",
NETFILTER_VERSION, IPT_NTH_NUM_COUNTERS-1);
}

static struct option opts[] = {
	{ "every", 1, 0, '1' },
	{ "start", 1, 0, '2' },
        { "counter", 1, 0, '3' },
        { "packet", 1, 0, '4' },
	{ 0 }
};

/* Initialize the target. */
static void
init(struct ipt_entry_match *m, unsigned int *nfcache)
{
	*nfcache |= NFC_UNKNOWN;
}

#define IPT_NTH_OPT_EVERY	0x01
#define IPT_NTH_OPT_NOT_EVERY	0x02
#define IPT_NTH_OPT_START	0x04
#define IPT_NTH_OPT_COUNTER     0x08
#define IPT_NTH_OPT_PACKET      0x10

/* Function which parses command options; returns true if it
   ate an option */
static int
parse(int c, char **argv, int invert, unsigned int *flags,
      const struct ipt_entry *entry,
      unsigned int *nfcache,
      struct ipt_entry_match **match)
{
	struct ipt_nth_info *nthinfo = (struct ipt_nth_info *)(*match)->data;
	unsigned int num;

	switch (c) {
	case '1':
		/* check for common mistakes... */
		if ((!invert) && (*flags & IPT_NTH_OPT_EVERY))
			exit_error(PARAMETER_PROBLEM,
				   "Can't specify --every twice");
		if (invert && (*flags & IPT_NTH_OPT_NOT_EVERY))
			exit_error(PARAMETER_PROBLEM,
				   "Can't specify ! --every twice");
		if ((!invert) && (*flags & IPT_NTH_OPT_NOT_EVERY))
			exit_error(PARAMETER_PROBLEM,
				   "Can't specify --every with ! --every");
		if (invert && (*flags & IPT_NTH_OPT_EVERY))
			exit_error(PARAMETER_PROBLEM,
				   "Can't specify ! --every with --every");

		/* Remember, this function will interpret a leading 0 to be 
		   Octal, a leading 0x to be hexdecimal... */
                if (string_to_number(optarg, 2, 100, &num) == -1 || num < 2)
                        exit_error(PARAMETER_PROBLEM,
                                   "bad --every `%s', must be between 2 and 100", optarg);

		/* assign the values */
		nthinfo->every = num-1;
		nthinfo->startat = 0;
                nthinfo->packet = 0xFF;
                if(!(*flags & IPT_NTH_OPT_EVERY))
                {
                        nthinfo->counter = 0;
                }
		if (invert)
		{
			*flags |= IPT_NTH_OPT_NOT_EVERY;
			nthinfo->not = 1;
		}
		else
		{
			*flags |= IPT_NTH_OPT_EVERY;
			nthinfo->not = 0;
		}
		break;
	case '2':
		/* check for common mistakes... */
		if (!((*flags & IPT_NTH_OPT_EVERY) ||
		      (*flags & IPT_NTH_OPT_NOT_EVERY)))
			exit_error(PARAMETER_PROBLEM,
				   "Can't specify --start before --every");
		if (invert)
			exit_error(PARAMETER_PROBLEM,
				   "Can't specify with ! --start");
		if (*flags & IPT_NTH_OPT_START)
			exit_error(PARAMETER_PROBLEM,
				   "Can't specify --start twice");
		if (string_to_number(optarg, 0, nthinfo->every, &num) == -1)
                        exit_error(PARAMETER_PROBLEM,
                                   "bad --start `%s', must between 0 and %u", optarg, nthinfo->every);
		*flags |= IPT_NTH_OPT_START;
		nthinfo->startat = num;
		break;
        case '3':
                /* check for common mistakes... */
                if (invert)
                        exit_error(PARAMETER_PROBLEM,
                                   "Can't specify with ! --counter");
                if (*flags & IPT_NTH_OPT_COUNTER)
                        exit_error(PARAMETER_PROBLEM,
                                   "Can't specify --counter twice");
                if (string_to_number(optarg, 0, IPT_NTH_NUM_COUNTERS-1, &num) == -1)
                        exit_error(PARAMETER_PROBLEM,
                                   "bad --counter `%s', must between 0 and %u", optarg, IPT_NTH_NUM_COUNTERS-1);
                /* assign the values */
                *flags |= IPT_NTH_OPT_COUNTER;
                nthinfo->counter = num;
                break;
        case '4':
                /* check for common mistakes... */
                if (!((*flags & IPT_NTH_OPT_EVERY) ||
                      (*flags & IPT_NTH_OPT_NOT_EVERY)))
                        exit_error(PARAMETER_PROBLEM,
                                   "Can't specify --packet before --every");
                if ((*flags & IPT_NTH_OPT_NOT_EVERY))
                        exit_error(PARAMETER_PROBLEM,
                                   "Can't specify --packet with ! --every");
                if (invert)
                        exit_error(PARAMETER_PROBLEM,
                                   "Can't specify with ! --packet");
                if (*flags & IPT_NTH_OPT_PACKET)
                        exit_error(PARAMETER_PROBLEM,
                                   "Can't specify --packet twice");
                if (string_to_number(optarg, 0, nthinfo->every, &num) == -1)
                        exit_error(PARAMETER_PROBLEM,
                                   "bad --packet `%s', must between 0 and %u", optarg, nthinfo->every);
                *flags |= IPT_NTH_OPT_PACKET;
                nthinfo->packet = num;
                break;
	default:
		return 0;
	}
	return 1;
}

/* Final check; nothing. */
static void final_check(unsigned int flags)
{
}

/* Prints out the targinfo. */
static void
print(const struct ipt_ip *ip,
      const struct ipt_entry_match *match,
      int numeric)
{
	const struct ipt_nth_info *nthinfo
		= (const struct ipt_nth_info *)match->data;

	if (nthinfo->not == 1)
		printf(" !");
	printf("every %uth ", (nthinfo->every +1));
	if (nthinfo->counter != 0) 
		printf("counter #%u ", (nthinfo->counter));
        if (nthinfo->packet != 0xFF)
                printf("packet #%u ", nthinfo->packet);
	if (nthinfo->startat != 0)
		printf("start at %u ", nthinfo->startat);
}

/* Saves the union ipt_targinfo in parsable form to stdout. */
static void
save(const struct ipt_ip *ip, const struct ipt_entry_match *match)
{
	const struct ipt_nth_info *nthinfo
		= (const struct ipt_nth_info *)match->data;

	if (nthinfo->not == 1)
		printf("! ");
	printf("--every %u ", (nthinfo->every +1));
	printf("--counter %u ", (nthinfo->counter));
	if (nthinfo->startat != 0)
		printf("--start %u ", nthinfo->startat );
        if (nthinfo->packet != 0xFF)
                printf("--packet %u ", nthinfo->packet );
}

struct iptables_match nth
= { NULL,
    "nth",
    NETFILTER_VERSION,
    IPT_ALIGN(sizeof(struct ipt_nth_info)),
    IPT_ALIGN(sizeof(struct ipt_nth_info)),
    &help,
    &init,
    &parse,
    &final_check,
    &print,
    &save,
    opts
};

void _init(void)
{
	register_match(&nth);
}
