ppp.c

来自「代码在ti的c67系列单片机上实现了完整的TCPIP协议栈」· C语言 代码 · 共 537 行 · 第 1/2 页

C
537
字号
//--------------------------------------------------------------------------
// Ip Stack
//--------------------------------------------------------------------------
// PPP.C
//
// Member functions for PPP
//
// Author: Michael A. Denio
// Copyright 2000 by Texas Instruments Inc.
//-------------------------------------------------------------------------
#include <stkmain.h>
#include <netmain.h>
#include "ppp.h"

#ifdef _INCLUDE_PPP_CODE

//--------------------------------------------------------------------
// pppNew()
//
// Create new PPP device instance
//--------------------------------------------------------------------
HANDLE pppNew( HANDLE hSI, uint pppFlags, uint mru,
               IPN IPServer, IPN IPMask, IPN IPClient,
               char *Username, char *Password, UINT32 cmap,
               void (*SICtrl)( HANDLE, uint, UINT32, HANDLE ) )
{
    PPP_SESSION *p;

    // Allocate space for server
    if( !(p = mmAlloc( sizeof(PPP_SESSION) )) )
    {
        DbgPrintf(DBG_WARN,"pppNew: OOM");
        ExecLowResource();
        return(0);
    }

    // Unitialized parameters must be null
    mmZeroInit( p, sizeof(PPP_SESSION) );

    // Initialize type
    p->Type  = HTYPE_PPP;
    p->InUse = INUSE_IDLE;

    // Init Session Structure
    // p->hRoute, p->hNet, p->hClient, and IP addrs are all NULL
    p->hSI      = hSI;
    p->llIndex  = IFIndexNew( (HANDLE)p, 0 );
    p->ProtMTU  = mru;
    p->SICtrl   = SICtrl;
    p->Flags    = pppFlags;
    p->MTU_Phys = mru;
    p->CMap     = cmap;
    p->MTU_Tx   = p->MTU_Phys;
    p->MTU_Rx   = p->MTU_Phys;

    // Remaining options are server/client dependent
    if( p->Flags & PPPFLG_SERVER )
    {
        // Set the local and peer IP addr
        p->IPClient = IPClient;
        p->IPServer = IPServer;
        p->IPMask   = IPMask;

        // If using MS extensions, get the current DNS and NBNS IP addrs
        if( p->Flags & PPPFLG_OPT_USE_MSE )
        {
            if( p->Flags & PPPFLG_OPT_LOCALDNS )
            {
                // Read the default DNS and NBNS
                p->IPDNS1   = IPServer;
                p->IPDNS2   = 0x0;
            }
            else
            {
                // Here we go external to get the DNS servers
                llExit();
                CfgGetImmediate( 0, CFGTAG_SYSINFO,
                                 CFGITEM_DHCP_DOMAINNAMESERVER, 1,
                                 sizeof(p->IPNBNS1), (UINT8 *)&p->IPDNS1);
                CfgGetImmediate( 0, CFGTAG_SYSINFO,
                                 CFGITEM_DHCP_DOMAINNAMESERVER, 2,
                                 sizeof(p->IPNBNS2), (UINT8 *)&p->IPDNS2);
                llEnter();
            }

            // We always go external to get the NBNS servers
            llExit();
            CfgGetImmediate( 0, CFGTAG_SYSINFO, CFGITEM_DHCP_NBNS, 1,
                             sizeof(p->IPNBNS1), (UINT8 *)&p->IPNBNS1);
            CfgGetImmediate( 0, CFGTAG_SYSINFO, CFGITEM_DHCP_NBNS, 2,
                             sizeof(p->IPNBNS2), (UINT8 *)&p->IPNBNS2);
            llEnter();
        }
    }
    else
    {
        if( Username && strlen(Username) < sizeof(p->UserId) )
            strcpy( p->UserId, Username );
        if( Password && strlen(Password) < sizeof(p->Password) )
            strcpy( p->Password, Password );
    }

    // Init PPP Protocols
    lcpInit( (HANDLE)p );
    authInit( (HANDLE)p );
    ipcpInit( (HANDLE)p );

    // Open LCP
    if( p->Flags & PPPFLG_SERVER )
    {
        lcpOpen( (HANDLE)p, 0 );
        p->SICtrl( p->hSI, SI_MSG_CALLSTATUS, SI_CSTATUS_WAITING, 0);
    }
    else
        lcpOpen( (HANDLE)p, 1 );

    return( (HANDLE)p );
}

