/*
 *
 *  DHCP client library with GLib integration
 *
 *  Copyright (C) 2009-2014  Intel Corporation. All rights reserved.
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License version 2 as
 *  published by the Free Software Foundation.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 */

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

#define _GNU_SOURCE
#include <stdio.h>
#include <errno.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <sys/ioctl.h>
#include <arpa/inet.h>
#include <sys/time.h>
#include <resolv.h>

#include <netpacket/packet.h>
#include <netinet/if_ether.h>
#include <net/ethernet.h>

#include <linux/if.h>
#include <linux/filter.h>

#include <glib.h>

#include "gdhcp.h"
#include "common.h"
#include "ipv4ll.h"
#include "timer.h"
#define CLOCK_BOOTTIME_ALARM 9
#define DISCOVER_TIMEOUT 10
#define DISCOVER_RETRIES 6

#define REQUEST_TIMEOUT 5
#define REQUEST_RETRIES 3

typedef enum _listen_mode {
	L_NONE,
	L2,
	L3,
	L_ARP,
} ListenMode;

typedef enum _dhcp_client_state {
	INIT_SELECTING,
	REBOOTING,
	REQUESTING,
	BOUND,
	RENEWING,
	REBINDING,
	RELEASED,
	IPV4LL_PROBE,
	IPV4LL_ANNOUNCE,
	IPV4LL_MONITOR,
	IPV4LL_DEFEND,
	INFORMATION_REQ,
	SOLICITATION,
	REQUEST,
	CONFIRM,
	RENEW,
	REBIND,
	RELEASE,
	DECLINE,
} ClientState;

struct _GDHCPClient {
	int ref_count;
	GDHCPType type;
	ClientState state;
	int ifindex;
	char *interface;
	uint8_t mac_address[6];
	uint32_t xid;
	uint32_t server_ip;
	uint32_t requested_ip;
	char *assigned_ip;
	time_t start;
	uint32_t lease_seconds;
	ListenMode listen_mode;
	int listener_sockfd;
	uint8_t retry_times;
	uint8_t ack_retry_times;
	uint8_t conflicts;
	guint timeout;
	guint t1_timeout;
	guint t2_timeout;
	guint lease_timeout;
	guint listener_watch;
	GList *require_list;
	GList *request_list;
	GHashTable *code_value_hash;
	GHashTable *send_value_hash;
	GDHCPClientEventFunc lease_available_cb;
	gpointer lease_available_data;
	GDHCPClientEventFunc ipv4ll_available_cb;
	gpointer ipv4ll_available_data;
	GDHCPClientEventFunc no_lease_cb;
	gpointer no_lease_data;
	GDHCPClientEventFunc lease_lost_cb;
	gpointer lease_lost_data;
	GDHCPClientEventFunc ipv4ll_lost_cb;
	gpointer ipv4ll_lost_data;
	GDHCPClientEventFunc address_conflict_cb;
	gpointer address_conflict_data;
	GDHCPDebugFunc debug_func;
	gpointer debug_data;
	GDHCPClientEventFunc information_req_cb;
	gpointer information_req_data;
	GDHCPClientEventFunc solicitation_cb;
	gpointer solicitation_data;
	GDHCPClientEventFunc advertise_cb;
	gpointer advertise_data;
	GDHCPClientEventFunc request_cb;
	gpointer request_data;
	GDHCPClientEventFunc renew_cb;
	gpointer renew_data;
	GDHCPClientEventFunc wake_event_cb;
	gpointer wake_event_data;
	GDHCPClientEventFunc rebind_cb;
	gpointer rebind_data;
	GDHCPClientEventFunc release_cb;
	gpointer release_data;
	GDHCPClientEventFunc confirm_cb;
	gpointer confirm_data;
	GDHCPClientEventFunc decline_cb;
	gpointer decline_data;
	char *last_address;
	unsigned char *duid;
	int duid_len;
	unsigned char *server_duid;
	int server_duid_len;
	uint16_t status_code;
	uint32_t iaid;
	uint32_t T1, T2;
	uint32_t next_event;
	int can_sleep;
	struct in6_addr ia_na;
	struct in6_addr ia_ta;
	time_t last_request;
	uint32_t expire;
	bool retransmit;
	struct timeval start_time;
	bool request_bcast;
};

static inline void debug(GDHCPClient *client, const char *format, ...)
{
	char str[256];
	va_list ap;

	if (!client->debug_func)
		return;

	va_start(ap, format);

	if (vsnprintf(str, sizeof(str), format, ap) > 0)
		client->debug_func(str, client->debug_data);

	va_end(ap);
}

static void set_wake(GDHCPClient *dhcp_client, uint32_t timeout)
{
	debug(dhcp_client, "Stay awake for %d", timeout);

	dhcp_client->next_event = timeout + time(NULL);
	dhcp_client->can_sleep = FALSE;
	if (dhcp_client->wake_event_cb)
		dhcp_client->wake_event_cb(dhcp_client,
				dhcp_client->wake_event_data);
}

static void release_wake(GDHCPClient *dhcp_client, uint32_t timeout)
{
	debug(dhcp_client, "may sleep for %d", timeout);
	dhcp_client->next_event = timeout + time(NULL);
	dhcp_client->can_sleep = TRUE;
	if (dhcp_client->wake_event_cb)
		dhcp_client->wake_event_cb(dhcp_client,
				dhcp_client->wake_event_data);
}

int g_dhcp_get_next_event(GDHCPClient *dhcp_client, time_t *next_event)
{
	*next_event = dhcp_client->next_event;
	return dhcp_client->can_sleep;
}

/* Initialize the packet with the proper defaults */
static void init_packet(GDHCPClient *dhcp_client, gpointer pkt, char type)
{
	if (dhcp_client->type == G_DHCP_IPV6)
		dhcpv6_init_header(pkt, type);
	else {
		struct dhcp_packet *packet = pkt;

		dhcp_init_header(packet, type);
		memcpy(packet->chaddr, dhcp_client->mac_address, 6);
	}
}

static void add_request_options(GDHCPClient *dhcp_client,
				struct dhcp_packet *packet)
{
	int len = 0;
	GList *list;
	uint8_t code;
	int end = dhcp_end_option(packet->options);

	for (list = dhcp_client->request_list; list; list = list->next) {
		code = (uint8_t) GPOINTER_TO_INT(list->data);

		packet->options[end + OPT_DATA + len] = code;
		len++;
	}

	if (len) {
		packet->options[end + OPT_CODE] = DHCP_PARAM_REQ;
		packet->options[end + OPT_LEN] = len;
		packet->options[end + OPT_DATA + len] = DHCP_END;
	}
}

struct hash_params {
	unsigned char *buf;
	int max_buf;
	unsigned char **ptr_buf;
};

static void add_dhcpv6_binary_option(gpointer key, gpointer value,
					gpointer user_data)
{
	uint8_t *option = value;
	uint16_t len;
	struct hash_params *params = user_data;

	/* option[0][1] contains option code */
	len = option[2] << 8 | option[3];

	if ((*params->ptr_buf + len + 2 + 2) > (params->buf + params->max_buf))
		return;

	memcpy(*params->ptr_buf, option, len + 2 + 2);
	(*params->ptr_buf) += len + 2 + 2;
}

static void add_dhcpv6_send_options(GDHCPClient *dhcp_client,
				unsigned char *buf, int max_buf,
				unsigned char **ptr_buf)
{
	struct hash_params params = {
		.buf = buf,
		.max_buf = max_buf,
		.ptr_buf = ptr_buf
	};

	if (dhcp_client->type != G_DHCP_IPV6)
		return;

	g_hash_table_foreach(dhcp_client->send_value_hash,
				add_dhcpv6_binary_option, &params);

	*ptr_buf = *params.ptr_buf;
}

static void copy_option(uint8_t *buf, uint16_t code, uint16_t len,
			uint8_t *msg)
{
	buf[0] = code >> 8;
	buf[1] = code & 0xff;
	buf[2] = len >> 8;
	buf[3] = len & 0xff;
	if (len > 0 && msg)
		memcpy(&buf[4], msg, len);
}

static int32_t get_time_diff(struct timeval *tv)
{
	struct timeval now;
	int32_t hsec;

	gettimeofday(&now, NULL);

	hsec = (now.tv_sec - tv->tv_sec) * 100;
	hsec += (now.tv_usec - tv->tv_usec) / 10000;

	return hsec;
}

static void remove_timeouts(GDHCPClient *dhcp_client)
{

	if (dhcp_client->timeout > 0)
		g_rttimeout_source_remove(dhcp_client->timeout);
	if (dhcp_client->t1_timeout > 0)
		g_rttimeout_source_remove(dhcp_client->t1_timeout);
	if (dhcp_client->t2_timeout > 0)
		g_rttimeout_source_remove(dhcp_client->t2_timeout);
	if (dhcp_client->lease_timeout > 0)
		g_rttimeout_source_remove(dhcp_client->lease_timeout);

	dhcp_client->timeout = 0;
	dhcp_client->t1_timeout = 0;
	dhcp_client->t2_timeout = 0;
	dhcp_client->lease_timeout = 0;

}

static void add_dhcpv6_request_options(GDHCPClient *dhcp_client,
				struct dhcpv6_packet *packet,
				unsigned char *buf, int max_buf,
				unsigned char **ptr_buf)
{
	GList *list;
	uint16_t code, value;
	bool added;
	int32_t diff;
	int len;

	if (dhcp_client->type != G_DHCP_IPV6)
		return;

	for (list = dhcp_client->request_list; list; list = list->next) {
		code = (uint16_t) GPOINTER_TO_INT(list->data);
		added = false;

		switch (code) {
		case G_DHCPV6_CLIENTID:
			if (!dhcp_client->duid)
				return;

			len = 2 + 2 + dhcp_client->duid_len;
			if ((*ptr_buf + len) > (buf + max_buf)) {
				debug(dhcp_client, "Too long dhcpv6 message "
					"when writing client id option");
				return;
			}

			copy_option(*ptr_buf, G_DHCPV6_CLIENTID,
				dhcp_client->duid_len, dhcp_client->duid);
			(*ptr_buf) += len;
			added = true;
			break;

		case G_DHCPV6_SERVERID:
			if (!dhcp_client->server_duid)
				break;

			len = 2 + 2 + dhcp_client->server_duid_len;
			if ((*ptr_buf + len) > (buf + max_buf)) {
				debug(dhcp_client, "Too long dhcpv6 message "
					"when writing server id option");
				return;
			}

			copy_option(*ptr_buf, G_DHCPV6_SERVERID,
				dhcp_client->server_duid_len,
				dhcp_client->server_duid);
			(*ptr_buf) += len;
			added = true;
			break;

		case G_DHCPV6_RAPID_COMMIT:
			len = 2 + 2;
			if ((*ptr_buf + len) > (buf + max_buf)) {
				debug(dhcp_client, "Too long dhcpv6 message "
					"when writing rapid commit option");
				return;
			}

			copy_option(*ptr_buf, G_DHCPV6_RAPID_COMMIT, 0, 0);
			(*ptr_buf) += len;
			added = true;
			break;

		case G_DHCPV6_ORO:
			break;

		case G_DHCPV6_ELAPSED_TIME:
			if (!dhcp_client->retransmit) {
				/*
				 * Initial message, elapsed time is 0.
				 */
				diff = 0;
			} else {
				diff = get_time_diff(&dhcp_client->start_time);
				if (diff < 0 || diff > 0xffff)
					diff = 0xffff;
			}

			len = 2 + 2 + 2;
			if ((*ptr_buf + len) > (buf + max_buf)) {
				debug(dhcp_client, "Too long dhcpv6 message "
					"when writing elapsed time option");
				return;
			}

			value = htons((uint16_t)diff);
			copy_option(*ptr_buf, G_DHCPV6_ELAPSED_TIME,
				2, (uint8_t *)&value);
			(*ptr_buf) += len;
			added = true;
			break;

		case G_DHCPV6_DNS_SERVERS:
			break;

		case G_DHCPV6_DOMAIN_LIST:
			break;

		case G_DHCPV6_SNTP_SERVERS:
			break;

		default:
			break;
		}

		if (added)
			debug(dhcp_client, "option %d len %d added", code, len);
	}
}

static void add_binary_option(gpointer key, gpointer value, gpointer user_data)
{
	uint8_t *option = value;
	struct dhcp_packet *packet = user_data;

	dhcp_add_binary_option(packet, option);
}

static void add_send_options(GDHCPClient *dhcp_client,
				struct dhcp_packet *packet)
{
	g_hash_table_foreach(dhcp_client->send_value_hash,
				add_binary_option, packet);
}

static const char *get_message_type(uint8_t type)
{
	switch (type) {
	case DHCPDISCOVER:
		return "DISCOVER";
	case DHCPOFFER:
		return "OFFER";
	case DHCPREQUEST:
		return "REQUEST";
	case DHCPDECLINE:
		return "DECLINE";
	case DHCPACK:
		return "ACK";
	case DHCPNAK:
		return "NAK";
	case DHCPRELEASE:
		return "RELEASE";
	case DHCPINFORM:
		return "INFORM";
	default:
		return "";
	}
}
/*
 * Return an RFC 951- and 2131-complaint BOOTP 'secs' value that
 * represents the number of seconds elapsed from the start of
 * attempting DHCP to satisfy some DHCP servers that allow for an
 * "authoritative" reply before responding.
 */
