<commit_before>﻿using Caliburn.Micro;
using Microsoft.Win32;
using SimpleDnsCrypt.Config;
using SimpleDnsCrypt.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.NetworkInformation;

namespace SimpleDnsCrypt.Helper
{
	/// <summary>
	///     Class to manage the local network interfaces.
	/// </summary>
	public static class LocalNetworkInterfaceManager
	{
		private static readonly ILog Log = LogManagerHelper.Factory();

		/// <summary>
		///     Get a list of the local network interfaces.
		/// </summary>
		/// <param name="listenAddresses"></param>
		/// <param name="showHiddenCards">Show hidden cards.</param>
		/// <param name="showOnlyOperationalUp">Include only connected network cards.</param>
		/// <returns>A (filtered) list of the local network interfaces.</returns>
		/// <exception cref="NetworkInformationException">A Windows system function call failed. </exception>
		/// <exception cref="ArgumentNullException"></exception>
		public static List<LocalNetworkInterface> GetLocalNetworkInterfaces(List<string> listenAddresses = null, bool showHiddenCards = false,
			bool showOnlyOperationalUp = true)
		{
			var interfaces = new List<LocalNetworkInterface>();
			foreach (var nic in NetworkInterface.GetAllNetworkInterfaces())
			{
				if (showOnlyOperationalUp)
				{
					if (nic.OperationalStatus != OperationalStatus.Up)
					{
						continue;
					}
				}

				if (!showHiddenCards)
				{
					var add = true;
					foreach (var blacklistEntry in Global.NetworkInterfaceBlacklist)
					{
						if (nic.Description.Contains(blacklistEntry) || nic.Name.Contains(blacklistEntry))
						{
							add = false;
						}
					}
					if (!add) continue;
				}
				var localNetworkInterface = new LocalNetworkInterface
				{
					Name = nic.Name,
					Description = nic.Description,
					Type = nic.NetworkInterfaceType,
					Dns = GetDnsServerList(nic.Id),
					Ipv4Support = nic.Supports(NetworkInterfaceComponent.IPv4),
					Ipv6Support = nic.Supports(NetworkInterfaceComponent.IPv6),
					OperationalStatus = nic.OperationalStatus
				};
				// strict check if the interface supports IPv6
				localNetworkInterface.UseDnsCrypt = IsUsingDnsCrypt(listenAddresses, localNetworkInterface, localNetworkInterface.Ipv6Support);
				interfaces.Add(localNetworkInterface);
			}
			return interfaces;
		}

		/// <summary>
		///     Simple check if the network interface contains any of resolver addresses.
		/// </summary>
		/// <param name="listenAddresses"></param>
		/// <param name="localNetworkInterface">The interface to check.</param>
		/// <returns><c>true</c> if a address was found, otherwise <c>false</c></returns>
		public static bool IsUsingDnsCrypt(List<string> listenAddresses, LocalNetworkInterface localNetworkInterface, bool strictCheck = false)
		{
			if (listenAddresses == null) return false;
			var addressOnly = (from listenAddress in listenAddresses let lastIndex = listenAddress.LastIndexOf(":", StringComparison.Ordinal) select listenAddress.Substring(0, lastIndex).Replace("[", "").Replace("]", "")).ToList();

			if (strictCheck)
			{
				// check for ALL addresses
				return addressOnly.Intersect(localNetworkInterface.Dns.Select(x => x.Address).ToList()).Count() == addressOnly.Count();
			}

			return localNetworkInterface.Dns.Any(d => addressOnly.Contains(d.Address));
		}



