📄 etherin.c
字号:
//--------------------------------------------------------------------------
// Ip Stack
//--------------------------------------------------------------------------
// ETHERIN.C
//
// Receive routines interact with the low-level packet support layer.
//
// Author: Michael A. Denio
// Copyright 1999 by Texas Instruments Inc.
//-------------------------------------------------------------------------
#include <stkmain.h>
//--------------------------------------------------------------------
// EtherRxPacket()
//
// This routine takes a raw packet received from the MAC device, and
// validates the link level related data. Link level fields include the
// LLC Header size, and the EtherType field. If the packet requires
// additional processing, it is passed on the the specific routine
// indicated by the LLC header.
//--------------------------------------------------------------------
void EtherRxPacket( HANDLE hIF, uint size, UINT8* pb )
{
ETHDRV *pe = (ETHDRV *)hIF;
HANDLE hPkt;
HANDLE hFrag;
uint Type;
UINT8 *pbTmp;
int i;
if( pe->Type != HTYPE_ETH )
{
DbgPrintf(DBG_ERROR,"EtherRxPacket: Invalid Handle");
llPacketReturnBuffer( pb );
return;
}
// We have a packet for a legal device of "size" bytes in UINT8 *pb
// The length of the packet must conform to standard Ethernet
if( (size - pe->EthHdrSize - pe->PacketPad) < ETH_MIN_PAYLOAD
|| size > pe->PhysMTU )
{
DbgPrintf(DBG_WARN,"EtherRxPacket: Bad Size");
llPacketReturnBuffer( pb );
return;
}
// Take off the CRC pad (if any)
size -= pe->PacketPad;
// Create a packet structure
if( !(hPkt = PktNew()) )
{
llPacketReturnBuffer( pb );
return;
}
// Wrap the buffer in a packet fragment
if( !(hFrag=FragNewWrap( FRAG_POOL_PACKET, size, size, 0, pb )) )
{
// We can't use it
PktFree( hPkt );
llPacketReturnBuffer( pb );
return;
}
// Attach the frag to the packet
PktSetFrag( hPkt, hFrag );
// Initialize essentials
PktSetIFRx( hPkt, hIF );
// We need to pass the packet to the next layer, after
// translating some of the fields in the packet structure.
// Now that we think the packet is valid, the
// first thing to do is to find the EtherType (if any) in
// order to determine where the packet belongs.
// See if the destination is a link-level MCast or BCast
pbTmp = pb+pe->OffDstMac;
if( *pbTmp & 1 )
{
for( i=0; i<6; i++ )
if( *pbTmp++ != 0xFF )
break;
if( i == 6 )
PktSetFlagsSet( hPkt, FLG_PKT_MACBCAST );
else
PktSetFlagsSet( hPkt, FLG_PKT_MACMCAST );
}
// Decode packet, validate the ethernet header, and send to
// appropriate task handler
// Get header type (802.3 or Ethernet), in NETWORK format
pbTmp = pb+pe->OffEtherType;
Type = *pbTmp * 256 + *(pbTmp+1);
// If the "type" field is less than 1514-hdrlen, the word actually
// specifies "size" (strict 802.3), and the packet will have an 802.2
// header as well.
if( Type >= 0x600 )
{
// Frame is Ethernet, so we'll mark the LLC header as valid.
// We can now also validate header size and EtherType fields.
PktSetSizeLLC( hPkt, pe->EthHdrSize );
}
else
{
// Get a pointer to the 802.2 header
pbTmp = pb + pe->EthHdrSize;
// If this is not a 802.2 SNAP Packet, the tpye is invalid
if( *pbTmp != 0xAA )
Type = 0;
// Else, we can get the type from the SNAP header
else
{
pbTmp += 6;
Type = *pbTmp * 256 + *(pbTmp+1);
// Add the size of the SNAP header to the ETHER size
PktSetSizeLLC( hPkt, pe->EthHdrSize+6 );
}
}
// Save the Ether Type
PktSetEthType( hPkt, Type );
// Mark the LLC as valid (part of the valid data)
PktSetFlagsSet( hPkt, FLG_PKT_LLC_VALID );
// Dispatch the Packet
switch( PktGetEthType( hPkt ) )
{
case 0x800:
IPRxPacket( hPkt );
break;
case 0x806:
LLIRxPacket( hPkt );
break;
#ifdef _INCLUDE_PPPOE_CODE
case ETHERTYPE_PPPOE_CTRL:
case ETHERTYPE_PPPOE_DATA:
pppoeInput( hPkt );
break;
#endif
default:
PktFree( hPkt );
break;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -