/*! \file gprs_ns2_frgre.c
 * NS-over-FR-over-GRE implementation.
 * GPRS Networks Service (NS) messages on the Gb interface.
 * 3GPP TS 08.16 version 8.0.1 Release 1999 / ETSI TS 101 299 V8.0.1 (2002-05)
 * as well as its successor 3GPP TS 48.016 */

/* (C) 2009-2010,2014,2017 by Harald Welte <laforge@gnumonks.org>
 * (C) 2020 sysmocom - s.f.m.c. GmbH
 * Author: Alexander Couzens <lynxis@fe80.eu>
 *
 * All Rights Reserved
 *
 * SPDX-License-Identifier: GPL-2.0+
 *
 * This program is free software; you can redistribute 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.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 */

#include <errno.h>
#include <string.h>
#include <unistd.h>

#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <netinet/ip6.h>
#include <arpa/inet.h>

#include <osmocom/core/byteswap.h>
#include <osmocom/core/logging.h>
#include <osmocom/core/msgb.h>
#include <osmocom/core/select.h>
#include <osmocom/core/socket.h>
#include <osmocom/core/talloc.h>
#include <osmocom/gprs/gprs_ns2.h>

#include "gprs_ns2_internal.h"

#define GRE_PTYPE_FR	0x6559
#define GRE_PTYPE_IPv4	0x0800
#define GRE_PTYPE_IPv6	0x86dd
#define GRE_PTYPE_KAR	0x0000	/* keepalive response */

#ifndef IPPROTO_GRE
# define IPPROTO_GRE 47
#endif

struct gre_hdr {
	uint16_t flags;
	uint16_t ptype;
} __attribute__ ((packed));

#if defined(__FreeBSD__) || defined(__APPLE__) || defined(__CYGWIN__)
/**
 * On BSD the IPv4 struct is called struct ip and instead of iXX
 * the members are called ip_XX. One could change this code to use
 * struct ip but that would require to define _BSD_SOURCE and that
 * might have other complications. Instead make sure struct iphdr
 * is present on FreeBSD. The below is taken from GLIBC.
 *
 * The GNU C Library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 */
struct iphdr
  {
#if BYTE_ORDER == LITTLE_ENDIAN
    unsigned int ihl:4;
    unsigned int version:4;
#elif BYTE_ORDER == BIG_ENDIAN
    unsigned int version:4;
    unsigned int ihl:4;
#endif
    u_int8_t tos;
    u_int16_t tot_len;
    u_int16_t id;
    u_int16_t frag_off;
    u_int8_t ttl;
    u_int8_t protocol;
    u_int16_t check;
    u_int32_t saddr;
    u_int32_t daddr;
    /*The options start here. */
  };
#endif


static void free_bind(struct gprs_ns2_vc_bind *bind);
static inline int frgre_sendmsg(struct gprs_ns2_vc_bind *bind,
			       struct msgb *msg,
			       struct osmo_sockaddr *dest);

struct gprs_ns2_vc_driver vc_driver_frgre = {
	.name = "GB frame relay over GRE",
	.free_bind = free_bind,
};

struct priv_bind {
	struct osmo_fd fd;
	struct osmo_sockaddr addr;
	uint16_t dlci;
	int dscp;
};

struct priv_vc {
	struct osmo_sockaddr remote;
	uint16_t dlci;
};

static void free_vc(struct gprs_ns2_vc *nsvc)
{
	OSMO_ASSERT(nsvc);

	if (!nsvc->priv)
		return;

	talloc_free(nsvc->priv);
	nsvc->priv = NULL;
}


/*! clean up all private driver state. Should be only called by gprs_ns2_free_bind() */
static void free_bind(struct gprs_ns2_vc_bind *bind)
{
	struct priv_bind *priv;

	if (!bind)
		return;

	priv = bind->priv;

	OSMO_ASSERT(llist_empty(&bind->nsvc));

	osmo_fd_close(&priv->fd);
	talloc_free(priv);
}

