/* Copyright 2007-2010 Jozsef Kadlecsik (kadlec@blackhole.kfki.hu)
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 */
#include <assert.h>				/* assert */
#include <errno.h>				/* errno */
#include <net/ethernet.h>			/* ETH_ALEN */
#include <netinet/in.h>				/* struct in6_addr */
#include <sys/socket.h>				/* AF_ */
#include <stdlib.h>				/* malloc, free */
#include <stdio.h>				/* FIXME: debug */
#include <libmnl/libmnl.h>			/* MNL_ALIGN */

#include <libipset/debug.h>			/* D() */
#include <libipset/data.h>			/* ipset_data_* */
#include <libipset/session.h>			/* ipset_cmd */
#include <libipset/utils.h>			/* STREQ */
#include <libipset/types.h>			/* prototypes */

#ifdef ENABLE_SETTYPE_MODULES
#include <dlfcn.h>
#include <sys/types.h>
#include <dirent.h>
#endif

/* Userspace cache of sets which exists in the kernel */

struct ipset {
	char name[IPSET_MAXNAMELEN];		/* set name */
	const struct ipset_type *type;		/* set type */
	uint8_t family;				/* family */
	struct ipset *next;
};

static struct ipset_type *typelist;		/* registered set types */
static struct ipset *setlist;			/* cached sets */

/**
 * ipset_cache_add - add a set to the cache
 * @name: set name
 * @type: set type structure
 *
 * Add the named set to the internal cache with the specified
 * set type. The set name must be unique.
 *
 * Returns 0 on success or a negative error code.
 */
int
ipset_cache_add(const char *name, const struct ipset_type *type,
		uint8_t family)
{
	struct ipset *s, *n;

	assert(name);
	assert(type);

	n = malloc(sizeof(*n));
	if (n == NULL)
		return -ENOMEM;

	ipset_strlcpy(n->name, name, IPSET_MAXNAMELEN);
	n->type = type;
	n->family = family;
	n->next = NULL;

	if (setlist == NULL) {
		setlist = n;
		return 0;
	}
	for (s = setlist; s->next != NULL; s = s->next) {
		if (STREQ(name, s->name)) {
			free(n);
			return -EEXIST;
		}
	}
	s->next = n;

	return 0;
}

/**
 * ipset_cache_del - delete set from the cache
 * @name: set name
 *
 * Delete the named set from the internal cache. If NULL is
 * specified as setname, the whole cache is emptied.
 *
 * Returns 0 on success or a negative error code.
 */
int
ipset_cache_del(const char *name)
{
	struct ipset *s, *match = NULL, *prev = NULL;

	if (!name) {
		for (s = setlist; s != NULL; ) {
			prev = s;
			s = s->next;
			free(prev);
		}
		setlist = NULL;
		return 0;
	}
	for (s = setlist; s != NULL && match == NULL; s = s->next) {
		if (STREQ(s->name, name)) {
			match = s;
			if (prev == NULL)
				setlist = match->next;
			else
				prev->next = match->next;
		}
		prev = s;
	}
	if (match == NULL)
		return -EEXIST;

	free(match);
	return 0;
}

/**
 * ipset_cache_rename - rename a set in the cache
 * @from: the set to rename
 * @to: the new name of the set
 *
 * Rename the given set in the cache.
 *
 * Returns 0 on success or a negative error code.
 */
int
ipset_cache_rename(const char *from, const char *to)
{
	struct ipset *s;

	assert(from);
	assert(to);

	for (s = setlist; s != NULL; s = s->next) {
		if (STREQ(s->name, from)) {
			ipset_strlcpy(s->name, to, IPSET_MAXNAMELEN);
			return 0;
		}
	}
	return -EEXIST;
}

/**
 * ipset_cache_swap - swap two sets in the cache
 * @from: the first set
 * @to: the second set
 *
 * Swap two existing sets in the cache.
 *
 * Returns 0 on success or a negative error code.
 */
int
ipset_cache_swap(const char *from, const char *to)
{
	struct ipset *s, *a = NULL, *b = NULL;

	assert(from);
	assert(to);

	for (s = setlist; s != NULL && (a == NULL || b == NULL); s = s->next) {
		if (a == NULL && STREQ(s->name, from))
			a = s;
		if (b == NULL && STREQ(s->name, to))
			b = s;
	}
	if (a != NULL && b != NULL) {
		ipset_strlcpy(a->name, to, IPSET_MAXNAMELEN);
		ipset_strlcpy(b->name, from, IPSET_MAXNAMELEN);
		return 0;
	}

	return -EEXIST;
}

#define MATCH_FAMILY(type, f)	\
	(f == NFPROTO_UNSPEC || type->family == f || \
	 type->family == NFPROTO_IPSET_IPV46)

bool
ipset_match_typename(const char *name, const struct ipset_type *type)
{
	const char * const *alias = type->alias;

	if (STREQ(name, type->name))
		return true;

	while (alias[0]) {
		if (STREQ(name, alias[0]))
			return true;
		alias++;
	}
	return false;
}

static inline const struct ipset_type *
create_type_get(struct ipset_session *session)
{
	struct ipset_type *t, *match = NULL;
	struct ipset_data *data;
	const char *typename;
	uint8_t family, tmin = 0, tmax = 0;
	uint8_t kmin, kmax;
	int ret;
	bool ignore_family = false;

	data = ipset_session_data(session);
	assert(data);
	typename = ipset_data_get(data, IPSET_OPT_TYPENAME);
	assert(typename);
	family = ipset_data_family(data);

	/* Check registered types in userspace */
	for (t = typelist; t != NULL; t = t->next) {
		/* Skip revisions which are unsupported by the kernel */
		if (t->kernel_check == IPSET_KERNEL_MISMATCH)
			continue;
		if (ipset_match_typename(typename, t)
		    && MATCH_FAMILY(t, family)) {
			if (match == NULL) {
				match = t;
				tmin = tmax = t->revision;
			} else if (t->family == match->family)
				tmin = t->revision;
		}
	}
	if (!match)
		return ipset_errptr(session,
				    "Syntax error: unknown settype %s",
				    typename);

	/* Family is unspecified yet: set from matching set type */
	if (family == NFPROTO_UNSPEC && match->family != NFPROTO_UNSPEC) {
		family = match->family == NFPROTO_IPSET_IPV46 ?
			 NFPROTO_IPV4 : match->family;
		ipset_data_set(data, IPSET_OPT_FAMILY, &family);
		if (match->family == NFPROTO_IPSET_IPV46)
			ignore_family = true;
	}

	if (match->kernel_check == IPSET_KERNEL_OK)
		goto found;

	/* Check kernel */
	ret = ipset_cmd(session, IPSET_CMD_TYPE, 0);
	if (ret != 0)
		return NULL;

	kmin = kmax = *(const uint8_t *)ipset_data_get(data,
						IPSET_OPT_REVISION);
	if (ipset_data_test(data, IPSET_OPT_REVISION_MIN))
		kmin = *(const uint8_t *)ipset_data_get(data,
						IPSET_OPT_REVISION_MIN);

	if (MAX(tmin, kmin) > MIN(tmax, kmax)) {
		if (kmin > tmax)
			return ipset_errptr(session,
				"Kernel supports %s type, family %s "
				"with minimal revision %u while ipset program "
				"with maximal revision %u.\n"
				"You need to upgrade your ipset program.",
				typename,
				family == NFPROTO_IPV4 ? "INET" :
				family == NFPROTO_IPV6 ? "INET6" : "UNSPEC",
				kmin, tmax);
		else
			return ipset_errptr(session,
				"Kernel supports %s type, family %s "
				"with maximal revision %u while ipset program "
				"with minimal revision %u.\n"
				"You need to upgrade your kernel.",
				typename,
				family == NFPROTO_IPV4 ? "INET" :
				family == NFPROTO_IPV6 ? "INET6" : "UNSPEC",
				kmax, tmin);
	}

	/* Disable unsupported revisions */
	for (match = NULL, t = typelist; t != NULL; t = t->next) {
		/* Skip revisions which are unsupported by the kernel */
		if (t->kernel_check == IPSET_KERNEL_MISMATCH)
			continue;
		if (ipset_match_typename(typename, t)
		    && MATCH_FAMILY(t, family)) {
			if (t->revision < kmin || t->revision > kmax)
				t->kernel_check = IPSET_KERNEL_MISMATCH;
			else if (match == NULL)
				match = t;
		}
	}
	match->kernel_check = IPSET_KERNEL_OK;
found:
	ipset_data_set(data, IPSET_OPT_TYPE, match);

	if (ignore_family) {
		/* Overload ignored flag */
		D("set ignored flag to FAMILY");
		ipset_data_ignored(data, IPSET_OPT_FAMILY);
	}
	return match;
}

#define set_family_and_type(data, match, family) do {		\
	if (family == NFPROTO_UNSPEC && match->family != NFPROTO_UNSPEC) \
		family = match->family == NFPROTO_IPSET_IPV46 ? \
			 NFPROTO_IPV4 : match->family;\
	ipset_data_set(data, IPSET_OPT_FAMILY, &family);	\
	ipset_data_set(data, IPSET_OPT_TYPE, match);		\
} while (0)


static inline const struct ipset_type *
adt_type_get(struct ipset_session *session)
{
	struct ipset_data *data;
	struct ipset *s;
	struct ipset_type *t;
	const struct ipset_type *match;
	const char *setname, *typename;
	const uint8_t *revision;
	uint8_t family = NFPROTO_UNSPEC;
	int ret;

	data = ipset_session_data(session);
	assert(data);
	setname = ipset_data_setname(data);
	assert(setname);

	/* Check existing sets in cache */
	for (s = setlist; s != NULL; s = s->next) {
		if (STREQ(setname, s->name)) {
			ipset_data_set(data, IPSET_OPT_FAMILY, &s->family);
			ipset_data_set(data, IPSET_OPT_TYPE, s->type);
			return s->type;
		}
	}

	/* Check kernel */
	ret = ipset_cmd(session, IPSET_CMD_HEADER, 0);
	if (ret != 0)
		return NULL;

	typename = ipset_data_get(data, IPSET_OPT_TYPENAME);
	revision = ipset_data_get(data, IPSET_OPT_REVISION);
	family = ipset_data_family(data);

	/* Check registered types */
	for (t = typelist, match = NULL;
	     t != NULL && match == NULL; t = t->next) {
		if (t->kernel_check == IPSET_KERNEL_MISMATCH)
			continue;
		if (STREQ(typename, t->name)
		    && MATCH_FAMILY(t, family)
		    && *revision == t->revision) {
			t->kernel_check = IPSET_KERNEL_OK;
			match = t;
		}
	}
	if (!match)
		return ipset_errptr(session,
				    "Kernel-library incompatibility: "
				    "set %s in kernel has got settype %s "
				    "with family %s and revision %u while "
				    "ipset library does not support the "
				    "settype with that family and revision.",
				    setname, typename,
				    family == NFPROTO_IPV4 ? "inet" :
				    family == NFPROTO_IPV6 ? "inet6" : "unspec",
				    *revision);

	set_family_and_type(data, match, family);

	return match;
}

/**
 * ipset_type_get - get a set type from the kernel
 * @session: session structure
 * @cmd: the command which needs the set type
 *
 * Build up and send a private message to the kernel in order to
 * get the set type. When creating the set, we send the typename
 * and family and get the supported revisions of the given set type.
 * When adding/deleting/testing an entry, we send the setname and
 * receive the typename, family and revision.
 *
 * Returns the set type for success and NULL for failure.
 */
const struct ipset_type *
ipset_type_get(struct ipset_session *session, enum ipset_cmd cmd)
{
	assert(session);

	switch (cmd) {
	case IPSET_CMD_CREATE:
		return ipset_data_test(ipset_session_data(session),
				       IPSET_OPT_TYPE)
			? ipset_data_get(ipset_session_data(session),
					 IPSET_OPT_TYPE)
			: create_type_get(session);
	case IPSET_CMD_ADD:
	case IPSET_CMD_DEL:
	case IPSET_CMD_TEST:
		return adt_type_get(session);
	default:
		break;
	}

	assert(cmd == IPSET_CMD_NONE);
	return NULL;
}

/**
 * ipset_type_check - check the set type received from kernel
 * @session: session structure
 *
 * Check the set type received from the kernel (typename, revision,
 * family) against the userspace types looking for a matching type.
 *
 * Returns the set type for success and NULL for failure.
 */
const struct ipset_type *
ipset_type_check(struct ipset_session *session)
{
	const struct ipset_type *t, *match = NULL;
	struct ipset_data *data;
	const char *typename;
	uint8_t family = NFPROTO_UNSPEC, revision;

	assert(session);
	data = ipset_session_data(session);
	assert(data);

	typename = ipset_data_get(data, IPSET_OPT_TYPENAME);
	family = ipset_data_family(data);
	revision = *(const uint8_t *) ipset_data_get(data, IPSET_OPT_REVISION);

	/* Check registered types */
	for (t = typelist; t != NULL && match == NULL; t = t->next) {
		if (t->kernel_check == IPSET_KERNEL_MISMATCH)
			continue;
		if (ipset_match_typename(typename, t)
		    && MATCH_FAMILY(t, family)
		    && t->revision == revision)
			match = t;
	}
	if (!match)
		return ipset_errptr(session,
			     "Kernel and userspace incompatible: "
			     "settype %s with revision %u not supported ",
			     "by userspace.", typename, revision);

	set_family_and_type(data, match, family);

	return match;
}

