/* Low level mDNS encoding and decoding functions of the qname IE, header/question sections and resource records,
 * as described in these RFCs:
 * - RFC 1035 (Domain names - implementation and specification)
 * - RFC 3596 (DNS Extensions to Support IP Version 6) */

/* Copyright 2019 by sysmocom s.f.m.c. GmbH <info@sysmocom.de>
 *
 * All Rights Reserved
 *
 * 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 <string.h>
#include <ctype.h>
#include <errno.h>
#include <osmocom/core/msgb.h>
#include <osmocom/core/bitvec.h>
#include <osmocom/core/logging.h>
#include <osmocom/mslookup/mdns_rfc.h>

/*
 * Encode/decode IEs
 */

/*! Encode a domain string as qname (RFC 1035 4.1.2).
 * \param[in] domain  multiple labels separated by dots, e.g. "sip.voice.1234.msisdn".
 * \returns allocated buffer with length-value pairs for each label (e.g. 0x03 "sip" 0x05 "voice" ...), NULL on error.
 */
char *osmo_mdns_rfc_qname_encode(void *ctx, const char *domain)
{
	char *domain_dup;
	char *domain_iter;
	char buf[OSMO_MDNS_RFC_MAX_NAME_LEN + 2] = ""; /* len(qname) is len(domain) +1 */
	struct osmo_strbuf sb = { .buf = buf, .len = sizeof(buf) };
	char *label;

	if (strlen(domain) > OSMO_MDNS_RFC_MAX_NAME_LEN)
		return NULL;

	domain_iter = domain_dup = talloc_strdup(ctx, domain);
	while ((label = strsep(&domain_iter, "."))) {
		size_t len = strlen(label);

		/* Empty domain, dot at start, two dots in a row, or ending with a dot */
		if (!len)
			goto error;

		OSMO_STRBUF_PRINTF(sb, "%c%s", (char)len, label);
	}

	talloc_free(domain_dup);
	return talloc_strdup(ctx, buf);

error:
	talloc_free(domain_dup);
	return NULL;
}

/*! Decode a domain string from a qname (RFC 1035 4.1.2).
 * \param[in] qname  buffer with length-value pairs for each label (e.g. 0x03 "sip" 0x05 "voice" ...)
 * \param[in] qname_max_len  amount of bytes that can be read at most from the memory location that qname points to.
 * \returns allocated buffer with domain string, multiple labels separated by dots (e.g. "sip.voice.1234.msisdn"),
 *	    NULL on error.
 */
char *osmo_mdns_rfc_qname_decode(void *ctx, const char *qname, size_t qname_max_len)
{
	const char *next_label, *qname_end = qname + qname_max_len;
	char buf[OSMO_MDNS_RFC_MAX_NAME_LEN + 1];
	int i = 0;

	if (qname_max_len < 1)
		return NULL;

	while (*qname) {
		size_t len;

		if (i >= qname_max_len)
			return NULL;

		len = *qname;
		next_label = qname + len + 1;

		if (next_label >= qname_end || i + len > OSMO_MDNS_RFC_MAX_NAME_LEN)
			return NULL;

		if (i) {
			/* Two dots in a row is not allowed */
			if (buf[i - 1] == '.')
				return NULL;

			buf[i] = '.';
			i++;
		}

		memcpy(buf + i, qname + 1, len);
		i += len;
		qname = next_label;
	}
	buf[i] = '\0';

	return talloc_strdup(ctx, buf);
}

/*
 * Encode/decode message sections
 */

/*! Encode header section (RFC 1035 4.1.1).
 * \param[in] msgb  mesage buffer to which the encoded data will be appended.
 */
void osmo_mdns_rfc_header_encode(struct msgb *msg, const struct osmo_mdns_rfc_header *hdr)
{
	struct osmo_mdns_rfc_header *buf = (struct osmo_mdns_rfc_header *) msgb_put(msg, sizeof(*hdr));
	memcpy(buf, hdr, sizeof(*hdr));

	osmo_store16be(buf->id, &buf->id);
	osmo_store16be(buf->qdcount, &buf->qdcount);
	osmo_store16be(buf->ancount, &buf->ancount);
	osmo_store16be(buf->nscount, &buf->nscount);
	osmo_store16be(buf->arcount, &buf->arcount);
}

