using System.Numerics; using CoreAgent.Domain.Interfaces; namespace CoreAgent.Infrastructure.Network; /// /// 提供IP地址相关的工具方法 /// public static class IPAddressUtils { /// /// 检查两个IPv4地址是否在同一个子网内 /// /// 第一个IP地址 /// 第二个IP地址 /// 子网掩码 /// 如果两个IP地址在同一个子网内返回true,否则返回false /// 当IP地址或子网掩码不是IPv4格式时抛出 public static bool IsSameIPv4Subnet(System.Net.IPAddress ip1, System.Net.IPAddress ip2, System.Net.IPAddress subnetMask) { if (ip1.AddressFamily != System.Net.Sockets.AddressFamily.InterNetwork || ip2.AddressFamily != System.Net.Sockets.AddressFamily.InterNetwork || subnetMask.AddressFamily != System.Net.Sockets.AddressFamily.InterNetwork) { throw new ArgumentException("IP addresses and subnet mask must be IPv4."); } byte[] ip1Bytes = ip1.GetAddressBytes(); byte[] ip2Bytes = ip2.GetAddressBytes(); byte[] subnetBytes = subnetMask.GetAddressBytes(); byte[] network1 = new byte[4]; byte[] network2 = new byte[4]; for (int i = 0; i < 4; i++) { network1[i] = (byte)(ip1Bytes[i] & subnetBytes[i]); network2[i] = (byte)(ip2Bytes[i] & subnetBytes[i]); } return new System.Net.IPAddress(network1).Equals(new System.Net.IPAddress(network2)); } /// /// 检查两个IPv6地址是否在同一个子网内 /// /// 第一个IP地址 /// 第二个IP地址 /// 前缀长度 /// 如果两个IP地址在同一个子网内返回true,否则返回false /// 当IP地址不是IPv6格式时抛出 public static bool IsSameIPv6Subnet(System.Net.IPAddress ip1, System.Net.IPAddress ip2, int prefixLength) { if (ip1.AddressFamily != System.Net.Sockets.AddressFamily.InterNetworkV6 || ip2.AddressFamily != System.Net.Sockets.AddressFamily.InterNetworkV6) { throw new ArgumentException("IP addresses must be IPv6."); } BigInteger ip1Value = new BigInteger(ip1.GetAddressBytes()); BigInteger ip2Value = new BigInteger(ip2.GetAddressBytes()); BigInteger mask = BigInteger.One << (128 - prefixLength); mask -= BigInteger.One; mask = ~mask; return (ip1Value & mask) == (ip2Value & mask); } /// /// 获取系统的IPv4地址列表 /// /// 命令策略工厂 /// 取消令牌源 /// 日志记录器 /// IPv4地址列表 public static async Task> CheckAddressIPv4(ICommandStrategyFactory commandStrategyFactory, CancellationTokenSource source) { List addrs = new List(); var inet4result = await commandStrategyFactory.CreateStrategy().ExecuteBufferedAsync("ifconfig | grep 'inet ' | awk '{print $2}'", source); if (!string.IsNullOrWhiteSpace(inet4result)) addrs.AddRange(RemoveNewLines(inet4result)); return addrs; } /// /// 获取系统的IPv6地址列表 /// /// 命令策略工厂 /// 取消令牌源 /// 日志记录器 /// IPv6地址列表 public static async Task> CheckAddressIPv6(ICommandStrategyFactory commandStrategyFactory, CancellationTokenSource source) { List addrs = new List(); var inet6result = await commandStrategyFactory.CreateStrategy().ExecuteBufferedAsync("ifconfig | grep 'inet6 ' | awk '{print $2}'", source); if (!string.IsNullOrWhiteSpace(inet6result)) addrs.AddRange(RemoveNewLines(inet6result)); return addrs; } /// /// 获取系统的IPv4地址和子网掩码列表 /// /// 命令策略工厂 /// 取消令牌源 /// 日志记录器 /// IPv4地址和子网掩码的元组列表 public static async Task> CheckAddressIPv4Mask(ICommandStrategyFactory commandStrategyFactory, CancellationTokenSource source) { List<(string ipv4, string mask)> addrs = new List<(string ipv4, string mask)>(); var inet4result = await commandStrategyFactory.CreateStrategy().ExecuteBufferedAsync("ifconfig | grep 'inet ' | awk '{print $2\\\"|\\\"$4}'", source); if (!string.IsNullOrWhiteSpace(inet4result)) addrs.AddRange(RemoveNewLines(inet4result).Select(s => (s.Split("|")[0], s.Split("|")[1]))); return addrs; } /// /// 获取系统的IPv6地址和前缀长度列表 /// /// 命令策略工厂 /// 取消令牌源 /// 日志记录器 /// IPv6地址和前缀长度的元组列表 public static async Task> CheckAddressIPv6Prefix(ICommandStrategyFactory commandStrategyFactory, CancellationTokenSource source) { List<(string ipv6, string Prefix)> addrs = new List<(string ipv6, string Prefix)>(); var inet6result = await commandStrategyFactory.CreateStrategy().ExecuteBufferedAsync("ifconfig | grep 'inet6 ' | awk '{print $2\\\"|\\\"$4}'", source); if (!string.IsNullOrWhiteSpace(inet6result)) addrs.AddRange(RemoveNewLines(inet6result).Select(s => (s.Split("|")[0], s.Split("|")[1]))); return addrs; } /// /// 计算两个IP地址的匹配位数 /// /// 第一个IP地址 /// 第二个IP地址 /// 匹配的位数 public static int GetMatchingBits(string ip1, string ip2) { byte[] bytes1 = System.Net.IPAddress.Parse(ip1).GetAddressBytes(); byte[] bytes2 = System.Net.IPAddress.Parse(ip2).GetAddressBytes(); int matchingBits = 0; for (int i = 0; i < bytes1.Length; i++) { int diff = bytes1[i] ^ bytes2[i]; // 异或计算不同位 for (int bit = 7; bit >= 0; bit--) { if ((diff & (1 << bit)) == 0) matchingBits++; else return matchingBits; } } return matchingBits; } /// /// 移除字符串中的换行符并分割成数组 /// /// 输入字符串 /// 分割后的字符串数组 private static string[] RemoveNewLines(string input) { return input.Split("\n", StringSplitOptions.RemoveEmptyEntries); } }