#include <avr/io.h>
#include "net.h"
#include "enc28j60.h"
static uint8_t macaddr[6];
static uint8_t ipaddr[4];
uint16_t checksum(uint8_t *buf, uint16_t len);
void init_ip_arp(uint8_t *mymac,uint8_t *myip);
uint8_t eth_type_is_arp_and_my_ip(uint8_t *buf,uint16_t len);
uint8_t eth_type_is_ip_and_my_ip(uint8_t *buf,uint16_t len);
void make_eth(uint8_t *buf);
void fill_ip_hdr_checksum(uint8_t *buf);
void make_ip(uint8_t *buf);
void make_arp_answer_from_request(uint8_t *buf);
void make_echo_reply_from_request(uint8_t *buf,uint16_t len);

uint16_t checksum(uint8_t *buf, uint16_t len)// вычисляем контрольную сумму для ip заголовка
{ 
 uint32_t sum = 0;
 while(len >1)
		{sum += 0xFFFF & (*buf<<8|*(buf+1));
         buf+=2;
         len-=2;
        }
 if (len)
        {
         sum += (0xFF & *buf)<<8;
        }
 while (sum>>16)
		{
         sum = (sum & 0xFFFF)+(sum >> 16);
        }
 return( (uint16_t) sum ^ 0xFFFF);
}

void init_ip_arp(uint8_t *mymac,uint8_t *myip)// функция генерации ip- и MAC-адресов, которые будут переданы в пакет и фрейм соответственно
{
 uint8_t i=0;
 while(i<4)
		{
         ipaddr[i]=myip[i];// присваиваем ip-адресу, который впоследствии будет отправлен в ip- пакете значение нашего ip 
         i++;
        }
 i=0;
 while(i<6)
		{
         macaddr[i]=mymac[i];// присваиваем MAC-адресу, который впоследствии будет отправлен в Ethernet-фрейме  значение нашего MAC
         i++;
        }
}

uint8_t eth_type_is_arp_and_my_ip(uint8_t *buf,uint16_t len)// функция проверки, является ли полученный пакет ARP-запросом и предназначен ли нам?
{
 uint8_t i=0;
 if (len<41)
		{
         return(0);
        }
 if(buf[ETH_TYPE_H_P] != ETHTYPE_ARP_H_V || buf[ETH_TYPE_L_P] != ETHTYPE_ARP_L_V)
		{
         return(0);
        }
 while(i<4)
		{
         if(buf[ETH_ARP_DST_IP_P+i] != ipaddr[i])
			{
             return(0);
            }
         i++;
        }
return(1);//в случае успеха возвращает значение 1
}

uint8_t eth_type_is_ip_and_my_ip(uint8_t *buf,uint16_t len)// функция проверки, адресован ли полученный IP пакет нам?
{
 uint8_t i=0;
 if (len<42)
    {
     return(0);
    }
 if(buf[ETH_TYPE_H_P]!=ETHTYPE_IP_H_V || buf[ETH_TYPE_L_P]!=ETHTYPE_IP_L_V)
    {
     return(0);
    }
 if (buf[IP_HEADER_LEN_VER_P]!=0x45)
	{
     return(0);
    }
 while(i<4)
    {
     if(buf[IP_DST_P+i]!=ipaddr[i])
	    {
         return(0);
        }
     i++;
    }
 return(1);//если да, то возвращает 1
}

void make_eth(uint8_t *buf)//функция замены MAC-адреса источника на МАС-адрес получателя
{
 uint8_t i=0;
 while(i<6)
    {
     buf[ETH_DST_MAC +i]=buf[ETH_SRC_MAC +i];
     buf[ETH_SRC_MAC +i]=macaddr[i];
     i++;
    }
}

void fill_ip_hdr_checksum(uint8_t *buf)// функция генерации контрольной суммы, флагов, времени жизни для отправляемого IP пакета
{
 uint16_t ck;
 buf[IP_CHECKSUM_P]=0;
 buf[IP_CHECKSUM_P+1]=0;
 buf[IP_FLAGS_P]=0x40; 
 buf[IP_FLAGS_P+1]=0;  
 buf[IP_TTL_P]=64; 
 ck=checksum(&buf[IP_P], IP_HEADER_LEN);
 buf[IP_CHECKSUM_P]=ck>>8;
 buf[IP_CHECKSUM_P+1]=ck& 0xff;
}

void make_ip(uint8_t *buf)//функция генерации ip пакета для отправления
{
 uint8_t i=0;
 while(i<4)
    {
     buf[IP_DST_P+i]=buf[IP_SRC_P+i];
     buf[IP_SRC_P+i]=ipaddr[i];
     i++;
    }
 fill_ip_hdr_checksum(buf);
}

void make_arp_answer_from_request(uint8_t *buf)// функция генерации ARP-ответа для отправления
{
 uint8_t i=0;
 make_eth(buf);
 buf[ETH_ARP_OPCODE_H_P]=ETH_ARP_OPCODE_REPLY_H_V;
 buf[ETH_ARP_OPCODE_L_P]=ETH_ARP_OPCODE_REPLY_L_V;
 while(i<6)
    {
     buf[ETH_ARP_DST_MAC_P+i]=buf[ETH_ARP_SRC_MAC_P+i];
     buf[ETH_ARP_SRC_MAC_P+i]=macaddr[i];
     i++;
    }
 i=0;
 while(i<4)
    {
     buf[ETH_ARP_DST_IP_P+i]=buf[ETH_ARP_SRC_IP_P+i];
     buf[ETH_ARP_SRC_IP_P+i]=ipaddr[i];
     i++;
    }
 enc28j60PacketSend(42,buf); 
}

void make_echo_reply_from_request(uint8_t *buf,uint16_t len)// функция генерации понг-ответа для отправления
{
 make_eth(buf);
 make_ip(buf);
 buf[ICMP_TYPE_P]=ICMP_TYPE_ECHOREPLY_V;
 if (buf[ICMP_CHECKSUM_P] > (0xff-0x08))
    {
     buf[ICMP_CHECKSUM_P+1]++;
    }
 buf[ICMP_CHECKSUM_P]+=0x08;
 enc28j60PacketSend(len,buf);
}





