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

📄 ipcp.c

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

    case IPCPCODE_CFGACK:
        //---------------------
        // Configure-Ack
        //---------------------

        // If this ID matches ours, we're set
        if( p->ipcp.LastId == pHdr->Id )
        {
            p->ipcp.StateCFG = PROT_CFG_OK;
            goto IPCPStateChange;
        }
        break;

    case IPCPCODE_CFGNAK:
    case IPCPCODE_CFGREJ:
        //---------------------
        // Configure-Nak
        // Configure-Reject
        //---------------------
        // If this ID does not match ours, ignore it
        if( p->ipcp.LastId != pHdr->Id )
            goto IPCPExit;

        // Adjust our options according to Nak or Rej
        pTagData = pHdr->TagData;
        TagLen   = (int)(Len - SIZE_LCPHDR);

        while( TagLen > 0 )
        {
            Tag     = *pTagData++;
            TagSize = *pTagData++;

            // Check for malformed packet
            if( !TagSize )
                goto IPCPExit;

            // Convert extended options (we don't reply using them)
            if( Tag > 128 )
                Tag = HOPT(Tag);

            switch( Tag )
            {
            case IPCPOPT_IPADDR:
                // In client mode we accept a NAK, otherwise, just stop
                if( pHdr->Code == IPCPCODE_CFGNAK && (p->Flags & PPPFLG_CLIENT) )
                    p->IPClient = RdNet32( pTagData );
                else
                    goto StopConnect;
                break;

            case HOPT(IPCPOPT_PRI_DNS):
                // If NAK, record the proper address
                if( pHdr->Code == IPCPCODE_CFGNAK )
                    p->IPDNS1 = RdNet32( pTagData );
                break;

            case HOPT(IPCPOPT_SEC_DNS):
                // If NAK, record the proper address
                if( pHdr->Code == IPCPCODE_CFGNAK )
                    p->IPDNS2 = RdNet32( pTagData );
                break;

            case HOPT(IPCPOPT_PRI_NBNS):
                // If NAK, record the proper address
                if( pHdr->Code == IPCPCODE_CFGNAK )
                    p->IPNBNS1 = RdNet32( pTagData );
                break;

            case HOPT(IPCPOPT_SEC_NBNS):
                // If NAK, record the proper address
                if( pHdr->Code == IPCPCODE_CFGNAK )
                    p->IPNBNS2 = RdNet32( pTagData );
                break;

            default:
                goto ZapOption;
            }

            // If Reject, kill this option
            if( pHdr->Code == IPCPCODE_CFGREJ )
            {
ZapOption:
                p->ipcp.UseMask &= ~(1l<<Tag);
            }

            // Goto next tag
            TagLen -= (int)TagSize;
            pTagData += TagSize - 2;
        }

        // Send a new CFG
        p->ipcp.StateCFG = PROT_CFG_PENDING;
        p->ipcp.Count    = 5;

        ipcpSendCfg( p );
        break;

    case IPCPCODE_TERMREQ:
        //---------------------
        // Term Request
        //---------------------
        // ACK the request

        // Change the code to Ack
        pHdr->Code = IPCPCODE_TERMACK;

        // Send Packet
        FragSetBufParams( hFrag, Len, Offset );
        p->SICtrl(p->hSI, SI_MSG_SENDPACKET, PPPPROT_IPCP, hPkt );
        hPkt = 0;

StopConnect:
        p->ipcp.State = PROT_STATE_STOPPED;
        pppEvent( (HANDLE)p, PPP_EVENT_IPCP_STOPPED );
        goto IPCPExit;

    default:
        break;
    }

    goto IPCPExit;

IPCPStateChange:
    if( p->ipcp.State == PROT_STATE_OPEN )
    {
        // Check to see if we're connected
        if( p->ipcp.StateCFG == PROT_CFG_OK && p->ipcp.StateACK == PROT_CFG_OK )
        {
            p->ipcp.State = PROT_STATE_CONNECTED;
            pppEvent( p, PPP_EVENT_IPCP_CONNECT );
        }
    }

