using System; using System.Collections.Generic; using System.Net; using System.Linq; namespace LanDiscovery.Services { public class IpRangeService { public string SuggestCidrFromNic(string? ipAddress, string? subnetMask) { if (string.IsNullOrEmpty(ipAddress) || string.IsNullOrEmpty(subnetMask)) return ""; // Simple logic: if mask is 255.255.255.0 (/24), mask the IP // This is a naive implementation for MVP. if (IPAddress.TryParse(ipAddress, out var ip) && IPAddress.TryParse(subnetMask, out var mask)) { byte[] ipBytes = ip.GetAddressBytes(); byte[] maskBytes = mask.GetAddressBytes(); if (ipBytes.Length != 4 || maskBytes.Length != 4) return ""; byte[] networkBytes = new byte[4]; for (int i = 0; i < 4; i++) { networkBytes[i] = (byte)(ipBytes[i] & maskBytes[i]); } int cidr = 0; // Count bits in mask // System.Collections.BitArray could be used, or simple lookup // For MVP, handling common masks: uint maskVal = BitConverter.ToUInt32(maskBytes.Reverse().ToArray(), 0); while (maskVal != 0) { cidr += (int)(maskVal & 1); maskVal >>= 1; } return $"{new IPAddress(networkBytes)}/{cidr}"; } return ""; } public (IPAddress Start, IPAddress End) ParseCidr(string cidr) { var parts = cidr.Split('/'); if (parts.Length != 2) throw new ArgumentException("Invalid CIDR format"); var ip = IPAddress.Parse(parts[0]); int prefixLength = int.Parse(parts[1]); byte[] ipBytes = ip.GetAddressBytes(); uint ipVal = BitConverter.ToUInt32(ipBytes.Reverse().ToArray(), 0); uint mask = 0xffffffff << (32 - prefixLength); uint network = ipVal & mask; uint broadcast = network | ~mask; byte[] startBytes = BitConverter.GetBytes(network).Reverse().ToArray(); byte[] endBytes = BitConverter.GetBytes(broadcast).Reverse().ToArray(); // Skip network address and broadcast address for usable range? // Usually scanners scan everything including gateway (often .1) // Let's include everything in the range [Network, Broadcast] return (new IPAddress(startBytes), new IPAddress(endBytes)); } public IEnumerable GetIpsInRange(string cidr) { var (start, end) = ParseCidr(cidr); byte[] startBytes = start.GetAddressBytes().Reverse().ToArray(); byte[] endBytes = end.GetAddressBytes().Reverse().ToArray(); uint startVal = BitConverter.ToUInt32(startBytes, 0); uint endVal = BitConverter.ToUInt32(endBytes, 0); for (uint i = startVal; i <= endVal; i++) { byte[] bytes = BitConverter.GetBytes(i).Reverse().ToArray(); yield return new IPAddress(bytes); } } } }