Leaked source code of windows server 2003
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.

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