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;
}