/** @file
 * @brief LLMNR responder
 *
 * This listens to LLMNR queries and responds to them.
 */

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

#include <logging/log.h>
LOG_MODULE_REGISTER(net_llmnr_responder, CONFIG_LLMNR_RESPONDER_LOG_LEVEL);

#include <zephyr.h>
#include <init.h>
#include <string.h>
#include <strings.h>
#include <errno.h>
#include <stdlib.h>

#include <net/net_ip.h>
#include <net/net_pkt.h>
#include <net/dns_resolve.h>
#include <net/udp.h>

#include "dns_pack.h"
#include "ipv6.h"

#include "net_private.h"

#define LLMNR_LISTEN_PORT 5355

#define LLMNR_TTL CONFIG_LLMNR_RESPONDER_TTL /* In seconds */

static struct net_context *ipv4;

#if defined(CONFIG_NET_IPV6)
static struct net_context *ipv6;
#endif

#define BUF_ALLOC_TIMEOUT K_MSEC(100)

/* This value is recommended by RFC 1035 */
#define DNS_RESOLVER_MAX_BUF_SIZE	512
#define DNS_RESOLVER_MIN_BUF		2
#define DNS_RESOLVER_BUF_CTR	(DNS_RESOLVER_MIN_BUF + \
				 CONFIG_LLMNR_RESOLVER_ADDITIONAL_BUF_CTR)

NET_BUF_POOL_DEFINE(llmnr_dns_msg_pool, DNS_RESOLVER_BUF_CTR,
		    DNS_RESOLVER_MAX_BUF_SIZE, 0, NULL);

#if defined(CONFIG_NET_IPV6)
static void create_ipv6_addr(struct sockaddr_in6 *addr)
{
	addr->sin6_family = AF_INET6;
	addr->sin6_port = htons(LLMNR_LISTEN_PORT);

	/* Well known IPv6 ff02::1:3 address */
	net_ipv6_addr_create(&addr->sin6_addr,
			     0xff02, 0, 0, 0, 0, 0, 0x01, 0x03);
}

static void create_ipv6_dst_addr(struct net_pkt *pkt,
				 struct sockaddr_in6 *addr)
{
	struct net_udp_hdr *udp_hdr, hdr;

	udp_hdr = net_udp_get_hdr(pkt, &hdr);

	addr->sin6_family = AF_INET6;
	addr->sin6_port = udp_hdr->src_port;

	net_ipaddr_copy(&addr->sin6_addr, &NET_IPV6_HDR(pkt)->src);
}
#endif

#if defined(CONFIG_NET_IPV4)
static void create_ipv4_addr(struct sockaddr_in *addr)
{
	addr->sin_family = AF_INET;
	addr->sin_port = htons(LLMNR_LISTEN_PORT);

	/* Well known IPv4 224.0.0.252 address */
	addr->sin_addr.s_addr = htonl(0xE00000FC);
}

static void create_ipv4_dst_addr(struct net_pkt *pkt,
				 struct sockaddr_in *addr)
{
	struct net_udp_hdr *udp_hdr, hdr;

	udp_hdr = net_udp_get_hdr(pkt, &hdr);
	if (!udp_hdr) {
		NET_ERR("could not get UDP header");
		return;
	}

	addr->sin_family = AF_INET;
	addr->sin_port = udp_hdr->src_port;

	net_ipaddr_copy(&addr->sin_addr, &NET_IPV4_HDR(pkt)->src);
}
#endif

static struct net_context *get_ctx(sa_family_t family)
{
	struct net_context *ctx;
	int ret;

	ret = net_context_get(family, SOCK_DGRAM, IPPROTO_UDP, &ctx);
	if (ret < 0) {
		NET_DBG("Cannot get context (%d)", ret);
		return NULL;
	}

	return ctx;
}

static int bind_ctx(struct net_context *ctx,
		    struct sockaddr *local_addr,
		    socklen_t addrlen)
{
	int ret;

	if (!ctx) {
		return -EINVAL;
	}

	ret = net_context_bind(ctx, local_addr, addrlen);
	if (ret < 0) {
		NET_DBG("Cannot bind to LLMNR %s port (%d)",
			local_addr->sa_family == AF_INET ?
			"IPv4" : "IPv6", ret);
		return ret;
	}

	return ret;
}

static void setup_dns_hdr(u8_t *buf, u16_t answers, u16_t dns_id)
{
	u16_t offset;
	u16_t flags;

	/* See RFC 1035, ch 4.1.1 and RFC 4795 ch 2.1.1 for header details */

	flags = BIT(15);  /* This is response */

	UNALIGNED_PUT(htons(dns_id), (u16_t *)(buf));
	offset = DNS_HEADER_ID_LEN;

	UNALIGNED_PUT(htons(flags), (u16_t *)(buf+offset));
	offset += DNS_HEADER_FLAGS_LEN;

	UNALIGNED_PUT(htons(1), (u16_t *)(buf + offset));
	offset += DNS_QDCOUNT_LEN;

	UNALIGNED_PUT(htons(answers), (u16_t *)(buf + offset));
	offset += DNS_ANCOUNT_LEN;

	UNALIGNED_PUT(0, (u16_t *)(buf + offset));
	offset += DNS_NSCOUNT_LEN;

	UNALIGNED_PUT(0, (u16_t *)(buf + offset));
}

static void add_question(struct net_buf *query, enum dns_rr_type qtype)
{
	char *dot = query->data + DNS_MSG_HEADER_SIZE;
	char *prev = NULL;
	u16_t offset;

	while ((dot = strchr(dot, '.'))) {
		if (!prev) {
			prev = dot++;
			continue;
		}

		*prev = dot - prev - 1;
		prev = dot++;
	}

	if (prev) {
		*prev = strlen(prev) - 1;
	}

	offset = DNS_MSG_HEADER_SIZE + query->len;
	UNALIGNED_PUT(htons(qtype), (u16_t *)(query->data+offset));

	offset += DNS_QTYPE_LEN;
	UNALIGNED_PUT(htons(DNS_CLASS_IN), (u16_t *)(query->data+offset));
}

static void add_answer(struct net_buf *query, u32_t ttl,
		       u16_t addr_len, const u8_t *addr)
{
	const u16_t q_len = query->len + DNS_QTYPE_LEN + DNS_QCLASS_LEN;
	u16_t offset = DNS_MSG_HEADER_SIZE + q_len;

	memcpy(query->data + offset, query->data, q_len);
	offset += q_len;

	UNALIGNED_PUT(htonl(ttl), query->data + offset);
	offset += DNS_TTL_LEN;

	UNALIGNED_PUT(htons(addr_len), query->data + offset);
	offset += DNS_RDLENGTH_LEN;

	memcpy(query->data + offset, addr, addr_len);
}

static int create_answer(struct net_context *ctx,
			 enum dns_rr_type qtype,
			 struct net_buf *query,
			 u16_t dns_id,
			 u16_t addr_len, const u8_t *addr)
{
	/* Prepare the response into the query buffer: move the name
	 * query buffer has to get enough free space: dns_hdr + query + answer
	 */
	if ((query->size - query->len) < (DNS_MSG_HEADER_SIZE +
					  (DNS_QTYPE_LEN + DNS_QCLASS_LEN) * 2 +
					  DNS_TTL_LEN + DNS_RDLENGTH_LEN +
					  addr_len + query->len)) {
		return -ENOBUFS;
	}

	memmove(query->data + DNS_MSG_HEADER_SIZE, query->data, query->len);

	setup_dns_hdr(query->data, 1, dns_id);

	add_question(query, qtype);

	add_answer(query, LLMNR_TTL, addr_len, addr);

	query->len += DNS_MSG_HEADER_SIZE +
		(DNS_QTYPE_LEN + DNS_QCLASS_LEN) * 2 +
		DNS_TTL_LEN + DNS_RDLENGTH_LEN + addr_len + query->len;

	return 0;
}

#if defined(CONFIG_NET_IPV4)
static const u8_t *get_ipv4_src(struct net_if *iface, struct in_addr *dst)
{
	const struct in_addr *addr;

	addr = net_if_ipv4_select_src_addr(iface, dst);
	if (!addr || net_ipv4_is_addr_unspecified(addr)) {
		return NULL;
	}

	return (const u8_t *)addr;
}
#endif

#if defined(CONFIG_NET_IPV6)
static const u8_t *get_ipv6_src(struct net_if *iface, struct in6_addr *dst)
{
	const struct in6_addr *addr;

	addr = net_if_ipv6_select_src_addr(iface, dst);
	if (!addr || net_ipv6_is_addr_unspecified(addr)) {
		return NULL;
	}

	return (const u8_t *)addr;
}
#endif

#if defined(CONFIG_NET_IPV4)
static int create_ipv4_answer(struct net_context *ctx,
			      struct net_pkt *pkt,
			      union net_ip_header *ip_hdr,
			      enum dns_rr_type qtype,
			      struct net_buf *query,
			      u16_t dns_id,
			      struct sockaddr *dst,
			      socklen_t *dst_len)
{
	const u8_t *addr;
	int addr_len;

	create_ipv4_dst_addr(pkt, net_sin(dst));
	*dst_len = sizeof(struct sockaddr_in);

	if (qtype == DNS_RR_TYPE_A) {
		/* Select proper address according to destination */
		addr = get_ipv4_src(net_pkt_iface(pkt),
				    &net_sin(dst)->sin_addr);
		if (!addr) {
			return -ENOENT;
		}

		addr_len = sizeof(struct in_addr);

	} else if (qtype == DNS_RR_TYPE_AAAA) {
#if defined(CONFIG_NET_IPV6)
		addr = get_ipv6_src(net_pkt_iface(pkt),
				    &ip_hdr->ipv6->src);
		if (!addr) {
			return -ENOENT;
		}

		addr_len = sizeof(struct in6_addr);
#else
		addr = NULL;
		addr_len = 0;
#endif
	} else {
		return -EINVAL;
	}

	if (create_answer(ctx, qtype, query, dns_id, addr_len, addr)) {
		return -ENOMEM;
	}

	net_context_set_ipv4_ttl(ctx, 255);

	return 0;
}
#endif /* CONFIG_NET_IPV4 */

#if defined(CONFIG_NET_IPV6)
static int create_ipv6_answer(struct net_context *ctx,
			      struct net_pkt *pkt,
			      union net_ip_header *ip_hdr,
			      enum dns_rr_type qtype,
			      struct net_buf *query,
			      u16_t dns_id,
			      struct sockaddr *dst,
			      socklen_t *dst_len)
{
	const u8_t *addr;
	int addr_len;

	create_ipv6_dst_addr(pkt, net_sin6(dst));
	*dst_len = sizeof(struct sockaddr_in6);

	if (qtype == DNS_RR_TYPE_AAAA) {
		addr = get_ipv6_src(net_pkt_iface(pkt),
				    &ip_hdr->ipv6->src);
		if (!addr) {
			return -ENOENT;
		}

		addr_len = sizeof(struct in6_addr);
	} else if (qtype == DNS_RR_TYPE_A) {
#if defined(CONFIG_NET_IPV4)
		addr = get_ipv4_src(net_pkt_iface(pkt),
				    &ip_hdr->ipv4->src);
		if (!addr) {
			return -ENOENT;
		}

		addr_len = sizeof(struct in_addr);
#else
		addr_len = 0;
#endif
	} else {
		return -EINVAL;
	}

	if (create_answer(ctx, qtype, query, dns_id, addr_len, addr)) {
		return -ENOMEM;
	}

	net_context_set_ipv6_hop_limit(ctx, 255);

	return 0;
}
#endif /* CONFIG_NET_IPV6 */

static int send_response(struct net_context *ctx, struct net_pkt *pkt,
			 union net_ip_header *ip_hdr, struct net_buf *reply,
			 enum dns_rr_type qtype, u16_t dns_id)
{
	struct sockaddr dst;
	socklen_t dst_len;
	int ret;

	if (IS_ENABLED(CONFIG_NET_IPV4) &&
	    net_pkt_family(pkt) == AF_INET) {
		ret = create_ipv4_answer(ctx, pkt, ip_hdr, qtype, reply,
					 dns_id, &dst, &dst_len);
		if (ret < 0) {
			return ret;
		}
	} else if (IS_ENABLED(CONFIG_NET_IPV6) &&
		   net_pkt_family(pkt) == AF_INET6) {
		ret = create_ipv6_answer(ctx, pkt, ip_hdr, qtype, reply,
					 dns_id, &dst, &dst_len);
		if (ret < 0) {
			return ret;
		}
	} else {
		/* TODO: support also service PTRs */
		return -EPFNOSUPPORT;
	}

	ret = net_context_sendto(ctx, reply->data, reply->len, &dst,
				 dst_len, NULL, K_NO_WAIT, NULL);
	if (ret < 0) {
		NET_DBG("Cannot send LLMNR reply to %s (%d)",
			net_pkt_family(pkt) == AF_INET ?
			log_strdup(net_sprint_ipv4_addr(
					   &net_sin(&dst)->sin_addr)) :
			log_strdup(net_sprint_ipv6_addr(
					   &net_sin6(&dst)->sin6_addr)),
			ret);
	}

	return ret;
}

static int dns_read(struct net_context *ctx,
		    struct net_pkt *pkt,
		    union net_ip_header *ip_hdr,
		    struct net_buf *dns_data,
		    struct dns_addrinfo *info)
{
	/* Helper struct to track the dns msg received from the server */
	const char *hostname = net_hostname_get();
	int hostname_len = strlen(hostname);
	struct net_buf *result;
	struct dns_msg_t dns_msg;
	u16_t dns_id = 0U;
	int data_len;
	int queries;
	int ret;

	data_len = MIN(net_pkt_remaining_data(pkt), DNS_RESOLVER_MAX_BUF_SIZE);

	/* Store the DNS query name into a temporary net_buf, which will be
	 * enventually used to send a response
	 */
	result = net_buf_alloc(&llmnr_dns_msg_pool, BUF_ALLOC_TIMEOUT);
	if (!result) {
		ret = -ENOMEM;
		goto quit;
	}

	/* TODO: Instead of this temporary copy, just use the net_pkt directly.
	 */
	ret = net_pkt_read(pkt, dns_data->data, data_len);
	if (ret < 0) {
		goto quit;
	}

	dns_msg.msg = dns_data->data;
	dns_msg.msg_size = data_len;

	ret = llmnr_unpack_query_header(&dns_msg, &dns_id);
	if (ret < 0) {
		ret = -EINVAL;
		goto quit;
	}

	queries = ret;

	NET_DBG("Received %d %s from %s (id 0x%04x)", queries,
		queries > 1 ? "queries" : "query",
		net_pkt_family(pkt) == AF_INET ?
		log_strdup(net_sprint_ipv4_addr(&ip_hdr->ipv4->src)) :
		log_strdup(net_sprint_ipv6_addr(&ip_hdr->ipv6->src)),
		dns_id);

	do {
		enum dns_rr_type qtype;
		enum dns_class qclass;

		(void)memset(result->data, 0, result->size);
		result->len = 0U;

		ret = dns_unpack_query(&dns_msg, result, &qtype, &qclass);
		if (ret < 0) {
			goto quit;
		}

		NET_DBG("[%d] query %s/%s label %s (%d bytes)", queries,
			qtype == DNS_RR_TYPE_A ? "A" : "AAAA", "IN",
			log_strdup(result->data), ret);

		/* If the query matches to our hostname, then send reply */
		if (!strncasecmp(hostname, result->data + 1, hostname_len) &&
		    (result->len - 1) >= hostname_len) {
			NET_DBG("LLMNR query to our hostname %s", hostname);
			send_response(ctx, pkt, ip_hdr, result, qtype, dns_id);
		}
	} while (--queries);

	ret = 0;

quit:
	if (result) {
		net_buf_unref(result);
	}

	return ret;
}

static void recv_cb(struct net_context *net_ctx,
		    struct net_pkt *pkt,
		    union net_ip_header *ip_hdr,
		    union net_proto_header *proto_hdr,
		    int status,
		    void *user_data)
{
	struct net_context *ctx = user_data;
	struct net_buf *dns_data = NULL;
	struct dns_addrinfo info = { 0 };
	int ret;

	ARG_UNUSED(net_ctx);
	NET_ASSERT(ctx == net_ctx);

	if (!pkt) {
		return;
	}

	if (status) {
		goto quit;
	}

	dns_data = net_buf_alloc(&llmnr_dns_msg_pool, BUF_ALLOC_TIMEOUT);
	if (!dns_data) {
		goto quit;
	}

	ret = dns_read(ctx, pkt, ip_hdr, dns_data, &info);
	if (ret < 0 && ret != -EINVAL) {
		NET_DBG("LLMNR read failed (%d)", ret);
	}

	net_buf_unref(dns_data);

quit:
	net_pkt_unref(pkt);
}

#if defined(CONFIG_NET_IPV6)
static void iface_ipv6_cb(struct net_if *iface, void *user_data)
{
	struct in6_addr *addr = user_data;
	int ret;

	ret = net_ipv6_mld_join(iface, addr);
	if (ret < 0) {
		NET_DBG("Cannot join %s IPv6 multicast group (%d)",
			log_strdup(net_sprint_ipv6_addr(addr)), ret);
	}
}

static void setup_ipv6_addr(struct sockaddr_in6 *local_addr)
{
	create_ipv6_addr(local_addr);

	net_if_foreach(iface_ipv6_cb, &local_addr->sin6_addr);
}
#endif /* CONFIG_NET_IPV6 */

#if defined(CONFIG_NET_IPV4)
static void iface_ipv4_cb(struct net_if *iface, void *user_data)
{
	struct in_addr *addr = user_data;
	struct net_if_mcast_addr *ifaddr;

	ifaddr = net_if_ipv4_maddr_add(iface, addr);
	if (!ifaddr) {
		NET_DBG("Cannot add IPv4 multicast address to iface %p",
			iface);
	}
}

static void setup_ipv4_addr(struct sockaddr_in *local_addr)
{
	create_ipv4_addr(local_addr);

	net_if_foreach(iface_ipv4_cb, &local_addr->sin_addr);
}
#endif /* CONFIG_NET_IPV4 */

static int init_listener(void)
{
	int ret, ok = 0;

#if defined(CONFIG_NET_IPV6)
	{
		static struct sockaddr_in6 local_addr;

		setup_ipv6_addr(&local_addr);

		ipv6 = get_ctx(AF_INET6);

		ret = bind_ctx(ipv6, (struct sockaddr *)&local_addr,
			       sizeof(local_addr));
		if (ret < 0) {
			net_context_put(ipv6);
			goto ipv6_out;
		}

		ret = net_context_recv(ipv6, recv_cb, K_NO_WAIT, ipv6);
		if (ret < 0) {
			NET_WARN("Cannot receive IPv6 LLMNR data (%d)", ret);
			net_context_put(ipv6);
		} else {
			ok++;
		}
	}
ipv6_out:
#endif /* CONFIG_NET_IPV6 */

#if defined(CONFIG_NET_IPV4)
	{
		static struct sockaddr_in local_addr;

		setup_ipv4_addr(&local_addr);

		ipv4 = get_ctx(AF_INET);

		ret = bind_ctx(ipv4, (struct sockaddr *)&local_addr,
			       sizeof(local_addr));
		if (ret < 0) {
			net_context_put(ipv4);
			goto ipv4_out;
		}

		ret = net_context_recv(ipv4, recv_cb, K_NO_WAIT, ipv4);
		if (ret < 0) {
			NET_WARN("Cannot receive IPv4 LLMNR data (%d)", ret);
			net_context_put(ipv4);
		} else {
			ok++;
		}
	}
ipv4_out:
#endif /* CONFIG_NET_IPV4 */

	if (!ok) {
		NET_WARN("Cannot start LLMNR responder");
	}

	return !ok;
}

static int llmnr_responder_init(struct device *device)
{
	ARG_UNUSED(device);

	return init_listener();
}

SYS_INIT(llmnr_responder_init, APPLICATION, CONFIG_LLMNR_RESPONDER_INIT_PRIO);
