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

/*++
Copyright (c) 2001 Microsoft Corporation
Module Name:
ntddnlb.h
Abstract:
This header describes the structures and interfaces required to interact
with the NLB intermediate device driver.
Revision History:
--*/
#ifndef __NTDDNLB_H__
#define __NTDDNLB_H__
#include <ndis.h>
#include <ntddndis.h>
#include <devioctl.h>
/* This is the public callback object on which NLB will listen for connection
callbacks. Currently, only TCP (protocol=6) notifications are accepted by
NLB. To notify NLB when connections change state, open the callback object,
and call ExNotifyCallback with the following parameters:
CallbackObject - The handle to the NLB public callback object.
Argument1 - A pointer to an NLBConnectionInfo block, defined below.
Argument2 - NULL (This parameter is currently unused).
For TCP connections, NLB needs to be notified of the following state changes:
CLOSED -> SYN_RCVD: A new incoming connection is being established. This
notification requires the IP interface index on which the SYN was received.
NLB will create state on the appropriate interface to track this TCP connection.
CLOSED -> SYN_SENT: A new outgoing connection is being established. At this
time, it is unknown on which interface the connection will ultimately be
established, so the IP interface index is NOT required for this notification.
NLB will create temporary state to track this connection should it return
on an NLB interface.
SYN_SENT -> ESTAB: An outgoing connection has been established. This nofication
requires the IP interface index on which the connection was ultimately established.
If the interface was NLB, state will be created to track the new connection; if
the interface was not NLB, the temporary state created by the SYN_SENT notification
is cleaned up.
SYN_RCVD -> ESTAB: An incoming connection has been established. This notification
is not currently required by NLB.
SYN_SENT -> CLOSED: An outgoing connection has been prematurely terminated (the
connection never reached the ESTABlished state). This notification does not require
the IP interface index. NLB will destroy any state created to track this connection.
SYN_RCVD -> CLOSED: An outgoing connection has been prematurely terminated (the
connection never reached the ESTABlished state). This notification does not require
the IP interface index. NLB will destroy any state created to track this connection.
ESTAB -> CLOSED: A connection has been *completely* terminated (i.e., the connection
has gone through TIME_WAIT, if necessary, already). This notification does not
require the IP interface index. NLB will destroy any state created to track this
connection.
*/
#define NLB_CONNECTION_CALLBACK_NAME L"\\Callback\\NLBConnectionCallback"
/*
This registry key instructs NLB which notification mechanism to use.
When deciding what notification(s) to use for connection management,
NLB checks the following, in this order:
(i) NLB first looks for the EnableTCPNotification registry key under
HKLM\System\CurrentControlSet\Services\WLBS\Parameters\Global\
This key has three possible values that instruct NLB on which
notifications to listen for. They are:
0 = Do not use any connection notifications.
1 = Use the TCP connection notifications.
2 = Use the NLB public connection notifications.
(ii) If the EnableTCPNotification registry is not present, NLB defaults
to using TCP notifications.
Note: The name of the key is EnableTCPNotifications for legacy reasons
although it controls multiple notifications covering multiple protocols.
*/
#define NLB_CONNECTION_CALLBACK_KEY L"EnableTCPNotification"
#define NLB_CONNECTION_CALLBACK_NONE 0
#define NLB_CONNECTION_CALLBACK_TCP 1
#define NLB_CONNECTION_CALLBACK_ALTERNATE 2
#define NLB_TCPIP_PROTOCOL_TCP 6 /* IP protocol ID for TCP. */
#define NLB_TCP_CLOSED 1 /* The TCP connection is/was CLOSED. */
#define NLB_TCP_SYN_SENT 3 /* The TCP connection is/was in SYN_SENT. */
#define NLB_TCP_SYN_RCVD 4 /* The TCP connection is/was in SYN_RCVD. */
#define NLB_TCP_ESTAB 5 /* The TCP connection is/was ESTABlished. */
/* Force default alignment on the callback buffers. */
#pragma pack(push)
#pragma pack()
typedef struct NLBTCPAddressInfo {
ULONG RemoteIPAddress; /* The remote (client) IP address, in network byte order. */
ULONG LocalIPAddress; /* The local (server) IP address, in network byte order. */
USHORT RemotePort; /* The remote (client) TCP port, in network byte order. */
USHORT LocalPort; /* The local (server) TCP port, in network byte order. */
} NLBTCPAddressInfo;
typedef struct NLBTCPConnectionInfo {
ULONG PreviousState; /* The previous state for the connection, as defined above. */
ULONG CurrentState; /* The new state for the connection, as defined above. */
ULONG IPInterface; /* The IP interface index on which the connection was, or is being, established. */
NLBTCPAddressInfo Address; /* A pointer to a block containing the IP tuple for the connection. */
} NLBTCPConnectionInfo;
typedef struct NLBConnectionInfo {
UCHAR Protocol; /* The protocol of the connection (currently, only TCP is supported). */
union {
NLBTCPConnectionInfo * pTCPInfo; /* A pointer to the TCP connection information block. */
};
} NLBConnectionInfo;
#pragma pack(pop)
#define NLB_DEVICE_NAME L"\\Device\\WLBS" /* The NLB device name for use in ZwCreateFile, for instance. */
/*
This IOCTL registers or de-registers a kernel-mode hook with NLB.
Returns:
o STATUS_SUCCESS - if the (de)registration succeeds.
o STATUS_INVALID_PARAMETER - if a parameter is invalid. E.g.,
- The I/O buffers are missing or the incorrect size.
- The HookIdentifier does not match a known NLB hook GUID.
- The HookTable entry is non-NULL, but the DeregisterCallback is NULL.
- The HookTable entry is non-NULL, but all hook function pointers are NULL.
- The HookTable entry is NULL, but no function is registered for this hook.
o STATUS_ACCESS_DENIED - if the operation will NOT be permitted by NLB. E.g.,
- The request to (de)register a hook does not come from kernel-mode.
- The de-register information provided is for a hook that was registered
by a different component, as identified by the RegisteringEntity.
- The specified hook has already been registered by somebody (anybody).
Components wishing to change their hook must first de-register it.
*/
#define NLB_IOCTL_REGISTER_HOOK CTL_CODE(0xc0c0, 18, METHOD_BUFFERED, FILE_WRITE_ACCESS)
#define NLB_HOOK_IDENTIFIER_LENGTH 39 /* 39 is sufficient for {GUID}. */
#define NLB_FILTER_HOOK_INTERFACE L"{069267c4-7eee-4aff-832c-02e22e00f96f}" /* The filter interface includes hooks for influencing the NLB
load-balancing decision on either the send path, receive path,
or both. This hook will be called for any packet for which
NLB would normally apply load-balancing policy. Components
registering this interface should use an NLB_FILTER_HOOK_TABLE
as the hook table in the NLB_IOCTL_REGISTER_HOOK_REQUEST. */
/* The de-register callback must be specifed for all register
operations. This function is called by NLB whenever a
registered hook is de-registered, either gracefully by the
registrar, or forcefully by NLB itself (as a result of the
NLB device driver getting unloaded). */
typedef VOID (* NLBHookDeregister) (PWCHAR pHookIdentifier, HANDLE RegisteringEntity, ULONG Flags);
/* Bit settings for the Flags field of the de-register callback. */
#define NLB_HOOK_DEREGISTER_FLAGS_FORCED 0x00000001
/* This enumerated type is the feedback for all filter hooks. */
typedef enum {
NLB_FILTER_HOOK_PROCEED_WITH_HASH, /* Continue to load-balance normally; i.e., the hook has no specific feedback. */
NLB_FILTER_HOOK_REVERSE_HASH, /* Use reverse hashing (use destination parameters, rather than source). */
NLB_FILTER_HOOK_FORWARD_HASH, /* Use conventional forward hashing (use source parameters). */
NLB_FILTER_HOOK_ACCEPT_UNCONDITIONALLY, /* By-pass load-balancing and accept the packet unconditionally. */
NLB_FILTER_HOOK_REJECT_UNCONDITIONALLY /* By-pass load-balancing and reject the packet unconditionally. */
} NLB_FILTER_HOOK_DIRECTIVE;
/*
Filter hooks:
The adapter GUID (1st parameter) will allow the hook consumer to
determine the adapter on which the packet is being sent or received.
Note that the length parameters are not necesarily indicative of the
actual length of the media header or payload themselves, but rather
indicate how much of the buffers pointed to are contiguously
accessible from the provided pointer. For instance, the payload
length may just be the length of an IP header, meaning that only
the IP header can be found at that pointer. However, it might
be equal to the total size of the packet payload, in which case,
that pointer can be used to access subsequent pieces of the
packet, such as the TCP header. If the payload length provided
is not sufficient to find all necessary packet information, the
packet pointer can be used to traverse the packet buffers manually
to try and find the information needed. However, note that the
packet may not always be available (it may be NULL).
*/
/* The send filter hook is invoked for every packet sent on any
adapter to which NLB is bound for which NLB would normally
apply load-balancing policy. ARPs, for instance, are not
filtered by NLB, so such packets would not be indicated to
this hook. */
typedef NLB_FILTER_HOOK_DIRECTIVE (* NLBSendFilterHook) (
const WCHAR * pAdapter, /* The GUID of the adapter on which the packet is being sent. */
const NDIS_PACKET * pPacket, /* A pointer to the NDIS packet, which CAN be NULL if not available. */
const UCHAR * pMediaHeader, /* A pointer to the media header (ethernet, since NLB supports only ethernet). */
ULONG cMediaHeaderLength, /* The length of contiguous memory accessible from the media header pointer. */
const UCHAR * pPayload, /* A pointer to the payload of the packet. */
ULONG cPayloadLength, /* The length of contiguous memory accesible from the payload pointer. */
ULONG Flags); /* Hook-related flags including whether or not the cluster is stopped. */
/* The receive filter hook is invoked for every packet received
on any adapter to which NLB is bound for which NLB would
normally apply load-balancing policy. Some protocols, such
as ARP, or NLB-specific packets not normally seen by the
protocol(s) bound to NLB (heartbeats, remote control requests)
are not filtered by NLB and will not be indicated to the hook. */
typedef NLB_FILTER_HOOK_DIRECTIVE (* NLBReceiveFilterHook) (
const WCHAR * pAdapter, /* The GUID of the adapter on which the packet was received. */
const NDIS_PACKET * pPacket, /* A pointer to the NDIS packet, which CAN be NULL if not available. */
const UCHAR * pMediaHeader, /* A pointer to the media header (ethernet, since NLB supports only ethernet). */
ULONG cMediaHeaderLength, /* The length of contiguous memory accessible from the media header pointer. */
const UCHAR * pPayload, /* A pointer to the payload of the packet. */
ULONG cPayloadLength, /* The length of contiguous memory accesible from the payload pointer. */
ULONG Flags); /* Hook-related flags including whether or not the cluster is stopped. */
/* The query filter hook is invoked in cases where the NLB driver
needs to invoke its hashing algorithm and therefore needs to
know whether or not the hook will influence the way in which
manner NLB performs the hash, if at all. */
typedef NLB_FILTER_HOOK_DIRECTIVE (* NLBQueryFilterHook) (
const WCHAR * pAdapter, /* The GUID of the adapter on which the packet was received. */
ULONG ServerIPAddress, /* The server IP address of the "packet" in NETWORK byte order. */
USHORT ServerPort, /* The server port of the "packet" (if applicable to the Protocol) in HOST byte order. */
ULONG ClientIPAddress, /* The client IP address of the "packet" in NETWORK byte order. */
USHORT ClientPort, /* The client port of the "packet" (if applicable to the Protocol) in HOST byte order. */
UCHAR Protocol, /* The IP protocol of the "packet"; TCP, UDP, ICMP, GRE, etc. */
BOOLEAN bReceiveContext, /* A boolean to indicate whether the packet is being processed in send or receive context. */
ULONG Flags); /* Hook-related flags including whether or not the cluster is stopped. */
/* Bit settings for the Flags field of the filter hooks. */
#define NLB_FILTER_HOOK_FLAGS_STOPPED 0x00000001
#define NLB_FILTER_HOOK_FLAGS_DRAINING 0x00000002
/* Force default alignment on the IOCTL buffers. */
#pragma pack(push)
#pragma pack()
/* This table contains function pointers to register or de-register
a packet filter hook. To register a hook, set the appropriate
function pointer. Those not being specified (for instance if
you want to register a receive hook, but not a send hook) should
be set to NULL. The QueryHook should ONLY be specified if in
conjunction with setting either the send or receive hook; i.e.
a user may not ONLY register the QueryHook. Further, if regis-
tering a send or receive hook (or both), the QueryHook MUST be
provided in order for NLB to query the hook response for cases
where a hashing decision is needed, but we are not in the context
of sending or receiving a packet; most notably, in a connection
up or down notification from IPSec or TCP. */
typedef struct {
NLBSendFilterHook SendHook;
NLBQueryFilterHook QueryHook;
NLBReceiveFilterHook ReceiveHook;
} NLB_FILTER_HOOK_TABLE, * PNLB_FILTER_HOOK_TABLE;
/* This is the input buffer for the hook (de)register IOCTL. There is
no corresponding output buffer. This structure identifies the hook
interface being (de)registered, the entity registering the hook and
all appropriate function pointers (callbacks). Note that hooks are
registered in groups, called interfaces, which prevents different
related hooks from being owned by different entities (for example,
it prevents one entity owned the send hook, but another owned the
receive hook). Interfaces are identified by a GUID, and to set any
hook in the interface requires ownership of the entire interface -
even if not all hooks in the interface are being specified. The hook
table should be a pointer to a hook table of the type required by the
specified hook identifier. To de-register a hook, set the hook table
pointer to NULL.
Note: The HookTable pointer does NOT need to be valid following the
completion of the IOCTL. That is, this pointer is only referenced
within the context of the IOCTL.
*/
typedef struct {
WCHAR HookIdentifier[NLB_HOOK_IDENTIFIER_LENGTH]; /* The GUID identifying the hook interface being registered. */
HANDLE RegisteringEntity; /* The open file handle on the NLB driver, which uniquely identifies the registrar. */
PVOID HookTable; /* A pointer to the appropriate hook table containing the hook function pointers. */
NLBHookDeregister DeregisterCallback; /* The de-register callback function, which MUST be non-NULL if the operation is a registration. */
} NLB_IOCTL_REGISTER_HOOK_REQUEST, * PNLB_IOCTL_REGISTER_HOOK_REQUEST;
#pragma pack(pop)
#endif