/******************************************************************************
 * 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 <unistd.h>
#include <ipv4.h>
#include <dhcp.h>
#include <ethernet.h>
#include <sys/socket.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include "args.h"
#include "netapps.h"

struct ping_args {
	union {
		char string[4];
		unsigned int integer;
	} server_ip;
	union {
		char string[4];
		unsigned int integer;
	} client_ip;
	union {
		char string[4];
		unsigned int integer;
	} gateway_ip;
	unsigned int timeout;
	unsigned int netmask;
};

static void
usage(void)
{
	printf
	    ("\nping device-path:[device-args,]server-ip,[client-ip[\\nn]],[gateway-ip][,timeout]\n");

}

static int
parse_args(const char *args, struct ping_args *ping_args)
{
	unsigned int argc = get_args_count(args);
	char buf[64];
	ping_args->timeout = 10;
	if (argc == 0)
		/* at least server-ip has to be specified */
		return -1;
	if (argc == 1) {
		/* probably only server ip is specified */
		argncpy(args, 0, buf, 64);
		if (!strtoip(buf, ping_args->server_ip.string))
			return -1;
		return 0;
	}
	/* get first option from list */
	argncpy(args, 0, buf, 64);
	if (!strtoip(buf, ping_args->server_ip.string)) {
		/* it is not an IP address
		 * therefore it has to be device-args
		 * device-args are not supported and just ignored */
		args = get_arg_ptr(args, 1);
		argc--;
	}

	argncpy(args, 0, buf, 64);
	if (!strtoip(buf, ping_args->server_ip.string)) {
		/* this should have been the server IP address */
		return -1;
	} else {
		args = get_arg_ptr(args, 1);
		if (!--argc)
			return 0;
	}

	argncpy(args, 0, buf, 64);
	if (!strtoip_netmask(buf, ping_args->client_ip.string, &ping_args->netmask)) {
		/* this should have been the client (our) IP address */
		return -1;
	} else {
		args = get_arg_ptr(args, 1);
		if (!--argc)
			return 0;
	}
	argncpy(args, 0, buf, 64);
	if (!strtoip(buf, ping_args->gateway_ip.string)) {
		/* this should have been the gateway IP address */
		return -1;
	} else {
		args = get_arg_ptr(args, 1);
		if (!--argc)
			return 0;
	}
	argncpy(args, 0, buf, 64);
	ping_args->timeout = strtol(args, 0, 10);
	return 0;
}

int ping(char *args_fs, int alen)
{
	short arp_failed = 0;
	filename_ip_t fn_ip;
	int fd_device;
	struct ping_args ping_args;
	uint8_t own_mac[6];
	uint32_t netmask;
	char args[256];
	int ret = -1;

	memset(&ping_args, 0, sizeof(struct ping_args));

	if (alen <= 0 || alen >= sizeof(args) - 1) {
		usage();
		return -1;
	}

	/* Convert forth string into NUL-terminated C-string */
	memcpy(args, args_fs, alen);
	args[alen] = 0;

	if (parse_args(args, &ping_args)) {
		usage();
		return -1;
	}

	memset(&fn_ip, 0, sizeof(filename_ip_t));

	/* Get mac_addr from device */
	printf("\n  Reading MAC address from device: ");
	fd_device = socket(0, 0, 0, (char *) own_mac);
	if (fd_device == -1) {
		printf("\nE3000: Could not read MAC address\n");
		return -100;
	} else if (fd_device == -2) {
		printf("\nE3006: Could not initialize network device\n");
		return -101;
	}

	fn_ip.fd = fd_device;

	printf("%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);
	// identify the BOOTP/DHCP server via broadcasts
	// don't do this, when using DHCP !!!
	//  fn_ip.server_ip = 0xFFFFFFFF;
	//  memset(fn_ip.server_mac, 0xff, 6);

	if (!ping_args.client_ip.integer) {
		/* Get ip address for our mac address */
		arp_failed = dhcp(0, &fn_ip, 30, F_IPV4);

		if (arp_failed == -1) {
			printf("\n  DHCP: Could not get ip address\n");
			goto free_out;
		}

	} else {
		memcpy(&fn_ip.own_ip, &ping_args.client_ip.integer, 4);
		if (ping_args.gateway_ip.integer)
			set_ipv4_router(ping_args.gateway_ip.integer);
		if (!ping_args.netmask) {
			/* Netmask is not provided, assume default according to
			 * the network class
			 */
			ping_args.netmask = get_default_ipv4_netmask(ping_args.client_ip.string);
		}
		set_ipv4_netmask(ping_args.netmask);

		arp_failed = 1;
	}

	// reinit network stack
	set_ipv4_address(fn_ip.own_ip);

	printf("  Own IP address: %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));

	netmask = get_ipv4_netmask();
	if (netmask) {
		printf("  Netmask : ");
		printf("%d.%d.%d.%d\n", ((netmask >> 24) & 0xFF), ((netmask >> 16) & 0xFF),
		       ((netmask >> 8) & 0xFF), (netmask & 0xFF));
	}

	memcpy(&fn_ip.server_ip, &ping_args.server_ip.integer, 4);
	printf("  Ping to %d.%d.%d.%d ", ((fn_ip.server_ip >> 24) & 0xFF),
	       ((fn_ip.server_ip >> 16) & 0xFF),
	       ((fn_ip.server_ip >> 8) & 0xFF), (fn_ip.server_ip & 0xFF));


	ping_ipv4(fd_device, fn_ip.server_ip);

	set_timer(TICKS_SEC / 10 * ping_args.timeout);
	while(get_timer() > 0) {
		receive_ether(fd_device);
		if(pong_ipv4() == 0) {
			printf("success\n");
			ret = 0;
			goto free_out;
		}
	}

	printf("failed\n");
free_out:
	free(fn_ip.pl_cfgfile);
	free(fn_ip.pl_prefix);
	close(fn_ip.fd);

	return ret;
}
