/* 
 * dhcpcd - DHCP client daemon
 * Copyright 2006-2008 Roy Marples <roy@marples.name>
 * All rights reserved

 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 */

#include <sys/stat.h>
#include <sys/time.h>
#include <sys/types.h>
#include <arpa/inet.h>

#ifdef __linux__
# include <netinet/ether.h>
#endif

#include <errno.h>
#include <poll.h>
#include <signal.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <time.h>
#include <unistd.h>

#include "config.h"
#include "common.h"
#include "client.h"
#include "configure.h"
#include "dhcp.h"
#include "dhcpcd.h"
#include "net.h"
#include "logger.h"
#include "signals.h"

#define IPV4LL_LEASETIME 	2

/* Some platforms don't define INFTIM */
#ifndef INFTIM
# define INFTIM                 -1
#endif

#define STATE_INIT              0
#define STATE_DISCOVERING	1
#define STATE_REQUESTING        2
#define STATE_BOUND             3
#define STATE_RENEWING          4
#define STATE_REBINDING         5
#define STATE_REBOOT            6
#define STATE_RENEW_REQUESTED   7
#define STATE_INIT_IPV4LL	8
#define STATE_PROBING		9
#define STATE_ANNOUNCING	10

/* Constants taken from RFC 2131. */
#define T1			0.5
#define T2			0.875
#define DHCP_BASE		4
#define DHCP_MAX		64
#define DHCP_RAND_MIN		-1
#define DHCP_RAND_MAX		1
#define DHCP_ARP_FAIL		10

/* We should define a maximum for the NAK exponential backoff */ 
#define NAKOFF_MAX              60

#define SOCKET_CLOSED           0
#define SOCKET_OPEN             1

/* These are for IPV4LL, RFC 3927. */
#define PROBE_WAIT		 1
#define PROBE_NUM		 3
#define PROBE_MIN		 1
#define PROBE_MAX		 2
#define ANNOUNCE_WAIT		 2
/* BSD systems always do a grauitous ARP when assigning an address,
 * so we can do one less announce. */
#ifdef BSD
# define ANNOUNCE_NUM		 1
#else
# define ANNOUNCE_NUM		 2
#endif
#define ANNOUNCE_INTERVAL	 2
#define MAX_CONFLICTS		10
#define RATE_LIMIT_INTERVAL	60
#define DEFEND_INTERVAL		10


/* number of usecs in a second. */
#define USECS_SECOND		1000000
/* As we use timevals, we should use the usec part for
 * greater randomisation. */
#define DHCP_RAND_MIN_U		DHCP_RAND_MIN * USECS_SECOND
#define DHCP_RAND_MAX_U		DHCP_RAND_MAX * USECS_SECOND
#define PROBE_MIN_U		PROBE_MIN * USECS_SECOND
#define PROBE_MAX_U		PROBE_MAX * USECS_SECOND

#define timernorm(tvp)						\
	do {							\
		while ((tvp)->tv_usec >= 1000000) {		\
			(tvp)->tv_sec++;			\
			(tvp)->tv_usec -= 1000000;		\
		}						\
	} while (0 /* CONSTCOND */);

#define timerneg(tvp)	((tvp)->tv_sec < 0 || (tvp)->tv_usec < 0)

struct if_state {
	int options;
	struct interface *interface;
	struct dhcp_message *offer;
	struct dhcp_message *new;
	struct dhcp_message *old;
	struct dhcp_lease lease;
	struct timeval timeout;
	struct timeval stop;
	struct timeval exit;
	int state;
	int messages;
	time_t nakoff;
	uint32_t xid;
	int socket;
	int *pid_fd;
	int signal_fd;
	int carrier;
	int probes;
	int claims;
	int conflicts;
	time_t defend;
	struct in_addr fail;
};

#define LINK_UP 	1
#define LINK_UNKNOWN	0
#define LINK_DOWN 	-1

struct dhcp_op {
        uint8_t value;
        const char *name;
};

static const struct dhcp_op const dhcp_ops[] = {
	{ DHCP_DISCOVER, "DHCP_DISCOVER" },
	{ DHCP_OFFER,    "DHCP_OFFER" },
	{ DHCP_REQUEST,  "DHCP_REQUEST" },
	{ DHCP_DECLINE,  "DHCP_DECLINE" },
	{ DHCP_ACK,      "DHCP_ACK" },
	{ DHCP_NAK,      "DHCP_NAK" },
	{ DHCP_RELEASE,  "DHCP_RELEASE" },
	{ DHCP_INFORM,   "DHCP_INFORM" },
	{ 0, NULL }
};

static const char *
get_dhcp_op(uint8_t type)
{
	const struct dhcp_op *d;

	for (d = dhcp_ops; d->name; d++)
		if (d->value == type)
			return d->name;
	return NULL;
}

#ifdef THERE_IS_NO_FORK
#define daemonise(a,b) 0
#else
static int
daemonise(struct if_state *state, const struct options *options)
{
	pid_t pid;
	sigset_t full;
	sigset_t old;
	char buf = '\0';
	int sidpipe[2];

	if (state->options & DHCPCD_DAEMONISED ||
	    !(options->options & DHCPCD_DAEMONISE))
		return 0;

	sigfillset(&full);
	sigprocmask(SIG_SETMASK, &full, &old);

	/* Setup a signal pipe so parent knows when to exit. */
	if (pipe(sidpipe) == -1) {
		logger(LOG_ERR,"pipe: %s", strerror(errno));
		return -1;
	}

	logger(LOG_DEBUG, "forking to background");
	switch (pid = fork()) {
		case -1:
			logger(LOG_ERR, "fork: %s", strerror(errno));
			exit(EXIT_FAILURE);
			/* NOTREACHED */
		case 0:
			setsid();
			/* Notify parent it's safe to exit as we've detached. */
			close(sidpipe[0]);
			if (write(sidpipe[1], &buf, 1) != 1)
				logger(LOG_ERR, "write: %s", strerror(errno));
			close(sidpipe[1]);
			close_fds();
			break;
		default:
			/* Reset signals as we're the parent about to exit. */
			signal_reset();
			/* Wait for child to detach */
			close(sidpipe[1]);
			if (read(sidpipe[0], &buf, 1) != 1)
				logger(LOG_ERR, "read: %s", strerror(errno));
			close(sidpipe[0]);
			break;
	}

	/* Done with the fd now */
	if (pid != 0) {
		writepid(*state->pid_fd, pid);
		close(*state->pid_fd);
		*state->pid_fd = -1;
	}

	sigprocmask(SIG_SETMASK, &old, NULL);
	if (pid == 0) {
		state->options |= DHCPCD_DAEMONISED;
		timerclear(&state->exit);
		return 0;
	}
	state->options |= DHCPCD_PERSISTENT | DHCPCD_FORKED;
	return -1;
}
#endif

#define THIRTY_YEARS_IN_SECONDS    946707779
static size_t
get_duid(unsigned char *duid, const struct interface *iface)
{
	FILE *f;
	uint16_t type = 0;
	uint16_t hw = 0;
	uint32_t ul;
	time_t t;
	int x = 0;
	unsigned char *p = duid;
	size_t len = 0, l = 0;
	char *buffer = NULL, *line, *option;

	/* If we already have a DUID then use it as it's never supposed
	 * to change once we have one even if the interfaces do */
	if ((f = fopen(DUID, "r"))) {
		while ((get_line(&buffer, &len, f))) {
			line = buffer;
			while ((option = strsep(&line, " \t")))
				if (*option != '\0')
					break;
			if (!option || *option == '\0' || *option == '#')
				continue;
			l = hwaddr_aton(NULL, option);
			if (l && l <= DUID_LEN) {
				hwaddr_aton(duid, option);
				break;
			}
			l = 0;
		}
		fclose(f);
		free(buffer);
		if (l)
			return l;
	} else {
		if (errno != ENOENT)
			return 0;
	}

	/* No file? OK, lets make one based on our interface */
	if (!(f = fopen(DUID, "w")))
		return 0;
	type = htons(1); /* DUI-D-LLT */
	memcpy(p, &type, 2);
	p += 2;
	hw = htons(iface->family);
	memcpy(p, &hw, 2);
	p += 2;
	/* time returns seconds from jan 1 1970, but DUID-LLT is
	 * seconds from jan 1 2000 modulo 2^32 */
	t = time(NULL) - THIRTY_YEARS_IN_SECONDS;
	ul = htonl(t & 0xffffffff);
	memcpy(p, &ul, 4);
	p += 4;
	/* Finally, add the MAC address of the interface */
	memcpy(p, iface->hwaddr, iface->hwlen);
	p += iface->hwlen;
	len = p - duid;
	x = fprintf(f, "%s\n", hwaddr_ntoa(duid, len));
	fclose(f);
	/* Failed to write the duid? scrub it, we cannot use it */
	if (x < 1) {
		len = 0;
		unlink(DUID);
	}
	return len;
}

static struct dhcp_message*
ipv4ll_get_dhcp(uint32_t old_addr)
{
	uint32_t u32;
	struct dhcp_message *dhcp;
	uint8_t *p;

	dhcp = xzalloc(sizeof(*dhcp));
	/* Put some LL options in */
	p = dhcp->options;
	*p++ = DHO_SUBNETMASK;
	*p++ = sizeof(u32);
	u32 = htonl(LINKLOCAL_MASK);
	memcpy(p, &u32, sizeof(u32));
	p += sizeof(u32);
	*p++ = DHO_BROADCAST;
	*p++ = sizeof(u32);
	u32 = htonl(LINKLOCAL_BRDC);
	memcpy(p, &u32, sizeof(u32));
	p += sizeof(u32);
	*p++ = DHO_END;

	for (;;) {
		dhcp->yiaddr = htonl(LINKLOCAL_ADDR |
				     (((uint32_t)abs((int)arc4random())
				       % 0xFD00) + 0x0100));
		if (dhcp->yiaddr != old_addr &&
		    IN_LINKLOCAL(ntohl(dhcp->yiaddr)))
			break;
	}
	return dhcp;
}

static double
timeval_to_double(struct timeval *tv)
{
	return tv->tv_sec * 1.0 + tv->tv_usec * 1.0e-6;
}

static void
get_lease(struct dhcp_lease *lease, const struct dhcp_message *dhcp)
{
	time_t t;

	if (lease->frominfo)
		return;
	lease->addr.s_addr = dhcp->yiaddr;

	if (get_option_addr(&lease->net, dhcp, DHO_SUBNETMASK) == -1)
		lease->net.s_addr = get_netmask(dhcp->yiaddr);
	if (get_option_uint32(&lease->leasetime, dhcp, DHO_LEASETIME) == 0) {
		/* Ensure that we can use the lease */
		t = 0;
		if (t + (time_t)lease->leasetime < t) {
			logger(LOG_WARNING, "lease of %u would overflow, "
			       "treating as infinite", lease->leasetime);
			lease->leasetime = ~0U; /* Infinite lease */
		}
	} else
		lease->leasetime = DEFAULT_LEASETIME;
	if (get_option_uint32(&lease->renewaltime, dhcp, DHO_RENEWALTIME) != 0)
		lease->renewaltime = 0;
	if (get_option_uint32(&lease->rebindtime, dhcp, DHO_REBINDTIME) != 0)
		lease->rebindtime = 0;
}

static int
get_old_lease(struct if_state *state)
{
	struct interface *iface = state->interface;
	struct dhcp_lease *lease = &state->lease;
	struct dhcp_message *dhcp = NULL;
	struct timeval tv;
	unsigned int offset = 0;
	struct stat sb;

	if (stat(iface->leasefile, &sb) == -1) {
		if (errno != ENOENT)
			logger(LOG_ERR, "stat: %s", strerror(errno));
		goto eexit;
	}
	if (!IN_LINKLOCAL(ntohl(iface->addr.s_addr)))
		logger(LOG_INFO, "trying to use old lease in `%s'",
		       iface->leasefile);
	if ((dhcp = read_lease(iface)) == NULL) {
		logger(LOG_INFO, "read_lease: %s", strerror(errno));
		goto eexit;
	}
	lease->frominfo = 0;
	get_lease(&state->lease, dhcp);
	lease->frominfo = 1;
	lease->leasedfrom = sb.st_mtime;

	/* Vitaly important we remove the server information here */
	state->lease.server.s_addr = 0;
	dhcp->servername[0] = '\0';

	if (!IN_LINKLOCAL(ntohl(dhcp->yiaddr))) {
		if (!(state->options & DHCPCD_LASTLEASE))
			goto eexit;

		/* Ensure that we can still use the lease */
		if (gettimeofday(&tv, NULL) == -1) {
			logger(LOG_ERR, "gettimeofday: %s", strerror(errno));
			goto eexit;
		}

		offset = tv.tv_sec - lease->leasedfrom;
		if (lease->leasedfrom &&
		    tv.tv_sec - lease->leasedfrom > (time_t)lease->leasetime)
		{
			logger(LOG_ERR, "lease expired %u seconds ago",
			       offset + lease->leasetime);
			/* Persistent interfaces should still try and use the
			 * lease if we can't contact a DHCP server.
			 * We just set the timeout to 1 second. */
			if (state->options & DHCPCD_PERSISTENT)
				offset = lease->renewaltime - 1;
			else
				goto eexit;
		}
		lease->leasetime -= offset;
		lease->rebindtime -= offset;
		lease->renewaltime -= offset;
	}

	free(state->old);
	state->old = state->new;
	state->new = NULL;
	state->offer = dhcp;
	return 0;

eexit:
	lease->addr.s_addr = 0;
	free(dhcp);
	return -1;
}

