private void Init() { active = false; // if there is no /dev/net/tun, run in a "dummy" mode if (!File.Exists("/dev/net/tun")) { this.Log(LogLevel.Warning, "No TUN device found, running in dummy mode."); return; } IntPtr devName; if (deviceName != "") { // non-anonymous mapping devName = Marshal.StringToHGlobalAnsi(deviceName); } else { devName = Marshal.AllocHGlobal(DeviceNameBufferSize); Marshal.WriteByte(devName, 0); // null termination } try { tapFileDescriptor = LibC.OpenTAP(devName, persistent); if (tapFileDescriptor < 0) { var process = new Process(); var output = string.Empty; process.StartInfo.FileName = "mono"; process.StartInfo.Arguments = string.Format("{0} {1} true", DynamicModuleSpawner.GetTAPHelper(), deviceName); try { SudoTools.EnsureSudoProcess(process, "TAP creator"); } catch (Exception ex) { throw new RecoverableException("Process elevation failed: " + ex.Message); } process.EnableRaisingEvents = true; process.StartInfo.CreateNoWindow = false; process.StartInfo.UseShellExecute = false; process.StartInfo.RedirectStandardError = true; process.StartInfo.RedirectStandardOutput = true; var started = process.Start(); if (started) { output = process.StandardError.ReadToEnd(); process.WaitForExit(); } if (!started || process.ExitCode != 0) { this.Log(LogLevel.Warning, "Could not create TUN/TAP interface, running in dummy mode."); this.Log(LogLevel.Debug, "Error {0} while opening tun device '{1}': {2}", process.ExitCode, deviceName, output); return; } Init(); return; } stream = new UnixStream(tapFileDescriptor, true); InterfaceName = Marshal.PtrToStringAnsi(devName); this.Log(LogLevel.Info, "Opened interface {0}.", InterfaceName); } finally { Marshal.FreeHGlobal(devName); } active = true; }