From 37455bb89e95b5256a98c8737fe41f3c9229d72f Mon Sep 17 00:00:00 2001 From: ChsBuffer <33744752+chsbuffer@users.noreply.github.com> Date: Fri, 2 Apr 2021 00:19:57 +0800 Subject: [PATCH] Update nfapinet interop --- Interop.nfapinet/Interop.nfapinet.csproj | 16 - Interop.nfapinet/nfapinet.cs | 1033 ---------------------- Netch.sln | 6 - Netch/Controllers/NFController.cs | 2 +- Netch/Interops/NFAPI.cs | 20 + Netch/Interops/NF_STATUS.cs | 11 + Netch/Netch.csproj | 4 - 7 files changed, 32 insertions(+), 1060 deletions(-) delete mode 100644 Interop.nfapinet/Interop.nfapinet.csproj delete mode 100644 Interop.nfapinet/nfapinet.cs create mode 100644 Netch/Interops/NFAPI.cs create mode 100644 Netch/Interops/NF_STATUS.cs diff --git a/Interop.nfapinet/Interop.nfapinet.csproj b/Interop.nfapinet/Interop.nfapinet.csproj deleted file mode 100644 index 1e349ac0..00000000 --- a/Interop.nfapinet/Interop.nfapinet.csproj +++ /dev/null @@ -1,16 +0,0 @@ - - - - net5.0-windows7.0 - latest - true - Debug;Release - x64 - - - - none - false - - - diff --git a/Interop.nfapinet/nfapinet.cs b/Interop.nfapinet/nfapinet.cs deleted file mode 100644 index 6700740c..00000000 --- a/Interop.nfapinet/nfapinet.cs +++ /dev/null @@ -1,1033 +0,0 @@ -#nullable disable -using System; -using System.Runtime.InteropServices; - -// ReSharper disable All - -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 - }; - - 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 - }; - - 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 - }; - - /** - * 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; - }; - - /** - * 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("bin\\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("bin\\nfapinet", CallingConvention = CallingConvention.Cdecl)] - public static extern void nf_free(); - - /** - * Registers and starts a driver with specified name (without ".sys" extension) - * @param driverName - **/ - [DllImport("bin\\nfapinet", CallingConvention = CallingConvention.Cdecl)] - public static extern NF_STATUS nf_registerDriver(String driverName); - - /** - * Unregisters a driver with specified name (without ".sys" extension) - * @param driverName - **/ - [DllImport("bin\\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("bin\\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("bin\\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("bin\\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("bin\\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("bin\\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("bin\\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("bin\\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("bin\\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("bin\\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 NF_RULE - * @param toHead TRUE (1) - add rule to list head, FALSE (0) - add rule to tail - **/ - [DllImport("bin\\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 NF_RULE - * @param toHead TRUE (1) - add rule to list head, FALSE (0) - add rule to tail - **/ - [DllImport("bin\\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 NF_RULE structures - * @param count Number of items in array - **/ - [DllImport("bin\\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 NF_RULE structures - * @param count Number of items in array - **/ - [DllImport("bin\\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("bin\\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("bin\\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("bin\\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("bin\\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("bin\\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 NF_FLAGS - **/ - [DllImport("bin\\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("bin\\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("bin\\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("bin\\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("bin\\nfapinet", CallingConvention = CallingConvention.Cdecl)] - public static extern NF_STATUS nf_getUDPConnInfo(ulong id, ref NF_UDP_CONN_INFO pConnInfo); - - [DllImport("bin\\nfapinet", CallingConvention = CallingConvention.Cdecl)] - private static extern bool nf_getProcessNameW(uint processId, IntPtr buf, int len); - - [DllImport("bin\\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("bin\\nfapinet", CallingConvention = CallingConvention.Cdecl)] - public static extern void nf_adjustProcessPriviledges(); - - /* - * Set the event handler for IP filtering events - */ - [DllImport("bin\\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("bin\\nfapinet", CallingConvention = CallingConvention.Cdecl)] - public static extern NF_STATUS nf_addFlowCtl(ref NF_FLOWCTL_DATA pData, ref UInt32 pFcHandle); - - /** - * Delete flow control context - */ - [DllImport("bin\\nfapinet", CallingConvention = CallingConvention.Cdecl)] - public static extern NF_STATUS nf_deleteFlowCtl(UInt32 fcHandle); - - /** - * Associate flow control context with TCP connection - */ - [DllImport("bin\\nfapinet", CallingConvention = CallingConvention.Cdecl)] - public static extern NF_STATUS nf_setTCPFlowCtl(ulong id, UInt32 fcHandle); - - /** - * Associate flow control context with UDP socket - */ - [DllImport("bin\\nfapinet", CallingConvention = CallingConvention.Cdecl)] - public static extern NF_STATUS nf_setUDPFlowCtl(ulong id, UInt32 fcHandle); - - /** - * Modify flow control context limits - */ - [DllImport("bin\\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("bin\\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("bin\\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("bin\\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("bin\\nfapinet", CallingConvention = CallingConvention.Cdecl)] - public static extern NF_STATUS nf_tcpSetSockOpt(ulong id, NF_SOCKET_OPTIONS optname, ref int optval, int optlen); - - [DllImport("bin\\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("bin\\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("bin\\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("bin\\nfapinet", CallingConvention = CallingConvention.Cdecl)] - public static extern UInt32 nf_getDriverType(); - }; -} \ No newline at end of file diff --git a/Netch.sln b/Netch.sln index 0a2e21a2..e5f36578 100644 --- a/Netch.sln +++ b/Netch.sln @@ -7,8 +7,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Netch", "Netch\Netch.csproj EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "UnitTest", "UnitTest\UnitTest.csproj", "{53397641-35CA-4336-8E22-2CE12EF476AC}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Interop.nfapinet", "Interop.nfapinet\Interop.nfapinet.csproj", "{2C968ADF-4822-46A9-A7D9-D05A61CB14DE}" -EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|x64 = Debug|x64 @@ -22,10 +20,6 @@ Global {53397641-35CA-4336-8E22-2CE12EF476AC}.Debug|x64.ActiveCfg = Debug|x64 {53397641-35CA-4336-8E22-2CE12EF476AC}.Debug|x64.Build.0 = Debug|x64 {53397641-35CA-4336-8E22-2CE12EF476AC}.Release|x64.ActiveCfg = Release|x64 - {2C968ADF-4822-46A9-A7D9-D05A61CB14DE}.Debug|x64.ActiveCfg = Debug|x64 - {2C968ADF-4822-46A9-A7D9-D05A61CB14DE}.Debug|x64.Build.0 = Debug|x64 - {2C968ADF-4822-46A9-A7D9-D05A61CB14DE}.Release|x64.ActiveCfg = Release|x64 - {2C968ADF-4822-46A9-A7D9-D05A61CB14DE}.Release|x64.Build.0 = Release|x64 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/Netch/Controllers/NFController.cs b/Netch/Controllers/NFController.cs index fb1a7e08..0c8848ba 100644 --- a/Netch/Controllers/NFController.cs +++ b/Netch/Controllers/NFController.cs @@ -3,11 +3,11 @@ using System.Collections.Generic; using System.IO; using System.Linq; using System.ServiceProcess; +using Netch.Interops; using Netch.Models; using Netch.Servers.Shadowsocks; using Netch.Servers.Socks5; using Netch.Utils; -using nfapinet; using static Netch.Interops.RedirectorInterop; namespace Netch.Controllers diff --git a/Netch/Interops/NFAPI.cs b/Netch/Interops/NFAPI.cs new file mode 100644 index 00000000..65db5e40 --- /dev/null +++ b/Netch/Interops/NFAPI.cs @@ -0,0 +1,20 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Runtime.InteropServices; +using System.Text; +using System.Threading.Tasks; + +namespace Netch.Interops +{ + public static class NFAPI + { + private const string nfapinet_bin = "nfapinet.dll"; + + [DllImport(nfapinet_bin, CallingConvention = CallingConvention.Cdecl)] + public static extern NF_STATUS nf_registerDriver(string driverName); + + [DllImport(nfapinet_bin, CallingConvention = CallingConvention.Cdecl)] + public static extern NF_STATUS nf_unRegisterDriver(string driverName); + } +} \ No newline at end of file diff --git a/Netch/Interops/NF_STATUS.cs b/Netch/Interops/NF_STATUS.cs new file mode 100644 index 00000000..a1a45152 --- /dev/null +++ b/Netch/Interops/NF_STATUS.cs @@ -0,0 +1,11 @@ +namespace Netch.Interops +{ + public enum NF_STATUS : int + { + NF_STATUS_SUCCESS = 0, + NF_STATUS_FAIL = -1, + NF_STATUS_INVALID_ENDPOINT_ID = -2, + NF_STATUS_NOT_INITIALIZED = -3, + NF_STATUS_IO_ERROR = -4 + } +} \ No newline at end of file diff --git a/Netch/Netch.csproj b/Netch/Netch.csproj index cb4bee4e..8a5a82f4 100644 --- a/Netch/Netch.csproj +++ b/Netch/Netch.csproj @@ -54,10 +54,6 @@ - - - -