ppp.c

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

C
537
字号
            if( p->hNet || p->hRoute )
            {
                // Setup packet to look like it came from Ethernet
                PktSetIFRx( hPkt, hPPP );
                PktSetEthType( hPkt, 0x800 );

                // We'll let IP take off our 2 byte header
                PktSetSizeLLC( hPkt, 2 );
                PktSetFlagsSet( hPkt, FLG_PKT_LLC_VALID );

                // Give it to IP
                IPRxPacket( hPkt );     // Consume packet
                break;
            }
            PktFree( hPkt );            // Free packet
            break;

        case PPPPROT_LCP:
            lcpInput( p, hPkt );        // Consume packet
            break;

        case PPPPROT_PAP:
            papInput( p, hPkt );        // Consume packet
            break;

        case PPPPROT_CHAP:
            chapInput( p, hPkt );       // Consume packet
            break;

        case PPPPROT_IPCP:
            ipcpInput( p, hPkt );       // Consume packet
            break;

        default:
            PktFree( hPkt );            // Free packet
            break;
        }

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

//--------------------------------------------------------------------
// pppAddIP()
//
// Local function to add IP address via the configuration system
//--------------------------------------------------------------------
static HANDLE pppAddIP( uint Index, uint NetType, IPN IPAddr, IPN IPMask )
{
    CI_IPNET NA;
    int      rc;
    HANDLE   hNet;

    // Initialize Network Address
    mmZeroInit( &NA, sizeof(NA) );
    NA.NetType = NetType;
    NA.IPAddr  = IPAddr;
    NA.IPMask  = IPMask;
    sprintf( NA.Domain, "localppp%d.net", Index );

    //
    // Add the Entry
    //
    // Note we need to keep a copy of the address we add in the event
    // that we need to remove it later. An alternate way of doing this
    // would be to search the configuration for the entry we want to
    // remove once its time, but this way is cleaner.
    //
    llExit();
    rc = CfgAddEntry( 0, CFGTAG_IPNET, Index, CFG_ADDMODE_NOSAVE,
                      sizeof(CI_IPNET), (UINT8 *)&NA, &hNet );
    if( rc < 0 )
    {
        // If this is a service error, the entry was still added
        if( rc <= CFGERROR_SERVICE )
            CfgRemoveEntry( 0, hNet );
        hNet = 0;
    }
    llEnter();

    return(hNet);
}

//--------------------------------------------------------------------
// pppAddClient()
//
// Local function to add a client record to the configuration system
//--------------------------------------------------------------------
static HANDLE pppAddClient( uint Index, IPN IPAddr, INT8 *Name )
{
    CI_CLIENT CC;
    int       rc;
    HANDLE    hClient;

    // Initialize Network Address
    mmZeroInit( &CC, sizeof(CC) );

    CC.ClientType = CFG_CLIENTTYPE_DYNAMIC;
    CC.IPAddr     = IPAddr;
    CC.Status     = CFG_CLIENTSTATUS_STATIC;
    strcpy( CC.Hostname, Name );

    // Add it to the configuration
    llExit();
    rc = CfgAddEntry( 0, CFGTAG_CLIENT, Index, CFG_ADDMODE_NOSAVE,
                      sizeof(CI_CLIENT), (UINT8 *)&CC, &hClient );
    if( rc < 0 )
    {
        // If this is a service error, the entry was still added
        if( rc <= CFGERROR_SERVICE )
            CfgRemoveEntry( 0, hClient );
        hClient = 0;
    }
    llEnter();

    return(hClient);
}

