/******************************************************************************
 * Copyright (c) 2004, 2008 IBM Corporation
 * All rights reserved.
 * This program and the accompanying materials
 * are made available under the terms of the BSD License
 * which accompanies this distribution, and is available at
 * http://www.opensource.org/licenses/bsd-license.php
 *
 * Contributors:
 *     IBM Corporation - initial implementation
 *****************************************************************************/


/******************************* ALGORITHMS ******************************/

/** \file dhcp.c <pre>
 * **************** State-transition diagram for DHCP client  *************
 *
 *   +---------+                  Note: DHCP-server msg / DHCP-client msg
 *   |  INIT   |
 *   +---------+
 *        |
 *        |  - / Discover
 *        V
 *   +---------+
 *   | SELECT  |                     Timeout
 *   +---------+                        |
 *        |                             |
 *        |  Offer / Request            |
 *        |                             |
 *        V                             V
 *   +---------+     NACK / -      ***********
 *   | REQUEST | ----------------> *  FAULT  *
 *   +---------+                   ***********
 *        |
 *        |          ACK / -       ***********
 *        +----------------------> * SUCCESS *
 *                                 ***********
 *
 * ************************************************************************
 * </pre> */


/********************** DEFINITIONS & DECLARATIONS ***********************/

#include <dhcp.h>
#include <ethernet.h>
#include <ipv4.h>
#include <udp.h>
#include <dns.h>
#include <netapps/args.h>

#include <stdio.h>
#include <string.h>
#include <time.h>
#include <sys/socket.h>
#include <ctype.h>
#include <stdlib.h>

/* DHCP Message Types */
#define DHCPDISCOVER    1
#define DHCPOFFER       2
#define DHCPREQUEST     3
#define DHCPDECLINE     4
#define DHCPACK	        5
#define DHCPNACK        6
#define DHCPRELEASE     7
#define DHCPINFORM      8

/* DHCP Option Codes */
#define DHCP_MASK              1
#define DHCP_ROUTER            3
#define DHCP_DNS               6
#define DHCP_REQUESTED_IP     50
#define DHCP_OVERLOAD         52
#define DHCP_MSG_TYPE         53
#define DHCP_SERVER_ID        54
#define DHCP_REQUEST_LIST     55
#define DHCP_TFTP_SERVER      66
#define DHCP_BOOTFILE         67
#define DHCP_CLIENT_ARCH      93
#define DHCP_ENDOPT         0xFF
#define DHCP_PADOPT         0x00

/* "file/sname" overload option values */
#define DHCP_OVERLOAD_FILE     1
#define DHCP_OVERLOAD_SNAME    2
#define DHCP_OVERLOAD_BOTH     3

/* DHCP states codes */
#define DHCP_STATE_SELECT      1
#define DHCP_STATE_REQUEST     2
#define DHCP_STATE_SUCCESS     3
#define DHCP_STATE_FAULT       4

/* DHCP Client Architecture */
#ifndef DHCPARCH
#define USE_DHCPARCH 0
#define DHCPARCH 0
#else
#define USE_DHCPARCH 1
#endif

static uint8_t dhcp_magic[] = {0x63, 0x82, 0x53, 0x63};
/**< DHCP_magic is a cookie, that identifies DHCP options (see RFC 2132) */

/** \struct dhcp_options_t
 *  This structure is used to fill options in DHCP-msg during transmitting
 *  or to retrieve options from DHCP-msg during receiving.
 *  <p>
 *  If flag[i] == TRUE then field for i-th option retains valid value and
 *  information from this field may retrived (in case of receiving) or will
 *  be transmitted (in case of transmitting).
 *
 */
typedef struct {
	uint8_t    flag[256];         /**< Show if corresponding opt. is valid */
	uint8_t    request_list[256]; /**< o.55 If i-th member is TRUE, then i-th
	                                  option will be requested from server */
	uint32_t   server_ID;         /**< o.54 Identifies DHCP-server         */
	uint32_t   requested_IP;      /**< o.50 Must be filled in DHCP-Request */
	uint32_t   dns_IP;            /**< o. 6 DNS IP                         */
	uint32_t   router_IP;         /**< o. 3 Router IP                      */
	uint32_t   subnet_mask;       /**< o. 1 Subnet mask                    */
	uint8_t    msg_type;          /**< o.53 DHCP-message type              */
	uint8_t    overload;          /**< o.52 Overload sname/file fields     */
	int8_t     tftp_server[256];  /**< o.66 TFTP server name               */
	int8_t     bootfile[256];     /**< o.67 Boot file name                 */
	uint16_t   client_arch;       /**< o.93 Client architecture type       */
} dhcp_options_t;

