📄 ipcp.c
字号:
//--------------------------------------------------------------------------
// 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 + -