Update Redirector

This commit is contained in:
Netch
2021-07-19 10:50:14 +08:00
parent 90b9547087
commit 727fe27b06
20 changed files with 1812 additions and 64 deletions

415
Redirector/include/nfapi.h Normal file
View File

@@ -0,0 +1,415 @@
//
// NetFilterSDK
// Copyright (C) Vitaly Sidorov
// All rights reserved.
//
// This file is a part of the NetFilter SDK.
// The code and information is provided "as-is" without
// warranty of any kind, either expressed or implied.
//
#ifndef _NFAPI_H
#define _NFAPI_H
#include <nfevents.h>
#define _NFAPI_STATIC_LIB
#ifdef _NFAPI_STATIC_LIB
#define NFAPI_API
#else
#ifdef NFAPI_EXPORTS
#define NFAPI_API __declspec(dllexport)
#else
#define NFAPI_API __declspec(dllimport)
#endif
#endif
// Flags for NF_UDP_OPTIONS.flags
#define TDI_RECEIVE_BROADCAST 0x00000004 // received TSDU was broadcast.
#define TDI_RECEIVE_MULTICAST 0x00000008 // received TSDU was multicast.
#define TDI_RECEIVE_PARTIAL 0x00000010 // received TSDU is not fully presented.
#define TDI_RECEIVE_NORMAL 0x00000020 // received TSDU is normal data
#define TDI_RECEIVE_EXPEDITED 0x00000040 // received TSDU is expedited data
#define TDI_RECEIVE_PEEK 0x00000080 // received TSDU is not released
#define TDI_RECEIVE_NO_RESPONSE_EXP 0x00000100 // HINT: no back-traffic expected
#define TDI_RECEIVE_COPY_LOOKAHEAD 0x00000200 // for kernel-mode indications
#define TDI_RECEIVE_ENTIRE_MESSAGE 0x00000400 // opposite of RECEIVE_PARTIAL
// (for kernel-mode indications)
#define TDI_RECEIVE_AT_DISPATCH_LEVEL 0x00000800 // receive indication called
// at dispatch level
#define TDI_RECEIVE_CONTROL_INFO 0x00001000 // Control info is being passed up.
#define TDI_RECEIVE_FORCE_INDICATION 0x00002000 // reindicate rejected data.
#define TDI_RECEIVE_NO_PUSH 0x00004000 // complete only when full.
typedef enum _NF_FLAGS
{
NFF_NONE = 0,
NFF_DONT_DISABLE_TEREDO = 1,
NFF_DONT_DISABLE_TCP_OFFLOADING = 2,
NFF_DISABLE_AUTO_REGISTER = 4,
NFF_DISABLE_AUTO_START = 8,
} NF_FLAGS;
#ifndef _C_API
namespace nfapi
{
#define NFAPI_NS nfapi::
#define NFAPI_CC
#else // _C_API
#define NFAPI_CC __cdecl
#define NFAPI_NS
#ifdef __cplusplus
extern "C"
{
#endif
#endif // _C_API
/**
* Initializes the internal data structures and starts the filtering thread.
* @param driverName The name of hooking driver, without ".sys" extension.
* @param pHandler Pointer to event handling object
**/
NFAPI_API NF_STATUS NFAPI_CC
nf_init(const char * driverName, NF_EventHandler * pHandler);
/**
* Stops the filtering thread, breaks all filtered connections and closes
* a connection with the hooking driver.
**/
NFAPI_API void NFAPI_CC
nf_free();
/**
* Registers and starts a driver with specified name (without ".sys" extension)
* @param driverName
**/
NFAPI_API NF_STATUS NFAPI_CC
nf_registerDriver(const char * driverName);
/**
* Registers and starts a driver with specified name (without ".sys" extension) and path to driver folder
* @param driverName
* @param driverPath
**/
NFAPI_API NF_STATUS NFAPI_CC
nf_registerDriverEx(const char * driverName, const char * driverPath);
/**
* Unregisters a driver with specified name (without ".sys" extension)
* @param driverName
**/
NFAPI_API NF_STATUS NFAPI_CC
nf_unRegisterDriver(const char * driverName);
//
// TCP control routines
//
/**
* Suspends or resumes indicating of sends and receives for specified connection.
* @param id Connection identifier
* @param suspended TRUE(1) for suspend, FALSE(0) for resume
**/
NFAPI_API NF_STATUS NFAPI_CC
nf_tcpSetConnectionState(ENDPOINT_ID id, int suspended);
/**
* Sends the buffer to remote server via specified connection.
* @param id Connection identifier
* @param buf Pointer to data buffer
* @param len Buffer length
**/
NFAPI_API NF_STATUS NFAPI_CC
nf_tcpPostSend(ENDPOINT_ID id, const char * buf, int len);
/**
* Indicates the buffer to local process via specified connection.
* @param id Unique connection identifier
* @param buf Pointer to data buffer
* @param len Buffer length
**/
NFAPI_API NF_STATUS NFAPI_CC
nf_tcpPostReceive(ENDPOINT_ID id, const char * buf, int len);
/**
* Breaks the connection with given id.
* @param id Connection identifier
**/
NFAPI_API NF_STATUS NFAPI_CC
nf_tcpClose(ENDPOINT_ID id);
/**
* Sets the timeout for TCP connections and returns old timeout.
* @param timeout Timeout value in milliseconds. Specify zero value to disable timeouts.
*/
NFAPI_API unsigned long NFAPI_CC
nf_setTCPTimeout(unsigned long timeout);
/**
* Disables indicating TCP packets to user mode for the specified endpoint
* @param id Socket identifier
*/
NFAPI_API NF_STATUS NFAPI_CC
nf_tcpDisableFiltering(ENDPOINT_ID id);
//
// UDP control routines
//
/**
* Suspends or resumes indicating of sends and receives for specified socket.
* @param id Socket identifier
* @param suspended TRUE(1) for suspend, FALSE(0) for resume
**/
NFAPI_API NF_STATUS NFAPI_CC
nf_udpSetConnectionState(ENDPOINT_ID id, int suspended);
/**
* Sends the buffer to remote server via specified socket.
* @param id Socket identifier
* @param options UDP options
* @param remoteAddress Destination address
* @param buf Pointer to data buffer
* @param len Buffer length
**/
NFAPI_API NF_STATUS NFAPI_CC
nf_udpPostSend(ENDPOINT_ID id, const unsigned char * remoteAddress, const char * buf, int len, PNF_UDP_OPTIONS options);
/**
* Indicates the buffer to local process via specified socket.
* @param id Unique connection identifier
* @param options UDP options
* @param remoteAddress Source address
* @param buf Pointer to data buffer
* @param len Buffer length
**/
NFAPI_API NF_STATUS NFAPI_CC
nf_udpPostReceive(ENDPOINT_ID id, const unsigned char * remoteAddress, const char * buf, int len, PNF_UDP_OPTIONS options);
/**
* Disables indicating UDP packets to user mode for the specified endpoint
* @param id Socket identifier
*/
NFAPI_API NF_STATUS NFAPI_CC
nf_udpDisableFiltering(ENDPOINT_ID id);
/**
* Sends a packet to remote IP
* @param buf Pointer to IP packet
* @param len Buffer length
* @param options IP options
**/
NFAPI_API NF_STATUS NFAPI_CC
nf_ipPostSend(const char * buf, int len, PNF_IP_PACKET_OPTIONS options);
/**
* Indicates a packet to TCP/IP stack
* @param buf Pointer to IP packet
* @param len Buffer length
* @param options IP options
**/
NFAPI_API NF_STATUS NFAPI_CC
nf_ipPostReceive(const char * buf, int len, PNF_IP_PACKET_OPTIONS options);
//
// Filtering rules
//
/**
* Add a rule to the head of rules list in driver.
* @param pRule See <tt>NF_RULE</tt>
* @param toHead TRUE (1) - add rule to list head, FALSE (0) - add rule to tail
**/
NFAPI_API NF_STATUS NFAPI_CC
nf_addRule(PNF_RULE pRule, int toHead);
/**
* Removes all rules from driver.
**/
NFAPI_API NF_STATUS NFAPI_CC
nf_deleteRules();
/**
* Replace the rules in driver with the specified array.
* @param pRules Array of <tt>NF_RULE</tt> structures
* @param count Number of items in array
**/
NFAPI_API NF_STATUS NFAPI_CC
nf_setRules(PNF_RULE pRules, int count);
/**
* Add a rule to the head of rules list in driver.
* @param pRule See <tt>NF_RULE_EX</tt>
* @param toHead TRUE (1) - add rule to list head, FALSE (0) - add rule to tail
**/
NFAPI_API NF_STATUS NFAPI_CC
nf_addRuleEx(PNF_RULE_EX pRule, int toHead);
/**
* Replace the rules in driver with the specified array.
* @param pRules Array of <tt>NF_RULE_EX</tt> structures
* @param count Number of items in array
**/
NFAPI_API NF_STATUS NFAPI_CC
nf_setRulesEx(PNF_RULE_EX pRules, int count);
//
// Debug routine
//
NFAPI_API unsigned long NFAPI_CC
nf_getConnCount();
NFAPI_API NF_STATUS NFAPI_CC
nf_tcpSetSockOpt(ENDPOINT_ID id, int optname, const char* optval, int optlen);
/**
* Returns the process name for given process id
* @param processId Process identifier
* @param buf Buffer
* @param len Buffer length
**/
NFAPI_API BOOL NFAPI_CC
nf_getProcessNameA(DWORD processId, char * buf, DWORD len);
NFAPI_API BOOL NFAPI_CC
nf_getProcessNameW(DWORD processId, wchar_t * buf, DWORD len);
#ifdef UNICODE
#define nf_getProcessName nf_getProcessNameW
#else
#define nf_getProcessName nf_getProcessNameA
#endif
NFAPI_API BOOL NFAPI_CC
nf_getProcessNameFromKernel(DWORD processId, wchar_t * buf, DWORD len);
/**
* Allows the current process to see the names of all processes in system
**/
NFAPI_API void NFAPI_CC
nf_adjustProcessPriviledges();
/**
* Returns TRUE if the specified process acts as a local proxy, accepting the redirected TCP connections.
**/
NFAPI_API BOOL NFAPI_CC
nf_tcpIsProxy(DWORD processId);
/**
* Set the number of worker threads and initialization flags.
* The function should be called before nf_init.
* By default nThreads = 1 and flags = 0
* @param nThreads Number of worker threads for NF_EventHandler events
* @param flags A combination of flags from <tt>NF_FLAGS</tt>
**/
NFAPI_API void NFAPI_CC
nf_setOptions(DWORD nThreads, DWORD flags);
/**
* Complete TCP connect request pended using flag NF_PEND_CONNECT_REQUEST.
**/
NFAPI_API NF_STATUS NFAPI_CC
nf_completeTCPConnectRequest(ENDPOINT_ID id, PNF_TCP_CONN_INFO pConnInfo);
/**
* Complete UDP connect request pended using flag NF_PEND_CONNECT_REQUEST.
**/
NFAPI_API NF_STATUS NFAPI_CC
nf_completeUDPConnectRequest(ENDPOINT_ID id, PNF_UDP_CONN_REQUEST pConnInfo);
/**
* Returns in pConnInfo the properties of TCP connection with specified id.
**/
NFAPI_API NF_STATUS NFAPI_CC
nf_getTCPConnInfo(ENDPOINT_ID id, PNF_TCP_CONN_INFO pConnInfo);
/**
* Returns in pConnInfo the properties of UDP socket with specified id.
**/
NFAPI_API NF_STATUS NFAPI_CC
nf_getUDPConnInfo(ENDPOINT_ID id, PNF_UDP_CONN_INFO pConnInfo);
/**
* Set the event handler for IP filtering events
*/
NFAPI_API void NFAPI_CC
nf_setIPEventHandler(NF_IPEventHandler * pHandler);
/**
* Add flow control context
*/
NFAPI_API NF_STATUS NFAPI_CC
nf_addFlowCtl(PNF_FLOWCTL_DATA pData, unsigned int * pFcHandle);
/**
* Delete flow control context
*/
NFAPI_API NF_STATUS NFAPI_CC
nf_deleteFlowCtl(unsigned int fcHandle);
/**
* Associate flow control context with TCP connection
*/
NFAPI_API NF_STATUS NFAPI_CC
nf_setTCPFlowCtl(ENDPOINT_ID id, unsigned int fcHandle);
/**
* Associate flow control context with UDP socket
*/
NFAPI_API NF_STATUS NFAPI_CC
nf_setUDPFlowCtl(ENDPOINT_ID id, unsigned int fcHandle);
/**
* Modify flow control context limits
*/
NFAPI_API NF_STATUS NFAPI_CC
nf_modifyFlowCtl(unsigned int fcHandle, PNF_FLOWCTL_DATA pData);
/**
* Get flow control context statistics as the numbers of in/out bytes
*/
NFAPI_API NF_STATUS NFAPI_CC
nf_getFlowCtlStat(unsigned int fcHandle, PNF_FLOWCTL_STAT pStat);
/**
* Get TCP connection statistics as the numbers of in/out bytes.
* The function can be called only from tcpClosed handler!
*/
NFAPI_API NF_STATUS NFAPI_CC
nf_getTCPStat(ENDPOINT_ID id, PNF_FLOWCTL_STAT pStat);
/**
* Get UDP socket statistics as the numbers of in/out bytes.
* The function can be called only from udpClosed handler!
*/
NFAPI_API NF_STATUS NFAPI_CC
nf_getUDPStat(ENDPOINT_ID id, PNF_FLOWCTL_STAT pStat);
/**
* Add binding rule to driver
*/
NFAPI_API NF_STATUS NFAPI_CC
nf_addBindingRule(PNF_BINDING_RULE pRule, int toHead);
/**
* Delete all binding rules from driver
*/
NFAPI_API NF_STATUS NFAPI_CC
nf_deleteBindingRules();
/**
* Returns the type of attached driver (DT_WFP, DT_TDI or DT_UNKNOWN)
*/
NFAPI_API unsigned long NFAPI_CC
nf_getDriverType();
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,449 @@
//
// NetFilterSDK
// Copyright (C) Vitaly Sidorov
// All rights reserved.
//
// This file is a part of the NetFilter SDK.
// The code and information is provided "as-is" without
// warranty of any kind, either expressed or implied.
//
#ifndef _NFDRIVER_H
#define _NFDRIVER_H
#define NF_TCP_PACKET_BUF_SIZE 8192
#define NF_UDP_PACKET_BUF_SIZE 2 * 65536
/**
* IO data codes
**/
typedef enum _NF_DATA_CODE
{
NF_TCP_CONNECTED, // TCP connection established
NF_TCP_CLOSED, // TCP connection closed
NF_TCP_RECEIVE, // TCP data packet received
NF_TCP_SEND, // TCP data packet sent
NF_TCP_CAN_RECEIVE, // The buffer for TCP receives is empty
NF_TCP_CAN_SEND, // The buffer for TCP sends is empty
NF_TCP_REQ_SUSPEND, // Requests suspending TCP connection
NF_TCP_REQ_RESUME, // Requests resuming TCP connection
NF_UDP_CREATED, // UDP socket created
NF_UDP_CLOSED, // UDP socket closed
NF_UDP_RECEIVE, // UDP data packet received
NF_UDP_SEND, // UDP data packet sent
NF_UDP_CAN_RECEIVE, // The buffer for UDP receives is empty
NF_UDP_CAN_SEND, // The buffer for UDP sends is empty
NF_UDP_REQ_SUSPEND, // Requests suspending UDP address
NF_UDP_REQ_RESUME, // Requests resuming UDP address
NF_REQ_ADD_HEAD_RULE, // Add a rule to list head
NF_REQ_ADD_TAIL_RULE, // Add a rule to list tail
NF_REQ_DELETE_RULES, // Remove all rules
NF_TCP_CONNECT_REQUEST, // Outgoing TCP connect request
NF_UDP_CONNECT_REQUEST, // Outgoing UDP connect request
NF_TCP_DISABLE_USER_MODE_FILTERING, // Disable indicating TCP packets to user mode for a connection
NF_UDP_DISABLE_USER_MODE_FILTERING, // Disable indicating UDP packets to user mode for a socket
NF_REQ_SET_TCP_OPT, // Set TCP socket options
NF_REQ_IS_PROXY, // Check if process with specified id is local proxy
NF_TCP_REINJECT, // Reinject pended packets
NF_TCP_REMOVE_CLOSED, // Delete TCP context for the closed connection
NF_TCP_DEFERRED_DISCONNECT, // Delete TCP context for the closed connection
NF_IP_RECEIVE, // IP data packet received
NF_IP_SEND, // IP data packet sent
NF_TCP_RECEIVE_PUSH, // Push all TCP data packets
} NF_DATA_CODE;
typedef enum _NF_DIRECTION
{
NF_D_IN = 1, // Incoming TCP connection or UDP packet
NF_D_OUT = 2, // Outgoing TCP connection or UDP packet
NF_D_BOTH = 3 // Any direction
} NF_DIRECTION;
typedef enum _NF_FILTERING_FLAG
{
NF_ALLOW = 0, // Allow the activity without filtering transmitted packets
NF_BLOCK = 1, // Block the activity
NF_FILTER = 2, // Filter the transmitted packets
NF_SUSPENDED = 4, // Suspend receives from server and sends from client
NF_OFFLINE = 8, // Emulate establishing a TCP connection with remote server
NF_INDICATE_CONNECT_REQUESTS = 16, // Indicate outgoing connect requests to API
NF_DISABLE_REDIRECT_PROTECTION = 32, // Disable blocking indicating connect requests for outgoing connections of local proxies
NF_PEND_CONNECT_REQUEST = 64, // Pend outgoing connect request to complete it later using nf_complete(TCP|UDP)ConnectRequest
NF_FILTER_AS_IP_PACKETS = 128, // Indicate the traffic as IP packets via ipSend/ipReceive
NF_READONLY = 256, // Don't block the IP packets and indicate them to ipSend/ipReceive only for monitoring
NF_CONTROL_FLOW = 512, // Use the flow limit rules even without NF_FILTER flag
NF_REDIRECT = 1024, // Redirect the outgoing TCP connections to address specified in redirectTo
} NF_FILTERING_FLAG;
#pragma pack(push, 1)
#define NF_MAX_ADDRESS_LENGTH 28
#define NF_MAX_IP_ADDRESS_LENGTH 16
#ifndef AF_INET
#define AF_INET 2 /* internetwork: UDP, TCP, etc. */
#endif
#ifndef AF_INET6
#define AF_INET6 23 /* Internetwork Version 6 */
#endif
// Protocols
#ifndef IPPROTO_TCP
#define IPPROTO_TCP 6
#endif
#ifndef IPPROTO_UDP
#define IPPROTO_UDP 17
#endif
#define TCP_SOCKET_NODELAY 1
#define TCP_SOCKET_KEEPALIVE 2
#define TCP_SOCKET_OOBINLINE 3
#define TCP_SOCKET_BSDURGENT 4
#define TCP_SOCKET_ATMARK 5
#define TCP_SOCKET_WINDOW 6
/**
* Filtering rule
**/
typedef UNALIGNED struct _NF_RULE
{
int protocol; // IPPROTO_TCP or IPPROTO_UDP
unsigned long processId; // Process identifier
unsigned char direction; // See NF_DIRECTION
unsigned short localPort; // Local port
unsigned short remotePort; // Remote port
unsigned short ip_family; // AF_INET for IPv4 and AF_INET6 for IPv6
// Local IP (or network if localIpAddressMask is not zero)
unsigned char localIpAddress[NF_MAX_IP_ADDRESS_LENGTH];
// Local IP mask
unsigned char localIpAddressMask[NF_MAX_IP_ADDRESS_LENGTH];
// Remote IP (or network if remoteIpAddressMask is not zero)
unsigned char remoteIpAddress[NF_MAX_IP_ADDRESS_LENGTH];
// Remote IP mask
unsigned char remoteIpAddressMask[NF_MAX_IP_ADDRESS_LENGTH];
unsigned long filteringFlag; // See NF_FILTERING_FLAG
} NF_RULE, *PNF_RULE;
typedef struct _NF_PORT_RANGE
{
unsigned short valueLow;
unsigned short valueHigh;
} NF_PORT_RANGE, *PNF_PORT_RANGE;
/**
* Filtering rule with additional fields
**/
typedef UNALIGNED struct _NF_RULE_EX
{
int protocol; // IPPROTO_TCP or IPPROTO_UDP
unsigned long processId; // Process identifier
unsigned char direction; // See NF_DIRECTION
unsigned short localPort; // Local port
unsigned short remotePort; // Remote port
unsigned short ip_family; // AF_INET for IPv4 and AF_INET6 for IPv6
// Local IP (or network if localIpAddressMask is not zero)
unsigned char localIpAddress[NF_MAX_IP_ADDRESS_LENGTH];
// Local IP mask
unsigned char localIpAddressMask[NF_MAX_IP_ADDRESS_LENGTH];
// Remote IP (or network if remoteIpAddressMask is not zero)
unsigned char remoteIpAddress[NF_MAX_IP_ADDRESS_LENGTH];
// Remote IP mask
unsigned char remoteIpAddressMask[NF_MAX_IP_ADDRESS_LENGTH];
unsigned long filteringFlag; // See NF_FILTERING_FLAG
// Process name tail mask (supports * as 0 or more symbols)
wchar_t processName[MAX_PATH];
NF_PORT_RANGE localPortRange; // Local port(s)
NF_PORT_RANGE remotePortRange; // Remote port(s)
// Remote address for redirection as sockaddr_in for IPv4 and sockaddr_in6 for IPv6
unsigned char redirectTo[NF_MAX_ADDRESS_LENGTH];
// Process identifier of a local proxy
unsigned long localProxyProcessId;
} NF_RULE_EX, *PNF_RULE_EX;
typedef unsigned __int64 ENDPOINT_ID;
/**
* TCP connection properties
**/
typedef UNALIGNED struct _NF_TCP_CONN_INFO
{
unsigned long filteringFlag; // See NF_FILTERING_FLAG
unsigned long processId; // Process identifier
unsigned char direction; // See NF_DIRECTION
unsigned short ip_family; // AF_INET for IPv4 and AF_INET6 for IPv6
// Local address as sockaddr_in for IPv4 and sockaddr_in6 for IPv6
unsigned char localAddress[NF_MAX_ADDRESS_LENGTH];
// Remote address as sockaddr_in for IPv4 and sockaddr_in6 for IPv6
unsigned char remoteAddress[NF_MAX_ADDRESS_LENGTH];
} NF_TCP_CONN_INFO, *PNF_TCP_CONN_INFO;
/**
* UDP endpoint properties
**/
typedef UNALIGNED struct _NF_UDP_CONN_INFO
{
unsigned long processId; // Process identifier
unsigned short ip_family; // AF_INET for IPv4 and AF_INET6 for IPv6
// Local address as sockaddr_in for IPv4 and sockaddr_in6 for IPv6
unsigned char localAddress[NF_MAX_ADDRESS_LENGTH];
} NF_UDP_CONN_INFO, *PNF_UDP_CONN_INFO;
/**
* UDP TDI_CONNECT request properties
**/
typedef UNALIGNED struct _NF_UDP_CONN_REQUEST
{
unsigned long filteringFlag; // See NF_FILTERING_FLAG
unsigned long processId; // Process identifier
unsigned short ip_family; // AF_INET for IPv4 and AF_INET6 for IPv6
// Local address as sockaddr_in for IPv4 and sockaddr_in6 for IPv6
unsigned char localAddress[NF_MAX_ADDRESS_LENGTH];
// Remote address as sockaddr_in for IPv4 and sockaddr_in6 for IPv6
unsigned char remoteAddress[NF_MAX_ADDRESS_LENGTH];
} NF_UDP_CONN_REQUEST, *PNF_UDP_CONN_REQUEST;
/**
* UDP options
**/
typedef UNALIGNED struct _NF_UDP_OPTIONS
{
unsigned long flags; // Datagram flags
long optionsLength; // Length of options buffer
unsigned char options[1]; // Options of variable size
} NF_UDP_OPTIONS, *PNF_UDP_OPTIONS;
typedef enum _NF_IP_FLAG
{
NFIF_NONE = 0, // No flags
NFIF_READONLY = 1, // The packet was not blocked and indicated only for monitoring in read-only mode
// (see NF_READ_ONLY flags from NF_FILTERING_FLAG).
} NF_IP_FLAG;
/**
* IP options
**/
typedef struct _NF_IP_PACKET_OPTIONS
{
unsigned short ip_family; // AF_INET for IPv4 and AF_INET6 for IPv6
unsigned int ipHeaderSize; // Size in bytes of IP header
unsigned long compartmentId; // Network routing compartment identifier (can be zero)
unsigned long interfaceIndex; // Index of the interface on which the original packet data was received (irrelevant to outgoing packets)
unsigned long subInterfaceIndex; // Index of the subinterface on which the original packet data was received (irrelevant to outgoing packets)
unsigned long flags; // Can be a combination of flags from NF_IP_FLAG enumeration
} NF_IP_PACKET_OPTIONS, *PNF_IP_PACKET_OPTIONS;
/**
* Internal IO structure
**/
typedef UNALIGNED struct _NF_DATA
{
int code;
ENDPOINT_ID id;
unsigned long bufferSize;
char buffer[1];
} NF_DATA, *PNF_DATA;
typedef UNALIGNED struct _NF_BUFFERS
{
unsigned __int64 inBuf;
unsigned __int64 inBufLen;
unsigned __int64 outBuf;
unsigned __int64 outBufLen;
} NF_BUFFERS, *PNF_BUFFERS;
typedef UNALIGNED struct _NF_READ_RESULT
{
unsigned __int64 length;
} NF_READ_RESULT, *PNF_READ_RESULT;
typedef UNALIGNED struct _NF_FLOWCTL_DATA
{
unsigned __int64 inLimit;
unsigned __int64 outLimit;
} NF_FLOWCTL_DATA, *PNF_FLOWCTL_DATA;
typedef UNALIGNED struct _NF_FLOWCTL_MODIFY_DATA
{
unsigned int fcHandle;
NF_FLOWCTL_DATA data;
} NF_FLOWCTL_MODIFY_DATA, *PNF_FLOWCTL_MODIFY_DATA;
typedef UNALIGNED struct _NF_FLOWCTL_STAT
{
unsigned __int64 inBytes;
unsigned __int64 outBytes;
} NF_FLOWCTL_STAT, *PNF_FLOWCTL_STAT;
typedef UNALIGNED struct _NF_FLOWCTL_SET_DATA
{
unsigned __int64 endpointId;
unsigned int fcHandle;
} NF_FLOWCTL_SET_DATA, *PNF_FLOWCTL_SET_DATA;
/**
* Binding rule
**/
typedef UNALIGNED struct _NF_BINDING_RULE
{
int protocol; // IPPROTO_TCP or IPPROTO_UDP
unsigned long processId; // Process identifier
// Process name tail mask (supports * as 0 or more symbols)
wchar_t processName[MAX_PATH];
unsigned short localPort; // Local port
unsigned short ip_family; // AF_INET for IPv4 and AF_INET6 for IPv6
// Local IP (or network if localIpAddressMask is not zero)
unsigned char localIpAddress[NF_MAX_IP_ADDRESS_LENGTH];
// Local IP mask
unsigned char localIpAddressMask[NF_MAX_IP_ADDRESS_LENGTH];
// Redirect bind request to this IP
unsigned char newLocalIpAddress[NF_MAX_IP_ADDRESS_LENGTH];
// Redirect bind request to this port, if it is not zero
unsigned short newLocalPort;
unsigned long filteringFlag; // See NF_FILTERING_FLAG, NF_ALLOW or NF_FILTER
} NF_BINDING_RULE, *PNF_BINDING_RULE;
#pragma pack(pop)
#ifdef WIN32
typedef enum _NF_DRIVER_TYPE
{
DT_UNKNOWN = 0,
DT_TDI = 1,
DT_WFP = 2
} NF_DRIVER_TYPE;
#ifdef _NF_INTERNALS
#define NF_REQ_GET_ADDR_INFO \
CTL_CODE(FILE_DEVICE_UNKNOWN, 101, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define NF_REQ_GET_PROCESS_NAME \
CTL_CODE(FILE_DEVICE_UNKNOWN, 102, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define NF_REQ_GET_DRIVER_TYPE \
CTL_CODE(FILE_DEVICE_UNKNOWN, 103, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define NF_REQ_TCP_ABORT \
CTL_CODE(FILE_DEVICE_UNKNOWN, 104, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define NF_REQ_ADD_FLOW_CTL \
CTL_CODE(FILE_DEVICE_UNKNOWN, 105, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define NF_REQ_DELETE_FLOW_CTL \
CTL_CODE(FILE_DEVICE_UNKNOWN, 106, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define NF_REQ_SET_TCP_FLOW_CTL \
CTL_CODE(FILE_DEVICE_UNKNOWN, 107, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define NF_REQ_SET_UDP_FLOW_CTL \
CTL_CODE(FILE_DEVICE_UNKNOWN, 108, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define NF_REQ_MODIFY_FLOW_CTL \
CTL_CODE(FILE_DEVICE_UNKNOWN, 109, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define NF_REQ_GET_FLOW_CTL_STAT \
CTL_CODE(FILE_DEVICE_UNKNOWN, 110, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define NF_REQ_CLEAR_TEMP_RULES \
CTL_CODE(FILE_DEVICE_UNKNOWN, 111, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define NF_REQ_ADD_TEMP_RULE \
CTL_CODE(FILE_DEVICE_UNKNOWN, 112, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define NF_REQ_SET_TEMP_RULES \
CTL_CODE(FILE_DEVICE_UNKNOWN, 113, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define NF_REQ_ADD_HEAD_BINDING_RULE \
CTL_CODE(FILE_DEVICE_UNKNOWN, 114, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define NF_REQ_ADD_TAIL_BINDING_RULE \
CTL_CODE(FILE_DEVICE_UNKNOWN, 115, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define NF_REQ_DELETE_BINDING_RULES \
CTL_CODE(FILE_DEVICE_UNKNOWN, 116, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define NF_REQ_ADD_HEAD_RULE_EX \
CTL_CODE(FILE_DEVICE_UNKNOWN, 117, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define NF_REQ_ADD_TAIL_RULE_EX \
CTL_CODE(FILE_DEVICE_UNKNOWN, 118, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define NF_REQ_ADD_TEMP_RULE_EX \
CTL_CODE(FILE_DEVICE_UNKNOWN, 119, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define NF_REQ_GET_UDP_ADDR_INFO \
CTL_CODE(FILE_DEVICE_UNKNOWN, 120, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define FSCTL_TCP_BASE FILE_DEVICE_NETWORK
#define _TCP_CTL_CODE(function, method, access) \
CTL_CODE(FSCTL_TCP_BASE, function, method, access)
#define IOCTL_TCP_QUERY_INFORMATION_EX \
_TCP_CTL_CODE(0, METHOD_NEITHER, FILE_ANY_ACCESS)
#define IOCTL_TCP_SET_INFORMATION_EX \
_TCP_CTL_CODE(1, METHOD_BUFFERED, FILE_WRITE_ACCESS)
#endif
#define FSCTL_DEVCTRL_BASE FILE_DEVICE_NETWORK
#define _DEVCTRL_CTL_CODE(_Function, _Method, _Access) \
CTL_CODE(FSCTL_DEVCTRL_BASE, _Function, _Method, _Access)
#define IOCTL_DEVCTRL_OPEN \
_DEVCTRL_CTL_CODE(0x200, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS)
#endif
#endif // _NFDRIVER_H

View File

@@ -0,0 +1,270 @@
//
// NetFilterSDK
// Copyright (C) Vitaly Sidorov
// All rights reserved.
//
// This file is a part of the NetFilter SDK.
// The code and information is provided "as-is" without
// warranty of any kind, either expressed or implied.
//
#ifndef _NFEVENTS_H
#define _NFEVENTS_H
#pragma warning(disable: 26812)
/**
* Return status codes
**/
typedef enum _NF_STATUS
{
NF_STATUS_SUCCESS = 0,
NF_STATUS_FAIL = -1,
NF_STATUS_INVALID_ENDPOINT_ID = -2,
NF_STATUS_NOT_INITIALIZED = -3,
NF_STATUS_IO_ERROR = -4,
NF_STATUS_REBOOT_REQUIRED = -5
} NF_STATUS;
#define _C_API
#ifndef _C_API
#define NFAPI_NS nfapi::
#define NFAPI_CC
/////////////////////////////////////////////////////////////////////////////////////
// C++ API
/////////////////////////////////////////////////////////////////////////////////////
namespace nfapi
{
#include <nfdriver.h>
/**
* Filtering events
**/
class NF_EventHandler
{
public:
/**
* Called immediately after starting the filtering thread.
* Use this event for thread-specific initialization, e.g. calling
* CoInitialize() etc.
**/
virtual void threadStart() = 0;
/**
* Called before stopping the thread.
**/
virtual void threadEnd() = 0;
//
// TCP events
//
/**
* Called before establishing an outgoing TCP connection,
* when NF_INDICATE_CONNECT_REQUESTS flag is specified in an appropriate rule.
* It is possible to change pConnInfo->filteringFlag and pConnInfo->remoteAddress
* in this handler. The changes will be applied to connection.
* @param id Unique connection identifier
* @param pConnInfo Connection parameters, see <tt>NF_TCP_CONN_INFO</tt>
**/
virtual void tcpConnectRequest(ENDPOINT_ID id, PNF_TCP_CONN_INFO pConnInfo) = 0;
/**
* Called after successful establishing the incoming or outgoing TCP connection.
* @param id Unique connection identifier
* @param pConnInfo Connection parameters, see <tt>NF_TCP_CONN_INFO</tt>
**/
virtual void tcpConnected(ENDPOINT_ID id, PNF_TCP_CONN_INFO pConnInfo) = 0;
/**
* Called after closing the connection identified by id.
* @param id Unique connection identifier
* @param pConnInfo Connection parameters, see <tt>NF_TCP_CONN_INFO</tt>
**/
virtual void tcpClosed(ENDPOINT_ID id, PNF_TCP_CONN_INFO pConnInfo) = 0;
/**
* Indicates the buffer received from server.
* @param id Unique connection identifier
* @param buf Pointer to data buffer
* @param len Buffer length
**/
virtual void tcpReceive(ENDPOINT_ID id, const char * buf, int len) = 0;
/**
* Indicates the buffer sent from the local socket.
* @param id Unique connection identifier
* @param buf Pointer to data buffer
* @param len Buffer length
**/
virtual void tcpSend(ENDPOINT_ID id, const char * buf, int len) = 0;
/**
* Informs that the internal buffer for receives is empty and
* it is possible to call nf_tcpPostReceive for pushing receives
* via specified connection.
* @param id Unique connection identifier
**/
virtual void tcpCanReceive(ENDPOINT_ID id) = 0;
/**
* Informs that the internal buffer for sends is empty and
* it is possible to call nf_tcpPostSend for pushing sends
* via specified connection.
* @param id Unique connection identifier
**/
virtual void tcpCanSend(ENDPOINT_ID id) = 0;
//
// UDP events
//
/**
* Called after creating UDP socket.
* @param id Unique socket identifier
* @param pConnInfo Socket parameters, see <tt>NF_UDP_CONN_INFO</tt>
**/
virtual void udpCreated(ENDPOINT_ID id, PNF_UDP_CONN_INFO pConnInfo) = 0;
/**
* Called before establishing an outgoing UDP connection,
* when NF_INDICATE_CONNECT_REQUESTS flag is specified in an appropriate rule.
* It is possible to change pConnReq->filteringFlag and pConnReq->remoteAddress
* in this handler. The changes will be applied to connection.
* @param id Unique connection identifier
* @param pConnInfo Connection parameters, see <tt>NF_UDP_CONN_REQUEST</tt>
**/
virtual void udpConnectRequest(ENDPOINT_ID id, PNF_UDP_CONN_REQUEST pConnReq) = 0;
/**
* Called after closing UDP socket identified by id.
* @param id Unique socket identifier
* @param pConnInfo Socket parameters, see <tt>NF_UDP_CONN_INFO</tt>
**/
virtual void udpClosed(ENDPOINT_ID id, PNF_UDP_CONN_INFO pConnInfo) = 0;
/**
* Indicates the buffer received from server.
* @param id Unique socket identifier
* @param options UDP options
* @param remoteAddress Source address
* @param buf Pointer to data buffer
* @param len Buffer length
**/
virtual void udpReceive(ENDPOINT_ID id, const unsigned char * remoteAddress, const char * buf, int len, PNF_UDP_OPTIONS options) = 0;
/**
* Indicates the buffer sent from the local socket.
* @param id Unique socket identifier
* @param options UDP options
* @param remoteAddress Destination address
* @param buf Pointer to data buffer
* @param len Buffer length
**/
virtual void udpSend(ENDPOINT_ID id, const unsigned char * remoteAddress, const char * buf, int len, PNF_UDP_OPTIONS options) = 0;
/**
* Informs that the internal buffer for receives is empty and
* it is possible to call nf_udpPostReceive for pushing receives
* via specified socket.
* @param id Unique socket identifier
**/
virtual void udpCanReceive(ENDPOINT_ID id) = 0;
/**
* Informs that the internal buffer for sends is empty and
* it is possible to call nf_udpPostSend for pushing sends
* via specified socket.
* @param id Unique socket identifier
**/
virtual void udpCanSend(ENDPOINT_ID id) = 0;
};
/**
* IP level filtering events
**/
class NF_IPEventHandler
{
public:
/**
* Indicates a packet received from server.
* @param buf Pointer to data buffer
* @param len Buffer length
* @param options IP options
**/
virtual void ipReceive(const char * buf, int len, PNF_IP_PACKET_OPTIONS options) = 0;
/**
* Indicates a packet sent to server.
* @param buf Pointer to data buffer
* @param len Buffer length
* @param options IP options
**/
virtual void ipSend(const char * buf, int len, PNF_IP_PACKET_OPTIONS options) = 0;
};
#else
#ifdef WIN32
#define NFAPI_CC __cdecl
#else
#define NFAPI_CC
#endif
#define NFAPI_NS
/////////////////////////////////////////////////////////////////////////////////////
// C API
/////////////////////////////////////////////////////////////////////////////////////
#ifdef __cplusplus
extern "C"
{
#endif
#include <nfdriver.h>
#pragma pack(push, 1)
// C analogue of the class NF_EventHandler (see the definition above)
typedef struct _NF_EventHandler
{
void (NFAPI_CC *threadStart)();
void (NFAPI_CC *threadEnd)();
void (NFAPI_CC *tcpConnectRequest)(ENDPOINT_ID id, PNF_TCP_CONN_INFO pConnInfo);
void (NFAPI_CC *tcpConnected)(ENDPOINT_ID id, PNF_TCP_CONN_INFO pConnInfo);
void (NFAPI_CC *tcpClosed)(ENDPOINT_ID id, PNF_TCP_CONN_INFO pConnInfo);
void (NFAPI_CC *tcpReceive)(ENDPOINT_ID id, const char * buf, int len);
void (NFAPI_CC *tcpSend)(ENDPOINT_ID id, const char * buf, int len);
void (NFAPI_CC *tcpCanReceive)(ENDPOINT_ID id);
void (NFAPI_CC *tcpCanSend)(ENDPOINT_ID id);
void (NFAPI_CC *udpCreated)(ENDPOINT_ID id, PNF_UDP_CONN_INFO pConnInfo);
void (NFAPI_CC *udpConnectRequest)(ENDPOINT_ID id, PNF_UDP_CONN_REQUEST pConnReq);
void (NFAPI_CC *udpClosed)(ENDPOINT_ID id, PNF_UDP_CONN_INFO pConnInfo);
void (NFAPI_CC *udpReceive)(ENDPOINT_ID id, const unsigned char * remoteAddress, const char * buf, int len, PNF_UDP_OPTIONS options);
void (NFAPI_CC *udpSend)(ENDPOINT_ID id, const unsigned char * remoteAddress, const char * buf, int len, PNF_UDP_OPTIONS options);
void (NFAPI_CC *udpCanReceive)(ENDPOINT_ID id);
void (NFAPI_CC *udpCanSend)(ENDPOINT_ID id);
} NF_EventHandler, *PNF_EventHandler;
// C analogue of the class NF_IPEventHandler (see the definition above)
typedef struct _NF_IPEventHandler
{
void (NFAPI_CC *ipReceive)(const char * buf, int len, PNF_IP_PACKET_OPTIONS options);
void (NFAPI_CC *ipSend)(const char * buf, int len, PNF_IP_PACKET_OPTIONS options);
} NF_IPEventHandler, *PNF_IPEventHandler;
#pragma pack(pop)
#endif
#ifdef __cplusplus
}
#endif
#endif