/*! Decode header section (RFC 1035 4.1.1). */
int osmo_mdns_rfc_header_decode(const uint8_t *data, size_t data_len, struct osmo_mdns_rfc_header *hdr)
{
	if (data_len != sizeof(*hdr))
		return -EINVAL;

	memcpy(hdr, data, data_len);

	hdr->id = osmo_load16be(&hdr->id);
	hdr->qdcount = osmo_load16be(&hdr->qdcount);
	hdr->ancount = osmo_load16be(&hdr->ancount);
	hdr->nscount = osmo_load16be(&hdr->nscount);
	hdr->arcount = osmo_load16be(&hdr->arcount);

	return 0;
}

/*! Encode question section (RFC 1035 4.1.2).
 * \param[in] msgb  mesage buffer to which the encoded data will be appended.
 */
int osmo_mdns_rfc_question_encode(void *ctx, struct msgb *msg, const struct osmo_mdns_rfc_question *qst)
{
	char *qname;
	size_t qname_len;
	uint8_t *qname_buf;

	/* qname */
	qname = osmo_mdns_rfc_qname_encode(ctx, qst->domain);
	if (!qname)
		return -EINVAL;
	qname_len = strlen(qname) + 1;
	qname_buf = msgb_put(msg, qname_len);
	memcpy(qname_buf, qname, qname_len);
	talloc_free(qname);

	/* qtype and qclass */
	msgb_put_u16(msg, qst->qtype);
	msgb_put_u16(msg, qst->qclass);

	return 0;
}

/*! Decode question section (RFC 1035 4.1.2). */
struct osmo_mdns_rfc_question *osmo_mdns_rfc_question_decode(void *ctx, const uint8_t *data, size_t data_len)
{
	struct osmo_mdns_rfc_question *ret;
	size_t qname_len = data_len - 4;

	if (data_len < 6)
		return NULL;

	/* qname */
	ret = talloc_zero(ctx, struct osmo_mdns_rfc_question);
	if (!ret)
		return NULL;
	ret->domain = osmo_mdns_rfc_qname_decode(ret, (const char *)data, qname_len);
	if (!ret->domain) {
		talloc_free(ret);
		return NULL;
	}

	/* qtype and qclass */
	ret->qtype = osmo_load16be(data + qname_len);
	ret->qclass = osmo_load16be(data + qname_len + 2);

	return ret;
}

/*
 * Encode/decode resource records
 */

/*! Encode one resource record (RFC 1035 4.1.3).
 * \param[in] msgb  mesage buffer to which the encoded data will be appended.
 */
int osmo_mdns_rfc_record_encode(void *ctx, struct msgb *msg, const struct osmo_mdns_rfc_record *rec)
{
	char *name;
	size_t name_len;
	uint8_t *buf;

	/* name */
	name = osmo_mdns_rfc_qname_encode(ctx, rec->domain);
	if (!name)
		return -EINVAL;
	name_len = strlen(name) + 1;
	buf = msgb_put(msg, name_len);
	memcpy(buf, name, name_len);
	talloc_free(name);

	/* type, class, ttl, rdlength */
	msgb_put_u16(msg, rec->type);
	msgb_put_u16(msg, rec->class);
	msgb_put_u32(msg, rec->ttl);
	msgb_put_u16(msg, rec->rdlength);

	/* rdata */
	buf = msgb_put(msg, rec->rdlength);
	memcpy(buf, rec->rdata, rec->rdlength);
	return 0;
}

/*! Decode one resource record (RFC 1035 4.1.3). */
struct osmo_mdns_rfc_record *osmo_mdns_rfc_record_decode(void *ctx, const uint8_t *data, size_t data_len,
						       size_t *record_len)
{
	struct osmo_mdns_rfc_record *ret = talloc_zero(ctx, struct osmo_mdns_rfc_record);
	size_t name_len;

	/* name */
	ret->domain = osmo_mdns_rfc_qname_decode(ret, (const char *)data, data_len - 10);
	if (!ret->domain)
		goto error;
	name_len = strlen(ret->domain) + 2;
	if (name_len + 10 > data_len)
		goto error;

	/* type, class, ttl, rdlength */
	ret->type = osmo_load16be(data + name_len);
	ret->class = osmo_load16be(data + name_len + 2);
	ret->ttl = osmo_load32be(data + name_len + 4);
	ret->rdlength = osmo_load16be(data + name_len + 8);
	if (name_len + 10 + ret->rdlength > data_len)
		goto error;

	/* rdata */
	ret->rdata = talloc_memdup(ret, data + name_len + 10, ret->rdlength);
	if (!ret->rdata)
		return NULL;

	*record_len = name_len + 10 + ret->rdlength;
	return ret;
error:
	talloc_free(ret);
	return NULL;
}

