// Mozilla Public License 2.0 // If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/. // Copyright (C) LibreHardwareMonitor and Contributors // All Rights Reserved using System.Collections.Generic; using System.Linq; using System.Net.NetworkInformation; using System.Text; namespace LibreHardwareMonitor.Hardware.Network { internal class NetworkGroup : IGroup { private readonly Dictionary _networks = new Dictionary(); private readonly object _scanLock = new object(); private readonly ISettings _settings; private List _hardware = new List(); public NetworkGroup(ISettings settings) { _settings = settings; AddNetworkInterfaces(settings); NetworkChange.NetworkAddressChanged += NetworkChange_NetworkAddressChanged; NetworkChange.NetworkAvailabilityChanged += NetworkChange_NetworkAddressChanged; } public IEnumerable Hardware { get { return _hardware; } } public string GetReport() { var report = new StringBuilder(); foreach (Network hw in _hardware) { report.AppendLine(hw.NetworkInterface.Description); report.AppendLine(hw.NetworkInterface.OperationalStatus.ToString()); report.AppendLine(); foreach (var sensor in hw.Sensors) { report.AppendLine(sensor.Name); report.AppendLine(sensor.Value.ToString() + sensor.SensorType); report.AppendLine(); } } return report.ToString(); } public void Close() { NetworkChange.NetworkAddressChanged -= NetworkChange_NetworkAddressChanged; NetworkChange.NetworkAvailabilityChanged -= NetworkChange_NetworkAddressChanged; foreach (var nic in _hardware) nic.Close(); } private void AddNetworkInterfaces(ISettings settings) { // If no network is marked up (excluding loopback and tunnel) then don't scan // for interfaces. if (!NetworkInterface.GetIsNetworkAvailable()) return; // When multiple events fire concurrently, we don't want threads interfering // with others as they manipulate non-thread safe state. lock (_scanLock) { var networkInterfaces = NetworkInterface.GetAllNetworkInterfaces() .Where(DesiredNetworkType) .OrderBy(x => x.Name); var scanned = networkInterfaces.ToDictionary(x => x.Id, x => x); var newNetworkInterfaces = scanned.Where(x => !_networks.ContainsKey(x.Key)); var removedNetworkInterfaces = _networks.Where(x => !scanned.ContainsKey(x.Key)).ToList(); foreach (var nic in removedNetworkInterfaces) { nic.Value.Close(); _networks.Remove(nic.Key); } foreach (var nic in newNetworkInterfaces) { _networks.Add(nic.Key, new Network(nic.Value, settings)); } _hardware = _networks.Values.OrderBy(x => x.Name).ToList(); } } private void NetworkChange_NetworkAddressChanged(object sender, System.EventArgs e) { AddNetworkInterfaces(_settings); } private static bool DesiredNetworkType(NetworkInterface nic) { switch (nic.NetworkInterfaceType) { case NetworkInterfaceType.Loopback: case NetworkInterfaceType.Tunnel: case NetworkInterfaceType.Unknown: return false; default: return true; } } } }