/*
 *
 *  DHCP Server library with GLib integration
 *
 *  Copyright (C) 2009-2012  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

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

#include <netpacket/packet.h>
#include <net/ethernet.h>
#include <net/if_arp.h>

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

#include <glib.h>

#include "common.h"

/* 8 hours */
#define DEFAULT_DHCP_LEASE_SEC (8*60*60)

/* 5 minutes  */
#define OFFER_TIME (5*60)

struct _GDHCPServer {
	int ref_count;
	GDHCPType type;
	bool started;
	int ifindex;
	char *interface;
	uint32_t start_ip;
	uint32_t end_ip;
	uint32_t server_nip;	/* our address in network byte order */
	uint32_t lease_seconds;
	int listener_sockfd;
	guint listener_watch;
	GIOChannel *listener_channel;
	GList *lease_list;
	GHashTable *nip_lease_hash;
	GHashTable *option_hash; /* Options send to client */
	GDHCPSaveLeaseFunc save_lease_func;
	GDHCPLeaseAddedCb lease_added_cb;
	GDHCPDebugFunc debug_func;
	gpointer debug_data;
};

struct dhcp_lease {
	time_t expire;
	uint32_t lease_nip;
	uint8_t lease_mac[ETH_ALEN];
};

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

	if (!server->debug_func)
		return;

	va_start(ap, format);

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

	va_end(ap);
}

static struct dhcp_lease *find_lease_by_mac(GDHCPServer *dhcp_server,
						const uint8_t *mac)
{
	GList *list;

	for (list = dhcp_server->lease_list; list; list = list->next) {
		struct dhcp_lease *lease = list->data;

		if (memcmp(lease->lease_mac, mac, ETH_ALEN) == 0)
			return lease;
	}

	return NULL;
}

static void remove_lease(GDHCPServer *dhcp_server, struct dhcp_lease *lease)
{
	dhcp_server->lease_list =
			g_list_remove(dhcp_server->lease_list, lease);

	g_hash_table_remove(dhcp_server->nip_lease_hash,
				GINT_TO_POINTER((int) lease->lease_nip));
	g_free(lease);
}

/* Clear the old lease and create the new one */
static int get_lease(GDHCPServer *dhcp_server, uint32_t yiaddr,
				const uint8_t *mac, struct dhcp_lease **lease)
{
	struct dhcp_lease *lease_nip, *lease_mac;

	if (yiaddr == 0)
		return -ENXIO;

	if (ntohl(yiaddr) < dhcp_server->start_ip)
		return -ENXIO;

	if (ntohl(yiaddr) > dhcp_server->end_ip)
		return -ENXIO;

	if (memcmp(mac, MAC_BCAST_ADDR, ETH_ALEN) == 0)
		return -ENXIO;

	if (memcmp(mac, MAC_ANY_ADDR, ETH_ALEN) == 0)
		return -ENXIO;

	lease_mac = find_lease_by_mac(dhcp_server, mac);

	lease_nip = g_hash_table_lookup(dhcp_server->nip_lease_hash,
					GINT_TO_POINTER((int) ntohl(yiaddr)));
	debug(dhcp_server, "lease_mac %p lease_nip %p", lease_mac, lease_nip);

	if (lease_nip) {
		dhcp_server->lease_list =
				g_list_remove(dhcp_server->lease_list,
								lease_nip);
		g_hash_table_remove(dhcp_server->nip_lease_hash,
				GINT_TO_POINTER((int) ntohl(yiaddr)));

		if (!lease_mac)
			*lease = lease_nip;
		else if (lease_nip != lease_mac) {
			remove_lease(dhcp_server, lease_mac);
			*lease = lease_nip;
		} else
			*lease = lease_nip;

		return 0;
	}

	if (lease_mac) {
		dhcp_server->lease_list =
				g_list_remove(dhcp_server->lease_list,
								lease_mac);
		g_hash_table_remove(dhcp_server->nip_lease_hash,
				GINT_TO_POINTER((int) lease_mac->lease_nip));
		*lease = lease_mac;

		return 0;
	}

	*lease = g_try_new0(struct dhcp_lease, 1);
	if (!*lease)
		return -ENOMEM;

	return 0;
}

static gint compare_expire(gconstpointer a, gconstpointer b)
{
	const struct dhcp_lease *lease1 = a;
	const struct dhcp_lease *lease2 = b;

	return lease2->expire - lease1->expire;
}

static struct dhcp_lease *add_lease(GDHCPServer *dhcp_server, uint32_t expire,
					const uint8_t *chaddr, uint32_t yiaddr)
{
	struct dhcp_lease *lease = NULL;
	int ret;

	ret = get_lease(dhcp_server, yiaddr, chaddr, &lease);
	if (ret != 0)
		return NULL;

	memset(lease, 0, sizeof(*lease));

	memcpy(lease->lease_mac, chaddr, ETH_ALEN);
	lease->lease_nip = ntohl(yiaddr);

	if (expire == 0)
		lease->expire = time(NULL) + dhcp_server->lease_seconds;
	else
		lease->expire = expire;

	dhcp_server->lease_list = g_list_insert_sorted(dhcp_server->lease_list,
							lease, compare_expire);

	g_hash_table_insert(dhcp_server->nip_lease_hash,
				GINT_TO_POINTER((int) lease->lease_nip), lease);

	if (dhcp_server->lease_added_cb)
		dhcp_server->lease_added_cb(lease->lease_mac, yiaddr);

	return lease;
}

static struct dhcp_lease *find_lease_by_nip(GDHCPServer *dhcp_server,
								uint32_t nip)
{
	return g_hash_table_lookup(dhcp_server->nip_lease_hash,
						GINT_TO_POINTER((int) nip));
}

/* Check if the IP is taken; if it is, add it to the lease table */
static bool arp_check(uint32_t nip, const uint8_t *safe_mac)
{
	/* TODO: Add ARP checking */
	return true;
}

static bool is_expired_lease(struct dhcp_lease *lease)
{
	if (lease->expire < time(NULL))
		return true;

	return false;
}

static uint32_t find_free_or_expired_nip(GDHCPServer *dhcp_server,
					const uint8_t *safe_mac)
{
	uint32_t ip_addr;
	struct dhcp_lease *lease;
	GList *list;
	ip_addr = dhcp_server->start_ip;
	for (; ip_addr <= dhcp_server->end_ip; ip_addr++) {
		/* e.g. 192.168.55.0 */
		if ((ip_addr & 0xff) == 0)
			continue;

		/* e.g. 192.168.55.255 */
		if ((ip_addr & 0xff) == 0xff)
			continue;

		lease = find_lease_by_nip(dhcp_server, ip_addr);
		if (lease)
			continue;

		if (arp_check(htonl(ip_addr), safe_mac))
			return ip_addr;
	}

	/* The last lease is the oldest one */
	list = g_list_last(dhcp_server->lease_list);
	if (!list)
		return 0;

	lease = list->data;
	if (!lease)
		return 0;

	 if (!is_expired_lease(lease))
		return 0;

	 if (!arp_check(lease->lease_nip, safe_mac))
		return 0;

	return lease->lease_nip;
}

static void lease_set_expire(GDHCPServer *dhcp_server,
			struct dhcp_lease *lease, uint32_t expire)
{
	dhcp_server->lease_list = g_list_remove(dhcp_server->lease_list, lease);

	lease->expire = expire;

	dhcp_server->lease_list = g_list_insert_sorted(dhcp_server->lease_list,
							lease, compare_expire);
}

