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.

420 lines
9.6 KiB

  1. /*++
  2. Copyright (c) 1989, 1990, 1991 Microsoft Corporation
  3. Module Name:
  4. nbfmac.c
  5. Abstract:
  6. This module contains code which implements Mac type dependent code for
  7. the NBF transport.
  8. Author:
  9. David Beaver (dbeaver) 1-July-1991
  10. Environment:
  11. Kernel mode (Actually, unimportant)
  12. Revision History:
  13. --*/
  14. #include "precomp.h"
  15. #pragma hdrstop
  16. UCHAR SingleRouteSourceRouting[] = { 0xc2, 0x70 };
  17. UCHAR GeneralRouteSourceRouting[] = { 0x82, 0x70 };
  18. ULONG DefaultSourceRoutingLength = 2;
  19. //
  20. // This is the interpretation of the length bits in
  21. // the 802.5 source-routing information.
  22. //
  23. ULONG SR802_5Lengths[8] = { 516, 1500, 2052, 4472,
  24. 8144, 11407, 17800, 17800 };
  25. #ifdef ALLOC_PRAGMA
  26. #pragma alloc_text(PAGE,MacInitializeMacInfo)
  27. #pragma alloc_text(PAGE,MacSetNetBIOSMulticast)
  28. #endif
  29. VOID
  30. MacInitializeMacInfo(
  31. IN NDIS_MEDIUM MacType,
  32. IN BOOLEAN UseDix,
  33. OUT PNBF_NDIS_IDENTIFICATION MacInfo
  34. )
  35. /*++
  36. Routine Description:
  37. Fills in the MacInfo table based on MacType.
  38. Arguments:
  39. MacType - The MAC type we wish to decode.
  40. UseDix - TRUE if we should use DIX encoding on 802.3.
  41. MacInfo - The MacInfo structure to fill in.
  42. Return Value:
  43. None.
  44. --*/
  45. {
  46. switch (MacType) {
  47. case NdisMedium802_3:
  48. MacInfo->DestinationOffset = 0;
  49. MacInfo->SourceOffset = 6;
  50. MacInfo->SourceRouting = FALSE;
  51. MacInfo->AddressLength = 6;
  52. if (UseDix) {
  53. MacInfo->TransferDataOffset = 3;
  54. MacInfo->MaxHeaderLength = 17;
  55. MacInfo->MediumType = NdisMediumDix;
  56. } else {
  57. MacInfo->TransferDataOffset = 0;
  58. MacInfo->MaxHeaderLength = 14;
  59. MacInfo->MediumType = NdisMedium802_3;
  60. }
  61. MacInfo->MediumAsync = FALSE;
  62. break;
  63. case NdisMedium802_5:
  64. MacInfo->DestinationOffset = 2;
  65. MacInfo->SourceOffset = 8;
  66. MacInfo->SourceRouting = TRUE;
  67. MacInfo->AddressLength = 6;
  68. MacInfo->TransferDataOffset = 0;
  69. MacInfo->MaxHeaderLength = 32;
  70. MacInfo->MediumType = NdisMedium802_5;
  71. MacInfo->MediumAsync = FALSE;
  72. break;
  73. case NdisMediumFddi:
  74. MacInfo->DestinationOffset = 1;
  75. MacInfo->SourceOffset = 7;
  76. MacInfo->SourceRouting = FALSE;
  77. MacInfo->AddressLength = 6;
  78. MacInfo->TransferDataOffset = 0;
  79. MacInfo->MaxHeaderLength = 13;
  80. MacInfo->MediumType = NdisMediumFddi;
  81. MacInfo->MediumAsync = FALSE;
  82. break;
  83. case NdisMediumWan:
  84. MacInfo->DestinationOffset = 0;
  85. MacInfo->SourceOffset = 6;
  86. MacInfo->SourceRouting = FALSE;
  87. MacInfo->AddressLength = 6;
  88. MacInfo->TransferDataOffset = 0;
  89. MacInfo->MaxHeaderLength = 14;
  90. MacInfo->MediumType = NdisMedium802_3;
  91. MacInfo->MediumAsync = TRUE;
  92. break;
  93. default:
  94. ASSERT(FALSE);
  95. }
  96. }
  97. VOID
  98. MacConstructHeader (
  99. IN PNBF_NDIS_IDENTIFICATION MacInfo,
  100. IN PUCHAR Buffer,
  101. IN PUCHAR DestinationAddress,
  102. IN PUCHAR SourceAddress,
  103. IN UINT PacketLength,
  104. IN PUCHAR SourceRouting,
  105. IN UINT SourceRoutingLength,
  106. OUT PUINT HeaderLength
  107. )
  108. /*++
  109. Routine Description:
  110. This routine is called to construct the Mac header for the particular
  111. network type we're talking to.
  112. Arguments:
  113. MacInfo - Describes the mac we wish to build a header for.
  114. Buffer - Where to build the header.
  115. DestinationAddress - the address this packet is to be sent to.
  116. SourceAddress - Our address. Passing it in as a parameter allows us to play
  117. games with source if we need to.
  118. PacketLength - The length of this packet. Note that this does not
  119. includes the Mac header.
  120. SourceRouting - Optional source routing information.
  121. SourceRoutingLength - The length of SourceRouting.
  122. HeaderLength - Returns the length of the constructed header.
  123. Return Value:
  124. None.
  125. --*/
  126. {
  127. //
  128. // Note network order of bytes.
  129. //
  130. switch (MacInfo->MediumType) {
  131. case NdisMedium802_3:
  132. *(ULONG UNALIGNED *)&Buffer[6] = *(ULONG UNALIGNED *)&SourceAddress[0];
  133. Buffer[10] = SourceAddress[4];
  134. Buffer[11] = SourceAddress[5];
  135. *(ULONG UNALIGNED *)&Buffer[0] = *(ULONG UNALIGNED *)&DestinationAddress[0];
  136. Buffer[4] = DestinationAddress[4];
  137. Buffer[5] = DestinationAddress[5];
  138. Buffer[12] = (UCHAR)(PacketLength >> 8);
  139. Buffer[13] = (UCHAR)PacketLength;
  140. *HeaderLength = 14;
  141. break;
  142. case NdisMediumDix:
  143. *(ULONG UNALIGNED *)&Buffer[6] = *(ULONG UNALIGNED *)&SourceAddress[0];
  144. Buffer[10] = SourceAddress[4];
  145. Buffer[11] = SourceAddress[5];
  146. *(ULONG UNALIGNED *)&Buffer[0] = *(ULONG UNALIGNED *)&DestinationAddress[0];
  147. Buffer[4] = DestinationAddress[4];
  148. Buffer[5] = DestinationAddress[5];
  149. Buffer[12] = 0x80;
  150. Buffer[13] = 0xd5;
  151. Buffer[14] = (UCHAR)(PacketLength >> 8);
  152. Buffer[15] = (UCHAR)PacketLength;
  153. Buffer[16] = 0x00;
  154. *HeaderLength = 17;
  155. break;
  156. case NdisMedium802_5:
  157. Buffer[0] = TR_HEADER_BYTE_0;
  158. Buffer[1] = TR_HEADER_BYTE_1;
  159. ASSERT (TR_ADDRESS_LENGTH == 6);
  160. *(ULONG UNALIGNED *)&Buffer[8] = *(ULONG UNALIGNED *)&SourceAddress[0];
  161. Buffer[12] = SourceAddress[4];
  162. Buffer[13] = SourceAddress[5];
  163. *(ULONG UNALIGNED *)&Buffer[2] = *(ULONG UNALIGNED *)&DestinationAddress[0];
  164. Buffer[6] = DestinationAddress[4];
  165. Buffer[7] = DestinationAddress[5];
  166. *HeaderLength = 14;
  167. if (SourceRouting != NULL) {
  168. RtlCopyMemory (&Buffer[14], SourceRouting, SourceRoutingLength);
  169. Buffer[8] |= 0x80; // add SR bit in source address
  170. *HeaderLength = 14 + SourceRoutingLength;
  171. }
  172. break;
  173. case NdisMediumFddi:
  174. Buffer[0] = FDDI_HEADER_BYTE;
  175. *(ULONG UNALIGNED *)&Buffer[7] = *(ULONG UNALIGNED *)&SourceAddress[0];
  176. Buffer[11] = SourceAddress[4];
  177. Buffer[12] = SourceAddress[5];
  178. *(ULONG UNALIGNED *)&Buffer[1] = *(ULONG UNALIGNED *)&DestinationAddress[0];
  179. Buffer[5] = DestinationAddress[4];
  180. Buffer[6] = DestinationAddress[5];
  181. *HeaderLength = 13;
  182. break;
  183. default:
  184. PANIC ("MacConstructHeader: PANIC! called with unsupported Mac type.\n");
  185. // This should not happen - but just in case
  186. *HeaderLength = 0;
  187. }
  188. }
  189. VOID
  190. MacReturnMaxDataSize(
  191. IN PNBF_NDIS_IDENTIFICATION MacInfo,
  192. IN PUCHAR SourceRouting,
  193. IN UINT SourceRoutingLength,
  194. IN UINT DeviceMaxFrameSize,
  195. IN BOOLEAN AssumeWorstCase,
  196. OUT PUINT MaxFrameSize
  197. )
  198. /*++
  199. Routine Description:
  200. This routine returns the space available for user data in a MAC packet.
  201. This will be the available space after the MAC header; all LLC and NBF
  202. headers will be included in this space.
  203. Arguments:
  204. MacInfo - Describes the MAC we wish to decode.
  205. SourceRouting - If we are concerned about a reply to a specific
  206. frame, then this information is used.
  207. SourceRouting - The length of SourceRouting.
  208. MaxFrameSize - The maximum frame size as returned by the adapter.
  209. AssumeWorstCase - TRUE if we should be pessimistic.
  210. MaxDataSize - The maximum data size computed.
  211. Return Value:
  212. None.
  213. --*/
  214. {
  215. switch (MacInfo->MediumType) {
  216. case NdisMedium802_3:
  217. //
  218. // For 802.3, we always have a 14-byte MAC header.
  219. //
  220. *MaxFrameSize = DeviceMaxFrameSize - 14;
  221. break;
  222. case NdisMediumDix:
  223. //
  224. // For DIX, we have the 14-byte MAC header plus
  225. // the three-byte DIX header.
  226. //
  227. *MaxFrameSize = DeviceMaxFrameSize - 17;
  228. break;
  229. case NdisMedium802_5:
  230. //
  231. // For 802.5, if we have source routing information then
  232. // use that, otherwise assume the worst if told to.
  233. //
  234. if (SourceRouting && SourceRoutingLength >= 2) {
  235. UINT SRLength;
  236. SRLength = SR802_5Lengths[(SourceRouting[1] & 0x70) >> 4];
  237. DeviceMaxFrameSize -= (SourceRoutingLength + 14);
  238. if (DeviceMaxFrameSize < SRLength) {
  239. *MaxFrameSize = DeviceMaxFrameSize;
  240. } else {
  241. *MaxFrameSize = SRLength;
  242. }
  243. } else {
  244. if (!AssumeWorstCase) {
  245. *MaxFrameSize = DeviceMaxFrameSize - 16;
  246. } else if (DeviceMaxFrameSize < (544+sizeof(DLC_FRAME)+sizeof(NBF_HDR_CONNECTIONLESS))) {
  247. *MaxFrameSize = DeviceMaxFrameSize - 32;
  248. } else {
  249. *MaxFrameSize = 512 + sizeof(DLC_FRAME) + sizeof(NBF_HDR_CONNECTIONLESS);
  250. }
  251. }
  252. break;
  253. case NdisMediumFddi:
  254. //
  255. // For FDDI, we always have a 13-byte MAC header.
  256. //
  257. *MaxFrameSize = DeviceMaxFrameSize - 13;
  258. break;
  259. }
  260. }
  261. VOID
  262. MacSetNetBIOSMulticast (
  263. IN NDIS_MEDIUM Type,
  264. IN PUCHAR Buffer
  265. )
  266. /*++
  267. Routine Description:
  268. This routine sets the NetBIOS broadcast address into a buffer provided
  269. by the user.
  270. Arguments:
  271. Type the Mac Medium type.
  272. Buffer the buffer to put the multicast address in.
  273. Return Value:
  274. none.
  275. --*/
  276. {
  277. switch (Type) {
  278. case NdisMedium802_3:
  279. case NdisMediumDix:
  280. Buffer[0] = 0x03;
  281. Buffer[ETHERNET_ADDRESS_LENGTH-1] = 0x01;
  282. break;
  283. case NdisMedium802_5:
  284. Buffer[0] = 0xc0;
  285. Buffer[TR_ADDRESS_LENGTH-1] = 0x80;
  286. break;
  287. case NdisMediumFddi:
  288. Buffer[0] = 0x03;
  289. Buffer[FDDI_ADDRESS_LENGTH-1] = 0x01;
  290. break;
  291. default:
  292. PANIC ("MacSetNetBIOSAddress: PANIC! called with unsupported Mac type.\n");
  293. }
  294. }
  295.