static uint16_t dhcp_attempt_secs(GDHCPClient *dhcp_client)
{
	return htons(MIN(time(NULL) - dhcp_client->start, UINT16_MAX));
}

static int send_discover(GDHCPClient *dhcp_client, uint32_t requested)
{
	const uint8_t type = DHCPDISCOVER;
	struct dhcp_packet packet;
	struct in_addr dest;
	char destbuf[INET_ADDRSTRLEN];

	init_packet(dhcp_client, &packet, type);

	packet.xid = dhcp_client->xid;
	packet.secs = dhcp_attempt_secs(dhcp_client);

	if (requested)
		dhcp_add_option_uint32(&packet, DHCP_REQUESTED_IP, requested);

	/* Explicitly saying that we want RFC-compliant packets helps
	 * some buggy DHCP servers to NOT send bigger packets */
	dhcp_add_option_uint16(&packet, DHCP_MAX_SIZE, 576);

	add_request_options(dhcp_client, &packet);

	add_send_options(dhcp_client, &packet);

	dest.s_addr = INADDR_BROADCAST;

	debug(dhcp_client, "%s on %s to %s port %d interval %d",
		get_message_type(type),
		dhcp_client->interface,
		inet_ntop(AF_INET, &dest, destbuf, sizeof(destbuf)),
		SERVER_PORT,
		DISCOVER_TIMEOUT);

	set_wake(dhcp_client, DISCOVER_TIMEOUT);

	return dhcp_send_raw_packet(&packet, INADDR_ANY, CLIENT_PORT,
					dest.s_addr, SERVER_PORT,
					MAC_BCAST_ADDR, dhcp_client->ifindex,
                    dhcp_client->retry_times % 2);
}

static int send_request(GDHCPClient *dhcp_client)
{
	const uint8_t type = DHCPREQUEST;
	struct dhcp_packet packet;
	struct in_addr request, dest;
	char requestbuf[INET_ADDRSTRLEN], destbuf[INET_ADDRSTRLEN];
    
    debug(dhcp_client, "sending DHCP request (state %d)",
                     dhcp_client->state);

	init_packet(dhcp_client, &packet, type);

	packet.xid = dhcp_client->xid;
	packet.secs = dhcp_attempt_secs(dhcp_client);

	if (dhcp_client->state == REQUESTING || dhcp_client->state == REBOOTING)
		dhcp_add_option_uint32(&packet, DHCP_REQUESTED_IP,
				dhcp_client->requested_ip);

	if (dhcp_client->state == REQUESTING)
		dhcp_add_option_uint32(&packet, DHCP_SERVER_ID,
				dhcp_client->server_ip);

	dhcp_add_option_uint16(&packet, DHCP_MAX_SIZE, 576);

	add_request_options(dhcp_client, &packet);

	add_send_options(dhcp_client, &packet);
    
    request.s_addr = dhcp_client->requested_ip;
    dest.s_addr = INADDR_BROADCAST;
          
    debug(dhcp_client, "%s of %s on %s to %s port %d interval %d",
          get_message_type(type),
          inet_ntop(AF_INET, &request, requestbuf, sizeof(requestbuf)),
          dhcp_client->interface,
          inet_ntop(AF_INET, &dest, destbuf, sizeof(destbuf)),
          SERVER_PORT,
          REQUEST_TIMEOUT);

	if (dhcp_client->state == RENEWING || dhcp_client->state == REBINDING)
		packet.ciaddr = htonl(dhcp_client->requested_ip);

	set_wake(dhcp_client, REQUEST_TIMEOUT);

	if (dhcp_client->state == RENEWING )
		return dhcp_send_kernel_packet(&packet,
				dhcp_client->requested_ip, CLIENT_PORT,
				dhcp_client->server_ip, SERVER_PORT);

	return dhcp_send_raw_packet(&packet, INADDR_ANY, CLIENT_PORT,
				INADDR_BROADCAST, SERVER_PORT,
				MAC_BCAST_ADDR, dhcp_client->ifindex,
				dhcp_client->request_bcast);
}

static int send_release(GDHCPClient *dhcp_client,
			uint32_t server, uint32_t ciaddr)
{
	const uint8_t type = DHCPRELEASE;
	struct dhcp_packet packet;
	uint64_t rand;
    struct in_addr release, dest;
	char releasebuf[INET_ADDRSTRLEN], destbuf[INET_ADDRSTRLEN];
	
    debug(dhcp_client, "sending DHCP release request");

	init_packet(dhcp_client, &packet, DHCPRELEASE);
	dhcp_get_random(&rand);
	packet.xid = rand;
	packet.ciaddr = htonl(ciaddr);

	dhcp_add_option_uint32(&packet, DHCP_SERVER_ID, server);

	release.s_addr = ciaddr;
	dest.s_addr = server;

	debug(dhcp_client, "%s of %s on %s to %s port %d",
		get_message_type(type),
		inet_ntop(AF_INET, &release, releasebuf, sizeof(releasebuf)),
		dhcp_client->interface,
		inet_ntop(AF_INET, &dest, destbuf, sizeof(destbuf)),
		SERVER_PORT);

	return dhcp_send_kernel_packet(&packet, release.s_addr, CLIENT_PORT,
						dest.s_addr, SERVER_PORT);
}

static gboolean ipv4ll_probe_timeout(gpointer dhcp_data);
static int switch_listening_mode(GDHCPClient *dhcp_client,
					ListenMode listen_mode);

static gboolean send_probe_packet(gpointer dhcp_data)
{
	GDHCPClient *dhcp_client;
	guint timeout;

	dhcp_client = dhcp_data;
	/* if requested_ip is not valid, pick a new address*/
	if (dhcp_client->requested_ip == 0) {
		debug(dhcp_client, "pick a new random address");
		dhcp_client->requested_ip = ipv4ll_random_ip();
	}

	debug(dhcp_client, "sending IPV4LL probe request");

	if (dhcp_client->retry_times == 1) {
		dhcp_client->state = IPV4LL_PROBE;
		switch_listening_mode(dhcp_client, L_ARP);
	}
	ipv4ll_send_arp_packet(dhcp_client->mac_address, 0,
			dhcp_client->requested_ip, dhcp_client->ifindex);

	if (dhcp_client->retry_times < PROBE_NUM) {
		/*add a random timeout in range of PROBE_MIN to PROBE_MAX*/
		timeout = ipv4ll_random_delay_ms(PROBE_MAX-PROBE_MIN);
		timeout += PROBE_MIN*1000;
	} else
		timeout = (ANNOUNCE_WAIT * 1000);

	dhcp_client->timeout = g_rttimeout_add_full(CLOCK_BOOTTIME_ALARM, G_PRIORITY_HIGH,
						 timeout,
						 ipv4ll_probe_timeout,
						 dhcp_client,
						 NULL);
	return FALSE;
}

static gboolean ipv4ll_announce_timeout(gpointer dhcp_data);
static gboolean ipv4ll_defend_timeout(gpointer dhcp_data);

static gboolean send_announce_packet(gpointer dhcp_data)
{
	GDHCPClient *dhcp_client;

	dhcp_client = dhcp_data;

	debug(dhcp_client, "sending IPV4LL announce request");

	ipv4ll_send_arp_packet(dhcp_client->mac_address,
				dhcp_client->requested_ip,
				dhcp_client->requested_ip,
				dhcp_client->ifindex);

	remove_timeouts(dhcp_client);

	if (dhcp_client->state == IPV4LL_DEFEND) {
		dhcp_client->timeout =
			g_rttimeout_add_seconds_full(CLOCK_BOOTTIME_ALARM, G_PRIORITY_HIGH,
						DEFEND_INTERVAL,
						ipv4ll_defend_timeout,
						dhcp_client,
						NULL);
		return TRUE;
	} else
		dhcp_client->timeout =
			g_rttimeout_add_seconds_full(CLOCK_BOOTTIME_ALARM, G_PRIORITY_HIGH,
						ANNOUNCE_INTERVAL,
						ipv4ll_announce_timeout,
						dhcp_client,
						NULL);
	return TRUE;
}

static void get_interface_mac_address(int index, uint8_t *mac_address)
{
	struct ifreq ifr;
	int sk, err;

	sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
	if (sk < 0) {
		perror("Open socket error");
		return;
	}

	memset(&ifr, 0, sizeof(ifr));
	ifr.ifr_ifindex = index;

	err = ioctl(sk, SIOCGIFNAME, &ifr);
	if (err < 0) {
		perror("Get interface name error");
		goto done;
	}

	err = ioctl(sk, SIOCGIFHWADDR, &ifr);
	if (err < 0) {
		perror("Get mac address error");
		goto done;
	}

	memcpy(mac_address, ifr.ifr_hwaddr.sa_data, 6);

done:
	close(sk);
}

void g_dhcpv6_client_set_retransmit(GDHCPClient *dhcp_client)
{
	if (!dhcp_client)
		return;

	dhcp_client->retransmit = true;
}

void g_dhcpv6_client_clear_retransmit(GDHCPClient *dhcp_client)
{
	if (!dhcp_client)
		return;

	dhcp_client->retransmit = false;
}

int g_dhcpv6_create_duid(GDHCPDuidType duid_type, int index, int type,
			unsigned char **duid, int *duid_len)
{
	time_t duid_time;

	switch (duid_type) {
	case G_DHCPV6_DUID_LLT:
		*duid_len = 2 + 2 + 4 + ETH_ALEN;
		*duid = g_try_malloc(*duid_len);
		if (!*duid)
			return -ENOMEM;

		(*duid)[0] = 0;
		(*duid)[1] = 1;
		get_interface_mac_address(index, &(*duid)[2 + 2 + 4]);
		(*duid)[2] = 0;
		(*duid)[3] = type;
		duid_time = time(NULL) - DUID_TIME_EPOCH;
		(*duid)[4] = duid_time >> 24;
		(*duid)[5] = duid_time >> 16;
		(*duid)[6] = duid_time >> 8;
		(*duid)[7] = duid_time & 0xff;
		break;
	case G_DHCPV6_DUID_EN:
		return -EINVAL;
	case G_DHCPV6_DUID_LL:
		*duid_len = 2 + 2 + ETH_ALEN;
		*duid = g_try_malloc(*duid_len);
		if (!*duid)
			return -ENOMEM;

		(*duid)[0] = 0;
		(*duid)[1] = 3;
		get_interface_mac_address(index, &(*duid)[2 + 2]);
		(*duid)[2] = 0;
		(*duid)[3] = type;
		break;
	}

	return 0;
}

static gchar *convert_to_hex(unsigned char *buf, int len)
{
	gchar *ret = g_try_malloc(len * 2 + 1);
	int i;

	for (i = 0; ret && i < len; i++)
		g_snprintf(ret + i * 2, 3, "%02x", buf[i]);

	return ret;
}

int g_dhcpv6_client_set_duid(GDHCPClient *dhcp_client, unsigned char *duid,
			int duid_len)
{
	if (!dhcp_client || dhcp_client->type != G_DHCP_IPV6)
		return -EINVAL;

	g_free(dhcp_client->duid);

	dhcp_client->duid = duid;
	dhcp_client->duid_len = duid_len;

	if (dhcp_client->debug_func) {
		gchar *hex = convert_to_hex(duid, duid_len);
		debug(dhcp_client, "DUID(%d) %s", duid_len, hex);
		g_free(hex);
	}

	return 0;
}

int g_dhcpv6_client_set_pd(GDHCPClient *dhcp_client, uint32_t *T1,
			uint32_t *T2, GSList *prefixes)
{
	uint8_t options[1452];
	unsigned int max_buf = sizeof(options);
	int len, count = g_slist_length(prefixes);

	if (!dhcp_client || dhcp_client->type != G_DHCP_IPV6)
		return -EINVAL;

	g_dhcp_client_set_request(dhcp_client, G_DHCPV6_IA_PD);

	memset(options, 0, sizeof(options));

	options[0] = dhcp_client->iaid >> 24;
	options[1] = dhcp_client->iaid >> 16;
	options[2] = dhcp_client->iaid >> 8;
	options[3] = dhcp_client->iaid;

	if (T1) {
		uint32_t t = htonl(*T1);
		memcpy(&options[4], &t, 4);
	}

	if (T2) {
		uint32_t t = htonl(*T2);
		memcpy(&options[8], &t, 4);
	}

	len = 12;

	if (count > 0) {
		GSList *list;

		for (list = prefixes; list; list = list->next) {
			GDHCPIAPrefix *prefix = list->data;
			uint8_t sub_option[4+4+1+16];

			if ((len + 2 + 2 + sizeof(sub_option)) >= max_buf) {
				debug(dhcp_client,
					"Too long dhcpv6 message "
					"when writing IA prefix option");
				return -EINVAL;
			}

			memset(&sub_option, 0, sizeof(sub_option));

			/* preferred and validity time are left zero */

			sub_option[8] = prefix->prefixlen;
			memcpy(&sub_option[9], &prefix->prefix, 16);

			copy_option(&options[len], G_DHCPV6_IA_PREFIX,
				sizeof(sub_option), sub_option);
			len += 2 + 2 + sizeof(sub_option);
		}
	}

	g_dhcpv6_client_set_send(dhcp_client, G_DHCPV6_IA_PD,
				options, len);

	return 0;
}

uint32_t g_dhcpv6_client_get_iaid(GDHCPClient *dhcp_client)
{
	if (!dhcp_client || dhcp_client->type != G_DHCP_IPV6)
		return 0;

	return dhcp_client->iaid;
}

