|
@@ -0,0 +1,1045 @@
|
|
|
|
+using System;
|
|
|
|
+using System.Collections.Generic;
|
|
|
|
+using System.Text;
|
|
|
|
+using System.Runtime.InteropServices;
|
|
|
|
+using System.Diagnostics;
|
|
|
|
+
|
|
|
|
+namespace nfapinet
|
|
|
|
+{
|
|
|
|
+ public 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
|
|
|
|
+ };
|
|
|
|
+
|
|
|
|
+ public 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
|
|
|
|
+ };
|
|
|
|
+
|
|
|
|
+ public 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
|
|
|
|
+ };
|
|
|
|
+
|
|
|
|
+ public enum NF_FLAGS
|
|
|
|
+ {
|
|
|
|
+ NFF_NONE = 0,
|
|
|
|
+ NFF_DONT_DISABLE_TEREDO = 1, // Don't disable Teredo
|
|
|
|
+ NFF_DONT_DISABLE_TCP_OFFLOADING = 2, // Don't disable TCP offloading
|
|
|
|
+ NFF_DISABLE_AUTO_REGISTER = 4, // Dont' try to register the driver automatically
|
|
|
|
+ NFF_DISABLE_AUTO_START = 8, // Dont' try to start the driver automatically
|
|
|
|
+ };
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ public enum NF_CONSTS
|
|
|
|
+ {
|
|
|
|
+ NF_MAX_ADDRESS_LENGTH = 28,
|
|
|
|
+ NF_MAX_IP_ADDRESS_LENGTH = 16
|
|
|
|
+ };
|
|
|
|
+
|
|
|
|
+ public enum NF_DRIVER_TYPE
|
|
|
|
+ {
|
|
|
|
+ DT_UNKNOWN = 0,
|
|
|
|
+ DT_TDI = 1,
|
|
|
|
+ DT_WFP = 2
|
|
|
|
+ };
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * Filtering rule
|
|
|
|
+ **/
|
|
|
|
+ [StructLayout(LayoutKind.Sequential, Pack = 1)]
|
|
|
|
+ public struct NF_RULE
|
|
|
|
+ {
|
|
|
|
+ public int protocol; // IPPROTO_TCP or IPPROTO_UDP
|
|
|
|
+ public UInt32 processId; // Process identifier
|
|
|
|
+ public Byte direction; // See NF_DIRECTION
|
|
|
|
+ public ushort localPort; // Local port
|
|
|
|
+ public ushort remotePort; // Remote port
|
|
|
|
+ public ushort ip_family; // AF_INET for IPv4 and AF_INET6 for IPv6
|
|
|
|
+
|
|
|
|
+ // Local IP (or network if localIpAddressMask is not zero)
|
|
|
|
+ [MarshalAs(UnmanagedType.ByValArray, SizeConst=(int)NF_CONSTS.NF_MAX_IP_ADDRESS_LENGTH)]
|
|
|
|
+ public byte[] localIpAddress;
|
|
|
|
+
|
|
|
|
+ // Local IP mask
|
|
|
|
+ [MarshalAs(UnmanagedType.ByValArray, SizeConst = (int)NF_CONSTS.NF_MAX_IP_ADDRESS_LENGTH)]
|
|
|
|
+ public byte[] localIpAddressMask;
|
|
|
|
+
|
|
|
|
+ // Remote IP (or network if remoteIpAddressMask is not zero)
|
|
|
|
+ [MarshalAs(UnmanagedType.ByValArray, SizeConst = (int)NF_CONSTS.NF_MAX_IP_ADDRESS_LENGTH)]
|
|
|
|
+ public byte[] remoteIpAddress;
|
|
|
|
+
|
|
|
|
+ // Remote IP mask
|
|
|
|
+ [MarshalAs(UnmanagedType.ByValArray, SizeConst = (int)NF_CONSTS.NF_MAX_IP_ADDRESS_LENGTH)]
|
|
|
|
+ public byte[] remoteIpAddressMask;
|
|
|
|
+
|
|
|
|
+ public UInt32 filteringFlag; // See NF_FILTERING_FLAG
|
|
|
|
+ };
|
|
|
|
+
|
|
|
|
+ [StructLayout(LayoutKind.Sequential, Pack = 1)]
|
|
|
|
+ public struct NF_PORT_RANGE
|
|
|
|
+ {
|
|
|
|
+ public ushort valueLow;
|
|
|
|
+ public ushort valueHigh;
|
|
|
|
+ };
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * Filtering rule with additional fields
|
|
|
|
+ **/
|
|
|
|
+ [StructLayout(LayoutKind.Sequential, Pack = 1, CharSet = CharSet.Unicode)]
|
|
|
|
+ public struct NF_RULE_EX
|
|
|
|
+ {
|
|
|
|
+ public int protocol; // IPPROTO_TCP or IPPROTO_UDP
|
|
|
|
+ public UInt32 processId; // Process identifier
|
|
|
|
+ public Byte direction; // See NF_DIRECTION
|
|
|
|
+ public ushort localPort; // Local port
|
|
|
|
+ public ushort remotePort; // Remote port
|
|
|
|
+ public ushort ip_family; // AF_INET for IPv4 and AF_INET6 for IPv6
|
|
|
|
+
|
|
|
|
+ // Local IP (or network if localIpAddressMask is not zero)
|
|
|
|
+ [MarshalAs(UnmanagedType.ByValArray, SizeConst = (int)NF_CONSTS.NF_MAX_IP_ADDRESS_LENGTH)]
|
|
|
|
+ public byte[] localIpAddress;
|
|
|
|
+
|
|
|
|
+ // Local IP mask
|
|
|
|
+ [MarshalAs(UnmanagedType.ByValArray, SizeConst = (int)NF_CONSTS.NF_MAX_IP_ADDRESS_LENGTH)]
|
|
|
|
+ public byte[] localIpAddressMask;
|
|
|
|
+
|
|
|
|
+ // Remote IP (or network if remoteIpAddressMask is not zero)
|
|
|
|
+ [MarshalAs(UnmanagedType.ByValArray, SizeConst = (int)NF_CONSTS.NF_MAX_IP_ADDRESS_LENGTH)]
|
|
|
|
+ public byte[] remoteIpAddress;
|
|
|
|
+
|
|
|
|
+ // Remote IP mask
|
|
|
|
+ [MarshalAs(UnmanagedType.ByValArray, SizeConst = (int)NF_CONSTS.NF_MAX_IP_ADDRESS_LENGTH)]
|
|
|
|
+ public byte[] remoteIpAddressMask;
|
|
|
|
+
|
|
|
|
+ public UInt32 filteringFlag; // See NF_FILTERING_FLAG
|
|
|
|
+
|
|
|
|
+ // Tail part of the process path mask
|
|
|
|
+ [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)]
|
|
|
|
+ public string processName;
|
|
|
|
+
|
|
|
|
+ public NF_PORT_RANGE localPortRange; // Local port(s)
|
|
|
|
+ public NF_PORT_RANGE remotePortRange; // Remote port(s)
|
|
|
|
+
|
|
|
|
+ // Remote address for redirection as sockaddr_in for IPv4 and sockaddr_in6 for IPv6
|
|
|
|
+ [MarshalAs(UnmanagedType.ByValArray, SizeConst = (int)NF_CONSTS.NF_MAX_ADDRESS_LENGTH)]
|
|
|
|
+ public byte[] redirectTo;
|
|
|
|
+
|
|
|
|
+ // Process identifier of a local proxy
|
|
|
|
+ public UInt32 localProxyProcessId;
|
|
|
|
+ };
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * TCP connection properties
|
|
|
|
+ **/
|
|
|
|
+ [StructLayout(LayoutKind.Sequential, Pack = 1)]
|
|
|
|
+ public struct NF_TCP_CONN_INFO
|
|
|
|
+ {
|
|
|
|
+ public UInt32 filteringFlag; // See NF_FILTERING_FLAG
|
|
|
|
+ public UInt32 processId; // Process identifier
|
|
|
|
+ public Byte direction; // See NF_DIRECTION
|
|
|
|
+ public ushort ip_family; // AF_INET for IPv4 and AF_INET6 for IPv6
|
|
|
|
+
|
|
|
|
+ // Local address as sockaddr_in for IPv4 and sockaddr_in6 for IPv6
|
|
|
|
+ [MarshalAs(UnmanagedType.ByValArray, SizeConst = (int)NF_CONSTS.NF_MAX_ADDRESS_LENGTH)]
|
|
|
|
+ public byte[] localAddress;
|
|
|
|
+
|
|
|
|
+ // Remote address as sockaddr_in for IPv4 and sockaddr_in6 for IPv6
|
|
|
|
+ [MarshalAs(UnmanagedType.ByValArray, SizeConst = (int)NF_CONSTS.NF_MAX_ADDRESS_LENGTH)]
|
|
|
|
+ public byte[] remoteAddress;
|
|
|
|
+ };
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * UDP endpoint properties
|
|
|
|
+ **/
|
|
|
|
+ [StructLayout(LayoutKind.Sequential, Pack = 1)]
|
|
|
|
+ public struct NF_UDP_CONN_INFO
|
|
|
|
+ {
|
|
|
|
+ public UInt32 processId; // Process identifier
|
|
|
|
+ public ushort ip_family; // AF_INET for IPv4 and AF_INET6 for IPv6
|
|
|
|
+
|
|
|
|
+ // Local address as sockaddr_in for IPv4 and sockaddr_in6 for IPv6
|
|
|
|
+ [MarshalAs(UnmanagedType.ByValArray, SizeConst = (int)NF_CONSTS.NF_MAX_ADDRESS_LENGTH)]
|
|
|
|
+ public byte[] localAddress;
|
|
|
|
+ };
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * UDP options
|
|
|
|
+ **/
|
|
|
|
+ [StructLayout(LayoutKind.Sequential, Pack = 1)]
|
|
|
|
+ public struct NF_UDP_OPTIONS
|
|
|
|
+ {
|
|
|
|
+ public UInt32 flags; // UDP flags
|
|
|
|
+ public Int32 optionsLength; // options length
|
|
|
|
+ [MarshalAs(UnmanagedType.ByValArray)]
|
|
|
|
+ public byte[] options; // Options array
|
|
|
|
+ };
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * UDP connect request properties
|
|
|
|
+ **/
|
|
|
|
+ [StructLayout(LayoutKind.Sequential, Pack = 1)]
|
|
|
|
+ public struct NF_UDP_CONN_REQUEST
|
|
|
|
+ {
|
|
|
|
+ public UInt32 filteringFlag; // See NF_FILTERING_FLAG
|
|
|
|
+ public UInt32 processId; // Process identifier
|
|
|
|
+ public ushort ip_family; // AF_INET for IPv4 and AF_INET6 for IPv6
|
|
|
|
+
|
|
|
|
+ // Local address as sockaddr_in for IPv4 and sockaddr_in6 for IPv6
|
|
|
|
+ [MarshalAs(UnmanagedType.ByValArray, SizeConst = (int)NF_CONSTS.NF_MAX_ADDRESS_LENGTH)]
|
|
|
|
+ public byte[] localAddress;
|
|
|
|
+
|
|
|
|
+ // Remote address as sockaddr_in for IPv4 and sockaddr_in6 for IPv6
|
|
|
|
+ [MarshalAs(UnmanagedType.ByValArray, SizeConst = (int)NF_CONSTS.NF_MAX_ADDRESS_LENGTH)]
|
|
|
|
+ public byte[] remoteAddress;
|
|
|
|
+ };
|
|
|
|
+
|
|
|
|
+ public 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).
|
|
|
|
+ };
|
|
|
|
+
|
|
|
|
+ [StructLayout(LayoutKind.Sequential, Pack = 1)]
|
|
|
|
+ public struct NF_IP_PACKET_OPTIONS
|
|
|
|
+ {
|
|
|
|
+ public ushort ip_family; // AF_INET for IPv4 and AF_INET6 for IPv6
|
|
|
|
+ public UInt32 ipHeaderSize; // Size in bytes of IP header
|
|
|
|
+ public UInt32 compartmentId; // Network routing compartment identifier (can be zero)
|
|
|
|
+ public UInt32 interfaceIndex; // Index of the interface on which the original packet data was received (irrelevant to outgoing packets)
|
|
|
|
+ public UInt32 subInterfaceIndex; // Index of the subinterface on which the original packet data was received (irrelevant to outgoing packets)
|
|
|
|
+ public UInt32 flags; // Can be a combination of flags from NF_IP_FLAG enumeration
|
|
|
|
+ };
|
|
|
|
+
|
|
|
|
+ [StructLayout(LayoutKind.Sequential, Pack = 1)]
|
|
|
|
+ public struct NF_FLOWCTL_DATA
|
|
|
|
+ {
|
|
|
|
+ public ulong inLimit;
|
|
|
|
+ public ulong outLimit;
|
|
|
|
+ };
|
|
|
|
+
|
|
|
|
+ [StructLayout(LayoutKind.Sequential, Pack = 1)]
|
|
|
|
+ public struct NF_FLOWCTL_MODIFY_DATA
|
|
|
|
+ {
|
|
|
|
+ public UInt32 fcHandle;
|
|
|
|
+ public NF_FLOWCTL_DATA data;
|
|
|
|
+ };
|
|
|
|
+
|
|
|
|
+ [StructLayout(LayoutKind.Sequential, Pack = 1)]
|
|
|
|
+ public struct NF_FLOWCTL_STAT
|
|
|
|
+ {
|
|
|
|
+ public ulong inBytes;
|
|
|
|
+ public ulong outBytes;
|
|
|
|
+ };
|
|
|
|
+
|
|
|
|
+ [StructLayout(LayoutKind.Sequential, Pack = 1)]
|
|
|
|
+ public struct NF_FLOWCTL_SET_DATA
|
|
|
|
+ {
|
|
|
|
+ public ulong endpointId;
|
|
|
|
+ public UInt32 fcHandle;
|
|
|
|
+ };
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * Binding rule
|
|
|
|
+ **/
|
|
|
|
+ [StructLayout(LayoutKind.Sequential, Pack = 1, CharSet = CharSet.Unicode)]
|
|
|
|
+ public struct NF_BINDING_RULE
|
|
|
|
+ {
|
|
|
|
+ // IPPROTO_TCP or IPPROTO_UDP
|
|
|
|
+ public int protocol;
|
|
|
|
+
|
|
|
|
+ // Process identifier
|
|
|
|
+ public UInt32 processId;
|
|
|
|
+
|
|
|
|
+ // Tail part of the process path mask
|
|
|
|
+ [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)]
|
|
|
|
+ public string processName;
|
|
|
|
+
|
|
|
|
+ // Local port
|
|
|
|
+ public ushort localPort;
|
|
|
|
+
|
|
|
|
+ // AF_INET for IPv4 and AF_INET6 for IPv6
|
|
|
|
+ public ushort ip_family;
|
|
|
|
+
|
|
|
|
+ // Local IP (or network if localIpAddressMask is not zero)
|
|
|
|
+ [MarshalAs(UnmanagedType.ByValArray, SizeConst = (int)NF_CONSTS.NF_MAX_IP_ADDRESS_LENGTH)]
|
|
|
|
+ public byte[] localIpAddress;
|
|
|
|
+
|
|
|
|
+ // Local IP mask
|
|
|
|
+ [MarshalAs(UnmanagedType.ByValArray, SizeConst = (int)NF_CONSTS.NF_MAX_IP_ADDRESS_LENGTH)]
|
|
|
|
+ public byte[] localIpAddressMask;
|
|
|
|
+
|
|
|
|
+ // Redirect bind request to this IP
|
|
|
|
+ [MarshalAs(UnmanagedType.ByValArray, SizeConst = (int)NF_CONSTS.NF_MAX_IP_ADDRESS_LENGTH)]
|
|
|
|
+ public byte[] newLocalIpAddress;
|
|
|
|
+
|
|
|
|
+ // Redirect bind request to this port, if it is not zero
|
|
|
|
+ public ushort newLocalPort;
|
|
|
|
+
|
|
|
|
+ // See NF_FILTERING_FLAG, NF_ALLOW or NF_FILTER
|
|
|
|
+ public ulong filteringFlag;
|
|
|
|
+ };
|
|
|
|
+
|
|
|
|
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
|
|
|
+ delegate void cbd_threadStart();
|
|
|
|
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
|
|
|
+ delegate void cbd_threadEnd();
|
|
|
|
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
|
|
|
+ delegate void cbd_tcpConnectRequest(ulong id, ref NF_TCP_CONN_INFO pConnInfo);
|
|
|
|
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
|
|
|
+ delegate void cbd_tcpConnected(ulong id, ref NF_TCP_CONN_INFO pConnInfo);
|
|
|
|
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
|
|
|
+ delegate void cbd_tcpClosed(ulong id, ref NF_TCP_CONN_INFO pConnInfo);
|
|
|
|
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
|
|
|
+ delegate void cbd_tcpReceive(ulong id, IntPtr buf, int len);
|
|
|
|
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
|
|
|
+ delegate void cbd_tcpSend(ulong id, IntPtr buf, int len);
|
|
|
|
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
|
|
|
+ delegate void cbd_tcpCanReceive(ulong id);
|
|
|
|
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
|
|
|
+ delegate void cbd_tcpCanSend(ulong id);
|
|
|
|
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
|
|
|
+ delegate void cbd_udpCreated(ulong id, ref NF_UDP_CONN_INFO pConnInfo);
|
|
|
|
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
|
|
|
+ delegate void cbd_udpConnectRequest(ulong id, ref NF_UDP_CONN_REQUEST pConnReq);
|
|
|
|
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
|
|
|
+ delegate void cbd_udpClosed(ulong id, ref NF_UDP_CONN_INFO pConnInfo);
|
|
|
|
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
|
|
|
+ delegate void cbd_udpReceive(ulong id, IntPtr remoteAddress, IntPtr buf, int len, IntPtr options);
|
|
|
|
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
|
|
|
+ delegate void cbd_udpSend(ulong id, IntPtr remoteAddress, IntPtr buf, int len, IntPtr options);
|
|
|
|
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
|
|
|
+ delegate void cbd_udpCanReceive(ulong id);
|
|
|
|
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
|
|
|
+ delegate void cbd_udpCanSend(ulong id);
|
|
|
|
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
|
|
|
+ delegate void cbd_ipReceive(IntPtr buf, int len, ref NF_IP_PACKET_OPTIONS ipOptions);
|
|
|
|
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
|
|
|
+ delegate void cbd_ipSend(IntPtr buf, int len, ref NF_IP_PACKET_OPTIONS ipOptions);
|
|
|
|
+
|
|
|
|
+ /*
|
|
|
|
+ * Event handler interface
|
|
|
|
+ */
|
|
|
|
+ public interface NF_EventHandler
|
|
|
|
+ {
|
|
|
|
+ void threadStart();
|
|
|
|
+ void threadEnd();
|
|
|
|
+ void tcpConnectRequest(ulong id, ref NF_TCP_CONN_INFO pConnInfo);
|
|
|
|
+ void tcpConnected(ulong id, NF_TCP_CONN_INFO pConnInfo);
|
|
|
|
+ void tcpClosed(ulong id, NF_TCP_CONN_INFO pConnInfo);
|
|
|
|
+ void tcpReceive(ulong id, IntPtr buf, int len);
|
|
|
|
+ void tcpSend(ulong id, IntPtr buf, int len);
|
|
|
|
+ void tcpCanReceive(ulong id);
|
|
|
|
+ void tcpCanSend(ulong id);
|
|
|
|
+ void udpCreated(ulong id, NF_UDP_CONN_INFO pConnInfo);
|
|
|
|
+ void udpConnectRequest(ulong id, ref NF_UDP_CONN_REQUEST pConnReq);
|
|
|
|
+ void udpClosed(ulong id, NF_UDP_CONN_INFO pConnInfo);
|
|
|
|
+ void udpReceive(ulong id, IntPtr remoteAddress, IntPtr buf, int len, IntPtr options, int optionsLen);
|
|
|
|
+ void udpSend(ulong id, IntPtr remoteAddress, IntPtr buf, int len, IntPtr options, int optionsLen);
|
|
|
|
+ void udpCanReceive(ulong id);
|
|
|
|
+ void udpCanSend(ulong id);
|
|
|
|
+ };
|
|
|
|
+
|
|
|
|
+ /*
|
|
|
|
+ * IP event handler interface
|
|
|
|
+ */
|
|
|
|
+ public interface NF_IPEventHandler
|
|
|
|
+ {
|
|
|
|
+ void ipReceive(IntPtr buf, int len, ref NF_IP_PACKET_OPTIONS ipOptions);
|
|
|
|
+ void ipSend(IntPtr buf, int len, ref NF_IP_PACKET_OPTIONS ipOptions);
|
|
|
|
+ };
|
|
|
|
+
|
|
|
|
+ /*
|
|
|
|
+ * Internal events forwarder
|
|
|
|
+ */
|
|
|
|
+ class NF_EventHandlerFwd
|
|
|
|
+ {
|
|
|
|
+ public static NF_EventHandler m_pEventHandler = null;
|
|
|
|
+
|
|
|
|
+ public static void threadStart()
|
|
|
|
+ {
|
|
|
|
+ m_pEventHandler.threadStart();
|
|
|
|
+ }
|
|
|
|
+ public static void threadEnd()
|
|
|
|
+ {
|
|
|
|
+ m_pEventHandler.threadEnd();
|
|
|
|
+ }
|
|
|
|
+ public static void tcpConnectRequest(ulong id, ref NF_TCP_CONN_INFO pConnInfo)
|
|
|
|
+ {
|
|
|
|
+ m_pEventHandler.tcpConnectRequest(id, ref pConnInfo);
|
|
|
|
+ }
|
|
|
|
+ public static void tcpConnected(ulong id, ref NF_TCP_CONN_INFO pConnInfo)
|
|
|
|
+ {
|
|
|
|
+ m_pEventHandler.tcpConnected(id, pConnInfo);
|
|
|
|
+ }
|
|
|
|
+ public static void tcpClosed(ulong id, ref NF_TCP_CONN_INFO pConnInfo)
|
|
|
|
+ {
|
|
|
|
+ m_pEventHandler.tcpClosed(id, pConnInfo);
|
|
|
|
+ }
|
|
|
|
+ public static void tcpReceive(ulong id, IntPtr buf, int len)
|
|
|
|
+ {
|
|
|
|
+ m_pEventHandler.tcpReceive(id, buf, len);
|
|
|
|
+ }
|
|
|
|
+ public static void tcpSend(ulong id, IntPtr buf, int len)
|
|
|
|
+ {
|
|
|
|
+ m_pEventHandler.tcpSend(id, buf, len);
|
|
|
|
+ }
|
|
|
|
+ public static void tcpCanReceive(ulong id)
|
|
|
|
+ {
|
|
|
|
+ m_pEventHandler.tcpCanReceive(id);
|
|
|
|
+ }
|
|
|
|
+ public static void tcpCanSend(ulong id)
|
|
|
|
+ {
|
|
|
|
+ m_pEventHandler.tcpCanSend(id);
|
|
|
|
+ }
|
|
|
|
+ public static void udpCreated(ulong id, ref NF_UDP_CONN_INFO pConnInfo)
|
|
|
|
+ {
|
|
|
|
+ m_pEventHandler.udpCreated(id, pConnInfo);
|
|
|
|
+ }
|
|
|
|
+ public static void udpConnectRequest(ulong id, ref NF_UDP_CONN_REQUEST pConnReq)
|
|
|
|
+ {
|
|
|
|
+ m_pEventHandler.udpConnectRequest(id, ref pConnReq);
|
|
|
|
+ }
|
|
|
|
+ public static void udpClosed(ulong id, ref NF_UDP_CONN_INFO pConnInfo)
|
|
|
|
+ {
|
|
|
|
+ m_pEventHandler.udpClosed(id, pConnInfo);
|
|
|
|
+ }
|
|
|
|
+ public static void udpReceive(ulong id, IntPtr remoteAddress, IntPtr buf, int len, IntPtr options)
|
|
|
|
+ {
|
|
|
|
+ if (options.ToInt64() != 0)
|
|
|
|
+ {
|
|
|
|
+ NF_UDP_OPTIONS optionsCopy = (NF_UDP_OPTIONS)Marshal.PtrToStructure((IntPtr)options, typeof(NF_UDP_OPTIONS));
|
|
|
|
+ int optionsLen = 8 + optionsCopy.optionsLength;
|
|
|
|
+ m_pEventHandler.udpReceive(id, remoteAddress, buf, len, options, optionsLen);
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ m_pEventHandler.udpReceive(id, remoteAddress, buf, len, (IntPtr)null, 0);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ public static void udpSend(ulong id, IntPtr remoteAddress, IntPtr buf, int len, IntPtr options)
|
|
|
|
+ {
|
|
|
|
+ if (options.ToInt64() != 0)
|
|
|
|
+ {
|
|
|
|
+ NF_UDP_OPTIONS optionsCopy = (NF_UDP_OPTIONS)Marshal.PtrToStructure((IntPtr)options, typeof(NF_UDP_OPTIONS));
|
|
|
|
+ int optionsLen = 8 + optionsCopy.optionsLength;
|
|
|
|
+ m_pEventHandler.udpSend(id, remoteAddress, buf, len, options, optionsLen);
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ m_pEventHandler.udpSend(id, remoteAddress, buf, len, (IntPtr)null, 0);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ public static void udpCanReceive(ulong id)
|
|
|
|
+ {
|
|
|
|
+ m_pEventHandler.udpCanReceive(id);
|
|
|
|
+ }
|
|
|
|
+ public static void udpCanSend(ulong id)
|
|
|
|
+ {
|
|
|
|
+ m_pEventHandler.udpCanSend(id);
|
|
|
|
+ }
|
|
|
|
+ };
|
|
|
|
+
|
|
|
|
+ /*
|
|
|
|
+ * Internal IP events forwarder
|
|
|
|
+ */
|
|
|
|
+ class NF_IPEventHandlerFwd
|
|
|
|
+ {
|
|
|
|
+ public static NF_IPEventHandler m_pEventHandler = null;
|
|
|
|
+
|
|
|
|
+ public static void ipReceive(IntPtr buf, int len, ref NF_IP_PACKET_OPTIONS ipOptions)
|
|
|
|
+ {
|
|
|
|
+ m_pEventHandler.ipReceive(buf, len, ref ipOptions);
|
|
|
|
+ }
|
|
|
|
+ public static void ipSend(IntPtr buf, int len, ref NF_IP_PACKET_OPTIONS ipOptions)
|
|
|
|
+ {
|
|
|
|
+ m_pEventHandler.ipSend(buf, len, ref ipOptions);
|
|
|
|
+ }
|
|
|
|
+ };
|
|
|
|
+
|
|
|
|
+ /*
|
|
|
|
+ * Event handler structure for C API
|
|
|
|
+ */
|
|
|
|
+ [StructLayout(LayoutKind.Sequential, Pack=1)]
|
|
|
|
+ struct NF_EventHandlerInternal
|
|
|
|
+ {
|
|
|
|
+ public cbd_threadStart threadStart;
|
|
|
|
+ public cbd_threadEnd threadEnd;
|
|
|
|
+ public cbd_tcpConnectRequest tcpConnectRequest;
|
|
|
|
+ public cbd_tcpConnected tcpConnected;
|
|
|
|
+ public cbd_tcpClosed tcpClosed;
|
|
|
|
+ public cbd_tcpReceive tcpReceive;
|
|
|
|
+ public cbd_tcpSend tcpSend;
|
|
|
|
+ public cbd_tcpCanReceive tcpCanReceive;
|
|
|
|
+ public cbd_tcpCanSend tcpCanSend;
|
|
|
|
+ public cbd_udpCreated udpCreated;
|
|
|
|
+ public cbd_udpConnectRequest udpConnectRequest;
|
|
|
|
+ public cbd_udpClosed udpClosed;
|
|
|
|
+ public cbd_udpReceive udpReceive;
|
|
|
|
+ public cbd_udpSend udpSend;
|
|
|
|
+ public cbd_udpCanReceive udpCanReceive;
|
|
|
|
+ public cbd_udpCanSend udpCanSend;
|
|
|
|
+ };
|
|
|
|
+
|
|
|
|
+ /*
|
|
|
|
+ * IP event handler structure for C API
|
|
|
|
+ */
|
|
|
|
+ [StructLayout(LayoutKind.Sequential, Pack = 1)]
|
|
|
|
+ struct NF_IPEventHandlerInternal
|
|
|
|
+ {
|
|
|
|
+ public cbd_ipReceive ipReceive;
|
|
|
|
+ public cbd_ipSend ipSend;
|
|
|
|
+ };
|
|
|
|
+
|
|
|
|
+ // Managed wrapper over API
|
|
|
|
+ public class NFAPI
|
|
|
|
+ {
|
|
|
|
+ private static IntPtr m_pEventHandlerRaw = (IntPtr)null;
|
|
|
|
+ private static NF_EventHandlerInternal m_pEventHandler;
|
|
|
|
+ private static IntPtr m_pIPEventHandlerRaw = (IntPtr)null;
|
|
|
|
+ private static NF_IPEventHandlerInternal m_pIPEventHandler;
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 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
|
|
|
|
+ **/
|
|
|
|
+ [DllImport("nfapinet", CallingConvention=CallingConvention.Cdecl)]
|
|
|
|
+ public static extern NF_STATUS nf_init(String driverName, IntPtr pHandler);
|
|
|
|
+
|
|
|
|
+ public static NF_STATUS nf_init(String driverName, NF_EventHandler pHandler)
|
|
|
|
+ {
|
|
|
|
+ NF_EventHandlerFwd.m_pEventHandler = pHandler;
|
|
|
|
+
|
|
|
|
+ nf_adjustProcessPriviledges();
|
|
|
|
+
|
|
|
|
+ m_pEventHandler = new NF_EventHandlerInternal();
|
|
|
|
+
|
|
|
|
+ m_pEventHandler.threadStart = new cbd_threadStart(NF_EventHandlerFwd.threadStart);
|
|
|
|
+ m_pEventHandler.threadEnd = new cbd_threadEnd(NF_EventHandlerFwd.threadEnd);
|
|
|
|
+ m_pEventHandler.tcpConnectRequest = new cbd_tcpConnectRequest(NF_EventHandlerFwd.tcpConnectRequest);
|
|
|
|
+ m_pEventHandler.tcpConnected = new cbd_tcpConnected(NF_EventHandlerFwd.tcpConnected);
|
|
|
|
+ m_pEventHandler.tcpClosed = new cbd_tcpClosed(NF_EventHandlerFwd.tcpClosed);
|
|
|
|
+ m_pEventHandler.tcpReceive = new cbd_tcpReceive(NF_EventHandlerFwd.tcpReceive);
|
|
|
|
+ m_pEventHandler.tcpSend = new cbd_tcpSend(NF_EventHandlerFwd.tcpSend);
|
|
|
|
+ m_pEventHandler.tcpCanReceive = new cbd_tcpCanReceive(NF_EventHandlerFwd.tcpCanReceive);
|
|
|
|
+ m_pEventHandler.tcpCanSend = new cbd_tcpCanSend(NF_EventHandlerFwd.tcpCanSend);
|
|
|
|
+ m_pEventHandler.udpCreated = new cbd_udpCreated(NF_EventHandlerFwd.udpCreated);
|
|
|
|
+ m_pEventHandler.udpConnectRequest = new cbd_udpConnectRequest(NF_EventHandlerFwd.udpConnectRequest);
|
|
|
|
+ m_pEventHandler.udpClosed = new cbd_udpClosed(NF_EventHandlerFwd.udpClosed);
|
|
|
|
+ m_pEventHandler.udpReceive = new cbd_udpReceive(NF_EventHandlerFwd.udpReceive);
|
|
|
|
+ m_pEventHandler.udpSend = new cbd_udpSend(NF_EventHandlerFwd.udpSend);
|
|
|
|
+ m_pEventHandler.udpCanReceive = new cbd_udpCanReceive(NF_EventHandlerFwd.udpCanReceive);
|
|
|
|
+ m_pEventHandler.udpCanSend = new cbd_udpCanSend(NF_EventHandlerFwd.udpCanSend);
|
|
|
|
+
|
|
|
|
+ m_pEventHandlerRaw = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(NF_EventHandlerInternal)));
|
|
|
|
+ Marshal.StructureToPtr(m_pEventHandler, m_pEventHandlerRaw, true);
|
|
|
|
+
|
|
|
|
+ return nf_init(driverName, m_pEventHandlerRaw);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * Stops the filtering thread, breaks all filtered connections and closes
|
|
|
|
+ * a connection with the hooking driver.
|
|
|
|
+ **/
|
|
|
|
+ [DllImport("nfapinet", CallingConvention = CallingConvention.Cdecl)]
|
|
|
|
+ public static extern void nf_free();
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * Registers and starts a driver with specified name (without ".sys" extension)
|
|
|
|
+ * @param driverName
|
|
|
|
+ **/
|
|
|
|
+ [DllImport("nfapinet", CallingConvention = CallingConvention.Cdecl)]
|
|
|
|
+ public static extern NF_STATUS nf_registerDriver(String driverName);
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * Registers and starts a driver with specified name (without ".sys" extension) and path to driver folder
|
|
|
|
+ * @param driverName
|
|
|
|
+ * @param driverPath
|
|
|
|
+ **/
|
|
|
|
+ [DllImport("nfapinet", CallingConvention = CallingConvention.Cdecl)]
|
|
|
|
+ public static extern NF_STATUS nf_registerDriverEx(String driverName, String driverPath);
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * Unregisters a driver with specified name (without ".sys" extension)
|
|
|
|
+ * @param driverName
|
|
|
|
+ **/
|
|
|
|
+ [DllImport("nfapinet", CallingConvention = CallingConvention.Cdecl)]
|
|
|
|
+ public static extern NF_STATUS nf_unRegisterDriver(String driverName);
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ //
|
|
|
|
+ // TCP control routines
|
|
|
|
+ //
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * Suspends or resumes indicating of sends and receives for specified connection.
|
|
|
|
+ * @param id Connection identifier
|
|
|
|
+ * @param suspended true for suspend, false for resume
|
|
|
|
+ **/
|
|
|
|
+ [DllImport("nfapinet", CallingConvention = CallingConvention.Cdecl)]
|
|
|
|
+ public static extern NF_STATUS nf_tcpSetConnectionState(ulong 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
|
|
|
|
+ **/
|
|
|
|
+ [DllImport("nfapinet", CallingConvention = CallingConvention.Cdecl)]
|
|
|
|
+ public static extern NF_STATUS nf_tcpPostSend(ulong id, IntPtr 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
|
|
|
|
+ **/
|
|
|
|
+ [DllImport("nfapinet", CallingConvention = CallingConvention.Cdecl)]
|
|
|
|
+ public static extern NF_STATUS nf_tcpPostReceive(ulong id, IntPtr buf, int len);
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * Breaks the connection with given id.
|
|
|
|
+ * @param id Connection identifier
|
|
|
|
+ **/
|
|
|
|
+ [DllImport("nfapinet", CallingConvention = CallingConvention.Cdecl)]
|
|
|
|
+ public static extern NF_STATUS nf_tcpClose(ulong id);
|
|
|
|
+
|
|
|
|
+ //
|
|
|
|
+ // UDP control routines
|
|
|
|
+ //
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * Suspends or resumes indicating of sends and receives for specified socket.
|
|
|
|
+ * @param id Socket identifier
|
|
|
|
+ * @param suspended true for suspend, false for resume
|
|
|
|
+ **/
|
|
|
|
+ [DllImport("nfapinet", CallingConvention = CallingConvention.Cdecl)]
|
|
|
|
+ public static extern NF_STATUS nf_udpSetConnectionState(ulong id, int suspended);
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * Sends the buffer to remote server via specified socket.
|
|
|
|
+ * @param id Socket identifier
|
|
|
|
+ * @param remoteAddress Destination address
|
|
|
|
+ * @param buf Pointer to data buffer
|
|
|
|
+ * @param len Buffer length
|
|
|
|
+ **/
|
|
|
|
+ [DllImport("nfapinet", CallingConvention = CallingConvention.Cdecl)]
|
|
|
|
+ public static extern NF_STATUS nf_udpPostSend(ulong id,
|
|
|
|
+ IntPtr remoteAddress,
|
|
|
|
+ IntPtr buf, int len,
|
|
|
|
+ IntPtr options);
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * Indicates the buffer to local process via specified socket.
|
|
|
|
+ * @param id Unique connection identifier
|
|
|
|
+ * @param remoteAddress Source address
|
|
|
|
+ * @param buf Pointer to data buffer
|
|
|
|
+ * @param len Buffer length
|
|
|
|
+ **/
|
|
|
|
+ [DllImport("nfapinet", CallingConvention = CallingConvention.Cdecl)]
|
|
|
|
+ public static extern NF_STATUS nf_udpPostReceive(ulong id,
|
|
|
|
+ IntPtr remoteAddress,
|
|
|
|
+ IntPtr buf, int len,
|
|
|
|
+ IntPtr options);
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * Indicates a packet to TCP/IP stack
|
|
|
|
+ * @param buf Pointer to IP packet
|
|
|
|
+ * @param len Buffer length
|
|
|
|
+ * @param options IP options
|
|
|
|
+ **/
|
|
|
|
+ [DllImport("nfapinet", CallingConvention = CallingConvention.Cdecl)]
|
|
|
|
+ public static extern NF_STATUS nf_ipPostReceive(
|
|
|
|
+ IntPtr buf, int len,
|
|
|
|
+ ref NF_IP_PACKET_OPTIONS options);
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * Sends a packet to remote IP
|
|
|
|
+ * @param buf Pointer to IP packet
|
|
|
|
+ * @param len Buffer length
|
|
|
|
+ * @param options IP options
|
|
|
|
+ **/
|
|
|
|
+ [DllImport("nfapinet", CallingConvention = CallingConvention.Cdecl)]
|
|
|
|
+ public static extern NF_STATUS nf_ipPostSend(
|
|
|
|
+ IntPtr buf, int len,
|
|
|
|
+ ref NF_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
|
|
|
|
+ **/
|
|
|
|
+ [DllImport("nfapinet", CallingConvention = CallingConvention.Cdecl)]
|
|
|
|
+ private static extern NF_STATUS nf_addRule(ref NF_RULE pRule, int toHead);
|
|
|
|
+
|
|
|
|
+ private static void updateAddressLength(ref byte[] buf)
|
|
|
|
+ {
|
|
|
|
+ if (buf == null)
|
|
|
|
+ {
|
|
|
|
+ buf = new byte[(int)NF_CONSTS.NF_MAX_IP_ADDRESS_LENGTH];
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ if (buf.Length < (int)NF_CONSTS.NF_MAX_IP_ADDRESS_LENGTH)
|
|
|
|
+ {
|
|
|
|
+ Array.Resize(ref buf, (int)NF_CONSTS.NF_MAX_IP_ADDRESS_LENGTH);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ public static NF_STATUS nf_addRule(NF_RULE pRule, int toHead)
|
|
|
|
+ {
|
|
|
|
+ updateAddressLength(ref pRule.localIpAddress);
|
|
|
|
+ updateAddressLength(ref pRule.localIpAddressMask);
|
|
|
|
+ updateAddressLength(ref pRule.remoteIpAddress);
|
|
|
|
+ updateAddressLength(ref pRule.remoteIpAddressMask);
|
|
|
|
+
|
|
|
|
+ return nf_addRule(ref pRule, toHead);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 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
|
|
|
|
+ **/
|
|
|
|
+ [DllImport("nfapinet", CallingConvention = CallingConvention.Cdecl)]
|
|
|
|
+ private static extern NF_STATUS nf_addRuleEx(ref NF_RULE_EX pRule, int toHead);
|
|
|
|
+
|
|
|
|
+ public static NF_STATUS nf_addRuleEx(NF_RULE_EX pRule, int toHead)
|
|
|
|
+ {
|
|
|
|
+ updateAddressLength(ref pRule.localIpAddress);
|
|
|
|
+ updateAddressLength(ref pRule.localIpAddressMask);
|
|
|
|
+ updateAddressLength(ref pRule.remoteIpAddress);
|
|
|
|
+ updateAddressLength(ref pRule.remoteIpAddressMask);
|
|
|
|
+
|
|
|
|
+ return nf_addRuleEx(ref pRule, toHead);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 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
|
|
|
|
+ **/
|
|
|
|
+ [DllImport("nfapinet", CallingConvention = CallingConvention.Cdecl)]
|
|
|
|
+ private static extern NF_STATUS nf_setRules(IntPtr pRules, int count);
|
|
|
|
+
|
|
|
|
+ public static NF_STATUS nf_setRules(NF_RULE[] rules)
|
|
|
|
+ {
|
|
|
|
+ NF_RULE pRule;
|
|
|
|
+
|
|
|
|
+ IntPtr ptr = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(NF_RULE)) * rules.Length);
|
|
|
|
+
|
|
|
|
+ long longPtr = ptr.ToInt64();
|
|
|
|
+ for (int i = 0; i < rules.Length; i++)
|
|
|
|
+ {
|
|
|
|
+ pRule = rules[i];
|
|
|
|
+
|
|
|
|
+ updateAddressLength(ref pRule.localIpAddress);
|
|
|
|
+ updateAddressLength(ref pRule.localIpAddressMask);
|
|
|
|
+ updateAddressLength(ref pRule.remoteIpAddress);
|
|
|
|
+ updateAddressLength(ref pRule.remoteIpAddressMask);
|
|
|
|
+
|
|
|
|
+ Marshal.StructureToPtr(pRule, new IntPtr(longPtr), false);
|
|
|
|
+
|
|
|
|
+ longPtr += Marshal.SizeOf(typeof(NF_RULE));
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return nf_setRules(ptr, rules.Length);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 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
|
|
|
|
+ **/
|
|
|
|
+ [DllImport("nfapinet", CallingConvention = CallingConvention.Cdecl)]
|
|
|
|
+ private static extern NF_STATUS nf_setRulesEx(IntPtr pRules, int count);
|
|
|
|
+
|
|
|
|
+ public static NF_STATUS nf_setRulesEx(NF_RULE_EX[] rules)
|
|
|
|
+ {
|
|
|
|
+ NF_RULE_EX pRule;
|
|
|
|
+
|
|
|
|
+ IntPtr ptr = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(NF_RULE_EX)) * rules.Length);
|
|
|
|
+
|
|
|
|
+ long longPtr = ptr.ToInt64();
|
|
|
|
+ for (int i = 0; i < rules.Length; i++)
|
|
|
|
+ {
|
|
|
|
+ pRule = rules[i];
|
|
|
|
+
|
|
|
|
+ updateAddressLength(ref pRule.localIpAddress);
|
|
|
|
+ updateAddressLength(ref pRule.localIpAddressMask);
|
|
|
|
+ updateAddressLength(ref pRule.remoteIpAddress);
|
|
|
|
+ updateAddressLength(ref pRule.remoteIpAddressMask);
|
|
|
|
+
|
|
|
|
+ Marshal.StructureToPtr(pRule, new IntPtr(longPtr), false);
|
|
|
|
+
|
|
|
|
+ longPtr += Marshal.SizeOf(typeof(NF_RULE_EX));
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return nf_setRules(ptr, rules.Length);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * Removes all rules from driver.
|
|
|
|
+ **/
|
|
|
|
+ [DllImport("nfapinet", CallingConvention = CallingConvention.Cdecl)]
|
|
|
|
+ public static extern NF_STATUS nf_deleteRules();
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * Sets the timeout for TCP connections and returns old timeout.
|
|
|
|
+ * @param timeout Timeout value in milliseconds. Specify zero value to disable timeouts.
|
|
|
|
+ */
|
|
|
|
+ [DllImport("nfapinet", CallingConvention = CallingConvention.Cdecl)]
|
|
|
|
+ public static extern UInt32 nf_setTCPTimeout(UInt32 timeout);
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * Disables indicating TCP packets to user mode for the specified endpoint
|
|
|
|
+ * @param id Socket identifier
|
|
|
|
+ */
|
|
|
|
+ [DllImport("nfapinet", CallingConvention = CallingConvention.Cdecl)]
|
|
|
|
+ public static extern NF_STATUS nf_tcpDisableFiltering(ulong id);
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * Disables indicating UDP packets to user mode for the specified endpoint
|
|
|
|
+ * @param id Socket identifier
|
|
|
|
+ */
|
|
|
|
+ [DllImport("nfapinet", CallingConvention = CallingConvention.Cdecl)]
|
|
|
|
+ public static extern NF_STATUS nf_udpDisableFiltering(ulong id);
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * Returns TRUE if the specified process acts as a local proxy, accepting the redirected TCP connections.
|
|
|
|
+ **/
|
|
|
|
+ [DllImport("nfapinet", CallingConvention = CallingConvention.Cdecl)]
|
|
|
|
+ private static extern bool nf_tcpIsProxy(uint 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>
|
|
|
|
+ **/
|
|
|
|
+ [DllImport("nfapinet", CallingConvention = CallingConvention.Cdecl)]
|
|
|
|
+ public static extern void nf_setOptions(uint nThreads, uint flags);
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * Complete TCP connect request pended using flag NF_PEND_CONNECT_REQUEST.
|
|
|
|
+ **/
|
|
|
|
+ [DllImport("nfapinet", CallingConvention = CallingConvention.Cdecl)]
|
|
|
|
+ public static extern NF_STATUS nf_completeTCPConnectRequest(ulong id, ref NF_TCP_CONN_INFO pConnInfo);
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * Complete UDP connect request pended using flag NF_PEND_CONNECT_REQUEST.
|
|
|
|
+ **/
|
|
|
|
+ [DllImport("nfapinet", CallingConvention = CallingConvention.Cdecl)]
|
|
|
|
+ public static extern NF_STATUS nf_completeUDPConnectRequest(ulong id, ref NF_UDP_CONN_REQUEST pConnInfo);
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * Returns in pConnInfo the properties of TCP connection with specified id.
|
|
|
|
+ **/
|
|
|
|
+ [DllImport("nfapinet", CallingConvention = CallingConvention.Cdecl)]
|
|
|
|
+ public static extern NF_STATUS nf_getTCPConnInfo(ulong id, ref NF_TCP_CONN_INFO pConnInfo);
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * Returns in pConnInfo the properties of UDP socket with specified id.
|
|
|
|
+ **/
|
|
|
|
+ [DllImport("nfapinet", CallingConvention = CallingConvention.Cdecl)]
|
|
|
|
+ public static extern NF_STATUS nf_getUDPConnInfo(ulong id, ref NF_UDP_CONN_INFO pConnInfo);
|
|
|
|
+
|
|
|
|
+ [DllImport("nfapinet", CallingConvention = CallingConvention.Cdecl)]
|
|
|
|
+ private static extern bool nf_getProcessNameW(uint processId, IntPtr buf, int len);
|
|
|
|
+
|
|
|
|
+ [DllImport("nfapinet", CallingConvention = CallingConvention.Cdecl)]
|
|
|
|
+ private static extern bool nf_getProcessNameFromKernel(uint processId, IntPtr buf, int len);
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * Returns the process name for given process id
|
|
|
|
+ **/
|
|
|
|
+ public static unsafe String nf_getProcessNameFromKernel(UInt32 processId)
|
|
|
|
+ {
|
|
|
|
+ char[] buf = new char[1024];
|
|
|
|
+
|
|
|
|
+ fixed (char* p = buf)
|
|
|
|
+ {
|
|
|
|
+ if (nf_getProcessNameFromKernel(processId, (IntPtr)p, buf.Length))
|
|
|
|
+ {
|
|
|
|
+ return Marshal.PtrToStringUni((IntPtr)p);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return "System";
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * Returns the process name for given process id
|
|
|
|
+ **/
|
|
|
|
+ public static unsafe String nf_getProcessName(UInt32 processId)
|
|
|
|
+ {
|
|
|
|
+ char[] buf = new char[256];
|
|
|
|
+
|
|
|
|
+ fixed (char* p = buf)
|
|
|
|
+ {
|
|
|
|
+ if (nf_getProcessNameW(processId, (IntPtr)p, buf.Length))
|
|
|
|
+ {
|
|
|
|
+ return Marshal.PtrToStringUni((IntPtr)p);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return "System";
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ [DllImport("nfapinet", CallingConvention = CallingConvention.Cdecl)]
|
|
|
|
+ public static extern void nf_adjustProcessPriviledges();
|
|
|
|
+
|
|
|
|
+ /*
|
|
|
|
+ * Set the event handler for IP filtering events
|
|
|
|
+ */
|
|
|
|
+ [DllImport("nfapinet", CallingConvention = CallingConvention.Cdecl)]
|
|
|
|
+ private static extern void nf_setIPEventHandler(IntPtr pHandler);
|
|
|
|
+
|
|
|
|
+ /*
|
|
|
|
+ * Set the event handler for IP filtering events
|
|
|
|
+ */
|
|
|
|
+ public static void nf_setIPEventHandler(NF_IPEventHandler pHandler)
|
|
|
|
+ {
|
|
|
|
+ NF_IPEventHandlerFwd.m_pEventHandler = pHandler;
|
|
|
|
+
|
|
|
|
+ m_pIPEventHandler = new NF_IPEventHandlerInternal();
|
|
|
|
+
|
|
|
|
+ m_pIPEventHandler.ipReceive = new cbd_ipReceive(NF_IPEventHandlerFwd.ipReceive);
|
|
|
|
+ m_pIPEventHandler.ipSend = new cbd_ipSend(NF_IPEventHandlerFwd.ipSend);
|
|
|
|
+
|
|
|
|
+ m_pIPEventHandlerRaw = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(NF_IPEventHandlerInternal)));
|
|
|
|
+ Marshal.StructureToPtr(m_pIPEventHandler, m_pIPEventHandlerRaw, true);
|
|
|
|
+
|
|
|
|
+ nf_setIPEventHandler(m_pIPEventHandlerRaw);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * Add flow control context
|
|
|
|
+ */
|
|
|
|
+ [DllImport("nfapinet", CallingConvention = CallingConvention.Cdecl)]
|
|
|
|
+ public static extern NF_STATUS nf_addFlowCtl(ref NF_FLOWCTL_DATA pData, ref UInt32 pFcHandle);
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * Delete flow control context
|
|
|
|
+ */
|
|
|
|
+ [DllImport("nfapinet", CallingConvention = CallingConvention.Cdecl)]
|
|
|
|
+ public static extern NF_STATUS nf_deleteFlowCtl(UInt32 fcHandle);
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * Associate flow control context with TCP connection
|
|
|
|
+ */
|
|
|
|
+ [DllImport("nfapinet", CallingConvention = CallingConvention.Cdecl)]
|
|
|
|
+ public static extern NF_STATUS nf_setTCPFlowCtl(ulong id, UInt32 fcHandle);
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * Associate flow control context with UDP socket
|
|
|
|
+ */
|
|
|
|
+ [DllImport("nfapinet", CallingConvention = CallingConvention.Cdecl)]
|
|
|
|
+ public static extern NF_STATUS nf_setUDPFlowCtl(ulong id, UInt32 fcHandle);
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * Modify flow control context limits
|
|
|
|
+ */
|
|
|
|
+ [DllImport("nfapinet", CallingConvention = CallingConvention.Cdecl)]
|
|
|
|
+ public static extern NF_STATUS nf_modifyFlowCtl(UInt32 fcHandle, ref NF_FLOWCTL_DATA pData);
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * Get flow control context statistics as the numbers of in/out bytes
|
|
|
|
+ */
|
|
|
|
+ [DllImport("nfapinet", CallingConvention = CallingConvention.Cdecl)]
|
|
|
|
+ public static extern NF_STATUS nf_getFlowCtlStat(UInt32 fcHandle, ref NF_FLOWCTL_STAT pStat);
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * Get TCP connection statistics as the numbers of in/out bytes.
|
|
|
|
+ * The function can be called only from tcpClosed handler!
|
|
|
|
+ */
|
|
|
|
+ [DllImport("nfapinet", CallingConvention = CallingConvention.Cdecl)]
|
|
|
|
+ public static extern NF_STATUS nf_getTCPStat(ulong id, ref NF_FLOWCTL_STAT pStat);
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * Get UDP socket statistics as the numbers of in/out bytes.
|
|
|
|
+ * The function can be called only from udpClosed handler!
|
|
|
|
+ */
|
|
|
|
+ [DllImport("nfapinet", CallingConvention = CallingConvention.Cdecl)]
|
|
|
|
+ public static extern NF_STATUS nf_getUDPStat(ulong id, ref NF_FLOWCTL_STAT pStat);
|
|
|
|
+
|
|
|
|
+ public enum NF_SOCKET_OPTIONS
|
|
|
|
+ {
|
|
|
|
+ TCP_SOCKET_NODELAY = 1,
|
|
|
|
+ TCP_SOCKET_KEEPALIVE = 2,
|
|
|
|
+ TCP_SOCKET_OOBINLINE = 3,
|
|
|
|
+ TCP_SOCKET_BSDURGENT = 4,
|
|
|
|
+ TCP_SOCKET_ATMARK = 5,
|
|
|
|
+ TCP_SOCKET_WINDOW = 6
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ [DllImport("nfapinet", CallingConvention = CallingConvention.Cdecl)]
|
|
|
|
+ public static extern NF_STATUS nf_tcpSetSockOpt(ulong id, NF_SOCKET_OPTIONS optname, ref int optval, int optlen);
|
|
|
|
+
|
|
|
|
+ [DllImport("nfapinet", CallingConvention = CallingConvention.Cdecl)]
|
|
|
|
+ public static extern NF_STATUS nf_tcpSetSockOpt(ulong id, NF_SOCKET_OPTIONS optname, IntPtr optval, int optlen);
|
|
|
|
+
|
|
|
|
+ public static NF_STATUS nf_tcpSetSockOpt(ulong id, NF_SOCKET_OPTIONS optname, bool optval)
|
|
|
|
+ {
|
|
|
|
+ int dword = optval ? 1 : 0;
|
|
|
|
+ return nf_tcpSetSockOpt(id, optname, ref dword, Marshal.SizeOf(typeof(int)));
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * Add binding rule to driver
|
|
|
|
+ */
|
|
|
|
+ [DllImport("nfapinet", CallingConvention = CallingConvention.Cdecl)]
|
|
|
|
+ private static extern NF_STATUS
|
|
|
|
+ nf_addBindingRule(ref NF_BINDING_RULE pRule, int toHead);
|
|
|
|
+
|
|
|
|
+ public static NF_STATUS
|
|
|
|
+ nf_addBindingRule(NF_BINDING_RULE pRule, int toHead)
|
|
|
|
+ {
|
|
|
|
+ updateAddressLength(ref pRule.localIpAddress);
|
|
|
|
+ updateAddressLength(ref pRule.localIpAddressMask);
|
|
|
|
+ updateAddressLength(ref pRule.newLocalIpAddress);
|
|
|
|
+
|
|
|
|
+ return nf_addBindingRule(ref pRule, toHead);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * Delete all binding rules from driver
|
|
|
|
+ */
|
|
|
|
+ [DllImport("nfapinet", CallingConvention = CallingConvention.Cdecl)]
|
|
|
|
+ public static extern NF_STATUS
|
|
|
|
+ nf_deleteBindingRules();
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * Returns the type of attached driver (DT_WFP, DT_TDI or DT_UNKNOWN)
|
|
|
|
+ */
|
|
|
|
+ [DllImport("nfapinet", CallingConvention = CallingConvention.Cdecl)]
|
|
|
|
+ public static extern UInt32
|
|
|
|
+ nf_getDriverType();
|
|
|
|
+ };
|
|
|
|
+
|
|
|
|
+}
|