/** Stores state of DHCP-client (refer to State-transition diagram) */
static uint8_t dhcp_state;


/***************************** PROTOTYPES ********************************/

static int32_t dhcp_attempt(int fd);

static int32_t dhcp_encode_options(uint8_t * opt_field, dhcp_options_t * opt_struct);

static int32_t dhcp_decode_options(uint8_t opt_field[], uint32_t opt_len,
				   dhcp_options_t * opt_struct);

static int8_t dhcp_merge_options(uint8_t dst_options[], uint32_t * dst_len,
				 uint8_t src_options[], uint32_t src_len);

static int8_t dhcp_find_option(uint8_t options[], uint32_t len,
			       uint8_t op_code, uint32_t * op_offset);

static void dhcp_append_option(uint8_t dst_options[], uint32_t * dst_len,
			       uint8_t * new_option);

static void dhcp_combine_option(uint8_t dst_options[], uint32_t * dst_len,
				uint32_t dst_offset, uint8_t * new_option);

static void dhcp_send_discover(int fd);

static void dhcp_send_request(int fd);

/***************************** LOCAL VARIABLES ***************************/

static uint8_t  ether_packet[ETH_MTU_SIZE];
static uint32_t dhcp_own_ip        = 0;
static uint32_t dhcp_server_ip     = 0;
static uint32_t dhcp_siaddr_ip     = 0;
static char   dhcp_filename[256];
static char   dhcp_tftp_name[256];
static uint32_t dhcp_xid;

static char   * response_buffer;

/***************************** IMPLEMENTATION ****************************/

void dhcpv4_generate_transaction_id(void)
{
	dhcp_xid = (rand() << 16) ^ rand();
}

int32_t dhcpv4(char *ret_buffer, filename_ip_t *fn_ip)
{
	uint32_t dhcp_tftp_ip     = 0;
	int fd = fn_ip->fd;

	strcpy(dhcp_filename, "");
	strcpy(dhcp_tftp_name, "");

	response_buffer = ret_buffer;

	if (dhcp_attempt(fd) == 0)
		return -1;

	if (fn_ip->own_ip) {
		dhcp_own_ip = fn_ip->own_ip;
	}
	if (fn_ip->server_ip) {
		dhcp_siaddr_ip = fn_ip->server_ip;
	}
	if(fn_ip->filename[0] != 0) {
		strcpy(dhcp_filename, (char *) fn_ip->filename);
	}

	// TFTP SERVER
	if (!strlen(dhcp_tftp_name)) {
		if (!dhcp_siaddr_ip) {
			// ERROR: TFTP name is not presented
			return -3;
		}

		// take TFTP-ip from siaddr field
		dhcp_tftp_ip = dhcp_siaddr_ip;
	}
	else {
		// TFTP server defined by its name
		if (!strtoip(dhcp_tftp_name, (char *)&dhcp_tftp_ip)) {
			if (!dns_get_ip(fd, dhcp_tftp_name, (uint8_t *)&dhcp_tftp_ip, 4)) {
				// DNS error - can't obtain TFTP-server name
				// Use TFTP-ip from siaddr field, if presented
				if (dhcp_siaddr_ip) {
					dhcp_tftp_ip = dhcp_siaddr_ip;
				}
				else {
					// ERROR: Can't obtain TFTP server IP
					return -4;
				}
			}
		}
	}

	// Store configuration info into filename_ip strucutre
	fn_ip -> own_ip = dhcp_own_ip;
	fn_ip -> server_ip = dhcp_tftp_ip;
	strcpy((char *) fn_ip -> filename, dhcp_filename);

	return 0;
}

/**
 * DHCP: Tries o obtain DHCP parameters, refer to state-transition diagram
 */
