Functions¶
Driver registration¶
-
NF_STATUS nf_registerDriver(const char *driverName)¶
- Parameters:
driverName – The name of the network hooking driver, without “.sys” extension.
- Returns:
NF_STATUS_SUCCESS on success, or other NF_STATUS error code on failure. Windows API function GetLastError() returns an extended error code if the function returns NF_STATUS_FAIL.
- Description:
Registers and starts a driver with the specified name (without “.sys” extension).
When the flag NFF_DISABLE_AUTO_REGISTER is enabled using nf_setOptions, any application that uses the driver API tries to register the driver automatically during a call to nf_init, if it is not yet registered. The administrative rights are required to perform this operation. The driver starts immediately after registration, and reboot is not required. The driver will be loaded automatically on each system start. When the driver is registered and started, a client process doesn’t require administrative rights for using it via API.
-
NF_STATUS nf_registerDriverEx(const char *driverName, const char *driverPath)¶
- Parameters:
driverName – The name of the network hooking driver, without “.sys” extension.
driverPath – The full path to a folder containing the specified driver.
- Returns:
NF_STATUS_SUCCESS on success, or other NF_STATUS error code on failure. Windows API function GetLastError() returns an extended error code if the function returns NF_STATUS_FAIL.
- Description:
Registers and starts a driver with the specified name (without “.sys” extension), saved to the specified folder.
When the flag NFF_DISABLE_AUTO_REGISTER is enabled using nf_setOptions, any application that uses the driver API tries to register the driver automatically during a call to nf_init, if it is not yet registered. The administrative rights are required to perform this operation. The driver starts immediately after registration, and reboot is not required. The driver will be loaded automatically on each system start. When the driver is registered and started, a client process doesn’t require administrative rights for using it via API.
-
NF_STATUS nf_unRegisterDriver(const char *driverName)¶
- Parameters:
driverName – The name of the network hooking driver, without “.sys” extension.
- Returns:
NF_STATUS_SUCCESS on success, or other NF_STATUS error code on failure. Windows API function GetLastError() returns an extended error code if the function returns NF_STATUS_FAIL.
- Description:
Unregisters a driver with the specified name (without “.sys” extension).
Unregistering the driver requires administrative rights. Delete Windows\System32\Drivers\<driverName>.sys (or from another folder if the driver is registered elsewhere) and reboot to remove the driver from the system completely.
Initialization¶
-
NF_STATUS nf_init(const char *driverName, NF_EventHandler *pHandler)¶
- Parameters:
driverName – The name of the network hooking driver, without “.sys” extension.
pHandler – Pointer to NF_EventHandler object.
- Returns:
NF_STATUS_SUCCESS on success, or other NF_STATUS error code on failure.
- Description:
Call this function to initialize an attachment to the hooking driver and set the event handler object. The library calls NF_EventHandler methods from a separate thread.
By default the driver uses the NF_ALLOW filtering flag and doesn’t filter the transmitted data. In this mode the library notifies the API about creating and closing UDP sockets. To filter the transmitted packets, add the filtering rules with the necessary flags using the function nf_addRule(Ex) or nf_setRules(Ex).
The function returns NF_STATUS_FAIL if some other process is already attached to the hooking driver. The driver doesn’t allow multiple attachments. If an additional process must filter the network data on the same system, it is possible to rename and register another copy of the driver, then use the new name in the nf_init call from another process.
It is possible to call nf_setOptions before nf_init to specify additional parameters.
-
void nf_free()¶
- Description:
Stops the filtering threads, aborts all filtered connections and detaches from the hooking driver.
This function aborts all filtered TCP connections, which means that all unsent buffered data will be lost. To avoid this, it is possible to remove the filtering rules with a call to nf_deleteRules, and wait until the filtered connections close gracefully.
-
void nf_setOptions(DWORD nThreads, DWORD flags)¶
- Parameters:
nThreads – Number of worker threads for NF_EventHandler events.
flags –
A combination of flags from NF_FLAGS:
NFF_NONE = 0 - no flags
NFF_DISABLE_AUTO_REGISTER = 4 - Disables automatic registration of the driver during nf_init call.
NFF_DISABLE_AUTO_START = 8 - Disables automatic start of the driver in nf_init.
- Description:
Specifies the number of worker threads and initialization flags.
The function can be called before nf_init. If it is called after initialization, the changes are not applied until the library is reinitialized. By default nThreads = 0 and flags = 0. When nThreads=0 the code detects the number of logical processors and uses it as the number of worker threads.
Filtering rules¶
-
NF_STATUS nf_addRule(PNF_RULE pRule, int toHead)¶
- Parameters:
pRule – A pointer to NF_RULE structure.
toHead – TRUE (1) - add rule to list head, FALSE (0) - add rule to list tail
- Returns:
NF_STATUS_SUCCESS on success, or other NF_STATUS error code on failure.
- Description:
Adds the specified filtering rule to the list.
The list of rules is scanned from the beginning and the first matching rule is applied. The new rules are added to the list head or tail, depending on the toHead parameter. The driver doesn’t filter the network activity of the attached process. In effect, the rules are not applied to the sockets created by a process that uses the driver API.
-
NF_STATUS nf_addRuleEx(PNF_RULE_EX pRule, int toHead)¶
- Parameters:
pRule – A pointer to NF_RULE_EX structure.
toHead – TRUE (1) - add rule to list head, FALSE (0) - add rule to list tail
- Returns:
NF_STATUS_SUCCESS on success, or other NF_STATUS error code on failure.
- Description:
Adds the specified filtering rule to the list.
The list of rules is scanned from the beginning and the first matching rule is applied. The new rules are added to the list head or tail, depending on the toHead parameter. The driver doesn’t filter the network activity of the attached process. In effect, the rules are not applied to the sockets created by a process that uses the driver API. NF_RULE_EX rules are added to the same list as NF_RULE. NF_RULE is treated as NF_RULE_EX without additional condition. So it is possible to add both types of rules in any order.
-
NF_STATUS nf_setRules(PNF_RULE pRules, int count)¶
- Parameters:
pRules – A pointer to an array of NF_RULE structures.
count – Number of items in pRules array
- Returns:
NF_STATUS_SUCCESS on success, or other NF_STATUS error code on failure.
- Description:
Replaces the rules in the driver with the specified array.
It is an atomic operation, which means that the old rules are replaced with a new list in a single synchronized call. If the rules list in the driver is empty, the new list is assigned as current.
-
NF_STATUS nf_setRulesEx(PNF_RULE_EX pRules, int count)¶
- Parameters:
pRules – A pointer to an array of NF_RULE_EX structures.
count – Number of items in pRules array
- Returns:
NF_STATUS_SUCCESS on success, or other NF_STATUS error code on failure.
- Description:
Replaces the rules in the driver with the specified array.
It is an atomic operation, which means that the old rules are replaced with a new list in a single synchronized call. If the rules list in the driver is empty, the new list is assigned as current.
-
NF_STATUS nf_deleteRules()¶
- Returns:
NF_STATUS_SUCCESS on success, or other NF_STATUS error code on failure.
- Description:
Removes all added filtering rules.
The rules are removed automatically after closing the attached process. The filtering flags assigned to an active TCP connection persist even after removing the matching rules, until the connection is closed or the process attached to the driver terminates.
TCP protocol¶
-
NF_STATUS nf_tcpClose(ENDPOINT_ID id)¶
- Parameters:
id – Connection identifier
- Returns:
NF_STATUS_SUCCESS on success, or other NF_STATUS error code on failure.
- Description:
Closes the connection with the given id.
The driver cancels all pending send and receive requests and aborts the connection. For a graceful disconnect, call nf_tcpPostSend and nf_tcpPostReceive with a zero-length buffer after receiving NF_EventHandler::tcpSend and NF_EventHandler::tcpReceive calls with a zero-length buffer.
-
NF_STATUS nf_tcpPostReceive(ENDPOINT_ID id, const char *buf, int len)¶
- Parameters:
id – Connection identifier
buf – Pointer to data buffer
len – Buffer length
- Returns:
NF_STATUS_SUCCESS on success, or other NF_STATUS error code on failure.
- Description:
Passes the buffer to the local process via TCP connection with the specified id.
The method NF_EventHandler::tcpCanReceive is called when the internal packet buffer is empty. The function always returns NF_STATUS_SUCCESS after buffering the data. To optimize memory usage, split large buffers into chunks and indicate each chunk after receiving tcpCanReceive. There is no need to wait for tcpCanReceive before indicating the first chunk. If len is zero, the driver sends a controlled disconnect request to the local process for the specified TCP connection.
-
NF_STATUS nf_tcpPostSend(ENDPOINT_ID id, const char *buf, int len)¶
- Parameters:
id – Connection identifier
buf – Pointer to data buffer
len – Buffer length
- Returns:
NF_STATUS_SUCCESS on success, or other NF_STATUS error code on failure.
- Description:
Passes the buffer to the local process via TCP connection with the specified id.
The method NF_EventHandler::tcpCanSend is called when the internal packet buffer is empty. The function always returns NF_STATUS_SUCCESS after buffering the data. To optimize memory usage, split large buffers into chunks and send each chunk after receiving tcpCanSend. There is no need to wait for tcpCanSend before sending the first chunk. If len is zero, the driver initiates a controlled disconnect for the specified TCP connection. The driver aborts the connection if NF_EventHandler::tcpSend with zero len was not yet called.
-
NF_STATUS nf_tcpSetConnectionState(ENDPOINT_ID id, BOOL suspended)¶
- Parameters:
id – Connection identifier
suspended – TRUE to suspend, FALSE to resume
- Returns:
NF_STATUS_SUCCESS on success, or other NF_STATUS error code on failure.
- Description:
Suspends or resumes indicating sends and receives for the specified TCP connection via NF_EventHandler methods.
The library automatically suspends connections having a large amount of data in send or receive buffers, to avoid wasting memory when the network application or remote server are too slow. The automatic suspending is temporary, and the library resumes indicating new packets after successful delivery of the buffered data.
-
NF_STATUS nf_tcpDisableFiltering(ENDPOINT_ID id)¶
- Parameters:
id – Connection identifier
- Returns:
NF_STATUS_SUCCESS on success, or other NF_STATUS error code on failure.
- Description:
Disables calling TCP events for the specified endpoint.
This function helps improve performance if the filtering application is not interested in packets transmitted via a filtered connection (with NF_FILTER flag assigned). It is possible to call this function in the tcpConnected event to stop indicating new packets.
-
NF_STATUS nf_tcpSetSockOpt(ENDPOINT_ID id, int optname, const char *optval, int optlen)¶
- Parameters:
id – Connection identifier
optname – Option code
optval – Pointer to option value
optlen – Option value length
- Returns:
NF_STATUS_SUCCESS on success, or other NF_STATUS error code on failure.
- Description:
Sets socket options for a TCP connection.
This is an analogue of the setsockopt() function from WinSock API.
-
BOOL nf_tcpIsProxy(DWORD processId)¶
- Parameters:
processId – Process identifier
- Returns:
TRUE or FALSE.
- Description:
Returns TRUE if the specified process acts as a local proxy, accepting local TCP connections.
If your filter redirects TCP connections to a local proxy in the tcpConnectRequest event, and there is another filter in the system that redirects connections to its own local proxy, a filtering loop can occur. nf_tcpIsProxy returns TRUE if the process with the specified id has accepted a connection established from some other process, i.e. the process with the specified id acts as a local proxy handling the redirected connections. In this case it is not safe to redirect the connections of such process, because of possible filtering loops when a connection is redirected between local proxies infinitely.
-
NF_STATUS nf_getTCPConnInfo(ENDPOINT_ID id, PNF_TCP_CONN_INFO pConnInfo)¶
- Parameters:
id – Connection identifier
pConnInfo – Pointer to NF_TCP_CONN_INFO structure
- Returns:
NF_STATUS_SUCCESS on success, or other NF_STATUS error code on failure.
- Description:
Returns the properties of the TCP connection with the specified id in pConnInfo.
-
NF_STATUS nf_completeTCPConnectRequest(ENDPOINT_ID id, PNF_TCP_CONN_INFO pConnInfo)¶
- Parameters:
id – Connection identifier
pConnInfo – Pointer to NF_TCP_CONN_INFO structure
- Returns:
NF_STATUS_SUCCESS on success, or other NF_STATUS error code on failure.
- Description:
Completes a TCP connect request pended using the NF_PEND_CONNECT_REQUEST flag in the tcpConnectRequest event.
The creation of TCP connections can be pended from tcpConnectRequest by specifying the NF_PEND_CONNECT_REQUEST flag in NF_TCP_CONN_INFO.filteringFlag. In this case the creation of the connection must be continued later from any thread using nf_completeTCPConnectRequest. If the NF_PEND_CONNECT_REQUEST flag is specified, nf_completeTCPConnectRequest cannot be called from the tcpConnectRequest event.
-
NF_STATUS nf_findOriginalRemoteAddress(USHORT srcPort, char *remoteAddress, int remoteAddressLen);¶
- Parameters:
srcPort – Local port of the redirected connection.
remoteAddress – Buffer for the returned remote address as sockaddr_in or sockaddr_in6.
remoteAddressLen – Length of remoteAddress.
- Returns:
NF_STATUS_SUCCESS on success, or other NF_STATUS error code on failure.
- Description:
Returns the original server address for the given local port of an outgoing TCP connection.
UDP protocol¶
-
NF_STATUS nf_udpPostReceive(ENDPOINT_ID id, const unsigned char *remoteAddress, const char *buf, int len, PNF_UDP_OPTIONS options)¶
- Parameters:
id – Socket identifier
remoteAddress – Remote address (sockaddr_in* for IPv4 and sockaddr_in6* for IPv6)
buf – Pointer to data buffer
len – Buffer length
options – Pointer to NF_UDP_OPTIONS structure
- Returns:
NF_STATUS_SUCCESS on success, or other NF_STATUS error code on failure.
- Description:
Indicates the buffer to the local process via the specified socket.
The method NF_EventHandler::udpCanReceive is called when the internal packet buffer is empty. The NF_UDP_OPTIONS structure contains datagram parameters including the control data buffer. The options parameter can be NULL. In this case the library generates default parameters with zero-length control data.
-
NF_STATUS nf_udpPostSend(ENDPOINT_ID id, const unsigned char *remoteAddress, const char *buf, int len, PNF_UDP_OPTIONS options)¶
- Parameters:
id – Socket identifier
remoteAddress – Remote address (sockaddr_in* for IPv4 and sockaddr_in6* for IPv6)
buf – Pointer to data buffer
len – Buffer length
options – Pointer to NF_UDP_OPTIONS structure
- Returns:
NF_STATUS_SUCCESS on success, or other NF_STATUS error code on failure.
- Description:
Sends the buffer to the remote server via the specified endpoint.
The method NF_EventHandler::udpCanSend is called when the internal packet buffer is empty. The NF_UDP_OPTIONS structure contains datagram parameters including the control data buffer. The options parameter can be NULL. In this case the library generates default parameters with zero-length control data.
-
NF_STATUS nf_udpSetConnectionState(ENDPOINT_ID id, BOOL suspended)¶
- Parameters:
id – Socket identifier
suspended – TRUE to suspend, FALSE to resume
- Returns:
NF_STATUS_SUCCESS on success, or other NF_STATUS error code on failure.
- Description:
Suspends or resumes indicating sends and receives for the specified UDP socket via NF_EventHandler methods.
The library automatically suspends connections having a large amount of data in send or receive buffers, to avoid wasting memory when the network application or remote server are too slow. The automatic suspending is temporary, and the library resumes indicating new packets after successful delivery of the buffered data.
-
NF_STATUS nf_udpDisableFiltering(ENDPOINT_ID id)¶
- Parameters:
id – Socket identifier
- Returns:
NF_STATUS_SUCCESS on success, or other NF_STATUS error code on failure.
- Description:
Disables indicating UDP events for the specified endpoint.
This function helps improve performance if the filtering application is not interested in packets transmitted via a filtered socket (with NF_FILTER flag assigned).
-
NF_STATUS nf_getUDPConnInfo(ENDPOINT_ID id, PNF_UDP_CONN_INFO pConnInfo)¶
- Parameters:
id – Socket identifier
pConnInfo – Pointer to NF_UDP_CONN_INFO structure
- Returns:
NF_STATUS_SUCCESS on success, or other NF_STATUS error code on failure.
- Description:
Returns the properties of the UDP socket with the specified id in pConnInfo.
Flow control contexts and statistics¶
-
NF_STATUS nf_addFlowCtl(PNF_FLOWCTL_DATA pData, unsigned int *pFcHandle)¶
- Parameters:
pData – A pointer to NF_FLOWCTL_DATA structure.
pFcHandle – Returns a flow control context handle on success
- Returns:
NF_STATUS_SUCCESS on success, or other NF_STATUS error code on failure.
- Description:
Adds a flow control context with the specified parameters.
Call this function to add a new flow control context with the specified parameters.
-
NF_STATUS nf_deleteFlowCtl(unsigned int fcHandle)¶
- Parameters:
fcHandle – Flow control context handle
- Returns:
NF_STATUS_SUCCESS on success, or other NF_STATUS error code on failure.
- Description:
Deletes the flow control context.
Deletes the flow control context with the specified handle and disables its association with TCP/UDP sockets. When fcHandle is zero, all existing flow control contexts are deleted. All flow control contexts are deleted automatically after detaching from the driver with nf_free or on unexpected shutdown of the filtering process.
-
NF_STATUS nf_modifyFlowCtl(unsigned int fcHandle, PNF_FLOWCTL_DATA pData)¶
- Parameters:
fcHandle – Flow control context handle
pData – A pointer to NF_FLOWCTL_DATA structure.
- Returns:
NF_STATUS_SUCCESS on success, or other NF_STATUS error code on failure.
- Description:
Modifies the flow control context parameters.
The function changes the parameters of the flow control context with the specified handle.
-
NF_STATUS nf_setTCPFlowCtl(ENDPOINT_ID id, unsigned int fcHandle)¶
- Parameters:
id – Connection identifier
fcHandle – Flow control context handle
- Returns:
NF_STATUS_SUCCESS on success, or other NF_STATUS error code on failure.
- Description:
Associates a flow control context with the specified TCP connection.
To count traffic or limit bandwidth using a flow control context, it is necessary to associate the context with one or more TCP connections or UDP sockets. If fcHandle is zero, the function disables the association with the flow control context for the specified connection/socket. A TCP connection can be associated with only one flow control context. A flow control context can be associated with any number of connections/sockets.
-
NF_STATUS nf_setUDPFlowCtl(ENDPOINT_ID id, unsigned int fcHandle)¶
- Parameters:
id – Endpoint id of UDP socket
fcHandle – Flow control context handle
- Returns:
NF_STATUS_SUCCESS on success, or other NF_STATUS error code on failure.
- Description:
Associates a flow control context with the specified UDP socket.
To count traffic or limit bandwidth using a flow control context, it is necessary to associate the context with one or more TCP connections or UDP sockets. If fcHandle is zero, the function disables the association with the flow control context for the specified connection/socket. A UDP socket can be associated with only one flow control context. A flow control context can be associated with any number of connections/sockets.
-
NF_STATUS nf_getFlowCtlStat(unsigned int fcHandle, PNF_FLOWCTL_STAT pStat)¶
- Parameters:
fcHandle – Flow control context handle
pStat – A pointer to NF_FLOWCTL_STAT structure.
- Returns:
NF_STATUS_SUCCESS on success, or other NF_STATUS error code on failure.
- Description:
Returns the flow control context statistics.
The function returns the statistics counted for the flow control context with the specified handle.
-
NF_STATUS nf_getTCPStat(ENDPOINT_ID id, PNF_FLOWCTL_STAT pStat)¶
- Parameters:
id – Connection identifier
pStat – A pointer to NF_FLOWCTL_STAT structure.
- Returns:
NF_STATUS_SUCCESS on success, or other NF_STATUS error code on failure.
- Description:
Gets TCP connection statistics as the numbers of inbound/outbound bytes.
The function can be called only from the tcpClosed handler. The statistics are counted for connections having filtering flags NF_FILTER or NF_CONTROL_FLOW.
-
NF_STATUS nf_getUDPStat(ENDPOINT_ID id, PNF_FLOWCTL_STAT pStat)¶
- Parameters:
id – Socket identifier
pStat – A pointer to NF_FLOWCTL_STAT structure.
- Returns:
NF_STATUS_SUCCESS on success, or other NF_STATUS error code on failure.
- Description:
Gets UDP socket statistics as the numbers of inbound/outbound bytes.
The function can be called only from the udpClosed handler. The statistics are counted for sockets having filtering flags NF_FILTER or NF_CONTROL_FLOW.
Common functions¶
-
BOOL nf_getProcessNameA(DWORD processId, char *buf, DWORD len)¶
-
BOOL nf_getProcessNameW(DWORD processId, char *buf, DWORD len)¶
-
BOOL nf_getProcessNameFromKernel(DWORD processId, wchar_t *buf, DWORD len)¶
- Parameters:
processId – Process identifier
buf – Memory buffer for process name
len – Size of buf, in characters.
- Returns:
TRUE on success
- Description:
Returns the process name for the given process id.
nf_getProcessName(A|W) requires administrative privileges for accessing the process information. nf_getProcessNameFromKernel queries the process name from kernel mode, and doesn’t require administrative privileges.