/* Shared library add-on to iptables to add u32 matching,
 * generalized matching on values found at packet offsets
 *
 * Detailed doc is in the kernel module source
 * net/ipv4/netfilter/ipt_u32.c
 *
 * (C) 2002 by Don Cohen <don-netf@isis.cs3-inc.com>
 * Released under the terms of GNU GPL v2
 */
#include <stdio.h>
#include <netdb.h>
#include <string.h>
#include <stdlib.h>
#include <getopt.h>
#include <iptables.h>
#include <linux/netfilter_ipv4/ipt_u32.h>
#include <errno.h>
#include <ctype.h>

/* Function which prints out usage message. */
static void
help(void)
{
	printf( "u32 v%s options:\n"
		" --u32 tests\n"
		" tests := location = value | tests && location = value\n"
		" value := range | value , range\n"
		" range := number | number : number\n"
		" location := number | location operator number\n"
		" operator := & | << | >> | @\n"
		,IPTABLES_VERSION);
}

/* defined in /usr/include/getopt.h maybe in man getopt */
static struct option opts[] = {
	{ "u32", 1, 0, '1' },
	{ 0 }
};

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

/* shared printing code */
static void print_u32(struct ipt_u32 *data)
{
	unsigned int testind;

	for (testind=0; testind < data->ntests; testind++) {
		if (testind) printf("&&");
		{
			unsigned int i;

			printf("0x%x", data->tests[testind].location[0].number);
			for (i = 1; i < data->tests[testind].nnums; i++) {
				switch (data->tests[testind].location[i].nextop) {
				case IPT_U32_AND: printf("&"); break;
				case IPT_U32_LEFTSH: printf("<<"); break;
				case IPT_U32_RIGHTSH: printf(">>"); break;
				case IPT_U32_AT: printf("@"); break;
				}
				printf("0x%x", data->tests[testind].location[i].number);
			}
			printf("=");
			for (i = 0; i < data->tests[testind].nvalues; i++) {
				if (i) printf(",");
				if (data->tests[testind].value[i].min
				    == data->tests[testind].value[i].max)
					printf("0x%x", data->tests[testind].value[i].min);
				else printf("0x%x:0x%x", data->tests[testind].value[i].min,
					    data->tests[testind].value[i].max);
			}
		}
	}
	printf(" ");
}

/* string_to_number is not quite what we need here ... */
u_int32_t parse_number(char **s, int pos)
{
	u_int32_t number;
	char *end;
	errno = 0;

	number = strtol(*s, &end, 0);
	if (end == *s)
		exit_error(PARAMETER_PROBLEM, 
			   "u32: at char %d expected number", pos);
	if (errno)
		exit_error(PARAMETER_PROBLEM, 
			   "u32: at char %d error reading number", pos);
	*s = end;
	return number;
}

/* 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_u32 *data = (struct ipt_u32 *)(*match)->data;
	char *arg = argv[optind-1]; /* the argument string */
	char *start = arg;
	int state=0, testind=0, locind=0, valind=0;

	if (c != '1') return 0;
	/* states: 0 = looking for numbers and operations, 1 = looking for ranges */
	while (1) { /* read next operand/number or range */
		while (isspace(*arg)) 
			arg++;  /* skip white space */
		if (! *arg) { /* end of argument found */
			if (state == 0)
				exit_error(PARAMETER_PROBLEM, 
					   "u32: input ended in location spec");
			if (valind == 0)
				exit_error(PARAMETER_PROBLEM, 
					   "u32: test ended with no value spec");
			data->tests[testind].nnums = locind;
			data->tests[testind].nvalues = valind;
			testind++;
			data->ntests=testind;
			if (testind > U32MAXSIZE)
				exit_error(PARAMETER_PROBLEM, 
					   "u32: at char %d too many &&'s",
					   arg-start);
			/* debugging 
			   print_u32(data);printf("\n");
			   exit_error(PARAMETER_PROBLEM, "debugging output done"); */
			return 1;
		}
		if (state == 0) {
			/* reading location: read a number if nothing read yet,
			   otherwise either op number or = to end location spec */	 
			if (*arg == '=') {
				if (locind == 0)
					exit_error(PARAMETER_PROBLEM,
						   "u32: at char %d location spec missing", arg-start);
				else {
					arg++; 
					state=1;
				}
			}
			else {
				if (locind) { /* need op before number */
					if (*arg == '&') {
						data->tests[testind].location[locind].nextop = IPT_U32_AND;
					}
					else if (*arg == '<') {
						arg++;
						if (*arg != '<')
							exit_error(PARAMETER_PROBLEM,
								   "u32: at char %d a second < expected", arg-start);
						data->tests[testind].location[locind].nextop = IPT_U32_LEFTSH;
					}
					else if (*arg == '>') {
						arg++;
						if (*arg != '>')
							exit_error(PARAMETER_PROBLEM,
								   "u32: at char %d a second > expected", arg-start);
						data->tests[testind].location[locind].nextop = IPT_U32_RIGHTSH;
					}
					else if (*arg == '@') {
						data->tests[testind].location[locind].nextop = IPT_U32_AT;
					}
					else exit_error(PARAMETER_PROBLEM,
							"u32: at char %d operator expected", arg-start);
					arg++;
				}
				/* now a number; string_to_number skips white space? */
				data->tests[testind].location[locind].number =
					parse_number(&arg, arg-start);
				locind++;
				if (locind > U32MAXSIZE)
					exit_error(PARAMETER_PROBLEM,
						   "u32: at char %d too many operators", arg-start);
			}
		}
		else {
			/* state 1 - reading values: read a range if nothing read yet,
			   otherwise either ,range or && to end test spec */
			if (*arg == '&') {
				arg++;
				if (*arg != '&')
					exit_error(PARAMETER_PROBLEM,
						   "u32: at char %d a second & expected", arg-start);
				if (valind == 0)
					exit_error(PARAMETER_PROBLEM,
						   "u32: at char %d value spec missing", arg-start);
				else {
					data->tests[testind].nnums = locind;
					data->tests[testind].nvalues = valind;
					testind++;
					if (testind > U32MAXSIZE)
						exit_error(PARAMETER_PROBLEM,
							   "u32: at char %d too many &&'s", arg-start);
					arg++; state=0; locind=0; valind=0;
				}
			}
			else { /* read value range */
				if (valind) { /* need , before number */
					if (*arg != ',')
						exit_error(PARAMETER_PROBLEM,
							   "u32: at char %d expected , or &&", arg-start);
					arg++;
				}
				data->tests[testind].value[valind].min = parse_number(&arg, arg-start);
				while (isspace(*arg)) 
					arg++;  /* another place white space could be */
				if (*arg==':') {
					arg++;
					data->tests[testind].value[valind].max
						= parse_number(&arg, arg-start);
				}
				else data->tests[testind].value[valind].max
					     = data->tests[testind].value[valind].min;
				valind++;
				if (valind > U32MAXSIZE)
					exit_error(PARAMETER_PROBLEM,
						   "u32: at char %d too many ,'s", arg-start);
			}
		}
	}
}

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

/* Prints out the matchinfo. */
static void
print(const struct ipt_ip *ip,
      const struct ipt_entry_match *match,
      int numeric)
{
	printf("u32 ");
	print_u32((struct ipt_u32 *)match->data);
}

/* Saves the union ipt_matchinfo in parsable form to stdout. */
static void save(const struct ipt_ip *ip, const struct ipt_entry_match *match)
{
	printf("--u32 ");
	print_u32((struct ipt_u32 *)match->data);
}

struct iptables_match u32
= { NULL,
    "u32",
    IPTABLES_VERSION,
    IPT_ALIGN(sizeof(struct ipt_u32)),
    IPT_ALIGN(sizeof(struct ipt_u32)),
    &help,
    &init,
    &parse,
    &final_check,
    &print,
    &save,
    opts
};

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