void g_dhcpv6_client_set_iaid(GDHCPClient *dhcp_client, uint32_t iaid)
{
	if (!dhcp_client || dhcp_client->type != G_DHCP_IPV6)
		return;

	dhcp_client->iaid = iaid;
}

void g_dhcpv6_client_create_iaid(GDHCPClient *dhcp_client, int index,
				unsigned char *iaid)
{
	uint8_t buf[6];

	get_interface_mac_address(index, buf);

	memcpy(iaid, &buf[2], 4);
	dhcp_client->iaid = iaid[0] << 24 |
			iaid[1] << 16 | iaid[2] << 8 | iaid[3];
}

int g_dhcpv6_client_get_timeouts(GDHCPClient *dhcp_client,
				uint32_t *T1, uint32_t *T2,
				time_t *started,
				time_t *expire)
{
	if (!dhcp_client || dhcp_client->type != G_DHCP_IPV6)
		return -EINVAL;

	if (T1)
		*T1 = dhcp_client->T1;

	if (T2)
		*T2 = dhcp_client->T2;

	if (started)
		*started = dhcp_client->last_request;

	if (expire)
		*expire = dhcp_client->last_request + dhcp_client->expire;

	return 0;
}

static uint8_t *create_iaaddr(GDHCPClient *dhcp_client, uint8_t *buf,
				uint16_t len)
{
	buf[0] = 0;
	buf[1] = G_DHCPV6_IAADDR;
	buf[2] = 0;
	buf[3] = len;
	memcpy(&buf[4], &dhcp_client->ia_na, 16);
	memset(&buf[20], 0, 4); /* preferred */
	memset(&buf[24], 0, 4); /* valid */
	return buf;
}

static uint8_t *append_iaaddr(GDHCPClient *dhcp_client, uint8_t *buf,
			const char *address)
{
	struct in6_addr addr;

	if (inet_pton(AF_INET6, address, &addr) != 1)
		return NULL;

	buf[0] = 0;
	buf[1] = G_DHCPV6_IAADDR;
	buf[2] = 0;
	buf[3] = 24;
	memcpy(&buf[4], &addr, 16);
	memset(&buf[20], 0, 4); /* preferred */
	memset(&buf[24], 0, 4); /* valid */
	return &buf[28];
}

static void put_iaid(GDHCPClient *dhcp_client, int index, uint8_t *buf)
{
	uint32_t iaid;

	iaid = g_dhcpv6_client_get_iaid(dhcp_client);
	if (iaid == 0) {
		g_dhcpv6_client_create_iaid(dhcp_client, index, buf);
		return;
	}

	buf[0] = iaid >> 24;
	buf[1] = iaid >> 16;
	buf[2] = iaid >> 8;
	buf[3] = iaid;
}

int g_dhcpv6_client_set_ia(GDHCPClient *dhcp_client, int index,
			int code, uint32_t *T1, uint32_t *T2,
			bool add_iaaddr, const char *ia_na)
{
	if (code == G_DHCPV6_IA_TA) {
		uint8_t ia_options[4];

		put_iaid(dhcp_client, index, ia_options);

		g_dhcp_client_set_request(dhcp_client, G_DHCPV6_IA_TA);
		g_dhcpv6_client_set_send(dhcp_client, G_DHCPV6_IA_TA,
					ia_options, sizeof(ia_options));

	} else if (code == G_DHCPV6_IA_NA) {
		struct in6_addr addr;

		g_dhcp_client_set_request(dhcp_client, G_DHCPV6_IA_NA);

		/*
		 * If caller has specified the IPv6 address it wishes to
		 * to use (ia_na != NULL and address is valid), then send
		 * the address to server.
		 * If caller did not specify the address (ia_na == NULL) and
		 * if the current address is not set, then we should not send
		 * the address sub-option.
		 */
		if (add_iaaddr && ((!ia_na &&
			!IN6_IS_ADDR_UNSPECIFIED(&dhcp_client->ia_na))
			|| (ia_na &&
				inet_pton(AF_INET6, ia_na, &addr) == 1))) {
#define IAADDR_LEN (16+4+4)
			uint8_t ia_options[4+4+4+2+2+IAADDR_LEN];

			if (ia_na)
				memcpy(&dhcp_client->ia_na, &addr,
						sizeof(struct in6_addr));

			put_iaid(dhcp_client, index, ia_options);

			if (T1) {
				ia_options[4] = *T1 >> 24;
				ia_options[5] = *T1 >> 16;
				ia_options[6] = *T1 >> 8;
				ia_options[7] = *T1;
			} else
				memset(&ia_options[4], 0x00, 4);

			if (T2) {
				ia_options[8] = *T2 >> 24;
				ia_options[9] = *T2 >> 16;
				ia_options[10] = *T2 >> 8;
				ia_options[11] = *T2;
			} else
				memset(&ia_options[8], 0x00, 4);

			create_iaaddr(dhcp_client, &ia_options[12],
					IAADDR_LEN);

			g_dhcpv6_client_set_send(dhcp_client, G_DHCPV6_IA_NA,
					ia_options, sizeof(ia_options));
		} else {
			uint8_t ia_options[4+4+4];

			put_iaid(dhcp_client, index, ia_options);

			memset(&ia_options[4], 0x00, 4); /* T1 (4 bytes) */
			memset(&ia_options[8], 0x00, 4); /* T2 (4 bytes) */

			g_dhcpv6_client_set_send(dhcp_client, G_DHCPV6_IA_NA,
					ia_options, sizeof(ia_options));
		}

	} else
		return -EINVAL;

	return 0;
}

int g_dhcpv6_client_set_ias(GDHCPClient *dhcp_client, int index,
			int code, uint32_t *T1, uint32_t *T2,
			GSList *addresses)
{
	GSList *list;
	uint8_t *ia_options, *pos;
	int len, count, total_len;

	count = g_slist_length(addresses);
	if (count == 0)
		return -EINVAL;

	g_dhcp_client_set_request(dhcp_client, code);

	if (code == G_DHCPV6_IA_TA)
		len = 4;         /* IAID */
	else if (code == G_DHCPV6_IA_NA)
		len = 4 + 4 + 4; /* IAID + T1 + T2 */
	else
		return -EINVAL;

	total_len = len + count * (2 + 2 + 16 + 4 + 4);
	ia_options = g_try_malloc0(total_len);
	if (!ia_options)
		return -ENOMEM;

	put_iaid(dhcp_client, index, ia_options);

	pos = &ia_options[len]; /* skip the IA_NA or IA_TA */

	for (list = addresses; list; list = list->next) {
		pos = append_iaaddr(dhcp_client, pos, list->data);
		if (!pos)
			break;
	}

	if (code == G_DHCPV6_IA_NA) {
		if (T1) {
			ia_options[4] = *T1 >> 24;
			ia_options[5] = *T1 >> 16;
			ia_options[6] = *T1 >> 8;
			ia_options[7] = *T1;
		} else
			memset(&ia_options[4], 0x00, 4);

		if (T2) {
			ia_options[8] = *T2 >> 24;
			ia_options[9] = *T2 >> 16;
			ia_options[10] = *T2 >> 8;
			ia_options[11] = *T2;
		} else
			memset(&ia_options[8], 0x00, 4);
	}

	g_dhcpv6_client_set_send(dhcp_client, code, ia_options, total_len);

	g_free(ia_options);

	return 0;
}

int g_dhcpv6_client_set_oro(GDHCPClient *dhcp_client, int args, ...)
{
	va_list va;
	int i, j, len = sizeof(uint16_t) * args;
	uint8_t *values;

	values = g_try_malloc(len);
	if (!values)
		return -ENOMEM;

	va_start(va, args);
	for (i = 0, j = 0; i < args; i++) {
		uint16_t value = va_arg(va, int);
		values[j++] = value >> 8;
		values[j++] = value & 0xff;
	}
	va_end(va);

	g_dhcpv6_client_set_send(dhcp_client, G_DHCPV6_ORO, values, len);

	g_free(values);

	return 0;
}

static int send_dhcpv6_msg(GDHCPClient *dhcp_client, int type, char *msg)
{
	struct dhcpv6_packet *packet;
	uint8_t buf[MAX_DHCPV6_PKT_SIZE];
	unsigned char *ptr;
	int ret, max_buf;

	memset(buf, 0, sizeof(buf));
	packet = (struct dhcpv6_packet *)&buf[0];
	ptr = buf + sizeof(struct dhcpv6_packet);

	debug(dhcp_client, "sending DHCPv6 %s message", msg);

	init_packet(dhcp_client, packet, type);

	if (!dhcp_client->retransmit) {
		dhcp_client->xid = packet->transaction_id[0] << 16 |
				packet->transaction_id[1] << 8 |
				packet->transaction_id[2];
		gettimeofday(&dhcp_client->start_time, NULL);
	} else {
		packet->transaction_id[0] = dhcp_client->xid >> 16;
		packet->transaction_id[1] = dhcp_client->xid >> 8 ;
		packet->transaction_id[2] = dhcp_client->xid;
	}

	g_dhcp_client_set_request(dhcp_client, G_DHCPV6_ELAPSED_TIME);

	debug(dhcp_client, "sending DHCPv6 %s message xid 0x%04x", msg,
							dhcp_client->xid);

	max_buf = MAX_DHCPV6_PKT_SIZE - sizeof(struct dhcpv6_packet);

	add_dhcpv6_request_options(dhcp_client, packet, buf, max_buf, &ptr);

	add_dhcpv6_send_options(dhcp_client, buf, max_buf, &ptr);

	ret = dhcpv6_send_packet(dhcp_client->ifindex, packet, ptr - buf);

	debug(dhcp_client, "sent %d pkt %p len %d", ret, packet, ptr - buf);
	return ret;
}

static int send_solicitation(GDHCPClient *dhcp_client)
{
	return send_dhcpv6_msg(dhcp_client, DHCPV6_SOLICIT, "solicit");
}

static int send_dhcpv6_request(GDHCPClient *dhcp_client)
{
	return send_dhcpv6_msg(dhcp_client, DHCPV6_REQUEST, "request");
}

static int send_dhcpv6_confirm(GDHCPClient *dhcp_client)
{
	return send_dhcpv6_msg(dhcp_client, DHCPV6_CONFIRM, "confirm");
}

static int send_dhcpv6_renew(GDHCPClient *dhcp_client)
{
	return send_dhcpv6_msg(dhcp_client, DHCPV6_RENEW, "renew");
}

static int send_dhcpv6_rebind(GDHCPClient *dhcp_client)
{
	return send_dhcpv6_msg(dhcp_client, DHCPV6_REBIND, "rebind");
}

static int send_dhcpv6_decline(GDHCPClient *dhcp_client)
{
	return send_dhcpv6_msg(dhcp_client, DHCPV6_DECLINE, "decline");
}

static int send_dhcpv6_release(GDHCPClient *dhcp_client)
{
	return send_dhcpv6_msg(dhcp_client, DHCPV6_RELEASE, "release");
}

static int send_information_req(GDHCPClient *dhcp_client)
{
	return send_dhcpv6_msg(dhcp_client, DHCPV6_INFORMATION_REQ,
				"information-req");
}

static void remove_value(gpointer data, gpointer user_data)
{
	char *value = data;
	g_free(value);
}

static void remove_option_value(gpointer data)
{
	GList *option_value = data;

	g_list_foreach(option_value, remove_value, NULL);
	g_list_free(option_value);
}

GDHCPClient *g_dhcp_client_new(GDHCPType type,
			int ifindex, GDHCPClientError *error)
{
	GDHCPClient *dhcp_client;

	if (ifindex < 0) {
		*error = G_DHCP_CLIENT_ERROR_INVALID_INDEX;
		return NULL;
	}

	dhcp_client = g_try_new0(GDHCPClient, 1);
	if (!dhcp_client) {
		*error = G_DHCP_CLIENT_ERROR_NOMEM;
		return NULL;
	}

	dhcp_client->interface = get_interface_name(ifindex);
	if (!dhcp_client->interface) {
		*error = G_DHCP_CLIENT_ERROR_INTERFACE_UNAVAILABLE;
		goto error;
	}

	if (!interface_is_up(ifindex)) {
		*error = G_DHCP_CLIENT_ERROR_INTERFACE_DOWN;
		goto error;
	}

	get_interface_mac_address(ifindex, dhcp_client->mac_address);

	dhcp_client->listener_sockfd = -1;
	dhcp_client->listen_mode = L_NONE;
	dhcp_client->ref_count = 1;
	dhcp_client->type = type;
	dhcp_client->ifindex = ifindex;
	dhcp_client->lease_available_cb = NULL;
	dhcp_client->ipv4ll_available_cb = NULL;
	dhcp_client->no_lease_cb = NULL;
	dhcp_client->lease_lost_cb = NULL;
	dhcp_client->ipv4ll_lost_cb = NULL;
	dhcp_client->address_conflict_cb = NULL;
	dhcp_client->listener_watch = 0;
	dhcp_client->retry_times = 0;
	dhcp_client->ack_retry_times = 0;
	dhcp_client->code_value_hash = g_hash_table_new_full(g_direct_hash,
				g_direct_equal, NULL, remove_option_value);
	dhcp_client->send_value_hash = g_hash_table_new_full(g_direct_hash,
				g_direct_equal, NULL, g_free);
	dhcp_client->request_list = NULL;
	dhcp_client->require_list = NULL;
	dhcp_client->duid = NULL;
	dhcp_client->duid_len = 0;
	dhcp_client->last_request = time(NULL);
	dhcp_client->expire = 0;
	dhcp_client->request_bcast = false;

	*error = G_DHCP_CLIENT_ERROR_NONE;

	return dhcp_client;

error:
	g_free(dhcp_client->interface);
	g_free(dhcp_client);
	return NULL;
}

