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

#include <string.h>
#include <zephyr/net/buf.h>

#include "dns_pack.h"

#include "dns_internal.h"

static inline uint16_t dns_strlen(const char *str)
{
	if (str == NULL) {
		return 0;
	}
	return (uint16_t)strlen(str);
}

int dns_msg_pack_qname(uint16_t *len, uint8_t *buf, uint16_t size,
		       const char *domain_name)
{
	uint16_t dn_size;
	uint16_t lb_start;
	uint16_t lb_index;
	uint16_t lb_size;
	uint16_t i;

	lb_start = 0U;
	lb_index = 1U;
	lb_size = 0U;

	dn_size = dns_strlen(domain_name);
	if (dn_size == 0U) {
		return -EINVAL;
	}

	/* traverse the domain name str, including the null-terminator :) */
	for (i = 0U; i < dn_size + 1; i++) {
		if (lb_index >= size) {
			return -ENOMEM;
		}

		switch (domain_name[i]) {
		default:
			buf[lb_index] = domain_name[i];
			lb_size += 1U;
			break;
		case '.':
			buf[lb_start] = lb_size;
			lb_size = 0U;
			lb_start = lb_index;
			break;
		case '\0':
			buf[lb_start] = lb_size;
			buf[lb_index] = 0U;
			break;
		}
		lb_index += 1U;
	}

	*len = lb_index;

	return 0;
}

static inline void set_dns_msg_response(struct dns_msg_t *dns_msg, int type,
					uint16_t pos, uint16_t len)
{
	dns_msg->response_type = type;
	dns_msg->response_position = pos;
	dns_msg->response_length = len;
}

/*
 * Skip encoded FQDN in DNS message.
 * Returns size in bytes of encoded FQDN, or negative error code.
 */
static int skip_fqdn(uint8_t *answer, int buf_sz)
{
	int i = 0;

	while (1) {
		if (i >= buf_sz) {
			return -EINVAL;
		}

		if (answer[i] == 0) {
			i += 1;
			break;
		} else if (answer[i] >= 0xc0) {
			i += 2;
			if (i > buf_sz) {
				return -EINVAL;
			}
			break;
		} else if (answer[i] < DNS_LABEL_MAX_SIZE) {
			i += answer[i] + 1;
		} else {
			return -EINVAL;
		}
	}

	return i;
}

int dns_unpack_answer(struct dns_msg_t *dns_msg, int dname_ptr, uint32_t *ttl,
		      enum dns_rr_type *type)
{
	int dname_len;
	uint16_t rem_size;
	uint16_t pos;
	uint16_t len;
	uint8_t *answer;

	answer = dns_msg->msg + dns_msg->answer_offset;

	dname_len = skip_fqdn(answer,
			      dns_msg->msg_size - dns_msg->answer_offset);
	if (dname_len < 0) {
		return dname_len;
	}

	/*
	 * We need to be sure this buffer has enough space
	 * to contain the answer.
	 *
	 * size: dname_size + type + class + ttl + rdlength + rdata
	 *            2     +   2  +   2   +  4  +     2    +  ?
	 *
	 * So, answer size >= 12
	 *
	 * See RFC-1035 4.1.3. Resource record format
	 */
	rem_size = dns_msg->msg_size - dname_len;
	if (rem_size < 2 + 2 + 4 + 2) {
		return -EINVAL;
	}

	/* Only DNS_CLASS_IN answers. If mDNS is enabled, strip away the
	 * Cache-Flush bit (highest one).
	 */
	if ((dns_answer_class(dname_len, answer) &
	     (IS_ENABLED(CONFIG_MDNS_RESOLVER) ? 0x7fff : 0xffff))
							!= DNS_CLASS_IN) {
		return -EINVAL;
	}

	/* TTL value */
	*ttl = dns_answer_ttl(dname_len, answer);
	len = dns_answer_rdlength(dname_len, answer);
	pos = dns_msg->answer_offset + dname_len +
		DNS_COMMON_UINT_SIZE + /* class length */
		DNS_COMMON_UINT_SIZE + /* type length */
		DNS_TTL_LEN +
		DNS_RDLENGTH_LEN;
	*type = dns_answer_type(dname_len, answer);

	switch (*type) {
	case DNS_RR_TYPE_A:
	case DNS_RR_TYPE_AAAA:
		set_dns_msg_response(dns_msg, DNS_RESPONSE_IP, pos, len);
		return 0;

	case DNS_RR_TYPE_CNAME:
		set_dns_msg_response(dns_msg, DNS_RESPONSE_CNAME_NO_IP,
				     pos, len);
		return 0;

	default:
		/* malformed dns answer */
		return -EINVAL;
	}

	return 0;
}

int dns_unpack_response_header(struct dns_msg_t *msg, int src_id)
{
	uint8_t *dns_header;
	uint16_t size;
	int qdcount;
	int ancount;
	int rc;

	dns_header = msg->msg;
	size = msg->msg_size;

	if (size < DNS_MSG_HEADER_SIZE) {
		return -ENOMEM;
	}

	if (dns_unpack_header_id(dns_header) != src_id) {
		return -EINVAL;
	}

	if (dns_header_qr(dns_header) != DNS_RESPONSE) {
		return -EINVAL;
	}

	if (dns_header_opcode(dns_header) != DNS_QUERY) {
		return -EINVAL;
	}

	if (dns_header_z(dns_header) != 0) {
		return -EINVAL;
	}

	rc = dns_header_rcode(dns_header);
	switch (rc) {
	case DNS_HEADER_NOERROR:
		break;
	default:
		return rc;

	}

	qdcount = dns_unpack_header_qdcount(dns_header);
	ancount = dns_unpack_header_ancount(dns_header);

	/* For mDNS (when src_id == 0) the query count is 0 so accept
	 * the packet in that case.
	 */
	if ((qdcount < 1 && src_id > 0) || ancount < 1) {
		return -EINVAL;
	}

	return 0;
}

static int dns_msg_pack_query_header(uint8_t *buf, uint16_t size, uint16_t id)
{
	uint16_t offset;

	if (size < DNS_MSG_HEADER_SIZE) {
		return -ENOMEM;
	}

	UNALIGNED_PUT(htons(id), (uint16_t *)(buf));

	/* RD = 1, TC = 0, AA = 0, Opcode = 0, QR = 0 <-> 0x01 (1B)
	 * RCode = 0, Z = 0, RA = 0		      <-> 0x00 (1B)
	 *
	 * QDCOUNT = 1				      <-> 0x0001 (2B)
	 */

	offset = DNS_HEADER_ID_LEN;
	/* Split the following assignments just in case we need to alter
	 * the flags in future releases
	 */
	*(buf + offset) = DNS_FLAGS1;		/* QR, Opcode, AA, TC and RD */
	*(buf + offset + 1) = DNS_FLAGS2;	/* RA, Z and RCODE */

	offset += DNS_HEADER_FLAGS_LEN;
	/* set question counter */
	UNALIGNED_PUT(htons(1), (uint16_t *)(buf + offset));

	offset += DNS_QDCOUNT_LEN;
	/* set answer and ns rr */
	UNALIGNED_PUT(0, (uint32_t *)(buf + offset));

	offset += DNS_ANCOUNT_LEN + DNS_NSCOUNT_LEN;
	/* set the additional records */
	UNALIGNED_PUT(0, (uint16_t *)(buf + offset));

	return 0;
}

int dns_msg_pack_query(uint8_t *buf, uint16_t *len, uint16_t size,
		       uint8_t *qname, uint16_t qname_len, uint16_t id,
		       enum dns_rr_type qtype)
{
	uint16_t msg_size;
	uint16_t offset;
	int rc;

	msg_size = DNS_MSG_HEADER_SIZE + DNS_QTYPE_LEN + DNS_QCLASS_LEN;
	if (msg_size + qname_len > size) {
		return -ENOMEM;
	}

	rc = dns_msg_pack_query_header(buf, size, id);
	if (rc != 0) {
		return rc;
	}

