Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

247 lines
6.8 KiB

  1. /*++
  2. Copyright (c) 1993 Microsoft Corporation
  3. Module Name:
  4. pppframe.c
  5. Abstract:
  6. Author:
  7. Thomas J. Dimitri (TommyD)
  8. Environment:
  9. Revision History:
  10. --*/
  11. #include "asyncall.h"
  12. VOID
  13. AssemblePPPFrame(
  14. PNDIS_WAN_PACKET WanPacket)
  15. {
  16. PUCHAR pOldFrame;
  17. PUCHAR pNewFrame;
  18. USHORT crcData;
  19. UINT dataSize;
  20. PASYNC_INFO pInfo;
  21. ULONG bitMask;
  22. //
  23. // Initialize locals
  24. //
  25. pOldFrame = WanPacket->CurrentBuffer;
  26. pNewFrame = WanPacket->StartBuffer;
  27. //
  28. // for quicker access, get a copy of data length field
  29. //
  30. dataSize = WanPacket->CurrentLength;
  31. pInfo = WanPacket->MacReserved1;
  32. bitMask = pInfo->SetLinkInfo.SendACCM;
  33. //
  34. // Now we run through the entire frame and pad it FORWARDS...
  35. //
  36. // <------------- new frame -----------> (could be twice as large)
  37. // +-----------------------------------+
  38. // | |x|
  39. // +-----------------------------------+
  40. // ^
  41. // <---- old frame --> |
  42. // +-----------------+ |
  43. // | |x| |
  44. // +-----------------+ |
  45. // | |
  46. // \-----------------/
  47. //
  48. // so that we don't overrun ourselves
  49. //
  50. //-----------------------------------------------------------------------
  51. //
  52. // +----------+----------+----------+----------+------------
  53. // | Flag | Address | Control | Protocol | Information
  54. // | 01111110 | 11111111 | 00000011 | 16 bits | *
  55. // +----------+----------+----------+----------+------------
  56. // ---+----------+----------+-----------------
  57. // | FCS | Flag | Inter-frame Fill
  58. // | 16 bits | 01111110 | or next Address
  59. // ---+----------+----------+-----------------
  60. //
  61. //
  62. // Frame Check Sequence (FCS) Field
  63. //
  64. // The Frame Check Sequence field is normally 16 bits (two octets). The
  65. // use of other FCS lengths may be defined at a later time, or by prior
  66. // agreement.
  67. //
  68. // The FCS field is calculated over all bits of the Address, Control,
  69. // Protocol and Information fields not including any start and stop bits
  70. // (asynchronous) and any bits (synchronous) or octets (asynchronous)
  71. // inserted for transparency. This does not include the Flag Sequences
  72. // or the FCS field itself. The FCS is transmitted with the coefficient
  73. // of the highest term first.
  74. //
  75. // Note: When octets are received which are flagged in the Async-
  76. // Control-Character-Map, they are discarded before calculating the
  77. // FCS. See the description in Appendix A.
  78. //
  79. //
  80. // RFC 1331 Point-to-Point Protocol May 1992
  81. // Transparency
  82. //
  83. // On asynchronous links, a character stuffing procedure is used.
  84. // The Control Escape octet is defined as binary 01111101
  85. // (hexadecimal 0x7d) where the bit positions are numbered 87654321
  86. // (not 76543210, BEWARE).
  87. //
  88. // After FCS computation, the transmitter examines the entire frame
  89. // between the two Flag Sequences. Each Flag Sequence, Control
  90. // Escape octet and octet with value less than hexadecimal 0x20 which
  91. // is flagged in the Remote Async-Control-Character-Map is replaced
  92. // by a two octet sequence consisting of the Control Escape octet and
  93. // the original octet with bit 6 complemented (i.e., exclusive-or'd
  94. // with hexadecimal 0x20).
  95. //
  96. // Prior to FCS computation, the receiver examines the entire frame
  97. // between the two Flag Sequences. Each octet with value less than
  98. // hexadecimal 0x20 is checked. If it is flagged in the Local
  99. // Async-Control-Character-Map, it is simply removed (it may have
  100. // been inserted by intervening data communications equipment). For
  101. // each Control Escape octet, that octet is also removed, but bit 6
  102. // of the following octet is complemented. A Control Escape octet
  103. // immediately preceding the closing Flag Sequence indicates an
  104. // invalid frame.
  105. //
  106. // Note: The inclusion of all octets less than hexadecimal 0x20
  107. // allows all ASCII control characters [10] excluding DEL (Delete)
  108. // to be transparently communicated through almost all known data
  109. // communications equipment.
  110. //
  111. //
  112. // The transmitter may also send octets with value in the range 0x40
  113. // through 0xff (except 0x5e) in Control Escape format. Since these
  114. // octet values are not negotiable, this does not solve the problem
  115. // of receivers which cannot handle all non-control characters.
  116. // Also, since the technique does not affect the 8th bit, this does
  117. // not solve problems for communications links that can send only 7-
  118. // bit characters.
  119. //
  120. // A few examples may make this more clear. Packet data is
  121. // transmitted on the link as follows:
  122. //
  123. // 0x7e is encoded as 0x7d, 0x5e.
  124. // 0x7d is encoded as 0x7d, 0x5d.
  125. //
  126. // 0x01 is encoded as 0x7d, 0x21.
  127. //
  128. // Some modems with software flow control may intercept outgoing DC1
  129. // and DC3 ignoring the 8th (parity) bit. This data would be
  130. // transmitted on the link as follows:
  131. //
  132. // 0x11 is encoded as 0x7d, 0x31.
  133. // 0x13 is encoded as 0x7d, 0x33.
  134. // 0x91 is encoded as 0x7d, 0xb1.
  135. // 0x93 is encoded as 0x7d, 0xb3.
  136. //
  137. //
  138. // put CRC from FLAG byte to FLAG byte
  139. //
  140. crcData=CalcCRCPPP(pOldFrame, // Skip FLAG
  141. dataSize); // All the way to end
  142. crcData ^= 0xFFFF;
  143. //
  144. // Do it the hard way to avoid little endian problems.
  145. //
  146. pOldFrame[dataSize]=(UCHAR)(crcData);
  147. pOldFrame[dataSize+1]=(UCHAR)(crcData >> 8);
  148. dataSize += 2; // include two CRC bytes we just added
  149. *pNewFrame++ = PPP_FLAG_BYTE; // 0x7e - mark beginning of frame
  150. //
  151. // If we do not have a bitMask (common case), we use a faster loop
  152. //
  153. if (bitMask) {
  154. //
  155. // loop to remove all control, ESC, and FLAG chars
  156. //
  157. while (dataSize--) {
  158. UCHAR c;
  159. c=*pOldFrame++; // get current byte in frame
  160. //
  161. // Check if we have to escape out this byte or not
  162. //
  163. if ( ( (c < 32) && ((0x01 << c) & bitMask)) ||
  164. c == PPP_ESC_BYTE || c == PPP_FLAG_BYTE) {
  165. *pNewFrame++ = PPP_ESC_BYTE;
  166. *pNewFrame++ = c ^ 0x20;
  167. } else {
  168. *pNewFrame++ = c;
  169. }
  170. }
  171. } else {
  172. //
  173. // loop to remove all ESC and FLAG chars
  174. //
  175. while (dataSize--) {
  176. UCHAR c;
  177. c=*pOldFrame++; // get current byte in frame
  178. //
  179. // Check if we have to escape out this byte or not
  180. //
  181. if (c == PPP_ESC_BYTE || c == PPP_FLAG_BYTE) {
  182. *pNewFrame++ = PPP_ESC_BYTE;
  183. *pNewFrame++ = c ^ 0x20;
  184. } else {
  185. *pNewFrame++ = c;
  186. }
  187. }
  188. }
  189. //
  190. // Mark end of frame
  191. //
  192. *pNewFrame++= PPP_FLAG_BYTE;
  193. //
  194. // Calc how many bytes we expanded to including CRC
  195. //
  196. WanPacket->CurrentLength = (ULONG)(pNewFrame - WanPacket->StartBuffer);
  197. //
  198. // Put in the adjusted length -- actual num of bytes to send
  199. //
  200. WanPacket->CurrentBuffer = WanPacket->StartBuffer;
  201. }