/*
 * IPv4/v6 address functions.
 * 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 "../lib/in46_addr.h"
#include "../gtp/pdp.h"

#include <osmocom/core/utils.h>

#include <sys/types.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <stdlib.h>
#include <string.h>

/*! Return the address family of given \reff in46_addr argument */
int in46a_to_af(const struct in46_addr *in)
{
	switch (in->len) {
	case 4:
		return AF_INET;
	case 8:
	case 16:
		return AF_INET6;
	default:
		OSMO_ASSERT(0);
		return -1;
	}
}

/*! Convert \ref in46_addr to sockaddr_storage */
int in46a_to_sas(struct sockaddr_storage *out, const struct in46_addr *in)
{
	struct sockaddr_in *sin = (struct sockaddr_in *)out;
	struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)out;

	switch (in->len) {
	case 4:
		sin->sin_family = AF_INET;
		sin->sin_addr = in->v4;
		break;
	case 16:
		sin6->sin6_family = AF_INET6;
		sin6->sin6_addr = in->v6;
		break;
	default:
		OSMO_ASSERT(0);
		return -1;
	}

	return 0;
}

/*! Convenience wrapper around inet_ntop() for \ref in46_addr */
const char *in46a_ntop(const struct in46_addr *in, char *dst, socklen_t dst_size)
{
	int af;

	if (!in || in->len == 0) {
		strncpy(dst, "UNDEFINED", dst_size);
		return dst;
	}

	af = in46a_to_af(in);
	if (af < 0)
		return NULL;

	return inet_ntop(af, (const void *) &in->v4, dst, dst_size);
}

/* like inet_ntoa() */
const char *in46a_ntoa(const struct in46_addr *in46)
{
	static char addrstr_buf[256];
	if (in46a_ntop(in46, addrstr_buf, sizeof(addrstr_buf)) < 0)
		return "INVALID";
	else
		return addrstr_buf;
}

const char *in46p_ntoa(const struct in46_prefix *in46p)
{
	static char addrstr_buf[256];
	snprintf(addrstr_buf, sizeof(addrstr_buf), "%s/%u", in46a_ntoa(&in46p->addr), in46p->prefixlen);
	return addrstr_buf;
}

/*! Determine if two in46_addr are equal or not
 *  \returns 1 in case they are equal; 0 otherwise */
int in46a_equal(const struct in46_addr *a, const struct in46_addr *b)
{
	if (a->len == b->len && !memcmp(&a->v6, &b->v6, a->len))
		return 1;
	else
		return 0;
}

/*! Determine if two in46_addr prefix are equal or not
 *  The prefix length is determined by the shortest of the prefixes of a and b
 *  \returns 1 in case the common prefix are equal; 0 otherwise */
int in46a_prefix_equal(const struct in46_addr *a, const struct in46_addr *b)
{
	unsigned int len;
	if (a->len > b->len)
		len = b->len;
	else
		len = a->len;

	if (!memcmp(&a->v6, &b->v6, len))
		return 1;
	else
		return 0;
}

/*! Match if IPv6 addr1 + addr2 are within same \a mask */
static int ipv6_within_mask(const struct in6_addr *addr1, const struct in6_addr *addr2,
			    const struct in6_addr *mask)
{
	struct in6_addr masked = *addr2;
#if defined(__linux__)
	masked.s6_addr32[0] &= mask->s6_addr32[0];
	masked.s6_addr32[1] &= mask->s6_addr32[1];
	masked.s6_addr32[2] &= mask->s6_addr32[2];
	masked.s6_addr32[3] &= mask->s6_addr32[3];
#else
	masked.__u6_addr.__u6_addr32[0] &= mask->__u6_addr.__u6_addr32[0];
	masked.__u6_addr.__u6_addr32[1] &= mask->__u6_addr.__u6_addr32[1];
	masked.__u6_addr.__u6_addr32[2] &= mask->__u6_addr.__u6_addr32[2];
	masked.__u6_addr.__u6_addr32[3] &= mask->__u6_addr.__u6_addr32[3];
#endif
	if (!memcmp(addr1, &masked, sizeof(struct in6_addr)))
		return 1;
	else
		return 0;
}

/*! Create an IPv6 netmask from the given prefix length */
static void create_ipv6_netmask(struct in6_addr *netmask, int prefixlen)
{
	uint32_t *p_netmask;
	memset(netmask, 0, sizeof(struct in6_addr));
	if (prefixlen < 0)
		prefixlen = 0;
	else if (128 < prefixlen)
		prefixlen = 128;

#if defined(__linux__)
	p_netmask = &netmask->s6_addr32[0];
#else
	p_netmask = &netmask->__u6_addr.__u6_addr32[0];
#endif
	while (32 < prefixlen) {
		*p_netmask = 0xffffffff;
		p_netmask++;
		prefixlen -= 32;
	}
	if (prefixlen != 0) {
		*p_netmask = htonl(0xFFFFFFFF << (32 - prefixlen));
	}
}

/*! Determine if given \a addr is within given \a net + \a prefixlen
 *  Builds the netmask from \a net + \a prefixlen and matches it to \a addr
 *  \returns 1 in case of a match, 0 otherwise */
int in46a_within_mask(const struct in46_addr *addr, const struct in46_addr *net, size_t prefixlen)
{
	struct in_addr netmask;
	struct in6_addr netmask6;

	if (addr->len != net->len)
		return 0;

	switch (addr->len) {
	case 4:
		netmask.s_addr = htonl(0xFFFFFFFF << (32 - prefixlen));
		if ((addr->v4.s_addr & netmask.s_addr) == net->v4.s_addr)
			return 1;
		else
			return 0;
	case 16:
		create_ipv6_netmask(&netmask6, prefixlen);
		return ipv6_within_mask(&addr->v6, &net->v6, &netmask6);
	default:
		OSMO_ASSERT(0);
		return 0;
	}
}

static unsigned int ipv4_netmasklen(const struct in_addr *netmask)
{
	uint32_t bits = netmask->s_addr;
	uint8_t *b = (uint8_t*) &bits;
	unsigned int i, prefix = 0;

	for (i = 0; i < 4; i++) {
		while (b[i] & 0x80) {
			prefix++;
			b[i] = b[i] << 1;
		}
	}
	return prefix;
}

static unsigned int ipv6_netmasklen(const struct in6_addr *netmask)
{
	#if defined(__linux__)
		#define ADDRFIELD(i) s6_addr32[i]
	#else
		#define ADDRFIELD(i) __u6_addr.__u6_addr32[i]
	#endif

	unsigned int i, j, prefix = 0;

	for (j = 0; j < 4; j++) {
		uint32_t bits = netmask->ADDRFIELD(j);
		uint8_t *b = (uint8_t*) &bits;
		for (i = 0; i < 4; i++) {
			while (b[i] & 0x80) {
				prefix++;
				b[i] = b[i] << 1;
			}
		}
	}

	#undef ADDRFIELD

	return prefix;
}

/*! Convert netmask to prefix length representation
 *  \param[in] netmask in46_addr containing a netmask (consecutive list of 1-bit followed by consecutive list of 0-bit)
 *  \returns prefix length representation of the netmask (count of 1-bit from the start of the netmask)
 */
unsigned int in46a_netmasklen(const struct in46_addr *netmask)
{
	switch (netmask->len) {
	case 4:
		return ipv4_netmasklen(&netmask->v4);
	case 16:
		return ipv6_netmasklen(&netmask->v6);
	default:
		OSMO_ASSERT(0);
		return 0;
	}
}

/*! Convert given array of in46_addr to PDP End User Address
 *  \param[in] src Array containing 1 or 2 in46_addr
 *  \param[out] eua End User Address structure to fill
 *  \returns 0 on success; negative on error
 *
 * In case size is 2, this function expects to find exactly one IPv4 and one
 * IPv6 addresses in src. */
int in46a_to_eua(const struct in46_addr *src, unsigned int size, struct ul66_t *eua)
{
	const struct in46_addr *src_v4, *src_v6;
	if (size == 1) {
		switch (src->len) {
		case 4:
			eua->l = 6;
			eua->v[0] = PDP_EUA_ORG_IETF;
			eua->v[1] = PDP_EUA_TYPE_v4;
			memcpy(&eua->v[2], &src->v4, 4);	/* Copy a 4 byte address */
			break;
		case 8:
		case 16:
			eua->l = 18;
			eua->v[0] = PDP_EUA_ORG_IETF;
			eua->v[1] = PDP_EUA_TYPE_v6;
			memcpy(&eua->v[2], &src->v6, 16);	/* Copy a 16 byte address */
			break;
		default:
			OSMO_ASSERT(0);
			return -1;
		}
		return 0;
	}

	if (src[0].len == src[1].len)
		return -1; /* we should have a v4 and a v6 address */

	src_v4 = (src[0].len == 4) ? &src[0] : &src[1];
	src_v6 = (src[0].len == 4) ? &src[1] : &src[0];

	eua->l = 22;
	eua->v[0] = PDP_EUA_ORG_IETF;
	eua->v[1] = PDP_EUA_TYPE_v4v6;
	memcpy(&eua->v[2], &src_v4->v4, 4);
	memcpy(&eua->v[6], &src_v6->v6, 16);

	return 0;
}

/*! Convert given PDP End User Address to an array of in46_addr
 *  \param[in] eua End User Address structure to parse
 *  \param[out] dst Array containing 2 in46_addr
 *  \returns number of parsed addresses (1 or 2) on success; negative on error
 *
 * This function expects to receive an End User Address struct together with an
 * array of 2 zeroed in46_addr structs. The in46_addr structs are filled in
 * order, hence if the function returns 1 the parsed address will be stored in
 * the first struct and the second one will be left intact. If 2 is returned, it
 * is guaranteed that one of them is an IPv4 and the other one is an IPv6, but
 * the order in which they are presented is not specified and must be
 * discovered for instance by checking the len field of each address.
 */
int in46a_from_eua(const struct ul66_t *eua, struct in46_addr *dst)
{
	if (eua->l < 2)
		goto default_to_dyn_v4;

	if (eua->v[0] != 0xf1)
		return -1;

	switch (eua->v[1]) {
	case PDP_EUA_TYPE_v4:
		dst->len = 4;
		if (eua->l >= 6)
			memcpy(&dst->v4, &eua->v[2], 4);	/* Copy a 4 byte address */
		else
			dst->v4.s_addr = 0;
		return 1;
	case PDP_EUA_TYPE_v6:
		dst->len = 16;
		if (eua->l >= 18)
			memcpy(&dst->v6, &eua->v[2], 16);	/* Copy a 16 byte address */
		else
			memset(&dst->v6, 0, 16);
		return 1;
	case PDP_EUA_TYPE_v4v6:
		/* 3GPP TS 29.060, section 7.7.27 */
		switch (eua->l) {
			case 2: /* v4 & v6 dynamic */
				dst[0].v4.s_addr = 0;
				memset(&dst[1].v6, 0, 16);
				break;
			case 6: /* v4 static, v6 dynamic */
				memcpy(&dst[0].v4, &eua->v[2], 4);
				memset(&dst[1].v6, 0, 16);
				break;
			case 18: /* v4 dynamic, v6 static */
				dst[0].v4.s_addr = 0;
				memcpy(&dst[1].v6, &eua->v[2], 16);
				break;
			case 22:  /* v4 & v6 static */
				memcpy(&dst[0].v4, &eua->v[2], 4);
				memcpy(&dst[1].v6, &eua->v[6], 16);
				break;
			default:
				return -1;
		}
		dst[0].len = 4;
		dst[1].len = 16;
		return 2;
	default:
		return -1;
	}

default_to_dyn_v4:
	/* assume dynamic IPv4 by default */
	dst->len = 4;
	dst->v4.s_addr = 0;
	return 1;
}