#define SERVER_AND_CLIENT_PORTS  ((67 << 16) + 68)

static int dhcp_l2_socket(int ifindex)
{
	int fd;
	struct sockaddr_ll sock;

	/*
	 * Comment:
	 *
	 *	I've selected not to see LL header, so BPF doesn't see it, too.
	 *	The filter may also pass non-IP and non-ARP packets, but we do
	 *	a more complete check when receiving the message in userspace.
	 *
	 * and filter shamelessly stolen from:
	 *
	 *	http://www.flamewarmaster.de/software/dhcpclient/
	 *
	 * There are a few other interesting ideas on that page (look under
	 * "Motivation").  Use of netlink events is most interesting.  Think
	 * of various network servers listening for events and reconfiguring.
	 * That would obsolete sending HUP signals and/or make use of restarts.
	 *
	 * Copyright: 2006, 2007 Stefan Rompf <sux@loplof.de>.
	 * License: GPL v2.
	 *
	 * TODO: make conditional?
	 */
	static const struct sock_filter filter_instr[] = {
		/* check for udp */
		BPF_STMT(BPF_LD|BPF_B|BPF_ABS, 9),
		/* L5, L1, is UDP? */
		BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, IPPROTO_UDP, 2, 0),
		/* ugly check for arp on ethernet-like and IPv4 */
		BPF_STMT(BPF_LD|BPF_W|BPF_ABS, 2), /* L1: */
		BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, 0x08000604, 3, 4),/* L3, L4 */
		/* skip IP header */
		BPF_STMT(BPF_LDX|BPF_B|BPF_MSH, 0), /* L5: */
		/* check udp source and destination ports */
		BPF_STMT(BPF_LD|BPF_W|BPF_IND, 0),
		/* L3, L4 */
		BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, SERVER_AND_CLIENT_PORTS, 0, 1),
		/* returns */
		BPF_STMT(BPF_RET|BPF_K, 0x0fffffff), /* L3: pass */
		BPF_STMT(BPF_RET|BPF_K, 0), /* L4: reject */
	};

	static const struct sock_fprog filter_prog = {
		.len = sizeof(filter_instr) / sizeof(filter_instr[0]),
		/* casting const away: */
		.filter = (struct sock_filter *) filter_instr,
	};

	fd = socket(PF_PACKET, SOCK_DGRAM | SOCK_CLOEXEC, htons(ETH_P_IP));
	if (fd < 0)
		return -errno;

	if (SERVER_PORT == 67 && CLIENT_PORT == 68)
		/* Use only if standard ports are in use */
		setsockopt(fd, SOL_SOCKET, SO_ATTACH_FILTER, &filter_prog,
							sizeof(filter_prog));

	memset(&sock, 0, sizeof(sock));
	sock.sll_family = AF_PACKET;
	sock.sll_protocol = htons(ETH_P_IP);
	sock.sll_ifindex = ifindex;

	if (bind(fd, (struct sockaddr *) &sock, sizeof(sock)) != 0) {
		int err = -errno;
		close(fd);
		return err;
	}

	return fd;
}

static bool sanity_check(struct ip_udp_dhcp_packet *packet, int bytes)
{
	if (packet->ip.protocol != IPPROTO_UDP)
		return false;

	if (packet->ip.version != IPVERSION)
		return false;

	if (packet->ip.ihl != sizeof(packet->ip) >> 2)
		return false;

	if (packet->udp.dest != htons(CLIENT_PORT))
		return false;

	if (ntohs(packet->udp.len) != (uint16_t)(bytes - sizeof(packet->ip)))
		return false;

	return true;
}

static int dhcp_recv_l2_packet(struct dhcp_packet *dhcp_pkt, int fd,
				struct sockaddr_in *dst_addr)
{
	int bytes;
	struct ip_udp_dhcp_packet packet;
	uint16_t check;

	memset(&packet, 0, sizeof(packet));

	bytes = read(fd, &packet, sizeof(packet));
	if (bytes < 0)
		return -1;

	if (bytes < (int) (sizeof(packet.ip) + sizeof(packet.udp)))
		return -1;

	if (bytes < ntohs(packet.ip.tot_len))
		/* packet is bigger than sizeof(packet), we did partial read */
		return -1;

	/* ignore any extra garbage bytes */
	bytes = ntohs(packet.ip.tot_len);

	if (!sanity_check(&packet, bytes))
		return -1;

	check = packet.ip.check;
	packet.ip.check = 0;
	if (check != dhcp_checksum(&packet.ip, sizeof(packet.ip)))
		return -1;

	/* verify UDP checksum. IP header has to be modified for this */
	memset(&packet.ip, 0, offsetof(struct iphdr, protocol));
	/* ip.xx fields which are not memset: protocol, check, saddr, daddr */
	packet.ip.tot_len = packet.udp.len; /* yes, this is needed */
	check = packet.udp.check;
	packet.udp.check = 0;
	if (check && check != dhcp_checksum(&packet, bytes))
		return -1;

	memcpy(dhcp_pkt, &packet.data, bytes - (sizeof(packet.ip) +
							sizeof(packet.udp)));

	if (dhcp_pkt->cookie != htonl(DHCP_MAGIC))
		return -1;

	dst_addr->sin_addr.s_addr = packet.ip.daddr;

	return bytes - (sizeof(packet.ip) + sizeof(packet.udp));
}

static void ipv4ll_start(GDHCPClient *dhcp_client)
{
	guint timeout;

	remove_timeouts(dhcp_client);

	switch_listening_mode(dhcp_client, L_NONE);
	dhcp_client->retry_times = 0;
	dhcp_client->requested_ip = 0;

	dhcp_client->requested_ip = ipv4ll_random_ip();

	/*first wait a random delay to avoid storm of arp request on boot*/
	timeout = ipv4ll_random_delay_ms(PROBE_WAIT);

	dhcp_client->retry_times++;
	dhcp_client->timeout = g_rttimeout_add_full(CLOCK_BOOTTIME_ALARM, G_PRIORITY_HIGH,
						timeout,
						send_probe_packet,
						dhcp_client,
						NULL);
}

static void ipv4ll_stop(GDHCPClient *dhcp_client)
{

	switch_listening_mode(dhcp_client, L_NONE);

	remove_timeouts(dhcp_client);

	if (dhcp_client->listener_watch > 0) {
		g_source_remove(dhcp_client->listener_watch);
		dhcp_client->listener_watch = 0;
	}

	dhcp_client->state = IPV4LL_PROBE;
	dhcp_client->retry_times = 0;
	dhcp_client->requested_ip = 0;

	g_free(dhcp_client->assigned_ip);
	dhcp_client->assigned_ip = NULL;
}

static int ipv4ll_recv_arp_packet(GDHCPClient *dhcp_client)
{
	int bytes;
	struct ether_arp arp;
	uint32_t ip_requested;
	int source_conflict;
	int target_conflict;

	memset(&arp, 0, sizeof(arp));
	bytes = read(dhcp_client->listener_sockfd, &arp, sizeof(arp));
	if (bytes < 0)
		return bytes;

	if (arp.arp_op != htons(ARPOP_REPLY) &&
			arp.arp_op != htons(ARPOP_REQUEST))
		return -EINVAL;

	ip_requested = htonl(dhcp_client->requested_ip);
	source_conflict = !memcmp(arp.arp_spa, &ip_requested,
						sizeof(ip_requested));

	target_conflict = !memcmp(arp.arp_tpa, &ip_requested,
				sizeof(ip_requested));

	if (!source_conflict && !target_conflict)
		return 0;

	dhcp_client->conflicts++;

	debug(dhcp_client, "IPV4LL conflict detected");

	if (dhcp_client->state == IPV4LL_MONITOR) {
		if (!source_conflict)
			return 0;
		dhcp_client->state = IPV4LL_DEFEND;
		debug(dhcp_client, "DEFEND mode conflicts : %d",
			dhcp_client->conflicts);
		/*Try to defend with a single announce*/
		send_announce_packet(dhcp_client);
		return 0;
	}

	if (dhcp_client->state == IPV4LL_DEFEND) {
		if (!source_conflict)
			return 0;
		else if (dhcp_client->ipv4ll_lost_cb)
			dhcp_client->ipv4ll_lost_cb(dhcp_client,
						dhcp_client->ipv4ll_lost_data);
	}

	ipv4ll_stop(dhcp_client);

	if (dhcp_client->conflicts < MAX_CONFLICTS) {
		/*restart whole state machine*/
		dhcp_client->retry_times++;
		dhcp_client->timeout =
			g_rttimeout_add_full(CLOCK_BOOTTIME_ALARM, G_PRIORITY_HIGH,
					ipv4ll_random_delay_ms(PROBE_WAIT),
					send_probe_packet,
					dhcp_client,
					NULL);
	}
	/* Here we got a lot of conflicts, RFC3927 states that we have
	 * to wait RATE_LIMIT_INTERVAL before retrying,
	 * but we just report failure.
	 */
	else if (dhcp_client->no_lease_cb)
			dhcp_client->no_lease_cb(dhcp_client,
						dhcp_client->no_lease_data);

	return 0;
}

static bool check_package_owner(GDHCPClient *dhcp_client, gpointer pkt)
{
	if (dhcp_client->type == G_DHCP_IPV6) {
		struct dhcpv6_packet *packet6 = pkt;
		uint32_t xid;

		if (!packet6)
			return false;

		xid = packet6->transaction_id[0] << 16 |
			packet6->transaction_id[1] << 8 |
			packet6->transaction_id[2];

		if (xid != dhcp_client->xid)
			return false;
	} else {
		struct dhcp_packet *packet = pkt;

		if (packet->xid != dhcp_client->xid)
			return false;

		if (packet->hlen != 6)
			return false;

		if (memcmp(packet->chaddr, dhcp_client->mac_address, 6))
			return false;
	}

	return true;
}

static void start_request(GDHCPClient *dhcp_client);

static gboolean request_timeout(gpointer user_data)
{
	GDHCPClient *dhcp_client = user_data;

	debug(dhcp_client, "request timeout (retries %d)",
					dhcp_client->retry_times);

	dhcp_client->retry_times++;

	start_request(dhcp_client);

	return FALSE;
}

static gboolean listener_event(GIOChannel *channel, GIOCondition condition,
							gpointer user_data);

static int switch_listening_mode(GDHCPClient *dhcp_client,
					ListenMode listen_mode)
{
	GIOChannel *listener_channel;
	int listener_sockfd;

	if (dhcp_client->listen_mode == listen_mode)
		return 0;

	debug(dhcp_client, "switch listening mode (%d ==> %d)",
				dhcp_client->listen_mode, listen_mode);

	if (dhcp_client->listen_mode != L_NONE) {
		if (dhcp_client->listener_watch > 0)
			g_source_remove(dhcp_client->listener_watch);
		dhcp_client->listen_mode = L_NONE;
		dhcp_client->listener_sockfd = -1;
		dhcp_client->listener_watch = 0;
	}

	if (listen_mode == L_NONE)
		return 0;

	if (listen_mode == L2)
		listener_sockfd = dhcp_l2_socket(dhcp_client->ifindex);
	else if (listen_mode == L3) {
		if (dhcp_client->type == G_DHCP_IPV6)
			listener_sockfd = dhcp_l3_socket(DHCPV6_CLIENT_PORT,
							dhcp_client->interface,
							AF_INET6);
		else
			listener_sockfd = dhcp_l3_socket(CLIENT_PORT,
							dhcp_client->interface,
							AF_INET);
	} else if (listen_mode == L_ARP)
		listener_sockfd = ipv4ll_arp_socket(dhcp_client->ifindex);
	else
		return -EIO;

	if (listener_sockfd < 0)
		return -EIO;

	listener_channel = g_io_channel_unix_new(listener_sockfd);
	if (!listener_channel) {
		/* Failed to create listener channel */
		close(listener_sockfd);
		return -EIO;
	}

	dhcp_client->listen_mode = listen_mode;
	dhcp_client->listener_sockfd = listener_sockfd;

	g_io_channel_set_close_on_unref(listener_channel, TRUE);
	dhcp_client->listener_watch =
			g_io_add_watch_full(listener_channel, G_PRIORITY_HIGH,
				G_IO_IN | G_IO_NVAL | G_IO_ERR | G_IO_HUP,
						listener_event, dhcp_client,
								NULL);
	g_io_channel_unref(listener_channel);

	return 0;
}

