/*
 * m_pedit.c		generic packet editor actions module 
 *
 *		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:  J Hadi Salim (hadi@cyberus.ca) 
 * 
 * TODO: 
 * 	1) Big endian broken in some spots
 * 	2) A lot of this stuff was added on the fly; get a big double-double
 * 	and clean it up at some point.
 * 	
 */

#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 "utils.h"
#include "tc_util.h"
#include "m_pedit.h"

static struct m_pedit_util *pedit_list;
int pedit_debug = 1;

static void
p_explain(void)
{
	fprintf(stderr, "Usage: ... pedit <MUNGE>\n");
	fprintf(stderr,
		"Where: MUNGE := <RAW>|<LAYERED>\n" 
		"<RAW>:= <OFFSETC>[ATC]<CMD>\n "
		"OFFSETC:= offset <offval> <u8|u16|u32>\n "
		"ATC:= at <atval> offmask <maskval> shift <shiftval>\n "
		"NOTE: offval is byte offset, must be multiple of 4\n "
		"NOTE: maskval is a 32 bit hex number\n "
		"NOTE: shiftval is a is a shift value\n "
		"CMD:= clear | invert | set <setval>| retain\n "
		"<LAYERED>:= ip <ipdata> | ip6 <ip6data> \n "
		" | udp <udpdata> | tcp <tcpdata> | icmp <icmpdata> \n"
		"For Example usage look at the examples directory");

}

#define usage() return(-1)

static int 
pedit_parse_nopopt (int *argc_p, char ***argv_p,struct tc_pedit_sel *sel,struct tc_pedit_key *tkey) 
{
	int argc = *argc_p;
	char **argv = *argv_p;

	if (argc) {
		fprintf(stderr, "Unknown action  hence option \"%s\" is unparsable\n", *argv);
			return -1;
	}

	return 0;

}

struct m_pedit_util 
*get_pedit_kind(char *str)
{
	static void *pBODY;
	void *dlh;
	char buf[256];
	struct  m_pedit_util *p;

	for (p = pedit_list; p; p = p->next) {
		if (strcmp(p->id, str) == 0)
			return p;
	}

	snprintf(buf, sizeof(buf), "p_%s.so", str);
	dlh = dlopen(buf, RTLD_LAZY);
	if (dlh == NULL) {
		dlh = pBODY;
		if (dlh == NULL) {
			dlh = pBODY = dlopen(NULL, RTLD_LAZY);
			if (dlh == NULL)
				goto noexist;
		}
	}

	snprintf(buf, sizeof(buf), "p_pedit_%s", str);
	p = dlsym(dlh, buf);
	if (p == NULL)
		goto noexist;

reg:
	p->next = pedit_list;
	pedit_list = p;
	return p;

noexist:
	p = malloc(sizeof(*p));
	if (p) {
		memset(p, 0, sizeof(*p));
		strncpy(p->id, str, sizeof(p->id)-1);
		p->parse_peopt = pedit_parse_nopopt;
		goto reg;
	}
	return p;
}

int
pack_key(struct tc_pedit_sel *sel,struct tc_pedit_key *tkey)
{
	int hwm = sel->nkeys;

	if (hwm >= MAX_OFFS)
		return -1;

	if (tkey->off % 4) {
		fprintf(stderr, "offsets MUST be in 32 bit boundaries\n");
		return -1;
	}

	sel->keys[hwm].val = tkey->val;
	sel->keys[hwm].mask = tkey->mask;
	sel->keys[hwm].off = tkey->off;
	sel->keys[hwm].at = tkey->at;
	sel->keys[hwm].offmask = tkey->offmask;
	sel->keys[hwm].shift = tkey->shift;
	sel->nkeys++;
	return 0;
}


int
pack_key32(__u32 retain,struct tc_pedit_sel *sel,struct tc_pedit_key *tkey)
{
	if (tkey->off > (tkey->off & ~3)) {
		fprintf(stderr,
			"pack_key32: 32 bit offsets must begin in 32bit boundaries\n");
		return -1;
	}

	tkey->val = htonl(tkey->val & retain);
	tkey->mask = htonl(tkey->mask | ~retain);
	/* jamal remove this - it is not necessary given the if check above */
	tkey->off &= ~3;
	return pack_key(sel,tkey);
}

int
pack_key16(__u32 retain,struct tc_pedit_sel *sel,struct tc_pedit_key *tkey)
{
	int ind = 0, stride = 0;
	__u32 m[4] = {0xFFFF0000,0xFF0000FF,0x0000FFFF};

	if (0 > tkey->off) {
		ind = tkey->off + 1;
		if (0 > ind)
			ind = -1*ind;
	} else {
		ind = tkey->off;
	}

	if (tkey->val > 0xFFFF || tkey->mask > 0xFFFF) {
		fprintf(stderr, "pack_key16 bad value\n");
		return -1;
	}

	ind = tkey->off & 3;

	if (0 > ind || 2 < ind) {
		fprintf(stderr, "pack_key16 bad index value %d\n",ind);
		return -1;
	}

	stride = 8 * ind;
	tkey->val = htons(tkey->val);
	if (stride > 0) {
		tkey->val <<= stride;
		tkey->mask <<= stride;
		retain <<= stride;
	}
	tkey->mask = retain|m[ind];

	tkey->off &= ~3;

	if (pedit_debug)
		printf("pack_key16: Final val %08x mask %08x \n",tkey->val,tkey->mask);
	return pack_key(sel,tkey);

}

int
pack_key8(__u32 retain,struct tc_pedit_sel *sel,struct tc_pedit_key *tkey)
{
	int ind = 0, stride = 0;
	__u32 m[4] = {0xFFFFFF00,0xFFFF00FF,0xFF00FFFF,0x00FFFFFF};

	if (0 > tkey->off) {
		ind = tkey->off + 1;
		if (0 > ind)
			ind = -1*ind;
	} else {
		ind = tkey->off;
	}

	if (tkey->val > 0xFF || tkey->mask > 0xFF) {
		fprintf(stderr, "pack_key8 bad value (val %x mask %x\n", tkey->val, tkey->mask);
		return -1;
	}

	ind = tkey->off & 3;
	stride = 8 * ind;
	tkey->val <<= stride;
	tkey->mask <<= stride;
	retain <<= stride;
	tkey->mask = retain|m[ind];
	tkey->off &= ~3;
	
	if (pedit_debug)
		printf("pack_key8: Final word off %d  val %08x mask %08x \n",tkey->off , tkey->val,tkey->mask);
	return pack_key(sel,tkey);
}

int
parse_val(int *argc_p, char ***argv_p, __u32 * val, int type)
{
	int argc = *argc_p;
	char **argv = *argv_p;

	if (argc <= 0)
		return -1;

	if (TINT == type)
		return get_integer((int *) val, *argv, 0);

	if (TU32 == type)
		return get_u32(val, *argv, 0);

	if (TIPV4 == type) {
		inet_prefix addr;
		if (get_prefix_1(&addr, *argv, AF_INET)) {
			return -1;
		}
		*val=addr.data[0];
		return 0;
	}
	if (TIPV6 == type) {
		/* not implemented yet */
		return -1;
	}

	return -1;
}

int
parse_cmd(int *argc_p, char ***argv_p, __u32 len, int type,__u32 retain,struct tc_pedit_sel *sel,struct tc_pedit_key *tkey)
{
	__u32 mask = 0, val = 0;
	__u32 o = 0xFF;
	int res = -1;
	int argc = *argc_p;
	char **argv = *argv_p;

	if (argc <= 0)
		return -1;

	if (pedit_debug)
		printf("parse_cmd argc %d %s offset %d length %d\n",argc,*argv,tkey->off,len);

	if (len == 2)
		o = 0xFFFF;
	if (len == 4)
		o = 0xFFFFFFFF;

	if (matches(*argv, "invert") == 0) {
		retain = val = mask = o;
	} else if (matches(*argv, "set") == 0) {
		NEXT_ARG();
		if (parse_val(&argc, &argv, &val, type))
			return -1;
	} else if (matches(*argv, "preserve") == 0) {
		retain = mask = o;
	} else {
		if (matches(*argv, "clear") != 0) 
			return -1;
	}

	argc--; argv++;

	if (argc && matches(*argv, "retain") == 0) {
		NEXT_ARG();
		if (parse_val(&argc, &argv, &retain, TU32))
			return -1;
		argc--; argv++;
	}

	tkey->val = val;

	if (len == 1) {
		tkey->mask = 0xFF;
		res = pack_key8(retain,sel,tkey);
		goto done;
	}
	if (len == 2) {
		tkey->mask = mask;
		res = pack_key16(retain,sel,tkey);
		goto done;
	}
	if (len == 4) {
		tkey->mask = mask;
		res = pack_key32(retain,sel,tkey);
		goto done;
	}

	return -1;
done:
	if (pedit_debug)
		printf("parse_cmd done argc %d %s offset %d length %d\n",argc,*argv,tkey->off,len);
	*argc_p = argc;
	*argv_p = argv;
	return res;

}

int
parse_offset(int *argc_p, char ***argv_p,struct tc_pedit_sel *sel,struct tc_pedit_key *tkey)
{
	int off;
	__u32 len, retain;
	int argc = *argc_p;
	char **argv = *argv_p;
	int res = -1;

	if (argc <= 0)
		return -1;

	if (get_integer(&off, *argv, 0))
		return -1;
	tkey->off = off;

	argc--;
	argv++;

	if (argc <= 0)
		return -1;


	if (matches(*argv, "u32") == 0) {
		len = 4;
		retain = 0xFFFFFFFF;
		goto done;
	}
	if (matches(*argv, "u16") == 0) {
		len = 2;
		retain = 0x0;
		goto done;
	}
	if (matches(*argv, "u8") == 0) {
		len = 1;
		retain = 0x0;
		goto done;
	}

	return -1;

done:

	NEXT_ARG();

	/* [at <someval> offmask <maskval> shift <shiftval>] */
	if (matches(*argv, "at") == 0) {

		__u32 atv=0,offmask=0x0,shift=0;

		NEXT_ARG();
		if (get_u32(&atv, *argv, 0))
			return -1;
		tkey->at = atv;

		NEXT_ARG();
		
		if (get_u32(&offmask, *argv, 16))
			return -1;
		tkey->offmask = offmask;

		NEXT_ARG();

		if (get_u32(&shift, *argv, 0))
			return -1;
		tkey->shift = shift;

		NEXT_ARG();
	}

	res = parse_cmd(&argc, &argv, len, TU32,retain,sel,tkey);

	*argc_p = argc;
	*argv_p = argv;
	return res;
}

int
parse_munge(int *argc_p, char ***argv_p,struct tc_pedit_sel *sel)
{
	struct tc_pedit_key tkey;
	int argc = *argc_p;
	char **argv = *argv_p;
	int res = -1;

	if (argc <= 0)
		return -1;

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

	if (matches(*argv, "offset") == 0) {
		NEXT_ARG();
		res = parse_offset(&argc, &argv,sel,&tkey);
		goto done;
#if jamal
	} else if (strcmp(*argv, "help") == 0) {
		p_explain();
		return -1;
#endif
	} else {
		char k[16];
		struct m_pedit_util *p = NULL;

		strncpy(k, *argv, sizeof (k) - 1);

		if (argc > 0 ) {
			p = get_pedit_kind(k);
			if (NULL == p)
				goto bad_val;
			res = p->parse_peopt(&argc, &argv, sel,&tkey);
			if (res < 0) {
				fprintf(stderr,"bad pedit parsing\n");
				goto bad_val;
			}
			goto done;
		}
	}

bad_val:
	return -1;

done:

	*argc_p = argc;
	*argv_p = argv;
	return res;
}

int
parse_pedit(struct action_util *a, int *argc_p, char ***argv_p, int tca_id, struct nlmsghdr *n)
{
	struct {
		struct tc_pedit_sel sel;
		struct tc_pedit_key keys[MAX_OFFS];
	} sel;

	int argc = *argc_p;
	char **argv = *argv_p;
	int ok = 0, iok = 0;
	struct rtattr *tail;

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

	while (argc > 0) {
		if (pedit_debug > 1)
			fprintf(stderr, "while pedit (%d:%s)\n",argc, *argv);
		if (matches(*argv, "pedit") == 0) {
			NEXT_ARG();
			ok++;
			continue;
		} else if (matches(*argv, "munge") == 0) {
			if (!ok) {
				fprintf(stderr, "Illegal pedit construct (%s) \n", *argv);
				p_explain();
				return -1;
			}
			NEXT_ARG();
			if (parse_munge(&argc, &argv,&sel.sel)) {
				fprintf(stderr, "Illegal pedit construct (%s) \n", *argv);
				p_explain();
				return -1;
			}
			ok++;
		} else {
			break;
		}

	}

	if (!ok) {
		p_explain();
		return -1;
	}

	if (argc) {
		if (matches(*argv, "reclassify") == 0) {
			sel.sel.action = TC_ACT_RECLASSIFY;
			NEXT_ARG();
		} else if (matches(*argv, "pipe") == 0) {
			sel.sel.action = TC_ACT_PIPE;
			NEXT_ARG();
		} else if (matches(*argv, "drop") == 0 ||
			matches(*argv, "shot") == 0) {
			sel.sel.action = TC_ACT_SHOT;
			NEXT_ARG();
		} else if (matches(*argv, "continue") == 0) {
			sel.sel.action = TC_ACT_UNSPEC;
			NEXT_ARG();
		} else if (matches(*argv, "pass") == 0) {
			sel.sel.action = TC_ACT_OK;
			NEXT_ARG();
		}
	}

	if (argc) {
		if (matches(*argv, "index") == 0) {
			NEXT_ARG();
			if (get_u32(&sel.sel.index, *argv, 10)) {
				fprintf(stderr, "Pedit: Illegal \"index\"\n");
				return -1;
			}
			argc--;
			argv++;
			iok++;
		}
	}

	tail = NLMSG_TAIL(n);
	addattr_l(n, MAX_MSG, tca_id, NULL, 0);
	addattr_l(n, MAX_MSG, TCA_PEDIT_PARMS,&sel, sizeof(sel.sel)+sel.sel.nkeys*sizeof(struct tc_pedit_key));
	tail->rta_len = (void *) NLMSG_TAIL(n) - (void *) tail;

	*argc_p = argc;
	*argv_p = argv;
	return 0;
}

int
print_pedit(struct action_util *au,FILE * f, struct rtattr *arg)
{
	struct tc_pedit_sel *sel;
	struct rtattr *tb[TCA_PEDIT_MAX + 1];
	SPRINT_BUF(b1);

	if (arg == NULL)
		return -1;

	parse_rtattr_nested(tb, TCA_PEDIT_MAX, arg);

	if (tb[TCA_PEDIT_PARMS] == NULL) {
		fprintf(f, "[NULL pedit parameters]");
		return -1;
	}
	sel = RTA_DATA(tb[TCA_PEDIT_PARMS]);

	fprintf(f, " pedit action %s keys %d\n ", action_n2a(sel->action, b1, sizeof (b1)),sel->nkeys);
	fprintf(f, "\t index %d ref %d bind %d", sel->index,sel->refcnt, sel->bindcnt);

	if (show_stats) {
		if (tb[TCA_PEDIT_TM]) {
			struct tcf_t *tm = RTA_DATA(tb[TCA_PEDIT_TM]);
			print_tm(f,tm);
		}
	}
	if (sel->nkeys) {
		int i;
		struct tc_pedit_key *key = sel->keys;

		for (i=0; i<sel->nkeys; i++, key++) {
			fprintf(f, "\n\t key #%d",i);
			fprintf(f, "  at %d: val %08x mask %08x",
			(unsigned int)key->off,
			(unsigned int)ntohl(key->val),
			(unsigned int)ntohl(key->mask));
		}
	} else {
		fprintf(f, "\npedit %x keys %d is not LEGIT", sel->index,sel->nkeys);
	}


	fprintf(f, "\n ");
	return 0;
}

int 
pedit_print_xstats(struct action_util *au, FILE *f, struct rtattr *xstats)
{
	return 0;
}

struct action_util pedit_action_util = {
	.id = "pedit",
	.parse_aopt = parse_pedit,
	.print_aopt = print_pedit,
};
