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

📄 lliout.c

📁 代码在ti的c67系列单片机上实现了完整的TCPIP协议栈
💻 C
字号:
//--------------------------------------------------------------------------
// Ip Stack
//--------------------------------------------------------------------------
// LLIOut.c
//
// Link level Resolution
//
// Author: Michael A. Denio
// Copyright 1999 by Texas Instruments Inc.
//-------------------------------------------------------------------------
#include <stkmain.h>
#include "lli.h"

//--------------------------------------------------------------------
// LLITxIpPacket - Resolve Tx Packet
//
// Resolves the MAC addressing of the packet, queues it to an LLI
// entry, or gives it back to IP.
//--------------------------------------------------------------------
void LLITxIpPacket( HANDLE hPkt )
{
    uint   tmp;
    HANDLE hIF,hRt;
    LLI    *plli;

    //
    // Our final goal is to have the following:
    //
    // Valid EtherType in Packet Object
    // Valid IFTx in Pkt
    // Pkt Dst is valid LLA or Packet contains mappable IP
    //
    // If any of these are not valid now, we can't hand the packet
    // off the the device.
    //
    // Additionally, if EtherType or hIF are invalid, we should never
    // have gotten here to begin with.
    //

    // Verify outgoing IF and Dst LLA

    // At this point, we must have an egress interface
    if( !(hIF = PktGetIFTx( hPkt )) )
    {
        DbgPrintf(DBG_ERROR,"LLIResolve: No IF");
        PktFree( hPkt );
        return;
    }

    // hLLADst must be valid
    if( !PktGetLLADst( hPkt ) )
    {
        // We must find a destination LLA for the packet

        // The route MUST be valid
        if( !(hRt = PktGetRoute( hPkt )) )
        {
            DbgPrintf(DBG_ERROR,"LLIResolve: No DstLLA/Route");
            PktFree( hPkt );
            return;
        }

        // Override the egress IF with that from the route
        hIF = RtGetIF( hRt );

        // Get the route flags
        tmp = RtGetFlags( hRt );

        //
        // - The route can not be CLONING, GATEWAY or IFLOCAL
        // - The route MUST have an LLI
        //
        if( (tmp & (FLG_RTE_CLONING|FLG_RTE_GATEWAY|FLG_RTE_IFLOCAL)) ||
            !(plli = RtGetLLI( hRt )) )
        {
            DbgPrintf(DBG_ERROR,"LLIResolve: Invalid Route %04x",tmp);
            PktFree( hPkt );
            return;
        }

        // If the LLI does not have a valid LLA, then we need to
        // so some resolving, else assign the destination
        if( plli->Status == LLI_STATUS_VALID )
            PktSetLLADst( hPkt, plli->hLLA );
        else
        {
            // Here we have an LLI without an LLA. The methodology
            // of obtaining an LLA on Ethernet is via ARP. Here we
            // attach the pending packet to the LLI entry for later.

            // Attach packet, and discard any previously attached packet
            if( plli->hPkt )
                PktFree( plli->hPkt );
            plli->hPkt = hPkt;

            // Send an ARP if IDLE
            if( plli->Status == LLI_STATUS_IDLE )
            {
                // Signify we've initiated ARP
                plli->Status = LLI_STATUS_ARP1;

                // Insert into timeout list
                _LLIExpListInsert( plli, llTimerGetTime(0) + 2 );

                // Send the ARP
                LLIGenArpPacket( RtGetIF(plli->hRt), RtGetIPAddr(plli->hRt) );
            }

            // We're done for now
            return;
        }
    }

    // Tell Ether that the LLC layer is invalid
    PktSetFlagsClear( hPkt, FLG_PKT_LLC_VALID );

    // Once here, the packet is ready to be dispatched to the IF device
    // that can transmit it.
    // NOTE: For us, ALL devices are currently ETHER
    EtherTxPacket( hIF, hPkt );
}

//--------------------------------------------------------------------
// LLIMapIpPacket - Map IP to Packet Dst LLA
//
// Maps an IP multicast addr to an LLA compatible with the packet's
// egress device.
//--------------------------------------------------------------------
HANDLE LLIMapIpPacket( HANDLE hPkt, IPN IPDst )
{
    HANDLE hLLA;
    UINT8  bMac[6];

    //
    // For now assume Ethernet (all our devices are Ethernet)
    //

    // Create the destination LLA
    if( (hLLA = LLANew()) != 0 )
    {
        // Map the relevant IP bits
        IPDst = HNC32(IPDst);
        IPDst = (IPDst & 0x7fffffl) | 0x5e000000l;

        // Form multicast MAC address
        bMac[0] = 0x01;
        bMac[1] = 0x00;
        bMac[2] = (UINT8)(IPDst >> 24);
        bMac[3] = (UINT8)(IPDst >> 16);
        bMac[4] = (UINT8)(IPDst >> 8);
        bMac[5] = (UINT8)(IPDst);

        // Set multicast address
        LLASet( hLLA, TYPE_LLA_MULTICAST, 6, bMac );

        // Set the destination LLA
        PktSetLLADst( hPkt, hLLA );

        // Packet holds the reference
        LLADeRef( hLLA );
    }

    return(hLLA);
}

//--------------------------------------------------------------------
// LLIGenArpPacket - Transmit ARP Packet
//
// Create an ARP packet for the given IF/IP and transmit it
//--------------------------------------------------------------------
void LLIGenArpPacket( HANDLE hIF, IPN dwIPDst )
{
    IPN     dwIPSrc;
    HANDLE  hPkt,hFrag,hLLA;
    uint    Offset,BufSize;
    UINT8   *pb;
    ARPHDR  *pArpHdr;

    // Get the parameters (Interface and DestIP)
    dwIPSrc = BindIFNet2IPHost( hIF, dwIPDst );

    // Check for idiots
    if( !hIF || !dwIPDst || dwIPDst==0xFFFFFFFF || !dwIPSrc )
    {
        DbgPrintf(DBG_ERROR,"LLIGenArpPacket: Illegal ARP Attempt - Check Configuration");
        return;
    }

    // Create the packet
    if( !(hPkt = IFCreatePacket( ARPHDR_SIZE, 0, 0 )) )
        return;

    // Get a pointer to the net data
    // We know we don't have an offset yet, because the packet is
    // empty!
    hFrag = PktGetFrag( hPkt );
    pb    = FragGetBufParams( hFrag, &BufSize, 0, 0 );

    // Point past the LLC header
    Offset = PktGetSizeLLC( hPkt );
    pArpHdr = (ARPHDR *)(pb + Offset);

    // Fill in the Source MAC address
    hLLA = EtherGetLLADirect( hIF );
    LLAGetData( hLLA, 6, pArpHdr->SrcAddr );

    // Fill in the Destination MAC address
    mmZeroInit( pArpHdr->DstAddr, 6 );

    // Get the Destination
    hLLA = EtherGetLLABCast( hIF );
    PktSetLLADst( hPkt, hLLA );

    // Fill in IPs
    WrNet32( pArpHdr->IPSrc, dwIPSrc );
    WrNet32( pArpHdr->IPDst, dwIPDst );

    // Validate the ARP packet
    pArpHdr->HardType = HNC16(0x1);
    pArpHdr->ProtocolType = HNC16(0x800);
    pArpHdr->Op = HNC16(0x1);
    pArpHdr->HardSize = 6;
    pArpHdr->ProtocolSize = 4;

    // Set the Ether Type
    PktSetEthType( hPkt, 0x806 );

    // Set the fragment valid data size and offset
    FragSetBufParams( hFrag, ARPHDR_SIZE, Offset );

    // Tell Ether that the LLC layer is invalid
    PktSetFlagsClear( hPkt, FLG_PKT_LLC_VALID );

    // Send the packet
    EtherTxPacket( hIF, hPkt );
}

⌨️ 快捷键说明

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