static struct priv_vc *frgre_alloc_vc(struct gprs_ns2_vc_bind *bind,
				      struct gprs_ns2_vc *nsvc,
				      struct osmo_sockaddr *remote,
				      uint16_t dlci)
{
	struct priv_vc *priv = talloc_zero(bind, struct priv_vc);
	if (!priv)
		return NULL;

	nsvc->priv = priv;
	priv->remote = *remote;
	priv->dlci = dlci;

	return priv;
}

static int handle_rx_gre_ipv6(struct osmo_fd *bfd, struct msgb *msg,
			      struct ip6_hdr *ip6hdr, struct gre_hdr *greh)
{
	/* RFC 7676 IPv6 Support for Generic Routing Encapsulation (GRE) */
	struct gprs_ns2_vc_bind *bind = bfd->data;
	struct priv_bind *priv = bind->priv;
	int gre_payload_len;
	struct ip6_hdr *inner_ip6h;
	struct gre_hdr *inner_greh;
	struct sockaddr_in6 daddr;
	struct in6_addr ia6;

	gre_payload_len = msg->len - (sizeof(*ip6hdr) + sizeof(*greh));

	inner_ip6h = (struct ip6_hdr *) ((uint8_t *)greh + sizeof(*greh));

	if (gre_payload_len < sizeof(*ip6hdr) + sizeof(*inner_greh)) {
		LOGP(DLNS, LOGL_ERROR, "GRE keepalive too short\n");
		return -EIO;
	}

	if (!memcmp(&inner_ip6h->ip6_src, &ip6hdr->ip6_src, sizeof(struct in6_addr)) ||
	    !memcmp(&inner_ip6h->ip6_dst, &ip6hdr->ip6_dst, sizeof(struct in6_addr))) {
		LOGP(DLNS, LOGL_ERROR,
			"GRE keepalive with wrong tunnel addresses\n");
		return -EIO;
	}

	/* Are IPv6 extensions header are allowed in the *inner*? In the outer they are */
	if (inner_ip6h->ip6_ctlun.ip6_un1.ip6_un1_nxt != IPPROTO_GRE) {
		LOGP(DLNS, LOGL_ERROR, "GRE keepalive with wrong protocol\n");
		return -EIO;
	}

	inner_greh = (struct gre_hdr *) ((uint8_t *)inner_ip6h + sizeof(struct ip6_hdr));
	if (inner_greh->ptype != osmo_htons(GRE_PTYPE_KAR)) {
		LOGP(DLNS, LOGL_ERROR, "GRE keepalive inner GRE type != 0\n");
		return -EIO;
	}

	/* Actually send the response back */

	daddr.sin6_family = AF_INET6;
	daddr.sin6_addr = inner_ip6h->ip6_dst;
	daddr.sin6_port = IPPROTO_GRE;

	ia6 = ip6hdr->ip6_src;
	char ip6str[INET6_ADDRSTRLEN] = {};
	inet_ntop(AF_INET6, &ia6, ip6str, INET6_ADDRSTRLEN);
	LOGP(DLNS, LOGL_DEBUG, "GRE keepalive from %s, responding\n", ip6str);

	/* why does it reduce the gre_payload_len by the ipv6 header?
	 * make it similiar to ipv4 even this seems to be wrong */
	return sendto(priv->fd.fd, inner_greh,
		      gre_payload_len - sizeof(*inner_ip6h), 0,
		      (struct sockaddr *)&daddr, sizeof(daddr));
}

/* IPv4 messages inside the GRE tunnel might be GRE keepalives */
static int handle_rx_gre_ipv4(struct osmo_fd *bfd, struct msgb *msg,
			      struct iphdr *iph, struct gre_hdr *greh)
{
	struct gprs_ns2_vc_bind *bind = bfd->data;
	struct priv_bind *priv = bind->priv;
	int gre_payload_len;
	struct iphdr *inner_iph;
	struct gre_hdr *inner_greh;
	struct sockaddr_in daddr;
	struct in_addr ia;

	gre_payload_len = msg->len - (iph->ihl*4 + sizeof(*greh));

	inner_iph = (struct iphdr *) ((uint8_t *)greh + sizeof(*greh));

	if (gre_payload_len < inner_iph->ihl*4 + sizeof(*inner_greh)) {
		LOGP(DLNS, LOGL_ERROR, "GRE keepalive too short\n");
		return -EIO;
	}

	if (inner_iph->saddr != iph->daddr ||
	    inner_iph->daddr != iph->saddr) {
		LOGP(DLNS, LOGL_ERROR,
			"GRE keepalive with wrong tunnel addresses\n");
		return -EIO;
	}

	if (inner_iph->protocol != IPPROTO_GRE) {
		LOGP(DLNS, LOGL_ERROR, "GRE keepalive with wrong protocol\n");
		return -EIO;
	}

	inner_greh = (struct gre_hdr *) ((uint8_t *)inner_iph + iph->ihl*4);
	if (inner_greh->ptype != osmo_htons(GRE_PTYPE_KAR)) {
		LOGP(DLNS, LOGL_ERROR, "GRE keepalive inner GRE type != 0\n");
		return -EIO;
	}

	/* Actually send the response back */

	daddr.sin_family = AF_INET;
	daddr.sin_addr.s_addr = inner_iph->daddr;
	daddr.sin_port = IPPROTO_GRE;

	ia.s_addr = iph->saddr;
	LOGP(DLNS, LOGL_DEBUG, "GRE keepalive from %s, responding\n",
		inet_ntoa(ia));

	/* why does it reduce the gre_payload_len by the ipv4 header? */
	return sendto(priv->fd.fd, inner_greh,
		      gre_payload_len - inner_iph->ihl*4, 0,
		      (struct sockaddr *)&daddr, sizeof(daddr));
}

static struct msgb *read_nsfrgre_msg(struct osmo_fd *bfd, int *error,
				     struct osmo_sockaddr *saddr, uint16_t *dlci)
{
	struct msgb *msg = msgb_alloc(NS_ALLOC_SIZE, "Gb/NS/FR/GRE Rx");
	int ret = 0;
	socklen_t saddr_len = sizeof(*saddr);
	struct iphdr *iph = NULL;
	struct ip6_hdr *ip6h = NULL;
	size_t ip46hdr;
	struct gre_hdr *greh;
	uint8_t *frh;

	if (!msg) {
		*error = -ENOMEM;
		return NULL;
	}

	ret = recvfrom(bfd->fd, msg->data, NS_ALLOC_SIZE, 0,
			&saddr->u.sa, &saddr_len);
	if (ret < 0) {
		LOGP(DLNS, LOGL_ERROR, "recv error %s during NS-FR-GRE recv\n",
			strerror(errno));
		*error = ret;
		goto out_err;
	} else if (ret == 0) {
		*error = ret;
		goto out_err;
	}

	msgb_put(msg, ret);

	/* we've received a raw packet including the IPv4 or IPv6 header */
	switch (saddr->u.sa.sa_family) {
	case AF_INET:
		ip46hdr = sizeof(struct iphdr);
		break;
	case AF_INET6:
		ip46hdr = sizeof(struct ip6_hdr);
		break;
	default:
		*error = -EIO;
		goto out_err;
		break;
	}

	/* TODO: add support for the extension headers */
	if (msg->len < ip46hdr + sizeof(*greh) + 2) {
		LOGP(DLNS, LOGL_ERROR, "Short IP packet: %u bytes\n", msg->len);
		*error = -EIO;
		goto out_err;
	}

	switch (saddr->u.sa.sa_family) {
	case AF_INET:
		iph = (struct iphdr *) msg->data;
		if (msg->len < (iph->ihl*4 + sizeof(*greh) + 2)) {
			LOGP(DLNS, LOGL_ERROR, "Short IP packet: %u bytes\n", msg->len);
			*error = -EIO;
			goto out_err;
		}
		break;
	case AF_INET6:
		ip6h = (struct ip6_hdr *) msg->data;
		break;
	}

	greh = (struct gre_hdr *) (msg->data + iph->ihl*4);
	if (greh->flags) {
		LOGP(DLNS, LOGL_NOTICE, "Unknown GRE flags 0x%04x\n",
			osmo_ntohs(greh->flags));
	}