//--------------------------------------------------------------------
// pppFree()
//
// Free PPP device instance
//--------------------------------------------------------------------
void pppFree( HANDLE hPPP )
{
    PPP_SESSION *p = (PPP_SESSION *)hPPP;

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

    // Free handle if ref count is INUSE_IDLE and not LOCKED
    if( p->InUse != INUSE_LOCKED )
    {
        if( p->InUse > INUSE_IDLE )
            p->InUse--;                 // Deref one count
        else
        {
            // Close protocols (closing LCP is sufficient)
            lcpClose( p );

            // Clear the handle type and lock ref count
            p->Type  = 0;
            p->InUse = INUSE_LOCKED;

            // Remove the route if we have one
            if( p->hRoute )
            {
                RtRemove( p->hRoute, FLG_RTF_REPORT, RTC_NETUNREACH );
                RtDeRef( p->hRoute );
                p->hRoute = 0;
            }

            // Remove client record if any
            if( p->hClient )
            {
                llExit();
                CfgRemoveEntry( 0, p->hClient );
                llEnter();
                p->hClient = 0;
            }

            // Remove binding if we have one
            if( p->hNet )
            {
                llExit();
                CfgRemoveEntry( 0, p->hNet );
                llEnter();
                p->hNet = 0;
            }

            IFIndexFree( p->llIndex );
            mmFree( p );
        }
    }
}

//--------------------------------------------------------------------
// pppTimer()
//
// Timer function called once per second
//--------------------------------------------------------------------
void pppTimer( HANDLE hPPP )
{
    PPP_SESSION *p = (PPP_SESSION *)hPPP;

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

    // Add reference and execute
    if( p->InUse < (INUSE_LOCKED-1) )
    {
        p->InUse++;

        lcpTimer( p );
        authTimer( p );
        ipcpTimer( p );

        // Remove reference
        if( p->InUse == INUSE_IDLE )
            pppFree( p );
        else
            p->InUse--;
    }
}

//--------------------------------------------------------------------
// pppInput()
//
// Called when a packet is received by the serial interface
//--------------------------------------------------------------------
void pppInput( HANDLE hPPP, HANDLE hPkt )
{
    PPP_SESSION *p = (PPP_SESSION *)hPPP;
    HANDLE      hFrag;
    UINT8       *pb;
    uint        Size;
    uint        Offset;
    UINT16      type;

#ifdef _STRONG_CHECKING
    if( p->Type != HTYPE_PPP )
    {
        DbgPrintf(DBG_ERROR,"pppInput: HTYPE %04x",p->Type);
        PktFree( hPkt );
        return;
    }
#endif

    if( !(hFrag = PktGetFrag( hPkt ))  )
    {
        DbgPrintf(DBG_ERROR,"pppInput: No Frag on packet!");
        PktFree( hPkt );
        return;
    }

    // Add reference and execute
    if( p->InUse < (INUSE_LOCKED-1) )
    {
        p->InUse++;

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

        type = RdNet16s(pb);

        if( type & 0x8000 )
        {
            FragSetBufParams( hFrag, Size, Offset );
            PktSetFlagsClear( hPkt, FLG_PKT_LLC_VALID );
        }

        switch( type )
        {
        case PPPPROT_IP:
            // Only pass IP if hNet or hRoute is set

⌨️ 快捷键说明

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