?? ethernet.c
字號:
#define ETHERNET_GLOBALS
#include "..\User\includes.h"
uint8 My_Ip_1ID[4]=MY_IP_1ID;
uint8 My_Gateway_1ID[4]=MY_GATEWAY_1ID;
uint8 MY_IP_MARK_1ID[4]=IP_MARK_1ID;
uint8 MY_MAC_1ID[6]=My_Mac_1ID;//MAC地址
#if (MAX_NET_PORT>=2)
uint8 My_Ip_2ID[4]=MY_IP_2ID;
uint8 My_Gateway_2ID[4]=MY_GATEWAY_2ID;
uint8 MY_IP_MARK_2ID[4]=IP_MARK_2ID;
uint8 MY_MAC_2ID[6]=My_Mac_2ID;//MAC地址
#endif
/**********************************************************************
**函數原型:unsigned char Send_ethernet_Frame(struct _pkst *TxdData,unsigned char * de_mac,unsigned char PROTOCOL)
**入口參數:*TxdData : 發送結構指針
** * de_mac : MAC地址指針
** NextProtocal : 下一層協議,例如IP協議或ARP協議(如:IP_PACKED、ARP_PACKED)
**出口參數: unsigned char
**返 回 值: 1
**說 明: 為IP、ARP數據包產生ETHERNET包頭,并發送。
************************************************************************/
uint8 Send_ethernet_Frame (
struct _pkst *TxdData,//結構指針
uint8 * de_mac, //對方的MAC地址指針
uint8 PROTOCOL, //IP協議或ARP協議
uint8 num
)
{ //如果沒有MAC地址,就發送一個ARP包。得到MAC地址再發。
ipethernet ethernet_head; //ETHERNET處理緩存區
//ipethernet的結構體為DestMacId(目的網卡MAC) SourceMacId(源網卡MAC) NextProtocal(下層協議)
struct _pkst PKethernet;
/**************************獲取目的網卡的MAC****************************************/
ethernet_head.DestMacId[0]=*de_mac;
de_mac++;
ethernet_head.DestMacId[1]=*de_mac;
de_mac++;
ethernet_head.DestMacId[2]=*de_mac;
de_mac++;
ethernet_head.DestMacId[3]=*de_mac;
de_mac++;
ethernet_head.DestMacId[4]=*de_mac;
de_mac++;
ethernet_head.DestMacId[5]=*de_mac;
/************************獲取源網卡的MAC********************************************/
ethernet_head.SourceMacId[0]=NetPort[num].My_Mac[0];
ethernet_head.SourceMacId[1]=NetPort[num].My_Mac[1];
ethernet_head.SourceMacId[2]=NetPort[num].My_Mac[2];
ethernet_head.SourceMacId[3]=NetPort[num].My_Mac[3];
ethernet_head.SourceMacId[4]=NetPort[num].My_Mac[4];
ethernet_head.SourceMacId[5]=NetPort[num].My_Mac[5];
#ifdef Little_End
if(PROTOCOL==IP_PACKED)//如果是IP包,就設為0X0800
ethernet_head.NextProtocal=0X0008;
else if(PROTOCOL==ARP_PACKED)//如果是ARP包,就設為0X0806
ethernet_head.NextProtocal=0X0608;//0X0806;
#endif
#ifdef Big_End
if(PROTOCOL==IP_PACKED)//如果是IP包,就設為0X0800
ethernet_head.NextProtocal=0X0800;
else if(PROTOCOL==ARP_PACKED)//如果是ARP包,就設為0X0806
ethernet_head.NextProtocal=0X0806;//0X0806;
#endif
PKethernet.STPTR=TxdData;//指向前一個結構數組
PKethernet.length=14; //ETHERNET報頭的長度
PKethernet.DAPTR=(uint8 EX_RAM *)ðernet_head;//ETHERNET報頭的指針
OS_ENTER_CRITICAL();//保護
switch(num)
{
case 0:
Send_Packet(&PKethernet);//發送該幀
break;
case 1:
break;
case 2:
break;
default:
break;
}
OS_EXIT_CRITICAL();//恢復
return(1);
}
/**********************************************************************
**函數原型: uint8 Send_Ip_To_LLC(struct _pkst *TxdData,unsigned char * de_ip)
**入口參數:?*TxdData : 發送結構指針
** * de_ip : IP地址指針
**出口參數: unsigned char
**返 回 值: 1 :OK
0 :FAIL
**說 明: 為IP數據包的目標IP查找MAC地址,并發送。
************************************************************************/
uint8 Send_Ip_To_LLC(struct _pkst *TxdData,uint8 * de_ip,uint8 num)
{
uint8 i;
//如果該包在
if((de_ip[0]&NetPort[num].My_Ip_Mark[0])==(NetPort[num].My_Ip[0]&NetPort[num].My_Ip_Mark[0]))
if((de_ip[1]&NetPort[num].My_Ip_Mark[1])==(NetPort[num].My_Ip[1]&NetPort[num].My_Ip_Mark[1]))
if((de_ip[2]&NetPort[num].My_Ip_Mark[2])==(NetPort[num].My_Ip[2]&NetPort[num].My_Ip_Mark[2]))
if((de_ip[3]&NetPort[num].My_Ip_Mark[3])==(NetPort[num].My_Ip[3]&NetPort[num].My_Ip_Mark[3]))
{
i=0;//查找一次MAC表。
do
{
OS_ENTER_CRITICAL();//保護
if(NetPort[num].ARP_TERM[i].IP_NUM[2]==((IP_NUMBER*)de_ip)->IP[2])
if(NetPort[num].ARP_TERM[i].IP_NUM[3]==((IP_NUMBER*)de_ip)->IP[3])//如果ARP表的最后兩個數相等而且TTL>0表示,有對應的MAC
if(NetPort[num].ARP_TERM[i].TTL>0)
{
NetPort[num].ARP_TERM[i].TTL=100;//發送
Send_ethernet_Frame(TxdData,NetPort[num].ARP_TERM[i].MAC_NUM,IP_PACKED,num);
OS_EXIT_CRITICAL();//保護
return(1);
}
OS_EXIT_CRITICAL();//保護
i++;
}
while(i<MAX_ARP_TERM);//如果arp表查完了還沒有,就退出
Arp_Request(de_ip,num);//請求對方MAC
return(0);
}
Send_ethernet_Frame(TxdData,Gateway_MAC,IP_PACKED,num);
return(1);
}
uint8 Rec_Ethernet_Packed(uint8 * RecData,uint8 num)
{
uint8 i;
#ifdef Big_End
if(((ipethernet*)RecData)->NextProtocal==0x0800)//可以減少對數據緩沖取的利用
#endif
#ifdef Little_End
if(((ipethernet*)RecData)->NextProtocal==0x0008)//可以減少對數據緩沖取的利用
#endif
{
RecData=RecData+14;//指向IP包頭
//檢查是否屬于本IP段,否則不保存到ARP表種小?
if((((eip*)RecData)->SourceIp[0]&NetPort[num].My_Ip_Mark[0])==(NetPort[num].My_Ip[0]&NetPort[num].My_Ip_Mark[0]))
if((((eip*)RecData)->SourceIp[1]&NetPort[num].My_Ip_Mark[1])==(NetPort[num].My_Ip[1]&NetPort[num].My_Ip_Mark[1]))
if((((eip*)RecData)->SourceIp[2]&NetPort[num].My_Ip_Mark[2])==(NetPort[num].My_Ip[2]&NetPort[num].My_Ip_Mark[2]))
if((((eip*)RecData)->SourceIp[3]&NetPort[num].My_Ip_Mark[3])==(NetPort[num].My_Ip[3]&NetPort[num].My_Ip_Mark[3]))
{
for(i=0;i<MAX_ARP_TERM;i++)
{//同一網段內最多65535臺節點
if(NetPort[num].ARP_TERM[i].IP_NUM[2]==((eip*)RecData)->SourceIp[2])
if(NetPort[num].ARP_TERM[i].IP_NUM[3]==((eip*)RecData)->SourceIp[3])
if(NetPort[num].ARP_TERM[i].TTL>0)//如果已經保存有對應的MAC地址而且TTL有效
{//刷新TTL,處理IP包
NetPort[num].ARP_TERM[i].TTL=100;
IP_PROCESS(RecData,num);
return(2);
}
}
//ARP表沒有對應的MAC地址
for(i=0;i<MAX_ARP_TERM;i++)
{
if(NetPort[num].ARP_TERM[i].TTL==0)//如果該ARP表項無效
{
NetPort[num].ARP_TERM[i].IP_NUM[0]=((eip*)RecData)->SourceIp[0];
NetPort[num].ARP_TERM[i].IP_NUM[1]=((eip*)RecData)->SourceIp[1];
NetPort[num].ARP_TERM[i].IP_NUM[2]=((eip*)RecData)->SourceIp[2];
NetPort[num].ARP_TERM[i].IP_NUM[3]=((eip*)RecData)->SourceIp[3];
RecData=RecData-14;
NetPort[num].ARP_TERM[i].MAC_NUM[0]=((ipethernet*)RecData)->SourceMacId[0];
NetPort[num].ARP_TERM[i].MAC_NUM[1]=((ipethernet*)RecData)->SourceMacId[1];
NetPort[num].ARP_TERM[i].MAC_NUM[2]=((ipethernet*)RecData)->SourceMacId[2];
NetPort[num].ARP_TERM[i].MAC_NUM[3]=((ipethernet*)RecData)->SourceMacId[3];
NetPort[num].ARP_TERM[i].MAC_NUM[4]=((ipethernet*)RecData)->SourceMacId[4];
NetPort[num].ARP_TERM[i].MAC_NUM[5]=((ipethernet*)RecData)->SourceMacId[5];
NetPort[num].ARP_TERM[i].TTL=100;
RecData=RecData+14;//保存其IP和對應的MAC地址
IP_PROCESS(RecData,num);
return(2);
}
}
//MAC表溢出!!
IP_PROCESS(RecData,num);
return(4);
}//if((((eip*)TEMP)->
//非本地IP
IP_PROCESS(RecData,num);
return(3);
}//if(((ipethernet*)
#ifdef Big_End
else if(((ipethernet*)RecData)->NextProtocal==0x0806)//可以減少對數據緩沖取的利用
#endif
#ifdef Little_End
else if(((ipethernet*)RecData)->NextProtocal==0x0608)//可以減少對數據緩沖取的利用
#endif
{
RecData=RecData+14;
PROCESS_ARP_REC(RecData,num);
return(1);
}
return(3);
}
void SetNetPort(void)
{
uint8 i;
for(i=0;i<4;i++)
{
NetPort[0].My_Ip[i]=My_Ip_1ID[i];
NetPort[0].My_Gateway[i]=My_Gateway_1ID[i];
NetPort[0].My_Ip_Mark[i]=MY_IP_MARK_1ID[i];
#if MAX_NET_PORT>=2
NetPort[1].My_Ip[i]=My_Ip_2ID[i];
NetPort[1].My_Gateway[i]=My_Gateway_2ID[i];
NetPort[1].My_Ip_Mark[i]=MY_IP_MARK_2ID[i];
#endif
}
for(i=0;i<6;i++)
{
NetPort[0].My_Mac[i]=MY_MAC_1ID[i];
#if MAX_NET_PORT>=2
NetPort[1].My_Mac[i]=MY_MAC_2ID[i];
#endif
}
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -