/*
 * IP address pool functions.
 * Copyright (C) 2003, 2004 Mondru AB.
 * Copyright (C) 2017 by Harald Welte <laforge@gnumonks.org>
 *
 * The contents of this file may be used under the terms of the GNU
 * General Public License Version 2, provided that the above copyright
 * notice and this permission notice is included in all copies or
 * substantial portions of the software.
 *
 */

#include <sys/types.h>
#include <netinet/in.h>		/* in_addr */
#include <stdlib.h>		/* calloc */
#include <stdio.h>		/* sscanf */
#include <string.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netdb.h>
#include "syserr.h"
#include "ippool.h"
#include "lookup.h"

int ippool_printaddr(struct ippool_t *this)
{
	unsigned int n;
	printf("ippool_printaddr\n");
	printf("Firstdyn %td\n", this->firstdyn - this->member);
	printf("Lastdyn %td\n", this->lastdyn - this->member);
	printf("Firststat %td\n", this->firststat - this->member);
	printf("Laststat %td\n", this->laststat - this->member);
	printf("Listsize %u\n", this->listsize);

	for (n = 0; n < this->listsize; n++) {
		char s[256];
		in46a_ntop(&this->member[n].addr, s, sizeof(s));
		printf("Unit %d inuse %d prev %td next %td addr %s\n",
		       n,
		       this->member[n].inuse,
		       this->member[n].prev - this->member,
		       this->member[n].next - this->member,
		       s);
	}
	return 0;
}

int ippool_hashadd(struct ippool_t *this, struct ippoolm_t *member)
{
	uint32_t hash;
	struct ippoolm_t *p;
	struct ippoolm_t *p_prev = NULL;

	/* Insert into hash table */
	hash = ippool_hash(&member->addr) & this->hashmask;
	for (p = this->hash[hash]; p; p = p->nexthash)
		p_prev = p;
	if (!p_prev)
		this->hash[hash] = member;
	else
		p_prev->nexthash = member;
	return 0;		/* Always OK to insert */
}

int ippool_hashdel(struct ippool_t *this, struct ippoolm_t *member)
{
	uint32_t hash;
	struct ippoolm_t *p;
	struct ippoolm_t *p_prev = NULL;

	/* Find in hash table */
	hash = ippool_hash(&member->addr) & this->hashmask;
	for (p = this->hash[hash]; p; p = p->nexthash) {
		if (p == member) {
			break;
		}
		p_prev = p;
	}

	if (p != member) {
		SYS_ERR(DIP, LOGL_ERROR, 0,
			"ippool_hashdel: Tried to delete member not in hash table");
		return -1;
	}

	if (!p_prev)
		this->hash[hash] = p->nexthash;
	else
		p_prev->nexthash = p->nexthash;

	return 0;
}

static unsigned long int ippool_hash4(struct in_addr *addr)
{
	return lookup((unsigned char *)&addr->s_addr, sizeof(addr->s_addr), 0);
}

static unsigned long int ippool_hash6(struct in6_addr *addr, unsigned int len)
{
	/* TODO: Review hash spread for IPv6 */
	return lookup((unsigned char *)addr->s6_addr, len, 0);
}

unsigned long int ippool_hash(struct in46_addr *addr)
{
	if (addr->len == 4)
		return ippool_hash4(&addr->v4);
	else
		return ippool_hash6(&addr->v6, addr->len);
}

/* Get IP address and mask */
int ippool_aton(struct in46_addr *addr, size_t *prefixlen, const char *pool_in, int number)
{
	struct addrinfo *ai;
	struct addrinfo hints = {
		.ai_family = AF_UNSPEC,
		.ai_socktype = SOCK_DGRAM,
		.ai_flags = 0,
		.ai_protocol = 0
	};
	char pool[strlen(pool_in)+1];

	strcpy(pool, pool_in);

	int err;

	/* Find '/' and point to first char after it */
	char *prefixlen_str = strchr(pool, '/');
	if (prefixlen_str) {
		*prefixlen_str = '\0';
		prefixlen_str++;
		if (*prefixlen_str == '\0') {
			SYS_ERR(DIP, LOGL_ERROR, 0, "Empty prefix length specified");
			return -1;
		}
	}

	/* convert address */
	if ((err = getaddrinfo(pool, NULL, &hints, &ai))) {
		SYS_ERR(DIP, LOGL_ERROR, 0, "Bad address");
		return -1;
	}

	/* Copy address, set lengths */
	if (ai->ai_family == AF_INET) {
		*prefixlen = 32;
		addr->len = sizeof(struct in_addr);
		addr->v4 = ((struct sockaddr_in*)ai->ai_addr)->sin_addr;
	} else {
		*prefixlen = 128;
		addr->len = sizeof(struct in6_addr);
		addr->v6 = ((struct sockaddr_in6*)ai->ai_addr)->sin6_addr;
	}
	freeaddrinfo(ai);

	/* parse prefixlen */
	if (prefixlen_str) {
		char *e;
		*prefixlen = strtol(prefixlen_str, &e, 10);
		if (*e != '\0') {
			SYS_ERR(DIP, LOGL_ERROR, 0, "Prefixlen is not an int");
			return -1;
		}
	}

	if (*prefixlen > (addr->len * 8)) {
		SYS_ERR(DIP, LOGL_ERROR, 0, "Perfixlen too big");
		return -1;
	}

	return 0;
}

/* Increase IPv4/IPv6 address by 1 */
void in46a_inc(struct in46_addr *addr)
{
	size_t addrlen;
	uint8_t *a = (uint8_t *)&addr->v6;
	for (addrlen = addr->len; addrlen > 0; addrlen--) {
		if (++a[addrlen-1])
			break;
	}
}

static bool addr_in_prefix_list(struct in46_addr *addr, struct in46_prefix *list, size_t list_size)
{
	int i;
	for (i = 0; i < list_size; i++) {
		if (in46a_prefix_equal(addr, &list[i].addr))
			return true;
	}
	return false;
}

/* Create new address pool */
int ippool_new(struct ippool_t **this, const struct in46_prefix *dyn, const struct in46_prefix *stat,
	       int flags, struct in46_prefix *blacklist, size_t blacklist_size)
{

	/* Parse only first instance of pool for now */

	int i;
	struct in46_addr addr = { 0 };
	size_t addrprefixlen;
	struct in46_addr stataddr;
	size_t stataddrprefixlen;
	int listsize;
	int dynsize;
	unsigned int statsize;

	if (!dyn || dyn->addr.len == 0) {
		dynsize = 0;
	} else {
		addr = dyn->addr;
		addrprefixlen = dyn->prefixlen;
		/* we want to work with /64 prefixes, i.e. allocate /64 prefixes rather
		 * than /128 (single IPv6 addresses) */
		if (addr.len == sizeof(struct in6_addr))
			addr.len = 64/8;

		dynsize = (1 << (addr.len*8 - addrprefixlen));
		if (flags & IPPOOL_NONETWORK)	/* Exclude network address from pool */
			dynsize--;
		if (flags & IPPOOL_NOBROADCAST)	/* Exclude broadcast address from pool */
			dynsize--;
		/* Exclude included blacklist addresses from pool */
		for (i = 0; i < blacklist_size; i++) {
			if (in46a_within_mask(&blacklist[i].addr, &addr, addrprefixlen))
				dynsize--;
		}
	}

	if (!stat || stat->addr.len == 0) {
		statsize = 0;
		stataddr.len = 0;
		stataddrprefixlen = 0;
	} else {
		stataddr = stat->addr;
		stataddrprefixlen = stat->prefixlen;

		statsize = (1 << (stataddr.len*8 - stataddrprefixlen));
		if (statsize > IPPOOL_STATSIZE)
			statsize = IPPOOL_STATSIZE;
	}

	listsize = dynsize + statsize;	/* Allocate space for static IP addresses */

	if (!(*this = calloc(sizeof(struct ippool_t), 1))) {
		SYS_ERR(DIP, LOGL_ERROR, 0,
			"Failed to allocate memory for ippool");
		return -1;
	}

	(*this)->allowdyn = dyn ? 1 : 0;
	(*this)->allowstat = stat ? 1 : 0;
	if (stataddr.len > 0)
		(*this)->stataddr = stataddr;
	(*this)->stataddrprefixlen = stataddrprefixlen;

	(*this)->listsize += listsize;
	if (!((*this)->member = calloc(sizeof(struct ippoolm_t), listsize))) {
		SYS_ERR(DIP, LOGL_ERROR, 0,
			"Failed to allocate memory for members in ippool");
		return -1;
	}

	for ((*this)->hashlog = 0;
	     ((1 << (*this)->hashlog) < listsize); (*this)->hashlog++) ;

	/*   printf ("Hashlog %d %d %d\n", (*this)->hashlog, listsize, (1 << (*this)->hashlog)); */

	/* Determine hashsize */
	(*this)->hashsize = 1 << (*this)->hashlog;	/* Fails if mask=0: All Internet */
	(*this)->hashmask = (*this)->hashsize - 1;

	/* Allocate hash table */
	(*this)->hash = calloc((*this)->hashsize, sizeof(struct ippoolm_t *));
	if (!(*this)->hash) {
		SYS_ERR(DIP, LOGL_ERROR, 0,
			"Failed to allocate memory for hash members in ippool");
		return -1;
	}

	(*this)->firstdyn = NULL;
	(*this)->lastdyn = NULL;
	if (flags & IPPOOL_NONETWORK) {
		in46a_inc(&addr);
	}
	for (i = 0; i < dynsize; i++) {
		if (addr_in_prefix_list(&addr, blacklist, blacklist_size)) {
			SYS_ERR(DIP, LOGL_DEBUG, 0,
				"addr blacklisted from pool: %s", in46a_ntoa(&addr));
			in46a_inc(&addr);
			i--;
			continue;
		}
		(*this)->member[i].addr = addr;
		in46a_inc(&addr);

		(*this)->member[i].inuse = 0;
		(*this)->member[i].pool = *this;

		/* Insert into list of unused */
		(*this)->member[i].prev = (*this)->lastdyn;
		if ((*this)->lastdyn) {
			(*this)->lastdyn->next = &((*this)->member[i]);
		} else {
			(*this)->firstdyn = &((*this)->member[i]);
		}
		(*this)->lastdyn = &((*this)->member[i]);
		(*this)->member[i].next = NULL;	/* Redundant */

		(void)ippool_hashadd(*this, &(*this)->member[i]);
	}

	(*this)->firststat = NULL;
	(*this)->laststat = NULL;
	for (i = dynsize; i < listsize; i++) {
		struct in46_addr *i6al = &(*this)->member[i].addr;
		memset(i6al, 0, sizeof(*i6al));
		(*this)->member[i].inuse = 0;
		(*this)->member[i].pool = *this;

		/* Insert into list of unused */
		(*this)->member[i].prev = (*this)->laststat;
		if ((*this)->laststat) {
			(*this)->laststat->next = &((*this)->member[i]);
		} else {
			(*this)->firststat = &((*this)->member[i]);
		}
		(*this)->laststat = &((*this)->member[i]);
		(*this)->member[i].next = NULL;	/* Redundant */
	}

	if (0)
		(void)ippool_printaddr(*this);
	return 0;
}

/* Delete existing address pool */
int ippool_free(struct ippool_t *this)
{
	free(this->hash);
	free(this->member);
	free(this);
	return 0;		/* Always OK */
}

/* Find an IP address in the pool */
int ippool_getip(struct ippool_t *this, struct ippoolm_t **member,
		 struct in46_addr *addr)
{
	struct ippoolm_t *p;
	uint32_t hash;

	/* Find in hash table */
	hash = ippool_hash(addr) & this->hashmask;
	for (p = this->hash[hash]; p; p = p->nexthash) {
		if (in46a_prefix_equal(&p->addr, addr)) {
			if (member)
				*member = p;
			return 0;
		}
	}
	if (member)
		*member = NULL;
	/*SYS_ERR(DIP, LOGL_ERROR, 0, "Address could not be found"); */
	return -1;
}

/**
 * ippool_newip
 * Get an IP address. If addr = 0.0.0.0 get a dynamic IP address. Otherwise
 * check to see if the given address is available. If available within
 * dynamic address space allocate it there, otherwise allocate within static
 * address space.
**/
int ippool_newip(struct ippool_t *this, struct ippoolm_t **member,
		 struct in46_addr *addr, int statip)
{
	struct ippoolm_t *p;
	struct ippoolm_t *p2 = NULL;
	uint32_t hash;

	/* If static:
	 *   Look in dynaddr.
	 *     If found remove from firstdyn/lastdyn linked list.
	 *   Else allocate from stataddr.
	 *    Remove from firststat/laststat linked list.
	 *    Insert into hash table.
	 *
	 * If dynamic
	 *   Remove from firstdyn/lastdyn linked list.
	 *
	 */

	if (0)
		(void)ippool_printaddr(this);

	int specified = 0;
	if (addr) {
		if (addr->len == 4 && addr->v4.s_addr)
			specified = 1;
		if (addr->len == 16 && !IN6_IS_ADDR_UNSPECIFIED(&addr->v6))
			specified = 1;
	}

	/* First check to see if this type of address is allowed */
	if (specified && statip) {	/* IP address given */
		if (!this->allowstat) {
			SYS_ERR(DIP, LOGL_ERROR, 0,
				"Static IP address not allowed");
			return -GTPCAUSE_NOT_SUPPORTED;
		}
		if (!in46a_within_mask(addr, &this->stataddr, this->stataddrprefixlen)) {
			SYS_ERR(DIP, LOGL_ERROR, 0, "Static out of range");
			return -1;
		}
	} else {
		if (!this->allowdyn) {
			SYS_ERR(DIP, LOGL_ERROR, 0,
				"Dynamic IP address not allowed");
			return -GTPCAUSE_NOT_SUPPORTED;
		}
	}

	/* If IP address given try to find it in dynamic address pool */
	if (specified) {	/* IP address given */
		/* Find in hash table */
		hash = ippool_hash(addr) & this->hashmask;
		for (p = this->hash[hash]; p; p = p->nexthash) {
			if (in46a_prefix_equal(&p->addr, addr)) {
				p2 = p;
				break;
			}
		}
	}

	/* If IP was already allocated we can not use it */
	if ((!statip) && (p2) && (p2->inuse)) {
		p2 = NULL;
	}

	/* If not found yet and dynamic IP then allocate dynamic IP */
	if ((!p2) && (!statip)) {
		if (!this->firstdyn) {
			SYS_ERR(DIP, LOGL_ERROR, 0,
				"No more IP addresses available");
			return -GTPCAUSE_ADDR_OCCUPIED;
		} else
			p2 = this->firstdyn;
	}

	if (p2) {		/* Was allocated from dynamic address pool */
		if (p2->inuse) {
			SYS_ERR(DIP, LOGL_ERROR, 0,
				"IP address allready in use");
			return -GTPCAUSE_SYS_FAIL;	/* Allready in use / Should not happen */
		}

		if (p2->addr.len != addr->len && !(addr->len == 16 && p2->addr.len == 8)) {
			SYS_ERR(DIP, LOGL_ERROR, 0, "MS requested unsupported PDP context type");
			return -GTPCAUSE_UNKNOWN_PDP;
		}

		/* Remove from linked list of free dynamic addresses */
		if (p2->prev)
			p2->prev->next = p2->next;
		else
			this->firstdyn = p2->next;
		if (p2->next)
			p2->next->prev = p2->prev;
		else
			this->lastdyn = p2->prev;
		p2->next = NULL;
		p2->prev = NULL;
		p2->inuse = 1;	/* Dynamic address in use */

		*member = p2;
		if (0)
			(void)ippool_printaddr(this);
		return 0;	/* Success */
	}

	/* It was not possible to allocate from dynamic address pool */
	/* Try to allocate from static address space */

	if (specified  && (statip)) {	/* IP address given */
		if (!this->firststat) {
			SYS_ERR(DIP, LOGL_ERROR, 0,
				"No more IP addresses available");
			return -GTPCAUSE_ADDR_OCCUPIED;	/* No more available */
		} else
			p2 = this->firststat;

		if (p2->addr.len != addr->len) {
			SYS_ERR(DIP, LOGL_ERROR, 0, "MS requested unsupported PDP context type");
			return -GTPCAUSE_UNKNOWN_PDP;
		}

		/* Remove from linked list of free static addresses */
		if (p2->prev)
			p2->prev->next = p2->next;
		else
			this->firststat = p2->next;
		if (p2->next)
			p2->next->prev = p2->prev;
		else
			this->laststat = p2->prev;
		p2->next = NULL;
		p2->prev = NULL;
		p2->inuse = 2;	/* Static address in use */
		/* p2->addr.len and addr->len already match (see above). */
		if (p2->addr.len == sizeof(struct in_addr))
			p2->addr.v4 = addr->v4;
		else if (p2->addr.len == sizeof(struct in6_addr))
			p2->addr.v6 = addr->v6;
		else {
			SYS_ERR(DIP, LOGL_ERROR, 0, "MS requested unsupported PDP context type");
			return -GTPCAUSE_UNKNOWN_PDP;
		}
		*member = p2;
		(void)ippool_hashadd(this, *member);
		if (0)
			(void)ippool_printaddr(this);
		return 0;	/* Success */
	}

	SYS_ERR(DIP, LOGL_ERROR, 0,
		"Could not allocate IP address");
	return -GTPCAUSE_SYS_FAIL;		/* Should never get here. TODO: Bad code */
}

int ippool_freeip(struct ippool_t *this, struct ippoolm_t *member)
{

	if (0)
		(void)ippool_printaddr(this);

	if (!member->inuse) {
		SYS_ERR(DIP, LOGL_ERROR, 0, "Address not in use");
		return -1;	/* Not in use: Should not happen */
	}

	switch (member->inuse) {
	case 0:		/* Not in use: Should not happen */
		SYS_ERR(DIP, LOGL_ERROR, 0, "Address not in use");
		return -1;
	case 1:		/* Allocated from dynamic address space */
		/* Insert into list of unused */
		member->prev = this->lastdyn;
		if (this->lastdyn) {
			this->lastdyn->next = member;
		} else {
			this->firstdyn = member;
		}
		this->lastdyn = member;

		member->inuse = 0;
		member->peer = NULL;
		if (0)
			(void)ippool_printaddr(this);
		return 0;
	case 2:		/* Allocated from static address space */
		if (ippool_hashdel(this, member))
			return -1;
		/* Insert into list of unused */
		member->prev = this->laststat;
		if (this->laststat) {
			this->laststat->next = member;
		} else {
			this->firststat = member;
		}
		this->laststat = member;

		member->inuse = 0;
		memset(&member->addr, 0, sizeof(member->addr));
		member->peer = NULL;
		member->nexthash = NULL;
		if (0)
			(void)ippool_printaddr(this);
		return 0;
	default:		/* Should not happen */
		SYS_ERR(DIP, LOGL_ERROR, 0,
			"Could not free IP address");
		return -1;
	}
}
