⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 msg.c

📁 WinCE5.0部分核心源码
💻 C
📖 第 1 页 / 共 2 页
字号:
//
// Copyright (c) Microsoft Corporation.  All rights reserved.
//
//
// This source code is licensed under Microsoft Shared Source License
// Version 1.0 for Windows CE.
// For a copy of the license visit http://go.microsoft.com/fwlink/?LinkId=3223.
//

// PPP CCP Layer Message Processing

#include "windows.h"
#include "cclib.h"

#include "memory.h"
#include "cxport.h"

// PPP Include Files

#include "protocol.h"
#include "ppp.h"
#include "lcp.h"
#include "auth.h"
#include "ccp.h"
#include "ncp.h"
#include "mac.h"
#include "ip_intf.h"

void
ccpRxResetRequest(
	IN	PVOID	context,
	IN	BYTE	code,
	IN  BYTE    id,
	IN	PBYTE	pData,
	IN	DWORD	cbData)
//
//	Called when we receive a CCP Reset-Request packet
//
{
	PCCPContext  pContext = (PCCPContext)context;

	DEBUGMSG( ZONE_NCP | ZONE_FUNCTION, (TEXT( "PPP: ccpRxResetRequest\n" )));

    // A compression reset forces a TX flush sequence. We set the flush
    // flag to force the next tx packet to be uncompressed and re-initialize
    // the send context.

    // Flush next tx packet

    pContext->txFlush = TRUE;

    initsendcontext( &pContext->mppcSndCntxt );

    // NOTE:
    // The Microsoft implementation does not send an ACK
    // but rather sets the PACKET_FLUSH bit on the next outgoing packet
    // to signal a reset.
}

void
ccpRxResetAck(
	IN	PVOID	context,
	IN	BYTE	code,
	IN  BYTE    id,
	IN	PBYTE	pData,
	IN	DWORD	cbData)
//
//	Called when we receive a CCP Reset-Ack packet
//
{
	PCCPContext  pContext = (PCCPContext)context;

	DEBUGMSG( ZONE_NCP | ZONE_FUNCTION, (TEXT( "PPP: ccpRxResetAck\n" )));

	// MS CCP does not use the ACK mechanism.
}

void
ccpTxResetRequest(
	IN PCCPContext  pContext)
//
//  Send Reset Request Packet
//
{
	BYTE    resetRequestPacket[PPP_PACKET_HEADER_SIZE];

    pContext->idResetRequest++;
	PPP_INIT_PACKET( &resetRequestPacket[0], CCP_RESET_REQ, pContext->idResetRequest);
	pppSendData(pContext->session, PPP_PROTOCOL_CCP, resetRequestPacket, PPP_PACKET_HEADER_SIZE);
}

void
CpktProcessRxPacket(
	IN  OUT PVOID        context,
	IN  OUT pppMsg_t    *pMsg)
//
//	Process a compressed/encrypted data packet received
//  from the peer.
//
{	PCCPContext pContext = (PCCPContext)context;
	PBYTE           pDecompressed;
    DWORD           cbDecompressed;
	USHORT          coherencyHdr;

    DEBUGMSG( ZONE_NCP | ZONE_FUNCTION, (TEXT("PPP: RX CCP Data Message\n")));

	if (pContext->pFsm->state != PFS_Opened)
	{
		DEBUGMSG(ZONE_WARN, (TEXT("PPP: WARNING - Ignoring CCP data packet, CCP not opened\n")));
		return;
	}

#ifdef DEBUG
	if (ZONE_TRACE)
	{
		DEBUGMSG (1, (TEXT("PPP: CCP: RX Packet (%d):\n"), pMsg->len));
		DumpMem (pMsg->data, pMsg->len);
	}
#endif // DEBUG

    // Access the Coherency Header and adjust msg

	if (pMsg->len < 2)
	{
		DEBUGMSG(ZONE_WARN, (TEXT("PPP: WARNING - CCP compressed packet has no coherency header\n")));
		return;
	}

    coherencyHdr = (pMsg->data[0] << 8) + pMsg->data[1];
    pMsg->data += 2;
    pMsg->len  -= 2;

    DEBUGMSG( ZONE_NCP, (TEXT( "PPP: CCP: RX: coherency hdr= 0x%x\n" ), coherencyHdr ));

    // Force a resync for a FLUSHED packet

    if( coherencyHdr & (PACKET_FLUSHED << 8) )
    {
        DEBUGMSG (ZONE_CCP || ZONE_TRACE, (TEXT( "PPP: CCP RX FLUSH LastGood=0x%x New=0x%x.\n"), pContext->rxCoherency, coherencyHdr));           

		//
		//	If the peer acked our config-request for encryption, then
		//  the peer will be sending encrypted packets to us so we need
		//  to reset the receive encrypt context.
		//

		if (pContext->local.SupportedBits & (MSTYPE_ENCRYPTION_40F | MSTYPE_ENCRYPTION_128))
		{
			//
			// If it appears that this FLUSHED packet is stale, that is, we have
			// already changed our session key to the next one because we passed
			// a flag packet, then ignore it.
			//
			// That is, if we receive packets out of order due to some strangeness
			// at the MAC layer like this:
			// 
			//      RX CC = 0FE
			//      RX CC = 0FF (Session Key changed)
			//      RX CC = 100
			//      RX CC = 0FC FLUSHED	
			//
			// Then the CC=0FC packet is probably being received out of order. If we
			// accepted it as valid and in order then that would mean that we missed
			// the almost 4000 packets from 101 to 0FB, and thus would need to change
			// our session key 15 times to account for the intervening missed flag
			// packets. More likely, however, is that the 0FC packet is old and delivered
			// out of order for some reason. If we change our session key 15 times then
			// we will permanently lose sync with the transmitter's encryption key.
			//
			// So, rather than changing the encryption key 15 times we ignore the packet.
			// As a simplification, we ignore any FLUSHED packet with a CC that is in the
			// range of the 256 most recent CC's we received.
			//
			if ((((coherencyHdr & 0x0fff) - pContext->rxCoherency) & 0x0fff) >= 0x0f00)
			{
				DEBUGMSG(ZONE_WARN, (L"PPP: CCP RX Ignore FLUSHED Out-of-order - rx=%04x exp=%04x\n", coherencyHdr, pContext->rxCoherency));
				return;
			}
           
			//
			//  Each packet that gets encrypted modifies the current encryption key state. As a result, if a packet
			//  is lost the receiver will not be able to decode subsequent packets because its decryption key will
			//  not be in sync with the encryption key. To solve this issue, the MPPE protocol specifies that when
			//  a CCP packet is sent with the PACKET_FLUSHED bit set, the encryption key is reset to discard all
			//  prior packet data that has modified its state.
			//
			//  That is, suppose the receiver processes packets with CC=0 through CC=2A. The encryption key for both
			//  sender and receiver has been modified by all the data in these packets. But then CC=2B is dropped.
			//  The sender's encryption key has been modified by the data of packet 2B, but the receiver's has not,
			//  so the receiver cannot decrypt any more packets in this stream. So, the receiver sends a CCP Reset
			//  request to the sender. This causes the sender to reset its encryption key, discarding all the packet
			//  data history from CC=0 to CC=2B prior to encrypting its next packet, which it sends with FLUSHED=1.
			//  The receiver, when it sees the FLUSHED bit, then resets its decryption key discarding all prior
			//  packet data and thus is able to once again decrypt packets in the stream.
			//
			
			EncryptionInfoReinitializeKey(pContext->prxEncryptionInfo);					 
		}

		//
		//	If the peer acked our config-request for MCCP_COMPRESSION, then
		//  the peer will be sending compressed packets to us so we need
		//  to reset the receive compress context.
		//
		if (pContext->local.SupportedBits & MCCP_COMPRESSION)
		{
			initrecvcontext( &pContext->mppcRcvCntxt );          // reset rcv context
		}

        //
        //  This is now our new coherency count.
        //

        pContext->rxCoherency = coherencyHdr & 0x0fff;

        //
        //  We are back in sync...
        //

        pContext->bRxOutOfSync = FALSE;
        
    }

    // If the received coherency counters agree then we are in sync. 
    // Note: if the packet was a flush packet then the above logic 
    // forces the coherency counters to agree and resets the context 
    // so we are in sync here, albeit, without any history.

    if ((pContext->bRxOutOfSync)
	|| ((coherencyHdr & 0x0fff) != pContext->rxCoherency))
    {     
        DEBUGMSG( ZONE_ERROR | ZONE_NCP, (TEXT( "PPP: CCP:rx:TOSS PKT - BAD COHERENCY (got %x expected %x\n"),
			coherencyHdr, pContext->rxCoherency));         

        // Changes for coherency fix 
        // this indicates a lost packet, try re-syncing our
        // coherency counter, reseting the context, and the
        // sending a reset request packet

        pContext->bRxOutOfSync = TRUE;     
   		ccpTxResetRequest(pContext);
        return;        
    }

    //
    //  This is the next good coherency number we expect.
    //

    pContext->rxCoherency = (pContext->rxCoherency + 1) & 0x0FFF;


	// If packet is encrypted then attempt to decrypt
    if( coherencyHdr & (PACKET_ENCRYPTED << 8) )
	{
        DEBUGMSG( ZONE_CCP, (TEXT( "PPP: CCP - Decrypting packet\n" )));

		DecryptRxData(pContext, pMsg->data, pMsg->len);

#ifdef DEBUG
		if (ZONE_TRACE)
		{
			DEBUGMSG (1, (TEXT("PPP: CCP: RX Decrypted packet (%d):\n"), pMsg->len));
			DumpMem (pMsg->data, pMsg->len);
		}
#endif
	}

    // If packet is compressed attempt to decompress

    if( coherencyHdr & (PACKET_COMPRESSED << 8) ) 
    {
		if (!(pContext->local.SupportedBits & MCCP_COMPRESSION))
		{
			DEBUGMSG(ZONE_ERROR, (TEXT("PPP: CCP-ERROR Rx compressed packet with compression disabled\n")));
			return;
		}

        if( decompress( pMsg->data, 
                        pMsg->len, 
                        ((coherencyHdr & (PACKET_AT_FRONT << 8)) >> 8), 
                        &pDecompressed, 
                        &cbDecompressed, 
                        &pContext->mppcRcvCntxt ) == FALSE )
        {
            // Coherency is lost - Request a reset from Peer

            DEBUGMSG( ZONE_CCP | ZONE_ERROR, (TEXT( "CCP:RX:PKT DECOMPRESS FAILED - REQUEST RESET\r\n" )));

            //
            //  Should not reduce the pContext->rxCoherency here because we have already
            //  done the DecryptRxData().
            //
            
			ccpTxResetRequest(pContext);

			//
			//  We are in out of sync state.   Only flush packet can get us back...

⌨️ 快捷键说明

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