⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ip.c

📁 此文档为采用FPGA实现的以太网MAC层
💻 C
字号:
#include "ip.h"#include "mac.h"#include "serial.h"#include "udp.h"#include "icmp.h"#include "mac_low.h"extern IP_SETTINGS ipsettings;IP_TABLE iptable;Uint16 tmpident;Uint16 crc_counter =0;//Table for IP addressesARP_TABLE arptable;IPHEADER *ip_header;extern UDPHEADER *udp_header;extern ICMPHEADER *icmp_header;//Layer2 processingUint8 ip_process(IPHEADER *packet, ETHHEADER *eth_header){    Uint16 datasize,chk;    Uint8 *tmpptr;    Uint32 word;    //Calculate CRC on packet    //chk = ip_chksum((Uint16 *) packet,IP_SIZE/2);    //dbg(chk);    //if (chk != 0x0000)    if (ip_chksum((Uint16 *) packet,IP_SIZE/2) > 0)    {       crc_counter++;       //dbg(chk);       return 0;    }    //Check if packet is for us    else if ((((packet->destip_h == ipsettings.ip_address_h)) && ((packet->destip_l == ipsettings.ip_address_l))) || ((packet->destip_h == 0xffff) && (packet->destip_l == 0xffff)))    {        //dbg_char(packet->protocol);        //Set datasize        datasize = (packet->packetlength-IP_SIZE)/2;        //Store ident        tmpident = packet->ident;        //Handle source ip address        //Test if local        if ((packet->sourceip_h ^ packet->destip_h))        {          //Non-zero mask - not local        }        else        {          //Zero mask, local          //Test if in arptable          if (arptable_match(packet->sourceip_h,packet->sourceip_l) == 0xff)          {             //Not in table, add             arptable_add(packet->sourceip_h, packet->sourceip_l,eth_header->sourcemac);          }        }        word = (Uint32) packet;        word += IP_SIZE;        //Decode protocol        if (packet->protocol == PROTOCOL_UDP)        {          udp_header = (UDPHEADER *) word;          udp_process(udp_header,datasize,packet->sourceip_h,packet->sourceip_l);        }        else if (packet->protocol == PROTOCOL_ICMP)        {          icmp_header = (ICMPHEADER *) word;          //dbg_string((Uint16 *) &word,2);          icmp_process(icmp_header,datasize,packet->sourceip_h,packet->sourceip_l);        }    }    else    {       //dbg(packet->destip_h);       //dbg(packet->destip_l);    }    return 0;}void ip_init(void){    Uint8 x,*y;    y = (Uint8 *) &arptable;    for (x=0;x<sizeof(arptable);x++)    {       *(y++) = 0;    }    ipsettings.ip_address_h = ipsettings.ip_address_l = 0;         //fill in gateway information    //IP Address 192.168.1.1    arptable.entry[0].ip_address_h = 0xc0a8;    arptable.entry[0].ip_address_l = 0x0101;    arptable.entry[0].mac_address[0]=0;    arptable.entry[0].mac_address[1]=0x12;    arptable.entry[0].mac_address[2]=0x17;    arptable.entry[0].mac_address[3]=0xad;    arptable.entry[0].mac_address[4]=0x3d;    arptable.entry[0].mac_address[5]=0xf1;    arptable.index = 1;    iptable.index = 0;}void ip_send(Uint16 dest_ip_h,Uint16 dest_ip_l, Uint16 data_len, Uint8 protocol){    IPHEADER *ip_header;    Uint16 match;    //Set ip_header pointer    ip_header = (IPHEADER *) (EMAC_TX_PTR + ETH_SIZE);    ip_header->destip_h = dest_ip_h;    ip_header->destip_l = dest_ip_l;    ip_header->sourceip_h = ipsettings.ip_address_h;    ip_header->sourceip_l = ipsettings.ip_address_l;    ip_header->protocol = protocol;    ip_packet(ip_header,data_len);    //Header is filled out and added to buffer, check if IP is in table    match = arptable_match(dest_ip_h,dest_ip_l);    if (match != 0xff)    {       //Set length       //mac_set_len(((ETH_SIZE+IP_SIZE)/2)+data_len);       //Index is in 'match'       mac_send(match,IP_TYPE,data_len+(IP_SIZE/2));    }    else    {       //IP needs to be looked up    }}//Returns index of arp_table if IP is foundUint16 arptable_match(Uint16 ip_address_h, Uint16 ip_address_l){    Uint16 x;    //Check if broadcast msg    if ((ip_address_h == 0xffff) && (ip_address_l == 0xffff))    {       return 0xfe;    }    for (x=0;x<ENTRY_SIZE;x++)    {       if ((arptable.entry[x].ip_address_h == ip_address_h) && (arptable.entry[x].ip_address_l == ip_address_l))       {          //Match found          return x;       }    }    //See if ip is external    if (ip_address_h ^ ipsettings.ip_address_h)    {       //External ip, return gateway       return 0;    }    //No match found    return 0xff;}//Adds ip and mac to arptablevoid arptable_add(Uint16 ip_address_h, Uint16 ip_address_l, Uint8 *mac_address){    Uint8 x;    arptable.entry[arptable.index].ip_address_h = ip_address_h;    arptable.entry[arptable.index].ip_address_l = ip_address_l;    for (x=0;x<6;x++)    {       arptable.entry[arptable.index].mac_address[x] = mac_address[x];    }    //Rollover index    if (++arptable.index == ENTRY_SIZE) arptable.index = 1;}/////////////////////////////////////////////////Expect length, source/dest ip, protocol to be filled outUint16 ip_packet(IPHEADER *packet, Uint16 data_len){    //Fill out fields of structure    packet->version = 0x45;    packet->service = 0x00;    //If len != 0, change length    if (data_len != 0)       packet->packetlength = 20+(data_len*2);    packet->ident = tmpident;    packet->offset = 0x0000;    packet->timetolive = 0x80;    packet->checksum = 0x0000;    //All fields of struct have now been filled out, calculate checksum    packet->checksum = ip_chksum((Uint16 *) packet,10);    //Return length in words    return (packet->packetlength)/2;}//Returns checksum on string starting at 'buf' for 'len' wordsUint16 ip_chksum(Uint16 *buf,Uint16 len){    Uint16 i;    Uint32 tmp=0,tmp2;    Uint16 tmpint;    for (i=0;i<len;i++)    {       tmp += (Uint32) (buf[i] & 0xFFFF);    }    //Add the carry to tmp    tmp2 = (tmp >> 16) & 0xFFFF;    tmp += tmp2;    tmpint = 0xFFFF - ((Uint16) (tmp & 0xFFFF));    return tmpint;}//Calc checksum over 2 stringsUint16 ip_chksum2(Uint16 *buf,Uint16 len,Uint16 *buf2,Uint16 len2){    Uint16 i;    Uint32 tmp=0,tmp2;    Uint16 tmpint;    for (i=0;i<len;i++)    {       tmp += (Uint32) (buf[i] & 0xFFFF);    }    for (i=0;i<len2;i++)        tmp += (Uint32) (buf2[i] & 0xFFFF);    //Add the carry to tmp    tmp2 = (tmp >> 16) & 0xFFFF;    tmp += tmp2;    tmpint = 0xFFFF - ((Uint16) (tmp & 0xFFFF));    return tmpint;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -