/** @file
 * @brief IPv4 IGMP related functions
 */

/*
 * Copyright (c) 2021 Intel Corporation
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include <zephyr/logging/log.h>
LOG_MODULE_DECLARE(net_ipv4, CONFIG_NET_IPV4_LOG_LEVEL);

#include <errno.h>
#include <zephyr/net/net_core.h>
#include <zephyr/net/net_pkt.h>
#include <zephyr/net/net_stats.h>
#include <zephyr/net/net_context.h>
#include <zephyr/net/net_mgmt.h>
#include <zephyr/net/igmp.h>
#include "net_private.h"
#include "connection.h"
#include "ipv4.h"
#include "net_stats.h"

/* Timeout for various buffer allocations in this file. */
#define PKT_WAIT_TIME K_MSEC(50)

#define IPV4_OPT_HDR_ROUTER_ALERT_LEN 4

static const struct in_addr all_systems = { { { 224, 0, 0, 1 } } };
static const struct in_addr all_routers = { { { 224, 0, 0, 2 } } };

#define dbg_addr(action, pkt_str, src, dst)				\
	NET_DBG("%s %s from %s to %s", action, pkt_str,			\
		net_sprint_ipv4_addr(src),			\
		net_sprint_ipv4_addr(dst));

#define dbg_addr_recv(pkt_str, src, dst) \
	dbg_addr("Received", pkt_str, src, dst)

static int igmp_v2_create(struct net_pkt *pkt, const struct in_addr *addr,
			  uint8_t type)
{
	NET_PKT_DATA_ACCESS_DEFINE(igmp_access,
				   struct net_ipv4_igmp_v2_report);
	struct net_ipv4_igmp_v2_report *igmp;

	igmp = (struct net_ipv4_igmp_v2_report *)
				net_pkt_get_data(pkt, &igmp_access);
	if (!igmp) {
		return -ENOBUFS;
	}

	igmp->type = type;
	igmp->max_rsp = 0U;
	net_ipaddr_copy(&igmp->address, addr);
	igmp->chksum = 0;
	igmp->chksum = net_calc_chksum_igmp((uint8_t *)igmp, sizeof(*igmp));

	if (net_pkt_set_data(pkt, &igmp_access)) {
		return -ENOBUFS;
	}

	return 0;
}

static int igmp_v2_create_packet(struct net_pkt *pkt, const struct in_addr *dst,
				 const struct in_addr *group, uint8_t type)
{
	const uint32_t router_alert = 0x94040000; /* RFC 2213 ch 2.1 */
	int ret;

	ret = net_ipv4_create_full(pkt,
				   net_if_ipv4_select_src_addr(
							net_pkt_iface(pkt),
							dst),
				   dst,
				   0U,
				   0U,
				   0U,
				   0U,
				   1U);  /* TTL set to 1, RFC 3376 ch 2 */
	if (ret) {
		return -ENOBUFS;
	}

	/* Add router alert option, RFC 3376 ch 2 */
	if (net_pkt_write_be32(pkt, router_alert)) {
		return -ENOBUFS;
	}

	net_pkt_set_ipv4_opts_len(pkt, IPV4_OPT_HDR_ROUTER_ALERT_LEN);

	return igmp_v2_create(pkt, group, type);
}

static int igmp_send(struct net_pkt *pkt)
{
	int ret;

	net_pkt_cursor_init(pkt);
	net_ipv4_finalize(pkt, IPPROTO_IGMP);

	ret = net_send_data(pkt);
	if (ret < 0) {
		net_stats_update_ipv4_igmp_drop(net_pkt_iface(pkt));
		net_pkt_unref(pkt);
		return ret;
	}

	net_stats_update_ipv4_igmp_sent(net_pkt_iface(pkt));

	return 0;
}

static int send_igmp_report(struct net_if *iface,
			    struct net_ipv4_igmp_v2_query *igmp_v2_hdr)
{
	struct net_if_ipv4 *ipv4 = iface->config.ip.ipv4;
	struct net_pkt *pkt = NULL;
	int i, count = 0;
	int ret = 0;

	if (!ipv4) {
		return -ENOENT;
	}

	for (i = 0; i < NET_IF_MAX_IPV4_MADDR; i++) {
		if (!ipv4->mcast[i].is_used || !ipv4->mcast[i].is_joined) {
			continue;
		}

		count++;
	}

	if (count == 0) {
		return -ESRCH;
	}

	for (i = 0; i < NET_IF_MAX_IPV4_MADDR; i++) {
		if (!ipv4->mcast[i].is_used || !ipv4->mcast[i].is_joined) {
			continue;
		}

		pkt = net_pkt_alloc_with_buffer(iface,
					IPV4_OPT_HDR_ROUTER_ALERT_LEN +
					sizeof(struct net_ipv4_igmp_v2_report),
					AF_INET, IPPROTO_IGMP,
					PKT_WAIT_TIME);
		if (!pkt) {
			return -ENOMEM;
		}

		/* Send the IGMP V2 membership report to the group multicast
		 * address, as per RFC 2236 Section 9.
		 */
		ret = igmp_v2_create_packet(pkt, &ipv4->mcast[i].address.in_addr,
					    &ipv4->mcast[i].address.in_addr,
					    NET_IPV4_IGMP_REPORT_V2);
		if (ret < 0) {
			goto drop;
		}

		ret = igmp_send(pkt);
		if (ret < 0) {
			goto drop;
		}

		/* So that we do not free the data while it is being sent */
		pkt = NULL;
	}

drop:
	if (pkt) {
		net_pkt_unref(pkt);
	}

	return ret;
}

enum net_verdict net_ipv4_igmp_input(struct net_pkt *pkt,
				     struct net_ipv4_hdr *ip_hdr)
{
	NET_PKT_DATA_ACCESS_CONTIGUOUS_DEFINE(igmp_access,
					      struct net_ipv4_igmp_v2_query);
	struct net_ipv4_igmp_v2_query *igmp_hdr;

	/* TODO: receive from arbitrary group address instead of
	 * all_systems
	 */
	if (!net_ipv4_addr_cmp_raw(ip_hdr->dst, (uint8_t *)&all_systems)) {
		NET_DBG("DROP: Invalid dst address");
		return NET_DROP;
	}

	igmp_hdr = (struct net_ipv4_igmp_v2_query *)net_pkt_get_data(pkt,
								&igmp_access);
	if (!igmp_hdr) {
		NET_DBG("DROP: NULL IGMP header");
		return NET_DROP;
	}

	if (net_calc_chksum_igmp((uint8_t *)igmp_hdr,
				 sizeof(*igmp_hdr)) != 0U) {
		NET_DBG("DROP: Invalid checksum");
		goto drop;
	}

	net_pkt_acknowledge_data(pkt, &igmp_access);

	dbg_addr_recv("Internet Group Management Protocol", &ip_hdr->src,
		      &ip_hdr->dst);

	net_stats_update_ipv4_igmp_recv(net_pkt_iface(pkt));

	(void)send_igmp_report(net_pkt_iface(pkt), igmp_hdr);

	net_pkt_unref(pkt);

	return NET_OK;

drop:
	net_stats_update_ipv4_igmp_drop(net_pkt_iface(pkt));

	return NET_DROP;
}

static int igmp_send_generic(struct net_if *iface,
			     const struct in_addr *addr,
			     bool join)
{
	struct net_pkt *pkt;
	int ret;

	pkt = net_pkt_alloc_with_buffer(iface,
					IPV4_OPT_HDR_ROUTER_ALERT_LEN +
					sizeof(struct net_ipv4_igmp_v2_report),
					AF_INET, IPPROTO_IGMP,
					PKT_WAIT_TIME);
	if (!pkt) {
		return -ENOMEM;
	}

	/* Send the IGMP V2 membership report to the group multicast
	 * address, as per RFC 2236 Section 9. The leave report
	 * should be sent to the ALL ROUTERS multicast address (224.0.0.2)
	 */
	ret = igmp_v2_create_packet(pkt,
				join ? addr : &all_routers, addr,
				join ? NET_IPV4_IGMP_REPORT_V2 : NET_IPV4_IGMP_LEAVE);
	if (ret < 0) {
		goto drop;
	}

	ret = igmp_send(pkt);
	if (ret < 0) {
		goto drop;
	}

	return 0;

drop:
	net_pkt_unref(pkt);

	return ret;
}

int net_ipv4_igmp_join(struct net_if *iface, const struct in_addr *addr)
{
	struct net_if_mcast_addr *maddr;
	int ret;

	maddr = net_if_ipv4_maddr_lookup(addr, &iface);
	if (maddr && net_if_ipv4_maddr_is_joined(maddr)) {
		return -EALREADY;
	}

	if (!maddr) {
		maddr = net_if_ipv4_maddr_add(iface, addr);
		if (!maddr) {
			return -ENOMEM;
		}
	}

	ret = igmp_send_generic(iface, addr, true);
	if (ret < 0) {
		return ret;
	}

	net_if_ipv4_maddr_join(maddr);

	net_if_mcast_monitor(iface, &maddr->address, true);

	net_mgmt_event_notify_with_info(NET_EVENT_IPV4_MCAST_JOIN, iface,
					&maddr->address.in_addr,
					sizeof(struct in_addr));
	return ret;
}

int net_ipv4_igmp_leave(struct net_if *iface, const struct in_addr *addr)
{
	struct net_if_mcast_addr *maddr;
	int ret;

	maddr = net_if_ipv4_maddr_lookup(addr, &iface);
	if (!maddr) {
		return -ENOENT;
	}

	if (!net_if_ipv4_maddr_rm(iface, addr)) {
		return -EINVAL;
	}

	ret = igmp_send_generic(iface, addr, false);
	if (ret < 0) {
		return ret;
	}

	net_if_ipv4_maddr_leave(maddr);

	net_if_mcast_monitor(iface, &maddr->address, false);

	net_mgmt_event_notify_with_info(NET_EVENT_IPV4_MCAST_LEAVE, iface,
					&maddr->address.in_addr,
					sizeof(struct in_addr));
	return ret;
}
