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

📄 lcp.c

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

            switch( Tag )
            {
            case LCPOPT_MRU:
                if( pHdr->Code == LCPCODE_CFGNAK )
                {
                    // Read the size desired by peer
                    wTmp = RdNet16s( pTagData );
                    p->MTU_Rx = wTmp;
                }
                break;

            case LCPOPT_MAGIC:
                if( pHdr->Code == LCPCODE_CFGNAK )
                    p->lcp.OurMagic = RdNet32( pTagData );
                else
                    p->lcp.OurMagic = 0;
                break;

            case LCPOPT_CMAP:
                // When CMAP is specified, it is required
                goto StopConnect;

            case LCPOPT_AUTH:
                // Can't negotiate authentication in server mode
                if( p->Flags & PPPFLG_SERVER )
                    goto StopConnect;
                // Fallthrough...

            default:
                goto ZapOption;
            }

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

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

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

        lcpSendCfg( p );
        break;

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

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

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

StopConnect:
        p->lcp.State = PROT_STATE_STOPPED;
        // Notify PPP
        pppEvent( (HANDLE)p, PPP_EVENT_LCP_STOPPED );
        break;

    case LCPCODE_ECHOREQ:
        //---------------------
        // Echo Request
        //---------------------

        // Discard request if not connected
        if( p->lcp.State != PROT_STATE_CONNECTED )
            break;

        // Change the code to Ack
        pHdr->Code = LCPCODE_ECHOREPLY;
        WrNet32( pHdr->TagData, p->lcp.OurMagic );

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

    case LCPCODE_ECHOREPLY:
        //---------------------
        // Echo Reply
        //---------------------
        // Keep track that we got the echo reply
        if( p->lcp.State == PROT_STATE_CONNECTED )
            p->lcp.Count = 0;
        break;

    default:
        break;
    }
    goto LCPExit;

LCPStateChange:
    if( p->lcp.State == PROT_STATE_OPEN )
    {
        // Check to see if we should start up a configuration request
        if( p->lcp.StateCFG == PROT_CFG_IDLE &&
                p->lcp.StateACK != PROT_CFG_IDLE )
            lcpOpen( p, 1 );

        // Check to see if we're connected
        if( p->lcp.StateCFG == PROT_CFG_OK && p->lcp.StateACK == PROT_CFG_OK )
        {
            p->lcp.State = PROT_STATE_CONNECTED;
            p->lcp.Timer = LCP_TIMER_ECHOREQUEST;
            p->lcp.Count = 0;
            pppEvent( (HANDLE)p, PPP_EVENT_LCP_CONNECT );
        }
    }

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

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

        case PROT_STATE_CONNECTED:
            // We use count to track events without pings
            p->lcp.Count++;
            if( p->lcp.Count > LCP_TIMER_ECHORETRY )
                goto AbortConnect;

            // Now send a ping ourselves
            lcpSendEcho( p );

            // Reset the timer
            p->lcp.Timer = LCP_TIMER_ECHOREQUEST;
            break;
        }
}

//--------------------------------------------------------------------
// lcpSendCfg()
//
// Send a LCP Configuration Request
//--------------------------------------------------------------------
static void lcpSendCfg( 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->lcp.Timer = LCP_TIMER_CFGRETRY;

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

    // Build the CFG packet
    pHdr->Code = LCPCODE_CFGREQ;
    pHdr->Id   = p->lcp.LastId;

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

    for( wTmp=1; wTmp<32; wTmp++ )
    {
        if( p->lcp.UseMask & (1l<<wTmp) )
            switch( wTmp )
            {
            case LCPOPT_MRU:
                *pTagData++ = LCPOPT_MRU;
                *pTagData++ = 4;
                *pTagData++ = (UINT8)(p->MTU_Rx/256);
                *pTagData++ = (UINT8)(p->MTU_Rx&255);
                Len += 4;
                break;

            case LCPOPT_CMAP:
                *pTagData++ = LCPOPT_CMAP;
                *pTagData++ = 6;
                *pTagData++ = (UINT8)((p->CMap>>24)&255);
                *pTagData++ = (UINT8)((p->CMap>>16)&255);
                *pTagData++ = (UINT8)((p->CMap>>8)&255);
                *pTagData++ = (UINT8)((p->CMap)&255);
                Len += 6;
                break;

            case LCPOPT_AUTH:
                switch( p->auth.Protocol )
                {
                case PPPPROT_PAP:
                    *pTagData++ = LCPOPT_AUTH;
                    *pTagData++ = 4;
                    *pTagData++ = (UINT8)(PPPPROT_PAP/256);
                    *pTagData++ = (UINT8)(PPPPROT_PAP&255);
                    Len += 4;
                    break;
                case PPPPROT_CHAP:
                    *pTagData++ = LCPOPT_AUTH;
                    *pTagData++ = 5;
                    *pTagData++ = (UINT8)(PPPPROT_CHAP/256);
                    *pTagData++ = (UINT8)(PPPPROT_CHAP&255);
                    *pTagData++ = 5;    // MD5
                    Len += 5;
                }
                break;

            case LCPOPT_MAGIC:
                *pTagData++ = LCPOPT_MAGIC;
                *pTagData++ = 6;
                WrNet32( pTagData, p->lcp.OurMagic );
                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_LCP, hPkt );
}

//--------------------------------------------------------------------
// lcpSendTerm()
//
// Send a LCP Termination Request
//--------------------------------------------------------------------
static void lcpSendTerm( PPP_SESSION *p )
{
    HANDLE     hPkt,hFrag;
    uint       Offset;
    UINT8      *pb;
    LCPHDR     *pHdr;

    // 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);

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

    // Build the CFG packet
    pHdr->Code = LCPCODE_TERMREQ;
    pHdr->Id   = p->lcp.LastId;
    pHdr->Length = HNC16(SIZE_LCPHDR);

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

//--------------------------------------------------------------------
// lcpSendEcho()
//
// Send a LCP Echo Request
//--------------------------------------------------------------------
static void lcpSendEcho( PPP_SESSION *p )
{
    HANDLE     hPkt,hFrag;
    uint       Offset;
    UINT8      *pb;
    LCPHDR     *pHdr;

    // 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);

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

    // Build the CFG packet
    pHdr->Code   = LCPCODE_ECHOREQ;
    pHdr->Id     = p->lcp.LastId;
    pHdr->Length = HNC16((SIZE_LCPHDR+4));
    WrNet32( pHdr->TagData, p->lcp.OurMagic );

    // Send the packet
    FragSetBufParams( hFrag, SIZE_LCPHDR+4, Offset );
    p->SICtrl(p->hSI, SI_MSG_SENDPACKET, PPPPROT_LCP, hPkt );
}

#endif



⌨️ 快捷键说明

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