/******************************************************************************
 * Copyright (c) 2013 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 <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <stdbool.h>
#include <time.h>
#include <ctype.h>
#include <sys/socket.h>
#include "ethernet.h"
#include "ipv6.h"
#include "icmpv6.h"
#include "ndp.h"
#include "udp.h"

#undef IPV6_DEBUG
//#define IPV6_DEBUG
#ifdef IPV6_DEBUG
#define dprintf(_x ...) do { printf(_x); } while (0)
#else
#define dprintf(_x ...)
#endif

/****************************** PROTOTYPES *******************************/
static void ipv6_init(int fd);
static int ip6_is_multicast (ip6_addr_t * ip);

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

/* List of Ipv6 Addresses */
static struct ip6addr_list_entry *first_ip6;
static struct ip6addr_list_entry *last_ip6;

/* Own IPv6 address */
static struct ip6addr_list_entry *own_ip6;

/* All nodes link-local address */
struct ip6addr_list_entry all_nodes_ll;

/* Null IPv6 address */
static ip6_addr_t null_ip6;

/* helper variables */
static uint8_t null_mac[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};

struct ip6_config ip6_state;

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

/**
 * IPv6: Set the own IPv6 address.
 *
 * @param  fd            Socket descriptor
 * @param  _own_ip       client IPv6 address (e.g. ::1)
 */
void set_ipv6_address(int fd, ip6_addr_t *_own_ip6)
{
	struct ip6addr_list_entry *ile;

	ile = malloc(sizeof(struct ip6addr_list_entry));
	if (!ile)
		return;
	memset(ile, 0, sizeof(struct ip6addr_list_entry));
	own_ip6 = ile;

	/* If no address was passed as a parameter generate a link-local
	 * address from our MAC address.*/
	if (_own_ip6 == NULL)
		ip6_create_ll_address(get_mac_address(), &own_ip6->addr);
	else
		memcpy (&(own_ip6->addr.addr), _own_ip6, 16);

	/* Add to our list of IPv6 addresses */
	ip6addr_add (own_ip6);

	ipv6_init(fd);

	/*
	 * Check whether we've got a non-link-local address during
	 * ipv6_init() and use that as preferred address if possible
	 */
	if (_own_ip6 == NULL) {
		for (ile = first_ip6; ile != NULL ; ile = ile->next) {
			if (!ip6_is_multicast(&ile->addr) &&
			    !ip6_is_linklocal(&ile->addr)) {
				own_ip6 = ile;
				break;
			}
		}
	}
}

/**
 * IPv6: Get pointer to own IPv6 address.
 *
 * @return pointer to client IPv6 address (e.g. ::1)
 */
ip6_addr_t *get_ipv6_address(void)
{
	return (ip6_addr_t *) &(own_ip6->addr);
}

/**
 * IPv6: Search for IPv6 address in list
 *
 * @return 0 - IPv6 address is not in list
 *         1 - IPv6 address is in list
 */
static int8_t find_ip6addr(ip6_addr_t *ip)
{
	struct ip6addr_list_entry *n = NULL;

	if (ip == NULL)
	    return 0;

	for (n = first_ip6; n != NULL ; n=n->next)
		if (ip6_cmp (&(n->addr), ip))
			return 1; /* IPv6 address is in  our list*/

	return 0; /* not one of our IPv6 addresses*/
}

/**
 * NET: Handles IPv6-packets
 *
 * @param  fd         - Socket descriptor
 * @param  ip6_packet - Pointer to IPv6 header
 * @param  packetsize - Size of Ipv6 packet
 * @return ERROR      - -1 if packet is too small or unknown protocol
 *			return value of handle_udp
 *
 * @see handle_udp
 * @see ip6hdr
 */