static int32_t dhcp_attempt(int fd)
{
	int sec;

	// Send DISCOVER message and switch DHCP-client to SELECT state
	dhcp_send_discover(fd);

	dhcp_state = DHCP_STATE_SELECT;

	// setting up a timer with a timeout of two seconds
	for (sec = 0; sec < 2; sec++) {
		set_timer(TICKS_SEC);
		do {
			receive_ether(fd);

			// Wait until client will switch to Final state or Timeout occurs
			switch (dhcp_state) {
			case DHCP_STATE_SUCCESS :
				return 1;
			case DHCP_STATE_FAULT :
				return 0;
			}
		} while (get_timer() > 0);
	}

	// timeout
	return 0;
}

/**
 * DHCP: Supplements DHCP-message with options stored in structure.
 *       For more information about option coding see dhcp_options_t.
 *
 * @param  opt_field     Points to the "vend" field of DHCP-message
 *                       (destination)
 * @param  opt_struct    this structure stores info about the options which
 *                       will be added to DHCP-message (source)
 * @return               TRUE - options packed;
 *                       FALSE - error condition occurs.
 * @see                  dhcp_options_t
 */
static int32_t dhcp_encode_options(uint8_t * opt_field, dhcp_options_t * opt_struct)
{
	uint8_t * options = opt_field;
	uint16_t i, sum; // used to define is any options set

	// magic
	memcpy(options, dhcp_magic, 4);
	options += 4;

	// fill message type
	switch (opt_struct -> msg_type) {
	case DHCPDISCOVER :
	case DHCPREQUEST :
	case DHCPDECLINE :
	case DHCPINFORM :
	case DHCPRELEASE :
		options[0] = DHCP_MSG_TYPE;
		options[1] = 1;
		options[2] = opt_struct -> msg_type;
		options += 3;
		break;
	default :
		return 0; // Unsupported DHCP-message
	}

	if (opt_struct -> overload) {
		options[0] = DHCP_OVERLOAD;
		options[1] = 0x01;
		options[2] = opt_struct -> overload;
		options +=3;
	}

	if (opt_struct -> flag[DHCP_REQUESTED_IP]) {
		options[0] = DHCP_REQUESTED_IP;
		options[1] = 0x04;
		* (uint32_t *) (options + 2) = htonl (opt_struct -> requested_IP);
		options +=6;
	}

	if (opt_struct -> flag[DHCP_SERVER_ID]) {
		options[0] = DHCP_SERVER_ID;
		options[1] = 0x04;
		* (uint32_t *) (options + 2) = htonl (opt_struct -> server_ID);
		options +=6;
	}

	sum = 0;
	for (i = 0; i < 256; i++)
		sum += opt_struct -> request_list[i];

	if (sum) {
		options[0] = DHCP_REQUEST_LIST;
		options[1] = sum;
		options += 2;
		for (i = 0; i < 256; i++) {
			if (opt_struct -> request_list[i]) {
				options[0] = i; options++;
			}
		}
	}

	if (opt_struct -> flag[DHCP_TFTP_SERVER]) {
		options[0] = DHCP_TFTP_SERVER;
		options[1] = strlen((char *) opt_struct -> tftp_server) + 1;
		memcpy(options + 2, opt_struct -> tftp_server, options[1]);
		options += options[1] + 2;
	}

	if (opt_struct -> flag[DHCP_BOOTFILE]) {
		options[0] = DHCP_BOOTFILE;
		options[1] = strlen((char *) opt_struct -> bootfile) + 1;
		memcpy(options + 2, opt_struct -> bootfile, options[1]);
		options += options[1] + 2;
	}

	if (opt_struct -> flag[DHCP_CLIENT_ARCH]) {
		options[0] = DHCP_CLIENT_ARCH;
		options[1] = 2;
		options[2] = (DHCPARCH >> 8);
		options[3] = DHCPARCH & 0xff;
		options += 4;
	}

	// end options
	options[0] = 0xFF;
	options++;

	return 1;
}

/**
 * DHCP: Extracts encoded options from DHCP-message into the structure.
 *       For more information about option coding see dhcp_options_t.
 *
 * @param  opt_field     Points to the "options" field of DHCP-message
 *                       (source).
 * @param  opt_len       Length of "options" field.
 * @param  opt_struct    this structure stores info about the options which
 *                       was extracted from DHCP-message (destination).
 * @return               TRUE - options extracted;
 *                       FALSE - error condition occurs.
 * @see                  dhcp_options_t
 */
static int32_t dhcp_decode_options(uint8_t opt_field[], uint32_t opt_len,
				   dhcp_options_t * opt_struct)
{
	uint32_t offset = 0;

	memset(opt_struct, 0, sizeof(dhcp_options_t));

	// magic
	if (memcmp(opt_field, dhcp_magic, 4)) {
		return 0;
	}

	offset += 4;
	while (offset < opt_len) {
		opt_struct -> flag[opt_field[offset]] = 1;
		switch(opt_field[offset]) {
		case DHCP_OVERLOAD :
			opt_struct -> overload = opt_field[offset + 2];
			offset += 2 + opt_field[offset + 1];
			break;

		case DHCP_REQUESTED_IP :
			opt_struct -> requested_IP = htonl(* (uint32_t *) (opt_field + offset + 2));
			offset += 2 + opt_field[offset + 1];
			break;

		case DHCP_MASK :
			opt_struct -> flag[DHCP_MASK] = 1;
			opt_struct -> subnet_mask = htonl(* (uint32_t *) (opt_field + offset + 2));
			offset += 2 + opt_field[offset + 1];
			break;

		case DHCP_DNS :
			opt_struct -> flag[DHCP_DNS] = 1;
			opt_struct -> dns_IP = htonl(* (uint32_t *) (opt_field + offset + 2));
			offset += 2 + opt_field[offset + 1];
			break;

		case DHCP_ROUTER :
			opt_struct -> flag[DHCP_ROUTER] = 1;
			opt_struct -> router_IP = htonl(* (uint32_t *) (opt_field + offset + 2));
			offset += 2 + opt_field[offset + 1];
			break;

		case DHCP_MSG_TYPE :
			if ((opt_field[offset + 2] > 0) && (opt_field[offset + 2] < 9))
				opt_struct -> msg_type = opt_field[offset + 2];
			else
				return 0;
			offset += 2 + opt_field[offset + 1];
			break;

		case DHCP_SERVER_ID :
			opt_struct -> server_ID = htonl(* (uint32_t *) (opt_field + offset + 2));
			offset += 2 + opt_field[offset + 1];
			break;

		case DHCP_TFTP_SERVER	:
			memcpy(opt_struct -> tftp_server, opt_field + offset + 2, opt_field[offset + 1]);
			(opt_struct -> tftp_server)[opt_field[offset + 1]] = 0;
			offset += 2 + opt_field[offset + 1];
			break;

		case DHCP_BOOTFILE :
			memcpy(opt_struct ->  bootfile, opt_field + offset + 2, opt_field[offset + 1]);
			(opt_struct -> bootfile)[opt_field[offset + 1]] = 0;
			offset += 2 + opt_field[offset + 1];
			break;

		case DHCP_CLIENT_ARCH :
			opt_struct -> client_arch = ((opt_field[offset + 2] << 8) & 0xFF00) | (opt_field[offset + 3] & 0xFF);
			offset += 4;
			break;

		case DHCP_PADOPT :
			offset++;
			break;

		case DHCP_ENDOPT :  // End of options
			return 1;

		default :
			offset += 2 + opt_field[offset + 1]; // Unsupported opt. - do nothing
		}
	}
	if (offset == opt_len)
		return 1; // options finished without 0xFF

	return 0;
}

/**
 * DHCP: Appends information from source "options" into dest "options".
 *       This function is used to support "file/sname" overloading.
 *
 * @param  dst_options   destanation "options" field
 * @param  dst_len       size of dst_options (modified by this function)
 * @param  src_options   source "options" field
 * @param  src_len       size of src_options
 * @return               TRUE - options merged;
 *                       FALSE - error condition occurs.
 */
static int8_t dhcp_merge_options(uint8_t dst_options[], uint32_t * dst_len,
				 uint8_t src_options[], uint32_t src_len)
{
	uint32_t dst_offset, src_offset = 0;

	// remove ENDOPT if presented
	if (dhcp_find_option(dst_options, * dst_len, DHCP_ENDOPT, &dst_offset))
		* dst_len = dst_offset;

	while (src_offset < src_len) {
		switch(src_options[src_offset]) {
		case DHCP_PADOPT:
			src_offset++;
			break;
		case DHCP_ENDOPT:
			return 1;
		default:
			if (dhcp_find_option(dst_options, * dst_len,
			                     src_options[src_offset],
			                     &dst_offset)) {
				dhcp_combine_option(dst_options, dst_len,
				                    dst_offset,
				                    (uint8_t *) src_options +
				                    src_offset);
			}
			else {
				dhcp_append_option(dst_options, dst_len, src_options + src_offset);
			}
			src_offset += 2 + src_options[src_offset + 1];
		}
	}

	if (src_offset == src_len)
		return 1;
	return 0;
}

/**
 * DHCP: Finds given occurrence of the option with the given code (op_code)
 *       in "options" field of DHCP-message.
 *
 * @param  options       "options" field of DHCP-message
 * @param  len           length of the "options" field
 * @param  op_code       code of the option to find
 * @param  op_offset     SUCCESS - offset to an option occurrence;
 *                       FAULT - offset is set to zero.
 * @return               TRUE - option was find;
 *                       FALSE - option wasn't find.
 */
static int8_t dhcp_find_option(uint8_t options[], uint32_t len,
			       uint8_t op_code, uint32_t * op_offset)
{
	uint32_t srch_offset = 0;
	* op_offset = 0;

	while (srch_offset < len) {
		if (options[srch_offset] == op_code) {
			* op_offset = srch_offset;
			return 1;
		}
		if (options[srch_offset] == DHCP_ENDOPT)
			return 0;

		if (options[srch_offset] == DHCP_PADOPT)
			srch_offset++;
		else
			srch_offset += 2 + options[srch_offset + 1];
	}
	return 0;
}

/**
 * DHCP: Appends new option from one list (src) into the tail
 *       of another option list (dst)
 *
 * @param  dst_options   "options" field of DHCP-message
 * @param  dst_len       length of the "options" field (modified)
 * @param  new_option    points to an option in another list (src)
 */
static void dhcp_append_option(uint8_t dst_options[], uint32_t * dst_len,
			       uint8_t * new_option)
{
	memcpy(dst_options + ( * dst_len), new_option, 2 + (* (new_option + 1)));
	* dst_len += 2 + *(new_option + 1);
}

/**
 * DHCP: This function is used when options with the same code are
 *       presented in both merged lists. In this case information
 *       about the option from one list (src) is combined (complemented)
 *       with information about the option in another list (dst).
 *
 * @param  dst_options  "options" field of DHCP-message
 * @param  dst_len       length of the "options" field (modified)
 * @param  dst_offset    offset of the option from beginning of the list
 * @param  new_option    points to an option in another list (src)
 */
static void dhcp_combine_option(uint8_t dst_options[], uint32_t * dst_len,
				uint32_t dst_offset, uint8_t * new_option)
{
	uint8_t tmp_buffer[1024]; // use to provide safe memcpy
	uint32_t tail_len;

	// move all subsequent options (allocate size for additional info)
	tail_len = (* dst_len) - dst_offset - 2 - dst_options[dst_offset + 1];

	memcpy(tmp_buffer, dst_options + (* dst_len) - tail_len, tail_len);
	memcpy(dst_options + (* dst_len) - tail_len + (* (new_option + 1)),
	       tmp_buffer, tail_len);

	// add new_content to option
	memcpy(dst_options + (* dst_len) - tail_len, new_option + 2,
	       * (new_option + 1));
	dst_options[dst_offset + 1] += * (new_option + 1);

	// correct dst_len
	* dst_len += * (new_option + 1);
}

/**
 * DHCP: Sends DHCP-Discover message. Looks for DHCP servers.
 */
static void dhcp_send_discover(int fd)
{
	uint32_t packetsize = sizeof(struct iphdr) +
	                      sizeof(struct udphdr) + sizeof(struct btphdr);
	struct btphdr *btph;
	dhcp_options_t opt;

	memset(ether_packet, 0, packetsize);

	btph = (struct btphdr *) (&ether_packet[
	       sizeof(struct iphdr) + sizeof(struct udphdr)]);

	btph -> op = 1;
	btph -> htype = 1;
	btph -> hlen = 6;
	btph -> xid = dhcp_xid;
	memcpy(btph -> chaddr, get_mac_address(), 6);

	memset(&opt, 0, sizeof(dhcp_options_t));

	opt.msg_type = DHCPDISCOVER;

	opt.request_list[DHCP_MASK] = 1;
	opt.request_list[DHCP_DNS] = 1;
	opt.request_list[DHCP_ROUTER] = 1;
	opt.request_list[DHCP_TFTP_SERVER] = 1;
	opt.request_list[DHCP_BOOTFILE] = 1;
	opt.request_list[DHCP_CLIENT_ARCH] = USE_DHCPARCH;

	dhcp_encode_options(btph -> vend, &opt);

	fill_udphdr(&ether_packet[sizeof(struct iphdr)],
	            sizeof(struct btphdr) + sizeof(struct udphdr),
	            UDPPORT_BOOTPC, UDPPORT_BOOTPS);
	fill_iphdr(ether_packet, sizeof(struct btphdr) +
	           sizeof(struct udphdr) + sizeof(struct iphdr),
	           IPTYPE_UDP, dhcp_own_ip, 0xFFFFFFFF);

	send_ipv4(fd, ether_packet, packetsize);
}

/**
 * DHCP: Sends DHCP-Request message. Asks for acknowledgment to occupy IP.
 */
static void dhcp_send_request(int fd)
{
	uint32_t packetsize = sizeof(struct iphdr) +
	                      sizeof(struct udphdr) + sizeof(struct btphdr);
	struct btphdr *btph;
	dhcp_options_t opt;

	memset(ether_packet, 0, packetsize);

	btph = (struct btphdr *) (&ether_packet[
	       sizeof(struct iphdr) + sizeof(struct udphdr)]);

	btph -> op = 1;
	btph -> htype = 1;
	btph -> hlen = 6;
	btph -> xid = dhcp_xid;
	memcpy(btph -> chaddr, get_mac_address(), 6);

	memset(&opt, 0, sizeof(dhcp_options_t));

	opt.msg_type = DHCPREQUEST;
	memcpy(&(opt.requested_IP), &dhcp_own_ip, 4);
	opt.flag[DHCP_REQUESTED_IP] = 1;
	memcpy(&(opt.server_ID), &dhcp_server_ip, 4);
	opt.flag[DHCP_SERVER_ID] = 1;

	opt.request_list[DHCP_MASK] = 1;
	opt.request_list[DHCP_DNS] = 1;
	opt.request_list[DHCP_ROUTER] = 1;
	opt.request_list[DHCP_TFTP_SERVER] = 1;
	opt.request_list[DHCP_BOOTFILE] = 1;
	opt.request_list[DHCP_CLIENT_ARCH] = USE_DHCPARCH;
	opt.flag[DHCP_CLIENT_ARCH] = USE_DHCPARCH;

	dhcp_encode_options(btph -> vend, &opt);

	fill_udphdr(&ether_packet[sizeof(struct iphdr)],
	            sizeof(struct btphdr) + sizeof(struct udphdr),
	            UDPPORT_BOOTPC, UDPPORT_BOOTPS);
	fill_iphdr(ether_packet, sizeof(struct btphdr) +
	           sizeof(struct udphdr) + sizeof(struct iphdr),
	           IPTYPE_UDP, 0, 0xFFFFFFFF);

	send_ipv4(fd, ether_packet, packetsize);
}


/**
 * DHCP: Sends DHCP-Release message. Releases occupied IP.
 */
