/*
 * m_ipt.c	iptables based targets 
 * 		utilities mostly ripped from iptables <duh, its the linux way>
 *
 *		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: bad bad hardcoding IPT_LIB_DIR and PROC_SYS_MODPROBE
 *
*/

#include <syslog.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <iptables.h>
#include <linux/netfilter_ipv4/ip_tables.h>
#include "utils.h"
#include "tc_util.h"
#include <linux/tc_act/tc_ipt.h>
#include <stdio.h>
#include <dlfcn.h>
#include <getopt.h>
#include <errno.h>
#include <string.h>
#include <netdb.h>
#include <stdlib.h>
#include <ctype.h>
#include <stdarg.h>
#include <limits.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/wait.h>

const char *pname = "tc-ipt";
const char *tname = "mangle";
const char *pversion = "0.1";

#ifndef TRUE
#define TRUE 1
#endif
#ifndef FALSE
#define FALSE 0
#endif

#ifndef IPT_LIB_DIR
#define IPT_LIB_DIR "/usr/local/lib/iptables"
#endif

#ifndef PROC_SYS_MODPROBE
#define PROC_SYS_MODPROBE "/proc/sys/kernel/modprobe"
#endif

static const char *ipthooks[] = {
	"NF_IP_PRE_ROUTING",
	"NF_IP_LOCAL_IN",
	"NF_IP_FORWARD",
	"NF_IP_LOCAL_OUT",
	"NF_IP_POST_ROUTING",
};

static struct option original_opts[] = {
	{"jump", 1, 0, 'j'},
	{0, 0, 0, 0}
};

static struct iptables_target *t_list = NULL;
static struct option *opts = original_opts;
static unsigned int global_option_offset = 0;
#define OPTION_OFFSET 256


void
register_target(struct iptables_target *me)
{
/*      fprintf(stderr, "\nDummy register_target %s \n", me->name);
*/
	me->next = t_list;
	t_list = me;

}

void
exit_tryhelp(int status)
{
	fprintf(stderr, "Try `%s -h' or '%s --help' for more information.\n",
		pname, pname);
	exit(status);
}

void
exit_error(enum exittype status, char *msg, ...)
{
	va_list args;

	va_start(args, msg);
	fprintf(stderr, "%s v%s: ", pname, pversion);
	vfprintf(stderr, msg, args);
	va_end(args);
	fprintf(stderr, "\n");
	if (status == PARAMETER_PROBLEM)
		exit_tryhelp(status);
	if (status == VERSION_PROBLEM)
		fprintf(stderr,
			"Perhaps iptables or your kernel needs to be upgraded.\n");
	exit(status);
}

/* stolen from iptables 1.2.11
They should really have them as a library so i can link to them
Email them next time i remember
*/

char *
addr_to_dotted(const struct in_addr *addrp)
{
	static char buf[20];
	const unsigned char *bytep;

	bytep = (const unsigned char *) &(addrp->s_addr);
	sprintf(buf, "%d.%d.%d.%d", bytep[0], bytep[1], bytep[2], bytep[3]);
	return buf;
}

int string_to_number_ll(const char *s, unsigned long long min, 
			unsigned long long max,
		 unsigned long long *ret)
{
	unsigned long long number;
	char *end;

	/* Handle hex, octal, etc. */
	errno = 0;
	number = strtoull(s, &end, 0);
	if (*end == '\0' && end != s) {
		/* we parsed a number, let's see if we want this */
		if (errno != ERANGE && min <= number && (!max || number <= max)) {
			*ret = number;
			return 0;
		}
	}
	return -1;
}

int string_to_number_l(const char *s, unsigned long min, unsigned long max,
		       unsigned long *ret)
{
	int result;
	unsigned long long number;

	result = string_to_number_ll(s, min, max, &number);
	*ret = (unsigned long)number;

	return result;
}

int string_to_number(const char *s, unsigned int min, unsigned int max,
		unsigned int *ret)
{
	int result;
	unsigned long number;

	result = string_to_number_l(s, min, max, &number);
	*ret = (unsigned int)number;

	return result;
}

