public void TestComplexRule() { RulesChecker.RulesCheckerResult result; NetworkInfo networkInfo; AutoProxySwitcherLib.NetworkChangeDetector ncd = new NetworkChangeDetector(); ncd.LoadConfigurations("Samples/ComplexRule.xml"); NetworkInfo ni = new NetworkInfo(); ni.Description = "Test Network"; ni.DNS = new List<string> { "192.168.1.252" }; ni.IP = new List<string> { "192.168.1.254" }; ni.NetworkIP = new List<string> { "192.168.0.0/16" }; ni.Type = "Wi-Fi"; ni.IfName = "Test1"; List<NetworkInfo> networks = new List<NetworkInfo> { ni }; NetworkConfiguration configuration = ncd.FindMatchingConfiguration(networks, out result, out networkInfo); if (result != null) { Console.WriteLine(result.ReasonString); } Console.WriteLine("Test"); Assert.AreSame(configuration, ncd.Configurations[0]); //Assert.IsTrue(result.ReasonString.Equals("network DNS matches 192.168.1.252")); }
public void TestManyConfigs() { AutoProxySwitcherLib.NetworkChangeDetector ncd = new NetworkChangeDetector(); RulesChecker.RulesCheckerResult result; NetworkInfo networkInfo; ncd.LoadConfigurations("Samples/ManyConfigs.xml"); NetworkInfo ni = new NetworkInfo(); ni.Description = "Test Network"; ni.DNS = new List<string> { "172.17.4.80", "172.17.4.81" }; ni.IP = new List<string> { "172.17.4.145" }; ni.NetworkIP = new List<string> { "172.17.4.0/24" }; ni.Type = "Local Area Connection"; ni.IfName = "test"; List<NetworkInfo> networks; NetworkConfiguration configuration; networks = new List<NetworkInfo> { ni }; configuration = ncd.FindMatchingConfiguration(networks, out result, out networkInfo); Console.WriteLine(result.ReasonString); Console.WriteLine(configuration.ProxySettings); Assert.AreEqual(configuration.Name, "Config 1"); Assert.IsTrue(result.ReasonString.Equals("network subnet matches 172.17.4.0/24")); ni.Description = "Test Network"; ni.DNS = new List<string> { "172.17.80.80", "172.17.80.81" }; ni.IP = new List<string> { "172.17.80.15" }; ni.NetworkIP = new List<string> { "172.17.80.0/24" }; ni.Type = "Local Area Connection"; ni.IfName = "test"; networks = new List<NetworkInfo> { ni }; configuration = ncd.FindMatchingConfiguration(networks, out result, out networkInfo); Console.WriteLine(result.ReasonString); Console.WriteLine(configuration.ProxySettings); Assert.AreEqual(configuration.Name, "Config 4"); Assert.IsTrue(result.ReasonString.Equals("network subnet matches 172.17.80.0/24")); ni.Description = "Test Network"; ni.DNS = new List<string> { "172.16.0.5" }; ni.IP = new List<string> { "172.16.0.78" }; ni.NetworkIP = new List<string> { "172.16.2/24" }; ni.Type = "Local Area Connection"; ni.IfName = "test"; networks = new List<NetworkInfo> { ni }; configuration = ncd.FindMatchingConfiguration(networks, out result, out networkInfo); Console.WriteLine(result.ReasonString); Console.WriteLine(configuration.ProxySettings); Assert.AreEqual(configuration.Name, "Default Config"); Assert.IsTrue(result.ReasonString.Equals("default rule match")); }
/// <summary> /// Default constructor, only for design mode /// </summary> public MainViewModel() { if (DesignerProperties.GetIsInDesignMode(new DependencyObject())) { // Generate some configurations _configurationsList = new List<NetworkConfiguration>(); NetworkRulesSet rulesSet = new NetworkRulesSet(); rulesSet.Rules.Add(new AutoProxySwitcherLib.Rules.NetworkRuleDNS("10.0.0.1")); for (int i = 0; i < 5; i++) { _configurationsList.Add(new NetworkConfiguration("Config #" + i, rulesSet, new StandardProxySettings("http://test:8080", null, null))); } _activeConfiguration = _configurationsList[2]; // Generate some networks for(int i = 0; i < 10; i++) { _currentNetworks.Add(new NetworkInfo() { IfName = "Sample Network #" + i, IP = { "10.0.0.1" }, DNS = { "10.0.0.5" }, NetworkIP = { "10.0.0.0/24" } }); } _currentNetwork = _currentNetworks[3]; _currentProxySettings = _activeConfiguration.ProxySettings; // reason = "Network matching IP x.y.z.t"; } else { string rulesFile = System.Environment.GetFolderPath(System.Environment.SpecialFolder.CommonApplicationData) + "\\AutoProxySwitcher\\" + Environment.ExpandEnvironmentVariables(System.Configuration.ConfigurationManager.AppSettings["RulesFile"]); // Create default rules files if it doesn't exists if (!System.IO.File.Exists(rulesFile)) { System.IO.File.Copy("Examples/rules.xml", rulesFile); } // Load configurations _networkChangeDetector = new NetworkChangeDetector(); _networkChangeDetector.ProxyChanged += _networkChangeDetector_ProxyChanged; _networkChangeDetector.LoadConfigurations(rulesFile); _configurationsList = _networkChangeDetector.Configurations; // Init commands relay DebugCommand = new RelayCommand<string>(m => MessageBox.Show("toto: " + m)); SetConfigurationCommand = new RelayCommand<string>((conf) => _networkChangeDetector.SetConfiguration(conf)); AutoDetectCommand = new RelayCommand(() => _networkChangeDetector.SetConfiguration(null)); ExitCommand = new RelayCommand(() => { Messenger.Default.Send<ExitMessage>(new ExitMessage()); }); } }
/// <summary> /// Find rule matching the given network informations /// </summary> /// <param name="net">Network information</param> /// <returns>Result containing reason of match</returns> public RulesCheckerResult CheckRulesAgainstNetwork(NetworkInfo net) { // Si aucune règle, alors ça matche automatiquement if (m_NetworkRulesSet.Rules.Count == 0) { return new RulesCheckerResult(Reasons.DEFAULT, "default rule match"); } // Parcourir les règles de détection RulesCheckerResult res = new RulesCheckerResult(Reasons.NOMATCH, ""); bool result = CheckRuleAgainstNetwork(m_NetworkRulesSet, net, ref res); return res; }
/// <summary> /// Find rule matching the given network informations /// </summary> /// <param name="net">Network information</param> /// <returns>Result containing reason of match</returns> public RulesCheckerResult CheckRulesAgainstNetwork(NetworkInfo net) { // Si aucune règle, alors ça matche automatiquement if (m_NetworkRulesSet.Rules.Count == 0) { return(new RulesCheckerResult(Reasons.DEFAULT, "default rule match")); } // Parcourir les règles de détection RulesCheckerResult res = new RulesCheckerResult(Reasons.NOMATCH, ""); bool result = CheckRuleAgainstNetwork(m_NetworkRulesSet, net, ref res); return(res); }
/// <summary> /// Returns a list of available connected networks. The network address is given in text format: "a.b.c.d/bits" /// This list is build from the list of main IPs of each network interface /// </summary> /// <returns></returns> public static IList <NetworkInfo> ListAvailableNetworks() { List <NetworkInfo> networks = new List <NetworkInfo>(); NetworkInterface[] adapters = NetworkInterface.GetAllNetworkInterfaces(); foreach (NetworkInterface n in adapters) { NetworkInfo net = new NetworkInfo(); if (n.OperationalStatus == OperationalStatus.Up) { // Stores basic attributes net.IfName = n.Name; net.Description = n.Description; net.Type = n.NetworkInterfaceType.ToString(); // Stores interface address and network address // Sometimes, it lacks masks (ex: loopback) foreach (UnicastIPAddressInformation uipai in n.GetIPProperties().UnicastAddresses) { // Adds IP address net.IP.Add(uipai.Address.ToString()); // Adds network IP adress with netmask if (uipai.IPv4Mask != null && uipai.IPv4Mask.ToString() != "0.0.0.0") { net.NetworkIP.Add(GetNetworkAddressAsString(uipai.Address, uipai.IPv4Mask)); } } // Order addresses by length (shortest first) net.IP = net.IP.OrderBy((s) => s.Length).ToList(); foreach (System.Net.IPAddress ipAddress in n.GetIPProperties().DnsAddresses) { net.DNS.Add(ipAddress.ToString()); } networks.Add(net); } } return(networks); }
/// <summary> /// Sets proxy according to current available networks and configurations rules /// </summary> private void SetProxyAccordingToNetwork(string configName) { if (configName != null) { log.Info("Set configuration " + configName); NetworkConfiguration configuration = m_configurations.Find((c) => c.Name == configName); configuration.ProxySettings.Configure(); // Evénement if (ProxyChanged != null) { ProxyChanged(configName, null, configuration.ProxySettings, "Setting forced"); } } else { NetworkInfo matchingNetwork = null; NetworkConfiguration matchingConfiguration = null; RulesChecker.RulesCheckerResult result = new RulesChecker.RulesCheckerResult(); // Get current networks IList <NetworkInfo> currentNetworks = NetworkManager.ListAvailableNetworks(); _currentNetworks = currentNetworks; foreach (var networkInfo in currentNetworks) { log.Debug("Network " + networkInfo); } // Find matching configuration matchingConfiguration = FindMatchingConfiguration(currentNetworks, out result, out matchingNetwork); // Configurer le configuration en conséquence if (matchingConfiguration != null) { matchingConfiguration.ProxySettings.Configure(); } // Evénement if (ProxyChanged != null) { ProxyChanged(matchingConfiguration.Name, result.Reason != Reasons.DEFAULT ? matchingNetwork : null, matchingConfiguration.ProxySettings, result.ReasonString); } } }
/// <summary> /// Returns a list of available connected networks. The network address is given in text format: "a.b.c.d/bits" /// This list is build from the list of main IPs of each network interface /// </summary> /// <returns></returns> public static IList<NetworkInfo> ListAvailableNetworks() { List<NetworkInfo> networks = new List<NetworkInfo>(); NetworkInterface[] adapters = NetworkInterface.GetAllNetworkInterfaces(); foreach (NetworkInterface n in adapters) { NetworkInfo net = new NetworkInfo(); if (n.OperationalStatus == OperationalStatus.Up) { // Stores basic attributes net.IfName = n.Name; net.Description = n.Description; net.Type = n.NetworkInterfaceType.ToString(); // Stores interface address and network address // Sometimes, it lacks masks (ex: loopback) foreach (UnicastIPAddressInformation uipai in n.GetIPProperties().UnicastAddresses) { // Adds IP address net.IP.Add(uipai.Address.ToString()); // Adds network IP adress with netmask if (uipai.IPv4Mask != null && uipai.IPv4Mask.ToString() != "0.0.0.0") { net.NetworkIP.Add(GetNetworkAddressAsString(uipai.Address, uipai.IPv4Mask)); } } // Order addresses by length (shortest first) net.IP = net.IP.OrderBy((s) => s.Length).ToList(); foreach (System.Net.IPAddress ipAddress in n.GetIPProperties().DnsAddresses) { net.DNS.Add(ipAddress.ToString()); } networks.Add(net); } } return networks; }
/// <summary> /// Returns the configuration that matches the given network /// </summary> /// <param name="configurations"></param> public NetworkConfiguration FindMatchingConfiguration(IList<NetworkInfo> networks, out RulesChecker.RulesCheckerResult result, out NetworkInfo matchingNetwork) { int countMatches = 0; NetworkConfiguration matchingConfiguration = null; result = null; matchingNetwork = null; // Check each configuration foreach (NetworkConfiguration configuration in m_configurations) { using (log4net.ThreadContext.Stacks["NDC"].Push(String.Format("config {0}", configuration.Name))) { log.InfoFormat("Checking config {0}", configuration.Name); // Check each network foreach (NetworkInfo net in networks) { log.InfoFormat("Checking network: {0} (IP: {1}, DNS: {2})", net.IfName, string.Join(",", net.NetworkIP), string.Join(",", net.DNS)); RulesChecker rc = new RulesChecker(configuration.NetworkRulesSet); RulesChecker.RulesCheckerResult tempResult = rc.CheckRulesAgainstNetwork(net); if (tempResult.Match) { log.InfoFormat("Match #{1}: config {0}", configuration.Name, countMatches + 1); if (countMatches == 0) { result = tempResult; matchingConfiguration = configuration; matchingNetwork = net; } countMatches++; } } } } return matchingConfiguration; }
/// <summary> /// Checks (recursively) if a rule matches a given network information /// </summary> /// <param name="rule">Rule to check</param> /// <param name="net">Network information</param> /// <param name="res">Detailed result if match</param> /// <returns>true if rule matches</returns> private bool CheckRuleAgainstNetwork(NetworkRule rule, NetworkInfo net, ref RulesCheckerResult res) { if (rule is NetworkRulesSet) { bool thisRes = false; foreach (var rule2 in (rule as NetworkRulesSet).Rules) { thisRes = CheckRuleAgainstNetwork(rule2, net, ref res); if ((rule as NetworkRulesSet).Op == Operator.And && !thisRes) { thisRes = false; break; } if ((rule as NetworkRulesSet).Op == Operator.Or && thisRes) { thisRes = true; break; } if ((rule as NetworkRulesSet).Op == Operator.Not) { thisRes = !thisRes; break; } } res = new RulesCheckerResult(thisRes ? Reasons.MATCH : Reasons.NOMATCH, res != null ? res.ReasonString : "complex rule used"); return(thisRes); } else if (rule is NetworkRuleDNS) { foreach (string dns in net.DNS) { if ((rule as NetworkRuleDNS).DNS == dns) { res = new RulesCheckerResult(Reasons.MATCH, "network DNS matches " + dns); return(true); } } } else if (rule is NetworkRuleSubnet) { foreach (string ip in net.NetworkIP) { if ((rule as NetworkRuleSubnet).Subnet == ip) { res = new RulesCheckerResult(Reasons.MATCH, "network subnet matches " + ip); return(true); } } } else if (rule is NetworkRuleIfName) { string regex = (rule as NetworkRuleIfName).InterfaceName; if (Regex.IsMatch(net.IfName, regex)) { res = new RulesCheckerResult(Reasons.MATCH, "interface name matches " + regex); return(true); } } else if (rule is NetworkRulePingable) { string ip = (rule as NetworkRulePingable).IP; log.Debug("Pinging " + ip); System.Net.NetworkInformation.Ping ping = new System.Net.NetworkInformation.Ping(); var reply = ping.Send(ip, 5000); log.Info("Ping status: " + reply.Status); if (reply.Status == System.Net.NetworkInformation.IPStatus.Success) { res = new RulesCheckerResult(Reasons.MATCH, "machine " + ip + " is pingable"); return(true); } } return(false); }
/// <summary> /// Returns the configuration that matches the given network /// </summary> /// <param name="configurations"></param> public NetworkConfiguration FindMatchingConfiguration(IList <NetworkInfo> networks, out RulesChecker.RulesCheckerResult result, out NetworkInfo matchingNetwork) { int countMatches = 0; NetworkConfiguration matchingConfiguration = null; result = null; matchingNetwork = null; // Check each configuration foreach (NetworkConfiguration configuration in m_configurations) { using (log4net.ThreadContext.Stacks["NDC"].Push(String.Format("config {0}", configuration.Name))) { log.InfoFormat("Checking config {0}", configuration.Name); // Check each network foreach (NetworkInfo net in networks) { log.InfoFormat("Checking network: {0} (IP: {1}, DNS: {2})", net.IfName, string.Join(",", net.NetworkIP), string.Join(",", net.DNS)); RulesChecker rc = new RulesChecker(configuration.NetworkRulesSet); RulesChecker.RulesCheckerResult tempResult = rc.CheckRulesAgainstNetwork(net); if (tempResult.Match) { log.InfoFormat("Match #{1}: config {0}", configuration.Name, countMatches + 1); if (countMatches == 0) { result = tempResult; matchingConfiguration = configuration; matchingNetwork = net; } countMatches++; } } } } return(matchingConfiguration); }
void _networkChangeDetector_ProxyChanged(string name, NetworkInfo networkInfo, ProxySettings proxySettings, string reason) { try { log.DebugFormat("ProxyChanged event: {0}, network {1}, proxy {2}, reason", name, networkInfo, proxySettings, reason); lastUpdateTime = DateTime.Now; _activeConfiguration = _configurationsList.First((c) => c.Name == name); this.interfaceName = networkInfo != null ? networkInfo.IfName : "N/A"; this.addresses = networkInfo != null ? String.Join(", ", networkInfo.IP) : ""; this.reason = reason; _currentNetworks = _networkChangeDetector.CurrentNetworks; _currentNetwork = networkInfo != null ? _currentNetworks.FirstOrDefault((n) => networkInfo.IfName == n.IfName) : null; _currentProxySettings = proxySettings; RaisePropertyChanged("LastUpdateTime"); RaisePropertyChanged("ActiveConfiguration"); RaisePropertyChanged("InterfaceName"); RaisePropertyChanged("Addresses"); RaisePropertyChanged("Reason"); RaisePropertyChanged("CurrentNetworks"); RaisePropertyChanged("CurrentNetwork"); RaisePropertyChanged("CurrentProxySettings"); log.Debug("Sending ChangeMessage"); ChangeMessage msg = new ChangeMessage() { ConfName = name, Network = networkInfo, ProxySettings = proxySettings, Reason = reason }; Messenger.Default.Send<ChangeMessage>(msg); } catch (Exception ex) { log.Error("Failure", ex); } }
private void m_networkChangeDetector_ProxyChanged(string name, NetworkInfo networkInfo, ProxySettings proxySettings, string reason) { string info; string detailedInfo; log.Info("Proxy Changed"); // Afficher tooltip indiquant disponibilité if (networkInfo != null && proxySettings != null) { info = String.Format("Configuration \"{0}\" available\nInterface name: {1}\nReason: {2}", name, networkInfo.IfName, reason); m_notifyIcon.BalloonTipIcon = ToolTipIcon.Info; } else if (networkInfo == null) { info = String.Format("Configuration \"{0}\" available\nReason: {1}", name, reason); m_notifyIcon.BalloonTipIcon = ToolTipIcon.Info; } else { info = String.Format("No rule found, no change"); m_notifyIcon.BalloonTipIcon = ToolTipIcon.Warning; } m_notifyIcon.BalloonTipText = info; Assembly assembly = Assembly.GetExecutingAssembly(); FileVersionInfo fvi = FileVersionInfo.GetVersionInfo(assembly.Location); string version = fvi.FileVersion; detailedInfo = "V" + fvi.FileVersion; detailedInfo += "\n\nUpdate date: " + System.DateTime.Now; detailedInfo += "\n\n" + info; if (networkInfo != null) { detailedInfo += "\n\nNetwork details: "; detailedInfo += "\n Interface name: " + networkInfo.IfName; detailedInfo += "\n Type: " + networkInfo.Type; detailedInfo += "\n Description: " + networkInfo.Description; detailedInfo += "\n IP(s): " + String.Join(", ", networkInfo.IP); detailedInfo += "\n Network(s): " + String.Join(", ", networkInfo.NetworkIP); detailedInfo += "\n DNS: " + String.Join(", ", networkInfo.DNS); } if (proxySettings != null) { detailedInfo += "\n\nProxy details: "; detailedInfo += "\n " + proxySettings; } if (InvokeRequired) { UIA(() => m_statusForm.Status = detailedInfo); } else { m_statusForm.Status = detailedInfo; } m_notifyIcon.ShowBalloonTip(3000); }
/// <summary> /// Checks (recursively) if a rule matches a given network information /// </summary> /// <param name="rule">Rule to check</param> /// <param name="net">Network information</param> /// <param name="res">Detailed result if match</param> /// <returns>true if rule matches</returns> private bool CheckRuleAgainstNetwork(NetworkRule rule, NetworkInfo net, ref RulesCheckerResult res) { if (rule is NetworkRulesSet) { bool thisRes = false; foreach (var rule2 in (rule as NetworkRulesSet).Rules) { thisRes = CheckRuleAgainstNetwork(rule2, net, ref res); if ((rule as NetworkRulesSet).Op == Operator.And && !thisRes) { thisRes = false; break; } if ((rule as NetworkRulesSet).Op == Operator.Or && thisRes) { thisRes = true; break; } if ((rule as NetworkRulesSet).Op == Operator.Not) { thisRes = !thisRes; break; } } res = new RulesCheckerResult(thisRes ? Reasons.MATCH : Reasons.NOMATCH, res != null ? res.ReasonString : "complex rule used"); return thisRes; } else if (rule is NetworkRuleDNS) { foreach (string dns in net.DNS) { if ((rule as NetworkRuleDNS).DNS == dns) { res = new RulesCheckerResult(Reasons.MATCH, "network DNS matches " + dns); return true; } } } else if (rule is NetworkRuleSubnet) { foreach (string ip in net.NetworkIP) { if ((rule as NetworkRuleSubnet).Subnet == ip) { res = new RulesCheckerResult(Reasons.MATCH, "network subnet matches " + ip); return true; } } } else if (rule is NetworkRuleIfName) { string regex = (rule as NetworkRuleIfName).InterfaceName; if (Regex.IsMatch(net.IfName, regex)) { res = new RulesCheckerResult(Reasons.MATCH, "interface name matches " + regex); return true; } } else if (rule is NetworkRulePingable) { string ip = (rule as NetworkRulePingable).IP; log.Debug("Pinging " + ip); System.Net.NetworkInformation.Ping ping = new System.Net.NetworkInformation.Ping(); var reply = ping.Send(ip, 5000); log.Info("Ping status: " + reply.Status); if (reply.Status == System.Net.NetworkInformation.IPStatus.Success) { res = new RulesCheckerResult(Reasons.MATCH, "machine " + ip + " is pingable"); return true; } } return false; }