	offset = DNS_MSG_HEADER_SIZE;
	memcpy(buf + offset, qname, qname_len);

	offset += qname_len;

	/* QType */
	UNALIGNED_PUT(htons(qtype), (uint16_t *)(buf + offset + 0));
	offset += DNS_QTYPE_LEN;

	/* QClass */
	UNALIGNED_PUT(htons(DNS_CLASS_IN), (uint16_t *)(buf + offset));

	*len = offset + DNS_QCLASS_LEN;

	return 0;
}

static int dns_find_null(int *qname_size, uint8_t *buf, uint16_t size)
{
	*qname_size = 0;
	while (*qname_size < size) {
		if (buf[(*qname_size)++] == 0x00) {
			return 0;
		}
	}

	return -ENOMEM;
}

int dns_unpack_response_query(struct dns_msg_t *dns_msg)
{
	uint8_t *dns_query;
	uint8_t *buf;
	int remaining_size;
	int qname_size;
	int offset;
	int rc;

	dns_msg->query_offset = DNS_MSG_HEADER_SIZE;
	dns_query = dns_msg->msg + dns_msg->query_offset;
	remaining_size = dns_msg->msg_size - dns_msg->query_offset;

	rc = dns_find_null(&qname_size, dns_query, remaining_size);
	if (rc != 0) {
		return rc;
	}

	/* header already parsed + qname size */
	offset = dns_msg->query_offset + qname_size;

	/* 4 bytes more due to qtype and qclass */
	offset += DNS_QTYPE_LEN + DNS_QCLASS_LEN;
	if (offset >= dns_msg->msg_size) {
		return -ENOMEM;
	}

	buf = dns_query + qname_size;
	if (dns_unpack_query_qtype(buf) != DNS_RR_TYPE_A &&
	    dns_unpack_query_qtype(buf) != DNS_RR_TYPE_AAAA) {
		return -EINVAL;
	}

	if (dns_unpack_query_qclass(buf) != DNS_CLASS_IN) {
		return -EINVAL;
	}

	dns_msg->answer_offset = dns_msg->query_offset + qname_size +
				 DNS_QTYPE_LEN + DNS_QCLASS_LEN;

	return 0;
}

int dns_copy_qname(uint8_t *buf, uint16_t *len, uint16_t size,
		   struct dns_msg_t *dns_msg, uint16_t pos)
{
	uint16_t msg_size = dns_msg->msg_size;
	uint8_t *msg = dns_msg->msg;
	uint16_t lb_size;
	int rc = -EINVAL;

	*len = 0U;

	while (1) {
		if (pos >= msg_size) {
			rc = -ENOMEM;
			break;
		}

		lb_size = msg[pos];

		/* pointer */
		if (lb_size > DNS_LABEL_MAX_SIZE) {
			uint8_t mask = DNS_LABEL_MAX_SIZE;

			if (pos + 1 >= msg_size) {
				rc = -ENOMEM;
				break;
			}

			/* See: RFC 1035, 4.1.4. Message compression */
			pos = ((msg[pos] & mask) << 8) + msg[pos + 1];

			continue;
		}

		/* validate that the label (i.e. size + elements),
		 * fits the current msg buffer
		 */
		if (DNS_LABEL_LEN_SIZE + lb_size > size - *len) {
			rc = -ENOMEM;
			break;
		}

		/* copy the lb_size value and label elements */
		memcpy(buf + *len, msg + pos, DNS_LABEL_LEN_SIZE + lb_size);
		/* update destination buffer len */
		*len += DNS_LABEL_LEN_SIZE + lb_size;
		/* update msg ptr position */
		pos += DNS_LABEL_LEN_SIZE + lb_size;

		/* The domain name terminates with the zero length octet
		 * for the null label of the root
		 */
		if (lb_size == 0U) {
			rc = 0;
			break;
		}
	}

	return rc;
}

