/*
 * ipconfig/dhcp_proto.c
 *
 * DHCP RFC 2131 and 2132
 */
#include <sys/types.h>
#include <linux/types.h>	/* for __u8 */
#include <sys/uio.h>
#include <netinet/in.h>
#include <stdio.h>
#include <string.h>
#include <time.h>

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

static __u8 dhcp_params[] = {
	1,			/* subnet mask */
	3,			/* default gateway */
	6,			/* DNS server */
	12,			/* host name */
	15,			/* domain name */
	17,			/* root path */
	26,			/* interface mtu */
	28,			/* broadcast addr */
	40,			/* NIS domain name (why?) */
};

static __u8 dhcp_discover_hdr[] = {
	99, 130, 83, 99,	/* bootp cookie */
	53, 1, DHCPDISCOVER,	/* dhcp message type */
	55, sizeof(dhcp_params),/* parameter list */
};

static __u8 dhcp_request_hdr[] = {
	99, 130, 83, 99,	/* boot cookie */
	53, 1, DHCPREQUEST,	/* dhcp message type */
#define SERVER_IP_OFF 9
	54, 4, 0, 0, 0, 0,	/* server IP */
#define REQ_IP_OFF 15
	50, 4, 0, 0, 0, 0,	/* requested IP address */
	55, sizeof(dhcp_params),/* parameter list */
};

static __u8 dhcp_end[] = {
	255,
};

static struct iovec dhcp_discover_iov[] = {
	/* [0] = ip + udp header */
	/* [1] = bootp header */
	[2] = { dhcp_discover_hdr, sizeof(dhcp_discover_hdr) },
	[3] = { dhcp_params, sizeof(dhcp_params) },
	[4] = { dhcp_end, sizeof(dhcp_end) }
};

static struct iovec dhcp_request_iov[] = {
	/* [0] = ip + udp header */
	/* [1] = bootp header */
	[2] = { dhcp_request_hdr, sizeof(dhcp_request_hdr) },
	[3] = { dhcp_params, sizeof(dhcp_params) },
	[4] = { dhcp_end, sizeof(dhcp_end) }
};

/*
 * Parse a DHCP response packet
 */
static int
dhcp_parse(struct netdev *dev, struct bootp_hdr *hdr, __u8 *exts, int extlen)
{
	__u8 type = 0;
	__u32 serverid = INADDR_NONE;
	int ret = 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++;

			ext += len;

			if (*opt == 53)
				type = opt[2];
			if (*opt == 54)
				memcpy(&serverid, opt + 2, 4);
		}
	}

	switch (type) {
	case DHCPOFFER:
		ret = bootp_parse(dev, hdr, exts, extlen);
		if (ret == 1 && serverid != INADDR_NONE)
			dev->serverid = serverid;
		DEBUG(("\n   dhcp offer\n"));
		break;

	case DHCPACK:
		ret = bootp_parse(dev, hdr, exts, extlen);
		DEBUG(("\n   dhcp ack\n"));
		break;

	case DHCPNAK:
		ret = 2;
		DEBUG(("\n   dhcp nak\n"));
		break;
	}
	return ret;
}

/*
 * Receive and parse a DHCP packet
 */
static int dhcp_recv(struct netdev *dev)
{
	struct bootp_hdr bootp;
	__u8 dhcp_options[1500];
	struct iovec iov[] = {
		/* [0] = ip + udp header */
		[1] = { &bootp, sizeof(struct bootp_hdr) },
		[2] = { dhcp_options, sizeof(dhcp_options) }
	};
	int ret;

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

	DEBUG(("\n   dhcp xid %08x ", dev->bootp.xid));

	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 dhcp_parse(dev, &bootp, dhcp_options, ret);
}

static int dhcp_send(struct netdev *dev, struct iovec *vec, int len)
{
	struct bootp_hdr bootp;

	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.giaddr = dev->bootp.gateway;
	bootp.secs   = htons(time(NULL) - dev->open_time);
	memcpy(bootp.chaddr, dev->hwaddr, 16);

	vec[1].iov_base = &bootp;
	vec[1].iov_len = sizeof(struct bootp_hdr);

	DEBUG(("xid %08x secs %d ",
	       bootp.xid, ntohs(bootp.secs)));

	return packet_send(dev, vec, len);
}

/*
 * Send a DHCP discover packet
 */
int dhcp_send_discover(struct netdev *dev)
{
	dev->ip_addr = INADDR_ANY;
	dev->ip_gateway = INADDR_ANY;

	DEBUG(("-> dhcp discover "));
	
	return dhcp_send(dev, dhcp_discover_iov, 5);
}

/*
 * Receive a DHCP offer packet
 */
int dhcp_recv_offer(struct netdev *dev)
{
	return dhcp_recv(dev);
}

/*
 * Send a DHCP request packet
 */
int dhcp_send_request(struct netdev *dev)
{
	memcpy(&dhcp_request_hdr[SERVER_IP_OFF], &dev->serverid, 4);
	memcpy(&dhcp_request_hdr[REQ_IP_OFF], &dev->ip_addr, 4);

	DEBUG(("-> dhcp request "));

	return dhcp_send(dev, dhcp_request_iov, 5);
}

/*
 * Receive a DHCP ack packet
 */
int dhcp_recv_ack(struct netdev *dev)
{
	return dhcp_recv(dev);
}
