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

📄 bind.c

📁 代码在ti的c67系列单片机上实现了完整的TCPIP协议栈
💻 C
字号:
//--------------------------------------------------------------------------
// Ip Stack
//--------------------------------------------------------------------------
// BIND.C
//
// IP / Ether Binding Object
//
//
// Author: Michael A. Denio
// Copyright 1999 by Texas Instruments Inc.
//-------------------------------------------------------------------------
#include <stkmain.h>

// Address Structure
typedef struct _bind {
          uint          Type;           // Set to HTYPE_BIND
          struct _bind  *pNext;         // Next Binding
          HANDLE        hIF;            // Interface Handle
          HANDLE        hRtNet;         // Net Route
          HANDLE        hRtHost;        // Host Route
          IPN           dwIPHost;       // IP Addr
          IPN           dwIPNet;        // IP Net
          IPN           dwIPMask;       // IP Mask
         } BIND;

static BIND *pbindFirst = 0;

//--------------------------------------------------------------------
// BindNew()
//
// Create
//--------------------------------------------------------------------
HANDLE BindNew( HANDLE hIF, IPN dwIPHost, IPN dwIPMask )
{
    BIND   *pbind,*pbtmp;
    IPN    dwIPNet = 0;
    uint   type;

    // Verify the IF Handle
    if( !hIF )
    {
        DbgPrintf(DBG_ERROR,"BindNew: Illegal Device Handle");
        return(0);
    }

    // Get the IF type
    type = IFGetType(hIF);

    // If mask entered as '0', change it to 0xffffffff
    if( !dwIPMask )
        dwIPMask = 0xffffffffl;
    // Calc dwIPNet
    else if( dwIPMask != 0xffffffffl )
        dwIPNet = dwIPHost & dwIPMask;

    // Search for duplicate bindings
    if( (pbtmp = (BIND *)BindFindByHost(0, dwIPHost) ) ||
        (dwIPNet && (pbtmp = (BIND *)BindFindByNet(0, dwIPNet))) )
    {
        // Duplicate bindings allowed on PPP links
        if( type != HTYPE_PPP && IFGetType(pbtmp->hIF) != HTYPE_PPP )
        {
            DbgPrintf(DBG_WARN,"BindNew: Duplicate bindings ignored");
            return(0);
        }
    }

    if( !(pbind = mmAlloc(sizeof(BIND))) )
    {
        DbgPrintf(DBG_WARN,"BindNew: OOM");
        ExecLowResource();
        return(0);
    }

    // Initialize type
    pbind->Type = HTYPE_BIND;

    // Fill in the binding
    pbind->hIF      = hIF;
    pbind->dwIPHost = dwIPHost;
    pbind->dwIPNet  = dwIPNet;
    pbind->dwIPMask = dwIPMask;

    // Create a host and net route for this binding
    pbind->hRtHost = RtCreate( FLG_RTF_REPORT, FLG_RTE_HOST|FLG_RTE_IFLOCAL,
                               dwIPHost, 0xffffffffl, hIF, 0, 0 );
    if( dwIPNet && type != HTYPE_PPP )
        pbind->hRtNet = RtCreate( FLG_RTF_REPORT, FLG_RTE_CLONING,
                                  dwIPNet, dwIPMask, hIF, 0, 0 );
    else
        pbind->hRtNet = 0;

    // Tack binding pointer onto the list
    pbind->pNext = pbindFirst;
    pbindFirst   = pbind;

    // Gratuitous ARP on Ethernet
    if( IFGetType( hIF ) == HTYPE_ETH && dwIPHost != INADDR_ANY
                                         && dwIPHost != INADDR_BROADCAST )
        LLIGenArpPacket( hIF, dwIPHost );

    return( (HANDLE)pbind );
}

//--------------------------------------------------------------------
// BindFree()
//
// Destroy
//--------------------------------------------------------------------
void BindFree( HANDLE h )
{
    BIND *pbind = (BIND *)h;
    BIND *pbindTmp;

#ifdef _STRONG_CHECKING
    if( pbind->Type != HTYPE_BIND )
    {
        DbgPrintf(DBG_ERROR,"BindFree: HTYPE %04x",pbind->Type);
        return;
    }
#endif

    // Kill type for debug
    pbind->Type = 0;

    // Remove from list
    if( pbind == pbindFirst )
        pbindFirst = pbind->pNext;
    else
    {
        pbindTmp = pbindFirst;
        while( pbindTmp && pbindTmp->pNext != pbind )
            pbindTmp = pbindTmp->pNext;
        if( pbindTmp )
            pbindTmp->pNext = pbind->pNext;
    }

    // Deref Routes
    if( pbind->hRtHost )
    {
        RtRemove( pbind->hRtHost, FLG_RTF_REPORT, RTC_NETUNREACH );
        RtDeRef( pbind->hRtHost );
    }
    if( pbind->hRtNet )
    {
        RtRemove( pbind->hRtNet, FLG_RTF_REPORT, RTC_NETUNREACH );
        RtDeRef( pbind->hRtNet );
    }

    // Free Entry
    mmFree( pbind );
}