static void destroy_lease_table(GDHCPServer *dhcp_server)
{
	GList *list;

	g_hash_table_destroy(dhcp_server->nip_lease_hash);

	dhcp_server->nip_lease_hash = NULL;

	for (list = dhcp_server->lease_list; list; list = list->next) {
		struct dhcp_lease *lease = list->data;

		g_free(lease);
	}

	g_list_free(dhcp_server->lease_list);

	dhcp_server->lease_list = NULL;
}
static uint32_t get_interface_address(int index)
{
	struct ifreq ifr;
	int sk, err;
	struct sockaddr_in *server_ip;
	uint32_t ret = 0;

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

	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, SIOCGIFADDR, &ifr);
	if (err < 0) {
		perror("Get ip address error");
		goto done;
	}

	server_ip = (struct sockaddr_in *) &ifr.ifr_addr;
	ret = server_ip->sin_addr.s_addr;

done:
	close(sk);

	return ret;
}

GDHCPServer *g_dhcp_server_new(GDHCPType type,
		int ifindex, GDHCPServerError *error)
{
	GDHCPServer *dhcp_server = NULL;

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

	dhcp_server = g_try_new0(GDHCPServer, 1);
	if (!dhcp_server) {
		*error = G_DHCP_SERVER_ERROR_NOMEM;
		return NULL;
	}

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

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

	dhcp_server->server_nip = get_interface_address(ifindex);
	if (dhcp_server->server_nip == 0) {
		*error = G_DHCP_SERVER_ERROR_IP_ADDRESS_INVALID;
		goto error;
	}

	dhcp_server->nip_lease_hash = g_hash_table_new_full(g_direct_hash,
						g_direct_equal, NULL, NULL);
	dhcp_server->option_hash = g_hash_table_new_full(g_direct_hash,
						g_direct_equal, NULL, NULL);

	dhcp_server->started = FALSE;

	/* All the leases have the same fixed lease time,
	 * do not support DHCP_LEASE_TIME option from client.
	 */
	dhcp_server->lease_seconds = DEFAULT_DHCP_LEASE_SEC;

	dhcp_server->type = type;
	dhcp_server->ref_count = 1;
	dhcp_server->ifindex = ifindex;
	dhcp_server->listener_sockfd = -1;
	dhcp_server->listener_watch = -1;
	dhcp_server->listener_channel = NULL;
	dhcp_server->save_lease_func = NULL;
	dhcp_server->debug_func = NULL;
	dhcp_server->debug_data = NULL;

	*error = G_DHCP_SERVER_ERROR_NONE;

	return dhcp_server;

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


static uint8_t check_packet_type(struct dhcp_packet *packet)
{
	uint8_t *type;

	if (packet->hlen != ETH_ALEN)
		return 0;

	if (packet->op != BOOTREQUEST)
		return 0;

	type = dhcp_get_option(packet, DHCP_MESSAGE_TYPE);

	if (!type)
		return 0;

	if (*type < DHCP_MINTYPE)
		return 0;

	if (*type > DHCP_MAXTYPE)
		return 0;

	return *type;
}

static void init_packet(GDHCPServer *dhcp_server, struct dhcp_packet *packet,
				struct dhcp_packet *client_packet, char type)
{
	/* Sets op, htype, hlen, cookie fields
	 * and adds DHCP_MESSAGE_TYPE option */
	dhcp_init_header(packet, type);

	packet->xid = client_packet->xid;
	memcpy(packet->chaddr, client_packet->chaddr,
				sizeof(client_packet->chaddr));
	packet->flags = client_packet->flags;
	packet->gateway_nip = client_packet->gateway_nip;
	packet->ciaddr = client_packet->ciaddr;
	dhcp_add_option_uint32(packet, DHCP_SERVER_ID,
					ntohl(dhcp_server->server_nip));
}

static void add_option(gpointer key, gpointer value, gpointer user_data)
{
	const char *option_value = value;
	uint8_t option_code = GPOINTER_TO_INT(key);
	struct in_addr nip;
	struct dhcp_packet *packet = user_data;

	if (!option_value)
		return;

	switch (option_code) {
	case G_DHCP_SUBNET:
	case G_DHCP_ROUTER:
	case G_DHCP_DNS_SERVER:
		if (inet_aton(option_value, &nip) == 0)
			return;

		dhcp_add_option_uint32(packet, (uint8_t) option_code,
							ntohl(nip.s_addr));
		break;
	default:
		return;
	}
}

static void add_server_options(GDHCPServer *dhcp_server,
				struct dhcp_packet *packet)
{
	g_hash_table_foreach(dhcp_server->option_hash,
				add_option, packet);
}

static bool check_requested_nip(GDHCPServer *dhcp_server,
					uint32_t requested_nip)
{
	struct dhcp_lease *lease;

	if (requested_nip == 0)
		return false;

	if (requested_nip < dhcp_server->start_ip)
		return false;

	if (requested_nip > dhcp_server->end_ip)
		return false;

	lease = find_lease_by_nip(dhcp_server, requested_nip);
	if (!lease)
		return true;

	if (!is_expired_lease(lease))
		return false;

	return true;
}

static void send_packet_to_client(GDHCPServer *dhcp_server,
				struct dhcp_packet *dhcp_pkt)
{
	const uint8_t *chaddr;
	uint32_t ciaddr;

	if ((dhcp_pkt->flags & htons(BROADCAST_FLAG))
				|| dhcp_pkt->ciaddr == 0) {
		debug(dhcp_server, "Broadcasting packet to client");
		ciaddr = INADDR_BROADCAST;
		chaddr = MAC_BCAST_ADDR;
	} else {
		debug(dhcp_server, "Unicasting packet to client ciaddr");
		ciaddr = dhcp_pkt->ciaddr;
		chaddr = dhcp_pkt->chaddr;
	}

	dhcp_send_raw_packet(dhcp_pkt,
		dhcp_server->server_nip, SERVER_PORT,
		ciaddr, CLIENT_PORT, chaddr,
		dhcp_server->ifindex, false);
}

static void send_offer(GDHCPServer *dhcp_server,
			struct dhcp_packet *client_packet,
				struct dhcp_lease *lease,
					uint32_t requested_nip)
{
	struct dhcp_packet packet;
	struct in_addr addr;

	init_packet(dhcp_server, &packet, client_packet, DHCPOFFER);

	if (lease)
		packet.yiaddr = htonl(lease->lease_nip);
	else if (check_requested_nip(dhcp_server, requested_nip))
		packet.yiaddr = htonl(requested_nip);
	else
		packet.yiaddr = htonl(find_free_or_expired_nip(
					dhcp_server, client_packet->chaddr));

	debug(dhcp_server, "find yiaddr %u", packet.yiaddr);

	if (!packet.yiaddr) {
		debug(dhcp_server, "Err: Can not found lease and send offer");
		return;
	}

	lease = add_lease(dhcp_server, OFFER_TIME,
				packet.chaddr, packet.yiaddr);
	if (!lease) {
		debug(dhcp_server,
				"Err: No free IP addresses. OFFER abandoned");
		return;
	}

	dhcp_add_option_uint32(&packet, DHCP_LEASE_TIME,
						dhcp_server->lease_seconds);
	add_server_options(dhcp_server, &packet);

	addr.s_addr = packet.yiaddr;

	debug(dhcp_server, "Sending OFFER of %s", inet_ntoa(addr));
	send_packet_to_client(dhcp_server, &packet);
}

static void save_lease(GDHCPServer *dhcp_server)
{
	GList *list;

	if (!dhcp_server->save_lease_func)
		return;

	for (list = dhcp_server->lease_list; list; list = list->next) {
		struct dhcp_lease *lease = list->data;
		dhcp_server->save_lease_func(lease->lease_mac,
					lease->lease_nip, lease->expire);
	}
}

static void send_ACK(GDHCPServer *dhcp_server,
		struct dhcp_packet *client_packet, uint32_t dest)
{
	struct dhcp_packet packet;
	uint32_t lease_time_sec;
	struct in_addr addr;

	init_packet(dhcp_server, &packet, client_packet, DHCPACK);
	packet.yiaddr = htonl(dest);

	lease_time_sec = dhcp_server->lease_seconds;

	dhcp_add_option_uint32(&packet, DHCP_LEASE_TIME, lease_time_sec);

	add_server_options(dhcp_server, &packet);

	addr.s_addr = htonl(dest);

	debug(dhcp_server, "Sending ACK to %s", inet_ntoa(addr));

	send_packet_to_client(dhcp_server, &packet);

	add_lease(dhcp_server, 0, packet.chaddr, packet.yiaddr);
}

static void send_NAK(GDHCPServer *dhcp_server,
			struct dhcp_packet *client_packet)
{
	struct dhcp_packet packet;

	init_packet(dhcp_server, &packet, client_packet, DHCPNAK);

	debug(dhcp_server, "Sending NAK");

	dhcp_send_raw_packet(&packet,
			dhcp_server->server_nip, SERVER_PORT,
			INADDR_BROADCAST, CLIENT_PORT, MAC_BCAST_ADDR,
			dhcp_server->ifindex, false);
}

static void send_inform(GDHCPServer *dhcp_server,
				struct dhcp_packet *client_packet)
{
	struct dhcp_packet packet;

	init_packet(dhcp_server, &packet, client_packet, DHCPACK);
	add_server_options(dhcp_server, &packet);
	send_packet_to_client(dhcp_server, &packet);
}

static gboolean listener_event(GIOChannel *channel, GIOCondition condition,
							gpointer user_data)
{
	GDHCPServer *dhcp_server = user_data;
	struct dhcp_packet packet;
	struct dhcp_lease *lease;
	uint32_t requested_nip = 0;
	uint8_t type, *server_id_option, *request_ip_option;
	int re;

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

	re = dhcp_recv_l3_packet(&packet, dhcp_server->listener_sockfd);
	if (re < 0)
		return TRUE;

	type = check_packet_type(&packet);
	if (type == 0)
		return TRUE;

	server_id_option = dhcp_get_option(&packet, DHCP_SERVER_ID);
	if (server_id_option) {
		uint32_t server_nid =
			get_unaligned((const uint32_t *) server_id_option);

		if (server_nid != dhcp_server->server_nip)
			return TRUE;
	}

	request_ip_option = dhcp_get_option(&packet, DHCP_REQUESTED_IP);
	if (request_ip_option)
		requested_nip = get_be32(request_ip_option);

	lease = find_lease_by_mac(dhcp_server, packet.chaddr);

	switch (type) {
	case DHCPDISCOVER:
		debug(dhcp_server, "Received DISCOVER");

		send_offer(dhcp_server, &packet, lease, requested_nip);
		break;
	case DHCPREQUEST:
		debug(dhcp_server, "Received REQUEST NIP %d",
							requested_nip);
		if (requested_nip == 0) {
			requested_nip = packet.ciaddr;
			if (requested_nip == 0)
				break;
		}

		if (lease && requested_nip == lease->lease_nip) {
			debug(dhcp_server, "Sending ACK");
			send_ACK(dhcp_server, &packet,
				lease->lease_nip);
			break;
		}

		if (server_id_option || !lease) {
			debug(dhcp_server, "Sending NAK");
			send_NAK(dhcp_server, &packet);
		}

		break;
	case DHCPDECLINE:
		debug(dhcp_server, "Received DECLINE");

		if (!server_id_option)
			break;

		if (!request_ip_option)
			break;

		if (!lease)
			break;

		if (requested_nip == lease->lease_nip)
			remove_lease(dhcp_server, lease);

		break;
	case DHCPRELEASE:
		debug(dhcp_server, "Received RELEASE");

		if (!server_id_option)
			break;

		if (!lease)
			break;

		if (packet.ciaddr == lease->lease_nip)
			lease_set_expire(dhcp_server, lease,
					time(NULL));
		break;
	case DHCPINFORM:
		debug(dhcp_server, "Received INFORM");
		send_inform(dhcp_server, &packet);
		break;
	}

	return TRUE;
}

/* Caller need to load leases before call it */
int g_dhcp_server_start(GDHCPServer *dhcp_server)
{
	GIOChannel *listener_channel;
	int listener_sockfd;

	if (dhcp_server->started)
		return 0;

	listener_sockfd = dhcp_l3_socket(SERVER_PORT,
					dhcp_server->interface, AF_INET);
	if (listener_sockfd < 0)
		return -EIO;

	listener_channel = g_io_channel_unix_new(listener_sockfd);
	if (!listener_channel) {
		close(listener_sockfd);
		return -EIO;
	}

	dhcp_server->listener_sockfd = listener_sockfd;
	dhcp_server->listener_channel = listener_channel;

	g_io_channel_set_close_on_unref(listener_channel, TRUE);
	dhcp_server->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_server,
								NULL);
	g_io_channel_unref(dhcp_server->listener_channel);

	dhcp_server->started = TRUE;

	return 0;
}

int g_dhcp_server_set_option(GDHCPServer *dhcp_server,
		unsigned char option_code, const char *option_value)
{
	struct in_addr nip;

	if (!option_value)
		return -EINVAL;

	debug(dhcp_server, "option_code %d option_value %s",
					option_code, option_value);
	switch (option_code) {
	case G_DHCP_SUBNET:
	case G_DHCP_ROUTER:
	case G_DHCP_DNS_SERVER:
		if (inet_aton(option_value, &nip) == 0)
			return -ENXIO;
		break;
	default:
		return -EINVAL;
	}

	g_hash_table_replace(dhcp_server->option_hash,
			GINT_TO_POINTER((int) option_code),
					(gpointer) option_value);
	return 0;
}

void g_dhcp_server_set_save_lease(GDHCPServer *dhcp_server,
				GDHCPSaveLeaseFunc func, gpointer user_data)
{
	if (!dhcp_server)
		return;

	dhcp_server->save_lease_func = func;
}

void g_dhcp_server_set_lease_added_cb(GDHCPServer *dhcp_server,
							GDHCPLeaseAddedCb cb)
{
	if (!dhcp_server)
		return;

	dhcp_server->lease_added_cb = cb;
}

GDHCPServer *g_dhcp_server_ref(GDHCPServer *dhcp_server)
{
	if (!dhcp_server)
		return NULL;

	__sync_fetch_and_add(&dhcp_server->ref_count, 1);

	return dhcp_server;
}

