248 lines
6.8 KiB
C
248 lines
6.8 KiB
C
|
/*++
|
||
|
|
||
|
Copyright (c) 1993 Microsoft Corporation
|
||
|
|
||
|
Module Name:
|
||
|
|
||
|
pppframe.c
|
||
|
|
||
|
Abstract:
|
||
|
|
||
|
Author:
|
||
|
|
||
|
Thomas J. Dimitri (TommyD)
|
||
|
|
||
|
Environment:
|
||
|
|
||
|
Revision History:
|
||
|
|
||
|
--*/
|
||
|
|
||
|
#include "asyncall.h"
|
||
|
|
||
|
VOID
|
||
|
AssemblePPPFrame(
|
||
|
PNDIS_WAN_PACKET WanPacket)
|
||
|
|
||
|
{
|
||
|
PUCHAR pOldFrame;
|
||
|
PUCHAR pNewFrame;
|
||
|
USHORT crcData;
|
||
|
UINT dataSize;
|
||
|
PASYNC_INFO pInfo;
|
||
|
ULONG bitMask;
|
||
|
|
||
|
//
|
||
|
// Initialize locals
|
||
|
//
|
||
|
|
||
|
pOldFrame = WanPacket->CurrentBuffer;
|
||
|
|
||
|
pNewFrame = WanPacket->StartBuffer;
|
||
|
|
||
|
//
|
||
|
// for quicker access, get a copy of data length field
|
||
|
//
|
||
|
dataSize = WanPacket->CurrentLength;
|
||
|
|
||
|
pInfo = WanPacket->MacReserved1;
|
||
|
bitMask = pInfo->SetLinkInfo.SendACCM;
|
||
|
|
||
|
|
||
|
//
|
||
|
// Now we run through the entire frame and pad it FORWARDS...
|
||
|
//
|
||
|
// <------------- new frame -----------> (could be twice as large)
|
||
|
// +-----------------------------------+
|
||
|
// | |x|
|
||
|
// +-----------------------------------+
|
||
|
// ^
|
||
|
// <---- old frame --> |
|
||
|
// +-----------------+ |
|
||
|
// | |x| |
|
||
|
// +-----------------+ |
|
||
|
// | |
|
||
|
// \-----------------/
|
||
|
//
|
||
|
// so that we don't overrun ourselves
|
||
|
//
|
||
|
//-----------------------------------------------------------------------
|
||
|
//
|
||
|
// +----------+----------+----------+----------+------------
|
||
|
// | Flag | Address | Control | Protocol | Information
|
||
|
// | 01111110 | 11111111 | 00000011 | 16 bits | *
|
||
|
// +----------+----------+----------+----------+------------
|
||
|
// ---+----------+----------+-----------------
|
||
|
// | FCS | Flag | Inter-frame Fill
|
||
|
// | 16 bits | 01111110 | or next Address
|
||
|
// ---+----------+----------+-----------------
|
||
|
//
|
||
|
//
|
||
|
// Frame Check Sequence (FCS) Field
|
||
|
//
|
||
|
// The Frame Check Sequence field is normally 16 bits (two octets). The
|
||
|
// use of other FCS lengths may be defined at a later time, or by prior
|
||
|
// agreement.
|
||
|
//
|
||
|
// The FCS field is calculated over all bits of the Address, Control,
|
||
|
// Protocol and Information fields not including any start and stop bits
|
||
|
// (asynchronous) and any bits (synchronous) or octets (asynchronous)
|
||
|
// inserted for transparency. This does not include the Flag Sequences
|
||
|
// or the FCS field itself. The FCS is transmitted with the coefficient
|
||
|
// of the highest term first.
|
||
|
//
|
||
|
// Note: When octets are received which are flagged in the Async-
|
||
|
// Control-Character-Map, they are discarded before calculating the
|
||
|
// FCS. See the description in Appendix A.
|
||
|
//
|
||
|
//
|
||
|
// RFC 1331 Point-to-Point Protocol May 1992
|
||
|
// Transparency
|
||
|
//
|
||
|
// On asynchronous links, a character stuffing procedure is used.
|
||
|
// The Control Escape octet is defined as binary 01111101
|
||
|
// (hexadecimal 0x7d) where the bit positions are numbered 87654321
|
||
|
// (not 76543210, BEWARE).
|
||
|
//
|
||
|
// After FCS computation, the transmitter examines the entire frame
|
||
|
// between the two Flag Sequences. Each Flag Sequence, Control
|
||
|
// Escape octet and octet with value less than hexadecimal 0x20 which
|
||
|
// is flagged in the Remote Async-Control-Character-Map is replaced
|
||
|
// by a two octet sequence consisting of the Control Escape octet and
|
||
|
// the original octet with bit 6 complemented (i.e., exclusive-or'd
|
||
|
// with hexadecimal 0x20).
|
||
|
//
|
||
|
// Prior to FCS computation, the receiver examines the entire frame
|
||
|
// between the two Flag Sequences. Each octet with value less than
|
||
|
// hexadecimal 0x20 is checked. If it is flagged in the Local
|
||
|
// Async-Control-Character-Map, it is simply removed (it may have
|
||
|
// been inserted by intervening data communications equipment). For
|
||
|
// each Control Escape octet, that octet is also removed, but bit 6
|
||
|
// of the following octet is complemented. A Control Escape octet
|
||
|
// immediately preceding the closing Flag Sequence indicates an
|
||
|
// invalid frame.
|
||
|
//
|
||
|
// Note: The inclusion of all octets less than hexadecimal 0x20
|
||
|
// allows all ASCII control characters [10] excluding DEL (Delete)
|
||
|
// to be transparently communicated through almost all known data
|
||
|
// communications equipment.
|
||
|
//
|
||
|
//
|
||
|
// The transmitter may also send octets with value in the range 0x40
|
||
|
// through 0xff (except 0x5e) in Control Escape format. Since these
|
||
|
// octet values are not negotiable, this does not solve the problem
|
||
|
// of receivers which cannot handle all non-control characters.
|
||
|
// Also, since the technique does not affect the 8th bit, this does
|
||
|
// not solve problems for communications links that can send only 7-
|
||
|
// bit characters.
|
||
|
//
|
||
|
// A few examples may make this more clear. Packet data is
|
||
|
// transmitted on the link as follows:
|
||
|
//
|
||
|
// 0x7e is encoded as 0x7d, 0x5e.
|
||
|
// 0x7d is encoded as 0x7d, 0x5d.
|
||
|
//
|
||
|
// 0x01 is encoded as 0x7d, 0x21.
|
||
|
//
|
||
|
// Some modems with software flow control may intercept outgoing DC1
|
||
|
// and DC3 ignoring the 8th (parity) bit. This data would be
|
||
|
// transmitted on the link as follows:
|
||
|
//
|
||
|
// 0x11 is encoded as 0x7d, 0x31.
|
||
|
// 0x13 is encoded as 0x7d, 0x33.
|
||
|
// 0x91 is encoded as 0x7d, 0xb1.
|
||
|
// 0x93 is encoded as 0x7d, 0xb3.
|
||
|
//
|
||
|
|
||
|
|
||
|
//
|
||
|
// put CRC from FLAG byte to FLAG byte
|
||
|
//
|
||
|
crcData=CalcCRCPPP(pOldFrame, // Skip FLAG
|
||
|
dataSize); // All the way to end
|
||
|
|
||
|
crcData ^= 0xFFFF;
|
||
|
|
||
|
//
|
||
|
// Do it the hard way to avoid little endian problems.
|
||
|
//
|
||
|
pOldFrame[dataSize]=(UCHAR)(crcData);
|
||
|
pOldFrame[dataSize+1]=(UCHAR)(crcData >> 8);
|
||
|
|
||
|
dataSize += 2; // include two CRC bytes we just added
|
||
|
|
||
|
*pNewFrame++ = PPP_FLAG_BYTE; // 0x7e - mark beginning of frame
|
||
|
|
||
|
//
|
||
|
// If we do not have a bitMask (common case), we use a faster loop
|
||
|
//
|
||
|
if (bitMask) {
|
||
|
|
||
|
//
|
||
|
// loop to remove all control, ESC, and FLAG chars
|
||
|
//
|
||
|
while (dataSize--) {
|
||
|
UCHAR c;
|
||
|
|
||
|
c=*pOldFrame++; // get current byte in frame
|
||
|
|
||
|
//
|
||
|
// Check if we have to escape out this byte or not
|
||
|
//
|
||
|
if ( ( (c < 32) && ((0x01 << c) & bitMask)) ||
|
||
|
c == PPP_ESC_BYTE || c == PPP_FLAG_BYTE) {
|
||
|
|
||
|
*pNewFrame++ = PPP_ESC_BYTE;
|
||
|
*pNewFrame++ = c ^ 0x20;
|
||
|
|
||
|
} else {
|
||
|
|
||
|
*pNewFrame++ = c;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
} else {
|
||
|
|
||
|
//
|
||
|
// loop to remove all ESC and FLAG chars
|
||
|
//
|
||
|
while (dataSize--) {
|
||
|
UCHAR c;
|
||
|
|
||
|
c=*pOldFrame++; // get current byte in frame
|
||
|
|
||
|
//
|
||
|
// Check if we have to escape out this byte or not
|
||
|
//
|
||
|
if (c == PPP_ESC_BYTE || c == PPP_FLAG_BYTE) {
|
||
|
|
||
|
*pNewFrame++ = PPP_ESC_BYTE;
|
||
|
*pNewFrame++ = c ^ 0x20;
|
||
|
|
||
|
} else {
|
||
|
|
||
|
*pNewFrame++ = c;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
|
||
|
//
|
||
|
// Mark end of frame
|
||
|
//
|
||
|
*pNewFrame++= PPP_FLAG_BYTE;
|
||
|
|
||
|
//
|
||
|
// Calc how many bytes we expanded to including CRC
|
||
|
//
|
||
|
WanPacket->CurrentLength = (ULONG)(pNewFrame - WanPacket->StartBuffer);
|
||
|
|
||
|
//
|
||
|
// Put in the adjusted length -- actual num of bytes to send
|
||
|
//
|
||
|
|
||
|
WanPacket->CurrentBuffer = WanPacket->StartBuffer;
|
||
|
|
||
|
}
|