Functions

Initialization

NF_STATUS nf_init(const char *driverName, NF_EventHandler *pHandler)
Parameters:
  • driverName – The name of the proxy instance, used as the base name for the iptables chains that hold the filtering rules. The name must not be NULL, must not be longer than 21 characters, and may contain only the characters [A-Za-z0-9_-].

  • pHandler – Pointer to a NF_EventHandler object.

Returns:

NF_STATUS_SUCCESS on success, or another NF_STATUS error code on failure.

Description:

Call this function to initialize the library and set the event handler object. The library calls NF_EventHandler methods from multiple threads.

By default, the proxy allows all network activity and does not filter the transmitted data. To filter the transmitted packets, add the filtering rules with the necessary flags using the function nf_setRules.

The function returns NF_STATUS_FAIL in case of any issue with starting the local proxy or the worker thread pool.

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 removes all filtering rules.

This function aborts all filtered TCP connections, which means that all unsent buffered data is 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(int nThreads, int port)
Parameters:
  • nThreads – Number of worker threads for NF_EventHandler events.

  • port – The dual-stack port used by the local proxy.

Description:

Specifies the number of worker threads and the port used by the local proxy.

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, the local proxy listens on port 8888. When nThreads is zero or negative, the code detects the number of logical processors and uses it as the number of worker threads.

void nf_setProxyFlags(unsigned int flags)
Parameters:

flags – A combination of values from the NF_PROXY_FLAGS enumeration.

Description:

Sets the proxy flags.

The function must be called before nf_init. The default value is NF_PROXY_FLAG_NONE.

typedef enum _NF_PROXY_FLAGS
{
        NF_PROXY_FLAG_NONE = 0,
        // Connect to local services from the original client address for inbound connections
        NF_PROXY_FLAG_INBOUND_TRANSPARENT = 1,
        // Only the proxy's own sockets bypass redirection
        NF_PROXY_FLAG_NO_OWNER_BYPASS = 2
} NF_PROXY_FLAGS;
NF_PROXY_FLAG_INBOUND_TRANSPARENT

Connects to local services from the original client address for inbound (NF_D_IN) connections, using IP_TRANSPARENT/IPV6_TRANSPARENT. Without this flag, local services see connections from the host address. It requires CAP_NET_ADMIN and additional policy routing, which routes the replies of local services to the spoofed client addresses back to the proxy; the rules installed by nf_init/nf_setRules do not provide this routing. If the transparent socket option cannot be set (for example, when CAP_NET_ADMIN is unavailable), the connection to the local service is made from the host address as without this flag, and a warning is logged once.

NF_PROXY_FLAG_NO_OWNER_BYPASS

By default, all outgoing TCP connections of processes running with the proxy’s effective uid (usually root) bypass the redirect rules. This prevents another local proxy running under the same user from being redirected to this proxy. With this flag, only the proxy’s own sockets (SO_MARK) bypass redirection, so other processes of the same user are filtered too. The flag must be set before nf_setRules and applies to subsequent nf_setRules calls. Local proxies running under other users must be excluded using NFEXT_BYPASS redirect rules (NFEXT_USE_UID) placed before the redirecting rules.

Filtering rules

NF_STATUS nf_setRules(PNFEXT_RULE pRules, int count)
Parameters:
  • pRules – A pointer to an array of NFEXT_RULE structures.

  • count – Number of items in the pRules array

Returns:

NF_STATUS_SUCCESS on success, or another NF_STATUS error code on failure.

Description:

Replaces the rules 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 rules list is currently empty, the new list becomes current.

NF_STATUS nf_deleteRules()
Returns:

NF_STATUS_SUCCESS on success, or another NF_STATUS error code on failure.

Description:

Removes all added filtering rules.

The rules are removed automatically after the attached process is closed. The filtering flags assigned to an active TCP connection persist even after the matching rules are removed, until the connection is closed or the process attached to the extension terminates.

TCP protocol

NF_STATUS nf_tcpClose(ENDPOINT_ID id)
Parameters:

id – Connection identifier

Returns:

NF_STATUS_SUCCESS on success, or another NF_STATUS error code on failure.

Description:

Closes the connection with the given id.

The extension 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 to NF_EventHandler::tcpSend and NF_EventHandler::tcpReceive with a zero 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 another NF_STATUS error code on failure.

Description:

Passes the buffer to the local process via the 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 extension sends a graceful 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 another NF_STATUS error code on failure.

Description:

Passes the buffer to the remote server via the 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 extension initiates a graceful disconnect for the specified TCP connection.

NF_STATUS nf_tcpSetConnectionState(ENDPOINT_ID id, int suspended)
Parameters:
  • id – Connection identifier

  • suspended – A value from the NF_PROXY_SUSPEND_STATE enumeration

Returns:

NF_STATUS_SUCCESS on success, or another NF_STATUS error code on failure.

Description:

Suspends or resumes the indication of sends and receives for the specified TCP connection via the NF_EventHandler methods.

typedef enum _NF_PROXY_SUSPEND_STATE
{
        PSS_NONE = 0,
        PSS_SUSPEND = 1,                        // Suspend both directions
        PSS_SUSPEND_OUTBOUND = 2,       // Suspend outbound direction
        PSS_SUSPEND_INBOUND = 4         // Suspend inbound direction
} NF_PROXY_SUSPEND_STATE;

The library automatically suspends connections that have a large amount of data in their send or receive buffers, to avoid wasting memory when the network application or the remote server is too slow. The automatic suspension is temporary, and the library resumes indicating new packets after the buffered data is delivered successfully.

NF_STATUS nf_tcpDisableFiltering(ENDPOINT_ID id)
Parameters:

id – Connection identifier

Returns:

NF_STATUS_SUCCESS on success, or another NF_STATUS error code on failure.

Description:

Disables TCP event notification for the specified endpoint.

This function allows improving performance in cases where the filtering application is not interested in packets transmitted via a 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_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 another NF_STATUS error code on failure.

Description:

Returns the properties of the TCP connection with the specified id in pConnInfo.

UDP protocol

The UDP filtering functions are currently disabled. Only access control for UDP is available using rules.

Common functions

NF_STATUS nf_getProcessName(unsigned int pid, char *buf, int len)
Parameters:
  • pid – Process identifier

  • buf – Memory buffer for the process name

  • len – Size of buf, in characters.

Returns:

NF_STATUS_SUCCESS on success

Description:

Returns the process name for the given process id.

nf_getProcessName returns the full path of the executable for the specified pid.

NF_STATUS nf_getUid(ENDPOINT_ID id, unsigned int *pUid)
Parameters:
  • id – Endpoint identifier

  • pUid – Pointer to user identifier

Returns:

NF_STATUS_SUCCESS on success

Description:

Returns the user identifier for the given endpoint id.

NF_STATUS nf_getUserName(unsigned int uid, char *buf, int len)
Parameters:
  • uid – User identifier

  • buf – Memory buffer for the user name

  • len – Size of buf, in characters.

Returns:

NF_STATUS_SUCCESS on success

Description:

Returns the user name for the given user id.

NF_STATUS nf_requireFileLimit(int file_limit)
Parameters:

file_limit – New limit for the number of file handles

Returns:

NF_STATUS_SUCCESS on success

Description:

Sets a new process limit for the number of file handles.

By default, the OS has a short limit on the number of file handles. It is possible to specify a larger limit if the filtering application uses its own sockets.