/*
 * 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 <syslog.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 = NULL;
struct ematch *ematch_root;

static int begin_argc;
static char **begin_argv;

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[32];

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

	return get_ematch_kind(name);

	return NULL;
}

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 = NLMSG_TAIL(n);
		struct tcf_ematch_hdr hdr = {
			.flags = t->relation
		};

		if (t->inverted)
			hdr.flags |= TCF_EM_INVERT;
		
		addattr_l(n, MAX_MSG, index++, NULL, 0);

		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 (e->parse_eopt(n, &hdr, t->args->next) < 0)
				return -1;
		}

		tail->rta_len = (void*) NLMSG_TAIL(n) - (void*) 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;
}

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 = NLMSG_TAIL(n);
		addattr_l(n, MAX_MSG, tca_id, NULL, 0);
		addattr_l(n, MAX_MSG, TCA_EMATCH_TREE_HDR, &hdr, sizeof(hdr));

		tail_list = NLMSG_TAIL(n);
		addattr_l(n, MAX_MSG, TCA_EMATCH_TREE_LIST, NULL, 0);

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

		tail_list->rta_len = (void*) NLMSG_TAIL(n) - (void*) tail_list;
		tail->rta_len = (void*) NLMSG_TAIL(n) - (void*) 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 (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]);
}
