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

📄 etherin.c

📁 代码在ti的c67系列单片机上实现了完整的TCPIP协议栈
💻 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 + -