void dhcp_send_release(int fd)
{
	uint32_t packetsize = sizeof(struct iphdr) +
	                      sizeof(struct udphdr) + sizeof(struct btphdr);
	struct btphdr *btph;
	dhcp_options_t opt;

	btph = (struct btphdr *) (&ether_packet[
	       sizeof(struct iphdr) + sizeof(struct udphdr)]);

	memset(ether_packet, 0, packetsize);

	btph -> op = 1;
	btph -> htype = 1;
	btph -> hlen = 6;
	btph -> xid = dhcp_xid;
	strcpy((char *) btph -> file, "");
	memcpy(btph -> chaddr, get_mac_address(), 6);
	btph -> ciaddr = htonl(dhcp_own_ip);

	memset(&opt, 0, sizeof(dhcp_options_t));

	opt.msg_type = DHCPRELEASE;
	opt.server_ID = dhcp_server_ip;
	opt.flag[DHCP_SERVER_ID] = 1;

	dhcp_encode_options(btph -> vend, &opt);

	fill_udphdr(&ether_packet[sizeof(struct iphdr)],
	            sizeof(struct btphdr) + sizeof(struct udphdr),
	            UDPPORT_BOOTPC, UDPPORT_BOOTPS);
	fill_iphdr(ether_packet, sizeof(struct btphdr) +
	           sizeof(struct udphdr) + sizeof(struct iphdr), IPTYPE_UDP,
	           dhcp_own_ip, dhcp_server_ip);

	send_ipv4(fd, ether_packet, packetsize);
}

/**
 * DHCP: Handles DHCP-messages according to Receive-handle diagram.
 *       Changes the state of DHCP-client.
 *
 * @param  fd         socket descriptor
 * @param  packet     BootP/DHCP-packet to be handled
 * @param  packetsize length of the packet
 * @return            ZERO - packet handled successfully;
 *                    NON ZERO - packet was not handled (e.g. bad format)
 * @see               receive_ether
 * @see               btphdr
 */

int8_t handle_dhcp(int fd, uint8_t * packet, int32_t packetsize)
{
	struct btphdr * btph;
	struct iphdr * iph;
	dhcp_options_t opt;

	memset(&opt, 0, sizeof(dhcp_options_t));
	btph = (struct btphdr *) packet;
	iph = (struct iphdr *) packet - sizeof(struct udphdr) -
	      sizeof(struct iphdr);

	if (btph->op != 2)
		return -1;		/* It is not a Bootp/DHCP reply */
	if (btph->xid != dhcp_xid)
		return -1;		/* The transaction ID does not match */

	if (memcmp(btph -> vend, dhcp_magic, 4)) {
		// It is BootP - RFC 951
		dhcp_own_ip    = htonl(btph -> yiaddr);
		dhcp_siaddr_ip = htonl(btph -> siaddr);
		dhcp_server_ip = htonl(iph -> ip_src);

		if (strlen((char *) btph -> sname) && !dhcp_siaddr_ip) {
			strncpy((char *) dhcp_tftp_name, (char *) btph -> sname,
			        sizeof(btph -> sname));
			dhcp_tftp_name[sizeof(btph -> sname)] = 0;
		}

		if (strlen((char *) btph -> file)) {
			strncpy((char *) dhcp_filename, (char *) btph -> file, sizeof(btph -> file));
			dhcp_filename[sizeof(btph -> file)] = 0;
		}

		dhcp_state = DHCP_STATE_SUCCESS;
		return 0;
	}


	// decode options
	if (!dhcp_decode_options(btph -> vend, packetsize -
	                         sizeof(struct btphdr) + sizeof(btph -> vend),
	                         &opt)) {
		return -1;  // can't decode options
	}

	if (opt.overload) {
		int16_t decode_res = 0;
		uint8_t options[1024]; // buffer for merged options
		uint32_t opt_len;

		// move 1-st part of options from vend field into buffer
		opt_len = packetsize - sizeof(struct btphdr) +
		          sizeof(btph -> vend) - 4;
		memcpy(options, btph -> vend, opt_len + 4);

		// add other parts
		switch (opt.overload) {
		case DHCP_OVERLOAD_FILE:
			decode_res = dhcp_merge_options(options + 4, &opt_len,
			                                btph -> file,
			                                sizeof(btph -> file));
			break;
		case DHCP_OVERLOAD_SNAME:
			decode_res = dhcp_merge_options(options + 4, &opt_len,
			                                btph -> sname,
			                                sizeof(btph -> sname));
			break;
		case DHCP_OVERLOAD_BOTH:
			decode_res = dhcp_merge_options(options + 4, &opt_len,
			                                btph -> file,
			                                sizeof(btph -> file));
			if (!decode_res)
				break;
			decode_res = dhcp_merge_options(options + 4, &opt_len,
			                                btph -> sname,
			                                sizeof(btph -> sname));
			break;
		}

		if (!decode_res)
			return -1; // bad options in sname/file fields

		// decode merged options
		if (!dhcp_decode_options(options, opt_len + 4, &opt)) {
			return -1; // can't decode options
		}
	}

	if (!opt.msg_type) {
		// It is BootP with Extensions - RFC 1497
		// retrieve conf. settings from BootP - reply
		dhcp_own_ip = htonl(btph -> yiaddr);
		dhcp_siaddr_ip = htonl(btph -> siaddr);
		if (strlen((char *) btph -> sname) && !dhcp_siaddr_ip) {
			strncpy((char *) dhcp_tftp_name, (char *) btph -> sname, sizeof(btph -> sname));
			dhcp_tftp_name[sizeof(btph -> sname)] = 0;
		}

		if (strlen((char *) btph -> file)) {
			strncpy((char *) dhcp_filename, (char *) btph -> file, sizeof(btph -> file));
			dhcp_filename[sizeof(btph -> file)] = 0;
		}

		// retrieve DHCP-server IP from IP-header
		dhcp_server_ip = iph -> htonl(ip_src);

		dhcp_state = DHCP_STATE_SUCCESS;
	}
	else {
		// It is DHCP - RFC 2131 & RFC 2132
		// opt contains parameters from server
		switch (dhcp_state) {
		case DHCP_STATE_SELECT :
			if (opt.msg_type == DHCPOFFER) {
				dhcp_own_ip = htonl(btph -> yiaddr);
				dhcp_server_ip = opt.server_ID;
				dhcp_send_request(fd);
				dhcp_state = DHCP_STATE_REQUEST;
			}
			return 0;
		case DHCP_STATE_REQUEST :
			switch (opt.msg_type) {
			case DHCPNACK :
				dhcp_own_ip = 0;
				dhcp_server_ip = 0;
				dhcp_state = DHCP_STATE_FAULT;
				break;
			case DHCPACK :
				dhcp_own_ip = htonl(btph -> yiaddr);
				dhcp_server_ip = opt.server_ID;
				dhcp_siaddr_ip = htonl(btph -> siaddr);
				if (opt.flag[DHCP_TFTP_SERVER]) {
					strcpy((char *) dhcp_tftp_name, (char *) opt.tftp_server);
				}
				else {
					strcpy((char *) dhcp_tftp_name, "");
					if ((opt.overload != DHCP_OVERLOAD_SNAME &&
					     opt.overload != DHCP_OVERLOAD_BOTH) &&
					     !dhcp_siaddr_ip) {
						strncpy((char *) dhcp_tftp_name,
						        (char *) btph->sname,
						        sizeof(btph -> sname));
						dhcp_tftp_name[sizeof(btph->sname)] = 0;
					}
				}

				if (opt.flag[DHCP_BOOTFILE]) {
					strcpy((char *) dhcp_filename, (char *) opt.bootfile);
				}
				else {
					strcpy((char *) dhcp_filename, "");
					if (opt.overload != DHCP_OVERLOAD_FILE &&
						opt.overload != DHCP_OVERLOAD_BOTH &&
						strlen((char *) btph -> file)) {
						strncpy((char *) dhcp_filename,
						        (char *) btph->file,
						        sizeof(btph->file));
						dhcp_filename[sizeof(btph -> file)] = 0;
					}
				}

				dhcp_state = DHCP_STATE_SUCCESS;
				break;
			default:
				break; // Unused DHCP-message - do nothing
			}
			break;
		default :
			return -1; // Illegal DHCP-client state
		}
	}

	if (dhcp_state == DHCP_STATE_SUCCESS) {

		// initialize network entity with real own_ip
		// to be able to answer for foreign requests
		set_ipv4_address(dhcp_own_ip);

		if(response_buffer) {
			if(packetsize <= 1720)
				memcpy(response_buffer, packet, packetsize);
			else
				memcpy(response_buffer, packet, 1720);
		}

		/* Subnet mask */
		if (opt.flag[DHCP_MASK]) {
			/* Router */
			if (opt.flag[DHCP_ROUTER]) {
				set_ipv4_router(opt.router_IP);
				set_ipv4_netmask(opt.subnet_mask);
			}
		}

		/* DNS-server */
		if (opt.flag[DHCP_DNS]) {
			dns_init(opt.dns_IP, 0, 4);
		}
	}

	return 0;
}