static void start_request(GDHCPClient *dhcp_client)
{
	debug(dhcp_client, "start request (retries %d)",
					dhcp_client->retry_times);

	if (dhcp_client->retry_times == REQUEST_RETRIES) {
		if (dhcp_client->no_lease_cb)
			dhcp_client->no_lease_cb(dhcp_client,
						dhcp_client->no_lease_data);
		return;
	}

	if (dhcp_client->retry_times == 0) {
		dhcp_client->state = REQUESTING;
		switch_listening_mode(dhcp_client, L2);
	}

	send_request(dhcp_client);

	dhcp_client->timeout = g_rttimeout_add_seconds_full(CLOCK_BOOTTIME_ALARM, G_PRIORITY_HIGH,
							REQUEST_TIMEOUT,
							request_timeout,
							dhcp_client,
							NULL);
}
#define MINIMUM_LEASE_DURATION 3600
#define MAXIMUM_LEASE_DURATION 30*24*60*60
static uint32_t get_lease(GDHCPClient *dhcp_client, struct dhcp_packet *packet)
{
	uint8_t *option;
	uint32_t lease_seconds;

	option = dhcp_get_option(packet, DHCP_LEASE_TIME);
	if (!option)
		return 3600;

	lease_seconds = get_be32(option);
	if (lease_seconds < MINIMUM_LEASE_DURATION)
	{
		debug(dhcp_client, "actual lease %d, new lease %d", lease_seconds, MINIMUM_LEASE_DURATION);
		lease_seconds = MINIMUM_LEASE_DURATION;
	}

	if (lease_seconds > MAXIMUM_LEASE_DURATION)
	{
		debug(dhcp_client, "actual lease %d, new lease %d", lease_seconds, MAXIMUM_LEASE_DURATION);
		lease_seconds = MAXIMUM_LEASE_DURATION;
	}

	return lease_seconds;
}

static void restart_dhcp(GDHCPClient *dhcp_client, int retry_times)
{
	debug(dhcp_client, "restart DHCP (retries %d)", retry_times);

	remove_timeouts(dhcp_client);

	dhcp_client->retry_times = retry_times;
	dhcp_client->requested_ip = 0;
	dhcp_client->state = INIT_SELECTING;
	switch_listening_mode(dhcp_client, L2);

	g_dhcp_client_start(dhcp_client, dhcp_client->last_address);
}

static gboolean start_expire(gpointer user_data)
{
	GDHCPClient *dhcp_client = user_data;

	debug(dhcp_client, "lease expired");

	/*remove all timeouts if they are set*/
	remove_timeouts(dhcp_client);

	restart_dhcp(dhcp_client, 0);

	/* ip need to be cleared */
	if (dhcp_client->lease_lost_cb)
		dhcp_client->lease_lost_cb(dhcp_client,
				dhcp_client->lease_lost_data);

	return false;
}

static gboolean continue_rebound(gpointer user_data)
{
	GDHCPClient *dhcp_client = user_data;
	uint64_t rand;

	switch_listening_mode(dhcp_client, L2);
	send_request(dhcp_client);

	if (dhcp_client->t2_timeout> 0)
		g_source_remove(dhcp_client->t2_timeout);

	/*recalculate remaining rebind time*/
	dhcp_client->T2 >>= 1;
	if (dhcp_client->T2 > 60) {
		dhcp_get_random(&rand);
		dhcp_client->t2_timeout =
			g_rttimeout_add_full(CLOCK_BOOTTIME_ALARM, G_PRIORITY_HIGH,
					dhcp_client->T2 * 1000 + (rand % 2000) - 1000,
					continue_rebound,
					dhcp_client,
					NULL);
	}
	set_wake(dhcp_client, REQUEST_TIMEOUT);

	return FALSE;
}

static gboolean start_rebound(gpointer user_data)
{
	GDHCPClient *dhcp_client = user_data;

	/*remove renew timer*/
	if (dhcp_client->t1_timeout > 0)
		g_source_remove(dhcp_client->t1_timeout);

	debug(dhcp_client, "start rebound");
	dhcp_client->state = REBINDING;

	/*calculate total rebind time*/
	dhcp_client->T2 = dhcp_client->expire - dhcp_client->T2;

	/*send the first rebound and reschedule*/
	continue_rebound(user_data);

	return FALSE;
}

static gboolean continue_renew (gpointer user_data)
{
	GDHCPClient *dhcp_client = user_data;
	uint64_t rand;

	switch_listening_mode(dhcp_client, L3);
	send_request(dhcp_client);

	if (dhcp_client->t1_timeout > 0)
		g_source_remove(dhcp_client->t1_timeout);

	dhcp_client->t1_timeout = 0;

	dhcp_client->T1 >>= 1;

	if (dhcp_client->T1 > 60) {
		dhcp_get_random(&rand);
		dhcp_client->t1_timeout = g_rttimeout_add_full(CLOCK_BOOTTIME_ALARM, G_PRIORITY_HIGH,
				dhcp_client->T1 * 1000 + (rand % 2000) - 1000,
				continue_renew,
				dhcp_client,
				NULL);
	}
	set_wake(dhcp_client, REQUEST_TIMEOUT);

	return FALSE;
}
static gboolean start_renew(gpointer user_data)
{
	GDHCPClient *dhcp_client = user_data;

	debug(dhcp_client, "start renew");
	dhcp_client->state = RENEWING;

	/*calculate total renew period*/
	dhcp_client->T1 = dhcp_client->T2 - dhcp_client->T1;

	/*send first renew and reschedule for half the remaining time.*/
	continue_renew(user_data);

	return FALSE;
}

static void start_bound(GDHCPClient *dhcp_client)
{
	debug(dhcp_client, "bound to %s -- renewal in %ld seconds.",
	      dhcp_client->assigned_ip,
	      dhcp_client->lease_seconds);

	dhcp_client->state = BOUND;

	remove_timeouts(dhcp_client);

	/*
	 *TODO: T1 and T2 should be set through options instead of
	 * defaults as they are here.
	 */

	dhcp_client->T1 = dhcp_client->lease_seconds >> 1;
	dhcp_client->T2 = dhcp_client->lease_seconds * 0.875;
	dhcp_client->expire = dhcp_client->lease_seconds;

        dhcp_client->t1_timeout = g_rttimeout_add_seconds_full(CLOCK_BOOTTIME_ALARM,
                                                               G_PRIORITY_HIGH,
                                                               dhcp_client->T1,
                                                               start_renew, dhcp_client,
                                                               NULL);

        dhcp_client->t2_timeout = g_rttimeout_add_seconds_full(CLOCK_BOOTTIME_ALARM, G_PRIORITY_HIGH,
                                        dhcp_client->T2,
                                        start_rebound, dhcp_client,
                                                        NULL);

        dhcp_client->lease_timeout= g_rttimeout_add_seconds_full(CLOCK_BOOTTIME_ALARM, G_PRIORITY_HIGH,
                                        dhcp_client->expire,
                                        start_expire, dhcp_client,
                                                        NULL);
	release_wake(dhcp_client, dhcp_client->T1);
}

static gboolean restart_dhcp_timeout(gpointer user_data)
{
	GDHCPClient *dhcp_client = user_data;

	debug(dhcp_client, "restart DHCP timeout");

	if (dhcp_client->state == REBOOTING) {
		g_free(dhcp_client->last_address);
		dhcp_client->last_address = NULL;
		restart_dhcp(dhcp_client, 0);
	} else {
		dhcp_client->ack_retry_times++;
		restart_dhcp(dhcp_client, dhcp_client->ack_retry_times);
	}
	return FALSE;
}

static char *get_ip(uint32_t ip)
{
	struct in_addr addr;

	addr.s_addr = ip;

	return g_strdup(inet_ntoa(addr));
}

/* get a rough idea of how long an option will be */
static const uint8_t len_of_option_as_string[] = {
	[OPTION_IP] = sizeof("255.255.255.255 "),
	[OPTION_STRING] = 1,
	[OPTION_U8] = sizeof("255 "),
	[OPTION_U16] = sizeof("65535 "),
	[OPTION_U32] = sizeof("4294967295 "),
};

static int sprint_nip(char *dest, const char *pre, const uint8_t *ip)
{
	return sprintf(dest, "%s%u.%u.%u.%u", pre, ip[0], ip[1], ip[2], ip[3]);
}

/* Create "opt_value1 option_value2 ..." string */
static char *malloc_option_value_string(uint8_t *option, GDHCPOptionType type)
{
	unsigned upper_length;
	int len, optlen;
	char *dest, *ret;

	len = option[OPT_LEN - OPT_DATA];
	type &= OPTION_TYPE_MASK;
	optlen = dhcp_option_lengths[type];
	if (optlen == 0)
		return NULL;
	upper_length = len_of_option_as_string[type] *
			((unsigned)len / (unsigned)optlen);
	dest = ret = g_malloc(upper_length + 1);
	if (!ret)
		return NULL;

	while (len >= optlen) {
		switch (type) {
		case OPTION_IP:
			dest += sprint_nip(dest, "", option);
			break;
		case OPTION_U16: {
			uint16_t val_u16 = get_be16(option);
			dest += sprintf(dest, "%u", val_u16);
			break;
		}
		case OPTION_U32: {
			uint32_t val_u32 = get_be32(option);
			dest += sprintf(dest, "%u", val_u32);
			break;
		}
		case OPTION_STRING:
			memcpy(dest, option, len);
			dest[len] = '\0';
			return ret;
		default:
			break;
		}
		option += optlen;
		len -= optlen;
		if (len <= 0)
			break;
		*dest++ = ' ';
		*dest = '\0';
	}

	return ret;
}

static GList *get_option_value_list(char *value, GDHCPOptionType type)
{
	char *pos = value;
	GList *list = NULL;

	if (!pos)
		return NULL;

	if (type == OPTION_STRING)
		return g_list_append(list, g_strdup(value));

	while ((pos = strchr(pos, ' '))) {
		*pos = '\0';

		list = g_list_append(list, g_strdup(value));

		value = ++pos;
	}

	list = g_list_append(list, g_strdup(value));

	return list;
}

static inline uint32_t get_uint32(unsigned char *value)
{
	return value[0] << 24 | value[1] << 16 |
		value[2] << 8 | value[3];
}

static inline uint16_t get_uint16(unsigned char *value)
{
	return value[0] << 8 | value[1];
}

static GList *add_prefix(GDHCPClient *dhcp_client, GList *list,
			struct in6_addr *addr,
			unsigned char prefixlen, uint32_t preferred,
			uint32_t valid)
{
	GDHCPIAPrefix *ia_prefix;

	ia_prefix = g_try_new(GDHCPIAPrefix, 1);
	if (!ia_prefix)
		return list;

	if (dhcp_client->debug_func) {
		char addr_str[INET6_ADDRSTRLEN + 1];
		inet_ntop(AF_INET6, addr, addr_str, INET6_ADDRSTRLEN);
		debug(dhcp_client, "prefix %s/%d preferred %u valid %u",
			addr_str, prefixlen, preferred, valid);
	}

	memcpy(&ia_prefix->prefix, addr, sizeof(struct in6_addr));
	ia_prefix->prefixlen = prefixlen;
	ia_prefix->preferred = preferred;
	ia_prefix->valid = valid;
	ia_prefix->expire = time(NULL) + valid;

	return g_list_prepend(list, ia_prefix);
}

static GList *get_addresses(GDHCPClient *dhcp_client,
				int code, int len,
				unsigned char *value,
				uint16_t *status)
{
	GList *list = NULL;
	struct in6_addr addr;
	uint32_t iaid, T1 = 0, T2 = 0, preferred = 0, valid = 0;
	uint16_t option_len, option_code, st = 0, max_len;
	int addr_count = 0, prefix_count = 0, i, pos;
	unsigned char prefixlen;
	unsigned int shortest_valid = 0;
	uint8_t *option;
	char *str;

	if (!value || len < 4)
		return NULL;

	iaid = get_uint32(&value[0]);
	if (dhcp_client->iaid != iaid)
		return NULL;

	if (code == G_DHCPV6_IA_NA || code == G_DHCPV6_IA_PD) {
		T1 = get_uint32(&value[4]);
		T2 = get_uint32(&value[8]);

		if (T1 > T2)
			/* IA_NA: RFC 3315, 22.4 */
			/* IA_PD: RFC 3633, ch 9 */
			return NULL;

		pos = 12;
	} else
		pos = 4;

	if (len <= pos)
		return NULL;

	max_len = len - pos;

	debug(dhcp_client, "header %d sub-option max len %d", pos, max_len);

	/* We have more sub-options in this packet. */
	do {
		option = dhcpv6_get_sub_option(&value[pos], max_len,
					&option_code, &option_len);

		debug(dhcp_client, "pos %d option %p code %d len %d",
			pos, option, option_code, option_len);

		if (!option)
			break;

		if (pos >= len)
			break;

		switch (option_code) {
		case G_DHCPV6_IAADDR:
			i = 0;
			memcpy(&addr, &option[0], sizeof(addr));
			i += sizeof(addr);
			preferred = get_uint32(&option[i]);
			i += 4;
			valid = get_uint32(&option[i]);

			addr_count++;
			break;

		case G_DHCPV6_STATUS_CODE:
			st = get_uint16(&option[0]);
			debug(dhcp_client, "error code %d", st);
			if (option_len > 2) {
				str = g_strndup((gchar *)&option[2],
						option_len - 2);
				debug(dhcp_client, "error text: %s", str);
				g_free(str);
			}

			*status = st;
			break;

		case G_DHCPV6_IA_PREFIX:
			i = 0;
			preferred = get_uint32(&option[i]);
			i += 4;
			valid = get_uint32(&option[i]);
			i += 4;
			prefixlen = option[i];
			i += 1;
			memcpy(&addr, &option[i], sizeof(addr));
			i += sizeof(addr);
			if (preferred < valid) {
				/* RFC 3633, ch 10 */
				list = add_prefix(dhcp_client, list, &addr,
						prefixlen, preferred, valid);
				if (shortest_valid > valid)
					shortest_valid = valid;
				prefix_count++;
			}
			break;
		}

		pos += 2 + 2 + option_len;

	} while (pos < len);

	if (addr_count > 0 && st == 0) {
		/* We only support one address atm */
		char addr_str[INET6_ADDRSTRLEN + 1];

		if (preferred > valid)
			/* RFC 3315, 22.6 */
			return NULL;

		dhcp_client->T1 = T1;
		dhcp_client->T2 = T2;

		inet_ntop(AF_INET6, &addr, addr_str, INET6_ADDRSTRLEN);
		debug(dhcp_client, "address count %d addr %s T1 %u T2 %u",
			addr_count, addr_str, T1, T2);

		list = g_list_append(list, g_strdup(addr_str));

		if (code == G_DHCPV6_IA_NA)
			memcpy(&dhcp_client->ia_na, &addr,
						sizeof(struct in6_addr));
		else
			memcpy(&dhcp_client->ia_ta, &addr,
						sizeof(struct in6_addr));

		if (valid != dhcp_client->expire)
			dhcp_client->expire = valid;
	}

	if (prefix_count > 0 && list) {
		/*
		 * This means we have a list of prefixes to delegate.
		 */
		list = g_list_reverse(list);

		debug(dhcp_client, "prefix count %d T1 %u T2 %u",
			prefix_count, T1, T2);

		dhcp_client->T1 = T1;
		dhcp_client->T2 = T2;

		dhcp_client->expire = shortest_valid;
	}

	if (status && *status != 0)
		debug(dhcp_client, "status %d", *status);

	return list;
}

static GList *get_domains(int maxlen, unsigned char *value)

{
	GList *list = NULL;
	int pos = 0;
	unsigned char *c;
	char dns_name[NS_MAXDNAME + 1];

	if (!value || maxlen < 3)
		return NULL;

	while (pos < maxlen) {
		strncpy(dns_name, (char *)&value[pos], NS_MAXDNAME);

		c = (unsigned char *)dns_name;
		while (c && *c) {
			int jump;
			jump = *c;
			*c = '.';
			c += jump + 1;
		}
		list = g_list_prepend(list, g_strdup(&dns_name[1]));
		pos += (char *)c - dns_name + 1;
	}

	return g_list_reverse(list);
}

static GList *get_dhcpv6_option_value_list(GDHCPClient *dhcp_client,
					int code, int len,
					unsigned char *value,
					uint16_t *status)
{
	GList *list = NULL;
	char *str;
	int i;

	if (!value)
		return NULL;

	switch (code) {
	case G_DHCPV6_DNS_SERVERS:	/* RFC 3646, chapter 3 */
	case G_DHCPV6_SNTP_SERVERS:	/* RFC 4075, chapter 4 */
		if (len % 16) {
			debug(dhcp_client,
				"%s server list length (%d) is invalid",
				code == G_DHCPV6_DNS_SERVERS ? "DNS" : "SNTP",
				len);
			return NULL;
		}
		for (i = 0; i < len; i += 16) {

			str = g_try_malloc0(INET6_ADDRSTRLEN+1);
			if (!str)
				return list;

			if (!inet_ntop(AF_INET6, &value[i], str,
					INET6_ADDRSTRLEN))
				g_free(str);
			else
				list = g_list_append(list, str);
		}
		break;

	case G_DHCPV6_IA_NA:		/* RFC 3315, chapter 22.4 */
	case G_DHCPV6_IA_TA:		/* RFC 3315, chapter 22.5 */
	case G_DHCPV6_IA_PD:		/* RFC 3633, chapter 9 */
		list = get_addresses(dhcp_client, code, len, value, status);
		break;

	case G_DHCPV6_DOMAIN_LIST:
		list = get_domains(len, value);
		break;

	default:
		break;
	}

	return list;
}

static void get_dhcpv6_request(GDHCPClient *dhcp_client,
				struct dhcpv6_packet *packet,
				uint16_t pkt_len, uint16_t *status)
{
	GList *list, *value_list;
	uint8_t *option;
	uint16_t code;
	uint16_t option_len;

	for (list = dhcp_client->request_list; list; list = list->next) {
		code = (uint16_t) GPOINTER_TO_INT(list->data);

		option = dhcpv6_get_option(packet, pkt_len, code, &option_len,
						NULL);
		if (!option) {
			g_hash_table_remove(dhcp_client->code_value_hash,
						GINT_TO_POINTER((int) code));
			continue;
		}

		value_list = get_dhcpv6_option_value_list(dhcp_client, code,
						option_len, option, status);

		debug(dhcp_client, "code %d %p len %d list %p", code, option,
			option_len, value_list);

		if (!value_list)
			g_hash_table_remove(dhcp_client->code_value_hash,
						GINT_TO_POINTER((int) code));
		else
			g_hash_table_insert(dhcp_client->code_value_hash,
				GINT_TO_POINTER((int) code), value_list);
	}
}

static void get_request(GDHCPClient *dhcp_client, struct dhcp_packet *packet)
{
	GDHCPOptionType type;
	GList *list, *value_list;
	char *option_value;
	uint8_t *option;
	uint8_t code;

	for (list = dhcp_client->request_list; list; list = list->next) {
		code = (uint8_t) GPOINTER_TO_INT(list->data);

		option = dhcp_get_option(packet, code);
		if (!option) {
			g_hash_table_remove(dhcp_client->code_value_hash,
						GINT_TO_POINTER((int) code));
			continue;
		}

		type =  dhcp_get_code_type(code);

		option_value = malloc_option_value_string(option, type);
		if (!option_value)
			g_hash_table_remove(dhcp_client->code_value_hash,
						GINT_TO_POINTER((int) code));

		value_list = get_option_value_list(option_value, type);

		g_free(option_value);

		if (!value_list)
			g_hash_table_remove(dhcp_client->code_value_hash,
						GINT_TO_POINTER((int) code));
		else
			g_hash_table_insert(dhcp_client->code_value_hash,
				GINT_TO_POINTER((int) code), value_list);
	}
}

static gboolean listener_event(GIOChannel *channel, GIOCondition condition,
							gpointer user_data)
{
	GDHCPClient *dhcp_client = user_data;
	struct sockaddr_in dst_addr = { 0 };
	struct dhcp_packet packet;
	struct dhcpv6_packet *packet6 = NULL;
	uint8_t *message_type = NULL, *client_id = NULL, *option,
		*server_id = NULL;
	uint16_t option_len = 0, status = 0;
    uint32_t xid = 0;
    gpointer pkt;
	unsigned char buf[MAX_DHCPV6_PKT_SIZE];
	uint16_t pkt_len = 0;
	int count;
	int re;
	const char *p = NULL;
	struct in_addr server, request;
	char serverbuf[INET_ADDRSTRLEN], requestbuf[INET_ADDRSTRLEN];

	if (condition & (G_IO_NVAL | G_IO_ERR | G_IO_HUP)) {
		dhcp_client->listener_watch = 0;
		return FALSE;
	}

	if (dhcp_client->listen_mode == L_NONE)
		return FALSE;

	pkt = &packet;

	dhcp_client->status_code = 0;

	if (dhcp_client->listen_mode == L2) {
		re = dhcp_recv_l2_packet(&packet,
					dhcp_client->listener_sockfd,
					&dst_addr);
		xid = packet.xid;
	} else if (dhcp_client->listen_mode == L3) {
		if (dhcp_client->type == G_DHCP_IPV6) {
			re = dhcpv6_recv_l3_packet(&packet6, buf, sizeof(buf),
						dhcp_client->listener_sockfd);
			pkt_len = re;
			pkt = packet6;
			xid = packet6->transaction_id[0] << 16 |
			packet6->transaction_id[1] << 8 |
			packet6->transaction_id[2];

		} else {
			re = dhcp_recv_l3_packet(&packet,
						dhcp_client->listener_sockfd);
			xid = packet.xid;
		}
	} else if (dhcp_client->listen_mode == L_ARP) {
		ipv4ll_recv_arp_packet(dhcp_client);
		return TRUE;
	} else
		re = -EIO;

	if (re < 0)
		return TRUE;

	if (!check_package_owner(dhcp_client, pkt))
		return TRUE;

	if (dhcp_client->type == G_DHCP_IPV6) {
		if (!packet6)
			return TRUE;

		count = 0;
		client_id = dhcpv6_get_option(packet6, pkt_len,
				G_DHCPV6_CLIENTID, &option_len,	&count);

		if (!client_id || count == 0 || option_len == 0 ||
				memcmp(dhcp_client->duid, client_id,
					dhcp_client->duid_len) != 0) {
			debug(dhcp_client,
				"client duid error, discarding msg %p/%d/%d",
				client_id, option_len, count);
			return TRUE;
		}

		option = dhcpv6_get_option(packet6, pkt_len,
				G_DHCPV6_STATUS_CODE, &option_len, NULL);
		if (option != 0 && option_len > 0) {
			status = option[0]<<8 | option[1];
			if (status != 0) {
				debug(dhcp_client, "error code %d", status);
				if (option_len > 2) {
					gchar *txt = g_strndup(
						(gchar *)&option[2],
						option_len - 2);
					debug(dhcp_client, "error text: %s",
						txt);
					g_free(txt);
				}
			}
			dhcp_client->status_code = status;
		}
	} else {
		message_type = dhcp_get_option(&packet, DHCP_MESSAGE_TYPE);
		if (!message_type)
			return TRUE;
	}

	if (!message_type && !client_id)
		/* No message type / client id option, ignore package */
		return TRUE;

	debug(dhcp_client, "received DHCP packet xid 0x%04x "
		"(current state %d)", ntohl(xid), dhcp_client->state);

	if (message_type) {
		p = get_message_type(*message_type);

		debug(dhcp_client, "received DHCP%s (%#02x) packet "
			"(current state %d)",
			p,
			*message_type,
			dhcp_client->state);
	} else {
		debug(dhcp_client, "received DHCPv6 packet "
			"(current state %d)",
			dhcp_client->state);
	}

	switch (dhcp_client->state) {
	case INIT_SELECTING:
		if (message_type == NULL ) {
			debug(dhcp_client, "INIT_SELECTING but message_type is NULL" );
			return TRUE;
		}
		if (*message_type != DHCPOFFER)
			return TRUE;

		remove_timeouts(dhcp_client);
		dhcp_client->timeout = 0;
		dhcp_client->retry_times = 0;

		option = dhcp_get_option(&packet, DHCP_SERVER_ID);
		dhcp_client->server_ip = get_be32(option);
		dhcp_client->requested_ip = ntohl(packet.yiaddr);

		dhcp_client->state = REQUESTING;

		server.s_addr = dhcp_client->server_ip;
		request.s_addr = dhcp_client->requested_ip;

		debug(dhcp_client, "init ip %s -> %sadding broadcast flag",
			inet_ntoa(dst_addr.sin_addr),
			dhcp_client->request_bcast ? "" : "not ");
		
        server.s_addr = dhcp_client->server_ip;
		request.s_addr = dhcp_client->requested_ip;

		debug(dhcp_client, "%s of %s from %s",
			p,
			inet_ntop(AF_INET, &request,
				  requestbuf, sizeof(requestbuf)),
			inet_ntop(AF_INET, &server,
				  serverbuf, sizeof(serverbuf)));

		start_request(dhcp_client);

		return TRUE;
	case REBOOTING:
		if (dst_addr.sin_addr.s_addr == INADDR_BROADCAST)
			dhcp_client->request_bcast = true;
		else
			dhcp_client->request_bcast = false;

		debug(dhcp_client, "ip %s -> %sadding broadcast flag",
			inet_ntoa(dst_addr.sin_addr),
			dhcp_client->request_bcast ? "" : "not ");
		/* fall through */
	case REQUESTING:
	case RENEWING:
	case REBINDING:
		if (message_type == NULL ) {
			debug(dhcp_client, "REQUESTING/RENEWING/REBINDING/REBOOTING but message_type is NULL" );
			return TRUE;
		}
		if (*message_type == DHCPACK) {
			dhcp_client->retry_times = 0;

			remove_timeouts(dhcp_client);

			dhcp_client->lease_seconds = get_lease(dhcp_client, &packet);

			get_request(dhcp_client, &packet);

			switch_listening_mode(dhcp_client, L_NONE);

			g_free(dhcp_client->assigned_ip);
			dhcp_client->assigned_ip = get_ip(packet.yiaddr);

			if (dhcp_client->state == REBOOTING) {
				option = dhcp_get_option(&packet,
							DHCP_SERVER_ID);
				dhcp_client->server_ip = get_be32(option);
			}
			request.s_addr = packet.yiaddr;
			server.s_addr = dhcp_client->server_ip;

			debug(dhcp_client, "%s of %s from %s",
				p,
				inet_ntop(AF_INET, &request,
					  requestbuf, sizeof(requestbuf)),
				inet_ntop(AF_INET, &server,
					  serverbuf, sizeof(serverbuf)));

			/* Address should be set up here */
			if (dhcp_client->lease_available_cb)
				dhcp_client->lease_available_cb(dhcp_client,
					dhcp_client->lease_available_data);

			start_bound(dhcp_client);
		} else if (*message_type == DHCPNAK) {
			dhcp_client->retry_times = 0;

			remove_timeouts(dhcp_client);

			dhcp_client->timeout = g_rttimeout_add_seconds_full(CLOCK_BOOTTIME_ALARM,
							G_PRIORITY_HIGH, 3,
							restart_dhcp_timeout,
							dhcp_client,
							NULL);
		}

		break;
	case SOLICITATION:
		if (dhcp_client->type != G_DHCP_IPV6)
			return TRUE;

		if (packet6->message != DHCPV6_REPLY &&
				packet6->message != DHCPV6_ADVERTISE)
			return TRUE;

		count = 0;
		server_id = dhcpv6_get_option(packet6, pkt_len,
				G_DHCPV6_SERVERID, &option_len,	&count);
		if (!server_id || count != 1 || option_len == 0) {
			/* RFC 3315, 15.10 */
			debug(dhcp_client,
				"server duid error, discarding msg %p/%d/%d",
				server_id, option_len, count);
			return TRUE;
		}
		dhcp_client->server_duid = g_try_malloc(option_len);
		if (!dhcp_client->server_duid)
			return TRUE;
		memcpy(dhcp_client->server_duid, server_id, option_len);
		dhcp_client->server_duid_len = option_len;

		if (packet6->message == DHCPV6_REPLY) {
			uint8_t *rapid_commit;
			count = 0;
			option_len = 0;
			rapid_commit = dhcpv6_get_option(packet6, pkt_len,
							G_DHCPV6_RAPID_COMMIT,
							&option_len, &count);
			if (!rapid_commit || option_len != 0 ||
								count != 1)
				/* RFC 3315, 17.1.4 */
				return TRUE;
		}

		switch_listening_mode(dhcp_client, L_NONE);

		if (dhcp_client->status_code == 0)
			get_dhcpv6_request(dhcp_client, packet6, pkt_len,
					&dhcp_client->status_code);

		if (packet6->message == DHCPV6_ADVERTISE) {
			if (dhcp_client->advertise_cb)
				dhcp_client->advertise_cb(dhcp_client,
						dhcp_client->advertise_data);
			return TRUE;
		}

		if (dhcp_client->solicitation_cb) {
			/*
			 * The dhcp_client might not be valid after the
			 * callback call so just return immediately.
			 */
			dhcp_client->solicitation_cb(dhcp_client,
					dhcp_client->solicitation_data);
			return TRUE;
		}
		break;
	case REBIND:
		if (dhcp_client->type != G_DHCP_IPV6)
			return TRUE;

		server_id = dhcpv6_get_option(packet6, pkt_len,
				G_DHCPV6_SERVERID, &option_len,	&count);
		if (!dhcp_client->server_duid && server_id &&
								count == 1) {
			/*
			 * If we do not have server duid yet, then get it now.
			 * Prefix delegation renew support needs it.
			 */
			dhcp_client->server_duid = g_try_malloc(option_len);
			if (!dhcp_client->server_duid)
				return TRUE;
			memcpy(dhcp_client->server_duid, server_id, option_len);
			dhcp_client->server_duid_len = option_len;
		}
		/* fall through */
	case INFORMATION_REQ:
	case REQUEST:
	case RENEW:
	case RELEASE:
	case CONFIRM:
	case DECLINE:
		if (dhcp_client->type != G_DHCP_IPV6)
			return TRUE;

		if (packet6->message != DHCPV6_REPLY)
			return TRUE;

		count = 0;
		option_len = 0;
		server_id = dhcpv6_get_option(packet6, pkt_len,
				G_DHCPV6_SERVERID, &option_len, &count);
		if (!server_id || count != 1 || option_len == 0 ||
				(dhcp_client->server_duid_len > 0 &&
				memcmp(dhcp_client->server_duid, server_id,
					dhcp_client->server_duid_len) != 0)) {
			/* RFC 3315, 15.10 */
			debug(dhcp_client,
				"server duid error, discarding msg %p/%d/%d",
				server_id, option_len, count);
			return TRUE;
		}

		switch_listening_mode(dhcp_client, L_NONE);

		get_dhcpv6_request(dhcp_client, packet6, pkt_len,
						&dhcp_client->status_code);

		if (dhcp_client->information_req_cb) {
			/*
			 * The dhcp_client might not be valid after the
			 * callback call so just return immediately.
			 */
			dhcp_client->information_req_cb(dhcp_client,
					dhcp_client->information_req_data);
			return TRUE;
		}
		if (dhcp_client->request_cb) {
			dhcp_client->request_cb(dhcp_client,
					dhcp_client->request_data);
			return TRUE;
		}
		if (dhcp_client->renew_cb) {
			dhcp_client->renew_cb(dhcp_client,
					dhcp_client->renew_data);
			return TRUE;
		}
		if (dhcp_client->rebind_cb) {
			dhcp_client->rebind_cb(dhcp_client,
					dhcp_client->rebind_data);
			return TRUE;
		}
		if (dhcp_client->release_cb) {
			dhcp_client->release_cb(dhcp_client,
					dhcp_client->release_data);
			return TRUE;
		}
		if (dhcp_client->decline_cb) {
			dhcp_client->decline_cb(dhcp_client,
					dhcp_client->decline_data);
			return TRUE;
		}
		if (dhcp_client->confirm_cb) {
			count = 0;
			server_id = dhcpv6_get_option(packet6, pkt_len,
						G_DHCPV6_SERVERID, &option_len,
						&count);
			if (!server_id || count != 1 ||
							option_len == 0) {
				/* RFC 3315, 15.10 */
				debug(dhcp_client,
					"confirm server duid error, "
					"discarding msg %p/%d/%d",
					server_id, option_len, count);
				return TRUE;
			}
			dhcp_client->server_duid = g_try_malloc(option_len);
			if (!dhcp_client->server_duid)
				return TRUE;
			memcpy(dhcp_client->server_duid, server_id, option_len);
			dhcp_client->server_duid_len = option_len;

			dhcp_client->confirm_cb(dhcp_client,
						dhcp_client->confirm_data);
			return TRUE;
		}
		break;
	default:
		break;
	}

	if (message_type) {
		debug(dhcp_client, "processed DHCP%s (%#02x) packet (new state %d)",
			p,
			*message_type,
			dhcp_client->state);
	} else {
		debug(dhcp_client, "processed DHCPv6 packet (new state %d)",
			dhcp_client->state);
	}
	return TRUE;
}