		/// <summary>
		///     Get the nameservers of an interface.
		/// </summary>
		/// <param name="localNetworkInterface">The interface to extract from.</param>
		/// <returns>A list of nameservers.</returns>
		internal static List<DnsServer> GetDnsServerList(string localNetworkInterface)
		{
			var serverAddresses = new List<DnsServer>();
			try
			{
				var registryKeyIpv6 = Registry.GetValue(
						"HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Services\\TCPIP6\\Parameters\\Interfaces\\" +
						localNetworkInterface,<commit_msg>Update LocalNetworkInterfaceManager.cs<commit_after>﻿using Caliburn.Micro;
using Microsoft.Win32;
using SimpleDnsCrypt.Config;
using SimpleDnsCrypt.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.NetworkInformation;

namespace SimpleDnsCrypt.Helper
{
	/// <summary>
	///     Class to manage the local network interfaces.
	/// </summary>
	public static class LocalNetworkInterfaceManager
	{
		private static readonly ILog Log = LogManagerHelper.Factory();

		/// <summary>
		///     Get a list of the local network interfaces.
		/// </summary>
		/// <param name="listenAddresses"></param>
		/// <param name="showHiddenCards">Show hidden cards.</param>
		/// <param name="showOnlyOperationalUp">Include only connected network cards.</param>
		/// <returns>A (filtered) list of the local network interfaces.</returns>
		/// <exception cref="NetworkInformationException">A Windows system function call failed. </exception>
		/// <exception cref="ArgumentNullException"></exception>
		public static List<LocalNetworkInterface> GetLocalNetworkInterfaces(List<string> listenAddresses = null, bool showHiddenCards = false,
			bool showOnlyOperationalUp = true)
		{
			var interfaces = new List<LocalNetworkInterface>();
			foreach (var nic in NetworkInterface.GetAllNetworkInterfaces())
			{
				if (showOnlyOperationalUp)
				{
					if (nic.OperationalStatus != OperationalStatus.Up)
					{
						continue;
					}
				}

				if (!showHiddenCards)
				{
					var add = true;
					foreach (var blacklistEntry in Global.NetworkInterfaceBlacklist)
					{
						if (nic.Description.Contains(blacklistEntry) || nic.Name.Contains(blacklistEntry))
						{
							add = false;
						}
					}
					if (!add) continue;
				}
				var localNetworkInterface = new LocalNetworkInterface
				{
					Name = nic.Name,
					Description = nic.Description,
					Type = nic.NetworkInterfaceType,
					Dns = GetDnsServerList(nic.Id),
					Ipv4Support = nic.Supports(NetworkInterfaceComponent.IPv4),
					Ipv6Support = nic.Supports(NetworkInterfaceComponent.IPv6),
					OperationalStatus = nic.OperationalStatus
				};
				// strict check if the interface supports IPv6
				localNetworkInterface.UseDnsCrypt = IsUsingDnsCrypt(listenAddresses, localNetworkInterface, localNetworkInterface.Ipv6Support);
				interfaces.Add(localNetworkInterface);
			}
			return interfaces;
		}

		/// <summary>
		///     Simple check if the network interface contains any of resolver addresses.
		/// </summary>
		/// <param name="listenAddresses"></param>
		/// <param name="localNetworkInterface">The interface to check.</param>
		/// <param name="strictCheck"></param>
		/// <returns><c>true</c> if a address was found, otherwise <c>false</c></returns>
		public static bool IsUsingDnsCrypt(List<string> listenAddresses, LocalNetworkInterface localNetworkInterface, bool strictCheck = false)
		{
			if (listenAddresses == null) return false;
			var addressOnly = (from listenAddress in listenAddresses let lastIndex = listenAddress.LastIndexOf(":", StringComparison.Ordinal) select listenAddress.Substring(0, lastIndex).Replace("[", "").Replace("]", "")).ToList();

			if (strictCheck)
			{
				// check for ALL addresses
				return addressOnly.Intersect(localNetworkInterface.Dns.Select(x => x.Address).ToList()).Count() == addressOnly.Count;
			}

			return localNetworkInterface.Dns.Any(d => addressOnly.Contains(d.Address));
		}



		/// <summary>
		///     Get the nameservers of an interface.
		/// </summary>
		/// <param name="localNetworkInterface">The interface to extract from.</param>
		/// <returns>A list of nameservers.</returns>
		internal static List<DnsServer> GetDnsServerList(string localNetworkInterface)
		{
			var serverAddresses = new List<DnsServer>();
			try
			{
				var registryKeyIpv6 = Registry.GetValue(
						"HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Services\\TCPIP6\\Parameters\\Interfaces\\" +
						localNetworkInterface,
{'fraction_non_alphanumeric': 0.11914460285132383, 'fraction_numerical': 0.00280040733197556, 'mean_word_length': 3.820245398773006, 'pattern_counts': {'":': 2, '<': 85, '<?xml version=': 0, '>': 89, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2136995', 'n_tokens_mistral': 2616, 'n_tokens_neox': 2174, 'n_words': 518}