/*
 * 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 "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);

	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 */
				if (len > 4)
					len = 4;
				memcpy(&dev->ip_netmask, ext, len);
				break;
			case 3: /* default gateway */
				if (len > 4)
					len = 4;
				memcpy(&dev->ip_gateway, ext, len);
				break;
			case 6:	/* DNS server */
				if (len > 8)
					len = 8;
				memcpy(&dev->ip_nameserver, ext, 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 28: /* broadcast addr */
				if (len > 4)
					len = 4;
				memcpy(&dev->ip_broadcast, ext, 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)
		return 0;

	dev->caps |= CAP_BOOTP | CAP_DHCP;

	/*
	 * Get a random XID
	 */
	dev->bootp.xid = (__u32)lrand48();
	dev->open_time = time(NULL);

	return 0;
}
