/*
 * 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 net_server_ip. 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.
 */

#include <command.h>
#include <env.h>
#include <log.h>
#include <net.h>
#include <asm/unaligned.h>

#include "dns.h"

char *net_dns_resolve;	/* The host to resolve  */
char *net_dns_env_var;	/* The envvar to store the answer in */

static int dns_our_port;

/*
 * make port a little random (1024-17407)
 * This keeps the math somewhat trivial to compute, and seems to work with
 * all supported protocols/clients/servers
 */
static unsigned int random_port(void)
{
	return 1024 + (get_timer(0) % 0x4000);
}

static void dns_send(void)
{
	struct header *header;
	int n, name_len;
	uchar *p, *pkt;
	const char *s;
	const char *name;
	enum dns_query_type qtype = DNS_A_RECORD;

	name = net_dns_resolve;
	pkt = (uchar *)(net_tx_packet + net_eth_hdr_size() + IP_UDP_HDR_SIZE);
	p = pkt;

	/* Prepare DNS packet header */
	header           = (struct header *)pkt;
	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;

	/* Encode DNS name */
	name_len = strlen(name);
	p = (uchar *)&header->data;	/* For encoding host name into packet */

	do {
		s = strchr(name, '.');
		if (!s)
			s = name + name_len;

		n = s - name;			/* Chunk length */
		*p++ = n;			/* Copy length  */
		memcpy(p, name, n);		/* Copy chunk   */
		p += n;

		if (*s == '.')
			n++;

		name += n;
		name_len -= n;
	} while (*s != '\0');

	*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 */

	n = p - pkt;				/* Total packet length */
	debug("Packet size %d\n", n);

	dns_our_port = random_port();

	net_send_udp_packet(net_server_ethaddr, net_dns_server,
			    DNS_SERVICE_PORT, dns_our_port, n);
	debug("DNS packet sent\n");
}

static void dns_timeout_handler(void)
{
	puts("Timeout\n");
	net_set_state(NETLOOP_FAIL);
}

static void dns_handler(uchar *pkt, unsigned dest, struct in_addr sip,
			unsigned src, unsigned len)
{
	struct header *header;
	const unsigned char *p, *e, *s;
	u16 type, i;
	int found, stop, dlen;
	char ip_str[22];
	struct in_addr ip_addr;

	debug("%s\n", __func__);
	if (dest != dns_our_port)
		return;

	for (i = 0; i < len; i += 4)
		debug("0x%p - 0x%.2x  0x%.2x  0x%.2x  0x%.2x\n",
		      pkt+i, pkt[i], pkt[i+1], pkt[i+2], pkt[i+3]);

	/* We sent one query. We want to have a single answer: */
	header = (struct header *)pkt;
	if (ntohs(header->nqueries) != 1)
		return;

	/* Received 0 answers */
	if (header->nanswers == 0) {
		puts("DNS: host not found\n");
		net_set_state(NETLOOP_SUCCESS);
		return;
	}

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

	/* We sent query class 1, query type 1 */
	if (&p[5] > e || get_unaligned_be16(p+1) != DNS_A_RECORD) {
		puts("DNS: response was not an A record\n");
		net_set_state(NETLOOP_SUCCESS);
		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]);

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

	if (found && &p[12] < e) {
		dlen = get_unaligned_be16(p+10);
		p += 12;
		memcpy(&ip_addr, p, 4);

		if (p + dlen <= e) {
			ip_to_string(ip_addr, ip_str);
			printf("%s\n", ip_str);
			if (net_dns_env_var)
				env_set(net_dns_env_var, ip_str);
		} else {
			puts("server responded with invalid IP number\n");
		}
	}

	net_set_state(NETLOOP_SUCCESS);
}

void dns_start(void)
{
	debug("%s\n", __func__);

	net_set_timeout_handler(DNS_TIMEOUT, dns_timeout_handler);
	net_set_udp_handler(dns_handler);

	/* Clear a previous MAC address, the server IP might have changed. */
	memset(net_server_ethaddr, 0, sizeof(net_server_ethaddr));

	dns_send();
}
