using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Net.Http; using System.Net.NetworkInformation; using System.Threading; using System.Threading.Tasks; using Pingerino.Services.Interfaces; namespace Pingerino.Services { public class NetworkService : INetworkService { private readonly HttpClient _httpClient; private readonly ILoggingService _logger; private bool _disposed; public NetworkService(ILoggingService logger) { _logger = logger ?? throw new ArgumentNullException(nameof(logger)); _httpClient = new HttpClient { Timeout = TimeSpan.FromSeconds(10) }; } public async System.Threading.Tasks.Task GetPublicIpAddressAsync(CancellationToken cancellationToken = default) { try { var response = await _httpClient.GetStringAsync("http://ipinfo.io/ip"); var publicIp = response.Trim(); _logger.LogInformation($"Retrieved public IP: {publicIp}"); return publicIp; } catch (Exception ex) { _logger.LogError("Failed to retrieve public IP address", ex); throw; } } public async System.Threading.Tasks.Task> GetNetworkAdaptersAsync() { return await System.Threading.Tasks.Task.Run(() => { var adapters = new List(); try { foreach (var nic in NetworkInterface.GetAllNetworkInterfaces()) { if (nic.NetworkInterfaceType == NetworkInterfaceType.Loopback) continue; var properties = nic.GetIPProperties(); var adapter = new NetworkAdapterInfo { Name = nic.Name, Description = nic.Description, PhysicalAddress = nic.GetPhysicalAddress().ToString(), IsActive = nic.OperationalStatus == OperationalStatus.Up, InterfaceType = nic.NetworkInterfaceType.ToString() }; // Get IPv4 properties if available try { var ipv4Properties = properties.GetIPv4Properties(); adapter.IsDhcpEnabled = ipv4Properties.IsDhcpEnabled; } catch { adapter.IsDhcpEnabled = false; } // Get IP addresses var ipv4Address = properties.UnicastAddresses .FirstOrDefault(ip => ip.Address.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork); if (ipv4Address != null) { adapter.IpAddress = ipv4Address.Address.ToString(); adapter.SubnetMask = ipv4Address.IPv4Mask?.ToString(); } // Get gateway var gateway = properties.GatewayAddresses.FirstOrDefault(); if (gateway != null) { adapter.DefaultGateway = gateway.Address.ToString(); } // Get DHCP server var dhcpServer = properties.DhcpServerAddresses.FirstOrDefault(); if (dhcpServer != null) { adapter.DhcpServer = dhcpServer.ToString(); } // Get DNS servers adapter.DnsServers = properties.DnsAddresses.Select(dns => dns.ToString()).ToList(); adapters.Add(adapter); } _logger.LogInformation($"Retrieved {adapters.Count} network adapters"); } catch (Exception ex) { _logger.LogError("Error retrieving network adapters", ex); } return adapters; }); } public async System.Threading.Tasks.Task ResetNetworkAdapterAsync(string adapterName, IProgress progress = null, CancellationToken cancellationToken = default) { try { progress?.Report(10); _logger.LogInformation($"Starting network reset for adapter: {adapterName}"); var processInfo = new ProcessStartInfo { FileName = "cmd.exe", Arguments = $"/c ipconfig /release \"{adapterName}\" && ipconfig /renew \"{adapterName}\"", UseShellExecute = false, RedirectStandardOutput = true, RedirectStandardError = true, CreateNoWindow = true, Verb = "runas" }; progress?.Report(30); using (var process = Process.Start(processInfo)) { if (process == null) { _logger.LogError("Failed to start network reset process"); return false; } progress?.Report(60); process.WaitForExit(); progress?.Report(90); var success = process.ExitCode == 0; if (success) { _logger.LogInformation($"Network reset completed successfully for {adapterName}"); } else { _logger.LogError($"Network reset failed with exit code: {process.ExitCode}"); } progress?.Report(100); return success; } } catch (Exception ex) { _logger.LogError("Error during network reset", ex); return false; } } public async System.Threading.Tasks.Task GetActiveEthernetAdapterAsync() { var adapters = await GetNetworkAdaptersAsync(); return adapters.FirstOrDefault(a => a.InterfaceType == NetworkInterfaceType.Ethernet.ToString() && a.IsActive); } public async System.Threading.Tasks.Task IsNetworkAvailableAsync() { return await System.Threading.Tasks.Task.Run(() => NetworkInterface.GetIsNetworkAvailable()); } public void Dispose() { if (_disposed) return; _httpClient?.Dispose(); _disposed = true; } } }