/* 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/netfilter/xt_u32.c
 *
 * (C) 2002 by Don Cohen <don-netf@isis.cs3-inc.com>
 * Released under the terms of GNU GPL v2
 *
 * Copyright © CC Computer Consultants GmbH, 2007
 * Contact: <jengelh@computergmbh.de>
 */
#include <sys/types.h>
#include <ctype.h>
#include <errno.h>
#include <getopt.h>
#include <netdb.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>

#include <xtables.h>
#include <linux/netfilter/xt_u32.h>

static const struct option u32_opts[] = {
	{"u32", 1, NULL, 'u'},
	{ .name = NULL }
};

static void u32_help(void)
{
	printf(
		"u32 match options:\n"
		"[!] --u32 tests\n"
		"\t\t""tests := location \"=\" value | tests \"&&\" location \"=\" value\n"
		"\t\t""value := range | value \",\" range\n"
		"\t\t""range := number | number \":\" number\n"
		"\t\t""location := number | location operator number\n"
		"\t\t""operator := \"&\" | \"<<\" | \">>\" | \"@\"\n");
}

static void u32_dump(const struct xt_u32 *data)
{
	const struct xt_u32_test *ct;
	unsigned int testind, i;

	for (testind = 0; testind < data->ntests; ++testind) {
		ct = &data->tests[testind];

		if (testind > 0)
			printf("&&");

		printf("0x%x", ct->location[0].number);
		for (i = 1; i < ct->nnums; ++i) {
			switch (ct->location[i].nextop) {
			case XT_U32_AND:
				printf("&");
				break;
			case XT_U32_LEFTSH:
				printf("<<");
				break;
			case XT_U32_RIGHTSH:
				printf(">>");
				break;
			case XT_U32_AT:
				printf("@");
				break;
			}
			printf("0x%x", ct->location[i].number);
		}

		printf("=");
		for (i = 0; i < ct->nvalues; ++i) {
			if (i > 0)
				printf(",");
			if (ct->value[i].min == ct->value[i].max)
				printf("0x%x", ct->value[i].min);
			else
				printf("0x%x:0x%x", ct->value[i].min,
				       ct->value[i].max);
		}
	}
	printf(" ");
}

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

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

static int u32_parse(int c, char **argv, int invert, unsigned int *flags,
		     const void *entry, struct xt_entry_match **match)
{
	struct xt_u32 *data = (void *)(*match)->data;
	unsigned int testind = 0, locind = 0, valind = 0;
	struct xt_u32_test *ct = &data->tests[testind]; /* current test */
	char *arg = argv[optind-1]; /* the argument string */
	char *start = arg;
	int state = 0;

	if (c != 'u')
		return 0;

	data->invert = invert;

	/*
	 * states:
	 * 0 = looking for numbers and operations,
	 * 1 = looking for ranges
	 */
	while (1) {
		/* read next operand/number or range */
		while (isspace(*arg))
			++arg;

		if (*arg == '\0') {
			/* end of argument found */
			if (state == 0)
				xtables_error(PARAMETER_PROBLEM,
					   "u32: abrupt end of input after location specifier");
			if (valind == 0)
				xtables_error(PARAMETER_PROBLEM,
					   "u32: test ended with no value specified");

			ct->nnums    = locind;
			ct->nvalues  = valind;
			data->ntests = ++testind;

			if (testind > XT_U32_MAXSIZE)
				xtables_error(PARAMETER_PROBLEM,
				           "u32: at char %u: too many \"&&\"s",
				           (unsigned int)(arg - start));
			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) {
					xtables_error(PARAMETER_PROBLEM,
					           "u32: at char %u: "
					           "location spec missing",
					           (unsigned int)(arg - start));
				} else {
					++arg;
					state = 1;
				}
			} else {
				if (locind != 0) {
					/* need op before number */
					if (*arg == '&') {
						ct->location[locind].nextop = XT_U32_AND;
					} else if (*arg == '<') {
						if (*++arg != '<')
							xtables_error(PARAMETER_PROBLEM,
								   "u32: at char %u: a second '<' was expected", (unsigned int)(arg - start));
						ct->location[locind].nextop = XT_U32_LEFTSH;
					} else if (*arg == '>') {
						if (*++arg != '>')
							xtables_error(PARAMETER_PROBLEM,
								   "u32: at char %u: a second '>' was expected", (unsigned int)(arg - start));
						ct->location[locind].nextop = XT_U32_RIGHTSH;
					} else if (*arg == '@') {
						ct->location[locind].nextop = XT_U32_AT;
					} else {
						xtables_error(PARAMETER_PROBLEM,
							"u32: at char %u: operator expected", (unsigned int)(arg - start));
					}
					++arg;
				}
				/* now a number; string_to_number skips white space? */
				ct->location[locind].number =
					parse_number(&arg, arg - start);
				if (++locind > XT_U32_MAXSIZE)
					xtables_error(PARAMETER_PROBLEM,
						   "u32: at char %u: too many operators", (unsigned int)(arg - start));
			}
		} else {
			/*
			 * state 1 - reading values: read a range if nothing
			 * read yet, otherwise either ,range or && to end
			 * test spec
			 */
			if (*arg == '&') {
				if (*++arg != '&')
					xtables_error(PARAMETER_PROBLEM,
						   "u32: at char %u: a second '&' was expected", (unsigned int)(arg - start));
				if (valind == 0) {
					xtables_error(PARAMETER_PROBLEM,
						   "u32: at char %u: value spec missing", (unsigned int)(arg - start));
				} else {
					ct->nnums   = locind;
					ct->nvalues = valind;
					ct = &data->tests[++testind];
					if (testind > XT_U32_MAXSIZE)
						xtables_error(PARAMETER_PROBLEM,
							   "u32: at char %u: too many \"&&\"s", (unsigned int)(arg - start));
					++arg;
					state  = 0;
					locind = 0;
					valind = 0;
				}
			} else { /* read value range */
				if (valind > 0) { /* need , before number */
					if (*arg != ',')
						xtables_error(PARAMETER_PROBLEM,
							   "u32: at char %u: expected \",\" or \"&&\"", (unsigned int)(arg - start));
					++arg;
				}
				ct->value[valind].min =
					parse_number(&arg, arg - start);

				while (isspace(*arg))
					++arg;

				if (*arg == ':') {
					++arg;
					ct->value[valind].max =
						parse_number(&arg, arg-start);
				} else {
					ct->value[valind].max =
						ct->value[valind].min;
				}

				if (++valind > XT_U32_MAXSIZE)
					xtables_error(PARAMETER_PROBLEM,
						   "u32: at char %u: too many \",\"s", (unsigned int)(arg - start));
			}
		}
	}
}

static void u32_print(const void *ip, const struct xt_entry_match *match,
                      int numeric)
{
	const struct xt_u32 *data = (const void *)match->data;
	printf("u32 ");
	if (data->invert)
		printf("! ");
	u32_dump(data);
}

static void u32_save(const void *ip, const struct xt_entry_match *match)
{
	const struct xt_u32 *data = (const void *)match->data;
	if (data->invert)
		printf("! ");
	printf("--u32 ");
	u32_dump(data);
}

static struct xtables_match u32_match = {
	.name          = "u32",
	.family        = AF_UNSPEC,
	.version       = XTABLES_VERSION,
	.size          = XT_ALIGN(sizeof(struct xt_u32)),
	.userspacesize = XT_ALIGN(sizeof(struct xt_u32)),
	.help          = u32_help,
	.parse         = u32_parse,
	.print         = u32_print,
	.save          = u32_save,
	.extra_opts    = u32_opts,
};

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