IPCPExit:
    if( hPkt )
        PktFree( hPkt );
}

//--------------------------------------------------------------------
// ipcpTimer()
//
// Called every second for IPCP timeout
//--------------------------------------------------------------------
void ipcpTimer( PPP_SESSION *p )
{
    // What we do depends on our state
    if( p->ipcp.Timer && !--p->ipcp.Timer )
        switch( p->ipcp.State )
        {
        case PROT_STATE_OPEN:
            // See if we need a CFG message retry
            if( p->ipcp.Count )
            {
                p->ipcp.Count--;
                ipcpSendCfg( p );
            }
            else
            {
                p->ipcp.State = PROT_STATE_STOPPED;
                pppEvent( (HANDLE)p, PPP_EVENT_IPCP_STOPPED );
            }
            break;
        }
}

//--------------------------------------------------------------------
// ipcpSendCfg()
//
// Send a IPCP Configuration Request
//--------------------------------------------------------------------
static void ipcpSendCfg( PPP_SESSION *p )
{
    HANDLE     hPkt,hFrag;
    uint       Offset;
    UINT8      *pb;
    LCPHDR     *pHdr;
    UINT16     Len,wTmp;
    UINT8      *pTagData;

    // Create the packet (use size of 100 for now)
    if( !(hPkt = IFCreatePacket( 100, 0, 0 )) )
        return;

    // Get the frag
    hFrag = PktGetFrag( hPkt );

    // Get a pointer to the new header
    pb     = FragGetBufParams( hFrag, 0, 0, 0 );
    Offset = PktGetSizeLLC( hPkt );
    pHdr   = (LCPHDR *)(pb + Offset);

    // Reset the timeout
    p->ipcp.Timer = IPCP_TIMER_CFGRETRY;

    // Bump the Id
    p->ipcp.LastId++;

    // Build the CFG packet
    pHdr->Code = IPCPCODE_CFGREQ;
    pHdr->Id   = p->ipcp.LastId;

    // Add options
    pTagData = pHdr->TagData;
    Len      = SIZE_LCPHDR;

    for( wTmp=1; wTmp<32; wTmp++ )
    {
        if( p->ipcp.UseMask & (1l<<wTmp) )
            switch( wTmp )
            {
            case IPCPOPT_IPADDR:
                *pTagData++ = IPCPOPT_IPADDR;
                *pTagData++ = 6;
                if( p->Flags & PPPFLG_SERVER )
                {
                    WrNet32( pTagData, p->IPServer );
                }
                else
                {
                    WrNet32( pTagData, p->IPClient );
                }
                pTagData += 4;
                Len += 6;
                break;

            case HOPT(IPCPOPT_PRI_DNS):
                *pTagData++ = IPCPOPT_PRI_DNS;
                *pTagData++ = 6;
                WrNet32( pTagData, p->IPDNS1 );
                pTagData += 4;
                Len += 6;
                break;

            case HOPT(IPCPOPT_SEC_DNS):
                *pTagData++ = IPCPOPT_SEC_DNS;
                *pTagData++ = 6;
                WrNet32( pTagData, p->IPDNS2 );
                pTagData += 4;
                Len += 6;
                break;

            case HOPT(IPCPOPT_PRI_NBNS):
                *pTagData++ = IPCPOPT_PRI_NBNS;
                *pTagData++ = 6;
                WrNet32( pTagData, p->IPNBNS1 );
                pTagData += 4;
                Len += 6;
                break;

            case HOPT(IPCPOPT_SEC_NBNS):
                *pTagData++ = IPCPOPT_SEC_NBNS;
                *pTagData++ = 6;
                WrNet32( pTagData, p->IPNBNS2 );
                pTagData += 4;
                Len += 6;
                break;

            default:
                break;
            }
    }
    pHdr->Length = HNC16(Len);

    // Send the packet
    FragSetBufParams( hFrag, Len, Offset );
    p->SICtrl(p->hSI, SI_MSG_SENDPACKET, PPPPROT_IPCP, hPkt );
}

#endif

⌨️ 快捷键说明

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