/*
 * m_ematch.c		Extended Matches
 *
 *		This program is free software; you can distribute it and/or
 *		modify it under the terms of the GNU General Public License
 *		as published by the Free Software Foundation; either version
 *		2 of the License, or (at your option) any later version.
 *
 * Authors:	Thomas Graf <tgraf@suug.ch>
 */

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string.h>
#include <dlfcn.h>
#include <stdarg.h>
#include <errno.h>

#include "utils.h"
#include "tc_util.h"
#include "m_ematch.h"

#define EMATCH_MAP "/etc/iproute2/ematch_map"

static struct ematch_util *ematch_list;

/* export to bison parser */
int ematch_argc;
char **ematch_argv;
char *ematch_err;
struct ematch *ematch_root;

static int begin_argc;
static char **begin_argv;

static void bstr_print(FILE *fd, const struct bstr *b, int ascii);

static inline void map_warning(int num, char *kind)
{
	fprintf(stderr,
	    "Error: Unable to find ematch \"%s\" in %s\n" \
	    "Please assign a unique ID to the ematch kind the suggested " \
	    "entry is:\n" \
	    "\t%d\t%s\n",
	    kind, EMATCH_MAP, num, kind);
}

static int lookup_map(__u16 num, char *dst, int len, const char *file)
{
	int err = -EINVAL;
	char buf[512];
	FILE *fd = fopen(file, "r");

	if (fd == NULL)
		return -errno;

	while (fgets(buf, sizeof(buf), fd)) {
		char namebuf[512], *p = buf;
		int id;

		while (*p == ' ' || *p == '\t')
			p++;
		if (*p == '#' || *p == '\n' || *p == 0)
			continue;

		if (sscanf(p, "%d %s", &id, namebuf) != 2) {
			fprintf(stderr, "ematch map %s corrupted at %s\n",
			    file, p);
			goto out;
		}

		if (id == num) {
			if (dst)
				strncpy(dst, namebuf, len - 1);
			err = 0;
			goto out;
		}
	}

	err = -ENOENT;
out:
	fclose(fd);
	return err;
}

static int lookup_map_id(char *kind, int *dst, const char *file)
{
	int err = -EINVAL;
	char buf[512];
	FILE *fd = fopen(file, "r");

	if (fd == NULL)
		return -errno;

	while (fgets(buf, sizeof(buf), fd)) {
		char namebuf[512], *p = buf;
		int id;

		while (*p == ' ' || *p == '\t')
			p++;
		if (*p == '#' || *p == '\n' || *p == 0)
			continue;

		if (sscanf(p, "%d %s", &id, namebuf) != 2) {
			fprintf(stderr, "ematch map %s corrupted at %s\n",
			    file, p);
			goto out;
		}

		if (!strcasecmp(namebuf, kind)) {
			if (dst)
				*dst = id;
			err = 0;
			goto out;
		}
	}

	err = -ENOENT;
	*dst = 0;
out:
	fclose(fd);
	return err;
}

static struct ematch_util *get_ematch_kind(char *kind)
{
	static void *body;
	void *dlh;
	char buf[256];
	struct ematch_util *e;

	for (e = ematch_list; e; e = e->next) {
		if (strcmp(e->kind, kind) == 0)
			return e;
	}

	snprintf(buf, sizeof(buf), "em_%s.so", kind);
	dlh = dlopen(buf, RTLD_LAZY);
	if (dlh == NULL) {
		dlh = body;
		if (dlh == NULL) {
			dlh = body = dlopen(NULL, RTLD_LAZY);
			if (dlh == NULL)
				return NULL;
		}
	}

	snprintf(buf, sizeof(buf), "%s_ematch_util", kind);
	e = dlsym(dlh, buf);
	if (e == NULL)
		return NULL;

	e->next = ematch_list;
	ematch_list = e;

	return e;
}

static struct ematch_util *get_ematch_kind_num(__u16 kind)
{
	char name[513];

	if (lookup_map(kind, name, sizeof(name), EMATCH_MAP) < 0)
		return NULL;

	return get_ematch_kind(name);
}

static int em_parse_call(struct nlmsghdr *n, struct tcf_ematch_hdr *hdr,
			 struct ematch_util *e, struct ematch *t)
{
	if (e->parse_eopt_argv) {
		int argc = 0, i = 0, ret;
		struct bstr *args;
		char **argv;

		for (args = t->args; args; args = bstr_next(args))
			argc++;
		argv = calloc(argc, sizeof(char *));
		if (!argv)
			return -1;
		for (args = t->args; args; args = bstr_next(args))
			argv[i++] = args->data;

		ret = e->parse_eopt_argv(n, hdr, argc, argv);

		free(argv);
		return ret;
	}

	return e->parse_eopt(n, hdr, t->args->next);
}

static int parse_tree(struct nlmsghdr *n, struct ematch *tree)
{
	int index = 1;
	struct ematch *t;

	for (t = tree; t; t = t->next) {
		struct rtattr *tail;
		struct tcf_ematch_hdr hdr = { .flags = t->relation };

		if (t->inverted)
			hdr.flags |= TCF_EM_INVERT;

		tail = addattr_nest(n, MAX_MSG, index++);

		if (t->child) {
			__u32 r = t->child_ref;

			addraw_l(n, MAX_MSG, &hdr, sizeof(hdr));
			addraw_l(n, MAX_MSG, &r, sizeof(r));
		} else {
			int num = 0, err;
			char buf[64];
			struct ematch_util *e;

			if (t->args == NULL)
				return -1;

			strncpy(buf, (char *) t->args->data, sizeof(buf)-1);
			e = get_ematch_kind(buf);
			if (e == NULL) {
				fprintf(stderr, "Unknown ematch \"%s\"\n",
				    buf);
				return -1;
			}

			err = lookup_map_id(buf, &num, EMATCH_MAP);
			if (err < 0) {
				if (err == -ENOENT)
					map_warning(e->kind_num, buf);
				return err;
			}

			hdr.kind = num;
			if (em_parse_call(n, &hdr, e, t) < 0)
				return -1;
		}

		addattr_nest_end(n, tail);
	}

	return 0;
}

static int flatten_tree(struct ematch *head, struct ematch *tree)
{
	int i, count = 0;
	struct ematch *t;

	for (;;) {
		count++;

		if (tree->child) {
			for (t = head; t->next; t = t->next);
			t->next = tree->child;
			count += flatten_tree(head, tree->child);
		}

		if (tree->relation == 0)
			break;

		tree = tree->next;
	}

	for (i = 0, t = head; t; t = t->next, i++)
		t->index = i;

	for (t = head; t; t = t->next)
		if (t->child)
			t->child_ref = t->child->index;

	return count;
}

__attribute__((format(printf, 5, 6)))
int em_parse_error(int err, struct bstr *args, struct bstr *carg,
		   struct ematch_util *e, char *fmt, ...)
{
	va_list a;

	va_start(a, fmt);
	vfprintf(stderr, fmt, a);
	va_end(a);

	if (ematch_err)
		fprintf(stderr, ": %s\n... ", ematch_err);
	else
		fprintf(stderr, "\n... ");

	while (ematch_argc < begin_argc) {
		if (ematch_argc == (begin_argc - 1))
			fprintf(stderr, ">>%s<< ", *begin_argv);
		else
			fprintf(stderr, "%s ", *begin_argv);
		begin_argv++;
		begin_argc--;
	}

	fprintf(stderr, "...\n");

	if (args) {
		fprintf(stderr, "... %s(", e->kind);
		while (args) {
			fprintf(stderr, "%s", args == carg ? ">>" : "");
			bstr_print(stderr, args, 1);
			fprintf(stderr, "%s%s", args == carg ? "<<" : "",
			    args->next ? " " : "");
			args = args->next;
		}
		fprintf(stderr, ")...\n");

	}

	if (e == NULL) {
		fprintf(stderr,
		    "Usage: EXPR\n" \
		    "where: EXPR  := TERM [ { and | or } EXPR ]\n" \
		    "       TERM  := [ not ] { MATCH | '(' EXPR ')' }\n" \
		    "       MATCH := module '(' ARGS ')'\n" \
		    "       ARGS := ARG1 ARG2 ...\n" \
		    "\n" \
		    "Example: a(x y) and not (b(x) or c(x y z))\n");
	} else
		e->print_usage(stderr);

	return -err;
}

static inline void free_ematch_err(void)
{
	if (ematch_err) {
		free(ematch_err);
		ematch_err = NULL;
	}
}

extern int ematch_parse(void);

int parse_ematch(int *argc_p, char ***argv_p, int tca_id, struct nlmsghdr *n)
{
	begin_argc = ematch_argc = *argc_p;
	begin_argv = ematch_argv = *argv_p;

	if (ematch_parse()) {
		int err = em_parse_error(EINVAL, NULL, NULL, NULL,
		    "Parse error");
		free_ematch_err();
		return err;
	}

	free_ematch_err();

	/* undo look ahead by parser */
	ematch_argc++;
	ematch_argv--;

	if (ematch_root) {
		struct rtattr *tail, *tail_list;

		struct tcf_ematch_tree_hdr hdr = {
			.nmatches = flatten_tree(ematch_root, ematch_root),
			.progid = TCF_EM_PROG_TC
		};

		tail = addattr_nest(n, MAX_MSG, tca_id);
		addattr_l(n, MAX_MSG, TCA_EMATCH_TREE_HDR, &hdr, sizeof(hdr));

		tail_list = addattr_nest(n, MAX_MSG, TCA_EMATCH_TREE_LIST);

		if (parse_tree(n, ematch_root) < 0)
			return -1;

		addattr_nest_end(n, tail_list);
		addattr_nest_end(n, tail);
	}

	*argc_p = ematch_argc;
	*argv_p = ematch_argv;

	return 0;
}

static int print_ematch_seq(FILE *fd, struct rtattr **tb, int start,
			    int prefix)
{
	int n, i = start;
	struct tcf_ematch_hdr *hdr;
	int dlen;
	void *data;

	for (;;) {
		if (tb[i] == NULL)
			return -1;

		dlen = RTA_PAYLOAD(tb[i]) - sizeof(*hdr);
		data = (void *) RTA_DATA(tb[i]) + sizeof(*hdr);

		if (dlen < 0)
			return -1;

		hdr = RTA_DATA(tb[i]);

		if (hdr->flags & TCF_EM_INVERT)
			fprintf(fd, "NOT ");

		if (hdr->kind == 0) {
			__u32 ref;

			if (dlen < sizeof(__u32))
				return -1;

			ref = *(__u32 *) data;
			fprintf(fd, "(\n");
			for (n = 0; n <= prefix; n++)
				fprintf(fd, "  ");
			if (print_ematch_seq(fd, tb, ref + 1, prefix + 1) < 0)
				return -1;
			for (n = 0; n < prefix; n++)
				fprintf(fd, "  ");
			fprintf(fd, ") ");

		} else {
			struct ematch_util *e;

			e = get_ematch_kind_num(hdr->kind);
			if (e == NULL)
				fprintf(fd, "[unknown ematch %d]\n",
				    hdr->kind);
			else {
				fprintf(fd, "%s(", e->kind);
				if (e->print_eopt(fd, hdr, data, dlen) < 0)
					return -1;
				fprintf(fd, ")\n");
			}
			if (hdr->flags & TCF_EM_REL_MASK)
				for (n = 0; n < prefix; n++)
					fprintf(fd, "  ");
		}

		switch (hdr->flags & TCF_EM_REL_MASK) {
			case TCF_EM_REL_AND:
				fprintf(fd, "AND ");
				break;

			case TCF_EM_REL_OR:
				fprintf(fd, "OR ");
				break;

			default:
				return 0;
		}

		i++;
	}

	return 0;
}

static int print_ematch_list(FILE *fd, struct tcf_ematch_tree_hdr *hdr,
			     struct rtattr *rta)
{
	int err = -1;
	struct rtattr **tb;

	tb = malloc((hdr->nmatches + 1) * sizeof(struct rtattr *));
	if (tb == NULL)
		return -1;

	if (hdr->nmatches > 0) {
		if (parse_rtattr_nested(tb, hdr->nmatches, rta) < 0)
			goto errout;

		fprintf(fd, "\n  ");
		if (print_ematch_seq(fd, tb, 1, 1) < 0)
			goto errout;
	}

	err = 0;
errout:
	free(tb);
	return err;
}

int print_ematch(FILE *fd, const struct rtattr *rta)
{
	struct rtattr *tb[TCA_EMATCH_TREE_MAX+1];
	struct tcf_ematch_tree_hdr *hdr;

	if (parse_rtattr_nested(tb, TCA_EMATCH_TREE_MAX, rta) < 0)
		return -1;

	if (tb[TCA_EMATCH_TREE_HDR] == NULL) {
		fprintf(stderr, "Missing ematch tree header\n");
		return -1;
	}

	if (tb[TCA_EMATCH_TREE_LIST] == NULL) {
		fprintf(stderr, "Missing ematch tree list\n");
		return -1;
	}

	if (RTA_PAYLOAD(tb[TCA_EMATCH_TREE_HDR]) < sizeof(*hdr)) {
		fprintf(stderr, "Ematch tree header size mismatch\n");
		return -1;
	}

	hdr = RTA_DATA(tb[TCA_EMATCH_TREE_HDR]);

	return print_ematch_list(fd, hdr, tb[TCA_EMATCH_TREE_LIST]);
}

struct bstr *bstr_alloc(const char *text)
{
	struct bstr *b = calloc(1, sizeof(*b));

	if (b == NULL)
		return NULL;

	b->data = strdup(text);
	if (b->data == NULL) {
		free(b);
		return NULL;
	}

	b->len = strlen(text);

	return b;
}

unsigned long bstrtoul(const struct bstr *b)
{
	char *inv = NULL;
	unsigned long l;
	char buf[b->len+1];

	memcpy(buf, b->data, b->len);
	buf[b->len] = '\0';

	l = strtoul(buf, &inv, 0);
	if (l == ULONG_MAX || inv == buf)
		return ULONG_MAX;

	return l;
}

static void bstr_print(FILE *fd, const struct bstr *b, int ascii)
{
	int i;
	char *s = b->data;

	if (ascii)
		for (i = 0; i < b->len; i++)
		    fprintf(fd, "%c", isprint(s[i]) ? s[i] : '.');
	else {
		for (i = 0; i < b->len; i++)
		    fprintf(fd, "%02x", s[i]);
		fprintf(fd, "\"");
		for (i = 0; i < b->len; i++)
		    fprintf(fd, "%c", isprint(s[i]) ? s[i] : '.');
		fprintf(fd, "\"");
	}
}