static int
client_setup(struct if_state *state, const struct options *options)
{
	struct interface *iface = state->interface;
	struct dhcp_lease *lease = &state->lease;
	struct in_addr addr;
	struct timeval tv;
	size_t len = 0;
	unsigned char *duid = NULL;
	uint32_t ul;

	state->state = STATE_INIT;
	state->nakoff = 1;
	state->options = options->options;
	timerclear(&tv);

	if (options->request_address.s_addr == 0 &&
	    (options->options & DHCPCD_INFORM ||
	     options->options & DHCPCD_REQUEST ||
	     (options->options & DHCPCD_DAEMONISED &&
	      !(options->options & DHCPCD_BACKGROUND))))
	{
		if (get_old_lease(state) != 0)
			return -1;
		timerclear(&state->timeout);

		if (!(options->options & DHCPCD_DAEMONISED) &&
		    IN_LINKLOCAL(ntohl(lease->addr.s_addr)))
		{
			logger(LOG_ERR, "cannot request a link local address");
			return -1;
		}
	} else {
		lease->addr.s_addr = options->request_address.s_addr;
		lease->net.s_addr = options->request_netmask.s_addr;
	}

	/* If INFORMing, ensure the interface has the address */
	if (state->options & DHCPCD_INFORM &&
	    has_address(iface->name, &lease->addr, &lease->net) < 1)
	{
		addr.s_addr = lease->addr.s_addr | ~lease->net.s_addr;
		logger(LOG_DEBUG, "adding IP address %s/%d",
		       inet_ntoa(lease->addr), inet_ntocidr(lease->net));
		if (add_address(iface->name, &lease->addr,
				&lease->net, &addr) == -1)
		{
			logger(LOG_ERR, "add_address: %s", strerror(errno));
			return -1;
		}
		iface->addr.s_addr = lease->addr.s_addr;
		iface->net.s_addr = lease->net.s_addr;
	}

       /* If we haven't specified a ClientID and our hardware address 
	* length is greater than DHCP_CHADDR_LEN then we enforce a ClientID 
	* of the hardware address family and the hardware address. */ 
	if (!(state->options & DHCPCD_CLIENTID) && iface->hwlen > DHCP_CHADDR_LEN) 
		state->options |= DHCPCD_CLIENTID; 
 
	if (*options->clientid) {
		iface->clientid = xmalloc(options->clientid[0] + 1);
		memcpy(iface->clientid,
		       options->clientid, options->clientid[0] + 1);
	} else if (state->options & DHCPCD_CLIENTID) {
		if (state->options & DHCPCD_DUID) {
			duid = xmalloc(DUID_LEN);
			if ((len = get_duid(duid, iface)) == 0)
				logger(LOG_ERR, "get_duid: %s",
				       strerror(errno));
		}

		if (len > 0) {
			logger(LOG_DEBUG, "DUID = %s",
			       hwaddr_ntoa(duid, len));

			iface->clientid = xmalloc(len + 6);
			iface->clientid[0] = len + 5;
			iface->clientid[1] = 255; /* RFC 4361 */

			/* IAID is 4 bytes, so if the iface name is 4 bytes
			 * or less, use it */
			ul = strlen(iface->name);
			if (ul < 5) {
				memcpy(iface->clientid + 2, iface->name, ul);
				if (ul < 4)
					memset(iface->clientid + 2 + ul,
					       0, 4 - ul);
			} else {
				/* Name isn't 4 bytes, so use the index */
				ul = htonl(if_nametoindex(iface->name));
				memcpy(iface->clientid + 2, &ul, 4);
			}

			memcpy(iface->clientid + 6, duid, len);
			free(duid);
		}
		if (len == 0) {
			len = iface->hwlen + 1;
			iface->clientid = xmalloc(len + 1);
			iface->clientid[0] = len;
			iface->clientid[1] = iface->family;
			memcpy(iface->clientid + 2, iface->hwaddr, iface->hwlen);
		}
	}

	if (state->options & DHCPCD_LINK) {
		open_link_socket(iface);
		switch (carrier_status(iface->name)) {
		case 0:
			state->carrier = LINK_DOWN;
			break;
		case 1:
			state->carrier = LINK_UP;
			break;
		default:
			state->carrier = LINK_UNKNOWN;
		}
	}

	if (options->timeout > 0 &&
	    !(state->options & DHCPCD_DAEMONISED))
	{
		if (state->options & DHCPCD_IPV4LL) {
			state->stop.tv_sec = options->timeout;
			if (!(state->options & DHCPCD_BACKGROUND))
				state->exit.tv_sec = state->stop.tv_sec + 10;
		} else if (!(state->options & DHCPCD_BACKGROUND))
			state->exit.tv_sec = options->timeout;
	}
	return 0;
}

static int 
do_socket(struct if_state *state, int mode)
{
	if (state->interface->raw_fd != -1) {
		close(state->interface->raw_fd);
		state->interface->raw_fd = -1;
	}
	if (mode == SOCKET_CLOSED) {
		if (state->interface->udp_fd != -1) {
			close(state->interface->udp_fd);
			state->interface->udp_fd = -1;
		}
		if (state->interface->arp_fd != -1) {
			close(state->interface->arp_fd);
			state->interface->arp_fd = -1;
		}
	}

	/* Always have the UDP socket open to avoid the kernel sending
	 * ICMP unreachable messages. */
	/* For systems without SO_BINDTODEVICE, (ie BSD ones) we may get an
	 * error or EADDRINUSE when binding to INADDR_ANY as another dhcpcd
	 * instance could be running.
	 * Oddly enough, we don't care about this as the socket is there
	 * just to please the kernel - we don't care for reading from it. */
	if (mode == SOCKET_OPEN &&
	    state->interface->udp_fd == -1 &&
	    open_udp_socket(state->interface) == -1 &&
	    (errno != EADDRINUSE || state->interface->addr.s_addr != 0))
		logger(LOG_ERR, "open_udp_socket: %s", strerror(errno));

	if (mode == SOCKET_OPEN) 
		if (open_socket(state->interface, ETHERTYPE_IP) == -1) {
			logger(LOG_ERR, "open_socket: %s", strerror(errno));
			return -1;
		}
	state->socket = mode;
	return 0;
}

static ssize_t
send_message(struct if_state *state, int type, const struct options *options)
{
	struct dhcp_message *dhcp;
	uint8_t *udp;
	ssize_t len, r;
	struct in_addr from, to;
	in_addr_t a = 0;

	if (state->carrier == LINK_DOWN)
		return 0;
	if (type == DHCP_RELEASE)
		logger(LOG_DEBUG, "sending %s with xid 0x%x",
		       get_dhcp_op(type), state->xid);
	else
		logger(LOG_DEBUG,
		       "sending %s with xid 0x%x, next in %0.2f seconds",
		       get_dhcp_op(type), state->xid,
		       timeval_to_double(&state->timeout));
	state->messages++;
	if (state->messages < 0)
		state->messages = INT_MAX;
	/* If we couldn't open a UDP port for our IP address
	 * then we cannot renew.
	 * This could happen if our IP was pulled out from underneath us. */
	if (state->interface->udp_fd == -1) {
		a = state->interface->addr.s_addr;
		state->interface->addr.s_addr = 0;
	}
	len = make_message(&dhcp, state->interface, &state->lease, state->xid,
			   type, options);
	if (state->interface->udp_fd == -1)
		state->interface->addr.s_addr = a;
	from.s_addr = dhcp->ciaddr;
	if (from.s_addr)
		to.s_addr = state->lease.server.s_addr;
	else
		to.s_addr = 0;
	if (to.s_addr && to.s_addr != INADDR_BROADCAST) {
		r = send_packet(state->interface, to, (uint8_t *)dhcp, len);
		if (r == -1)
			logger(LOG_ERR, "send_packet: %s", strerror(errno));
	} else {
		len = make_udp_packet(&udp, (uint8_t *)dhcp, len, from, to);
		r = send_raw_packet(state->interface, ETHERTYPE_IP, udp, len);
		free(udp);
		if (r == -1)
			logger(LOG_ERR, "send_raw_packet: %s", strerror(errno));
	}
	free(dhcp);
	/* Failed to send the packet? Return to the init state */
	if (r == -1) {
		state->state = STATE_INIT;
		timerclear(&state->timeout);
		/* We need to set a timeout so we fall through gracefully */
		state->stop.tv_sec = 1;
		state->stop.tv_usec = 0;
		do_socket(state, SOCKET_CLOSED);
	}
	return r;
}

static void
drop_config(struct if_state *state, const char *reason,
	    const struct options *options)
{
	if (state->new || strcmp(reason, "FAIL") == 0) {
		configure(state->interface, reason, NULL, state->new,
			  &state->lease, options, 0);
		free(state->old);
		state->old = NULL;
		free(state->new);
		state->new = NULL;
	}
	state->lease.addr.s_addr = 0;
}

