/// <summary> /// Checks if there is any TAP interface ready to be used (disconnected or connected with a valid handle) /// </summary> /// <returns></returns> public static bool Check() { LoadingForm splash = new LoadingForm("Checking TAP interface ..."); if (handle != IntPtr.Zero) { IntPtr pTapVersion = Marshal.AllocHGlobal(2000); uint bytesReturned = 0; if (Kernel32.DeviceIoControl(handle, TAP_IOCTL_GET_VERSION, pTapVersion, 2000, pTapVersion, 2000, ref bytesReturned, IntPtr.Zero)) { Marshal.FreeHGlobal(pTapVersion); Connected = true; splash.Stop(); return true; } else { Marshal.FreeHGlobal(pTapVersion); handle = IntPtr.Zero; } } // not connected; seeking available interface Connected = false; Guid = null; string cfgKeyPath = @"SYSTEM\CurrentControlSet\Control\Class\{4D36E972-E325-11CE-BFC1-08002BE10318}"; string nameKeyPath = @"SYSTEM\CurrentControlSet\Control\Network\{4d36e972-e325-11ce-bfc1-08002be10318}"; RegistryKey key = Registry.LocalMachine.OpenSubKey(cfgKeyPath); foreach (string name in key.GetSubKeyNames()) { try { if ((string)Registry.LocalMachine.OpenSubKey(cfgKeyPath + @"\" + name).GetValue("ComponentId") == componentID) { string netCfgInstanceId = (string)Registry.LocalMachine.OpenSubKey(cfgKeyPath + @"\" + name).GetValue("NetCfgInstanceId"); string friendlyName = (string)Registry.LocalMachine.OpenSubKey(nameKeyPath + @"\" + netCfgInstanceId + @"\Connection").GetValue("Name"); if (NetworkInterface.GetAdapterStatus(friendlyName) == NetworkInterface.Status.MediaDisconnected || NetworkInterface.GetAdapterStatus(friendlyName) == NetworkInterface.Status.Disconnected) { Guid = netCfgInstanceId; FriendlyName = friendlyName; splash.Stop(); return true; } } } catch { } } splash.Stop(); return false; }
public static bool Start() { Global.WriteLog("UDP Detector is starting.", true); if (!Dependencies.RunWinPcapService(null, true)) { Global.WriteLog("UDP Detector failed to start.", true); Global.ShowTrayTip("UDP Detector", "Failed to start", System.Windows.Forms.ToolTipIcon.Error); return false; } LoadingForm splash = new LoadingForm("Initializing ..."); interfaceWorkers.Clear(); foreach (string guid in Dependencies.WinPcapDevices) { interfaceWorkers.Add(new InterfaceWorker(guid)); splash.UpdateStatus("Initializing " + interfaceWorkers.Last().Name + " ..."); new Thread(new ThreadStart(interfaceWorkers.Last().ReceivePackets)).Start(); interfaceWorkers.Last().Initialized.Wait(10000); } splash.Stop(); Dependencies.WinPcapInUse.Reset(Dependencies.WinPcapInUse.CurrentCount + 1); Global.WriteLog("UDP Detector: started"); Global.ShowTrayTip("UDP Detector", "Started", System.Windows.Forms.ToolTipIcon.Info); return true; }
/// <summary> /// HACK: metrics are sometimes ignored or the effect is delayed /// </summary> /// <param name="guid"></param> void MakeInterfacePrimary(string guid) { LoadingForm splash = new LoadingForm("Retrieving interfaces ..."); foreach (NetworkInterface nic in Global.NetworkInterfaces.Values) { splash.UpdateStatus("Configuring interface \"" + nic.Name + "\" ..."); if (nic.Guid == guid) { nic.SetInterfaceMetric("1"); foreach (NetworkInterface.IPGatewayAddress ip in nic.IPv4Gateway) nic.EditIPv4Gateway(ip.Address, "1"); foreach (NetworkInterface.IPGatewayAddress ip in nic.IPv6Gateway) nic.EditIPv4Gateway(ip.Address, "1"); // on Windows 8.1 occasionaly breaks routing until restart or ??? internal Windows stuff //foreach (NetworkInterface.IPGatewayAddress ip in nic.IPv4Gateway) // Iphlpapi.EditRoute("0.0.0.0", "0.0.0.0", ip.Address, nic.Index.ToString(), "0"); //foreach (NetworkInterface.IPGatewayAddress ip in nic.IPv6Gateway) // Iphlpapi.EditRoute("::", "0", ip.Address, nic.Index.ToString(), "0"); } else { nic.SetInterfaceMetric("4000"); foreach (NetworkInterface.IPGatewayAddress ip in nic.IPv4Gateway) nic.EditIPv4Gateway(ip.Address, "4000"); foreach (NetworkInterface.IPGatewayAddress ip in nic.IPv6Gateway) nic.EditIPv4Gateway(ip.Address, "4000"); // on Windows 8.1 occasionaly breaks routing until restart or ??? internal Windows stuff //foreach (NetworkInterface.IPGatewayAddress ip in nic.IPv4Gateway) // Iphlpapi.EditRoute("0.0.0.0", "0.0.0.0", ip.Address, nic.Index.ToString(), "4000"); //foreach (NetworkInterface.IPGatewayAddress ip in nic.IPv6Gateway) // Iphlpapi.EditRoute("::", "0", ip.Address, nic.Index.ToString(), "4000"); } } splash.Stop(); Program.Refresh(); }
public static bool Start(IEnumerable<NetworkInterface> requiredNics) { Global.WriteLog("Load Balancer is starting.", true); Status.Update(State.Starting); if (requiredNics.Count() == 0) { Global.WriteLog("Load Balancer can't start without any physical interface.", true); Global.ShowTrayTip("Load Balancer", "Can't start whitout any physical interface", System.Windows.Forms.ToolTipIcon.Error); Status.Update(State.Failed); return false; } if (!Jobs.Extensions.Dependencies.Check()) { Status.Update(State.Failed); return false; } if (!TapInterface.PutUp()) { Global.WriteLog("Load Balancer failed to connect to " + TapInterface.FriendlyName, true); Global.ShowTrayTip("Load Balancer", "Failed to connect to " + TapInterface.FriendlyName, System.Windows.Forms.ToolTipIcon.Error); Status.Update(State.Failed); return false; } if (!Dependencies.RunWinPcapService(requiredNics, true)) { Global.WriteLog("Load Balancer failed to start because some interfaces were not captured by WinPcap.", true); Global.ShowTrayTip("Load Balancer", "Failed to start", System.Windows.Forms.ToolTipIcon.Error); TapInterface.PutDown(); Status.Update(State.Failed); return false; } Interfaces = requiredNics; // start LB threads LoadingForm splash = new LoadingForm("Initializing ..."); foreach (NetworkInterface nic in Global.NetworkInterfaces.Values) if (nic.Guid != TapInterface.Guid && (nic.IPv4Gateway.Count > 0 || nic.IPv6Gateway.Count > 0)) { splash.UpdateStatus("Configuring " + nic.Name + " ..."); nic.SetInterfaceMetric("4000"); foreach (NetworkInterface.IPGatewayAddress ip in nic.IPv4Gateway) nic.EditIPv4Gateway(ip.Address, "4000"); foreach (NetworkInterface.IPGatewayAddress ip in nic.IPv6Gateway) nic.EditIPv6Gateway(ip.Address, "4000"); } splash.UpdateStatus("Initializing " + TapInterface.FriendlyName + " ..."); physicalWorkers.Clear(); tapWorker = new TapWorker(TapInterface.Guid, TapInterface.FriendlyName, TapInterface.Mac, Global.Config.LoadBalancer.IPv4LocalAddresses.First().Address, Global.Config.LoadBalancer.IPv4GatewayAddresses.First().Address); new Thread(new ThreadStart(tapWorker.ReceivePackets)).Start(); tapWorker.Initialized.Wait(1000); foreach (NetworkInterface nic in requiredNics) { splash.UpdateStatus("Initializing " + nic.Name + " ..."); physicalWorkers.Add(new PhysicalWorker(nic.Guid, nic.Name, nic.Mac, nic.IPv4Address.First().Address, nic.IPv4Address.First().Subnet, nic.DefaultIPv4GatewayMac, nic.DefaultIPv4Gateway)); new Thread(new ThreadStart(physicalWorkers.Last().ReceivePackets)).Start(); physicalWorkers.Last().Initialized.Wait(10000); } int mtu; MTU = requiredNics.Min((i) => int.TryParse(i.IPv4Mtu, out mtu) ? mtu : 1500); Global.WriteLog("Load Balancer: Negociated MTU = " + MTU); MSS = (ushort)(MTU - 40); splash.Stop(); Dependencies.WinPcapInUse.Reset(Dependencies.WinPcapInUse.CurrentCount + 1); Global.WriteLog("Load Balancer: started"); Global.ShowTrayTip("Load Balancer", "Started", System.Windows.Forms.ToolTipIcon.Info); Status.Update(State.Running); new Thread(new ThreadStart(CheckUp)).Start(); return true; }
public static bool Stop() { Status.Update(State.Stopping); TapInterface.PutDown(); LoadingForm splash = new LoadingForm("Stopping Load Balancer ..."); if (physicalWorkers.Count() > 0) { for (int i = physicalWorkers.Count() - 1; i >= 0; i--) { splash.UpdateStatus("Stop capturing from " + physicalWorkers[i].Name + " ..."); physicalWorkers[i].Stop(); physicalWorkers.RemoveAt(i); } } splash.UpdateStatus("Stop capturing from " + tapWorker.Name + " ..."); tapWorker.Stop(); splash.UpdateStatus("Clearing routing table ..."); RoutingTable.Clear(); Dependencies.WinPcapInUse.Signal(); splash.Stop(); Global.WriteLog("Load Balancer stopped.", true); Status.Update(State.Stopped); return true; }
public static bool Uninstall() { string cfgKeyPath = @"SYSTEM\CurrentControlSet\Control\Class\{4D36E972-E325-11CE-BFC1-08002BE10318}"; string nameKeyPath = @"SYSTEM\CurrentControlSet\Control\Network\{4d36e972-e325-11ce-bfc1-08002be10318}"; string tapList = ""; RegistryKey key = Registry.LocalMachine.OpenSubKey(cfgKeyPath); foreach (string name in key.GetSubKeyNames()) { try { if ((string)Registry.LocalMachine.OpenSubKey(cfgKeyPath + @"\" + name).GetValue("ComponentId") == componentID) { string netCfgInstanceId = (string)Registry.LocalMachine.OpenSubKey(cfgKeyPath + @"\" + name).GetValue("NetCfgInstanceId"); string friendlyName = (string)Registry.LocalMachine.OpenSubKey(nameKeyPath + @"\" + netCfgInstanceId + @"\Connection").GetValue("Name"); tapList += friendlyName + "\n"; } } catch { } } if (tapList == "") { MessageBox.Show("No TAP interface was found.", "TAP Driver Setup", MessageBoxButtons.OK, MessageBoxIcon.Information); return false; } DialogResult dialogResult = MessageBox.Show("This will remove the following network interfaces:\n\n" + tapList + "\nDo you want to remove all these TAP network interfaces?", "TAP Driver Setup", MessageBoxButtons.YesNo, MessageBoxIcon.Question); if (dialogResult == DialogResult.No) return false; LoadingForm splash = new LoadingForm("Uninstalling TAP driver ..."); if (Setupapi.UninstallDevice(componentID)) { splash.Stop(); MessageBox.Show("Uninstallation was successful.", "TAP Driver Setup", MessageBoxButtons.OK, MessageBoxIcon.Information); return true; } else { splash.Stop(); MessageBox.Show("Uninstallation failed.", "TAP Driver Setup", MessageBoxButtons.OK, MessageBoxIcon.Error); return false; } }
public static bool Install() { DialogResult dialogResult = MessageBox.Show("Do you want to create a TAP network interface?", "TAP Driver Setup", MessageBoxButtons.YesNo, MessageBoxIcon.Question); if (dialogResult == DialogResult.No) return false; LoadingForm splash = new LoadingForm("Decompressing TAP driver..."); Directory.CreateDirectory("Temp"); File.WriteAllBytes(@"Temp\TAP Driver.zip", Network_Manager.Properties.Resources.TAP_Driver); Lib.IO.Compression.UnZip(@"Temp\TAP Driver.zip", "Temp"); // Vista driver version does not install correctly on Vista, so Win2K is used string driverPath; if (Environment.Is64BitOperatingSystem) if (Environment.OSVersion.Version.CompareTo(new Version("6.1")) > -1) driverPath = @"Temp\TAP Driver\Vista 64-bit\OemVista.inf"; else driverPath = @"Temp\TAP Driver\XP 64-bit\OemWin2k.inf"; else if (Environment.OSVersion.Version.CompareTo(new Version("6.1")) > -1) driverPath = @"Temp\TAP Driver\Vista 32-bit\OemVista.inf"; else driverPath = @"Temp\TAP Driver\XP 32-bit\OemWin2k.inf"; splash.UpdateStatus("Installing TAP driver ..."); if (Setupapi.InstallInfDriver(driverPath, componentID, "Network Manager TAP Adapter")) { File.Delete("TAP Driver.zip"); splash.Stop(); MessageBox.Show("TAP network interface was successfully created.", "TAP Driver Setup", MessageBoxButtons.OK, MessageBoxIcon.Information); return true; } else { File.Delete("TAP Driver.zip"); splash.Stop(); MessageBox.Show("TAP network interface failed to create.", "TAP Driver Setup", MessageBoxButtons.OK, MessageBoxIcon.Error); return false; } }
public static bool PutDown() { if (handle == IntPtr.Zero) return true; LoadingForm splash = new LoadingForm("Disconnecting from \"" + FriendlyName + "\" ..."); uint bytesReturned = 0; IntPtr pBuffer = Marshal.AllocHGlobal(4); Marshal.Copy(BitConverter.GetBytes(0), 0, pBuffer, 4); bool deviceStatus = Kernel32.DeviceIoControl(handle, TAP_IOCTL_SET_MEDIA_STATUS, pBuffer, 4, pBuffer, 4, ref bytesReturned, IntPtr.Zero); Marshal.FreeHGlobal(pBuffer); Kernel32.CloseHandle(handle); handle = IntPtr.Zero; splash.Stop(); return deviceStatus; }
public static bool PutUp() { if (!Check()) return false; if (handle != IntPtr.Zero) return true; LoadingForm splash = new LoadingForm("Connecting to \"" + FriendlyName + "\" ..."); string duplicateName; if ((duplicateName = NetworkInterface.CheckIfIPv4Used(Global.Config.LoadBalancer.IPv4LocalAddresses[0].Address, Guid)) != null) { splash.Stop(); Global.WriteLog("TAP Interface: IP address " + Global.Config.LoadBalancer.IPv4LocalAddresses[0].Address + " already used by \"" + duplicateName + "\""); MessageBox.Show("\"" + FriendlyName + "\" can't use the IP address " + Global.Config.LoadBalancer.IPv4LocalAddresses[0].Address + " because it's already used by \"" + duplicateName + "\".\n\n Set a different IPv4 address in Control Panel>Tools>Load balancing>Advanced.", "TAP Interface", MessageBoxButtons.OK, MessageBoxIcon.Warning); return false; } handle = Kernel32.CreateFile(@"\\.\Global\" + Guid + ".tap", Kernel32.FILE_READ_DATA | Kernel32.FILE_WRITE_DATA, Kernel32.FILE_SHARE_READ | Kernel32.FILE_SHARE_WRITE, IntPtr.Zero, Kernel32.OPEN_EXISTING, Kernel32.FILE_ATTRIBUTE_SYSTEM | Kernel32.FILE_FLAG_OVERLAPPED, IntPtr.Zero); if (handle == Kernel32.INVALID_HANDLE_VALUE) { uint errorCode = Kernel32.GetLastError(); splash.Stop(); Global.WriteLog("TAP Interface: failed to connect to " + FriendlyName + ": " + Kernel32.GetLastErrorMessage(errorCode)); MessageBox.Show("Failed to connect to " + FriendlyName + ":\n" + Kernel32.GetLastErrorMessage(errorCode), "TAP Interface", MessageBoxButtons.OK, MessageBoxIcon.Error); return false; } // set TAP status to connected uint bytesReturned = 0; IntPtr pStatus = Marshal.AllocHGlobal(4); Marshal.Copy(BitConverter.GetBytes(1), 0, pStatus, 4); bool deviceStatus = Kernel32.DeviceIoControl(handle, TAP_IOCTL_SET_MEDIA_STATUS, pStatus, 4, pStatus, 4, ref bytesReturned, IntPtr.Zero); Marshal.FreeHGlobal(pStatus); // get TAP MAC address bytesReturned = 0; IntPtr pMac = Marshal.AllocHGlobal(8); bool macRetrieved = Kernel32.DeviceIoControl(handle, TAP_IOCTL_GET_MAC, pMac, 12, pMac, 12, ref bytesReturned, IntPtr.Zero); byte[] mac = new byte[bytesReturned]; Marshal.Copy(pMac, mac, 0, (int)bytesReturned); Mac = BitConverter.ToString(mac).Replace('-', ':'); Marshal.FreeHGlobal(pMac); // configure TAP splash.UpdateStatus("Configuring " + FriendlyName + " ..."); List<Iphlpapi.Adapter> adapters = Iphlpapi.GetAdapters(Iphlpapi.FAMILY.AF_UNSPEC); Iphlpapi.Adapter tap = adapters.Find(i => i.Guid == Guid); if (tap == null) { splash.Stop(); Global.WriteLog("TAP Interface: couldn't find " + FriendlyName + " index"); MessageBox.Show("Couldn't find " + FriendlyName + " index.", "TAP Interface", MessageBoxButtons.OK, MessageBoxIcon.Error); PutDown(); return false; } Index = tap.InterfaceIndex; if (Environment.OSVersion.Version.CompareTo(new Version("6.0")) < 0) NetworkInterface.SetInterfaceMetric(Mac, "1"); else NetworkInterface.SetInterfaceMetric(Index, "1"); NetworkInterface.SetNetBios(Guid, false); NetworkInterface.ClearIPv4Addresses(Mac, Global.Config.LoadBalancer.IPv4LocalAddresses[0].Address, Global.Config.LoadBalancer.IPv4LocalAddresses[0].Subnet); NetworkInterface.ClearGateways(Index); NetworkInterface.ClearIPv4DnsServers(Mac); if (Environment.OSVersion.Version.CompareTo(new Version("6.0")) < 0) NetworkInterface.AddIPv4Gateway(Mac, Global.Config.LoadBalancer.IPv4GatewayAddresses[0].Address, Global.Config.LoadBalancer.IPv4GatewayAddresses[0].GatewayMetric.ToString()); else NetworkInterface.AddIPv4Gateway(Index, Global.Config.LoadBalancer.IPv4GatewayAddresses[0].Address, Global.Config.LoadBalancer.IPv4GatewayAddresses[0].GatewayMetric.ToString()); NetworkInterface.SetIPv4DnsServer(FriendlyName, Global.Config.LoadBalancer.IPv4DnsAddresses[0]); splash.Stop(); if (handle != IntPtr.Zero && handle != Kernel32.INVALID_HANDLE_VALUE && deviceStatus && macRetrieved) return true; else return false; }
private void button5_Click(object sender, EventArgs e) { LoadingForm splash = new LoadingForm("Initializing ..."); Global.Config.LoadBalancer.ExcludedInterfacesForWindows.Clear(); List<NetworkInterface> loadBalancingInterfaces = new List<NetworkInterface>(); foreach (Control control in windowsInterfaces.Controls) if (!((CheckBox)control).Checked) Global.Config.LoadBalancer.ExcludedInterfacesForWindows.Add((string)((CheckBox)control).Tag); else loadBalancingInterfaces.Add(Global.NetworkInterfaces[(string)((CheckBox)control).Tag]); Global.Config.Save(); // Configure high metrics on interfaces that are not used foreach (NetworkInterface nic in Global.NetworkInterfaces.Values) if (!loadBalancingInterfaces.Any(i => i.Guid == nic.Guid) && (nic.IPv4Gateway.Count > 0 || nic.IPv6Gateway.Count > 0)) { splash.UpdateStatus("Configuring " + nic.Name + " ..."); nic.SetInterfaceMetric("4000"); foreach (NetworkInterface.IPGatewayAddress ip in nic.IPv4Gateway) nic.EditIPv4Gateway(ip.Address, "4000"); foreach (NetworkInterface.IPGatewayAddress ip in nic.IPv6Gateway) nic.EditIPv6Gateway(ip.Address, "4000"); } // Configure the used interfaces with the specified metrics foreach (NetworkInterface nic in loadBalancingInterfaces) { splash.UpdateStatus("Configuring " + nic.Name + " ..."); nic.SetInterfaceMetric(textBox1.Text); foreach (NetworkInterface.IPGatewayAddress ip in nic.IPv4Gateway) nic.EditIPv4Gateway(ip.Address, textBox2.Text); foreach (NetworkInterface.IPGatewayAddress ip in nic.IPv6Gateway) nic.EditIPv6Gateway(ip.Address, textBox2.Text); } splash.Stop(); Program.Refresh(); }