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

📄 ipcp.c

📁 代码在ti的c67系列单片机上实现了完整的TCPIP协议栈
💻 C
📖 第 1 页 / 共 2 页
字号:
//--------------------------------------------------------------------------
// Ip Stack
//--------------------------------------------------------------------------
// IPCP.C
//
// Member functions for PPP/IPCP
//
// Author: Michael A. Denio
// Copyright 2000 by Texas Instruments Inc.
//-------------------------------------------------------------------------
#include <stkmain.h>
#include "ppp.h"

#ifdef _INCLUDE_PPP_CODE

#define IPCP_TIMER_CFGRETRY      3

// IPCP Codes
#define IPCPCODE_CFGREQ          1
#define IPCPCODE_CFGACK          2
#define IPCPCODE_CFGNAK          3
#define IPCPCODE_CFGREJ          4
#define IPCPCODE_TERMREQ         5
#define IPCPCODE_TERMACK         6
#define IPCPCODE_CODEREJ         7

#define IPCPOPT_IPADDRS          1
#define IPCPOPT_COMPPROTO        2
#define IPCPOPT_IPADDR           3
#define IPCPOPT_PRI_DNS          129
#define IPCPOPT_PRI_NBNS         130
#define IPCPOPT_SEC_DNS          131
#define IPCPOPT_SEC_NBNS         132

#define HOPT(x) (x-129+16)
#define EXTENDED_OPT_MASK        0xF0000

static void ipcpSendCfg( PPP_SESSION *p );

//--------------------------------------------------------------------
// ipcpInit()
//
// Initialize IPCP and set it to CLOSED state
//--------------------------------------------------------------------
void ipcpInit( PPP_SESSION *p )
{
    p->ipcp.State     = PROT_STATE_CLOSED;
    p->ipcp.StateCFG  = PROT_CFG_IDLE;
    p->ipcp.StateACK  = PROT_CFG_IDLE;

    // The following can be used before we start

    // Set the options we allow
    p->ipcp.OptMask = (1l<<IPCPOPT_IPADDR);

    // If using extensions, add to options
    if( p->Flags & PPPFLG_OPT_USE_MSE && p->Flags & PPPFLG_SERVER )
        p->ipcp.OptMask |= EXTENDED_OPT_MASK;
}

//--------------------------------------------------------------------
// ipcpStart()
//
// Start IPCP session
//--------------------------------------------------------------------
void ipcpStart( PPP_SESSION *p )
{
    // Set our new state
    p->ipcp.State = PROT_STATE_OPEN;

    // Set our new state
    p->ipcp.StateCFG  = PROT_CFG_PENDING;
    p->ipcp.Count     = 5;               // Retry Count

    // Set some defaults
    p->ipcp.LastId    = 0;               // Default Id
    p->ipcp.UseMask = (1l<<IPCPOPT_IPADDR);

    // If using extensions, add to server or client flags
    if( p->Flags & PPPFLG_OPT_USE_MSE && p->Flags & PPPFLG_CLIENT )
        p->ipcp.UseMask |= EXTENDED_OPT_MASK;

    ipcpSendCfg( p );
}

//--------------------------------------------------------------------
// ipcpInput()
//
// Receive an IPCP packet
//--------------------------------------------------------------------
void ipcpInput( PPP_SESSION *p, HANDLE hPkt )
{
    LCPHDR      *pHdr;
    HANDLE      hFrag;
    UINT8       *pb;
    uint        Size,Offset;
    int         TagLen;
    UINT16      Len;
    UINT8       Tag,TagSize,*pTagData;
    UINT8       RetCode;
    int         BadTagLen;
    UINT8       *pBadTagData;
    IPN         IPTmp;

    // If we're closed, goto IPCPExit now
    if( p->ipcp.State == PROT_STATE_CLOSED )
        goto IPCPExit;

    // We know we have a Frag...
    hFrag = PktGetFrag( hPkt );

    // Get the buffer parameters
    pb = FragGetBufParams( hFrag, 0, &Size, &Offset );
    pb += Offset;

    // Get the LCPHDR
    pHdr = (LCPHDR *)pb;

    // Get packet length
    Len  = HNC16( pHdr->Length );

    // Verify that we have the entire packet
    if( Len > (UINT16)Size )
        goto IPCPExit;

    switch( pHdr->Code )
    {
    case IPCPCODE_CFGREQ:
        //---------------------
        // Configure-Request
        //---------------------

        // Scan the options
        pTagData    = pHdr->TagData;
        TagLen      = (int)(Len - SIZE_LCPHDR);
        RetCode     = IPCPCODE_CFGACK;

        // Setup these pointers for use by NAK
        BadTagLen   = 0;
        pBadTagData = pHdr->TagData;

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

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

            // First try reject
            if( (Tag<129 &&
                   (Tag>16 || !(p->ipcp.OptMask & (1l<<Tag))) ) ||
                (Tag>128 &&
                   (Tag>(128+16) || !(p->ipcp.OptMask & (1l<<HOPT(Tag)))) ) )
            {
                // Reject this option
                if( RetCode != IPCPCODE_CFGREJ )
                {
                    // We now use the pointer for REJ, so reset them
                    RetCode     = IPCPCODE_CFGREJ;
                    BadTagLen   = 0;
                    pBadTagData = pHdr->TagData;
                }

                *pBadTagData++ = Tag;
                *pBadTagData++ = TagSize;
                if( TagSize > 2 )
                    mmCopy( pBadTagData, pTagData, TagSize );
                BadTagLen   += TagSize;
                pBadTagData += TagSize - 2;
            }

            // If not in reject state, process option
            if( RetCode != IPCPCODE_CFGREJ )
            {
                if( p->Flags & PPPFLG_SERVER )
                {
                    // Process as SERVER
                    switch( Tag )
                    {
                    case IPCPOPT_IPADDR:
                        IPTmp = RdNet32( pTagData );
                        // As server we insist on our own address
                        if( IPTmp != p->IPClient )
                        {
                            IPTmp = p->IPClient;
NAKIPADDR:
                            // We must NAK this value
                            RetCode = IPCPCODE_CFGNAK;

                            *pBadTagData++ = Tag;
                            *pBadTagData++ = TagSize;
                            WrNet32( pBadTagData, IPTmp );
                            BadTagLen += TagSize;
                            pBadTagData += TagSize - 2;
                        }
                        break;

                    case IPCPOPT_PRI_DNS:
                        IPTmp = RdNet32( pTagData );
                        if( IPTmp != p->IPDNS1 )
                        {
                            IPTmp = p->IPDNS1;
                            goto NAKIPADDR;
                        }
                        break;

                    case IPCPOPT_PRI_NBNS:
                        IPTmp = RdNet32( pTagData );
                        if( IPTmp != p->IPNBNS1 )
                        {
                            IPTmp = p->IPNBNS1;
                            goto NAKIPADDR;
                        }
                        break;

                    case IPCPOPT_SEC_DNS:
                        IPTmp = RdNet32( pTagData );
                        if( IPTmp != p->IPDNS2 )
                        {
                            IPTmp = p->IPDNS2;
                            goto NAKIPADDR;
                        }
                        break;

                    case IPCPOPT_SEC_NBNS:
                        IPTmp = RdNet32( pTagData );
                        if( IPTmp != p->IPNBNS2 )
                        {
                            IPTmp = p->IPNBNS2;
                            goto NAKIPADDR;
                        }
                        break;
                    }
                }
                else
                {
                    // Process as CLIENT
                    switch( Tag )
                    {
                    case IPCPOPT_IPADDR:
                        IPTmp = RdNet32( pTagData );
                        p->IPServer = IPTmp;
                        break;
                    }
                }
            }

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

        // Reply to this request
        pHdr->Code = RetCode;
        if( RetCode == IPCPCODE_CFGACK )
        {
            FragSetBufParams( hFrag, Len, Offset );
            // Set new state
            p->ipcp.StateACK = PROT_CFG_OK;
        }
        else
        {
            // Change length to reflect bad options
            BadTagLen += SIZE_LCPHDR;
            pHdr->Length = HNC16(BadTagLen);
            FragSetBufParams( hFrag, BadTagLen, Offset );
            // Set new state
            p->ipcp.StateACK = PROT_CFG_PENDING;
        }

        // Send Packet
        p->SICtrl(p->hSI, SI_MSG_SENDPACKET, PPPPROT_IPCP, hPkt );

⌨️ 快捷键说明

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