📄 route.c
字号:
if( prt->Flags & FLG_RTE_UP )
RTCReport( MSG_RTC_UP, prt->dwIPAddr, prt->dwIPMask );
else
RTCReport( MSG_RTC_DOWN, prt->dwIPAddr, prt->dwIPMask );
}
}
//---------------------------------------------------------------------
// RtRemove - Remove a Route from the Route Table
//
// Flags:
// FLG_RTF_REPORT Report removal
//
// Failure Code:
// RTC_HOSTDOWN - Host is down
// RTC_HOSTUNREACH - Host unreachable
// RTC_NETUNREACH - Network unreachable
//
// Called to remove a route from the route table independently of any
// held refereces. This will cause the route to return the designated
// failure code to those that still hold a reference, but this function
// will also attempt to flush all cached references.
//---------------------------------------------------------------------
void RtRemove( HANDLE hRt, uint CallFlags, uint FailCode )
{
RT *prt = (RT *)hRt;
int deref = 0;
#ifdef _STRONG_CHECKING
if( prt->Type != HTYPE_RT )
{
DbgPrintf(DBG_ERROR,"RtSetFailure: HTYPE %04x",prt->Type);
return;
}
#endif
// Set the failure code
prt->Flags |= FLG_RTE_UP;
prt->FailCode = FailCode;
// Remove the entry from the timeout list if necessary
// And keep track of the times we will deref
if( prt->dwTimeout )
{
_RtExpListRemove( prt );
deref++;
}
// If we're STATIC, clear it and add a deref
if( prt->Flags & FLG_RTE_STATIC )
{
prt->Flags &= ~FLG_RTE_STATIC;
deref++;
}
// Post a report if requested
if( CallFlags & FLG_RTF_REPORT )
RTCReport( MSG_RTC_REMOVED, prt->dwIPAddr, prt->dwIPMask );
// Remove from Node list (removes the route from the route table)
_RtNodeRemove( prt );
// Notify all who cache routes
IPRtChange( (HANDLE)prt );
SockPcbRtChange( (HANDLE)prt );
// DeRef the route for any TimeoutList or STATIC removals
while( deref-- )
RtDeRef( prt );
}
//---------------------------------------------------------------------
// RtSetTimeout
//
// Set the timeout for a node in seconds
//---------------------------------------------------------------------
void RtSetTimeout( HANDLE hRt, UINT32 dwTimeout )
{
RT *prt = (RT *)hRt;
#ifdef _STRONG_CHECKING
if( prt->Type != HTYPE_RT )
{
DbgPrintf(DBG_ERROR,"RtSetTimeout: HTYPE %04x",prt->Type);
return;
}
#endif
// Ignore this call if the route is already expired
if( prt->Flags & FLG_RTE_EXPIRED )
return;
// Add one reference to the route if this is a NEW timeout
if( !prt->dwTimeout )
RtRef( prt );
// Get physical Timeout in Seconds
dwTimeout += llTimerGetTime(0);
// Set the Timeout
_RtExpListInsert( prt, dwTimeout );
}
//---------------------------------------------------------------------
// RtCreate - Create a route
//
// Parameters:
// CallFlags Call Type Flags
// Flags Route Type Flags
// dwIPAddr Destination IP address of route
// dwIPMask Destination IP Mask of route (or NULL)
// hIF Interface (or NULL)
// dwIPGate Gate IP address (or NULL)
// hLLA Static host L2 address for hLLI (or NULL)
//
// Description:
// Called to create a new host or network route and add it to the
// route table. Existing routes can not be modified via this call.
//
// Some flag combinations make no sense, but only the following are
// strictly enforced.
//
// FLG_RTE_UP in Flags is always SET.
//
// FLG_RTE_EXPIRED and FLG_RET_MODIFIED in Flags is always CLEARED.
//
// If FLG_RTE_STATIC is specified in Flags, the route is referenced
// once by the route code, and later dereferenced during shutdown.
//
// If FLG_RTE_PROXYPUB is specified in Flags, then FLG_RTE_HOST must
// also be set, and hLLA must be valid.
//
// If FLG_RTE_HOST is specified in Flags then the route is a host
// route and dwIPMask is ignored. FLG_RTE_CLONING can not be set.
//
// If FLG_RTE_GATEWAY is specified in Flags, then dwIPGate specifies
// a valid IP address.
//
// If FLG_RTE_IFLOCAL is specified in Flags, then the specified host
// address is local to this machine. FLG_RTE_HOST must also be set and
// hIF must be valid.
//
// If FLG_RTE_CLONING is specified in Flags, the route is a cloning
// network route. The dwIPMask argument must be valid, and the
// FLG_RTE_HOST or FLG_RET_GATEWAY flag must not be set.
//
// Note: LLIs do not "reference" their parent routes. If they did,
// the route refcnt would never reach zero.
//
// Flags:
// FLG_RTF_REPORT Report any new or unfound route
//
// Returns:
// Referenced handle to newly created route
//---------------------------------------------------------------------
HANDLE RtCreate( uint CallFlags, uint Flags, IPN dwIPAddr,
IPN dwIPMask, HANDLE hIF, IPN dwIPGate, HANDLE hLLA )
{
RT *prt;
UINT32 dwTest;
uint MaskBits;
// Clear/Set required flags
Flags |= FLG_RTE_UP;
Flags &= ~(FLG_RTE_MODIFIED|FLG_RTE_EXPIRED);
//
// Verify Legal Flag Configuration
//
// A PROXYPUB entry must be a HOST and have a MAC address supplied.
if( (Flags & FLG_RTE_PROXYPUB) && (!(Flags & FLG_RTE_HOST) || !hLLA) )
return(0);
// Host routes can not be CLONING routes. Also, if DYNAMIC, they
// must be GATEWAY routes, since directly connected DYNAMIC routes
// are illegal.
if( Flags & FLG_RTE_HOST )
{
if( Flags & FLG_RTE_CLONING )
return(0);
if( (Flags & FLG_RTE_DYNAMIC) && !(Flags & FLG_RTE_GATEWAY) )
return(0);
}
// GATEWAY routes must have a valid (and reachable) dwIPGate, and
// can not be CLONING routes.
if( Flags & FLG_RTE_GATEWAY )
{
if( Flags & FLG_RTE_CLONING )
return(0);
if( !dwIPGate || dwIPGate == dwIPAddr || !BindFindByNet(0,dwIPGate) )
return(0);
}
// Non-GATWAY routes must have an IF
else if( !hIF )
return(0);
//
// Create Route
//
// Create the route structure
if( !(prt = (RT *)RtNew()) )
return(0);
// Transfer the calling arguments
prt->hIF = hIF;
prt->Flags = Flags;
prt->dwIPAddr = dwIPAddr;
prt->dwIPMask = dwIPMask;
prt->dwIPGate = dwIPGate;
// If we have an IF, validate the MTU
if( hIF )
prt->ProtMTU = IFGetMTU( hIF );
// Check route type
if( Flags & FLG_RTE_HOST )
{
// Route is a host route
prt->dwIPMask = 0xffffffff;
prt->MaskBits = 32;
// Create LLI if LLA is provided, or we're NOT IFLOCAL or GATEWAY
if( hLLA || !(prt->Flags & (FLG_RTE_IFLOCAL|FLG_RTE_GATEWAY)) )
{
// Create static LLI
prt->hLLI = LLINew( prt, hLLA );
// Check for an error
if( !prt->hLLI )
{
RtFree( prt );
return(0);
}
}
}
else
{
// Route is a network route
// Validate the Mask Bits
dwIPMask = HNC32( dwIPMask ); // Convert to host format
dwTest = 0x80000000;
MaskBits = 0;
while( dwTest & dwIPMask )
{
MaskBits++;
dwTest >>= 1;
}
prt->MaskBits = MaskBits;
}
// We're now ready to add the route to the NODE tree.
if( !_RtNodeInsert( prt ) )
{
RtFree( prt );
return(0);
}
// STATIC routes add a system reference which is removed at
// system shutdown
if( prt->Flags & FLG_RTE_STATIC )
RtRef( prt );
// Next, post a report if needed
if( CallFlags & FLG_RTF_REPORT )
{
// Send Routing Report
RTCReport( MSG_RTC_NEW, prt->dwIPAddr, prt->dwIPMask );
}
return( prt );
}
//---------------------------------------------------------------------
// RtRedirect - Create Static Host Redirect Route
//
// Parameters:
// dwHostIP Host IP address to redirect
// dwIPGate Gate IP address
//
// Description:
// Called to create or modify a gatway host route.
//
// Returns:
// void
//---------------------------------------------------------------------
void RtRedirect( IPN dwIPHost, IPN dwIPGate )
{
RT *prt;
// Brain damage check - Gateway must be valid and reachable
if( !dwIPGate || dwIPGate == dwIPHost || !BindFindByNet(0,dwIPGate) )
return;
// Find the closest route we have
prt = RtFind( 0, dwIPHost );
if( prt )
{
// See if we can modify this route
if( (prt->Flags & (FLG_RTE_HOST|FLG_RTE_GATEWAY))
== (FLG_RTE_HOST|FLG_RTE_GATEWAY) )
{
// Modify existing route
prt->Flags |= FLG_RTE_MODIFIED;
prt->dwIPGate = dwIPGate;
RtDeRef( prt );
return;
}
RtDeRef( prt );
}
// Create new gateway route
prt = RtCreate( FLG_RTF_REPORT,
FLG_RTE_HOST|FLG_RTE_GATEWAY|FLG_RTE_DYNAMIC|FLG_RTE_STATIC,
dwIPHost, 0xffffffffl, 0, dwIPGate, 0 );
if( prt )
RtDeRef( prt );
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -