/******************************************************************************
 * 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
 *****************************************************************************/

#include <netlib/tftp.h>
#include <netlib/ethernet.h>
#include <netlib/dhcp.h>
#include <netlib/dhcpv6.h>
#include <netlib/ipv4.h>
#include <netlib/ipv6.h>
#include <netlib/dns.h>
#include <string.h>
#include <stdio.h>
#include <time.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <netapps/args.h>
#include <libbootmsg/libbootmsg.h>
#include <of.h>
#include "netapps.h"

#define IP_INIT_DEFAULT 5
#define IP_INIT_NONE    0
#define IP_INIT_BOOTP   1
#define IP_INIT_DHCP    2
#define IP_INIT_DHCPV6_STATELESS    3
#define IP_INIT_IPV6_MANUAL         4

#define DEFAULT_BOOT_RETRIES 10
#define DEFAULT_TFTP_RETRIES 20
static int ip_version = 4;

typedef struct {
	char filename[100];
	int  ip_init;
	char siaddr[4];
	ip6_addr_t si6addr;
	char ciaddr[4];
	ip6_addr_t ci6addr;
	char giaddr[4];
	ip6_addr_t gi6addr;
	int  bootp_retries;
	int  tftp_retries;
} obp_tftp_args_t;


/**
 * Parses a argument string for IPv6 booting, extracts all
 * parameters and fills a structure accordingly
 *
 * @param  arg_str        string with arguments, separated with ','
 * @param  argc           number of arguments
 * @param  obp_tftp_args  structure which contains the result
 * @return                updated arg_str
 */
static const char * 
parse_ipv6args (const char *arg_str, unsigned int argc,
		obp_tftp_args_t *obp_tftp_args)
{
	char *ptr = NULL;
	char arg_buf[100];

	// find out siaddr
	if (argc == 0)
		memset(&obp_tftp_args->si6addr.addr, 0, 16);
	else {
		argncpy(arg_str, 0, arg_buf, 100);
		if(str_to_ipv6(arg_buf, (uint8_t *) &(obp_tftp_args->si6addr.addr[0]))) {
			arg_str = get_arg_ptr(arg_str, 1);
			--argc;
		}
		else if(arg_buf[0] == 0) {
			memset(&obp_tftp_args->si6addr.addr, 0, 16);
			arg_str = get_arg_ptr(arg_str, 1);
			--argc;
		}
		else
			memset(&obp_tftp_args->si6addr.addr, 0, 16);
	}

	// find out filename
	if (argc == 0)
		obp_tftp_args->filename[0] = 0;
	else {
		argncpy(arg_str, 0, obp_tftp_args->filename, 100);
		for(ptr = obp_tftp_args->filename; *ptr != 0; ++ptr)
			if(*ptr == '\\') {
				*ptr = '/';
			}
		arg_str = get_arg_ptr(arg_str, 1);
		--argc;
	}

	// find out ciaddr
	if (argc == 0)
		memset(&obp_tftp_args->ci6addr, 0, 16);
	else {
		argncpy(arg_str, 0, arg_buf, 100);
		if (str_to_ipv6(arg_buf, (uint8_t *) &(obp_tftp_args->ci6addr.addr[0]))) {
			arg_str = get_arg_ptr(arg_str, 1);
			--argc;
		}
		else if(arg_buf[0] == 0) {
			memset(&obp_tftp_args->ci6addr.addr, 0, 16);
			arg_str = get_arg_ptr(arg_str, 1);
			--argc;
		}
		else
			memset(&obp_tftp_args->ci6addr.addr, 0, 16);
	}

	// find out giaddr
	if (argc == 0)
		memset(&obp_tftp_args->gi6addr, 0, 16);
	else {
		argncpy(arg_str, 0, arg_buf, 100);
		if (str_to_ipv6(arg_buf, (uint8_t *) &(obp_tftp_args->gi6addr.addr)) ) {
			arg_str = get_arg_ptr(arg_str, 1);
			--argc;
		}
		else if(arg_buf[0] == 0) {
			memset(&obp_tftp_args->gi6addr, 0, 16);
			arg_str = get_arg_ptr(arg_str, 1);
			--argc;
		}
		else
			memset(&obp_tftp_args->gi6addr.addr, 0, 16);
	}

	return arg_str;
}


/**
 * Parses a argument string for IPv4 booting, extracts all
 * parameters and fills a structure accordingly
 *
 * @param  arg_str        string with arguments, separated with ','
 * @param  argc           number of arguments
 * @param  obp_tftp_args  structure which contains the result
 * @return                updated arg_str
 */
static const char * 
parse_ipv4args (const char *arg_str, unsigned int argc,
		obp_tftp_args_t *obp_tftp_args)
{
	char *ptr = NULL;
	char arg_buf[100];

	// find out siaddr
	if(argc==0) {
		memset(obp_tftp_args->siaddr, 0, 4);
	} else {
		argncpy(arg_str, 0, arg_buf, 100);
		if(strtoip(arg_buf, obp_tftp_args->siaddr)) {
			arg_str = get_arg_ptr(arg_str, 1);
			--argc;
		}
		else if(arg_buf[0] == 0) {
			memset(obp_tftp_args->siaddr, 0, 4);
			arg_str = get_arg_ptr(arg_str, 1);
			--argc;
		}
		else
			memset(obp_tftp_args->siaddr, 0, 4);
	}

	// find out filename
	if(argc==0)
		obp_tftp_args->filename[0] = 0;
	else {
		argncpy(arg_str, 0, obp_tftp_args->filename, 100);
		for(ptr = obp_tftp_args->filename; *ptr != 0; ++ptr)
			if(*ptr == '\\')
				*ptr = '/';
		arg_str = get_arg_ptr(arg_str, 1);
		--argc;
	}

	// find out ciaddr
	if(argc==0)
		memset(obp_tftp_args->ciaddr, 0, 4);
	else {
		argncpy(arg_str, 0, arg_buf, 100);
		if(strtoip(arg_buf, obp_tftp_args->ciaddr)) {
			arg_str = get_arg_ptr(arg_str, 1);
			--argc;
		}
		else if(arg_buf[0] == 0) {
			memset(obp_tftp_args->ciaddr, 0, 4);
			arg_str = get_arg_ptr(arg_str, 1);
			--argc;
		}
		else
			memset(obp_tftp_args->ciaddr, 0, 4);
	}

	// find out giaddr
	if(argc==0)
		memset(obp_tftp_args->giaddr, 0, 4);
	else {
		argncpy(arg_str, 0, arg_buf, 100);
		if(strtoip(arg_buf, obp_tftp_args->giaddr)) {
			arg_str = get_arg_ptr(arg_str, 1);
			--argc;
		}
		else if(arg_buf[0] == 0) {
			memset(obp_tftp_args->giaddr, 0, 4);
			arg_str = get_arg_ptr(arg_str, 1);
			--argc;
		}
		else
			memset(obp_tftp_args->giaddr, 0, 4);
	}

	return arg_str;
}

/**
 * Parses a argument string which is given by netload, extracts all
 * parameters and fills a structure according to this
 *
 * Netload-Parameters:
 *    [bootp,]siaddr,filename,ciaddr,giaddr,bootp-retries,tftp-retries
 *
 * @param  arg_str        string with arguments, separated with ','
 * @param  obp_tftp_args  structure which contains the result
 * @return                none
 */
static void
parse_args(const char *arg_str, obp_tftp_args_t *obp_tftp_args)
{
	unsigned int argc;
	char arg_buf[100];

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

	argc = get_args_count(arg_str);

	// find out if we should use BOOTP or DHCP
	if(argc==0)
		obp_tftp_args->ip_init = IP_INIT_DEFAULT;
	else {
		argncpy(arg_str, 0, arg_buf, 100);
		if (strcasecmp(arg_buf, "bootp") == 0) {
			obp_tftp_args->ip_init = IP_INIT_BOOTP;
			arg_str = get_arg_ptr(arg_str, 1);
			--argc;
		}
		else if(strcasecmp(arg_buf, "dhcp") == 0) {
			obp_tftp_args->ip_init = IP_INIT_DHCP;
			arg_str = get_arg_ptr(arg_str, 1);
			--argc;
		}
		else if(strcasecmp(arg_buf, "ipv6") == 0) {
			obp_tftp_args->ip_init = IP_INIT_DHCPV6_STATELESS;
			arg_str = get_arg_ptr(arg_str, 1);
			--argc;
			ip_version = 6;
		}
		else
			obp_tftp_args->ip_init = IP_INIT_DEFAULT;
	}

	if (ip_version == 4) {
		arg_str = parse_ipv4args (arg_str, argc, obp_tftp_args);
	}
	else if (ip_version == 6) {
		arg_str = parse_ipv6args (arg_str, argc, obp_tftp_args);
	}

	// find out bootp-retries
	if (argc == 0)
		obp_tftp_args->bootp_retries = DEFAULT_BOOT_RETRIES;
	else {
		argncpy(arg_str, 0, arg_buf, 100);
		if(arg_buf[0] == 0)
			obp_tftp_args->bootp_retries = DEFAULT_BOOT_RETRIES;
		else {
			obp_tftp_args->bootp_retries = strtol(arg_buf, 0, 10);
			if(obp_tftp_args->bootp_retries < 0)
				obp_tftp_args->bootp_retries = DEFAULT_BOOT_RETRIES;
		}
		arg_str = get_arg_ptr(arg_str, 1);
		--argc;
	}

	// find out tftp-retries
	if (argc == 0)
		obp_tftp_args->tftp_retries = DEFAULT_TFTP_RETRIES;
	else {
		argncpy(arg_str, 0, arg_buf, 100);
		if(arg_buf[0] == 0)
			obp_tftp_args->tftp_retries = DEFAULT_TFTP_RETRIES;
		else {
			obp_tftp_args->tftp_retries = strtol(arg_buf, 0, 10);
			if(obp_tftp_args->tftp_retries < 0)
				obp_tftp_args->tftp_retries = DEFAULT_TFTP_RETRIES;
		}
		arg_str = get_arg_ptr(arg_str, 1);
		--argc;
	}
}

/**
 * DHCP: Wrapper for obtaining IP and configuration info from DHCP server
 *       for both IPv4 and IPv6.
 *       (makes several attempts).
 *
 * @param  ret_buffer    buffer for returning BOOTP-REPLY packet data
 * @param  fn_ip         contains the following configuration information:
 *                       client MAC, client IP, TFTP-server MAC,
 *                       TFTP-server IP, Boot file name
 * @param  retries       No. of DHCP attempts
 * @param  flags         flags for specifying type of dhcp attempt (IPv4/IPv6)
 *                       ZERO   - attempt DHCPv4 followed by DHCPv6
 *                       F_IPV4 - attempt only DHCPv4
 *                       F_IPV6 - attempt only DHCPv6
 * @return               ZERO - IP and configuration info obtained;
 *                       NON ZERO - error condition occurs.
 */
int dhcp(char *ret_buffer, filename_ip_t * fn_ip, unsigned int retries, int flags)
{
	int i = (int) retries+1;
	int rc = -1;

	printf("    ");

	do {
		printf("\b\b\b%03d", i-1);
		if (getchar() == 27) {
			printf("\nAborted\n");
			return -1;
		}
		if (!--i) {
			printf("\nGiving up after %d DHCP requests\n", retries);
			return -1;
		}
		if (!flags || (flags == F_IPV4)) {
			ip_version = 4;
			rc = dhcpv4(ret_buffer, fn_ip);
		}
		if ((!flags && (rc == -1)) || (flags == F_IPV6)) {
			ip_version = 6;
			set_ipv6_address(0);
			rc = dhcpv6(ret_buffer, fn_ip);
			if (rc == 0) {
				printf("\n");
				memcpy(&fn_ip->own_ip6, get_ipv6_address(), 16);
				break;
			}

		}
		if (rc != -1) /* either success or non-dhcp failure */
			break;
	} while (1);
	printf("\b\b\b\b");

	return rc;
}

int
netboot(int argc, char *argv[])
{
	char buf[256];
	int rc;
	int len = strtol(argv[2], 0, 16);
	char *buffer = (char *) strtol(argv[1], 0, 16);
	char *ret_buffer = (char *) strtol(argv[3], 0, 16);
	filename_ip_t fn_ip;
	int fd_device;
	tftp_err_t tftp_err;
	obp_tftp_args_t obp_tftp_args;
	char null_ip[4] = { 0x00, 0x00, 0x00, 0x00 };
	char null_ip6[16] = { 0x00, 0x00, 0x00, 0x00,
			     0x00, 0x00, 0x00, 0x00,
			     0x00, 0x00, 0x00, 0x00, 
			     0x00, 0x00, 0x00, 0x00 };
	int huge_load = strtol(argv[4], 0, 10);
	int32_t block_size = strtol(argv[5], 0, 10);
	uint8_t own_mac[6];

	printf("\n");
	printf(" Bootloader 1.6 \n");
	memset(&fn_ip, 0, sizeof(filename_ip_t));

	/***********************************************************
	 *
	 * Initialize network stuff and retrieve boot informations
	 *
	 ***********************************************************/

	/* Wait for link up and get mac_addr from device */
	for(rc=0; rc<DEFAULT_BOOT_RETRIES; ++rc) {
		if(rc > 0) {
			set_timer(TICKS_SEC);
			while (get_timer() > 0);
		}
		fd_device = socket(0, 0, 0, (char*) own_mac);
		if(fd_device != -2)
			break;
		if(getchar() == 27) {
			fd_device = -2;
			break;
		}
	}

	if (fd_device == -1) {
		strcpy(buf,"E3000: (net) Could not read MAC address");
		bootmsg_error(0x3000, &buf[7]);

		write_mm_log(buf, strlen(buf), 0x91);
		return -100;
	}
	else if (fd_device == -2) {
		strcpy(buf,"E3006: (net) Could not initialize network device");
		bootmsg_error(0x3006, &buf[7]);

		write_mm_log(buf, strlen(buf), 0x91);
		return -101;
	}

	printf("  Reading MAC address from device: "
	       "%02x:%02x:%02x:%02x:%02x:%02x\n",
	       own_mac[0], own_mac[1], own_mac[2],
	       own_mac[3], own_mac[4], own_mac[5]);

	// init ethernet layer
	set_mac_address(own_mac);

	if (argc > 6) {
		parse_args(argv[6], &obp_tftp_args);
		if(obp_tftp_args.bootp_retries - rc < DEFAULT_BOOT_RETRIES)
			obp_tftp_args.bootp_retries = DEFAULT_BOOT_RETRIES;
		else
			obp_tftp_args.bootp_retries -= rc;
	}
	else {
		memset(&obp_tftp_args, 0, sizeof(obp_tftp_args_t));
		obp_tftp_args.ip_init = IP_INIT_DEFAULT;
		obp_tftp_args.bootp_retries = DEFAULT_BOOT_RETRIES;
		obp_tftp_args.tftp_retries = DEFAULT_TFTP_RETRIES;
	}
	memcpy(&fn_ip.own_ip, obp_tftp_args.ciaddr, 4);

	//  reset of error code
	rc = 0;

	/* if we still have got all necessary parameters, then we don't
	   need to perform an BOOTP/DHCP-Request */
	if (ip_version == 4) {
		if (memcmp(obp_tftp_args.ciaddr, null_ip, 4) != 0
		    && memcmp(obp_tftp_args.siaddr, null_ip, 4) != 0
		    && obp_tftp_args.filename[0] != 0) {

			memcpy(&fn_ip.server_ip, &obp_tftp_args.siaddr, 4);
			obp_tftp_args.ip_init = IP_INIT_NONE;
		}
	}
	else if (ip_version == 6) {
		if (memcmp(&obp_tftp_args.ci6addr, null_ip6, 16) != 0
		    && memcmp(&obp_tftp_args.si6addr, null_ip6, 16) != 0
		    && obp_tftp_args.filename[0] != 0) {

			memcpy(&fn_ip.server_ip6.addr[0],
			       &obp_tftp_args.si6addr.addr, 16);
			obp_tftp_args.ip_init = IP_INIT_IPV6_MANUAL;
		}
		else {
			obp_tftp_args.ip_init = IP_INIT_DHCPV6_STATELESS;
		}
	}

	// construction of fn_ip from parameter
	switch(obp_tftp_args.ip_init) {
	case IP_INIT_BOOTP:
		printf("  Requesting IP address via BOOTP: ");
		// if giaddr in not specified, then we have to identify
		// the BOOTP server via broadcasts
		if(memcmp(obp_tftp_args.giaddr, null_ip, 4) == 0) {
			// don't do this, when using DHCP !!!
			fn_ip.server_ip = 0xFFFFFFFF;
		}
		// if giaddr is specified, then we have to use this
		// IP address as proxy to identify the BOOTP server
		else {
			memcpy(&fn_ip.server_ip, obp_tftp_args.giaddr, 4);
		}
		rc = bootp(ret_buffer, &fn_ip, obp_tftp_args.bootp_retries);
		break;
	case IP_INIT_DHCP:
		printf("  Requesting IP address via DHCPv4: ");
		rc = dhcp(ret_buffer, &fn_ip, obp_tftp_args.bootp_retries, F_IPV4);
		break;
	case IP_INIT_DHCPV6_STATELESS:
		printf("  Requesting information via DHCPv6: ");
		rc = dhcp(ret_buffer, &fn_ip,
			  obp_tftp_args.bootp_retries, F_IPV6);
		break;
	case IP_INIT_IPV6_MANUAL:
		set_ipv6_address(&obp_tftp_args.ci6addr);
		break;
	case IP_INIT_DEFAULT:
		printf("  Requesting IP address via DHCP: ");
		rc = dhcp(ret_buffer, &fn_ip, obp_tftp_args.bootp_retries, 0);
		break;
	case IP_INIT_NONE:
	default:
		break;
	}

	if(rc >= 0 && ip_version == 4) {
		if(memcmp(obp_tftp_args.ciaddr, null_ip, 4) != 0
		&& memcmp(obp_tftp_args.ciaddr, &fn_ip.own_ip, 4) != 0)
			memcpy(&fn_ip.own_ip, obp_tftp_args.ciaddr, 4);

		if(memcmp(obp_tftp_args.siaddr, null_ip, 4) != 0
		&& memcmp(obp_tftp_args.siaddr, &fn_ip.server_ip, 4) != 0)
			memcpy(&fn_ip.server_ip, obp_tftp_args.siaddr, 4);

		// init IPv4 layer
		set_ipv4_address(fn_ip.own_ip);
	}
	else if (rc >= 0 && ip_version == 6) {
		if(memcmp(&obp_tftp_args.ci6addr.addr, null_ip6, 16) != 0
		&& memcmp(&obp_tftp_args.ci6addr.addr, &fn_ip.own_ip6, 16) != 0)
			memcpy(&fn_ip.own_ip6, &obp_tftp_args.ci6addr.addr, 16);

		if(memcmp(&obp_tftp_args.si6addr.addr, null_ip6, 16) != 0
		&& memcmp(&obp_tftp_args.si6addr.addr, &fn_ip.server_ip6.addr, 16) != 0)
			memcpy(&fn_ip.server_ip6.addr, &obp_tftp_args.si6addr.addr, 16);
	}
	if (rc == -1) {
		strcpy(buf,"E3001: (net) Could not get IP address");
		bootmsg_error(0x3001, &buf[7]);

		write_mm_log(buf, strlen(buf), 0x91);
		return -101;
	}

	if(ip_version == 4)
		printf("%d.%d.%d.%d\n",
			((fn_ip.own_ip >> 24) & 0xFF), ((fn_ip.own_ip >> 16) & 0xFF),
			((fn_ip.own_ip >>  8) & 0xFF), ( fn_ip.own_ip        & 0xFF));

	if (rc == -2) {
		sprintf(buf,
			"E3002: (net) ARP request to TFTP server "
			"(%d.%d.%d.%d) failed",
			((fn_ip.server_ip >> 24) & 0xFF),
			((fn_ip.server_ip >> 16) & 0xFF),
			((fn_ip.server_ip >>  8) & 0xFF),
			( fn_ip.server_ip        & 0xFF));
		bootmsg_error(0x3002, &buf[7]);

		write_mm_log(buf, strlen(buf), 0x91);
		return -102;
	}
	if (rc == -4 || rc == -3) {
		strcpy(buf,"E3008: (net) Can't obtain TFTP server IP address");
		bootmsg_error(0x3008, &buf[7]);

		write_mm_log(buf, strlen(buf), 0x91);
		return -107;
	}


	/***********************************************************
	 *
	 * Load file via TFTP into buffer provided by OpenFirmware
	 *
	 ***********************************************************/

	if (obp_tftp_args.filename[0] != 0) {
		strncpy((char *) fn_ip.filename, obp_tftp_args.filename, sizeof(fn_ip.filename)-1);
		fn_ip.filename[sizeof(fn_ip.filename)-1] = 0;
	}

	if (ip_version == 4) {
		printf("  Requesting file \"%s\" via TFTP from %d.%d.%d.%d\n",
			fn_ip.filename,
			((fn_ip.server_ip >> 24) & 0xFF),
			((fn_ip.server_ip >> 16) & 0xFF),
			((fn_ip.server_ip >>  8) & 0xFF),
			( fn_ip.server_ip        & 0xFF));
	} else if (ip_version == 6) {
		char ip6_str[40];
		printf("  Requesting file \"%s\" via TFTP from ", fn_ip.filename);
		ipv6_to_str(fn_ip.server_ip6.addr, ip6_str);
		printf("%s\n", ip6_str);
	}

	// accept at most 20 bad packets
	// wait at most for 40 packets
	rc = tftp(&fn_ip, (unsigned char *) buffer,
	          len, obp_tftp_args.tftp_retries,
	          &tftp_err, huge_load, block_size, ip_version);

	if(obp_tftp_args.ip_init == IP_INIT_DHCP)
		dhcp_send_release();

	if (rc > 0) {
		printf("  TFTP: Received %s (%d KBytes)\n", fn_ip.filename,
		       rc / 1024);
	} else if (rc == -1) {
		bootmsg_error(0x3003, "(net) unknown TFTP error");
		return -103;
	} else if (rc == -2) {
		sprintf(buf,
			"E3004: (net) TFTP buffer of %d bytes "
			"is too small for %s",
			len, fn_ip.filename);
		bootmsg_error(0x3004, &buf[7]);

		write_mm_log(buf, strlen(buf), 0x91);
		return -104;
	} else if (rc == -3) {
		sprintf(buf,"E3009: (net) file not found: %s",
		       fn_ip.filename);
		bootmsg_error(0x3009, &buf[7]);

		write_mm_log(buf, strlen(buf), 0x91);
		return -108;
	} else if (rc == -4) {
		strcpy(buf,"E3010: (net) TFTP access violation");
		bootmsg_error(0x3010, &buf[7]);

		write_mm_log(buf, strlen(buf), 0x91);
		return -109;
	} else if (rc == -5) {
		strcpy(buf,"E3011: (net) illegal TFTP operation");
		bootmsg_error(0x3011, &buf[7]);

		write_mm_log(buf, strlen(buf), 0x91);
		return -110;
	} else if (rc == -6) {
		strcpy(buf, "E3012: (net) unknown TFTP transfer ID");
		bootmsg_error(0x3012, &buf[7]);

		write_mm_log(buf, strlen(buf), 0x91);
		return -111;
	} else if (rc == -7) {
		strcpy(buf, "E3013: (net) no such TFTP user");
		bootmsg_error(0x3013, &buf[7]);

		write_mm_log(buf, strlen(buf), 0x91);
		return -112;
	} else if (rc == -8) {
		strcpy(buf, "E3017: (net) TFTP blocksize negotiation failed");
		bootmsg_error(0x3017, &buf[7]);

		write_mm_log(buf, strlen(buf), 0x91);
		return -116;
	} else if (rc == -9) {
		strcpy(buf,"E3018: (net) file exceeds maximum TFTP transfer size");
		bootmsg_error(0x3018, &buf[7]);

		write_mm_log(buf, strlen(buf), 0x91);
		return -117;
	} else if (rc <= -10 && rc >= -15) {
		sprintf(buf,"E3005: (net) ICMP ERROR \"");
		switch (rc) {
		case -ICMP_NET_UNREACHABLE - 10:
			sprintf(buf+strlen(buf),"net unreachable");
			break;
		case -ICMP_HOST_UNREACHABLE - 10:
			sprintf(buf+strlen(buf),"host unreachable");
			break;
		case -ICMP_PROTOCOL_UNREACHABLE - 10:
			sprintf(buf+strlen(buf),"protocol unreachable");
			break;
		case -ICMP_PORT_UNREACHABLE - 10:
			sprintf(buf+strlen(buf),"port unreachable");
			break;
		case -ICMP_FRAGMENTATION_NEEDED - 10:
			sprintf(buf+strlen(buf),"fragmentation needed and DF set");
			break;
		case -ICMP_SOURCE_ROUTE_FAILED - 10:
			sprintf(buf+strlen(buf),"source route failed");
			break;
		default:
			sprintf(buf+strlen(buf)," UNKNOWN");
			break;
		}
		sprintf(buf+strlen(buf),"\"");
		bootmsg_error(0x3005, &buf[7]);

		write_mm_log(buf, strlen(buf), 0x91);
		return -105;
	} else if (rc == -40) {
		sprintf(buf,
			"E3014: (net) TFTP error occurred after "
			"%d bad packets received",
			tftp_err.bad_tftp_packets);
		bootmsg_error(0x3014, &buf[7]);
		write_mm_log(buf, strlen(buf), 0x91);
		return -113;
	} else if (rc == -41) {
		sprintf(buf,
			"E3015: (net) TFTP error occurred after "
			"missing %d responses",
			tftp_err.no_packets);
		bootmsg_error(0x3015, &buf[7]);
		write_mm_log(buf, strlen(buf), 0x91);
		return -114;
	} else if (rc == -42) {
		sprintf(buf,
			"E3016: (net) TFTP error missing block %d, "
			"expected block was %d",
			tftp_err.blocks_missed,
			tftp_err.blocks_received);
		bootmsg_error(0x3016, &buf[7]);
		write_mm_log(buf, strlen(buf), 0x91);
		return -115;
	}
	return rc;
}