int8_t handle_ipv6(int fd, uint8_t * ip6_packet, uint32_t packetsize)
{

	struct ip6hdr *ip6 = NULL;
	ip6 = (struct ip6hdr *) ip6_packet;

	/* Only handle packets which are for us */
	if (! find_ip6addr(&(ip6->dst)))
		return -1;

	if (packetsize < sizeof(struct ip6hdr))
		return -1; // packet is too small

	switch (ip6->nh) {
		case IPTYPE_UDP:
			return handle_udp (fd, ip6_packet + sizeof (struct ip6hdr),
					ip6->pl);
		case IPTYPE_ICMPV6:
			return handle_icmpv6 (fd, (struct ethhdr *) ip6_packet - sizeof(struct ethhdr),
					      ip6_packet);
	}

	return -1; // unknown protocol
}

 /**
 * NET: Creates IPv6-packet. Places IPv6-header in a packet and fills it
 *      with corresponding information.
 *      <p>
 *      Use this function with similar functions for other network layers
 *      (fill_ethhdr, fill_udphdr, fill_dnshdr, fill_btphdr).
 *
 * @param  packet      Points to the place where IPv6-header must be placed.
 * @param  packetsize  Size of payload (i.e. excluding ethhdr and ip6hdr)
 * @param  ip_proto    Type of the next level protocol (e.g. UDP).
 * @param  ip6_src     Sender IPv6 address
 * @param  ip6_dst     Receiver IPv6 address
 * @see                ip6hdr
 * @see                fill_iphdr
 * @see                fill_ethhdr
 * @see                fill_udphdr
 * @see                fill_dnshdr
 * @see                fill_btphdr
 */
void fill_ip6hdr(uint8_t * packet, uint16_t packetsize,
		 uint8_t ip_proto, ip6_addr_t *ip6_src, ip6_addr_t *ip6_dst)
{
	struct ip6hdr * ip6h = (struct ip6hdr *) packet;

	ip6h->ver_tc_fl = 6 << 28;	// set version to 6
	ip6h->pl = packetsize;		// IPv6 payload size
	ip6h->nh = ip_proto;
	ip6h->hl = 255;
	memcpy (&(ip6h->src), ip6_src, IPV6_ADDR_LENGTH);
	memcpy (&(ip6h->dst), ip6_dst, IPV6_ADDR_LENGTH);
}

/**
 * NET: For a given MAC calculates EUI64-Identifier.
 *      See RFC 4291 "IP Version 6 Addressing Architecture"
 *
 */
uint64_t mac2eui64(const uint8_t *mac)
{
	uint8_t eui64id[8];
	uint64_t retid;

	memcpy (eui64id, mac, 3);
	memcpy (eui64id + 5, mac + 3, 3);
	eui64id[3] = 0xff;
	eui64id[4] = 0xfe;

	memcpy(&retid, eui64id, 8);
	return retid;
}

/**
 * NET: create link-local IPv6 address
 *
 * @param  own_mac    MAC of NIC
 * @param ll_addr     pointer to link-local address which should be created
 */
void ip6_create_ll_address(const uint8_t *own_mac, ip6_addr_t *ll_addr)
{
	ll_addr->part.prefix = IPV6_LL_PREFIX;
	ll_addr->part.interface_id = mac2eui64((uint8_t *) own_mac);
}

/*
 * NET: check if we already have an address with the same prefix.
 * @param  struct ip6_addr_list_entry *ip6
 * @return true or false
 */
int8_t unknown_prefix(ip6_addr_t *ip)
{
	struct ip6addr_list_entry *node;

	for( node = first_ip6; node != NULL; node=node->next )
		if( node->addr.part.prefix == ip->part.prefix )
			return 0; /* address is one of ours */

	return 1; /* prefix not yet in our list */
}

/*
 * NET: Create empty element for prefix list and return a pointer to it;
 * @return NULL - malloc failed
 *	   ! NULL - pointer to new prefix_info
 */
struct prefix_info *ip6_create_prefix_info(void)
{
	struct prefix_info *prfx_info;

	prfx_info = malloc (sizeof(struct prefix_info));
	if (!prfx_info)
		return NULL;
	memset(prfx_info, 0, sizeof(struct prefix_info));

	return prfx_info;
}

/*
 * NET: create a new IPv6 address with a given network prefix
 *	and add it to our IPv6 address list
 *
 * @param  ip6_addr prefix (as received in RA)
 * @return NULL - pointer to new ip6addr_list entry
 */
void *ip6_prefix2addr(ip6_addr_t prefix)
{
	struct ip6addr_list_entry *new_address;
	uint64_t interface_id;

	new_address = malloc (sizeof(struct ip6addr_list_entry));
	if( !new_address )
		return NULL;
	memset(new_address, 0, sizeof(struct ip6addr_list_entry));

	/* fill new addr struct */
	/* extract prefix from Router Advertisement */
	memcpy (&(new_address->addr.part.prefix), &prefix, 8 );

	/* interface id is generated from MAC address */
	interface_id = mac2eui64 (get_mac_address());
	memcpy (&(new_address->addr.part.interface_id), &interface_id, 8);

	return new_address;
}

/**
 * NET: add new IPv6 adress to list
 *
 * @param   ip6_addr *new_address
 * @return  0 - passed pointer = NULL;
 *	    1 - ok
 */
int8_t ip6addr_add(struct ip6addr_list_entry *new_address)
{
	struct ip6addr_list_entry *solicited_node;


	if (new_address == NULL)
		return 0;

	 /* Don't add the same address twice */
	if (find_ip6addr (&(new_address->addr)))
		return 0;

	/* If address is a unicast address, we also have to process packets
	 * for its solicited-node multicast address.
	 * See RFC 2373 - IP Version 6 Adressing Architecture */
	if (! ip6_is_multicast(&(new_address->addr))) {
		solicited_node = malloc(sizeof(struct ip6addr_list_entry));
		if (! solicited_node)
			return 0;
		memset(solicited_node, 0, sizeof(struct ip6addr_list_entry));

		solicited_node->addr.part.prefix       = IPV6_SOLIC_NODE_PREFIX;
		solicited_node->addr.part.interface_id = IPV6_SOLIC_NODE_IFACE_ID;
		solicited_node->addr.addr[13] = new_address->addr.addr[13];
		solicited_node->addr.addr[14] = new_address->addr.addr[14];
		solicited_node->addr.addr[15] = new_address->addr.addr[15];
		ip6addr_add (solicited_node);
	}

	if (first_ip6 == NULL)
		first_ip6 = new_address;
	else
		last_ip6->next = new_address;
	last_ip6 = new_address;
	last_ip6->next = NULL;

	return 1; /* no error */
}

/**
 * NET: Initialize IPv6
 *
 * @param  fd            socket fd
 */
static void ipv6_init(int fd)
{
	int i = 0;

	send_ip = &send_ipv6;

	/* Address configuration parameters */
	ip6_state.managed_mode = 0;

	/* Null IPv6 address */
	null_ip6.part.prefix       = 0;
	null_ip6.part.interface_id = 0;

	/* Multicast addresses */
	all_nodes_ll.addr.part.prefix         = 0xff02000000000000;
	all_nodes_ll.addr.part.interface_id   = 1;
	ip6addr_add(&all_nodes_ll);

	ndp_init();

	send_router_solicitation (fd);
	for(i=0; i < 4 && !is_ra_received(); i++) {
		set_timer(TICKS_SEC);
		do {
			receive_ether(fd);
			if (is_ra_received())
				break;
		} while (get_timer() > 0);
	}
}

/**
 * NET: compare IPv6 adresses
 *
 * @param  ip6_addr ip_1
 * @param  ip6_addr ip_2
 */
int8_t ip6_cmp(ip6_addr_t *ip_1, ip6_addr_t *ip_2)
{
	return ((int8_t) !memcmp( &(ip_1->addr[0]), &(ip_2->addr[0]),
		IPV6_ADDR_LENGTH ));
}

/**
 * NET: Calculate checksum over IPv6 header and upper-layer protocol
 *      (e.g. UDP or ICMPv6)
 *
 * @param  *ip    - pointer to IPv6 address
 * @return true or false
 */
int ip6_is_multicast(ip6_addr_t * ip)
{
	return ip->addr[0] == 0xFF;
}

/**
 * NET: Generate multicast MAC address from IPv6 address
 *      (e.g. UDP or ICMPv6)
 *
 * @param  *ip    - pointer to IPv6 address
 * @param  *mc_mac  pointer to an array with 6 bytes (for the MAC address)
 * @return pointer to Multicast MAC address
 */
static uint8_t *ip6_to_multicast_mac(ip6_addr_t * ip, uint8_t *mc_mac)
{
	mc_mac[0] = 0x33;
	mc_mac[1] = 0x33;
	memcpy (mc_mac+2, (uint8_t *) &(ip->addr)+12, 4);

	return mc_mac;
}

/**
 * Check whether an IPv6 address is on the same network as we are
 */
static bool is_ip6addr_in_my_net(ip6_addr_t *ip)
{
	struct ip6addr_list_entry *n = NULL;

	for (n = first_ip6; n != NULL; n = n->next) {
		if (n->addr.part.prefix == ip->part.prefix)
			return true;  /* IPv6 address is in our neighborhood */
	}

	return false;    /* not in our neighborhood */
}

/**
 * NET: calculate checksum over IPv6 header and upper-layer protocol
 *      (e.g. UDP or ICMPv6)
 *
 * @param  struct ip6hdr *ip6h    - pointer to IPv6 header
 * @param  unsigned short *packet - pointer to header of upper-layer
 *				    protocol
 * @param  int words              - number of words (as in 2 bytes)
 *				    starting from *packet
 * @return checksum
 */
static unsigned short ip6_checksum(struct ip6hdr *ip6h, unsigned short *packet,
				   int words)
{
	int i=0;
	unsigned long checksum;
	struct ip6hdr pseudo_ip6h;
	unsigned short *pip6h;

	memcpy (&pseudo_ip6h, ip6h, sizeof(struct ip6hdr));
	pseudo_ip6h.hl	      = ip6h->nh;
	pseudo_ip6h.ver_tc_fl = 0;
	pseudo_ip6h.nh	      = 0;
	pip6h = (unsigned short *) &pseudo_ip6h;

	for (checksum = 0; words > 0; words--) {
		checksum += *packet++;
		i++;
	}

	for (i = 0; i < 20; i++) {
		checksum += *pip6h++;
	}

	checksum = (checksum >> 16) + (checksum & 0xffff);
	checksum += (checksum >> 16);

	return ~checksum;
}

/**
 * NET: Handles IPv6-packets
 *
 * @param fd          socket fd
 * @param ip6_packet  Pointer to IPv6 header in packet
 * @param packetsize  Size of IPv6 packet
 * @return -1 : Some error occured
 *          0 : packet stored (NDP request sent - packet will be sent if
 *                             NDP response is received)
 *         >0 : packet sent   (number of transmitted bytes is returned)
 *
 * @see receive_ether
 * @see ip6hdr
 */
