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

📄 rtable.c

📁 代码在ti的c67系列单片机上实现了完整的TCPIP协议栈
💻 C
📖 第 1 页 / 共 2 页
字号:

        // Save the expiration
        prt->dwTimeout = dwExp;

        // Now add the entry to the list
        // Check the easy case - being first
        if( !prtFirstExp || prtFirstExp->dwTimeout >= dwExp )
        {
            // What we point to next
            prt->pNextExp = prtFirstExp;
            // Before us...pointing to us
            prtFirstExp = prt;
        }
        else
        {
            // Find an entry we expire AFTER
            prtTmp = prtFirstExp;
            while( prtTmp->pNextExp &&
                   prtTmp->pNextExp->dwTimeout < dwExp )
                prtTmp = prtTmp->pNextExp;

            // What we point to next
            prt->pNextExp = prtTmp->pNextExp;
            // Before us...pointing to us
            prtTmp->pNextExp = prt;
        }
    }
}

//--------------------------------------------------------------------
// _RtExpListRemove - Remove route from expiration list
//
// Note: Normally, routes will be removed off the top of the list.
// However, if the route is prematurely removed, it may be anywhere
// in the list.
//--------------------------------------------------------------------
void _RtExpListRemove( RT *prt )
{
    RT *prtTmp;

    // Clear the expiration time
    prt->dwTimeout = 0;

    // Check to see if we're the head of the list
    if( prt == prtFirstExp )
        prtFirstExp = prt->pNextExp;
    else
    {
        // Look for us
        prtTmp = prtFirstExp;
        while( prtTmp && prtTmp->pNextExp != prt )
            prtTmp = prtTmp->pNextExp;

        // Patch entry which points to us
        if( prtTmp )
            prtTmp->pNextExp = prt->pNextExp;
    }
}

//--------------------------------------------------------------------
// RtWalkBegin - Get First Route in Tree
//
// (Refs returned route)
//--------------------------------------------------------------------
HANDLE RtWalkBegin()
{
    HANDLE hNode;
    HANDLE hRt = 0;

    // Disable Timeouts
    _RtNoTimer++;

    // Get the first node
    hNode = NodeWalk( 0 );

    // Return the first route on the fist node
    while( hNode && !hRt )
    {
        if( hRt = NodeGetRt( hNode ) )
            RtRef( hRt );
        else
            hNode = NodeWalk( hNode );
    }

    return( hRt );
}

//--------------------------------------------------------------------
// RtWalkNext - Get Next Route in Tree
//
// (DeRefs supplied route)
// (Refs returned route)
//--------------------------------------------------------------------
HANDLE RtWalkNext( HANDLE hRt )
{
    RT     *prt    = (RT *)hRt;
    RT     *prtRet = 0;
    HANDLE hNode;

    if( prt->Type != HTYPE_RT )
    {
        DbgPrintf(DBG_ERROR,"RtWalkGetNext: HTYPE %04x",prt->Type);
        return(0);
    }

    // First walk down the Rt list
    if( prtRet = prt->pNext )
        RtRef( prtRet );
    else
    {
        hNode = NodeWalk( prt->hNode );
        while( hNode && !prtRet )
        {
            if( (prtRet = (RT*)NodeGetRt( hNode )) )
                RtRef( prtRet );
            else
                hNode = NodeWalk( hNode );
        }
    }

    RtDeRef( prt );

    return( prtRet );
}

//--------------------------------------------------------------------
// RtWalkEnd - End Tree Walk
//
//--------------------------------------------------------------------
void RtWalkEnd( HANDLE hRt )
{
    if( hRt )
    {
        if( ((RT*)hRt)->Type != HTYPE_RT )
            DbgPrintf(DBG_ERROR,"RtWalkEnd: Bad HTYPE");
        else
            RtDeRef( hRt );
    }

    // Enable Timeouts
    if( _RtNoTimer )
        _RtNoTimer--;
}


void RtDiag()
{
    RT    *prt;
    UINT32 dwTimeNow;

    if( _RtNoTimer )
        DbgPrintf(DBG_INFO,"RtDiag: Timeouts Disabled");
    else
        DbgPrintf(DBG_INFO,"RtDiag: Timeouts Enabled");

    DbgPrintf(DBG_INFO,"RtDiag: Expiration Check:%lu  Attempt:%lu  Revive:%lu",
                        dwTestChecked,dwTestAttempt,dwTestRevived);

    dwTimeNow = llTimerGetTime(0);
    prt = prtFirstExp;

    if( !prt )
        DbgPrintf(DBG_INFO,"RtDiag: No routes in Timeout List!");
    else if( (prt->dwTimeout+6l) <= dwTimeNow )
        DbgPrintf(DBG_INFO,"RtDiag: Timeout Overdue");
    else if( prt->dwTimeout <= dwTimeNow )
        DbgPrintf(DBG_INFO,"RtDiag: Timeout Pending");
    else
        DbgPrintf(DBG_INFO,"RtDiag: Next Timeout in %lu Seconds",
                                            prt->dwTimeout-dwTimeNow);
}

//---------------------------------------------------------------------
// RtFind - Find a route
//
// Flags:
//     FLG_RTF_CLONE       Create cloned entry if needed
//     FLG_RTF_REPORT      Report any new or unfound route
//     FLG_RTF_HOST        Find only non-PROXYPUB HOST routes
//     FLG_RTF_PROXY       Find only PROXY or PROXYPUB routes
//     FLG_RTF_PROXYPUB    Find only PROXY or PROXYPUB routes
//
// (Bumps reference count)
//---------------------------------------------------------------------
HANDLE RtFind( uint wCallFlags, IPN dwIP )
{
    RT     *prt,*prtClone;
    int    Search = 1;
    HANDLE hNode = 0;

    while( Search )
    {
        // The following is guaranteed to find a node
        hNode = NodeFind( dwIP, hNode );

        // Now we need to find the "best" route on this node.
        // Note: Our search can be affected by the call flags

        // Get the route
        prt = (RT *)NodeGetRt( hNode );

        // We'll set the following flag to TRUE if we pass over a match
        Search = 0;

        while( prt )
        {
            // Try this route
            if( (dwIP & prt->dwIPMask) != (prt->dwIPAddr & prt->dwIPMask) )
                goto RouteNotAccepted;

            // Quit now if there are no matching conditions
            if( !(wCallFlags & FLG_RTF_CONDITIONAL) )
                break;

            // If we discard the match due to search criteria, first
            // mark if we can or can not continue. We don't continue
            // if we are at the far left node.
            if( prt->dwIPAddr & prt->dwIPMask )
                Search = 1;

            // Host only search
            if( wCallFlags & FLG_RTF_HOST )
            {
                // If Cloning is not set, we must have an exact host match,
                // otherwise; we will accept a route that can clone into a
                // host route.
                if( (prt->Flags & (FLG_RTE_HOST|FLG_RTE_PROXY|
                            FLG_RTE_PROXYPUB|FLG_RTE_GATEWAY)) != FLG_RTE_HOST )
                {
                    // We will reject this route unless it is a viable clone
                    // route and the caller wants to clone.
                    if( !(wCallFlags & FLG_RTF_CLONE) )
                        goto RouteNotAccepted;
                    if( !(prt->Flags & FLG_RTE_CLONING) )
                        goto RouteNotAccepted;
                }
                break;
            }

            // Proxy only search
            if( wCallFlags & FLG_RTF_PROXY )
            {
                if( !(prt->Flags & FLG_RTE_PROXY) )
                    goto RouteNotAccepted;
                break;
            }

            // ProxyPub only search
            if( wCallFlags & FLG_RTF_PROXYPUB )
            {
                if( !(prt->Flags & FLG_RTE_PROXYPUB) )
                    goto RouteNotAccepted;
                break;
            }

            // This route is acceptable
            break;

RouteNotAccepted:
            // No match yet
            prt = prt->pNext;
        }

        // Reference the matched route (if any)
        if( prt )
        {
            RtRef( prt );
            Search = 0;
        }
    }

    // We no longer need the node
    NodeDeRef( hNode );

    // If we have a route, we may need to clone it
    if( prt && (prt->Flags & FLG_RTE_CLONING) && (wCallFlags & FLG_RTF_CLONE) )
    {
        uint   NewFlags;

        // Yep, we have to clone ...

        // Copy the flags
        NewFlags = prt->Flags;

        // Clear the flags that don't carry over
        NewFlags &= ~(FLG_RTE_CLONING|FLG_RTE_STATIC|FLG_RTE_DYNAMIC);

        // Make us a host
        NewFlags |= FLG_RTE_HOST;

        if( !(prtClone = RtCreate( wCallFlags, NewFlags, dwIP, 0xffffffff,
                                   prt->hIF, prt->dwIPGate, 0 )) )
            DbgPrintf(DBG_WARN,"RtFind: Clone creation failed!");
        else
        {
            // Mark as "keep-alive" route
            prtClone->Flags |= FLG_RTE_KEEPALIVE;

            // Set Default Timeout for Clone Node
            RtSetTimeout( prtClone, ROUTE_CLONE_TIMEOUT );
        }

        // DeRef the source node
        RtDeRef( prt );

        // We now use the clone node
        prt = prtClone;
    }

    // If we have no match, this is a "miss"
    if( !prt )
    {
        // Miss! Post a report if needed
        if( wCallFlags & FLG_RTF_REPORT )
        {
            // Send Routing Report
            RTCReport( MSG_RTC_MISS, dwIP, 0xffffffff );
        }
    }

    // NOTE: prt contains one of three things:
    //  1. NULL for a "miss"
    //  2. The referenced original route found
    //  3. The referenced clone route (original unreferenced above).

    return( prt );
}

⌨️ 快捷键说明

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