/**
 * ipset_type_add - add (register) a userspace set type
 * @type: pointer to the set type structure
 *
 * Add the given set type to the type list. The types
 * are added sorted, in descending revision number.
 *
 * Returns 0 on success or a negative error code.
 */
int
ipset_type_add(struct ipset_type *type)
{
	struct ipset_type *t, *prev;

	assert(type);

	if (strlen(type->name) > IPSET_MAXNAMELEN - 1)
		return -EINVAL;

	/* Add to the list: higher revision numbers first */
	for (t = typelist, prev = NULL; t != NULL; t = t->next) {
		if (STREQ(t->name, type->name)) {
			if (t->revision == type->revision)
				return -EEXIST;
			else if (t->revision < type->revision) {
				type->next = t;
				if (prev)
					prev->next = type;
				else
					typelist = type;
				return 0;
			}
		}
		if (t->next != NULL && STREQ(t->next->name, type->name)) {
			if (t->next->revision == type->revision)
				return -EEXIST;
			else if (t->next->revision < type->revision) {
				type->next = t->next;
				t->next = type;
				return 0;
			}
		}
		prev = t;
	}
	type->next = typelist;
	typelist = type;
	return 0;
}

/**
 * ipset_typename_resolve - resolve typename alias
 * @str: typename or alias
 *
 * Check the typenames (and aliases) and return the
 * preferred name of the set type.
 *
 * Returns the name of the matching set type or NULL.
 */
const char *
ipset_typename_resolve(const char *str)
{
	const struct ipset_type *t;

	for (t = typelist; t != NULL; t = t->next)
		if (ipset_match_typename(str, t))
			return t->name;
	return NULL;
}

/**
 * ipset_types - return the list of the set types
 *
 * The types can be unchecked with respect of the running kernel.
 * Only useful for type specific help.
 *
 * Returns the list of the set types.
 */
const struct ipset_type *
ipset_types(void)
{
	return typelist;
}

/**
 * ipset_cache_init - initialize set cache
 *
 * Initialize the set cache in userspace.
 *
 * Returns 0 on success or a negative error code.
 */
int
ipset_cache_init(void)
{
	return 0;
}

/**
 * ipset_cache_fini - release the set cache
 *
 * Release the set cache.
 */
void
ipset_cache_fini(void)
{
	struct ipset *set;

	while (setlist) {
		set = setlist;
		setlist = setlist->next;
		free(set);
	}
}

extern void ipset_types_init(void);

/**
 * ipset_load_types - load known set types
 *
 * Load in (register) all known set types for the system
 */
void
ipset_load_types(void)
{
#ifdef ENABLE_SETTYPE_MODULES
	const char *dir  = IPSET_MODSDIR;
	const char *next = NULL;
	char   path[256];
	char   file[256];
	struct dirent **list = NULL;
	int    n;
	int    len;
#endif

	if (typelist != NULL)
		return;

	/* Initialize static types */
	ipset_types_init();

#ifdef ENABLE_SETTYPE_MODULES
	/* Initialize dynamic types */
	do {
		next = strchr(dir, ':');
		if (next == NULL)
			next = dir + strlen(dir);

		len = snprintf(path, sizeof(path), "%.*s",
			       (unsigned int)(next - dir), dir);

		if (len >= (int)sizeof(path) || len < 0)
			continue;

		n = scandir(path, &list, NULL, alphasort);
		if (n < 0)
			continue;

		while (n--) {
			if (strstr(list[n]->d_name, ".so") == NULL)
				goto nextf;

			len = snprintf(file, sizeof(file), "%s/%s",
				       path, list[n]->d_name);
			if (len >= (int)sizeof(file) || len < (int)0)
				goto nextf;

			if (dlopen(file, RTLD_NOW) == NULL)
				fprintf(stderr, "%s: %s\n", file, dlerror());

nextf:
			free(list[n]);
		}

		free(list);

		dir = next + 1;
	} while (*next != '\0');
#endif /* ENABLE_SETTYPE_MODULES */
}