//--------------------------------------------------------------------
// BindFindByIF( HANDLE hIF )
//
// Find a binding by searching IP Host address
//--------------------------------------------------------------------
HANDLE BindFindByIF( HANDLE hIF )
{
    BIND *pbind;

    pbind = pbindFirst;
    while(pbind)
    {
        if( hIF && pbind->hIF != hIF )
            pbind = pbind->pNext;
        else
            break;
    }
    return( pbind );
}

//--------------------------------------------------------------------
// BindFindByHost( HANDLE hIF, IPN dwIP )
//
// Find a binding by searching IF handle with IP Host addr
//--------------------------------------------------------------------
HANDLE BindFindByHost( HANDLE hIF, IPN dwIP )
{
    BIND *pbind;

    pbind = pbindFirst;
    while( pbind )
    {
        if( dwIP == pbind->dwIPHost && (!hIF || pbind->hIF == hIF) )
            break;
        pbind = pbind->pNext;
    }

    return( pbind );
}

//--------------------------------------------------------------------
// BindFindByNet( HANDLE hIF, IPN dwIP )
//
// Find a binding by searching IF handle with IP Net Addr
//--------------------------------------------------------------------
HANDLE BindFindByNet( HANDLE hIF, IPN dwIP )
{
    BIND *pbind;

    pbind = pbindFirst;
    while( pbind )
    {
        if( ((dwIP&pbind->dwIPMask) == pbind->dwIPNet) &&
            (!hIF || pbind->hIF == hIF) )
            break;
        pbind = pbind->pNext;
    }

    return( pbind );
}

//--------------------------------------------------------------------
// BindIFNet2IPHost( HANDLE hIF, IPN dwIP )
//
// Return an IP host address for this IF
//--------------------------------------------------------------------
IPN BindIFNet2IPHost( HANDLE hIF, IPN dwIP )
{
    BIND *pbind;

    if( !(pbind = (BIND *)BindFindByNet( hIF, dwIP )) )
        return(0);

    return( pbind->dwIPHost );
}

//--------------------------------------------------------------------
// BindIF2IPHost( HANDLE hIF )
//
// Return an IP host address for this IF
//--------------------------------------------------------------------
IPN BindIF2IPHost( HANDLE hIF )
{
    BIND *pbind;

    if( !(pbind = (BIND *)BindFindByIF( hIF )) )
        return(0);

    return( pbind->dwIPHost );
}

//--------------------------------------------------------------------
// BindIPHost2IF( IPN dwIP )
//
// Return an IF for this IP Host
//--------------------------------------------------------------------
HANDLE BindIPHost2IF( IPN dwIP )
{
    BIND *pbind;

    if( !(pbind = (BIND *)BindFindByHost( 0, dwIP )) )
        return(0);

    return( pbind->hIF );
}

//--------------------------------------------------------------------
// BindIPNet2IF( IPN dwIP )
//
// Return an IF for this IP Network
//--------------------------------------------------------------------
HANDLE BindIPNet2IF( IPN dwIP )
{
    BIND *pbind;

    if( !(pbind = (BIND *)BindFindByNet( 0, dwIP )) )
        return(0);

    return( pbind->hIF );
}

//--------------------------------------------------------------------
// BindGetFirst()
//
// Get the first binding
//--------------------------------------------------------------------
HANDLE BindGetFirst()
{
    return( pbindFirst );
}

//--------------------------------------------------------------------
// BindGetNext()
//
// Get the next binding
//--------------------------------------------------------------------
HANDLE BindGetNext( HANDLE hBind )
{
    BIND *pbind = (BIND *)hBind;

#ifdef _STRONG_CHECKING
    if( pbind->Type != HTYPE_BIND )
    {
        DbgPrintf(DBG_ERROR,"BindGetNext: HTYPE %d",pbind->Type);
        return(0);
    }
#endif

    return( pbind->pNext );
}

//--------------------------------------------------------------------
// BindGetIF()
//
// Get the Interface associated with a binding
//--------------------------------------------------------------------
HANDLE BindGetIF( HANDLE hBind )
{
    BIND *pbind = (BIND *)hBind;

#ifdef _STRONG_CHECKING
    if( pbind->Type != HTYPE_BIND )
    {
        DbgPrintf(DBG_ERROR,"BindGetIF: HTYPE %d",pbind->Type);
        return(0);
    }
#endif

    return( pbind->hIF );
}

//--------------------------------------------------------------------
// BindGetIP()
//
// Get the IP information associated with a binding
//--------------------------------------------------------------------
void BindGetIP( HANDLE hBind, IPN *pdwIPHost, IPN *pdwIPNet, IPN *pdwIPMask )
{
    BIND *pbind = (BIND *)hBind;

#ifdef _STRONG_CHECKING
    if( pbind->Type != HTYPE_BIND )
    {
        DbgPrintf(DBG_ERROR,"BindGetIP: HTYPE %d",pbind->Type);
        return;
    }
#endif

    if( pdwIPHost )
        *pdwIPHost = pbind->dwIPHost;
    if( pdwIPNet )
        *pdwIPHost = pbind->dwIPNet;
    if( pdwIPMask )
        *pdwIPHost = pbind->dwIPMask;
}

⌨️ 快捷键说明

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