/*
 * DNS support driver
 *
 * Copyright (c) 2008 Pieter Voorthuijsen <pieter.voorthuijsen@prodrive.nl>
 * Copyright (c) 2009 Robin Getz <rgetz@blackfin.uclinux.org>
 *
 * This is a simple DNS implementation for U-Boot. It will use the first IP
 * in the DNS response as NetServerIP. This can then be used for any other
 * network related activities.
 *
 * The packet handling is partly based on TADNS, original copyrights
 * follow below.
 *
 */

/*
 * Copyright (c) 2004-2005 Sergey Lyubka <valenok@gmail.com>
 *
 * "THE BEER-WARE LICENSE" (Revision 42):
 * Sergey Lyubka wrote this file.  As long as you retain this notice you
 * can do whatever you want with this stuff. If we meet some day, and you think
 * this stuff is worth it, you can buy me a beer in return.
 */
//#define DEBUG
#include <common.h>
#include <command.h>
#include <net.h>
#include <clock.h>
#include <environment.h>
#include <linux/err.h>

#define DNS_PORT 53

/* http://en.wikipedia.org/wiki/List_of_DNS_record_types */
enum dns_query_type {
	DNS_A_RECORD = 0x01,
	DNS_CNAME_RECORD = 0x05,
	DNS_MX_RECORD = 0x0f,
};

/*
 * DNS network packet
 */
struct header {
	uint16_t	tid;		/* Transaction ID */
	uint16_t	flags;		/* Flags */
	uint16_t	nqueries;	/* Questions */
	uint16_t	nanswers;	/* Answers */
	uint16_t	nauth;		/* Authority PRs */
	uint16_t	nother;		/* Other PRs */
	unsigned char	data[1];	/* Data, variable length */
};

#define STATE_INIT	0
#define STATE_DONE	1

static struct net_connection *dns_con;
static uint64_t dns_timer_start;
static int dns_state;
static IPaddr_t dns_ip;

static int dns_send(char *name)
{
	int ret;
	struct header *header;
	enum dns_query_type qtype = DNS_A_RECORD;
	unsigned char *packet = net_udp_get_payload(dns_con);
	unsigned char *p, *s, *fullname, *dotptr;
	const unsigned char *domain;

	/* Prepare DNS packet header */
	header           = (struct header *)packet;
	header->tid      = 1;
	header->flags    = htons(0x100);	/* standard query */
	header->nqueries = htons(1);		/* Just one query */
	header->nanswers = 0;
	header->nauth    = 0;
	header->nother   = 0;

	domain = getenv("domainname");

	if (!strchr(name, '.') && domain && *domain)
		fullname = asprintf(".%s.%s.", name, domain);
	else
		fullname = asprintf(".%s.", name);

	/* replace dots in fullname with chunk len */
	dotptr = fullname;
	do {
		int len;

		s = strchr(dotptr + 1, '.');

		len = s - dotptr - 1;

		*dotptr = len;
		dotptr = s;
	} while (*(dotptr + 1));
	*dotptr = 0;
//memory_display(fullname, 0, strlen(fullname), 1);
	strcpy(header->data, fullname);

	p = header->data + strlen(fullname);

	*p++ = 0;			/* Mark end of host name */
	*p++ = 0;			/* Some servers require double null */
	*p++ = (unsigned char)qtype;	/* Query Type */

	*p++ = 0;
	*p++ = 1;				/* Class: inet, 0x0001 */

	ret = net_udp_send(dns_con, p - packet);

	free(fullname);

	return ret;
}

static void dns_handler(void *ctx, char *packet, unsigned len)
{
	struct header *header;
	unsigned char *p, *e, *s;
	u16 type;
	int found, stop, dlen;
	short tmp;

	debug("%s\n", __func__);

	/* We sent 1 query. We want to see more that 1 answer. */
	header = (struct header *)net_eth_to_udp_payload(packet);;
	if (ntohs(header->nqueries) != 1)
		return;

	/* Received 0 answers */
	if (header->nanswers == 0) {
		dns_state = STATE_DONE;
		debug("DNS server returned no answers\n");
		return;
	}

	/* Skip host name */
	s = &header->data[0];
	e = packet + len;
	for (p = s; p < e && *p != '\0'; p++)
		continue;

	/* We sent query class 1, query type 1 */
	tmp = p[1] | (p[2] << 8);
	if (&p[5] > e || ntohs(tmp) != DNS_A_RECORD) {
		debug("DNS response was not A record\n");
		return;
	}

	/* Go to the first answer section */
	p += 5;

	/* Loop through the answers, we want A type answer */
	for (found = stop = 0; !stop && &p[12] < e; ) {

		/* Skip possible name in CNAME answer */
		if (*p != 0xc0) {
			while (*p && &p[12] < e)
				p++;
			p--;
		}
		debug("Name (Offset in header): %d\n", p[1]);

		tmp = p[2] | (p[3] << 8);
		type = ntohs(tmp);
		debug("type = %d\n", type);
		if (type == DNS_CNAME_RECORD) {
			/* CNAME answer. shift to the next section */
			debug("Found canonical name\n");
			tmp = p[10] | (p[11] << 8);
			dlen = ntohs(tmp);
			debug("dlen = %d\n", dlen);
			p += 12 + dlen;
		} else if (type == DNS_A_RECORD) {
			debug("Found A-record\n");
			found = stop = 1;
		} else {
			debug("Unknown type\n");
			stop = 1;
		}
	}

	if (found && &p[12] < e) {

		tmp = p[10] | (p[11] << 8);
		dlen = ntohs(tmp);
		p += 12;
		dns_ip = net_read_ip(p);
		dns_state = STATE_DONE;
	}
}

IPaddr_t resolv(char *host)
{
	IPaddr_t ip;

	if (!string_to_ip(host, &ip))
		return ip;

	dns_ip = 0;

	dns_state = STATE_INIT;

	ip = getenv_ip("nameserver");
	if (!ip)
		return 0;

	debug("resolving host %s via nameserver %s\n", host, getenv("nameserver"));

	dns_con = net_udp_new(ip, DNS_PORT, dns_handler, NULL);
	if (IS_ERR(dns_con))
		return PTR_ERR(dns_con);
	dns_timer_start = get_time_ns();
	dns_send(host);

	while (dns_state != STATE_DONE) {
		if (ctrlc()) {
			break;
		}
		net_poll();
		if (is_timeout(dns_timer_start, SECOND)) {
			dns_timer_start = get_time_ns();
			printf("T ");
			dns_send(host);
		}
	}

	net_unregister(dns_con);

	return dns_ip;
}

static int do_host(struct command *cmdtp, int argc, char *argv[])
{
	IPaddr_t ip;

	if (argc != 2)
		return COMMAND_ERROR_USAGE;

	ip = resolv(argv[1]);
	if (!ip)
		printf("unknown host %s\n", argv[1]);
	else {
		printf("%s is at ", argv[1]);
		print_IPaddr(ip);
		printf("\n");
	}

	return 0;
}

static const __maybe_unused char cmd_host_help[] =
"Usage: host <hostname>\n";

BAREBOX_CMD_START(host)
	.cmd		= do_host,
	.usage		= "resolve a hostname",
	BAREBOX_CMD_HELP(cmd_host_help)
BAREBOX_CMD_END