static gboolean discover_timeout(gpointer user_data)
{
	GDHCPClient *dhcp_client = user_data;

	dhcp_client->retry_times++;

	/*
	 * We do not send the REQUESTED IP option if we are retrying because
	 * if the server is non-authoritative it will ignore the request if the
	 * option is present.
	 */
	g_dhcp_client_start(dhcp_client, NULL);

	return FALSE;
}

static gboolean reboot_timeout(gpointer user_data)
{
	GDHCPClient *dhcp_client = user_data;
	dhcp_client->retry_times = 0;
	dhcp_client->requested_ip = 0;
	dhcp_client->state = INIT_SELECTING;
	/*
	 * We do not send the REQUESTED IP option because the server didn't
	 * respond when we send DHCPREQUEST with the REQUESTED IP option in
	 * init-reboot state
	 */
	g_dhcp_client_start(dhcp_client, NULL);

	return FALSE;
}

static gboolean ipv4ll_defend_timeout(gpointer dhcp_data)
{
	GDHCPClient *dhcp_client = dhcp_data;

	debug(dhcp_client, "back to MONITOR mode");

	dhcp_client->conflicts = 0;
	dhcp_client->state = IPV4LL_MONITOR;

	return FALSE;
}

static gboolean ipv4ll_announce_timeout(gpointer dhcp_data)
{
	GDHCPClient *dhcp_client = dhcp_data;
	uint32_t ip;

	debug(dhcp_client, "request timeout (retries %d)",
	       dhcp_client->retry_times);

	if (dhcp_client->retry_times != ANNOUNCE_NUM) {
		dhcp_client->retry_times++;
		send_announce_packet(dhcp_client);
		return FALSE;
	}

	ip = htonl(dhcp_client->requested_ip);
	debug(dhcp_client, "switching to monitor mode");
	dhcp_client->state = IPV4LL_MONITOR;
	dhcp_client->assigned_ip = get_ip(ip);

	if (dhcp_client->ipv4ll_available_cb)
		dhcp_client->ipv4ll_available_cb(dhcp_client,
					dhcp_client->ipv4ll_available_data);
	dhcp_client->conflicts = 0;

	return FALSE;
}

static gboolean ipv4ll_probe_timeout(gpointer dhcp_data)
{

	GDHCPClient *dhcp_client = dhcp_data;

	debug(dhcp_client, "IPV4LL probe timeout (retries %d)",
	       dhcp_client->retry_times);

	if (dhcp_client->retry_times == PROBE_NUM) {
		dhcp_client->state = IPV4LL_ANNOUNCE;
		dhcp_client->retry_times = 0;

		dhcp_client->retry_times++;
		send_announce_packet(dhcp_client);
		return FALSE;
	}
	dhcp_client->retry_times++;
	send_probe_packet(dhcp_client);

	return FALSE;
}

int g_dhcp_client_start(GDHCPClient *dhcp_client, const char *last_address)
{
	int re;
	uint32_t addr;
	uint64_t rand;

	if (dhcp_client->type == G_DHCP_IPV6) {
		if (dhcp_client->information_req_cb) {
			dhcp_client->state = INFORMATION_REQ;
			re = switch_listening_mode(dhcp_client, L3);
			if (re != 0) {
				switch_listening_mode(dhcp_client, L_NONE);
				dhcp_client->state = 0;
				return re;
			}
			send_information_req(dhcp_client);

		} else if (dhcp_client->solicitation_cb) {
			dhcp_client->state = SOLICITATION;
			re = switch_listening_mode(dhcp_client, L3);
			if (re != 0) {
				switch_listening_mode(dhcp_client, L_NONE);
				dhcp_client->state = 0;
				return re;
			}
			send_solicitation(dhcp_client);

		} else if (dhcp_client->request_cb) {
			dhcp_client->state = REQUEST;
			re = switch_listening_mode(dhcp_client, L3);
			if (re != 0) {
				switch_listening_mode(dhcp_client, L_NONE);
				dhcp_client->state = 0;
				return re;
			}
			send_dhcpv6_request(dhcp_client);

		} else if (dhcp_client->confirm_cb) {
			dhcp_client->state = CONFIRM;
			re = switch_listening_mode(dhcp_client, L3);
			if (re != 0) {
				switch_listening_mode(dhcp_client, L_NONE);
				dhcp_client->state = 0;
				return re;
			}
			send_dhcpv6_confirm(dhcp_client);

		} else if (dhcp_client->renew_cb) {
			dhcp_client->state = RENEW;
			re = switch_listening_mode(dhcp_client, L3);
			if (re != 0) {
				switch_listening_mode(dhcp_client, L_NONE);
				dhcp_client->state = 0;
				return re;
			}
			send_dhcpv6_renew(dhcp_client);

		} else if (dhcp_client->rebind_cb) {
			dhcp_client->state = REBIND;
			re = switch_listening_mode(dhcp_client, L3);
			if (re != 0) {
				switch_listening_mode(dhcp_client, L_NONE);
				dhcp_client->state = 0;
				return re;
			}
			send_dhcpv6_rebind(dhcp_client);

		} else if (dhcp_client->release_cb) {
			dhcp_client->state = RENEW;
			re = switch_listening_mode(dhcp_client, L3);
			if (re != 0) {
				switch_listening_mode(dhcp_client, L_NONE);
				dhcp_client->state = 0;
				return re;
			}
			send_dhcpv6_release(dhcp_client);
		} else if (dhcp_client->decline_cb) {
			dhcp_client->state = DECLINE;
			re = switch_listening_mode(dhcp_client, L3);
			if (re != 0) {
				switch_listening_mode(dhcp_client, L_NONE);
				dhcp_client->state = 0;
				return re;
			}
			send_dhcpv6_decline(dhcp_client);
		}

		return 0;
	}

	if (dhcp_client->type == G_DHCP_IPV4LL) {
		dhcp_client->state = INIT_SELECTING;
		ipv4ll_start(dhcp_client);
		return 0;
	}

	if (dhcp_client->retry_times == DISCOVER_RETRIES) {
		if (dhcp_client->no_lease_cb)
			dhcp_client->no_lease_cb(dhcp_client,
						dhcp_client->no_lease_data);
		dhcp_client->retry_times = 0;
		return 0;
	}

	if (dhcp_client->retry_times == 0) {
		g_free(dhcp_client->assigned_ip);
		dhcp_client->assigned_ip = NULL;

		dhcp_client->state = INIT_SELECTING;
		re = switch_listening_mode(dhcp_client, L2);
		if (re != 0)
			return re;

		dhcp_get_random(&rand);
		dhcp_client->xid = rand;
		dhcp_client->start = time(NULL);
	}

	if (!last_address) {
		addr = 0;
	} else {
		addr = ntohl(inet_addr(last_address));
		if (addr == 0xFFFFFFFF) {
			addr = 0;
		} else {
			g_free(dhcp_client->last_address);
			dhcp_client->last_address = g_strdup(last_address);
		}
	}

	if ((addr != 0) && (dhcp_client->type != G_DHCP_IPV4LL)) {
		debug(dhcp_client, "DHCP client start with state init_reboot");
		dhcp_client->requested_ip = addr;
		dhcp_client->state = REBOOTING;
		send_request(dhcp_client);

		dhcp_client->timeout = g_rttimeout_add_seconds_full(CLOCK_BOOTTIME_ALARM,
								G_PRIORITY_HIGH,
								REQUEST_TIMEOUT,
								reboot_timeout,
								dhcp_client,
								NULL);
		return 0;
	}
	send_discover(dhcp_client, addr);

	dhcp_client->timeout = g_rttimeout_add_seconds_full(CLOCK_BOOTTIME_ALARM, G_PRIORITY_HIGH,
							DISCOVER_TIMEOUT,
							discover_timeout,
							dhcp_client,
							NULL);
	return 0;
}

