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

📄 lliin.c

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

//--------------------------------------------------------------------
// LLIValidateRoute - Create/correct a route with an LLI entry as
//                    specified by the IF and IP/MAC address pair
//
// Returns a referenced route handle
//--------------------------------------------------------------------
HANDLE LLIValidateRoute( HANDLE hIF, IPN IPAddr, UINT8 *MacAddr )
{
    HANDLE hLLA,hRt,hPkt;
    LLI    *plli;

    // First see if we already have it
    if( hRt = RtFind( FLG_RTF_HOST, IPAddr ) )
    {
        // We have a match - update it

        // Get the LLI to update
        plli = (LLI *)RtGetLLI( hRt );

        if( plli->hLLA )
        {
            // Update the LLA
            LLASet( plli->hLLA, TYPE_LLA_UNICAST, 6, MacAddr );

            // Update the LLI Status
            plli->Status = LLI_STATUS_VALID;

            // Remove the LLI from the timeout list
            _LLIExpListRemove( plli );

            // Record the new valid timeout
            plli->dwTimeout = llTimerGetTime(0) +
                              (UINT32)LLI_KEEPALIVE_TIMEOUT;

            // Mark the route as up if it is down
            if( RtGetFailure( plli->hRt ) )
                RtSetFailure( plli->hRt, FLG_RTF_REPORT, 0 );

            // Return any waiting packet back to LLITxIp
            hPkt = plli->hPkt;
            plli->hPkt = 0;
            if( hPkt )
                LLITxIpPacket( hPkt );
        }
    }
    else
    {
        // We don't have a match - create one

        // Create a LLA
        if( hLLA = LLANew() )
        {
            // Update the LLA
            LLASet( hLLA, TYPE_LLA_UNICAST, 6, MacAddr );

            // Create the route
            hRt = RtCreate( FLG_RTF_REPORT, FLG_RTE_HOST|FLG_RTE_KEEPALIVE,
                            IPAddr, 0xffffffffl, hIF, 0, hLLA );

            // Set the route timeout
            if( hRt )
                RtSetTimeout( hRt, (UINT32)LLI_KEEPALIVE_TIMEOUT );

            // Deref the LLA
            LLADeRef( hLLA );
        }
    }

    // Return the referenced route
    return( hRt );
}

//--------------------------------------------------------------------
// LLIRxPacket - Receive LLI Packet
//
// Receives an ARP packet
//--------------------------------------------------------------------
void LLIRxPacket( HANDLE hPkt )
{
    HANDLE   hFrag,hIF,hLLA,hLLATmp;
    HANDLE   hRt = 0;
    IPN      dwIPDst,dwIPSrc;
    UINT8    bMAC[6];
    uint     Offset,w;
    LLI      *plli;
    UINT8    *pb;
    ARPHDR   *pArpHdr;

    if( !(hFrag = PktGetFrag( hPkt ))  )
    {
        DbgPrintf(DBG_ERROR,"LLIRxPacket: No Frag on packet!");
        goto LLIRXEXIT;
    }

    // Get the interface the packet was received on
    hIF = PktGetIFRx( hPkt );

    // Get the buffer parameters
    pb = FragGetBufParams( hFrag, 0, 0, &Offset );

    // We don't ever use the LLC
    if( PktGetFlags( hPkt ) & FLG_PKT_LLC_VALID )
    {
        // Get offset to our data
        Offset += PktGetSizeLLC( hPkt );

        // Patch the LLC out of the packet
        FragSetBufParams( hFrag, ARPHDR_SIZE, Offset );
        PktSetFlagsClear( hPkt, FLG_PKT_LLC_VALID );
    }

    // Get offset to our data
    pArpHdr = (ARPHDR *)(pb + Offset);

    // Validate Sender Hardware address
    hLLA = EtherGetLLADirect( hIF );
    LLAGetData( hLLA, 6, bMAC );

    // Check to see if we Rx'd our own frame
    if( *((UINT16 *)pArpHdr->SrcAddr)     == *((UINT16 *)(bMAC)) &&
           *((UINT16 *)(pArpHdr->SrcAddr+2)) == *((UINT16 *)(bMAC+2)) &&
           *((UINT16 *)(pArpHdr->SrcAddr+4)) == *((UINT16 *)(bMAC+4)) )
        goto LLIRXEXIT;

    // If the source MAC is a multicast or broadcast, then this is an
    // illegal ARP packet. We simply ignore it.
    if( pArpHdr->SrcAddr[0] & 1 )
        goto LLIRXEXIT;

    // Get the IP Source and Dest
    dwIPSrc = RdNet32(pArpHdr->IPSrc);
    dwIPDst = RdNet32(pArpHdr->IPDst);

    // If the sender thinks they are us, we have a problem
    if( BindFindByHost( hIF, dwIPSrc ) )
    {
        // Notify Route Control of the problem
        RTCReport( MSG_RTC_DUPIP, dwIPSrc, (UINT32)(pArpHdr->SrcAddr) );

        // We always reply to this condition
        dwIPDst = dwIPSrc;

        // hLLA is the REPLY MAC (Already set to hIF's Directed MAC)
    }
    // else If this packet is for the local IF, we record the source
    else if( BindFindByHost( hIF, dwIPDst ) )
    {
        // Update the host route with the supplied MAC, or create
        // a new host route given the supplied MAC.
        hRt = LLIValidateRoute( hIF, dwIPSrc, pArpHdr->SrcAddr );

        // hLLA is the REPLY MAC (Already set to hIF's Directed MAC)
    }
    // else Check for Proxy Arp Reply
    else
    {
        // We check PROXY first. If PROXY is set to respond, then we
        // know we have different IF's, thus PROXYPUB is not possible.
        // Otherwise, we'll check for a PROXYPUB.
        if( !(hRt = RtFind( FLG_RTF_PROXY, dwIPDst )) )
            goto CheckProxyPub;
        else
        {
            w = RtGetFlags( hRt );

            // If this is a Standard Proxy,
            // hLLA is the REPLY MAC (Already set to hIF's Directed MAC)
            if( (w & FLG_RTE_PROXY) && (hIF != RtGetIF( hRt )) )
                goto RequestValid;
        }
CheckProxyPub:
        // Check for a ProxyPub address
        if( !(hRt = RtFind( FLG_RTF_PROXYPUB, dwIPDst )) )
            goto LLIRXEXIT;
        else
        {
            w = RtGetFlags( hRt );

            if( !(w & FLG_RTE_PROXYPUB) || hIF != RtGetIF( hRt ) )
                // Not a proxy, or not on Proxy IF
                goto LLIRXEXIT;
            else
            {
                // ProxyPub - Publish another adapter's MAC on its behalf
                plli = (LLI *)RtGetLLI( hRt );
                // hLLA is the REPLY MAC
                hLLA = plli->hLLA;
            }
        }
    }

RequestValid:
    // If we get here, we may need to reply.
    if( pArpHdr->Op == HNC16(0x01) )
    {
        // Send ARP Reply

        // dwIPSrc  = New DstIP
        // SrcAddr  = New DstAddr
        // dwIPDst  = Net SrcIP
        // hLLA     = New SrcAddr
        // hIF      = Target IF

        // Create a TmpLLA
        if( hLLATmp = LLANew() )
        {
            // The packet is PHYSICALLY going to hLLATmp
            // Update the hLLATmp
            LLASet( hLLATmp, TYPE_LLA_UNICAST, 6, pArpHdr->SrcAddr );
            PktSetLLADst( hPkt, hLLATmp );

            // Set the Destination
            WrNet32( pArpHdr->IPDst, dwIPSrc );
            LLAGetData( hLLATmp, 6, pArpHdr->DstAddr );

            // Done with hLLATmp (packet is keeping a ref)
            LLADeRef( hLLATmp );

            // Set the Source
            WrNet32( pArpHdr->IPSrc, dwIPDst );
            LLAGetData( hLLA, 6, pArpHdr->SrcAddr );

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

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

LLIRXEXIT:
    // hRt Must be DeRef'd
    if( hRt )
        RtDeRef( hRt );
    // hPkt Must be Free'd
    if( hPkt )
        PktFree( hPkt );
}

⌨️ 快捷键说明

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