/*
 * em_meta.c		Metadata Ematch
 *
 *		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 <errno.h>

#include "m_ematch.h"
#include <linux/tc_ematch/tc_em_meta.h>

extern struct ematch_util meta_ematch_util;

static void meta_print_usage(FILE *fd)
{
	fprintf(fd,
	    "Usage: meta(OBJECT { eq | lt | gt } OBJECT)\n" \
	    "where: OBJECT  := { META_ID | VALUE }\n" \
	    "       META_ID := id [ shift SHIFT ] [ mask MASK ]\n" \
	    "\n" \
	    "Example: meta(nfmark gt 24)\n" \
	    "         meta(indev shift 1 eq \"ppp\"\n" \
	    "         meta(tcindex mask 0xf0 eq 0xf0)\n" \
	    "         meta(dev eq indev)\n" \
	    "\n" \
	    "For a list of meta identifiers, use meta(list).\n");
}

struct meta_entry {
	int		id;
	char *		kind;
	char *		mask;
	char *		desc;
} meta_table[] = {
#define TCF_META_ID_SECTION 0
#define __A(id, name, mask, desc) { TCF_META_ID_##id, name, mask, desc }
	__A(SECTION,		"Generic", "", ""),
	__A(RANDOM,		"random",	"i",
				"Random value (32 bit)"),
	__A(LOADAVG_0,		"loadavg_1",	"i",
				"Load average in last minute"),
	__A(LOADAVG_1,		"loadavg_5",	"i",
				"Load average in last 5 minutes"),
	__A(LOADAVG_2,		"loadavg_15",	"i",
				"Load average in last 15 minutes"),

	__A(SECTION,		"Interfaces", "", ""),
	__A(DEV,		"dev",		"iv",
				"Device the packet is on"),
	__A(SECTION,		"Packet attributes", "", ""),
	__A(PRIORITY,		"priority",	"i",
				"Priority of packet"),
	__A(PROTOCOL,		"protocol",	"i",
				"Link layer protocol"),
	__A(PKTTYPE,		"pkt_type",	"i",
				"Packet type (uni|multi|broad|...)cast"),
	__A(PKTLEN,		"pkt_len",	"i",
				"Length of packet"),
	__A(DATALEN,		"data_len",	"i",
				"Length of data in packet"),
	__A(MACLEN,		"mac_len",	"i",
				"Length of link layer header"),

	__A(SECTION,		"Netfilter", "", ""),
	__A(NFMARK,		"nf_mark",	"i",
				"Netfilter mark"),
	__A(NFMARK,		"fwmark",	"i",
				"Alias for nf_mark"),

	__A(SECTION,		"Traffic Control", "", ""),
	__A(TCINDEX,		"tc_index",	"i",	"TC Index"),
	__A(SECTION,		"Routing", "", ""),
	__A(RTCLASSID,		"rt_classid",	"i",
				"Routing ClassID (cls_route)"),
	__A(RTIIF,		"rt_iif",	"i",
				"Incoming interface index"),

	__A(SECTION,		"Sockets", "", ""),
	__A(SK_FAMILY,		"sk_family",	"i",	"Address family"),
	__A(SK_STATE,		"sk_state",	"i",	"State"),
	__A(SK_REUSE,		"sk_reuse",	"i",	"Reuse Flag"),
	__A(SK_BOUND_IF,	"sk_bind_if",	"iv",	"Bound interface"),
	__A(SK_REFCNT,		"sk_refcnt",	"i",	"Reference counter"),
	__A(SK_SHUTDOWN,	"sk_shutdown",	"i",	"Shutdown mask"),
	__A(SK_PROTO,		"sk_proto",	"i",	"Protocol"),
	__A(SK_TYPE,		"sk_type",	"i",	"Type"),
	__A(SK_RCVBUF,		"sk_rcvbuf",	"i",	"Receive buffer size"),
	__A(SK_RMEM_ALLOC,	"sk_rmem",	"i",	"RMEM"),
	__A(SK_WMEM_ALLOC,	"sk_wmem",	"i",	"WMEM"),
	__A(SK_OMEM_ALLOC,	"sk_omem",	"i",	"OMEM"),
	__A(SK_WMEM_QUEUED,	"sk_wmem_queue","i",	"WMEM queue"),
	__A(SK_SND_QLEN,	"sk_snd_queue",	"i",	"Send queue length"),
	__A(SK_RCV_QLEN,	"sk_rcv_queue",	"i",	"Receive queue length"),
	__A(SK_ERR_QLEN,	"sk_err_queue",	"i",	"Error queue length"),
	__A(SK_FORWARD_ALLOCS,	"sk_fwd_alloc",	"i",	"Forward allocations"),
	__A(SK_SNDBUF,		"sk_sndbuf",	"i",	"Send buffer size"),
#undef __A
};

static inline int map_type(char k)
{
	switch (k) {
		case 'i': return TCF_META_TYPE_INT;
		case 'v': return TCF_META_TYPE_VAR;
	}

	fprintf(stderr, "BUG: Unknown map character '%c'\n", k);
	return INT_MAX;
}

static struct meta_entry * lookup_meta_entry(struct bstr *kind)
{
	int i;

	for (i = 0; i < (sizeof(meta_table)/sizeof(meta_table[0])); i++)
		if (!bstrcmp(kind, meta_table[i].kind) &&
		    meta_table[i].id != 0)
			return &meta_table[i];
	
	return NULL;
}

static struct meta_entry * lookup_meta_entry_byid(int id)
{
	int i;

	for (i = 0; i < (sizeof(meta_table)/sizeof(meta_table[0])); i++)
		if (meta_table[i].id == id)
			return &meta_table[i];
	
	return NULL;
}

static inline void dump_value(struct nlmsghdr *n, int tlv, unsigned long val,
			      struct tcf_meta_val *hdr)
{
	__u32 t;

	switch (TCF_META_TYPE(hdr->kind)) {
		case TCF_META_TYPE_INT:
			t = val;
			addattr_l(n, MAX_MSG, tlv, &t, sizeof(t));
			break;

		case TCF_META_TYPE_VAR:
			if (TCF_META_ID(hdr->kind) == TCF_META_ID_VALUE) {
				struct bstr *a = (struct bstr *) val;
				addattr_l(n, MAX_MSG, tlv, a->data, a->len);
			}
			break;
	}
}

static inline int is_compatible(struct tcf_meta_val *what,
				struct tcf_meta_val *needed)
{
	char *p;
	struct meta_entry *entry;
	
	entry = lookup_meta_entry_byid(TCF_META_ID(what->kind));

	if (entry == NULL)
		return 0;
	
	for (p = entry->mask; p; p++)
		if (map_type(*p) == TCF_META_TYPE(needed->kind))
			return 1;

	return 0;
}

static void list_meta_ids(FILE *fd)
{
	int i;

	fprintf(fd,
	    "--------------------------------------------------------\n" \
	    "  ID               Type       Description\n" \
	    "--------------------------------------------------------");

	for (i = 0; i < (sizeof(meta_table)/sizeof(meta_table[0])); i++) {
		if (meta_table[i].id == TCF_META_ID_SECTION) {
			fprintf(fd, "\n%s:\n", meta_table[i].kind);
		} else {
			char *p = meta_table[i].mask;
			char buf[64] = {0};

			fprintf(fd, "  %-16s ", meta_table[i].kind);

			while (*p) {
				int type = map_type(*p);

				switch (type) {
					case TCF_META_TYPE_INT:
						strcat(buf, "INT");
						break;

					case TCF_META_TYPE_VAR:
						strcat(buf, "VAR");
						break;
				}

				if (*(++p))
					strcat(buf, ",");
			}

			fprintf(fd, "%-10s %s\n", buf, meta_table[i].desc);
		}
	}

	fprintf(fd,
	    "--------------------------------------------------------\n");
}

#undef TCF_META_ID_SECTION

#define PARSE_FAILURE ((void *) (-1))

#define PARSE_ERR(CARG, FMT, ARGS...) \
	em_parse_error(EINVAL, args, CARG, &meta_ematch_util, FMT ,##ARGS)

static inline int can_adopt(struct tcf_meta_val *val)
{
	return !!TCF_META_ID(val->kind);
}

static inline int overwrite_type(struct tcf_meta_val *src,
				 struct tcf_meta_val *dst)
{
	return (TCF_META_TYPE(dst->kind) << 12) | TCF_META_ID(src->kind);
}
	

static inline struct bstr *
parse_object(struct bstr *args, struct bstr *arg, struct tcf_meta_val *obj,
	     unsigned long *dst, struct tcf_meta_val *left)
{
	struct meta_entry *entry;
	unsigned long num;
	struct bstr *a;

	if (arg->quoted) {
		obj->kind = TCF_META_TYPE_VAR << 12;
		obj->kind |= TCF_META_ID_VALUE;
		*dst = (unsigned long) arg;
		return bstr_next(arg);
	}

	num = bstrtoul(arg);
	if (num != LONG_MAX) {
		obj->kind = TCF_META_TYPE_INT << 12;
		obj->kind |= TCF_META_ID_VALUE;
		*dst = (unsigned long) num;
		return bstr_next(arg);
	}

	entry = lookup_meta_entry(arg);

	if (entry == NULL) {
		PARSE_ERR(arg, "meta: unknown meta id\n");
		return PARSE_FAILURE;
	}

	obj->kind = entry->id | (map_type(entry->mask[0]) << 12);

	if (left) {
		struct tcf_meta_val *right = obj;
		
		if (TCF_META_TYPE(right->kind) == TCF_META_TYPE(left->kind))
			goto compatible;

		if (can_adopt(left) && !can_adopt(right)) {
			if (is_compatible(left, right))
				left->kind = overwrite_type(left, right);
			else
				goto not_compatible;
		} else if (can_adopt(right) && !can_adopt(left)) {
			if (is_compatible(right, left))
				right->kind = overwrite_type(right, left);
			else
				goto not_compatible;
		} else if (can_adopt(left) && can_adopt(right)) {
			if (is_compatible(left, right))
				left->kind = overwrite_type(left, right);
			else if (is_compatible(right, left))
				right->kind = overwrite_type(right, left);
			else
				goto not_compatible;
		} else 
			goto not_compatible;
	}

compatible:

	a = bstr_next(arg);

	while(a) {
		if (!bstrcmp(a, "shift")) {
			unsigned long shift;

			if (a->next == NULL) {
				PARSE_ERR(a, "meta: missing argument");
				return PARSE_FAILURE;
			}
			a = bstr_next(a);
			
			shift = bstrtoul(a);
			if (shift == LONG_MAX) {
				PARSE_ERR(a, "meta: invalid shift, must " \
				    "be numeric");
				return PARSE_FAILURE;
			}

			obj->shift = (__u8) shift;
			a = bstr_next(a);
		} else if (!bstrcmp(a, "mask")) {
			unsigned long mask;

			if (a->next == NULL) {
				PARSE_ERR(a, "meta: missing argument");
				return PARSE_FAILURE;
			}
			a = bstr_next(a);
			
			mask = bstrtoul(a);
			if (mask == LONG_MAX) {
				PARSE_ERR(a, "meta: invalid mask, must be " \
				    "numeric");
				return PARSE_FAILURE;
			}
			*dst = (unsigned long) mask;
			a = bstr_next(a);
		} else
			break;
	}

	return a;

not_compatible:
	PARSE_ERR(arg, "lvalue and rvalue are not compatible.");
	return PARSE_FAILURE;
}

static int meta_parse_eopt(struct nlmsghdr *n, struct tcf_ematch_hdr *hdr,
			   struct bstr *args)
{
	int opnd;
	struct bstr *a;
	struct tcf_meta_hdr meta_hdr;
	unsigned long lvalue = 0, rvalue = 0;

	memset(&meta_hdr, 0, sizeof(meta_hdr));

	if (args == NULL)
		return PARSE_ERR(args, "meta: missing arguments");

	if (!bstrcmp(args, "list")) {
		list_meta_ids(stderr);
		return -1;
	}

	a = parse_object(args, args, &meta_hdr.left, &lvalue, NULL);
	if (a == PARSE_FAILURE)
		return -1;
	else if (a == NULL)
		return PARSE_ERR(args, "meta: missing operand");

	if (!bstrcmp(a, "eq"))
		opnd = TCF_EM_OPND_EQ;
	else if (!bstrcmp(a, "gt"))
		opnd = TCF_EM_OPND_GT;
	else if (!bstrcmp(a, "lt"))
		opnd = TCF_EM_OPND_LT;
	else
		return PARSE_ERR(a, "meta: invalid operand");

	meta_hdr.left.op = (__u8) opnd;

	if (a->next == NULL)
		return PARSE_ERR(args, "meta: missing rvalue");
	a = bstr_next(a);

	a = parse_object(args, a, &meta_hdr.right, &rvalue, &meta_hdr.left);
	if (a == PARSE_FAILURE)
		return -1;
	else if (a != NULL)
		return PARSE_ERR(a, "meta: unexpected trailer");
	

	addraw_l(n, MAX_MSG, hdr, sizeof(*hdr));

	addattr_l(n, MAX_MSG, TCA_EM_META_HDR, &meta_hdr, sizeof(meta_hdr));

	if (lvalue)
		dump_value(n, TCA_EM_META_LVALUE, lvalue, &meta_hdr.left);

	if (rvalue)
		dump_value(n, TCA_EM_META_RVALUE, rvalue, &meta_hdr.right);

	return 0;
}
#undef PARSE_ERR

static inline void print_binary(FILE *fd, unsigned char *str, int len)
{
	int i;

	for (i = 0; i < len; i++)
		if (!isprint(str[i]))
			goto binary;

	for (i = 0; i < len; i++)
		fprintf(fd, "%c", str[i]);
	return;

binary:
	for (i = 0; i < len; i++)
		fprintf(fd, "%02x ", str[i]);

	fprintf(fd, "\"");
	for (i = 0; i < len; i++)
		fprintf(fd, "%c", isprint(str[i]) ? str[i] : '.');
	fprintf(fd, "\"");
}

static inline int print_value(FILE *fd, int type, struct rtattr *rta)
{
	if (rta == NULL) {
		fprintf(stderr, "Missing value TLV\n");
		return -1;
	}

	switch(type) {
		case TCF_META_TYPE_INT:
			if (RTA_PAYLOAD(rta) < sizeof(__u32)) {
				fprintf(stderr, "meta int type value TLV " \
				    "size mismatch.\n");
				return -1;
			}
			fprintf(fd, "%d", *(__u32 *) RTA_DATA(rta));
			break;

		case TCF_META_TYPE_VAR:
			print_binary(fd, RTA_DATA(rta), RTA_PAYLOAD(rta));
			break;
	}

	return 0;
}

static int print_object(FILE *fd, struct tcf_meta_val *obj, struct rtattr *rta)
{
	int id = TCF_META_ID(obj->kind);
	int type = TCF_META_TYPE(obj->kind);
	struct meta_entry *entry;

	if (id == TCF_META_ID_VALUE)
		return print_value(fd, type, rta);

	entry = lookup_meta_entry_byid(id);

	if (entry == NULL)
		fprintf(fd, "[unknown meta id %d]", id);
	else
		fprintf(fd, "%s", entry->kind);

	if (obj->shift)
		fprintf(fd, " shift %d", obj->shift);

	switch (type) {
		case TCF_META_TYPE_INT:
			if (rta) {
				if (RTA_PAYLOAD(rta) < sizeof(__u32))
					goto size_mismatch;

				fprintf(fd, " mask 0x%08x",
				    *(__u32*) RTA_DATA(rta));
			}
			break;
	}

	return 0;

size_mismatch:
	fprintf(stderr, "meta int type mask TLV size mismatch\n");
	return -1;
}


static int meta_print_eopt(FILE *fd, struct tcf_ematch_hdr *hdr, void *data,
			   int data_len)
{
	struct rtattr *tb[TCA_EM_META_MAX+1];
	struct tcf_meta_hdr *meta_hdr;

	if (parse_rtattr(tb, TCA_EM_META_MAX, data, data_len) < 0)
		return -1;

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

	if (RTA_PAYLOAD(tb[TCA_EM_META_HDR]) < sizeof(*meta_hdr)) {
		fprintf(stderr, "Meta header size mismatch\n");
		return -1;
	}

	meta_hdr = RTA_DATA(tb[TCA_EM_META_HDR]);

	if (print_object(fd, &meta_hdr->left, tb[TCA_EM_META_LVALUE]) < 0)
		return -1;

	switch (meta_hdr->left.op) {
		case TCF_EM_OPND_EQ:
			fprintf(fd, " eq ");
			break;
		case TCF_EM_OPND_LT:
			fprintf(fd, " lt ");
			break;
		case TCF_EM_OPND_GT:
			fprintf(fd, " gt ");
			break;
	}

	return print_object(fd, &meta_hdr->right, tb[TCA_EM_META_RVALUE]);
}

struct ematch_util meta_ematch_util = {
	.kind = "meta",
	.kind_num = TCF_EM_META,
	.parse_eopt = meta_parse_eopt,
	.print_eopt = meta_print_eopt,
	.print_usage = meta_print_usage
};