	switch (osmo_ntohs(greh->ptype)) {
	case GRE_PTYPE_IPv4:
		/* IPv4 messages might be GRE keepalives */
		*error = handle_rx_gre_ipv4(bfd, msg, iph, greh);
		goto out_err;
		break;
	case GRE_PTYPE_IPv6:
		*error = handle_rx_gre_ipv6(bfd, msg, ip6h, greh);
		goto out_err;
		break;
	case GRE_PTYPE_FR:
		/* continue as usual */
		break;
	default:
		LOGP(DLNS, LOGL_NOTICE, "Unknown GRE protocol 0x%04x != FR\n",
			osmo_ntohs(greh->ptype));
		*error = -EIO;
		goto out_err;
		break;
	}

	if (msg->len < sizeof(*greh) + 2) {
		LOGP(DLNS, LOGL_ERROR, "Short FR header: %u bytes\n", msg->len);
		*error = -EIO;
		goto out_err;
	}

	frh = (uint8_t *)greh + sizeof(*greh);
	if (frh[0] & 0x01) {
		LOGP(DLNS, LOGL_NOTICE, "Unsupported single-byte FR address\n");
		*error = -EIO;
		goto out_err;
	}
	*dlci = ((frh[0] & 0xfc) << 2);
	if ((frh[1] & 0x0f) != 0x01) {
		LOGP(DLNS, LOGL_NOTICE, "Unknown second FR octet 0x%02x\n",
			frh[1]);
		*error = -EIO;
		goto out_err;
	}
	*dlci |= (frh[1] >> 4);

	msg->l2h = frh+2;

	return msg;

out_err:
	msgb_free(msg);
	return NULL;
}

static int gprs_ns2_find_vc_by_dlci(struct gprs_ns2_vc_bind *bind,
				    uint16_t dlci,
				    struct gprs_ns2_vc **result)
{
	struct gprs_ns2_vc *nsvc;
	struct priv_vc *vcpriv;

	if (!result)
		return -EINVAL;

	llist_for_each_entry(nsvc, &bind->nsvc, blist) {
		vcpriv = nsvc->priv;
		if (vcpriv->dlci != dlci) {
			*result = nsvc;
			return 0;
		}
	}

	return 1;
}

static int handle_nsfrgre_read(struct osmo_fd *bfd)
{
	int rc;
	struct osmo_sockaddr saddr;
	struct gprs_ns2_vc *nsvc;
	struct gprs_ns2_vc_bind *bind = bfd->data;
	struct msgb *msg;
	struct msgb *reject;
	uint16_t dlci;

	msg = read_nsfrgre_msg(bfd, &rc, &saddr, &dlci);
	if (!msg)
		return rc;

	if (dlci == 0 || dlci == 1023) {
		LOGP(DLNS, LOGL_INFO, "Received FR on LMI DLCI %u - ignoring\n",
			dlci);
		rc = 0;
		goto out;
	}

	rc = gprs_ns2_find_vc_by_dlci(bind, dlci, &nsvc);
	if (rc) {
		/* VC not found */
		rc = ns2_create_vc(bind, msg, "newconnection", &reject, &nsvc);
		switch (rc) {
		case GPRS_NS2_CS_FOUND:
			break;
		case GPRS_NS2_CS_ERROR:
		case GPRS_NS2_CS_SKIPPED:
			rc = 0;
			goto out;
		case GPRS_NS2_CS_REJECTED:
			/* nsip_sendmsg will free reject */
			rc = frgre_sendmsg(bind, reject, &saddr);
			goto out;
		case GPRS_NS2_CS_CREATED:
			frgre_alloc_vc(bind, nsvc, &saddr, dlci);
			gprs_ns2_vc_fsm_start(nsvc);
			break;
		}
	}

	rc = ns2_recv_vc(nsvc, msg);
out:
	msgb_free(msg);

	return rc;
}

static int handle_nsfrgre_write(struct osmo_fd *bfd)
{
	/* FIXME: actually send the data here instead of nsip_sendmsg() */
	return -EIO;
}

static inline int frgre_sendmsg(struct gprs_ns2_vc_bind *bind,
			       struct msgb *msg,
			       struct osmo_sockaddr *dest)
{
	int rc;
	struct priv_bind *priv = bind->priv;

	rc = sendto(priv->fd.fd, msg->data, msg->len, 0,
		    &dest->u.sa, sizeof(*dest));

	msgb_free(msg);

	return rc;
}