/**
 * Parses a tftp arguments, extracts all
 * parameters and fills server ip according to this
 *
 * Parameters:
 * @param  buffer        string with arguments,
 * @param  server_ip	 server ip as result
 * @param  filename	 default filename
 * @param  len            len of the buffer,
 * @return               0 on SUCCESS and -1 on failure
 */
int parse_tftp_args(char buffer[], char *server_ip, char filename[], int len)
{
	char *raw;
	char *tmp, *tmp1;
	int i, j = 0;
	char domainname[256];
	uint8_t server_ip6[16];

	raw = malloc(len);
	if (raw == NULL) {
		printf("\n unable to allocate memory, parsing failed\n");
		return -1;
	}
	strncpy(raw,(const char *)buffer,len);
	/*tftp url contains tftp://[fd00:4f53:4444:90:214:5eff:fed9:b200]/testfile*/
	if(strncmp(raw,"tftp://",7)){
		printf("\n tftp missing in %s\n",raw);
		free(raw);
		return -1;
	}
	tmp = strchr(raw,'[');
	if(tmp != NULL && *tmp == '[') {
		/*check for valid ipv6 address*/
		tmp1 = strchr(tmp,']');
		if (tmp1 == NULL) {
			printf("\n missing ] in %s\n",raw);
			free(raw);
			return -1;
		}
		i = tmp1 - tmp;
		/*look for file name*/
		tmp1 = strchr(tmp,'/');
		if (tmp1 == NULL) {
			printf("\n missing filename in %s\n",raw);
			free(raw);
			return -1;
		}
		tmp[i] = '\0';
		/*check for 16 byte ipv6 address */
		if (!str_to_ipv6((tmp+1), (uint8_t *)(server_ip))) {
			printf("\n wrong format IPV6 address in %s\n",raw);
			free(raw);
			return -1;;
		}
		else {
			/*found filename */
			strcpy(filename,(tmp1+1));
			free(raw);
			return 0;
		}
	}
	else {
		/*here tftp://hostname/testfile from option request of dhcp*/
		/*look for dns server name */
		tmp1 = strchr(raw,'.');
		if(tmp1 == NULL) {
			printf("\n missing . seperator in %s\n",raw);
			free(raw);
			return -1;
		}
		/*look for domain name beyond dns server name
		* so ignore the current . and look for one more
		*/
		tmp = strchr((tmp1+1),'.');
		if(tmp == NULL) {
			printf("\n missing domain in %s\n",raw);
			free(raw);
			return -1;
		}
		tmp1 = strchr(tmp1,'/');
		if (tmp1 == NULL) {
			printf("\n missing filename in %s\n",raw);
			free(raw);
			return -1;
		}
		j = tmp1 - (raw + 7);
		tmp = raw + 7;
		tmp[j] = '\0';
		strcpy(domainname, tmp);
		if (dns_get_ip((int8_t *)domainname, server_ip6, 6) == 0) {
			printf("\n DNS failed for IPV6\n");
                        return -1;
                }
		ipv6_to_str(server_ip6, server_ip);

		strcpy(filename,(tmp1+1));
		free(raw);
		return 0;
	}

}