static void free_opts(struct option *opts)
{
	if (opts != original_opts) {
		free(opts);
		opts = original_opts;
		global_option_offset = 0;
	}
}

static struct option *
merge_options(struct option *oldopts, const struct option *newopts,
	      unsigned int *option_offset)
{
	struct option *merge;
	unsigned int num_old, num_new, i;

	for (num_old = 0; oldopts[num_old].name; num_old++) ;
	for (num_new = 0; newopts[num_new].name; num_new++) ;

	*option_offset = global_option_offset + OPTION_OFFSET;

	merge = malloc(sizeof (struct option) * (num_new + num_old + 1));
	memcpy(merge, oldopts, num_old * sizeof (struct option));
	for (i = 0; i < num_new; i++) {
		merge[num_old + i] = newopts[i];
		merge[num_old + i].val += *option_offset;
	}
	memset(merge + num_old + num_new, 0, sizeof (struct option));

	return merge;
}

static void *
fw_calloc(size_t count, size_t size)
{
	void *p;

	if ((p = (void *) calloc(count, size)) == NULL) {
		perror("iptables: calloc failed");
		exit(1);
	}
	return p;
}

static struct iptables_target *
find_t(char *name)
{
	struct iptables_target *m;
	for (m = t_list; m; m = m->next) {
		if (strcmp(m->name, name) == 0)
			return m;
	}

	return NULL;
}

static struct iptables_target *
get_target_name(char *name)
{
	void *handle;
	char *error;
	char *new_name, *lname;
	struct iptables_target *m;

	char path[sizeof (IPT_LIB_DIR) + sizeof ("/libipt_.so") + strlen(name)];

	new_name = malloc(strlen(name) + 1);
	lname = malloc(strlen(name) + 1);
	if (new_name)
		memset(new_name, '\0', strlen(name) + 1);
	else
		exit_error(PARAMETER_PROBLEM, "get_target_name");

	if (lname)
		memset(lname, '\0', strlen(name) + 1);
	else
		exit_error(PARAMETER_PROBLEM, "get_target_name");

	strcpy(new_name, name);
	strcpy(lname, name);

	if (isupper(lname[0])) {
		int i;
		for (i = 0; i < strlen(name); i++) {
			lname[i] = tolower(lname[i]);
		}
	}

	if (islower(new_name[0])) {
		int i;
		for (i = 0; i < strlen(new_name); i++) {
			new_name[i] = toupper(new_name[i]);
		}
	}

	sprintf(path, IPT_LIB_DIR "/libipt_%s.so", new_name);
	handle = dlopen(path, RTLD_LAZY);
	if (!handle) {
		sprintf(path, IPT_LIB_DIR "/libipt_%s.so", lname);
		handle = dlopen(path, RTLD_LAZY);
		if (!handle) {
			fputs(dlerror(), stderr);
			printf("\n");
			return NULL;
		}
	}

	m = dlsym(handle, new_name);
	if ((error = dlerror()) != NULL) {
		m = (struct iptables_target *) dlsym(handle, lname);
		if ((error = dlerror()) != NULL) {
			m = find_t(new_name);
			if (NULL == m) {
				m = find_t(lname);
				if (NULL == m) {
					fputs(error, stderr);
					fprintf(stderr, "\n");
					dlclose(handle);
					return NULL;
				}
			}
		}
	}

	return m;
}


struct in_addr *dotted_to_addr(const char *dotted)
{
	static struct in_addr addr;
	unsigned char *addrp;
	char *p, *q;
	unsigned int onebyte;
	int i;
	char buf[20];

	/* copy dotted string, because we need to modify it */
	strncpy(buf, dotted, sizeof (buf) - 1);
	addrp = (unsigned char *) &(addr.s_addr);

	p = buf;
	for (i = 0; i < 3; i++) {
		if ((q = strchr(p, '.')) == NULL)
			return (struct in_addr *) NULL;

		*q = '\0';
		if (string_to_number(p, 0, 255, &onebyte) == -1)
			return (struct in_addr *) NULL;

		addrp[i] = (unsigned char) onebyte;
		p = q + 1;
	}

	/* we've checked 3 bytes, now we check the last one */
	if (string_to_number(p, 0, 255, &onebyte) == -1)
		return (struct in_addr *) NULL;

	addrp[3] = (unsigned char) onebyte;

	return &addr;
}

static void set_revision(char *name, u_int8_t revision)
{
	/* Old kernel sources don't have ".revision" field,
	*  but we stole a byte from name. */
	name[IPT_FUNCTION_MAXNAMELEN - 2] = '\0';
	name[IPT_FUNCTION_MAXNAMELEN - 1] = revision;
}

/* 
 * we may need to check for version mismatch
*/
int
build_st(struct iptables_target *target, struct ipt_entry_target *t)
{
	unsigned int nfcache = 0;

	if (target) {
		size_t size;

		size =
		    IPT_ALIGN(sizeof (struct ipt_entry_target)) + target->size;

		if (NULL == t) {
			target->t = fw_calloc(1, size);
			target->t->u.target_size = size;

			if (target->init != NULL)
				target->init(target->t, &nfcache);
			set_revision(target->t->u.user.name, target->revision);
		} else {
			target->t = t;
		}
		strcpy(target->t->u.user.name, target->name);
		return 0;
	}

	return -1;
}

static int parse_ipt(struct action_util *a,int *argc_p, 
		     char ***argv_p, int tca_id, struct nlmsghdr *n)
{
	struct iptables_target *m = NULL;
	struct ipt_entry fw;
	struct rtattr *tail;
	int c;
	int rargc = *argc_p;
	char **argv = *argv_p;
	int argc = 0, iargc = 0;
	char k[16];
	int res = -1;
	int size = 0;
	int iok = 0, ok = 0;
	__u32 hook = 0, index = 0;
	res = 0;

	{
		int i;
		for (i = 0; i < rargc; i++) {
			if (NULL == argv[i] || 0 == strcmp(argv[i], "action")) {
				break;
			}
		}
		iargc = argc = i;
	}

	if (argc <= 2) {
		fprintf(stderr,"bad arguements to ipt %d vs %d \n", argc, rargc);
		return -1;
	}

	while (1) {
		c = getopt_long(argc, argv, "j:", opts, NULL);
		if (c == -1)
			break;
		switch (c) {
		case 'j':
			m = get_target_name(optarg);
			if (NULL != m) {

				if (0 > build_st(m, NULL)) {
					printf(" %s error \n", m->name);
					return -1;
				}
				opts =
				    merge_options(opts, m->extra_opts,
						  &m->option_offset);
			} else {
				fprintf(stderr," failed to find target %s\n\n", optarg);
				return -1;
			}
			ok++;
			break;

		default:
			memset(&fw, 0, sizeof (fw));
			if (m) {
				m->parse(c - m->option_offset, argv, 0,
					 &m->tflags, NULL, &m->t);
			} else {
				fprintf(stderr," failed to find target %s\n\n", optarg);
				return -1;

			}
			ok++;
			break;

		}
	}

	if (iargc > optind) {
		if (matches(argv[optind], "index") == 0) {
			if (get_u32(&index, argv[optind + 1], 10)) {
				fprintf(stderr, "Illegal \"index\"\n");
				free_opts(opts);
				return -1;
			}
			iok++;

			optind += 2;
		}
	}

	if (!ok && !iok) {
		fprintf(stderr," ipt Parser BAD!! (%s)\n", *argv);
		return -1;
	}

	/* check that we passed the correct parameters to the target */
	if (m)
		m->final_check(m->tflags);

	{
		struct tcmsg *t = NLMSG_DATA(n);
		if (t->tcm_parent != TC_H_ROOT
		    && t->tcm_parent == TC_H_MAJ(TC_H_INGRESS)) {
			hook = NF_IP_PRE_ROUTING;
		} else {
			hook = NF_IP_POST_ROUTING;
		}
	}

	tail = NLMSG_TAIL(n);
	addattr_l(n, MAX_MSG, tca_id, NULL, 0);
	fprintf(stdout, "tablename: %s hook: %s\n ", tname, ipthooks[hook]);
	fprintf(stdout, "\ttarget: ");

	if (m)
		m->print(NULL, m->t, 0);
	fprintf(stdout, " index %d\n", index);

	if (strlen(tname) > 16) {
		size = 16;
		k[15] = 0;
	} else {
		size = 1 + strlen(tname);
	}
	strncpy(k, tname, size);

	addattr_l(n, MAX_MSG, TCA_IPT_TABLE, k, size);
	addattr_l(n, MAX_MSG, TCA_IPT_HOOK, &hook, 4);
	addattr_l(n, MAX_MSG, TCA_IPT_INDEX, &index, 4);
	if (m)
		addattr_l(n, MAX_MSG, TCA_IPT_TARG, m->t, m->t->u.target_size);
	tail->rta_len = (void *) NLMSG_TAIL(n) - (void *) tail;

	argc -= optind;
	argv += optind;
	*argc_p = rargc - iargc;
	*argv_p = argv;
	
	optind = 1;
	free_opts(opts);

	return 0;

}

