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

📄 sockpcb.c

📁 代码在ti的c67系列单片机上实现了完整的TCPIP协议栈
💻 C
📖 第 1 页 / 共 2 页
字号:
    // If we got here, the addr is OK
    ps->dwLIP = dwLIP;
    ps->LPort = LPort;
    ps->OptionFlags |= SockOpts;

    return(0);
}

//--------------------------------------------------------------------
// SockPcbConnect()
//
// Set the foreign address to that specified in FIP and FPort
//--------------------------------------------------------------------
int SockPcbConnect( HANDLE hSock, IPN dwFIP, uint FPort )
{
    SOCK   *ps    = (SOCK *)hSock;
    SOCK   *psTmp;
    int    wc;

#ifdef _STRONG_CHECKING
    if( ps->Type != HTYPE_SOCK )
    {
        DbgPrintf(DBG_ERROR,"SockPcbConnect: HTYPE %04x",ps->Type);
        return( 0 );
    }

    if( ps->SockProt > 4 )
    {
        DbgPrintf(DBG_ERROR,"SockPcbConnect: Invalid SockProt");
        return( 0 );
    }
#endif

    // Anything goes with Raw sockets
    if( ps->SockProt == SOCKPROT_RAW )
        goto SockPcbConnectOk;

    // Verify that we have a local binding
    // Note that dwLIP can be NULL if one really odd case...
    if( !ps->dwLIP || !ps->LPort )
    {
        // We can bind to [0.0.0.0] if we've specified an IFTx device
        if( !ps->LPort || !ps->hIFTx )
            return( EINVAL );
    }

    // Verify we have a desired IP, and port
    if( !dwFIP || !FPort )
        return( EINVAL );

    // Find the best match
    psTmp = SockPcbFind( pSockList[ps->SockProt],
                         ps->dwLIP, ps->LPort, dwFIP, FPort, &wc, 0 );

    // Check for conflict
    if( psTmp && psTmp != ps && wc == 0 )
        return( EADDRINUSE );

SockPcbConnectOk:
    // If we got here, the addr is OK
    ps->dwFIP = dwFIP;
    ps->FPort = FPort;

    return(0);
}

//--------------------------------------------------------------------
// SockPcbResolve()
//
// Find the "best" match given the supplied parameters, and
// potentially spawn a new socket from an "accepting" (listening)
// socket.
//--------------------------------------------------------------------
HANDLE SockPcbResolve
(
    uint   SockProt,
    IPN    dwLIP,
    uint   LPort,
    IPN    dwFIP,
    uint   FPort,
    uint   Match
)
{
    SOCK *ps;
    SOCK *psSpawn;
    int  wc;

    // The first thing to do is the find the best match
    ps = SockPcbFind( pSockList[SockProt],
                      dwLIP, LPort, dwFIP, FPort, &wc, 0 );

    // Return NULL for no match, or for wildcard match when EXACT required
    if( !ps || (wc && Match == SOCK_RESOLVE_EXACT) )
        return(0);

    // If match type is not SPAWN, then we return what we got
    if( Match != SOCK_RESOLVE_SPAWN )
        return( ps );

    // We have a match type of SPAWN with wildcards. Here, we only return
    // a socket if we can spawn it. i.e.: exact match is a failure
    if( !wc )
        return(0);

    // If we're out of connect space, abort
    if( ps->ConnTotal >= ps->ConnMax )
        return(0);

    // Create a new socket - return NULL if we can't create it
    if( SockNew(ps->Family, ps->SockType, ps->Protocol, 0, (HANDLE *)&psSpawn) )
        return(0);

    // Inherit SOCKET Options
    psSpawn->OptionFlags |= ps->OptionFlags & ~(SO_ACCEPTCONN);
    psSpawn->dwLingerTime = ps->dwLingerTime;
    psSpawn->dwRxTimeout  = ps->dwRxTimeout;
    psSpawn->dwTxTimeout  = ps->dwTxTimeout;

    // Inherit IP Options
    psSpawn->IpFlags   = ps->IpFlags;
    psSpawn->IpTtl     = ps->IpTtl;
    psSpawn->IpTos     = ps->IpTos;
    if( ps->IpOptSize )
    {
        psSpawn->IpOptSize = ps->IpOptSize;
        mmCopy( psSpawn->IpOptions, ps->IpOptions, ps->IpOptSize );
    }

    // Inherit Some Protocol Options
    SockPrInherit( ps, psSpawn );

    // We're going to cheat here. We know the specified parameters do
    // not conflict (as there was no exact match).
    psSpawn->dwLIP  = dwLIP;
    psSpawn->LPort  = LPort;
    psSpawn->dwFIP  = dwFIP;
    psSpawn->FPort  = FPort;

    // Enqueue the spawned packet onto the parent's Pending queue
    psSpawn->pParent     = ps;
    psSpawn->pPending    = ps->pPending;
    ps->pPending         = psSpawn;
    psSpawn->StateFlags |= SS_PENDINGQ;
    ps->ConnTotal++;

    return( psSpawn );
}