static void
reduce_timers(struct if_state *state, const struct timeval *tv)
{
	if (timerisset(&state->exit)) {
		timersub(&state->exit, tv, &state->exit);
		if (!timerisset(&state->exit))
			state->exit.tv_sec = -1;
	}
	if (timerisset(&state->stop)) {
		timersub(&state->stop, tv, &state->stop);
		if (!timerisset(&state->stop))
			state->stop.tv_sec = -1;
	}
	if (timerisset(&state->timeout)) {
		timersub(&state->timeout, tv, &state->timeout);
		if (!timerisset(&state->timeout))
			state->timeout.tv_sec = -1;
	}
}

static struct timeval *
get_lowest_timer(struct if_state *state)
{
	struct timeval *ref = NULL;
	
	if (timerisset(&state->exit))
		ref = &state->exit;
	if (timerisset(&state->stop)) {
		if (!ref || timercmp(&state->stop, ref, <))
			ref = &state->stop;
	}
	if (timerisset(&state->timeout)) {
		if (!ref || timercmp(&state->timeout, ref, <))
			ref = &state->timeout;
	}
	return ref;
}

static int
wait_for_fd(struct if_state *state, int *fd)
{
	struct pollfd fds[4]; /* signal, link, raw, arp */
	struct interface *iface = state->interface;
	int i, r, nfds = 0, msecs = -1;
	struct timeval start, stop, diff, *ref;
	static int lastinf = 0;

	/* Ensure that we haven't already timed out */
	ref = get_lowest_timer(state);
	if (ref && timerneg(ref))
		return 0;

	/* We always listen to signals */
	fds[nfds].fd = state->signal_fd;
	fds[nfds].events = POLLIN;
	nfds++;
	/* And links */
	if (iface->link_fd != -1) {
		fds[nfds].fd = iface->link_fd;
		fds[nfds].events = POLLIN;
		nfds++;
	}

	if (state->lease.leasetime == ~0U &&
	    state->state == STATE_BOUND)
	{
		if (!lastinf) {
			logger(LOG_DEBUG, "waiting for infinity");
			lastinf = 1;
		}
		ref = NULL;
	} else if (state->carrier == LINK_DOWN && !ref) {
		if (!lastinf) {
			logger(LOG_DEBUG, "waiting for carrier");
			lastinf = 1;
		}
		if (timerisset(&state->exit))
			ref = &state->exit;
		else
			ref = NULL;
	} else {
		if (iface->raw_fd != -1) {
			fds[nfds].fd = iface->raw_fd;
			fds[nfds].events = POLLIN;
			nfds++;
		}
		if (iface->arp_fd != -1) {
			fds[nfds].fd = iface->arp_fd;
			fds[nfds].events = POLLIN;
			nfds++;
		}
	}

	/* Wait and then reduce the timers.
	 * If we reduce a timer to zero, set it negative to indicate timeout.
	 * We cannot reliably use select as there is no guarantee we will
	 * actually wait the whole time if greater than 31 days according
	 * to POSIX. So we loop on poll if needed as it's limitation of
	 * INT_MAX milliseconds is known. */
	for (;;) {
		get_monotonic(&start);
		if (ref) {
			lastinf = 0;
			if (ref->tv_sec > INT_MAX / 1000 ||
			    (ref->tv_sec == INT_MAX / 1000 &&
			     (ref->tv_usec + 999) / 1000 > INT_MAX % 1000))
				msecs = INT_MAX;
			else
				msecs = ref->tv_sec * 1000 +
					(ref->tv_usec + 999) / 1000;
		} else
			msecs = -1;
		r = poll(fds, nfds, msecs);
		get_monotonic(&stop);
		timersub(&stop, &start, &diff);
		reduce_timers(state, &diff);
		if (r == -1) {
			if (errno != EINTR)
				logger(LOG_ERR, "poll: %s", strerror(errno));
			return -1;
		}
		if (r)
			break;
		/* We should not have an infinite timeout if we get here */
		if (timerneg(ref))
			return 0;
	}

	/* We configured our array in the order we should deal with them */
	for (i = 0; i < nfds; i++) {
		if (fds[i].revents & POLLERR) {
			syslog(LOG_ERR, "poll: POLLERR on fd %d", fds[i].fd);
			errno = EBADF;
			return -1;
		}
		if (fds[i].revents & POLLNVAL) {
			syslog(LOG_ERR, "poll: POLLNVAL on fd %d", fds[i].fd);
			errno = EINVAL;
			return -1;
		}
		if (fds[i].revents & (POLLIN | POLLHUP)) {
			*fd = fds[i].fd;
			return r;
		}
	}
	/* We should never get here. */
	return 0;
}

static int
handle_signal(int sig, struct if_state *state,  const struct options *options)
{
	struct dhcp_lease *lease = &state->lease;

	switch (sig) {
	case SIGINT:
		logger(LOG_INFO, "received SIGINT, stopping");
		if (!(state->options & DHCPCD_PERSISTENT))
			drop_config(state, "STOP", options);
		return -1;
	case SIGTERM:
		logger(LOG_INFO, "received SIGTERM, stopping");
		if (!(state->options & DHCPCD_PERSISTENT))
			drop_config(state, "STOP", options);
		return -1;
	case SIGALRM:
		logger(LOG_INFO, "received SIGALRM, renewing lease");
		do_socket(state, SOCKET_CLOSED);
		state->state = STATE_RENEW_REQUESTED;
		timerclear(&state->timeout);
		timerclear(&state->stop);
		return 1;
	case SIGHUP:
		logger(LOG_INFO, "received SIGHUP, releasing lease");
		if (lease->addr.s_addr &&
		    !IN_LINKLOCAL(ntohl(lease->addr.s_addr)))
		{
			do_socket(state, SOCKET_OPEN);
			state->xid = arc4random();
			send_message(state, DHCP_RELEASE, options);
			do_socket(state, SOCKET_CLOSED);
		}
		drop_config(state, "RELEASE", options);
		return -1;
	default:
		logger (LOG_ERR,
			"received signal %d, but don't know what to do with it",
			sig);
	}

	return 0;
}

