📄 etherif.c
字号:
#include "true_false.h"
#include "stdlib.h"
#include "typedef.h"
#include "mem_man.h"
#include "rtl8019.h"
#include "netif.h"
#include "etherif.h"
#include "ip.h"
#include "arp.h"
#include "utilities.h"
/* call output to put a packet from IP layer to device. After
Ip layer selected a device, it use output to send this packet.
MemHead contain a packet and Netif tell dirver which netif it
is. NOTE:MemHead->pStart point to pIPHead
return:
TRUE: send successfuly.*/
BOOL EtherOutput(struct SMemHead*MemHead,struct SNetIf*NetIf,IP_ADDR DestIP)
{
DWORD NextIP; /* next host to receive the packet in rout */
struct SEtherHead *pEtherHead;
struct SMemHead *p;
pEtherHead = (struct SEtherHead *)(MemHead->pStart - sizeof(struct SEtherHead));
/* if DestIP in this subnet ... */
if((NetIf->NetMask & NetIf->IPAddr) == (NetIf->NetMask & DestIP))
NextIP = DestIP;
else
NextIP = NetIf->GateWay;
/* find Ether addr of NextIP */
if(ARPFind((void*)pEtherHead->DestAddr,NextIP) == FALSE)
{
/* send a arp query */
if((p = ARPQuery(NetIf,NextIP)) != NULL)
{
((struct SEtherDevice *)(NetIf->Info))->send(
p->pStart,sizeof(struct SARPPacket) +
sizeof(struct SEtherHead));
MemFree(p);
}
}
else
{
/* fill ehter header, DestAddr already filled in ARPFind */
MemCopy((void*)pEtherHead->ScrAddr,
(void*)((struct SEtherDevice *)(NetIf->Info))->Addr,ETHER_ADDR_LEN);
pEtherHead->type = htons(ETHER_TYPE_IP);
/* send the packet. packet lenth is less than MemHead size */
return ((struct SEtherDevice *)(NetIf->Info))->send(
(BYTE *)pEtherHead,(WORD)(MemHead->pEnd - (BYTE *)pEtherHead));
}
return FALSE;
/* free MemHead when it is acked in tcp model */
}
/* this function is called periodically.Get a packet from specific
device. If there is a packet, call NetIf->Input to do more */
void EtherInput(struct SNetIf * NetIf)
{
struct SMemHead *MemHead;
struct SEtherHead *pEtherHead;
struct SMemHead *p;
/* if there is a packet to deal with */
while((MemHead = ((struct SEtherDevice *)(NetIf->Info))->recv())
!= NULL)
{
/* Note, pStart point to EtherHead */
pEtherHead = (struct SEtherHead *)(MemHead->pStart);
/* which packet type */
switch(ntohs(pEtherHead->type))
{
case ETHER_TYPE_IP:
/* before pass to IP layer, let MemHead->pStart point
to IP header */
#ifdef debug_eth
Uart_Printf("\nETHERIF: RCV AN IP FRAME...\n");
#endif
MemHead->pStart += sizeof(struct SEtherHead);
/* pass to IP layer for more dealing */
IPInput(MemHead);
break;
case ETHER_TYPE_ARP:
#ifdef debug_eth
Uart_Printf( "\ncase ETHER_TYPE_ARP:\n" ) ;
#endif
if((p = ARPInput(MemHead,NetIf)) != NULL)
{
/* a arp reply need to be send */
((struct SEtherDevice *)(NetIf->Info))->send(
p->pStart,sizeof(struct SARPPacket)
+ sizeof(struct SEtherHead));
MemFree(p);
}
/* 'MemHead' is freed in ARPInput() */
break;
default:
/* unknown packet type free */
MemFree(MemHead);
}
}
}
/* ethernet device init */
void EtherDevInit(struct SEtherDevice *pDevice,
BYTE EtherAddr[],
BOOL ( *send)(BYTE *buf,WORD size),
struct SMemHead * (*recv)() )
{
MemCopy(pDevice->Addr,EtherAddr,ETHER_ADDR_LEN);
pDevice->recv=recv ;
pDevice->send=send ;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -