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 + -
显示快捷键?