//--------------------------------------------------------------------
// pppEvent()
//
// Event function called by upper level protocols
//--------------------------------------------------------------------
void pppEvent( HANDLE hPPP, uint Event )
{
    PPP_SESSION *p = (PPP_SESSION *)hPPP;

    switch( Event )
    {
    case PPP_EVENT_LCP_CONNECT:
        if( p->auth.Protocol )
        {
            authStart( p );
            p->SICtrl( p->hSI, SI_MSG_CALLSTATUS, SI_CSTATUS_AUTHORIZE, 0);
            break;
        }

        // Fallthrough ...

    case PPP_EVENT_AUTH_CONNECT:
        ipcpStart( p );
        p->SICtrl( p->hSI, SI_MSG_CALLSTATUS, SI_CSTATUS_CONFIGURE, 0);
        break;

    case PPP_EVENT_IPCP_CONNECT:
        // Use the smallest of all the MTU's
        if( p->ProtMTU > p->MTU_Tx )
            p->ProtMTU = p->MTU_Tx;
        if( p->ProtMTU > p->MTU_Rx )
            p->ProtMTU = p->MTU_Rx;

        if( p->Flags & PPPFLG_SERVER )
        {
            // SERVER MODE

            // Create the Local Address
            if( p->Flags & PPPFLG_OPT_LOCALDNS )
            {
                p->hNet = pppAddIP( p->llIndex,
                                    CFG_NETTYPE_DYNAMIC | CFG_NETTYPE_VIRTUAL,
                                    p->IPServer, p->IPMask );
                p->hClient = pppAddClient(p->llIndex, p->IPClient, p->UserId);
            }
            else
                p->hNet = pppAddIP( p->llIndex, CFG_NETTYPE_DYNAMIC,
                                    p->IPServer, p->IPMask );

            // Create a route to the client. Also proxy it just in case its
            // on the same subnet as our Ethernet devices.
            p->hRoute = RtCreate( FLG_RTF_REPORT, FLG_RTE_PROXY,
                                  p->IPClient, 0xffffffffl, (HANDLE)p, 0, 0 );
        }
        else
        {
            // CLIENT MODE

            // Create the Local Address
            p->hNet = pppAddIP( p->llIndex, CFG_NETTYPE_DYNAMIC,
                                p->IPClient, 0xffffffffl );

            // Create a default route that sends everything up this uplink
            p->hRoute = RtCreate( FLG_RTF_REPORT, 0, 0, 0, (HANDLE)p, 0, 0 );

            // If using MS extensions, record the new values
            if( p->Flags & PPPFLG_OPT_USE_MSE )
            {
                llExit();
                if( p->IPDNS1 )
                    CfgAddEntry( 0, CFGTAG_SYSINFO,
                                 CFGITEM_DHCP_DOMAINNAMESERVER,
                                 CFG_ADDMODE_NOSAVE, 4,
                                 (UINT8 *)&p->IPDNS1, 0 );

                if( p->IPDNS2 )
                    CfgAddEntry( 0, CFGTAG_SYSINFO,
                                 CFGITEM_DHCP_DOMAINNAMESERVER,
                                 CFG_ADDMODE_NOSAVE, 4,
                                 (UINT8 *)&p->IPDNS2, 0 );

                if( p->IPNBNS1 )
                    CfgAddEntry( 0, CFGTAG_SYSINFO, CFGITEM_DHCP_NBNS,
                                 CFG_ADDMODE_NOSAVE, 4,
                                 (UINT8 *)&p->IPNBNS1, 0 );

                if( p->IPNBNS2 )
                    CfgAddEntry( 0, CFGTAG_SYSINFO, CFGITEM_DHCP_NBNS,
                                 CFG_ADDMODE_NOSAVE, 4,
                                 (UINT8 *)&p->IPNBNS2, 0 );
                llEnter();
            }
        }
        p->SICtrl( p->hSI, SI_MSG_CALLSTATUS, SI_CSTATUS_CONNECTED, 0);
        break;

    case PPP_EVENT_LCP_STOPPED:
        p->SICtrl( p->hSI, SI_MSG_CALLSTATUS, SI_CSTATUS_DISCONNECT_LCP, 0);
        break;

    case PPP_EVENT_AUTH_STOPPED:
        p->SICtrl( p->hSI, SI_MSG_CALLSTATUS, SI_CSTATUS_DISCONNECT_AUTH, 0);
        break;

    case PPP_EVENT_IPCP_STOPPED:
        p->SICtrl( p->hSI, SI_MSG_CALLSTATUS, SI_CSTATUS_DISCONNECT_IPCP, 0);
        break;
    }
}

//--------------------------------------------------------------------
// pppTxIpPacket()
//
// Called by Ip to transmit a packet on a connected PPP device
//--------------------------------------------------------------------
void pppTxIpPacket( HANDLE hPkt )
{
    PPP_SESSION *p;

    // At this point, we must have an egress interface
    if( !(p = (PPP_SESSION *)PktGetIFTx( hPkt )) )
    {
        DbgPrintf(DBG_ERROR,"pppTxIpPacket: No IF");
        PktFree( hPkt );
        return;
    }

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

    // If the session is open send the packet
    if( p->hNet || p->hRoute )
        p->SICtrl( p->hSI, SI_MSG_SENDPACKET, PPPPROT_IP, hPkt);
    else
        PktFree( hPkt );
}

#endif

⌨️ 快捷键说明

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