/*! \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);
	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:
			rc = ns2_recv_vc(bind->nsi, nsvc, msg);
			break;
		case GPRS_NS2_CS_ERROR:
		case GPRS_NS2_CS_SKIPPED:
			rc = 0;
			break;
		case GPRS_NS2_CS_REJECTED:
			/* nsip_sendmsg will free reject */
			frgre_sendmsg(bind, reject, &saddr);
			return 0;
		case GPRS_NS2_CS_CREATED:
			frgre_alloc_vc(bind, nsvc, &saddr, dlci);
			gprs_ns2_vc_fsm_start(nsvc);
			rc = ns2_recv_vc(bind->nsi, nsvc, msg);
			break;
		}
	} else {
		/* VC found */
		rc = ns2_recv_vc(bind->nsi, 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,
			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 (!bind)
		return -ENOSPC;

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

	bind->driver = &vc_driver_frgre;
	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);
	}

	ns2_vty_bind_apply(bind);

	if (result)
		*result = bind;

	return rc;
}