static int frgre_vc_sendmsg(struct gprs_ns2_vc *nsvc, struct msgb *msg)
{
	struct gprs_ns2_vc_bind *bind = nsvc->bind;
	struct priv_vc *vcpriv = nsvc->priv;
	struct priv_bind *bindpriv = bind->priv;

	uint16_t dlci = osmo_htons(bindpriv->dlci);
	uint8_t *frh;
	struct gre_hdr *greh;

	/* Prepend the FR header */
	frh = msgb_push(msg, 2);
	frh[0] = (dlci >> 2) & 0xfc;
	frh[1] = ((dlci & 0xf)<<4) | 0x01;

	/* Prepend the GRE header */
	greh = (struct gre_hdr *) msgb_push(msg, sizeof(*greh));
	greh->flags = 0;
	greh->ptype = osmo_htons(GRE_PTYPE_FR);

	return frgre_sendmsg(bind, msg, &vcpriv->remote);
}

static int frgre_fd_cb(struct osmo_fd *bfd, unsigned int what)
{
	int rc = 0;

	if (what & OSMO_FD_READ)
		rc = handle_nsfrgre_read(bfd);
	if (what & OSMO_FD_WRITE)
		rc = handle_nsfrgre_write(bfd);

	return rc;
}

/*! determine if given bind is for FR-GRE encapsulation. */
int gprs_ns2_is_frgre_bind(struct gprs_ns2_vc_bind *bind)
{
	return (bind->driver == &vc_driver_frgre);
}

/*! Create a new bind for NS over FR-GRE.
 *  \param[in] nsi NS instance in which to create the bind
 *  \param[in] local local address on which to bind
 *  \param[in] dscp DSCP/TOS bits to use for transmitted data on this bind
 *  \param[out] result pointer to created bind
 *  \return 0 on success; negative on error */
int gprs_ns2_frgre_bind(struct gprs_ns2_inst *nsi,
			const char *name,
			const struct osmo_sockaddr *local,
			int dscp,
			struct gprs_ns2_vc_bind **result)
{
	struct gprs_ns2_vc_bind *bind = talloc_zero(nsi, struct gprs_ns2_vc_bind);
	struct priv_bind *priv;
	int rc;

	if (!name)
		return -ENOSPC;

	if (gprs_ns2_bind_by_name(nsi, name))
		return -EALREADY;

	if (!bind)
		return -ENOSPC;

	if (local->u.sa.sa_family != AF_INET && local->u.sa.sa_family != AF_INET6) {
		talloc_free(bind);
		return -EINVAL;
	}

	bind->name = talloc_strdup(bind, name);
	if (!bind->name) {
		talloc_free(bind);
		return -ENOSPC;
	}

	bind->driver = &vc_driver_frgre;
	bind->ll = GPRS_NS2_LL_FR_GRE;
	/* 2 mbit transfer capability. Counting should be done different for this. */
	bind->transfer_capability = 2;
	bind->send_vc = frgre_vc_sendmsg;
	bind->free_vc = free_vc;
	bind->nsi = nsi;

	priv = bind->priv = talloc_zero(bind, struct priv_bind);
	if (!priv) {
		talloc_free(bind);
		return -ENOSPC;
	}
	priv->fd.cb = frgre_fd_cb;
	priv->fd.data = bind;
	priv->addr = *local;
	INIT_LLIST_HEAD(&bind->nsvc);

	llist_add(&bind->list, &nsi->binding);

	rc = osmo_sock_init_osa_ofd(&priv->fd, SOCK_RAW, IPPROTO_GRE,
				 local, NULL,
				 OSMO_SOCK_F_BIND);
	if (rc < 0) {
		talloc_free(priv);
		talloc_free(bind);
		return rc;
	}

	if (dscp > 0) {
		priv->dscp = dscp;

		rc = setsockopt(priv->fd.fd, IPPROTO_IP, IP_TOS,
				&dscp, sizeof(dscp));
		if (rc < 0)
			LOGP(DLNS, LOGL_ERROR,
				"Failed to set the DSCP to %d with ret(%d) errno(%d)\n",
				dscp, rc, errno);
	}

	if (result)
		*result = bind;

	return rc;
}
