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);
}
}