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.

409 lines
12 KiB

  1. /*++
  2. Copyright(c) 1999-2000 Microsoft Corporation
  3. Module Name:
  4. bridge.h
  5. Abstract:
  6. Ethernet MAC level bridge.
  7. Author:
  8. Mark Aiken
  9. (original bridge by Jameel Hyder)
  10. Environment:
  11. Kernel mode driver
  12. Revision History:
  13. Sept 1999 - Original version
  14. Feb 2000 - Overhaul
  15. --*/
  16. #pragma warning( push, 3 )
  17. // For Ethernet constants and macros
  18. #include <xfilter.h>
  19. // For ULONG_MAX
  20. #include <limits.h>
  21. #pragma warning( pop )
  22. // Disable "conditional expression is constant" warning
  23. #pragma warning( disable: 4127 )
  24. // Disable "Unreferenced formal parameter" warning
  25. #pragma warning( disable: 4100 )
  26. // Disable "Bit field type other than int" warning
  27. #pragma warning( disable: 4214 )
  28. // Debugging defines
  29. #include "brdgdbg.h"
  30. // Singly-linked list implementation
  31. #include "brdgslist.h"
  32. // WAIT_REFCOUNT implementation
  33. #include "brdgwref.h"
  34. // Timer implementation
  35. #include "brdgtimr.h"
  36. // Hash table implementation
  37. #include "brdghash.h"
  38. // Cache implementation
  39. #include "brdgcach.h"
  40. // Our IOCTLs and control structures
  41. #include "bioctl.h"
  42. // Include the STA type declarations
  43. #include "brdgstad.h"
  44. // ===========================================================================
  45. //
  46. // CONSTANTS
  47. //
  48. // ===========================================================================
  49. #define DEVICE_NAME L"\\Device\\Bridge"
  50. #define SYMBOLIC_NAME L"\\DosDevices\\Bridge"
  51. #define PROTOCOL_NAME L"BRIDGE"
  52. //
  53. // The IEEE-specified reserved Spanning Tree Algorithm group destination
  54. // MAC address
  55. //
  56. // This exact address is specified as the "Bridge Group Address" and is used for
  57. // transmitting STA packets. *Any* address with these first 5 bytes is reserved
  58. // by the IEEE for future use (so there are 15 reserved but unused addresses).
  59. //
  60. // Frames addressed to ANY of the reserved addresses are never relayed by the bridge.
  61. //
  62. extern UCHAR STA_MAC_ADDR[ETH_LENGTH_OF_ADDRESS];
  63. //
  64. // Each queue draining thread blocks against one kernel event per adapter, plus
  65. // the global kill event and the per-processor event to trigger a re-enumeration
  66. // of adapters.
  67. //
  68. // This limits our maximum number of adapters, since the kernel can't block a
  69. // thread against an unbounded number of objects.
  70. //
  71. #define MAX_ADAPTERS (MAXIMUM_WAIT_OBJECTS - 2)
  72. // Registry key where we keep our global parameters
  73. extern const PWCHAR gRegConfigPath;
  74. // Size of an Ethernet frame header
  75. #define ETHERNET_HEADER_SIZE ((2*ETH_LENGTH_OF_ADDRESS) + 2)
  76. // Largest possible Ethernet packet (with header)
  77. #define MAX_PACKET_SIZE 1514
  78. // ===========================================================================
  79. //
  80. // TYPE DECLARATIONS
  81. //
  82. // ===========================================================================
  83. struct _NDIS_REQUEST_BETTER;
  84. // Completion function type for NDIS_REQUEST_BETTER
  85. typedef VOID (*PCOMPLETION_FUNC)(struct _NDIS_REQUEST_BETTER*, PVOID);
  86. //
  87. // Structure for performing NDIS requests. Can block to wait for result or
  88. // specify a custom completion routine.
  89. //
  90. typedef struct _NDIS_REQUEST_BETTER
  91. {
  92. NDIS_REQUEST Request;
  93. NDIS_STATUS Status; // Final status of the request
  94. NDIS_EVENT Event; // Event signaled when request completes
  95. PCOMPLETION_FUNC pFunc; // Completion function
  96. PVOID FuncArg; // Argument to completion function
  97. } NDIS_REQUEST_BETTER, *PNDIS_REQUEST_BETTER;
  98. typedef struct _ADAPTER_QUOTA
  99. {
  100. //
  101. // Total number of packets this adapter is holding from each major pool.
  102. //
  103. // Note that the sum of all adapters' pool usage can be greater than the pool capacity,
  104. // because base packets are shared. The quota scheme allows this.
  105. //
  106. // [0] == Copy packets
  107. // [1] == Wrapper packets
  108. //
  109. ULONG UsedPackets[2];
  110. } ADAPTER_QUOTA, *PADAPTER_QUOTA;
  111. //
  112. // Per adapter data structure
  113. //
  114. typedef struct _ADAPT ADAPT, *PADAPT;
  115. typedef struct _ADAPT
  116. {
  117. PADAPT Next; // Next adapter in queue
  118. LONG AdaptSize; // Size of structure (storage for DeviceName is at tail)
  119. WAIT_REFCOUNT Refcount; // Refcount for the adapter
  120. // State must be updated inside a write lock on gAdapterCharacteristicsLock,
  121. // since an adapter's relaying status affects our miniport's virtual status.
  122. // Only the STA code writes to this field; all other code should treat it as
  123. // read-only.
  124. PORT_STATE State;
  125. //
  126. // Various useful info about the adapter. None of these fields are ever changed after
  127. // adapter initialization.
  128. //
  129. NDIS_STRING DeviceName;
  130. NDIS_STRING DeviceDesc;
  131. UCHAR MACAddr[ETH_LENGTH_OF_ADDRESS];
  132. NDIS_MEDIUM PhysicalMedium; // Set to NO_MEDIUM if the NIC doesn't report something more specific
  133. NDIS_HANDLE BindingHandle;
  134. BOOLEAN bCompatibilityMode; // TRUE if the adapter is in compatibility mode
  135. // These two fields are used while opening / closing an adapter
  136. NDIS_EVENT Event;
  137. NDIS_STATUS Status;
  138. // This field is volatile
  139. BOOLEAN bResetting;
  140. // The queue and bServiceInProgress is protected by this spin lock
  141. NDIS_SPIN_LOCK QueueLock;
  142. BSINGLE_LIST_HEAD Queue;
  143. BOOLEAN bServiceInProgress;
  144. // This allows a caller to wait on the queue becoming empty. It is updated when an item is
  145. // queued or dequeued.
  146. WAIT_REFCOUNT QueueRefcount;
  147. // Auto-clearing event to request servicing of the queue
  148. KEVENT QueueEvent;
  149. // These fields are locked by gAdapterCharacteristicsLock for all adapters together
  150. ULONG MediaState; // NdisMediaStateConnected / NdisMediaStateDisconnected
  151. ULONG LinkSpeed; // Units of 100bps (10MBps == 100,000)
  152. // This structure is locked by gQuotaLock for all adapters together
  153. ADAPTER_QUOTA Quota; // Quota information for this adapter
  154. // Statistics
  155. LARGE_INTEGER SentFrames; // All frames sent (including relay)
  156. LARGE_INTEGER SentBytes; // All bytes sent (including relay)
  157. LARGE_INTEGER SentLocalFrames; // Frames sent from the local machine
  158. LARGE_INTEGER SentLocalBytes; // Bytes sent from the local machine
  159. LARGE_INTEGER ReceivedFrames; // All received frames (including relay)
  160. LARGE_INTEGER ReceivedBytes; // All received bytes (including relay)
  161. STA_ADAPT_INFO STAInfo; // STA data for this adapter
  162. // Set once from FALSE to TRUE when STA initialization on this adapter has completed.
  163. // This flag is set inside the gSTALock.
  164. BOOLEAN bSTAInited;
  165. } ADAPT, *PADAPT;
  166. // ===========================================================================
  167. //
  168. // INLINES / MACROS
  169. //
  170. // ===========================================================================
  171. //
  172. // Calculates the difference between a previously recorded time and now
  173. // allowing for timer rollover
  174. //
  175. __forceinline
  176. ULONG
  177. BrdgDeltaSafe(
  178. IN ULONG prevTime,
  179. IN ULONG nowTime,
  180. IN ULONG maxDelta
  181. )
  182. {
  183. ULONG delta;
  184. if( nowTime >= prevTime )
  185. {
  186. // Timer did not roll over
  187. delta = nowTime - prevTime;
  188. }
  189. else
  190. {
  191. // Looks like timer rolled over
  192. delta = ULONG_MAX - prevTime + nowTime;
  193. }
  194. SAFEASSERT( delta < maxDelta );
  195. return delta;
  196. }
  197. //
  198. // There is no defined InterlockedExchangeULong function in the kernel, just
  199. // InterlockedExchange. Abstract out the cast.
  200. //
  201. __forceinline ULONG
  202. InterlockedExchangeULong(
  203. IN PULONG pULong,
  204. IN ULONG NewValue
  205. )
  206. {
  207. return (ULONG)InterlockedExchange( (PLONG)pULong, NewValue );
  208. }
  209. //
  210. // Acquires an ADAPT structure checking whether the adapter is
  211. // closing or not.
  212. //
  213. __forceinline BOOLEAN
  214. BrdgAcquireAdapter(
  215. IN PADAPT pAdapt
  216. )
  217. {
  218. return BrdgIncrementWaitRef( &pAdapt->Refcount );
  219. }
  220. //
  221. // Just increments a PADAPT's refcount; assumes that the refcount is already > 0
  222. // Use when it is guaranteed that BrdgAcquireAdapter() has succeeded and
  223. // the refcount is still > 0.
  224. //
  225. __forceinline VOID
  226. BrdgReacquireAdapter(
  227. IN PADAPT pAdapt
  228. )
  229. {
  230. BrdgReincrementWaitRef( &pAdapt->Refcount );
  231. }
  232. //
  233. // It is safe to acquire an adapter inside the gAdapterListLock or the gAddressLock
  234. //
  235. __forceinline VOID
  236. BrdgAcquireAdapterInLock(
  237. IN PADAPT pAdapt
  238. )
  239. {
  240. BOOLEAN bIncremented;
  241. SAFEASSERT( pAdapt->Refcount.state == WaitRefEnabled );
  242. bIncremented = BrdgIncrementWaitRef( &pAdapt->Refcount );
  243. SAFEASSERT( bIncremented );
  244. }
  245. //
  246. // Releases a PADAPT structure (from either a BrdgAcquireAdapter() or BrdgReacquireAdapter()
  247. // call)
  248. //
  249. __forceinline VOID
  250. BrdgReleaseAdapter(
  251. IN PADAPT pAdapt
  252. )
  253. {
  254. BrdgDecrementWaitRef( &pAdapt->Refcount );
  255. }
  256. // ===========================================================================
  257. //
  258. // PROTOTYPES
  259. //
  260. // ===========================================================================
  261. VOID
  262. BrdgUnload(
  263. IN PDRIVER_OBJECT DriverObject
  264. );
  265. NDIS_STATUS
  266. BrdgDeferFunction(
  267. VOID (*pFunc)(PVOID),
  268. PVOID arg
  269. );
  270. NTSTATUS
  271. BrdgReadRegUnicode(
  272. IN PUNICODE_STRING KeyName,
  273. IN PWCHAR pValueName,
  274. OUT PWCHAR *String, // The string from the registry, freshly allocated
  275. OUT PULONG StringSize // Size of allocated memory at String
  276. );
  277. NTSTATUS
  278. BrdgReadRegDWord(
  279. IN PUNICODE_STRING KeyName,
  280. IN PWCHAR pValueName,
  281. OUT PULONG Value
  282. );
  283. NTSTATUS
  284. BrdgDispatchRequest(
  285. IN PDEVICE_OBJECT pDeviceObject,
  286. IN PIRP pIrp
  287. );
  288. NTSTATUS
  289. BrdgOpenDevice (
  290. IN LPWSTR pDeviceNameStr,
  291. OUT PDEVICE_OBJECT *ppDeviceObject,
  292. OUT HANDLE *pFileHandle,
  293. OUT PFILE_OBJECT *ppFileObject
  294. );
  295. VOID
  296. BrdgCloseDevice(
  297. IN HANDLE FileHandle,
  298. IN PFILE_OBJECT pFileObject,
  299. IN PDEVICE_OBJECT pDeviceObject
  300. );
  301. VOID
  302. BrdgShutdown(VOID);
  303. BOOLEAN
  304. BrdgIsRunningOnPersonal(VOID);
  305. // ===========================================================================
  306. //
  307. // GLOBAL VARIABLE DECLARATIONS
  308. //
  309. // ===========================================================================
  310. // NDIS handle for us as a protocol
  311. extern NDIS_HANDLE gProtHandle;
  312. // The adapter list
  313. extern PADAPT gAdapterList;
  314. // RW lock protecting the adapter list
  315. extern NDIS_RW_LOCK gAdapterListLock;
  316. // != 0 means we are shutting down
  317. extern LONG gShuttingDown;
  318. // Our driver object
  319. extern PDRIVER_OBJECT gDriverObject;
  320. // Our registry key where we can keep config information
  321. extern UNICODE_STRING gRegistryPath;
  322. // Set if the Bridge believes that tcp/ip has been loaded
  323. extern BOOLEAN g_fIsTcpIpLoaded;