📄 ipcp.c
字号:
hPkt = 0;
goto IPCPStateChange;
case IPCPCODE_CFGACK:
//---------------------
// Configure-Ack
//---------------------
// If this ID matches ours, we're set
if( p->ipcp.LastId == pHdr->Id )
{
p->ipcp.StateCFG = PROT_CFG_OK;
goto IPCPStateChange;
}
break;
case IPCPCODE_CFGNAK:
case IPCPCODE_CFGREJ:
//---------------------
// Configure-Nak
// Configure-Reject
//---------------------
// If this ID does not match ours, ignore it
if( p->ipcp.LastId != pHdr->Id )
goto IPCPExit;
// 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 IPCPExit;
// Convert extended options (we don't reply using them)
if( Tag > 128 )
Tag = HOPT(Tag);
switch( Tag )
{
case IPCPOPT_IPADDR:
// In client mode we accept a NAK, otherwise, just stop
if( pHdr->Code == IPCPCODE_CFGNAK && (p->Flags & PPPFLG_CLIENT) )
p->IPClient = RdNet32( pTagData );
else
goto StopConnect;
break;
case HOPT(IPCPOPT_PRI_DNS):
// If NAK, record the proper address
if( pHdr->Code == IPCPCODE_CFGNAK )
p->IPDNS1 = RdNet32( pTagData );
break;
case HOPT(IPCPOPT_SEC_DNS):
// If NAK, record the proper address
if( pHdr->Code == IPCPCODE_CFGNAK )
p->IPDNS2 = RdNet32( pTagData );
break;
case HOPT(IPCPOPT_PRI_NBNS):
// If NAK, record the proper address
if( pHdr->Code == IPCPCODE_CFGNAK )
p->IPNBNS1 = RdNet32( pTagData );
break;
case HOPT(IPCPOPT_SEC_NBNS):
// If NAK, record the proper address
if( pHdr->Code == IPCPCODE_CFGNAK )
p->IPNBNS2 = RdNet32( pTagData );
break;
default:
goto ZapOption;
}
// If Reject, kill this option
if( pHdr->Code == IPCPCODE_CFGREJ )
{
ZapOption:
p->ipcp.UseMask &= ~(1l<<Tag);
}
// Goto next tag
TagLen -= (int)TagSize;
pTagData += TagSize - 2;
}
// Send a new CFG
p->ipcp.StateCFG = PROT_CFG_PENDING;
p->ipcp.Count = 5;
ipcpSendCfg( p );
break;
case IPCPCODE_TERMREQ:
//---------------------
// Term Request
//---------------------
// ACK the request
// Change the code to Ack
pHdr->Code = IPCPCODE_TERMACK;
// Send Packet
FragSetBufParams( hFrag, Len, Offset );
p->SICtrl(p->hSI, SI_MSG_SENDPACKET, PPPPROT_IPCP, hPkt );
hPkt = 0;
StopConnect:
p->ipcp.State = PROT_STATE_STOPPED;
pppEvent( (HANDLE)p, PPP_EVENT_IPCP_STOPPED );
goto IPCPExit;
default:
break;
}
goto IPCPExit;
IPCPStateChange:
if( p->ipcp.State == PROT_STATE_OPEN )
{
// Check to see if we're connected
if( p->ipcp.StateCFG == PROT_CFG_OK && p->ipcp.StateACK == PROT_CFG_OK )
{
p->ipcp.State = PROT_STATE_CONNECTED;
pppEvent( p, PPP_EVENT_IPCP_CONNECT );
}
}
IPCPExit:
if( hPkt )
PktFree( hPkt );
}
//--------------------------------------------------------------------
// ipcpTimer()
//
// Called every second for IPCP timeout
//--------------------------------------------------------------------
void ipcpTimer( PPP_SESSION *p )
{
// What we do depends on our state
if( p->ipcp.Timer && !--p->ipcp.Timer )
switch( p->ipcp.State )
{
case PROT_STATE_OPEN:
// See if we need a CFG message retry
if( p->ipcp.Count )
{
p->ipcp.Count--;
ipcpSendCfg( p );
}
else
{
p->ipcp.State = PROT_STATE_STOPPED;
pppEvent( (HANDLE)p, PPP_EVENT_IPCP_STOPPED );
}
break;
}
}
//--------------------------------------------------------------------
// ipcpSendCfg()
//
// Send a IPCP Configuration Request
//--------------------------------------------------------------------
static void ipcpSendCfg( 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->ipcp.Timer = IPCP_TIMER_CFGRETRY;
// Bump the Id
p->ipcp.LastId++;
// Build the CFG packet
pHdr->Code = IPCPCODE_CFGREQ;
pHdr->Id = p->ipcp.LastId;
// Add options
pTagData = pHdr->TagData;
Len = SIZE_LCPHDR;
for( wTmp=1; wTmp<32; wTmp++ )
{
if( p->ipcp.UseMask & (1l<<wTmp) )
switch( wTmp )
{
case IPCPOPT_IPADDR:
*pTagData++ = IPCPOPT_IPADDR;
*pTagData++ = 6;
if( p->Flags & PPPFLG_SERVER )
{
WrNet32( pTagData, p->IPServer );
}
else
{
WrNet32( pTagData, p->IPClient );
}
pTagData += 4;
Len += 6;
break;
case HOPT(IPCPOPT_PRI_DNS):
*pTagData++ = IPCPOPT_PRI_DNS;
*pTagData++ = 6;
WrNet32( pTagData, p->IPDNS1 );
pTagData += 4;
Len += 6;
break;
case HOPT(IPCPOPT_SEC_DNS):
*pTagData++ = IPCPOPT_SEC_DNS;
*pTagData++ = 6;
WrNet32( pTagData, p->IPDNS2 );
pTagData += 4;
Len += 6;
break;
case HOPT(IPCPOPT_PRI_NBNS):
*pTagData++ = IPCPOPT_PRI_NBNS;
*pTagData++ = 6;
WrNet32( pTagData, p->IPNBNS1 );
pTagData += 4;
Len += 6;
break;
case HOPT(IPCPOPT_SEC_NBNS):
*pTagData++ = IPCPOPT_SEC_NBNS;
*pTagData++ = 6;
WrNet32( pTagData, p->IPNBNS2 );
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_IPCP, hPkt );
}
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -