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