int mdns_unpack_query_header(struct dns_msg_t *msg, uint16_t *src_id)
{
	uint8_t *dns_header;
	uint16_t size;
	int qdcount;

	dns_header = msg->msg;
	size = msg->msg_size;

	if (size < DNS_MSG_HEADER_SIZE) {
		return -ENOMEM;
	}

	if (dns_header_qr(dns_header) != DNS_QUERY) {
		return -EINVAL;
	}

	if (dns_header_opcode(dns_header) != DNS_QUERY) {
		return -EINVAL;
	}

	if (dns_header_opcode(dns_header) != 0) {
		return -EINVAL;
	}

	if (dns_header_rcode(dns_header) != 0) {
		return -EINVAL;
	}

	qdcount = dns_unpack_header_qdcount(dns_header);
	if (qdcount < 1) {
		return -EINVAL;
	}

	if (src_id) {
		*src_id = dns_unpack_header_id(dns_header);
	}

	msg->query_offset = DNS_MSG_HEADER_SIZE;

	return qdcount;
}

/* Returns the length of the unpacked name */
static int dns_unpack_name(const uint8_t *msg, int maxlen, const uint8_t *src,
			   struct net_buf *buf, const uint8_t **eol)
{
	int dest_size = net_buf_tailroom(buf);
	const uint8_t *end_of_label = NULL;
	const uint8_t *curr_src = src;
	int loop_check = 0, len = -1;
	int label_len;
	int val;

	if (curr_src < msg || curr_src >= (msg + maxlen)) {
		return -EMSGSIZE;
	}

	while ((val = *curr_src++)) {
		if (val & NS_CMPRSFLGS) {
			/* Follow pointer */
			int pos;

			if (curr_src >= (msg + maxlen)) {
				return -EMSGSIZE;
			}

			if (len < 0) {
				len = curr_src - src + 1;
			}

			end_of_label = curr_src + 1;

			/* Strip compress bits from length calculation */
			pos = ((val & 0x3f) << 8) | (*curr_src & 0xff);

			curr_src = msg + pos;
			if (curr_src >= (msg + maxlen)) {
				return -EMSGSIZE;
			}

			loop_check += 2;
			if (loop_check >= maxlen) {
				return -EMSGSIZE;
			}
		} else {
			/* Max label length is 64 bytes (because 2 bits are
			 * used for pointer)
			 */
			label_len = val;
			if (label_len > 63) {
				return -EMSGSIZE;
			}

			if (((buf->data + label_len + 1) >=
			     (buf->data + dest_size)) ||
			    ((curr_src + label_len) >= (msg + maxlen))) {
				return -EMSGSIZE;
			}

			loop_check += label_len + 1;

			net_buf_add_u8(buf, '.');
			net_buf_add_mem(buf, curr_src, label_len);

			curr_src += label_len;
		}
	}

	buf->data[buf->len] = '\0';

	if (eol) {
		if (!end_of_label) {
			end_of_label = curr_src;
		}

		*eol = end_of_label;
	}

	return buf->len;
}

int dns_unpack_query(struct dns_msg_t *dns_msg, struct net_buf *buf,
		     enum dns_rr_type *qtype, enum dns_class *qclass)
{
	const uint8_t *end_of_label;
	uint8_t *dns_query;
	int ret;
	int query_type, query_class;

	dns_query = dns_msg->msg + dns_msg->query_offset;

	ret = dns_unpack_name(dns_msg->msg, dns_msg->msg_size, dns_query,
			      buf, &end_of_label);
	if (ret < 0) {
		return ret;
	}

	query_type = dns_unpack_query_qtype(end_of_label);
	if (query_type != DNS_RR_TYPE_A && query_type != DNS_RR_TYPE_AAAA
		&& query_type != DNS_RR_TYPE_PTR
		&& query_type != DNS_RR_TYPE_SRV
		&& query_type != DNS_RR_TYPE_TXT) {
		return -EINVAL;
	}

	query_class = dns_unpack_query_qclass(end_of_label);
	if (query_class != DNS_CLASS_IN) {
		return -EINVAL;
	}

	if (qtype) {
		*qtype = query_type;
	}

	if (qclass) {
		*qclass = query_class;
	}

	dns_msg->query_offset = end_of_label - dns_msg->msg + 2 + 2;

	return ret;
}