static int bind_dhcp(struct if_state *state, const struct options *options)
{
	struct interface *iface = state->interface;
	struct dhcp_lease *lease = &state->lease;
	const char *reason = NULL;
	struct timeval start, stop, diff;
	int retval;

	free(state->old);
	state->old = state->new;
	state->new = state->offer;
	state->offer = NULL;
	state->messages = 0;
	state->conflicts = 0;
	state->defend = 0;
	timerclear(&state->exit);
	if (clock_monotonic)
		get_monotonic(&lease->boundtime);

	if (options->options & DHCPCD_INFORM) {
		if (options->request_address.s_addr != 0)
			lease->addr.s_addr = options->request_address.s_addr;
		else
			lease->addr.s_addr = iface->addr.s_addr;
		logger(LOG_INFO, "received approval for %s",
		       inet_ntoa(lease->addr));
		state->state = STATE_BOUND;
		state->lease.leasetime = ~0U;
		timerclear(&state->stop);
		reason = "INFORM";
	} else if (IN_LINKLOCAL(htonl(state->new->yiaddr))) {
		get_lease(lease, state->new);
		logger(LOG_INFO, "using IPv4LL address %s",
		       inet_ntoa(lease->addr));
		state->state = STATE_INIT;
		timerclear(&state->timeout);
		reason = "IPV4LL";
	} else {
		if (gettimeofday(&start, NULL) == 0)
			lease->leasedfrom = start.tv_sec;

		get_lease(lease, state->new);
		if (lease->frominfo)
			reason = "TIMEOUT";

		if (lease->leasetime == ~0U) {
			lease->renewaltime = lease->rebindtime = lease->leasetime;
			logger(LOG_INFO, "leased %s for infinity",
			       inet_ntoa(lease->addr));
			state->state = STATE_BOUND;
			timerclear(&state->stop);
		} else {
			if (lease->rebindtime == 0)
				lease->rebindtime = lease->leasetime * T2;
			else if (lease->rebindtime >= lease->leasetime) {
				lease->rebindtime = lease->leasetime * T2;
				logger(LOG_ERR,
				       "rebind time greater than lease "
				       "time, forcing to %u seconds",
				       lease->rebindtime);
			}
			if (lease->renewaltime == 0)
				lease->renewaltime = lease->leasetime * T1;
			else if (lease->renewaltime > lease->rebindtime) {
				lease->renewaltime = lease->leasetime * T1;
				logger(LOG_ERR,
				       "renewal time greater than rebind time, "
				       "forcing to %u seconds",
				       lease->renewaltime);
			}
			logger(LOG_INFO,
			       "leased %s for %u seconds",
			       inet_ntoa(lease->addr), lease->leasetime);
			state->stop.tv_sec = lease->renewaltime;
			state->stop.tv_usec = 0;
		}
		state->state = STATE_BOUND;
	}

	state->xid = 0;
	timerclear(&state->timeout);
	if (!reason) {
		if (state->old) {
			if (state->old->yiaddr == state->new->yiaddr &&
			    lease->server.s_addr)
				reason = "RENEW";
			else
				reason = "REBIND";
		} else
			reason = "BOUND";
	}
	/* If we have a monotonic clock we can safely substract the
	 * script execution time from our timers.
	 * Otherwise we can't as the script may update the real time. */
	if (clock_monotonic)
		get_monotonic(&start);
	retval = configure(iface, reason, state->new, state->old,
			   &state->lease, options, 1);
	if (clock_monotonic) {
		get_monotonic(&stop);
		timersub(&stop, &start, &diff);
		reduce_timers(state, &diff);
	}
	if (retval != 0)
		return -1;
	return daemonise(state, options);
}

static int
handle_timeout_fail(struct if_state *state, const struct options *options)
{
	struct dhcp_lease *lease = &state->lease;
	struct interface *iface = state->interface;
	int gotlease = -1, r;
	const char *reason = NULL;

	timerclear(&state->stop);
	timerclear(&state->exit);
	if (state->state != STATE_DISCOVERING)
		state->messages = 0;

	switch (state->state) {
	case STATE_INIT:	/* FALLTHROUGH */
	case STATE_DISCOVERING: /* FALLTHROUGH */
	case STATE_REQUESTING:
		if (IN_LINKLOCAL(ntohl(iface->addr.s_addr))) {
			if (!(state->options & DHCPCD_DAEMONISED))
				logger(LOG_ERR, "timed out");
		} else {
			if (iface->addr.s_addr != 0 &&
			    !(state->options & DHCPCD_INFORM))
				logger(LOG_ERR, "lost lease");
			else if (state->carrier != LINK_DOWN || 
				!(state->options & DHCPCD_DAEMONISED)) 
				logger(LOG_ERR, "timed out");
		}
		do_socket(state, SOCKET_CLOSED);
		if (state->options & DHCPCD_INFORM ||
		    state->options & DHCPCD_TEST)
			return -1;

		if (state->carrier != LINK_DOWN &&
		    (state->options & DHCPCD_IPV4LL ||
		     state->options & DHCPCD_LASTLEASE))
			gotlease = get_old_lease(state);

		if (state->carrier != LINK_DOWN &&
		    state->options & DHCPCD_IPV4LL &&
		    gotlease != 0)
		{
			logger(LOG_INFO, "probing for an IPV4LL address");
			free(state->offer);
			lease->frominfo = 0;
			state->offer = ipv4ll_get_dhcp(0);
			gotlease = 0;
		}

		if (gotlease == 0 &&
		    state->offer->yiaddr != iface->addr.s_addr &&
		    state->options & DHCPCD_ARP)
		{
			state->state = STATE_PROBING;
			state->claims = 0;
			state->probes = 0;
			if (iface->addr.s_addr)
				state->conflicts = 0;
			return 1;
		}

		if (gotlease == 0) {
			r = bind_dhcp(state, options);
			logger(LOG_DEBUG, "renew in %ld seconds",
				(long int)state->stop.tv_sec);
			return r;
		}
		if (iface->addr.s_addr)
			reason = "EXPIRE";
		else
			reason = "FAIL";
		drop_config(state, reason, options);
		if (!(state->options & DHCPCD_DAEMONISED) &&
		    (state->options & DHCPCD_DAEMONISE))
			return -1;
		state->state = STATE_RENEW_REQUESTED;
		return 1;
	case STATE_BOUND:
		logger(LOG_INFO, "renewing lease of %s",inet_ntoa(lease->addr));
		if (state->carrier != LINK_DOWN)
			do_socket(state, SOCKET_OPEN);
		state->xid = arc4random();
		state->state = STATE_RENEWING;
		state->stop.tv_sec = lease->rebindtime - lease->renewaltime;
		break;
	case STATE_RENEWING:
		logger(LOG_ERR, "failed to renew, attempting to rebind");
		state->state = STATE_REBINDING;
		if (lease->server.s_addr == 0)
			state->stop.tv_sec = options->timeout;
		else
			state->stop.tv_sec = lease->rebindtime - \
					     lease->renewaltime;
		lease->server.s_addr = 0;
		break;
	case STATE_REBINDING:
		logger(LOG_ERR, "failed to rebind");
		reason = "EXPIRE";
		drop_config(state, reason, options);
		state->state = STATE_INIT;
		break;
	case STATE_PROBING:    /* FALLTHROUGH */
	case STATE_ANNOUNCING:
		/* We should have lost carrier here and exit timer went */
		logger(LOG_ERR, "timed out");
		return -1;
	default:
		logger(LOG_DEBUG, "handle_timeout_failed: invalid state %d",
		       state->state);
	}

	/* This effectively falls through into the handle_timeout funtion */
	return 1;
}

static int
handle_timeout(struct if_state *state, const struct options *options)
{
	struct dhcp_lease *lease = &state->lease;
	struct interface *iface = state->interface;
	int i = 0;
	struct in_addr addr;
	struct timeval tv;

	timerclear(&state->timeout);
	if (timerneg(&state->exit))
		return handle_timeout_fail(state, options);

	if (state->state == STATE_RENEW_REQUESTED &&
	    IN_LINKLOCAL(ntohl(lease->addr.s_addr)))
	{
		state->state = STATE_PROBING;
		free(state->offer);
		state->offer = read_lease(state->interface);
		state->probes = 0;
		state->claims = 0;
	}
	switch (state->state) {
	case STATE_INIT_IPV4LL:
		state->state = STATE_PROBING;
		free(state->offer);
		state->offer = ipv4ll_get_dhcp(0);
		state->probes = 0;
		state->claims = 0;
		/* FALLTHROUGH */
	case STATE_PROBING:
		if (iface->arp_fd == -1)
			open_socket(iface, ETHERTYPE_ARP);
		if (state->probes < PROBE_NUM) {
			if (state->probes == 0) {
				addr.s_addr = state->offer->yiaddr;
				logger(LOG_INFO, "checking %s is available"
				       " on attached networks",
				       inet_ntoa(addr));
			}
			state->probes++;
			if (state->probes < PROBE_NUM) {
				state->timeout.tv_sec = PROBE_MIN;
				state->timeout.tv_usec = arc4random() %
					(PROBE_MAX_U - PROBE_MIN_U);
				timernorm(&state->timeout);
			} else {
				state->timeout.tv_sec = ANNOUNCE_WAIT;
				state->timeout.tv_usec = 0;
			}
			logger(LOG_DEBUG,
			       "sending ARP probe (%d of %d), next in %0.2f seconds",
			       state->probes, PROBE_NUM,
			       timeval_to_double(&state->timeout));
			if (send_arp(iface, ARPOP_REQUEST, 0,
				     state->offer->yiaddr) == -1)
			{
				logger(LOG_ERR, "send_arp: %s", strerror(errno));
				return -1;
			}
			return 0;
		} else {
			/* We've waited for ANNOUNCE_WAIT after the final probe
			 * so the address is now ours */
			i = bind_dhcp(state, options);
			state->state = STATE_ANNOUNCING;
			state->timeout.tv_sec = ANNOUNCE_INTERVAL;
			state->timeout.tv_usec = 0;
			return i;
		}
		break;
	case STATE_ANNOUNCING:
		if (iface->arp_fd == -1)
			open_socket(iface, ETHERTYPE_ARP);
		if (state->claims < ANNOUNCE_NUM) {
			state->claims++;
			if (state->claims < ANNOUNCE_NUM) {
				state->timeout.tv_sec = ANNOUNCE_INTERVAL;
				state->timeout.tv_usec = 0;
				logger(LOG_DEBUG,
				       "sending ARP announce (%d of %d),"
				       " next in %0.2f seconds",
				       state->claims, ANNOUNCE_NUM,
				       timeval_to_double(&state->timeout));
			} else
				logger(LOG_DEBUG,
				       "sending ARP announce (%d of %d)",
				       state->claims, ANNOUNCE_NUM);
			i = send_arp(iface, ARPOP_REQUEST,
				     state->new->yiaddr, state->new->yiaddr);
			if (i == -1) {
				logger(LOG_ERR, "send_arp: %s", strerror(errno));
				return -1;
			}
		}
		if (state->claims < ANNOUNCE_NUM)
			return 0;
		if (IN_LINKLOCAL(htonl(state->new->yiaddr))) {
			/* We should pretend to be at the end
			 * of the DHCP negotation cycle */
			state->state = STATE_INIT;
			state->messages = DHCP_MAX / DHCP_BASE;
			state->probes = 0;
			state->claims = 0;
			timerclear(&state->stop);
			goto dhcp_timeout;
		} else {
			state->state = STATE_BOUND;
			close(iface->arp_fd);
			iface->arp_fd = -1;
			if (lease->leasetime != ~0U) {
				state->stop.tv_sec = lease->renewaltime;
				state->stop.tv_usec = 0;
				if (clock_monotonic) {
					get_monotonic(&tv);
					timersub(&tv, &lease->boundtime, &tv);
					timersub(&state->stop, &tv, &state->stop);
				} else {
					state->stop.tv_sec -=
						(ANNOUNCE_INTERVAL * ANNOUNCE_NUM);
				}
				logger(LOG_DEBUG, "renew in %ld seconds",
				       (long int)state->stop.tv_sec);
			}
		}
		return 0;
	}

	if (timerneg(&state->stop))
		return handle_timeout_fail(state, options);

	switch (state->state) {
	case STATE_BOUND: /* FALLTHROUGH */
	case STATE_RENEW_REQUESTED:
		timerclear(&state->stop);
		/* FALLTHROUGH */
	case STATE_INIT:
		if (state->carrier == LINK_DOWN)
			return 0;
		do_socket(state, SOCKET_OPEN);
		state->xid = arc4random();
		iface->start_uptime = uptime();
		break;
	}

	switch(state->state) {
	case STATE_RENEW_REQUESTED:
		/* If a renew was requested (ie, didn't timeout) we actually
		 * enter the REBIND state so that we broadcast to all servers.
		 * We need to do this for when we change networks. */
		lease->server.s_addr = 0;
		state->messages = 0;
		if (lease->addr.s_addr && !(state->options & DHCPCD_INFORM)) {
			logger(LOG_INFO, "rebinding lease of %s",
			       inet_ntoa(lease->addr));
			state->state = STATE_REBINDING;
			state->stop.tv_sec = options->timeout;
			state->stop.tv_usec = 0;
			break;
		}
		/* FALLTHROUGH */
	case STATE_INIT:
		if (lease->addr.s_addr == 0 ||
		    IN_LINKLOCAL(ntohl(iface->addr.s_addr)))
		{
			logger(LOG_INFO, "broadcasting for a lease");
			state->state = STATE_DISCOVERING;
		} else if (state->options & DHCPCD_INFORM) {
			logger(LOG_INFO, "broadcasting inform for %s",
			       inet_ntoa(lease->addr));
			state->state = STATE_REQUESTING;
		} else {
			logger(LOG_INFO, "broadcasting for a lease of %s",
			       inet_ntoa(lease->addr));
			state->state = STATE_REQUESTING;
		}
		if (!lease->addr.s_addr && !timerisset(&state->stop)) {
			state->stop.tv_sec = DHCP_MAX + DHCP_RAND_MIN;
			state->stop.tv_usec = arc4random() % (DHCP_RAND_MAX_U - DHCP_RAND_MIN_U);
			timernorm(&state->stop);
		}
		break;
	}

dhcp_timeout:
	if (state->carrier == LINK_DOWN) {
		timerclear(&state->timeout);
		return 0;
	}
	state->timeout.tv_sec = DHCP_BASE;
	for (i = 0; i < state->messages; i++) {
		state->timeout.tv_sec *= 2;
		if (state->timeout.tv_sec > DHCP_MAX) {
			state->timeout.tv_sec = DHCP_MAX;
			break;
		}
	}
	state->timeout.tv_sec += DHCP_RAND_MIN;
	state->timeout.tv_usec = arc4random() %
		(DHCP_RAND_MAX_U - DHCP_RAND_MIN_U);
	timernorm(&state->timeout);

	/* We send the message here so that the timeout is reported */
	switch (state->state) {
	case STATE_DISCOVERING:
		send_message(state, DHCP_DISCOVER, options);
		break;
	case STATE_REQUESTING:
		if (state->options & DHCPCD_INFORM) {
			send_message(state, DHCP_INFORM, options);
			break;
		}
		/* FALLTHROUGH */
	case STATE_RENEWING:   /* FALLTHROUGH */
	case STATE_REBINDING:
		if (iface->raw_fd == -1)
			do_socket(state, SOCKET_OPEN);
		send_message(state, DHCP_REQUEST, options);
		break;
	}

	return 0;
}

static void
log_dhcp(int lvl, const char *msg, const struct dhcp_message *dhcp)
{
	char *a;
	struct in_addr addr;
	int r;

	if (strcmp(msg, "NAK:") == 0)
		a = get_option_string(dhcp, DHO_MESSAGE);
	else {
		addr.s_addr = dhcp->yiaddr;
		a = xstrdup(inet_ntoa(addr));
	}
	r = get_option_addr(&addr, dhcp, DHO_SERVERID);
	if (dhcp->servername[0] && r == 0)
		logger(lvl, "%s %s from %s `%s'", msg, a,
		       inet_ntoa(addr), dhcp->servername);
	else if (r == 0)
		logger(lvl, "%s %s from %s", msg, a, inet_ntoa(addr));
	else
		logger(lvl, "%s %s", msg, a);
	free(a);
}

