📄 msg.c
字号:
//
pContext->bRxOutOfSync = TRUE;
return;
}
//
// The decompressed data pointer points into the history buffer.
// If NAT is active, the receive packet data that
// we indicate up may be modified. Since the receive
// packet data is in the CCP history buffer, this
// will corrupt the history. So, we must copy the
// packet to a new buffer prior to indicating it.
//
if (cbDecompressed > pContext->cbScratchRxBuf)
{
// We were sent a packet which is too big. Discard.
DEBUGMSG( ZONE_ERROR, (TEXT( "PPP: CCP-ERROR decompressed packet is %d bytes > Max allowable %d\n" ),
cbDecompressed, pContext->cbScratchRxBuf));
return;
}
memcpy(pContext->ScratchRxBuf, pDecompressed, cbDecompressed);
pMsg->data = pContext->ScratchRxBuf;
pMsg->len = cbDecompressed;
DEBUGMSG( ZONE_CCP, (TEXT( "PPP: CCP RX decompress OK\n" )));
#ifdef DEBUG
if (ZONE_TRACE)
{
DEBUGMSG (1, (TEXT("PPP: CCP: RX Decompressed packet (%d):\n"), pMsg->len));
DumpMem (pMsg->data, pMsg->len);
}
#endif
}
else
{
DEBUGMSG( ZONE_CCP, ( TEXT( "CCP: RX Packet NOT COMPRESSED\n" )));
}
// Pass the payload of the CCP packet back through the receive packet engine
PPPRxPacketHandler(pContext->session, pMsg);
}
void
CcpProcessRxPacket(
IN PVOID context,
IN pppMsg_t *pMsg)
//
// Process a CCP packet received from the peer.
//
{
PCCPContext pContext = (PCCPContext )context;
ASSERT (PPP_PROTOCOL_CCP == pMsg->ProtocolType );
// If the layer below CCP (usually auth) has not indicated that it is up yet,
// then receiving a CCP packet means that we probably lost an
// authentication success packet from the peer. So, for some
// authentication protocols the reception of a network layer
// packet (e.g. CCP, IPCP) is implicit authentication success.
//
if (pContext->pFsm->state <= PFS_Starting)
{
AuthRxImpliedSuccessPacket(pContext->session->authCntxt);
}
// If we did not open the FSM earlier, because we did
// not want compression/encryption, open the FSM now
// that the peer has indicated that it wants
// compression/encryption.
if (pContext->pFsm->state == PFS_Closed)
{
DEBUGMSG(ZONE_CCP, (TEXT("PPP: Doing deferred CCP FSM Open as peer has requested CCP options\n")));
PppFsmOpen(pContext->pFsm);
}
PppFsmProcessRxPacket(pContext->pFsm, pMsg->data, pMsg->len);
}
/*****************************************************************************
*
* @func void | pppCcp_Compress | CCP Datagram compression
*
* @parm pppSession_t * | session | PPP session context.
* @parm PNDIS_WAN_PACKET * | ppPacket | Pointer to a ptr to NDIS_WAN_PACKET
*
* @comm This function will compress a packet if tx compression is active,
* and encrypt it if tx encryption is active.
*
*/
BOOL
pppCcp_Compress(
IN pppSession_t *pSession,
IN OUT PNDIS_WAN_PACKET *ppPacket,
IN OUT USHORT *pwProtocol )
//
// Compress and/or encrypt the input packet.
//
// Return FALSE if the packet should be discarded because CCP is not open
// and encryption is required.
// Otherwise, return TRUE (regardless of whether the packet was compressed
// and/or encrypted) indicating that the packet should be sent.
//
{
ncpCntxt_t *ncp_p = (ncpCntxt_t *)pSession->ncpCntxt;
PCCPContext pContext = (PCCPContext)ncp_p->protocol[ NCP_CCP ].context;
RASPENTRY *pRasEntry = &pSession->rasEntry;
PNDIS_WAN_PACKET pCompressedPacket;
PNDIS_WAN_PACKET pPacket;
USHORT coherencyHeader;
DEBUGMSG(ZONE_FUNCTION, (TEXT( "PPP: +pppCcp_Compress( 0x%X, 0x%X, 0x%X)\r\n" ), pSession, ppPacket, pwProtocol ));
if (pContext->pFsm->state != PFS_Opened)
{
// CCP is not open, cannot compress or encrypt packet
if (NEED_ENCRYPTION(pRasEntry))
{
// Encryption of packets is mandatory, so we just discard it
return FALSE;
}
else
{
// Just send the packet unencrypted, uncompressed
return TRUE;
}
}
else if (pContext->peer.SupportedBits == 0)
{
// TX Compression and Encryption both were disabled in negotiation
DEBUGMSG(ZONE_NCP, (TEXT("ccp:TX COMPRESSION/ENCRYPTION OFF\n")));
// If we need encryption, we should not have allowed negotiations to
// complete successfully without enabling it.
ASSERT(!NEED_ENCRYPTION(pRasEntry));
// Just send the packet unencrypted, uncompressed
return TRUE;
}
// CCP is open, and we negotiated the use of compression and/or encryption
pPacket = *ppPacket;
// Encode the protocol type into the packet data.
// It needs to be there because it is subject to compression and encryption.
// NOTE: currently ignoring whether protocol field compression is enabled or not.
//
pPacket->CurrentBuffer -= 2;
pPacket->CurrentLength += 2;
pPacket->CurrentBuffer[0] = (UCHAR )( *pwProtocol >> 8 );
pPacket->CurrentBuffer[1] = (UCHAR )( *pwProtocol );
// The new compressed/encrypted packet type is 0x00FD, which will be encoded into
// the packet outside of this function, in front of the coherency header.
*pwProtocol = PPP_PROTOCOL_COMPRESSION;
DEBUGMSG( ZONE_NCP, (TEXT( "ccp:tx:raw pkt length: %d\n" ), pPacket->CurrentLength ));
// Setup the compression/encryption packet header, the "ABCD" bits and the coherency count.
coherencyHeader = pContext->txCoherency;
ASSERT((coherencyHeader & 0xF000) == 0);
DEBUGMSG( ZONE_NCP, (TEXT("ccp:tx:coherency cnt: %x\n"), coherencyHeader));
// Bump coherency counter with 12 bit limit
pContext->txCoherency = (pContext->txCoherency + 1) & 0x0fff;
//
// If compression is enabled, then try to compress the packet data
//
if( pContext->peer.SupportedBits & MCCP_COMPRESSION)
{
// Get a new WAN packet into which to try to compress the packet data.
pCompressedPacket = pppMac_GetPacket (pSession->macCntxt);
// If we are unable to get a packet we will just send it uncompressed.
if (!pCompressedPacket)
{
if( pContext->peer.SupportedBits & (MSTYPE_ENCRYPTION_40F | MSTYPE_ENCRYPTION_128)) {
coherencyHeader |= PACKET_FLUSHED << 8;
initsendcontext(&pContext->mppcSndCntxt);
// force a start over next time
pContext->mppcSndCntxt.CurrentIndex = HISTORY_SIZE+1 ;
// Set txFlush to force encryption to reinitialize its table.
pContext->txFlush = TRUE;
}
}
else
{
pCompressedPacket->ProtocolReserved2 = pPacket->ProtocolReserved2;
// Reserve the following (worst case) header bytes:
// 2 - possible address and control bytes (FF 03)
// 2 - CCP protocol type (00 FD) (sometimes gets compressed to 1)
// 2 - CCP coherency header
//
// Do not need to reserve 2 bytes for the encapsulated protocol type,
// since it is part of the compressed payload, not header.
//
pCompressedPacket->CurrentBuffer += 6;
pCompressedPacket->CurrentLength -= 6;
#ifdef DEBUG
if (ZONE_TRACE) {
DEBUGMSG (1, (TEXT("pppCcp_Compress: About to compress packet (%d):\n"),
pPacket->CurrentLength));
DumpMem (pPacket->CurrentBuffer, pPacket->CurrentLength);
}
#endif
// Compress the packet data in pPacket into pCompressedPacket
// Set the "FLUSHED" and "COMPRESSED" bits in the coherency header.
pCompressedPacket->CurrentLength = pPacket->CurrentLength;
coherencyHeader |= compress( pPacket->CurrentBuffer,
pCompressedPacket->CurrentBuffer,
&pCompressedPacket->CurrentLength,
&pContext->mppcSndCntxt );
DEBUGMSG( ZONE_NCP, ( TEXT( "ccp:tx:compress %hs- Len: orig=%d comp=%d\n" ),
(coherencyHeader & (PACKET_FLUSHED << 8)) ? "FAILED" : "OK",
pPacket->CurrentLength, pCompressedPacket->CurrentLength));
// If compression failed, free pCompressedPacket.
// Otherwise, switch to use pCompressedPacket instead of the original, uncompressed packet.
//
// Note: If compression fails the PACKET_FLUSHED bit is set in the coherency
// header such that our peer resets its history.
if( coherencyHeader & (PACKET_FLUSHED << 8))
{
// Compression Failed - Send pOrigPacket
// Free the temporary packet we allocated.
NdisWanFreePacket (pSession->macCntxt, pCompressedPacket);
// Set txFlush to force encryption to reinitialize its table.
ASSERT(0 == (coherencyHeader & (PACKET_COMPRESSED << 8)));
pContext->txFlush = TRUE;
}
else
{
// Packet compressed - discard original packet and use the new compressed packet
NdisWanFreePacket (pSession->macCntxt, pPacket);
*ppPacket = pPacket = pCompressedPacket;
}
}
}
//
// Encrypt the data if encryption is enabled
//
if( pContext->peer.SupportedBits & (MSTYPE_ENCRYPTION_40F | MSTYPE_ENCRYPTION_128))
{
#ifdef DEBUG
if (ZONE_TRACE) {
DEBUGMSG (1, (TEXT("pppCcp_Compress: About to encrypt packet (%d):\n"),
pPacket->CurrentLength));
DumpMem (pPacket->CurrentBuffer, pPacket->CurrentLength);
}
#endif
coherencyHeader |= EncryptTxData(pContext, pPacket->CurrentBuffer, pPacket->CurrentLength);
}
// If the txFlush flag is set then we received a RESET REQUEST
// packet from our peer and the tx context was reset and the out
// going packet was created without any history. Therefore, add in
// the PACKET_FLUSHED bit to the outgoing packet.
if( pContext->txFlush )
{
DEBUGMSG( ZONE_NCP, (TEXT("PPP: CCP - TX sending PACKET_FLUSHED\n" )));
pContext->txFlush = FALSE;
coherencyHeader |= PACKET_FLUSHED << 8;
}
//
// Add the 2 byte coherency header to the packet:
// ABCD bits: 4 bits
// Coherency Count: 12 bits
//
pPacket->CurrentBuffer -= 2;
pPacket->CurrentLength += 2;
pPacket->CurrentBuffer[0] = (UCHAR )( coherencyHeader >> 8 );
pPacket->CurrentBuffer[1] = (UCHAR ) coherencyHeader;
return TRUE;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -