/*
 * ipconfig/bootp_proto.c
 *
 * BOOTP packet protocol handling.
 */
#include <sys/types.h>
#include <sys/uio.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <unistd.h>
#include <netinet/in.h>

#include "ipconfig.h"
#include "netdev.h"
#include "bootp_packet.h"
#include "bootp_proto.h"
#include "packet.h"

static __u8 bootp_options[312] = {
	[0]   = 99, 130, 83, 99,/* RFC1048 magic cookie */
	[4]   = 1, 4,		/*   4-  9 subnet mask */
	[10]  = 3, 4,		/*  10- 15 default gateway */
	[16]  = 5, 8,		/*  16- 25 nameserver */
	[26]  = 12, 32,		/*  26- 59 host name */
	[60]  = 40, 32,		/*  60- 95 nis domain name */
	[96]  = 17, 40,		/*  96-137 boot path */
	[138] = 57, 2, 1, 150,	/* 138-141 extension buffer */
	[142] = 255,		/* end of list */
};

/*
 * Send a plain bootp request packet with options
 */
int bootp_send_request(struct netdev *dev)
{
	struct bootp_hdr bootp;
	struct iovec iov[] = {
		/* [0] = ip + udp headers */
		[1] = { &bootp, sizeof(bootp) },
		[2] = { bootp_options, 312 }
	};

	memset(&bootp, 0, sizeof(struct bootp_hdr));

	bootp.op     = BOOTP_REQUEST,
	bootp.htype  = dev->hwtype;
	bootp.hlen   = dev->hwlen;
	bootp.xid    = dev->bootp.xid;
	bootp.ciaddr = dev->ip_addr;
	bootp.secs   = htons(time(NULL) - dev->open_time);
	memcpy(bootp.chaddr, dev->hwaddr, 16);

	DEBUG(("-> bootp xid 0x%08x secs 0x%08x ",
	       bootp.xid, ntohs(bootp.secs)));

	return packet_send(dev, iov, 2);
}

/*
 * Parse a bootp reply packet
 */
int
bootp_parse(struct netdev *dev, struct bootp_hdr *hdr, __u8 *exts, int extlen)
{
	dev->bootp.gateway    = hdr->giaddr;
	dev->ip_addr          = hdr->yiaddr;
	dev->ip_server        = hdr->siaddr;
	dev->ip_netmask       = INADDR_ANY;
	dev->ip_broadcast     = INADDR_ANY;
	dev->ip_gateway       = hdr->giaddr;
	dev->ip_nameserver[0] = INADDR_ANY;
	dev->ip_nameserver[1] = INADDR_ANY;
	dev->hostname[0]      = '\0';
	dev->nisdomainname[0] = '\0';
	dev->bootpath[0]      = '\0';

	if (extlen >= 4 && exts[0] == 99 && exts[1] == 130 &&
	    exts[2] == 83 && exts[3] == 99) {
		__u8 *ext;

		for (ext = exts + 4; ext - exts < extlen; ) {
			__u8 len, opt = *ext++;
			if (opt == 0)
				continue;

			len = *ext++;

			switch (opt) {
			case 1:	/* subnet mask */
				memcpy(&dev->ip_netmask, ext, len > 4 ? 4 : len);
				break;
			case 3: /* default gateway */
				memcpy(&dev->ip_gateway, ext, len > 4 ? 4 : len);
				break;
			case 6:	/* DNS server */
				memcpy(&dev->ip_nameserver, ext, len > 8 ? 8 : len);
				break;
			case 12: /* host name */
				if (len > sizeof(dev->hostname) - 1)
					len = sizeof(dev->hostname) - 1;
				memcpy(&dev->hostname, ext, len);
				dev->hostname[len] = '\0';
				break;
			case 15: /* domain name */
				if (len > sizeof(dev->dnsdomainname) - 1)
					len = sizeof(dev->dnsdomainname) - 1;
				memcpy(&dev->dnsdomainname, ext, len);
				dev->dnsdomainname[len] = '\0';
				break;
			case 17: /* root path */
				if (len > sizeof(dev->bootpath) - 1)
					len = sizeof(dev->bootpath) - 1;
				memcpy(&dev->bootpath, ext, len);
				dev->bootpath[len] = '\0';
				break;
			case 26: /* interface MTU */
				if ( len == 2  )
					dev->mtu = (ext[0] << 8) + ext[1];
				break;
			case 28: /* broadcast addr */
				memcpy(&dev->ip_broadcast, ext, len > 4 ? 4 : len);
				break;
			case 40: /* NIS domain name */
				if (len > sizeof(dev->nisdomainname) - 1)
					len = sizeof(dev->nisdomainname) - 1;
				memcpy(&dev->nisdomainname, ext, len);
				dev->nisdomainname[len] = '\0';
				break;
			}				

			ext += len;
		}
	}

	/*
	 * Got packet.
	 */
	return 1;
}

/*
 * Receive a bootp reply and parse packet
 */
int bootp_recv_reply(struct netdev *dev)
{
	struct bootp_hdr bootp;
	__u8 bootp_options[312];
	struct iovec iov[] = {
		/* [0] = ip + udp headers */
		[1] = { &bootp, sizeof(struct bootp_hdr) },
		[2] = { bootp_options, 312 }
	};
	int ret;

	ret = packet_recv(iov, 3);
	if (ret <= 0)
		return ret;

	if (ret < sizeof(struct bootp_hdr) ||
	    bootp.op != BOOTP_REPLY ||		/* RFC951 7.5 */
	    bootp.xid != dev->bootp.xid ||
	    memcmp(bootp.chaddr, dev->hwaddr, 16))
		return 0;

	ret -= sizeof(struct bootp_hdr);

	return bootp_parse(dev, &bootp, bootp_options, ret);
}

/*
 * Initialise interface for bootp.
 */
int bootp_init_if(struct netdev *dev)
{
	short flags;

	/*
	 * Get the device flags
	 */
	if (netdev_getflags(dev, &flags))
		return -1;

	/*
	 * We can't do DHCP nor BOOTP if this device
	 * doesn't support broadcast.
	 */
	if (dev->mtu < 364 || (flags & IFF_BROADCAST) == 0) {
		dev->caps &= ~(CAP_BOOTP | CAP_DHCP);
		return 0;
	}
	
	/*
	 * Get a random XID
	 */
	dev->bootp.xid = (__u32)lrand48();
	dev->open_time = time(NULL);

	return 0;
}
