/*
 * ipconfig/dhcp_proto.c
 *
 * DHCP RFC2132
 */
#include <sys/types.h>
#include <sys/uio.h>
#include <netinet/in.h>
#include <string.h>
#include <time.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,			/* boot path */
	28,			/* broadcast addr */
	40,			/* NIS domain name */
};

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;
		break;

	case DHCPACK:
		ret = bootp_parse(dev, hdr, exts, extlen);
		break;

	case DHCPNAK:
		ret = 2;
		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;

	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);

	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;

	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);

	return dhcp_send(dev, dhcp_request_iov, 5);
}

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