void g_dhcp_server_stop(GDHCPServer *dhcp_server)
{
	/* Save leases, before stop; load them before start */
	save_lease(dhcp_server);

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

	dhcp_server->listener_channel = NULL;

	dhcp_server->started = FALSE;
}

void g_dhcp_server_unref(GDHCPServer *dhcp_server)
{
	if (!dhcp_server)
		return;

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

	g_dhcp_server_stop(dhcp_server);

	g_hash_table_destroy(dhcp_server->option_hash);

	destroy_lease_table(dhcp_server);

	g_free(dhcp_server->interface);

	g_free(dhcp_server);
}

int g_dhcp_server_set_ip_range(GDHCPServer *dhcp_server,
		const char *start_ip, const char *end_ip)
{
	struct in_addr _host_addr;

	if (inet_aton(start_ip, &_host_addr) == 0)
		return -ENXIO;

	dhcp_server->start_ip = ntohl(_host_addr.s_addr);

	if (inet_aton(end_ip, &_host_addr) == 0)
		return -ENXIO;

	dhcp_server->end_ip = ntohl(_host_addr.s_addr);

	return 0;
}

void g_dhcp_server_set_lease_time(GDHCPServer *dhcp_server,
					unsigned int lease_time)
{
	if (!dhcp_server)
		return;

	dhcp_server->lease_seconds = lease_time;
}

void g_dhcp_server_set_debug(GDHCPServer *dhcp_server,
				GDHCPDebugFunc func, gpointer user_data)
{
	if (!dhcp_server)
		return;

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