void g_dhcp_client_stop(GDHCPClient *dhcp_client)
{
	switch_listening_mode(dhcp_client, L_NONE);

	if (dhcp_client->state == BOUND ||
			dhcp_client->state == RENEWING ||
				dhcp_client->state == REBINDING)
		send_release(dhcp_client, dhcp_client->server_ip,
					dhcp_client->requested_ip);

	remove_timeouts(dhcp_client);

	if (dhcp_client->listener_watch > 0) {
		g_source_remove(dhcp_client->listener_watch);
		dhcp_client->listener_watch = 0;
	}

	dhcp_client->retry_times = 0;
	dhcp_client->ack_retry_times = 0;

	dhcp_client->requested_ip = 0;
	dhcp_client->state = RELEASED;
	dhcp_client->lease_seconds = 0;
	dhcp_client->request_bcast = false;
}

GList *g_dhcp_client_get_option(GDHCPClient *dhcp_client,
					unsigned char option_code)
{
	return g_hash_table_lookup(dhcp_client->code_value_hash,
					GINT_TO_POINTER((int) option_code));
}

void g_dhcp_client_register_event(GDHCPClient *dhcp_client,
					GDHCPClientEvent event,
					GDHCPClientEventFunc func,
							gpointer data)
{
	switch (event) {
	case G_DHCP_CLIENT_EVENT_LEASE_AVAILABLE:
		dhcp_client->lease_available_cb = func;
		dhcp_client->lease_available_data = data;
		return;
	case G_DHCP_CLIENT_EVENT_IPV4LL_AVAILABLE:
		if (dhcp_client->type == G_DHCP_IPV6)
			return;
		dhcp_client->ipv4ll_available_cb = func;
		dhcp_client->ipv4ll_available_data = data;
		return;
	case G_DHCP_CLIENT_EVENT_NO_LEASE:
		dhcp_client->no_lease_cb = func;
		dhcp_client->no_lease_data = data;
		return;
	case G_DHCP_CLIENT_EVENT_LEASE_LOST:
		dhcp_client->lease_lost_cb = func;
		dhcp_client->lease_lost_data = data;
		return;
	case G_DHCP_CLIENT_EVENT_IPV4LL_LOST:
		if (dhcp_client->type == G_DHCP_IPV6)
			return;
		dhcp_client->ipv4ll_lost_cb = func;
		dhcp_client->ipv4ll_lost_data = data;
		return;
	case G_DHCP_CLIENT_EVENT_ADDRESS_CONFLICT:
		dhcp_client->address_conflict_cb = func;
		dhcp_client->address_conflict_data = data;
		return;
	case G_DHCP_CLIENT_EVENT_INFORMATION_REQ:
		if (dhcp_client->type != G_DHCP_IPV6)
			return;
		dhcp_client->information_req_cb = func;
		dhcp_client->information_req_data = data;
		return;
	case G_DHCP_CLIENT_EVENT_SOLICITATION:
		if (dhcp_client->type != G_DHCP_IPV6)
			return;
		dhcp_client->solicitation_cb = func;
		dhcp_client->solicitation_data = data;
		return;
	case G_DHCP_CLIENT_EVENT_ADVERTISE:
		if (dhcp_client->type != G_DHCP_IPV6)
			return;
		dhcp_client->advertise_cb = func;
		dhcp_client->advertise_data = data;
		return;
	case G_DHCP_CLIENT_EVENT_REQUEST:
		if (dhcp_client->type != G_DHCP_IPV6)
			return;
		dhcp_client->request_cb = func;
		dhcp_client->request_data = data;
		return;
	case G_DHCP_CLIENT_EVENT_RENEW:
		if (dhcp_client->type != G_DHCP_IPV6)
			return;
		dhcp_client->renew_cb = func;
		dhcp_client->renew_data = data;
		return;
	case G_DHCP_CLIENT_EVENT_REBIND:
		if (dhcp_client->type != G_DHCP_IPV6)
			return;
		dhcp_client->rebind_cb = func;
		dhcp_client->rebind_data = data;
		return;
	case G_DHCP_CLIENT_EVENT_RELEASE:
		if (dhcp_client->type != G_DHCP_IPV6)
			return;
		dhcp_client->release_cb = func;
		dhcp_client->release_data = data;
		return;
	case G_DHCP_CLIENT_EVENT_CONFIRM:
		if (dhcp_client->type != G_DHCP_IPV6)
			return;
		dhcp_client->confirm_cb = func;
		dhcp_client->confirm_data = data;
		return;
	case G_DHCP_CLIENT_EVENT_DECLINE:
		if (dhcp_client->type != G_DHCP_IPV6)
			return;
		dhcp_client->decline_cb = func;
		dhcp_client->decline_data = data;
		return;
	case G_DHCP_CLIENT_EVENT_WAKE_EVENT:
		dhcp_client->wake_event_cb = func;
		dhcp_client->wake_event_data= data;
		return;
	}
}

int g_dhcp_client_get_index(GDHCPClient *dhcp_client)
{
	return dhcp_client->ifindex;
}

char *g_dhcp_client_get_server_address(GDHCPClient *dhcp_client)
{
	if (!dhcp_client)
		return NULL;

	return get_ip(dhcp_client->server_ip);
}

char *g_dhcp_client_get_address(GDHCPClient *dhcp_client)
{
	if (!dhcp_client)
		return NULL;

	return g_strdup(dhcp_client->assigned_ip);
}

char *g_dhcp_client_get_netmask(GDHCPClient *dhcp_client)
{
	GList *option = NULL;

	if (dhcp_client->type == G_DHCP_IPV6)
		return NULL;

	switch (dhcp_client->state) {
	case IPV4LL_DEFEND:
	case IPV4LL_MONITOR:
		return g_strdup("255.255.0.0");
	case BOUND:
	case RENEWING:
	case REBINDING:
		option = g_dhcp_client_get_option(dhcp_client, G_DHCP_SUBNET);
		if (option)
			return g_strdup(option->data);
	case INIT_SELECTING:
	case REBOOTING:
	case REQUESTING:
	case RELEASED:
	case IPV4LL_PROBE:
	case IPV4LL_ANNOUNCE:
	case INFORMATION_REQ:
	case SOLICITATION:
	case REQUEST:
	case CONFIRM:
	case RENEW:
	case REBIND:
	case RELEASE:
	case DECLINE:
		break;
	}
	return NULL;
}

GDHCPClientError g_dhcp_client_set_request(GDHCPClient *dhcp_client,
						unsigned int option_code)
{
	if (!g_list_find(dhcp_client->request_list,
				GINT_TO_POINTER((int)option_code)))
		dhcp_client->request_list = g_list_prepend(
					dhcp_client->request_list,
					(GINT_TO_POINTER((int) option_code)));

	return G_DHCP_CLIENT_ERROR_NONE;
}

void g_dhcp_client_clear_requests(GDHCPClient *dhcp_client)
{
	g_list_free(dhcp_client->request_list);
	dhcp_client->request_list = NULL;
}

void g_dhcp_client_clear_values(GDHCPClient *dhcp_client)
{
	g_hash_table_remove_all(dhcp_client->send_value_hash);
}

static uint8_t *alloc_dhcp_option(int code, const uint8_t *data, unsigned size)
{
	uint8_t *storage;

	storage = g_try_malloc(size + OPT_DATA);
	if (!storage)
		return NULL;

	storage[OPT_CODE] = code;
	storage[OPT_LEN] = size;
	memcpy(&storage[OPT_DATA], data, size);

	return storage;
}

static uint8_t *alloc_dhcp_data_option(int code, const uint8_t *data,
					unsigned size)
{
	return alloc_dhcp_option(code, data, MIN(size, 255));
}

static uint8_t *alloc_dhcp_string_option(int code, const char *str)
{
	return alloc_dhcp_data_option(code, (const uint8_t *)str, strlen(str));
}

GDHCPClientError g_dhcp_client_set_id(GDHCPClient *dhcp_client)
{
	const unsigned maclen = 6;
	const unsigned idlen = maclen + 1;
	const uint8_t option_code = G_DHCP_CLIENT_ID;
	uint8_t idbuf[idlen];
	uint8_t *data_option;

	idbuf[0] = ARPHRD_ETHER;

	memcpy(&idbuf[1], dhcp_client->mac_address, maclen);

	data_option = alloc_dhcp_data_option(option_code, idbuf, idlen);
	if (!data_option)
		return G_DHCP_CLIENT_ERROR_NOMEM;

	g_hash_table_insert(dhcp_client->send_value_hash,
		GINT_TO_POINTER((int) option_code), data_option);

	return G_DHCP_CLIENT_ERROR_NONE;
}

/* Now only support send hostname */
GDHCPClientError g_dhcp_client_set_send(GDHCPClient *dhcp_client,
		unsigned char option_code, const char *option_value)
{
	uint8_t *binary_option;

	if (option_code == G_DHCP_HOST_NAME && option_value) {
		binary_option = alloc_dhcp_string_option(option_code,
							option_value);
		if (!binary_option)
			return G_DHCP_CLIENT_ERROR_NOMEM;

		g_hash_table_insert(dhcp_client->send_value_hash,
			GINT_TO_POINTER((int) option_code), binary_option);
	}

	return G_DHCP_CLIENT_ERROR_NONE;
}

static uint8_t *alloc_dhcpv6_option(uint16_t code, uint8_t *option,
				uint16_t len)
{
	uint8_t *storage;

	storage = g_malloc(2 + 2 + len);
	if (!storage)
		return NULL;

	storage[0] = code >> 8;
	storage[1] = code & 0xff;
	storage[2] = len >> 8;
	storage[3] = len & 0xff;
	memcpy(storage + 2 + 2, option, len);

	return storage;
}

gboolean g_dhcpv6_client_clear_send(GDHCPClient *dhcp_client, uint16_t code)
{
	return g_hash_table_remove(dhcp_client->send_value_hash,
				GINT_TO_POINTER((int)code));
}

void g_dhcpv6_client_set_send(GDHCPClient *dhcp_client,
					uint16_t option_code,
					uint8_t *option_value,
					uint16_t option_len)
{
	if (option_value) {
		uint8_t *binary_option;

		debug(dhcp_client, "setting option %d to %p len %d",
			option_code, option_value, option_len);

		binary_option = alloc_dhcpv6_option(option_code, option_value,
						option_len);
		if (binary_option)
			g_hash_table_insert(dhcp_client->send_value_hash,
					GINT_TO_POINTER((int) option_code),
					binary_option);
	}
}

void g_dhcpv6_client_reset_request(GDHCPClient *dhcp_client)
{
	if (!dhcp_client || dhcp_client->type != G_DHCP_IPV6)
		return;

	dhcp_client->last_request = time(NULL);
}

uint16_t g_dhcpv6_client_get_status(GDHCPClient *dhcp_client)
{
	if (!dhcp_client || dhcp_client->type != G_DHCP_IPV6)
		return 0;

	return dhcp_client->status_code;
}

GDHCPClient *g_dhcp_client_ref(GDHCPClient *dhcp_client)
{
	if (!dhcp_client)
		return NULL;

	__sync_fetch_and_add(&dhcp_client->ref_count, 1);

	return dhcp_client;
}

void g_dhcp_client_unref(GDHCPClient *dhcp_client)
{
	if (!dhcp_client)
		return;

	if (__sync_fetch_and_sub(&dhcp_client->ref_count, 1) != 1)
		return;

	g_dhcp_client_stop(dhcp_client);

	g_free(dhcp_client->interface);
	g_free(dhcp_client->assigned_ip);
	g_free(dhcp_client->last_address);
	g_free(dhcp_client->duid);
	g_free(dhcp_client->server_duid);

	g_list_free(dhcp_client->request_list);
	g_list_free(dhcp_client->require_list);

	g_hash_table_destroy(dhcp_client->code_value_hash);
	g_hash_table_destroy(dhcp_client->send_value_hash);

	g_free(dhcp_client);
}

void g_dhcp_client_set_debug(GDHCPClient *dhcp_client,
				GDHCPDebugFunc func, gpointer user_data)
{
	if (!dhcp_client)
		return;

	dhcp_client->debug_func = func;
	dhcp_client->debug_data = user_data;
}

static GDHCPIAPrefix *copy_prefix(gpointer data)
{
	GDHCPIAPrefix *copy, *prefix = data;

	copy = g_try_new(GDHCPIAPrefix, 1);
	if (!copy)
		return NULL;

	memcpy(copy, prefix, sizeof(GDHCPIAPrefix));

	return copy;
}

GSList *g_dhcpv6_copy_prefixes(GSList *prefixes)
{
	GSList *copy = NULL;
	GSList *list;

	for (list = prefixes; list; list = list->next)
		copy = g_slist_prepend(copy, copy_prefix(list->data));

	return copy;
}