static int
handle_dhcp(struct if_state *state, struct dhcp_message **dhcpp,
	    const struct options *options)
{
	struct dhcp_message *dhcp = *dhcpp;
	struct interface *iface = state->interface;
	struct dhcp_lease *lease = &state->lease;
	uint8_t type, tmp;
	struct in_addr addr;
	size_t i;
	int r;

	/* reset the message counter */
	state->messages = 0;

	/* We have to have DHCP type to work */
	if (get_option_uint8(&type, dhcp, DHO_MESSAGETYPE) == -1) {
		logger(LOG_ERR, "ignoring message; no DHCP type");
		return 0;
	}
	/* Every DHCP message should include ServerID */
	if (get_option_addr(&addr, dhcp, DHO_SERVERID) == -1) {
		logger(LOG_ERR, "ignoring message; no Server ID");
		return 0;
	}

	/* Ensure that it's not from a blacklisted server.
	 * We should expand this to check IP and/or hardware address
	 * at the packet level. */
	if (options->blacklist_len != 0 &&
	    get_option_addr(&addr, dhcp, DHO_SERVERID) == 0)
	{
		for (i = 0; i < options->blacklist_len; i++) {
			if (options->blacklist[i] != addr.s_addr)
				continue;
			if (dhcp->servername[0])
				logger(LOG_WARNING,
				       "ignoring blacklisted server %s `%s'",
					inet_ntoa(addr), dhcp->servername);
			else
				logger(LOG_WARNING,
				       "ignoring blacklisted server %s",
				       inet_ntoa(addr));
			return 0;
		}
	}

	/* We should restart on a NAK */
	if (type == DHCP_NAK) {
		log_dhcp(LOG_WARNING, "NAK:", dhcp);
		drop_config(state, "EXPIRE", options);
		do_socket(state, SOCKET_CLOSED);
		state->state = STATE_INIT;
		/* If we constantly get NAKS then we should slowly back off */
		if (state->nakoff == 0) {
			state->nakoff = 1;
			timerclear(&state->timeout);
		} else {
			state->timeout.tv_sec = state->nakoff;
			state->timeout.tv_usec = 0;
			state->nakoff *= 2;
			if (state->nakoff > NAKOFF_MAX)
				state->nakoff = NAKOFF_MAX;
		} 
		return 0;
	}

	/* No NAK, so reset the backoff */
	state->nakoff = 1;

	/* Ensure that all required options are present */
	for (i = 1; i < 255; i++) {
		if (has_option_mask(options->requiremask, i) &&
		    get_option_uint8(&tmp, dhcp, i) != 0)
		{
			log_dhcp(LOG_WARNING, "reject", dhcp);
			return 0;
		}
	}

	if (type == DHCP_OFFER && state->state == STATE_DISCOVERING) {
		lease->addr.s_addr = dhcp->yiaddr;
		get_option_addr(&lease->server, dhcp, DHO_SERVERID);
		log_dhcp(LOG_INFO, "offered", dhcp);
		if (state->options & DHCPCD_TEST) {
			run_script(options, iface->name, "TEST", dhcp, NULL);
			/* Fake the fact we forked so we return 0 to userland */
			state->options |= DHCPCD_FORKED;
			return -1;
		}
		free(state->offer);
		state->offer = dhcp;
		*dhcpp = NULL;
		timerclear(&state->timeout);
		state->state = STATE_REQUESTING;
		return 1;
	}

	if (type == DHCP_OFFER) {
		log_dhcp(LOG_INFO, "ignoring offer of", dhcp);
		return 0;
	}

	/* We should only be dealing with acks */
	if (type != DHCP_ACK) {
		log_dhcp(LOG_ERR, "not ACK or OFFER", dhcp);
		return 0;
	}
	    
	switch (state->state) {
	case STATE_RENEW_REQUESTED:
	case STATE_REQUESTING:
	case STATE_RENEWING:
	case STATE_REBINDING:
		if (!(state->options & DHCPCD_INFORM)) {
			get_option_addr(&lease->server,
					dhcp, DHO_SERVERID);
			log_dhcp(LOG_INFO, "acknowledged", dhcp);
		}
		free(state->offer);
		state->offer = dhcp;
		*dhcpp = NULL;
		break;
	default:
		logger(LOG_ERR, "wrong state %d", state->state);
	}

	lease->frominfo = 0;
	do_socket(state, SOCKET_CLOSED);
	if (state->options & DHCPCD_ARP &&
	    iface->addr.s_addr != state->offer->yiaddr)
	{
		/* If the interface already has the address configured
		 * then we can't ARP for duplicate detection. */
		addr.s_addr = state->offer->yiaddr;
		if (!has_address(iface->name, &addr, NULL)) {
			state->state = STATE_PROBING;
			state->claims = 0;
			state->probes = 0;
			state->conflicts = 0;
			timerclear(&state->stop);
			return 1;
		}
	}

	r = bind_dhcp(state, options);
	if (!(state->options & DHCPCD_ARP)) {
		if (!(state->options & DHCPCD_INFORM))
			logger(LOG_DEBUG, "renew in %ld seconds",
			       (long int)state->stop.tv_sec);
		return r;
	}
	state->state = STATE_ANNOUNCING;
	if (state->options & DHCPCD_FORKED)
		return r;
	return 1;
}

static int
handle_dhcp_packet(struct if_state *state, const struct options *options)
{
	uint8_t *packet;
	struct interface *iface = state->interface;
	struct dhcp_message *dhcp = NULL;
	const uint8_t *pp;
	ssize_t bytes;
	int retval = -1;

	/* We loop through until our buffer is empty.
	 * The benefit is that if we get >1 DHCP packet in our buffer and
	 * the first one fails for any reason, we can use the next. */
	packet = xmalloc(udp_dhcp_len);
	for(;;) {
		bytes = get_raw_packet(iface, ETHERTYPE_IP,
				       packet, udp_dhcp_len);
		if (bytes == 0) {
			retval = 0;
			break;
		}
		if (bytes == -1)
			break;
		if (valid_udp_packet(packet, bytes) == -1)
			continue;
		bytes = get_udp_data(&pp, packet);
		if ((size_t)bytes > sizeof(*dhcp)) {
			logger(LOG_ERR, "packet greater than DHCP size");
			continue;
		}
		if (!dhcp)
			dhcp = xzalloc(sizeof(*dhcp));
		memcpy(dhcp, pp, bytes);
		if (dhcp->cookie != htonl(MAGIC_COOKIE)) {
			logger(LOG_DEBUG, "bogus cookie, ignoring");
			continue;
		}
		/* Ensure it's the right transaction */
		if (state->xid != dhcp->xid) {
			logger(LOG_DEBUG,
			       "ignoring packet with xid 0x%x as"
			       " it's not ours (0x%x)",
			       dhcp->xid, state->xid);
			continue;
		}
		/* Ensure packet is for us */
		if (iface->hwlen <= sizeof(dhcp->chaddr) &&
		    memcmp(dhcp->chaddr, iface->hwaddr, iface->hwlen))
		{
			logger(LOG_DEBUG, "xid 0x%x is not for our hwaddr %s",
			       dhcp->xid,
			       hwaddr_ntoa(dhcp->chaddr, sizeof(dhcp->chaddr)));
			continue;
		}
		retval = handle_dhcp(state, &dhcp, options);
		if (retval == 0 && state->options & DHCPCD_TEST)
			state->options |= DHCPCD_FORKED;
		break;
	}

	free(packet);
	free(dhcp);
	return retval;
}

