📄 lliin.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 + -