int send_ipv6(int fd, void* buffer, int len)
{
	struct ip6hdr *ip6h;
	struct udphdr *udph;
	struct icmp6hdr *icmp6h;
	ip6_addr_t ip_dst;
	uint8_t *mac_addr, mc_mac[6];
	static uint8_t ethframe[ETH_MTU_SIZE];

	mac_addr = null_mac;

	ip6h    = (struct ip6hdr *) buffer;
	udph   = (struct udphdr *)   ((uint8_t *) ip6h + sizeof (struct ip6hdr));
	icmp6h = (struct icmp6hdr *) ((uint8_t *) ip6h + sizeof (struct ip6hdr));

	memcpy(&ip_dst, &ip6h->dst, 16);

	if(len + sizeof(struct ethhdr) > ETH_MTU_SIZE)
		return -1;

	if ( ip6_cmp (&ip6h->src, &null_ip6))
		memcpy (&(ip6h->src), get_ipv6_address(), IPV6_ADDR_LENGTH);

	if (ip6h->nh == 17) {//UDP
		udph->uh_sum = ip6_checksum (ip6h, (unsigned short *) udph ,
					     ip6h->pl >> 1);
		/* As per RFC 768, if the computed  checksum  is zero,
		 * it is transmitted as all ones (the equivalent in
		 * one's complement arithmetic).
		 */
		if (udph->uh_sum == 0)
			udph->uh_sum = ~udph->uh_sum;
	}
	else if (ip6h->nh == 0x3a) //ICMPv6
		icmp6h->checksum = ip6_checksum (ip6h,
						 (unsigned short *) icmp6h,
						 ip6h->pl >> 1);

	if (ip6_is_multicast (&ip_dst)) {
		/* If multicast, then create a proper multicast mac address */
		mac_addr = ip6_to_multicast_mac (&ip_dst, mc_mac);
	} else if (!is_ip6addr_in_my_net(&ip_dst)) {
		/* If server is not in same subnet, user MAC of the router */
		struct router *gw;
		gw = ipv6_get_default_router(&ip6h->src);
		mac_addr = gw ? gw->mac : null_mac;
	} else {
		/* Normal unicast, so use neighbor cache to look up MAC */
		struct neighbor *n = find_neighbor (&ip_dst);
		if (n) {				/* Already cached ? */
			if (memcmp(n->mac, null_mac, ETH_ALEN) != 0)
				mac_addr = n->mac;		/* found it */
		} else {
			mac_addr = null_mac;
			n = malloc(sizeof(struct neighbor));
			if (!n)
				return -1;
			memset(n, 0, sizeof(struct neighbor));
			memcpy(&(n->ip.addr[0]), &ip_dst, 16);
			n->status = NB_PROBE;
			n->times_asked = 1;
			neighbor_add(n);
		}

		if (! memcmp (mac_addr, &null_mac, 6)) {
			if (n->eth_len == 0) {
				send_neighbour_solicitation (fd, &ip_dst);

				// Store the packet until we know the MAC address
				fill_ethhdr (n->eth_frame,
					     htons(ETHERTYPE_IPv6),
					     get_mac_address(),
					     mac_addr);
				memcpy (&(n->eth_frame[sizeof(struct ethhdr)]),
				       buffer, len);
				n->eth_len = len;
				set_timer(TICKS_SEC);
				do {
					receive_ether(fd);
					if (n->status == NB_REACHABLE)
						return len;
				} while (get_timer() > 0);
				return 0;
			}
		}
	}

	if (mac_addr == null_mac)
		return -1;

	fill_ethhdr(ethframe, htons(ETHERTYPE_IPv6), get_mac_address(),
	            mac_addr);
	memcpy(&ethframe[sizeof(struct ethhdr)], buffer, len);

	return send_ether(fd, ethframe, len + sizeof(struct ethhdr));
}

static int check_colons(const char *str)
{
	char *pch, *prv;
	int col = 0;
	int dcol = 0;

	dprintf("str : %s\n",str);
	pch = strchr(str, ':');
	while(pch != NULL){
		prv = pch;
		pch = strchr(pch+1, ':');
		if((pch-prv) != 1) {
			col++;
		} else {
			col--; /* Its part of double colon */
			dcol++;
		}
	}

	dprintf("The number of  col : %d \n",col);
	dprintf("The number of dcol : %d \n",dcol);

	if((dcol > 1) ||                      /* Cannot have 2 "::" */
	   ((dcol == 1) && (col > 5)) ||      /* Too many ':'s */
	   ((dcol == 0) && (col != 7)) ) {    /* Too few ':'s */
		dprintf(" exiting for check_colons \n");
		return 0;
	}

	return (col+dcol);
}

static int ipv6str_to_bytes(const char *str, char *ip)
{
	char block[5];
	int res;
	char *pos;
	uint32_t cnt = 0, len;

	dprintf("str : %s \n",str);

	while (*str != 0) {
		if (cnt > 15 || !isxdigit(*str)){
			return 0;
		}
		if ((pos = strchr(str, ':')) != NULL) {
			len = (int16_t) (pos - str);
			dprintf("\t len  is : %d \n",len);
			if (len > 4)
				return 0;
			strncpy(block, str, len);
			block[len] = 0;
			dprintf("\t str   : %s \n",str);
			dprintf("\t block : %s \n",block);
			str += len;
		} else {
			strncpy(block, str, 4);
			block[4] = 0;
			dprintf("\t str   : %s \n",str);
			dprintf("\t block : %s \n",block);
			str += strlen(block);
		}
		res = strtol(block, NULL, 16);
		dprintf("\t res : %x \n",res);
		if ((res > 0xFFFF) || (res < 0))
			return 0;
		ip[cnt++] = (res & 0xFF00) >> 8;
		ip[cnt++] = (res & 0x00FF);
		if (*str == ':'){
			str++;
		}
	}

	dprintf("cnt : %d\n",cnt);
	return cnt;
}

int str_to_ipv6(const char *str, uint8_t *ip)
{
	int i, k;
	uint16_t len;
	char *ptr;
	char tmp[30], buf[16];

	memset(ip,0,16);

	if(!check_colons(str))
		return 0;

	if ((ptr = strstr(str, "::")) != NULL) {
		/* Handle the ::1 IPv6 loopback */
		if(!strcmp(str,"::1")) {
			ip[15] = 1;
			return 16;
		}
		len = (ptr-str);
		dprintf(" len : %d \n",len);
		if (len >= sizeof(tmp))
			return 0;
		strncpy(tmp, str, len);
		tmp[len] = 0;
		ptr += 2;

		i = ipv6str_to_bytes(ptr, buf);
		if(i == 0)
		return i;

		#if defined(ARGS_DEBUG)
		int j;
		dprintf("=========== bottom part i : %d \n",i);
		for(j=0; j<i; j++)
			dprintf("%02x \t",buf[j]);
		#endif

		/* Copy the bottom part i.e bytes following "::" */
		memcpy(ip+(16-i), buf, i);

		k = ipv6str_to_bytes(tmp, buf);
		if(k == 0)
			return k;

		#if defined(ARGS_DEBUG)
		dprintf("=========== top part k : %d \n",k);
		for(j=0; j<k; j++)
			printf("%02x \t",buf[j]);
		#endif

		/* Copy the top part i.e bytes before "::"  */
		memcpy(ip, buf, k);
		#if defined(ARGS_DEBUG)
		dprintf("\n");
		for(j=0; j<16; j++)
			dprintf("%02x \t",ip[j]);
		#endif

	} else {
		i = ipv6str_to_bytes(str, (char *)ip);
	}
	return i;
}

void ipv6_to_str(const uint8_t *ip, char *str)
{
	int i, len;
	uint8_t byte_even, byte_odd;
	char *consec_zero, *strptr;

	*str = 0;
	for (i = 0; i < 16; i+=2) {
		byte_even = ip[i];
		byte_odd = ip[i+1];
		if (byte_even)
			sprintf(str, "%s%x%02x", str, byte_even, byte_odd);
		else if (byte_odd)
			sprintf(str, "%s%x", str, byte_odd);
		else
			strcat(str, "0");
		if (i != 14)
			strcat(str, ":");
	}
	strptr = str;
	do {
		consec_zero = strstr(strptr, "0:0:");
		if (consec_zero) {
			len = consec_zero - strptr;
			if (!len)
				break;
			else if (strptr[len-1] == ':')
				break;
			else
				strptr = consec_zero + 2;
		}
	} while (consec_zero);
	if (consec_zero) {
		len = consec_zero - str;
		str[len] = 0;
		if (len)
			strcat(str, ":");
		else
			strcat(str, "::");
		strptr = consec_zero + 4;
		while (*strptr) {
			if (!strncmp(strptr, "0:", 2))
				strptr += 2;
			else
				break;
		}
		strcat(str, strptr);
		if (!strcmp(str, "::0"))
			strcpy(str, "::");
	}
}