static int
handle_arp_packet(struct if_state *state)
{
	struct arphdr reply;
	uint32_t reply_s;
	uint32_t reply_t;
	uint8_t arp_reply[sizeof(reply) + 2 * sizeof(reply_s) + 2 * HWADDR_LEN];
	uint8_t *hw_s, *hw_t;
	ssize_t bytes;
	struct interface *iface = state->interface;

	state->fail.s_addr = 0;
	for(;;) {
		bytes = get_raw_packet(iface, ETHERTYPE_ARP,
				       arp_reply, sizeof(arp_reply));
		if (bytes == 0 || bytes == -1)
			return (int)bytes;
		/* We must have a full ARP header */
		if ((size_t)bytes < sizeof(reply))
			continue;
		memcpy(&reply, arp_reply, sizeof(reply));
		/* Protocol must be IP. */
		if (reply.ar_pro != htons(ETHERTYPE_IP))
			continue;
		if (reply.ar_pln != sizeof(reply_s))
			continue;
		/* Only these types are recognised */
		if (reply.ar_op != htons(ARPOP_REPLY) &&
		    reply.ar_op != htons(ARPOP_REQUEST))
			continue;

		/* Get pointers to the hardware addreses */
		hw_s = arp_reply + sizeof(reply);
		hw_t = hw_s + reply.ar_hln + reply.ar_pln;
		/* Ensure we got all the data */
		if ((hw_t + reply.ar_hln + reply.ar_pln) - arp_reply > bytes)
			continue;
		/* Ignore messages from ourself */
		if (reply.ar_hln == iface->hwlen &&
		    memcmp(hw_s, iface->hwaddr, iface->hwlen) == 0)
			continue;
		/* Copy out the IP addresses */
		memcpy(&reply_s, hw_s + reply.ar_hln, reply.ar_pln);
		memcpy(&reply_t, hw_t + reply.ar_hln, reply.ar_pln);

		/* Check for conflict */
		if (state->offer && 
		    (reply_s == state->offer->yiaddr ||
		     (reply_s == 0 && reply_t == state->offer->yiaddr)))
			state->fail.s_addr = state->offer->yiaddr;

		/* Handle IPv4LL conflicts */
		if (IN_LINKLOCAL(htonl(iface->addr.s_addr)) &&
		    (reply_s == iface->addr.s_addr ||
		     (reply_s == 0 && reply_t == iface->addr.s_addr)))
			state->fail.s_addr = iface->addr.s_addr;

		if (state->fail.s_addr) {
			logger(LOG_ERR, "hardware address %s claims %s",
			       hwaddr_ntoa((unsigned char *)hw_s,
					   (size_t)reply.ar_hln),
			       inet_ntoa(state->fail));
			errno = EEXIST;
			return -1;
		}
	}
}

static int
handle_arp_fail(struct if_state *state, const struct options *options)
{
	time_t up;
	int cookie = state->offer->cookie;

	if (!IN_LINKLOCAL(htonl(state->fail.s_addr))) {
		if (cookie) {
			state->timeout.tv_sec = DHCP_ARP_FAIL;
			state->timeout.tv_usec = 0;
			do_socket(state, SOCKET_OPEN);
			send_message(state, DHCP_DECLINE, options);
			do_socket(state, SOCKET_CLOSED);
		}
		state->state = STATE_INIT;
		free(state->offer);
		state->offer = NULL;
		state->lease.addr.s_addr = 0;
		if (!cookie)
			return 1;
		return 0;
	}

	if (state->fail.s_addr == state->interface->addr.s_addr) {
		if (state->state == STATE_PROBING)
			/* This should only happen when SIGALRM or
			 * link when down/up and we have a conflict. */
			drop_config(state, "EXPIRE", options);
		else {
			up = uptime();
			if (state->defend + DEFEND_INTERVAL > up) {
				drop_config(state, "EXPIRE", options);
				state->conflicts = -1;
				/* drop through to set conflicts to 0 */
			} else {
				state->defend = up;
				return 0;
			}
		}
	}
	do_socket(state, SOCKET_CLOSED);
	state->conflicts++;
	timerclear(&state->stop);
	if (state->conflicts > MAX_CONFLICTS) {
		logger(LOG_ERR, "failed to obtain an IPv4LL address");
		state->state = STATE_INIT;
		timerclear(&state->timeout);
		if (!(state->options & DHCPCD_DAEMONISED) &&
		    (state->options & DHCPCD_DAEMONISE))
			return -1;
		return 1;
	}
	state->state = STATE_INIT_IPV4LL;
	state->timeout.tv_sec = PROBE_WAIT;
	state->timeout.tv_usec = 0;
	return 0;
}

static int
handle_link(struct if_state *state)
{
	int retval;

	retval = link_changed(state->interface);
	if (retval == -1) {
		logger(LOG_ERR, "link_changed: %s", strerror(errno));
		return -1;
	}
	if (retval == 0)
		return 0;

	switch (carrier_status(state->interface->name)) {
	case -1:
		logger(LOG_ERR, "carrier_status: %s", strerror(errno));
		return -1;
	case 0:
		if (state->carrier != LINK_DOWN) {
			logger(LOG_INFO, "carrier lost");
			state->carrier = LINK_DOWN;
			do_socket(state, SOCKET_CLOSED);
			timerclear(&state->timeout);
			if (state->state != STATE_BOUND)
				timerclear(&state->stop);
		}
		break;
	default:
		if (state->carrier != LINK_UP) {
			logger(LOG_INFO, "carrier acquired");
			state->state = STATE_RENEW_REQUESTED;
			state->carrier = LINK_UP;
			timerclear(&state->timeout);
			timerclear(&state->stop);
			return 1;
		}
		break;
	}
	return 0;
}

int
dhcp_run(const struct options *options, int *pid_fd)
{
	struct interface *iface;
	struct if_state *state = NULL;
	int fd = -1, r = 0, sig;

	iface = read_interface(options->interface, options->metric);
	if (!iface) {
		logger(LOG_ERR, "read_interface: %s", strerror(errno));
		goto eexit;
	}
	logger(LOG_DEBUG, "hardware address = %s",
	       hwaddr_ntoa(iface->hwaddr, iface->hwlen));
	state = xzalloc(sizeof(*state));
	state->pid_fd = pid_fd;
	state->interface = iface;
	if (!(options->options & DHCPCD_TEST))
		run_script(options, iface->name, "PREINIT", NULL, NULL);

	if (client_setup(state, options) == -1)
		goto eexit;
	if (signal_init() == -1)
		goto eexit;
	if (signal_setup() == -1)
		goto eexit;
	state->signal_fd = signal_fd();

	if (state->options & DHCPCD_BACKGROUND &&
	    !(state->options & DHCPCD_DAEMONISED))
		if (daemonise(state, options) == -1)
			goto eexit;

	if (state->carrier == LINK_DOWN)
		logger(LOG_INFO, "waiting for carrier");

	for (;;) {
		if (r == 0)
			r = handle_timeout(state, options);
		else if (r > 0) {
			if (fd == state->signal_fd) {
			    	if ((sig = signal_read()) != -1)
					r = handle_signal(sig, state, options);
			} else if (fd == iface->link_fd)
				r = handle_link(state);
			else if (fd == iface->raw_fd)
				r = handle_dhcp_packet(state, options);
			else if (fd == iface->arp_fd) {
				if ((r = handle_arp_packet(state)) == -1)
					r = handle_arp_fail(state, options);
			} else
				r = 0;
		}
		if (r == -1)
			break;
		if (r == 0) {
			fd = -1;
			r = wait_for_fd(state, &fd);
			if (r == -1 && errno == EINTR) {
				r = 1;
				fd = state->signal_fd;
			}
		} else
			r = 0;
	}

eexit:
	if (iface) {
		do_socket(state, SOCKET_CLOSED);
		if (iface->link_fd != -1)
		    close(iface->link_fd);
		free_routes(iface->routes);
		free(iface->clientid);
		free(iface->buffer);
		free(iface);
	}

	if (state) {
		if (state->options & DHCPCD_FORKED)
			r = 0;
		if (state->options & DHCPCD_DAEMONISED)
			unlink(options->pidfile);
		free(state->offer);
		free(state->new);
		free(state->old);
		free(state);
	}

	return r;
}