//--------------------------------------------------------------------
// SockPcbResolveChain()
//
// This is a chain version of PCB resolve, finding all sockets which
// match the selection criteria.
//--------------------------------------------------------------------
HANDLE SockPcbResolveChain
(
    HANDLE hSock,
    uint   SockProt,
    uint   Prot,
    IPN    dwLIP,
    uint   LPort,
    IPN    dwFIP,
    uint   FPort
)
{
    SOCK *ps = (SOCK *)hSock;

    // We chain off the supplied SOCK, or start at the head of the list
    // on a NULL
    if( !ps )
        ps = pSockList[SockProt];
    else
        ps = ps->pProtNext;

    // Find a match
    if( SockProt != SOCKPROT_RAW )
        ps = SockPcbFind( ps, dwLIP, LPort, dwFIP, FPort, 0, 1 );
    else
        ps = SockPcbFindRaw( ps, Prot, dwLIP, dwFIP, 0, 1 );

    return(ps);
}

//--------------------------------------------------------------------
// SockPcbCleanup()
//
// Abort all closing sockets
//--------------------------------------------------------------------
void SockPcbCleanup()
{
    SOCK *ps;
    int  GotOne;

    // The only type of socket that can be "closing" is TCP
    // We'll search and we'll search until no Closing socket lives
    do
    {
        GotOne = 0;
        ps = pSockList[SOCKPROT_TCP];
        while( ps )
        {
            if( ps->StateFlags & SS_CLOSING )
            {
                GotOne = 1;
                SockIntAbort( ps );
                break;
            }
            ps = ps->pProtNext;
        }
    } while( GotOne );
}

//--------------------------------------------------------------------
// SockCtlError()
//
// Called to notify the socket layer that an error has occurred
//--------------------------------------------------------------------
void SockPcbCtlError( uint Code, IPHDR *pIpHdr )
{
    IPN    dwLIP,dwFIP;
    uint   offset,SockProt;
    int    wc;
    UDPHDR *pUdpHdr;
    SOCK   *ps;

    dwFIP = RdNet32( &pIpHdr->dwIPDst );
    dwLIP = RdNet32( &pIpHdr->dwIPSrc );

    // Get the offset to the transport hdr (assume UDP)
    offset = (pIpHdr->VerLen & 0xF) * 4;
    pUdpHdr = (UDPHDR *)(((UINT8 *)pIpHdr)+offset);

    // Get the correct SockProt to notify
    if( pIpHdr->Protocol == 6 )
        SockProt = SOCKPROT_TCP;
    else if( pIpHdr->Protocol == 17 )
        SockProt = SOCKPROT_UDP;
    else
        return;

    // Notify all exact matches
    ps = pSockList[SockProt];

    while( ps )
    {
        // Find a match
        ps = SockPcbFind( ps, dwLIP, pUdpHdr->SrcPort,
                                     dwFIP, pUdpHdr->DstPort, &wc, 1 );
        // Notify the protocol
        if( ps && !wc )
        {
            // For redirect errors, we just update the route.
            if( Code >= PRC_REDIRECT_NET && Code <= PRC_REDIRECT_TOSHOST )
                SockValidateRoute( ps );
            else
                SockPrCtlError( ps, Code );
        }

        // Get the next matching socket
        if( ps )
            ps = ps->pProtNext;
    }
}

//--------------------------------------------------------------------
// SockPcbRtChange()
//
// Called to notify the socket layer that a route has changed
//--------------------------------------------------------------------
void SockPcbRtChange( HANDLE hRt )
{
    SOCK   *ps;
    int    i;

    for( i=SOCKPROT_TCP; i<=SOCKPROT_RAW; i++ )
    {
        ps = pSockList[i];

        while(ps)
        {
            if( ps->hRoute == hRt )
            {
                ps->hRoute = 0;
                RtDeRef( hRt );
            }
            SockValidateRoute( ps );
            ps = ps->pProtNext;
        }
    }
}

//--------------------------------------------------------------------
// SockGetPcb()
//
// Return socket PCB list
//--------------------------------------------------------------------
int SockGetPcb( uint SockProt, uint BufSize, UINT8 *pBuf )
{
    SOCK    *ps;
    SOCKPCB *ppcb;
    int     i;

    if( SockProt<SOCKPROT_TCP || SockProt>SOCKPROT_RAW )
        return(0);

    ps = pSockList[ SockProt ];

    i=0;
    while( ps && BufSize >= sizeof( SOCKPCB ))
    {
        ppcb = (SOCKPCB *)pBuf;

        ppcb->IPAddrLocal   = ps->dwLIP;
        ppcb->PortLocal     = ps->LPort;
        ppcb->IPAddrForeign = ps->dwFIP;
        ppcb->PortForeign   = ps->FPort;
        if( ps->hTP )
            ppcb->State = SockPrGetState( ps, ps->hTP );
        else
            ppcb->State = 0;
        if( !ppcb->State && (ps->OptionFlags & SO_ACCEPTCONN) )
            ppcb->State = 1;

        i++;
        BufSize -= sizeof(SOCKPCB);
        pBuf    += sizeof(SOCKPCB);

        ps = ps->pProtNext;
    }

    return(i);
}

⌨️ 快捷键说明

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