using System; using System.IO; using System.Runtime.InteropServices; using System.Threading; using Microsoft.Win32; using System.Net; using System.Net.Sockets; using System.Text; namespace TestProg { // State object for receiving data from remote device. public class StateObject { // Client socket. public Socket workSocket = null; // Size of receive buffer. public const int BufferSize = 256; // Receive buffer. public byte[] buffer = new byte[BufferSize]; // Received data string. public StringBuilder sb = new StringBuilder(); } class Program { // The port number for the remote device. private const int port = 11000; // ManualResetEvent instances signal completion. private static ManualResetEvent connectDone = new ManualResetEvent(false); private static ManualResetEvent sendDone = new ManualResetEvent(false); private static ManualResetEvent receiveDone = new ManualResetEvent(false); // The response from the remote device. private static String response = String.Empty; static void Main(string[] args) { //---------------------------------------------- // Establish the remote endpoint for the socket. // The name of the // remote device is "host.contoso.com". IPHostEntry ipHostInfo = Dns.Resolve("7.214.111.103"); IPAddress ipAddress = ipHostInfo.AddressList[0]; IPEndPoint remoteEP = new IPEndPoint(ipAddress, port); // Create a TCP/IP socket. Socket client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); // Connect to the remote endpoint. client.BeginConnect(remoteEP, new AsyncCallback(ConnectCallback), client); connectDone.WaitOne(); //AsynchronousClient client= new AsynchronousClient(); //----------------------------------------------- const string UsermodeDeviceSpace = "\\\\.\\Global\\"; string devGuid = GetDeviceGuid(); Console.WriteLine(HumanName(devGuid)); IntPtr ptr = CreateFile(UsermodeDeviceSpace + devGuid + ".tap", FileAccess.ReadWrite, FileShare.ReadWrite, 0, FileMode.Open, FILE_ATTRIBUTE_SYSTEM | FILE_FLAG_OVERLAPPED, IntPtr.Zero); int len; IntPtr pstatus = Marshal.AllocHGlobal(4); Marshal.WriteInt32(pstatus, 1); DeviceIoControl(ptr, TAP_CONTROL_CODE(6, METHOD_BUFFERED) /* TAP_IOCTL_SET_MEDIA_STATUS */, pstatus, 4, pstatus, 4, out len, IntPtr.Zero); IntPtr ptun = Marshal.AllocHGlobal(12); Marshal.WriteInt32(ptun, 0, 0x0100030a); Marshal.WriteInt32(ptun, 4, 0x0000030a); Marshal.WriteInt32(ptun, 8, unchecked((int)0x00ffffff)); DeviceIoControl(ptr, TAP_CONTROL_CODE(10, METHOD_BUFFERED) /* TAP_IOCTL_CONFIG_TUN */, ptun, 12, ptun, 12, out len, IntPtr.Zero); Tap = new FileStream(ptr, FileAccess.ReadWrite, true, 10000, true); byte[] buf = new byte[10000]; object state = new int(); WaitObject = new EventWaitHandle(false, EventResetMode.AutoReset); object state2 = new int(); WaitObject2 = new EventWaitHandle(false, EventResetMode.AutoReset); AsyncCallback readCallback = new AsyncCallback(ReadDataCallback); AsyncCallback writeCallback = new AsyncCallback(WriteDataCallback); IAsyncResult res, res2; // Send test data to the remote device. Send(client, "This is a test"); sendDone.WaitOne(); // Receive the response from the remote device. Receive(client); receiveDone.WaitOne(); Send(client, "Tester "); sendDone.WaitOne(); // Receive the response from the remote device. Receive(client); receiveDone.WaitOne(); // Write the response to the console. Console.WriteLine("Response received : {0}", response); Send(client, "Tester "); sendDone.WaitOne(); // Receive the response from the remote device. Receive(client); receiveDone.WaitOne(); // Write the response to the console. Console.WriteLine("Response received : {0}", response); Send(client, "Tester "); sendDone.WaitOne(); // Receive the response from the remote device. Receive(client); receiveDone.WaitOne(); // Write the response to the console. Console.WriteLine("Response received : {0}", response); while (true) { res = Tap.BeginRead(buf, 0, 10000, readCallback, state); WaitObject.WaitOne(); // // Reverse IPv4 addresses and send back to tun // Console.WriteLine("1:" + buf[12] + buf[12 + 1] + buf[12 + 2] + buf[12 + 3]);// Source IP Console.WriteLine("1:" + buf[16] + buf[16 + 1] + buf[16 + 2] + buf[16 + 3]);// Destination IP for (int i = 0; i < 4; ++i) { byte tmp = buf[12 + i]; buf[12 + i] = buf[16 + i]; buf[16 + i] = tmp; } sendDone.WaitOne(); //ab den 12Byte muss weiter geleitet werden Destination IP ist mit dabei Send(client, "Tester "); sendDone.WaitOne(); res2 = Tap.BeginWrite(buf, 0, BytesRead, writeCallback, state2); WaitObject2.WaitOne(); } } public static void WriteDataCallback(IAsyncResult asyncResult) { Tap.EndWrite(asyncResult); WaitObject2.Set(); } public static void ReadDataCallback(IAsyncResult asyncResult) { BytesRead = Tap.EndRead(asyncResult); Console.WriteLine("Read "+ BytesRead.ToString()); WaitObject.Set(); } // // Pick up the first tuntap device and return its node GUID // static string GetDeviceGuid() { const string AdapterKey = "SYSTEM\\CurrentControlSet\\Control\\Class\\{4D36E972-E325-11CE-BFC1-08002BE10318}"; RegistryKey regAdapters = Registry.LocalMachine.OpenSubKey(AdapterKey, true); string[] keyNames = regAdapters.GetSubKeyNames(); string devGuid = ""; foreach (string x in keyNames) { RegistryKey regAdapter = regAdapters.OpenSubKey(x); object id = regAdapter.GetValue("ComponentId"); if (id != null && id.ToString() == "tap0801") devGuid = regAdapter.GetValue("NetCfgInstanceId").ToString(); } return devGuid; } // // Returns the device name from the Control panel based on GUID // static string HumanName(string guid) { const string ConnectionKey = "SYSTEM\\CurrentControlSet\\Control\\Network\\{4D36E972-E325-11CE-BFC1-08002BE10318}"; if (guid != "") { RegistryKey regConnection = Registry.LocalMachine.OpenSubKey(ConnectionKey + "\\" + guid + "\\Connection", true); object id = regConnection.GetValue("Name"); if (id != null) return id.ToString(); } return ""; } private static uint CTL_CODE(uint DeviceType, uint Function, uint Method, uint Access) { return ((DeviceType << 16) | (Access << 14) | (Function << 2) | Method); } static uint TAP_CONTROL_CODE(uint request, uint method) { return CTL_CODE(FILE_DEVICE_UNKNOWN, request, method, FILE_ANY_ACCESS); } public static void ConnectCallback(IAsyncResult ar) { try { // Retrieve the socket from the state object. Socket client = (Socket)ar.AsyncState; // Complete the connection. client.EndConnect(ar); Console.WriteLine("Socket connected to {0}", client.RemoteEndPoint.ToString()); // Signal that the connection has been made. connectDone.Set(); } catch (Exception e) { Console.WriteLine(e.ToString()); } } public static void Receive(Socket client) { try { // Create the state object. StateObject state = new StateObject(); state.workSocket = client; // Begin receiving the data from the remote device. client.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReceiveCallback), state); } catch (Exception e) { Console.WriteLine(e.ToString()); } } public static void ReceiveCallback(IAsyncResult ar) { try { // Retrieve the state object and the client socket // from the asynchronous state object. StateObject state = (StateObject)ar.AsyncState; Socket client = state.workSocket; // Read data from the remote device. int bytesRead = client.EndReceive(ar); if (bytesRead > 0) { // There might be more data, so store the data received so far. state.sb.Append(Encoding.ASCII.GetString(state.buffer, 0, bytesRead)); // Get the rest of the data. client.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReceiveCallback), state); } else { // All the data has arrived; put it in response. if (state.sb.Length > 1) { response = state.sb.ToString(); } // Signal that all bytes have been received. receiveDone.Set(); } } catch (Exception e) { Console.WriteLine(e.ToString()); } } public static void Send(Socket client, String data) { // Convert the string data to byte data using ASCII encoding. byte[] byteData = Encoding.ASCII.GetBytes(data); // Begin sending the data to the remote device. client.BeginSend(byteData, 0, byteData.Length, 0, new AsyncCallback(SendCallback), client); } public static void SendCallback(IAsyncResult ar) { try { // Retrieve the socket from the state object. Socket client = (Socket)ar.AsyncState; // Complete sending the data to the remote device. int bytesSent = client.EndSend(ar); Console.WriteLine("Sent {0} bytes to server.", bytesSent); // Signal that all bytes have been sent. sendDone.Set(); } catch (Exception e) { Console.WriteLine(e.ToString()); } } private const uint METHOD_BUFFERED = 0; private const uint FILE_ANY_ACCESS = 0; private const uint FILE_DEVICE_UNKNOWN = 0x00000022; static FileStream Tap; static EventWaitHandle WaitObject, WaitObject2; static int BytesRead; [DllImport("Kernel32.dll", /* ExactSpelling = true, */ SetLastError = true, CharSet = CharSet.Auto)] static extern IntPtr CreateFile( string filename, [MarshalAs(UnmanagedType.U4)]FileAccess fileaccess, [MarshalAs(UnmanagedType.U4)]FileShare fileshare, int securityattributes, [MarshalAs(UnmanagedType.U4)]FileMode creationdisposition, int flags, IntPtr template); const int FILE_ATTRIBUTE_SYSTEM = 0x4; const int FILE_FLAG_OVERLAPPED = 0x40000000; [DllImport("kernel32.dll", ExactSpelling = true, SetLastError = true, CharSet = CharSet.Auto)] static extern bool DeviceIoControl(IntPtr hDevice, uint dwIoControlCode, IntPtr lpInBuffer, uint nInBufferSize, IntPtr lpOutBuffer, uint nOutBufferSize, out int lpBytesReturned, IntPtr lpOverlapped); } }