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

📄 route.c

📁 代码在ti的c67系列单片机上实现了完整的TCPIP协议栈
💻 C
📖 第 1 页 / 共 2 页
字号:
        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 + -