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. 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 startup. When the driver is registered and started, a client process doesn’t require administrative rights to use it via the 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. 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 startup. When the driver is registered and started, a client process doesn’t require administrative rights to use it via the 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 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 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 registering 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 the initialization, the changes are not applied until the library is reinitialized. By default nThreads = 1 and flags = 0. This means that the events are reported from a single thread and all flags are disabled. 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:
Add 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:
Add 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 an 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 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:
Replace the rules in the driver with the specified array.
It is an atomic operation, which means that the old rules are replaced with the new list in a single synchronized call. If the rule list in the driver is empty, the new list is assigned as the current one.
-
NF_STATUS nf_setRulesEx(PNF_RULE_EX pRules, int count)¶
- Parameters:
pRules – A pointer to 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:
Replace the rules in the driver with the specified array.
It is an atomic operation, which means that the old rules are replaced with the new list in a single synchronized call. If the rule list in the driver is empty, the new list is assigned as the current one.
-
NF_STATUS nf_deleteRules()¶
- Returns:
NF_STATUS_SUCCESS on success, or other NF_STATUS error code on failure.
- Description:
Remove 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.
Bind redirection¶
-
NF_STATUS nf_addBindingRule(PNF_BINDING_RULE pRule, int toHead)¶
- Parameters:
pRule – A pointer to NF_BINDING_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:
Add the specified binding rule to the driver.
The driver scans the list of rules from the beginning and uses the filtering flag of the first matching rule. The new rules are added to the list head or tail, depending on the toHead parameter.
-
NF_STATUS nf_deleteBindingRules()¶
- Returns:
NF_STATUS_SUCCESS on success, or other NF_STATUS error code on failure.
- Description:
Remove all binding rules from the driver.
The driver removes all binding rules automatically after closing the attached process.
IP filtering¶
-
void nf_setIPEventHandler(NF_IPEventHandler *pHandler)¶
- Parameters:
pHandler – Pointer to NF_IPEventHandler.
- Description:
Specifies an event handler for IP events.
The function can be called after nf_init for filtering IP packets. The IP events are indicated when the NF_FILTER_AS_IP_PACKETS flag is specified in the rule filteringFlag field. If the NF_READONLY flag is also specified in the same rule, the packets are indicated only for monitoring in read-only mode. In this case the NFIF_READONLY flag is set in the flags field of the NF_IP_PACKET_OPTIONS structure for the appropriate packets, and they are ignored by nf_ipPostSend/nf_ipPostReceive methods. Note that the IP filter bypasses loopback traffic. It indicates only communications with remote hosts.
-
NF_STATUS nf_ipPostSend(const char *buf, int len, PNF_IP_PACKET_OPTIONS options)¶
- Parameters:
buf – Pointer to data buffer
len – Buffer length
options – Pointer to NF_IP_PACKET_OPTIONS structure
- Returns:
NF_STATUS_SUCCESS on success, or other NF_STATUS error code on failure.
- Description:
Sends a packet to a remote host.
nf_ipPostSend uses only compartmentId, ip_family and flags from the NF_IP_PACKET_OPTIONS structure. When NFIF_READONLY is enabled in flags, the packet is ignored.
-
NF_STATUS nf_ipPostReceive(const char *buf, int len, PNF_IP_PACKET_OPTIONS options)¶
- Parameters:
buf – Pointer to data buffer
len – Buffer length
options – Pointer to NF_IP_PACKET_OPTIONS structure
- Returns:
NF_STATUS_SUCCESS on success, or other NF_STATUS error code on failure.
- Description:
Indicates a packet to the TCP/IP stack.
It is necessary to specify values for all fields in the NF_IP_PACKET_OPTIONS structure. When NFIF_READONLY is enabled in flags, the packet is ignored.
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 the calls NF_EventHandler::tcpSend and NF_EventHandler::tcpReceive 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:
Pass 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:
Pass 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 length 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 reporting sends and receives for the specified TCP connection via NF_EventHandler methods.
The library automatically suspends connections with a large amount of data in send or receive buffers, to avoid wasting memory when the network application or remote server is 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 TCP event reporting for the specified endpoint.
This function allows improving performance if the filtering application is not interested in packets transmitted via some filtered connection (with the 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 the 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 a process, because of possible filtering loops when a connection is redirected infinitely between local proxies.
-
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 in pConnInfo the properties of the TCP connection with the specified id.
-
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 in tcpConnectRequest by specifying the flag NF_PEND_CONNECT_REQUEST 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 flag NF_PEND_CONNECT_REQUEST is specified, nf_completeTCPConnectRequest cannot be called from the tcpConnectRequest event.
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:
Indicate 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 cannot be NULL. It is necessary to copy the structure passed to the udpReceive event.
-
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:
Send 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 cannot be NULL. It is necessary to copy the structure passed to the udpSend event.
-
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 reporting sends and receives for the specified UDP socket via NF_EventHandler methods.
The library automatically suspends connections with a large amount of data in send or receive buffers, to avoid wasting memory when the network application or remote server is 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 reporting of UDP events for the specified endpoint.
This function allows improving performance if the filtering application is not interested in packets transmitted via some filtered socket (with the 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 in pConnInfo the properties of the UDP socket with the specified id.
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:
Add 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:
Delete a flow control context.
Deletes the flow control context with the specified handle and disables its association with TCP/UDP sockets. When fcHandle is zero, it deletes all existing flow control contexts. 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:
Modify 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:
Associate a flow control context with the specified TCP connection.
To count the traffic or limit the 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. The 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:
Associate a flow control context with the specified UDP socket.
To count the traffic or limit the 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. The 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:
Get TCP connection statistics as in/out byte counts.
The function can be called only from the tcpClosed handler. The statistics are counted for connections having the 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:
Get UDP socket statistics as in/out byte counts.
The function can be called only from the udpClosed handler. The statistics are counted for sockets having the 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.