static int
print_ipt(struct action_util *au,FILE * f, struct rtattr *arg)
{
	struct rtattr *tb[TCA_IPT_MAX + 1];
	struct ipt_entry_target *t = NULL;

	if (arg == NULL)
		return -1;

	parse_rtattr_nested(tb, TCA_IPT_MAX, arg);

	if (tb[TCA_IPT_TABLE] == NULL) {
		fprintf(f, "[NULL ipt table name ] assuming mangle ");
	} else {
		fprintf(f, "tablename: %s ",
			(char *) RTA_DATA(tb[TCA_IPT_TABLE]));
	}

	if (tb[TCA_IPT_HOOK] == NULL) {
		fprintf(f, "[NULL ipt hook name ]\n ");
		return -1;
	} else {
		__u32 hook;
		hook = *(__u32 *) RTA_DATA(tb[TCA_IPT_HOOK]);
		fprintf(f, " hook: %s \n", ipthooks[hook]);
	}

	if (tb[TCA_IPT_TARG] == NULL) {
		fprintf(f, "\t[NULL ipt target parameters ] \n");
		return -1;
	} else {
		struct iptables_target *m = NULL;
		t = RTA_DATA(tb[TCA_IPT_TARG]);
		m = get_target_name(t->u.user.name);
		if (NULL != m) {
			if (0 > build_st(m, t)) {
				fprintf(stderr, " %s error \n", m->name);
				return -1;
			}

			opts =
			    merge_options(opts, m->extra_opts,
					  &m->option_offset);
		} else {
			fprintf(stderr, " failed to find target %s\n\n",
				t->u.user.name);
			return -1;
		}
		fprintf(f, "\ttarget ");
		m->print(NULL, m->t, 0);
		if (tb[TCA_IPT_INDEX] == NULL) {
			fprintf(f, " [NULL ipt target index ]\n");
		} else {
			__u32 index;
			index = *(__u32 *) RTA_DATA(tb[TCA_IPT_INDEX]);
			fprintf(f, " \n\tindex %d", index);
		}

		if (tb[TCA_IPT_CNT]) {
			struct tc_cnt *c  = RTA_DATA(tb[TCA_IPT_CNT]);;
			fprintf(f, " ref %d bind %d", c->refcnt, c->bindcnt);
		}
		if (show_stats) {
			if (tb[TCA_IPT_TM]) {
				struct tcf_t *tm = RTA_DATA(tb[TCA_IPT_TM]);
				print_tm(f,tm);
			}
		} 
		fprintf(f, " \n");

	}
	free_opts(opts);

	return 0;
}

struct action_util ipt_action_util = {
        .id = "ipt",
        .parse_aopt = parse_ipt,
        .print_aopt = print_ipt,
};

