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.

294 lines
18 KiB

  1. /*++
  2. Copyright (c) 2001 Microsoft Corporation
  3. Module Name:
  4. ntddnlb.h
  5. Abstract:
  6. This header describes the structures and interfaces required to interact
  7. with the NLB intermediate device driver.
  8. Revision History:
  9. --*/
  10. #ifndef __NTDDNLB_H__
  11. #define __NTDDNLB_H__
  12. #include <ndis.h>
  13. #include <ntddndis.h>
  14. #include <devioctl.h>
  15. /* This is the public callback object on which NLB will listen for connection
  16. callbacks. Currently, only TCP (protocol=6) notifications are accepted by
  17. NLB. To notify NLB when connections change state, open the callback object,
  18. and call ExNotifyCallback with the following parameters:
  19. CallbackObject - The handle to the NLB public callback object.
  20. Argument1 - A pointer to an NLBConnectionInfo block, defined below.
  21. Argument2 - NULL (This parameter is currently unused).
  22. For TCP connections, NLB needs to be notified of the following state changes:
  23. CLOSED -> SYN_RCVD: A new incoming connection is being established. This
  24. notification requires the IP interface index on which the SYN was received.
  25. NLB will create state on the appropriate interface to track this TCP connection.
  26. CLOSED -> SYN_SENT: A new outgoing connection is being established. At this
  27. time, it is unknown on which interface the connection will ultimately be
  28. established, so the IP interface index is NOT required for this notification.
  29. NLB will create temporary state to track this connection should it return
  30. on an NLB interface.
  31. SYN_SENT -> ESTAB: An outgoing connection has been established. This nofication
  32. requires the IP interface index on which the connection was ultimately established.
  33. If the interface was NLB, state will be created to track the new connection; if
  34. the interface was not NLB, the temporary state created by the SYN_SENT notification
  35. is cleaned up.
  36. SYN_RCVD -> ESTAB: An incoming connection has been established. This notification
  37. is not currently required by NLB.
  38. SYN_SENT -> CLOSED: An outgoing connection has been prematurely terminated (the
  39. connection never reached the ESTABlished state). This notification does not require
  40. the IP interface index. NLB will destroy any state created to track this connection.
  41. SYN_RCVD -> CLOSED: An outgoing connection has been prematurely terminated (the
  42. connection never reached the ESTABlished state). This notification does not require
  43. the IP interface index. NLB will destroy any state created to track this connection.
  44. ESTAB -> CLOSED: A connection has been *completely* terminated (i.e., the connection
  45. has gone through TIME_WAIT, if necessary, already). This notification does not
  46. require the IP interface index. NLB will destroy any state created to track this
  47. connection.
  48. */
  49. #define NLB_CONNECTION_CALLBACK_NAME L"\\Callback\\NLBConnectionCallback"
  50. /*
  51. This registry key instructs NLB which notification mechanism to use.
  52. When deciding what notification(s) to use for connection management,
  53. NLB checks the following, in this order:
  54. (i) NLB first looks for the EnableTCPNotification registry key under
  55. HKLM\System\CurrentControlSet\Services\WLBS\Parameters\Global\
  56. This key has three possible values that instruct NLB on which
  57. notifications to listen for. They are:
  58. 0 = Do not use any connection notifications.
  59. 1 = Use the TCP connection notifications.
  60. 2 = Use the NLB public connection notifications.
  61. (ii) If the EnableTCPNotification registry is not present, NLB defaults
  62. to using TCP notifications.
  63. Note: The name of the key is EnableTCPNotifications for legacy reasons
  64. although it controls multiple notifications covering multiple protocols.
  65. */
  66. #define NLB_CONNECTION_CALLBACK_KEY L"EnableTCPNotification"
  67. #define NLB_CONNECTION_CALLBACK_NONE 0
  68. #define NLB_CONNECTION_CALLBACK_TCP 1
  69. #define NLB_CONNECTION_CALLBACK_ALTERNATE 2
  70. #define NLB_TCPIP_PROTOCOL_TCP 6 /* IP protocol ID for TCP. */
  71. #define NLB_TCP_CLOSED 1 /* The TCP connection is/was CLOSED. */
  72. #define NLB_TCP_SYN_SENT 3 /* The TCP connection is/was in SYN_SENT. */
  73. #define NLB_TCP_SYN_RCVD 4 /* The TCP connection is/was in SYN_RCVD. */
  74. #define NLB_TCP_ESTAB 5 /* The TCP connection is/was ESTABlished. */
  75. /* Force default alignment on the callback buffers. */
  76. #pragma pack(push)
  77. #pragma pack()
  78. typedef struct NLBTCPAddressInfo {
  79. ULONG RemoteIPAddress; /* The remote (client) IP address, in network byte order. */
  80. ULONG LocalIPAddress; /* The local (server) IP address, in network byte order. */
  81. USHORT RemotePort; /* The remote (client) TCP port, in network byte order. */
  82. USHORT LocalPort; /* The local (server) TCP port, in network byte order. */
  83. } NLBTCPAddressInfo;
  84. typedef struct NLBTCPConnectionInfo {
  85. ULONG PreviousState; /* The previous state for the connection, as defined above. */
  86. ULONG CurrentState; /* The new state for the connection, as defined above. */
  87. ULONG IPInterface; /* The IP interface index on which the connection was, or is being, established. */
  88. NLBTCPAddressInfo Address; /* A pointer to a block containing the IP tuple for the connection. */
  89. } NLBTCPConnectionInfo;
  90. typedef struct NLBConnectionInfo {
  91. UCHAR Protocol; /* The protocol of the connection (currently, only TCP is supported). */
  92. union {
  93. NLBTCPConnectionInfo * pTCPInfo; /* A pointer to the TCP connection information block. */
  94. };
  95. } NLBConnectionInfo;
  96. #pragma pack(pop)
  97. #define NLB_DEVICE_NAME L"\\Device\\WLBS" /* The NLB device name for use in ZwCreateFile, for instance. */
  98. /*
  99. This IOCTL registers or de-registers a kernel-mode hook with NLB.
  100. Returns:
  101. o STATUS_SUCCESS - if the (de)registration succeeds.
  102. o STATUS_INVALID_PARAMETER - if a parameter is invalid. E.g.,
  103. - The I/O buffers are missing or the incorrect size.
  104. - The HookIdentifier does not match a known NLB hook GUID.
  105. - The HookTable entry is non-NULL, but the DeregisterCallback is NULL.
  106. - The HookTable entry is non-NULL, but all hook function pointers are NULL.
  107. - The HookTable entry is NULL, but no function is registered for this hook.
  108. o STATUS_ACCESS_DENIED - if the operation will NOT be permitted by NLB. E.g.,
  109. - The request to (de)register a hook does not come from kernel-mode.
  110. - The de-register information provided is for a hook that was registered
  111. by a different component, as identified by the RegisteringEntity.
  112. - The specified hook has already been registered by somebody (anybody).
  113. Components wishing to change their hook must first de-register it.
  114. */
  115. #define NLB_IOCTL_REGISTER_HOOK CTL_CODE(0xc0c0, 18, METHOD_BUFFERED, FILE_WRITE_ACCESS)
  116. #define NLB_HOOK_IDENTIFIER_LENGTH 39 /* 39 is sufficient for {GUID}. */
  117. #define NLB_FILTER_HOOK_INTERFACE L"{069267c4-7eee-4aff-832c-02e22e00f96f}" /* The filter interface includes hooks for influencing the NLB
  118. load-balancing decision on either the send path, receive path,
  119. or both. This hook will be called for any packet for which
  120. NLB would normally apply load-balancing policy. Components
  121. registering this interface should use an NLB_FILTER_HOOK_TABLE
  122. as the hook table in the NLB_IOCTL_REGISTER_HOOK_REQUEST. */
  123. /* The de-register callback must be specifed for all register
  124. operations. This function is called by NLB whenever a
  125. registered hook is de-registered, either gracefully by the
  126. registrar, or forcefully by NLB itself (as a result of the
  127. NLB device driver getting unloaded). */
  128. typedef VOID (* NLBHookDeregister) (PWCHAR pHookIdentifier, HANDLE RegisteringEntity, ULONG Flags);
  129. /* Bit settings for the Flags field of the de-register callback. */
  130. #define NLB_HOOK_DEREGISTER_FLAGS_FORCED 0x00000001
  131. /* This enumerated type is the feedback for all filter hooks. */
  132. typedef enum {
  133. NLB_FILTER_HOOK_PROCEED_WITH_HASH, /* Continue to load-balance normally; i.e., the hook has no specific feedback. */
  134. NLB_FILTER_HOOK_REVERSE_HASH, /* Use reverse hashing (use destination parameters, rather than source). */
  135. NLB_FILTER_HOOK_FORWARD_HASH, /* Use conventional forward hashing (use source parameters). */
  136. NLB_FILTER_HOOK_ACCEPT_UNCONDITIONALLY, /* By-pass load-balancing and accept the packet unconditionally. */
  137. NLB_FILTER_HOOK_REJECT_UNCONDITIONALLY /* By-pass load-balancing and reject the packet unconditionally. */
  138. } NLB_FILTER_HOOK_DIRECTIVE;
  139. /*
  140. Filter hooks:
  141. The adapter GUID (1st parameter) will allow the hook consumer to
  142. determine the adapter on which the packet is being sent or received.
  143. Note that the length parameters are not necesarily indicative of the
  144. actual length of the media header or payload themselves, but rather
  145. indicate how much of the buffers pointed to are contiguously
  146. accessible from the provided pointer. For instance, the payload
  147. length may just be the length of an IP header, meaning that only
  148. the IP header can be found at that pointer. However, it might
  149. be equal to the total size of the packet payload, in which case,
  150. that pointer can be used to access subsequent pieces of the
  151. packet, such as the TCP header. If the payload length provided
  152. is not sufficient to find all necessary packet information, the
  153. packet pointer can be used to traverse the packet buffers manually
  154. to try and find the information needed. However, note that the
  155. packet may not always be available (it may be NULL).
  156. */
  157. /* The send filter hook is invoked for every packet sent on any
  158. adapter to which NLB is bound for which NLB would normally
  159. apply load-balancing policy. ARPs, for instance, are not
  160. filtered by NLB, so such packets would not be indicated to
  161. this hook. */
  162. typedef NLB_FILTER_HOOK_DIRECTIVE (* NLBSendFilterHook) (
  163. const WCHAR * pAdapter, /* The GUID of the adapter on which the packet is being sent. */
  164. const NDIS_PACKET * pPacket, /* A pointer to the NDIS packet, which CAN be NULL if not available. */
  165. const UCHAR * pMediaHeader, /* A pointer to the media header (ethernet, since NLB supports only ethernet). */
  166. ULONG cMediaHeaderLength, /* The length of contiguous memory accessible from the media header pointer. */
  167. const UCHAR * pPayload, /* A pointer to the payload of the packet. */
  168. ULONG cPayloadLength, /* The length of contiguous memory accesible from the payload pointer. */
  169. ULONG Flags); /* Hook-related flags including whether or not the cluster is stopped. */
  170. /* The receive filter hook is invoked for every packet received
  171. on any adapter to which NLB is bound for which NLB would
  172. normally apply load-balancing policy. Some protocols, such
  173. as ARP, or NLB-specific packets not normally seen by the
  174. protocol(s) bound to NLB (heartbeats, remote control requests)
  175. are not filtered by NLB and will not be indicated to the hook. */
  176. typedef NLB_FILTER_HOOK_DIRECTIVE (* NLBReceiveFilterHook) (
  177. const WCHAR * pAdapter, /* The GUID of the adapter on which the packet was received. */
  178. const NDIS_PACKET * pPacket, /* A pointer to the NDIS packet, which CAN be NULL if not available. */
  179. const UCHAR * pMediaHeader, /* A pointer to the media header (ethernet, since NLB supports only ethernet). */
  180. ULONG cMediaHeaderLength, /* The length of contiguous memory accessible from the media header pointer. */
  181. const UCHAR * pPayload, /* A pointer to the payload of the packet. */
  182. ULONG cPayloadLength, /* The length of contiguous memory accesible from the payload pointer. */
  183. ULONG Flags); /* Hook-related flags including whether or not the cluster is stopped. */
  184. /* The query filter hook is invoked in cases where the NLB driver
  185. needs to invoke its hashing algorithm and therefore needs to
  186. know whether or not the hook will influence the way in which
  187. manner NLB performs the hash, if at all. */
  188. typedef NLB_FILTER_HOOK_DIRECTIVE (* NLBQueryFilterHook) (
  189. const WCHAR * pAdapter, /* The GUID of the adapter on which the packet was received. */
  190. ULONG ServerIPAddress, /* The server IP address of the "packet" in NETWORK byte order. */
  191. USHORT ServerPort, /* The server port of the "packet" (if applicable to the Protocol) in HOST byte order. */
  192. ULONG ClientIPAddress, /* The client IP address of the "packet" in NETWORK byte order. */
  193. USHORT ClientPort, /* The client port of the "packet" (if applicable to the Protocol) in HOST byte order. */
  194. UCHAR Protocol, /* The IP protocol of the "packet"; TCP, UDP, ICMP, GRE, etc. */
  195. BOOLEAN bReceiveContext, /* A boolean to indicate whether the packet is being processed in send or receive context. */
  196. ULONG Flags); /* Hook-related flags including whether or not the cluster is stopped. */
  197. /* Bit settings for the Flags field of the filter hooks. */
  198. #define NLB_FILTER_HOOK_FLAGS_STOPPED 0x00000001
  199. #define NLB_FILTER_HOOK_FLAGS_DRAINING 0x00000002
  200. /* Force default alignment on the IOCTL buffers. */
  201. #pragma pack(push)
  202. #pragma pack()
  203. /* This table contains function pointers to register or de-register
  204. a packet filter hook. To register a hook, set the appropriate
  205. function pointer. Those not being specified (for instance if
  206. you want to register a receive hook, but not a send hook) should
  207. be set to NULL. The QueryHook should ONLY be specified if in
  208. conjunction with setting either the send or receive hook; i.e.
  209. a user may not ONLY register the QueryHook. Further, if regis-
  210. tering a send or receive hook (or both), the QueryHook MUST be
  211. provided in order for NLB to query the hook response for cases
  212. where a hashing decision is needed, but we are not in the context
  213. of sending or receiving a packet; most notably, in a connection
  214. up or down notification from IPSec or TCP. */
  215. typedef struct {
  216. NLBSendFilterHook SendHook;
  217. NLBQueryFilterHook QueryHook;
  218. NLBReceiveFilterHook ReceiveHook;
  219. } NLB_FILTER_HOOK_TABLE, * PNLB_FILTER_HOOK_TABLE;
  220. /* This is the input buffer for the hook (de)register IOCTL. There is
  221. no corresponding output buffer. This structure identifies the hook
  222. interface being (de)registered, the entity registering the hook and
  223. all appropriate function pointers (callbacks). Note that hooks are
  224. registered in groups, called interfaces, which prevents different
  225. related hooks from being owned by different entities (for example,
  226. it prevents one entity owned the send hook, but another owned the
  227. receive hook). Interfaces are identified by a GUID, and to set any
  228. hook in the interface requires ownership of the entire interface -
  229. even if not all hooks in the interface are being specified. The hook
  230. table should be a pointer to a hook table of the type required by the
  231. specified hook identifier. To de-register a hook, set the hook table
  232. pointer to NULL.
  233. Note: The HookTable pointer does NOT need to be valid following the
  234. completion of the IOCTL. That is, this pointer is only referenced
  235. within the context of the IOCTL.
  236. */
  237. typedef struct {
  238. WCHAR HookIdentifier[NLB_HOOK_IDENTIFIER_LENGTH]; /* The GUID identifying the hook interface being registered. */
  239. HANDLE RegisteringEntity; /* The open file handle on the NLB driver, which uniquely identifies the registrar. */
  240. PVOID HookTable; /* A pointer to the appropriate hook table containing the hook function pointers. */
  241. NLBHookDeregister DeregisterCallback; /* The de-register callback function, which MUST be non-NULL if the operation is a registration. */
  242. } NLB_IOCTL_REGISTER_HOOK_REQUEST, * PNLB_IOCTL_REGISTER_HOOK_REQUEST;
  243. #pragma pack(pop)
  244. #endif