using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Threading.Tasks;
namespace Rainbow.Services;
/// <summary>Windows ARP 表采集。通过 arp -a 命令解析 ARP 缓存</summary>
public class WindowsArpScanner
{
/// <summary>获取当前 ARP 表</summary>
/// <returns>ARP 条目列表</returns>
public async Task<List<ArpEntry>> GetArpTableAsync()
{
var result = new List<ArpEntry>();
try
{
var psi = new ProcessStartInfo("arp", "-a")
{
RedirectStandardOutput = true,
UseShellExecute = false,
CreateNoWindow = true,
};
using var proc = Process.Start(psi);
if (proc == null) return result;
var output = await proc.StandardOutput.ReadToEndAsync();
await proc.WaitForExitAsync().WaitAsync(TimeSpan.FromSeconds(10));
// arp -a 输出格式(每个接口一段):
// 接口: 192.168.1.100 --- 0x5
// 192.168.1.1 00-11-22-33-44-55 动态
// 192.168.1.2 11-22-33-44-55-66 静态
foreach (var line in output.Split('\n'))
{
var trimmed = line.Trim();
if (String.IsNullOrEmpty(trimmed)) continue;
if (trimmed.Contains("接口") || trimmed.Contains("Interface")) continue;
var parts = trimmed.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
if (parts.Length < 3) continue;
// Windows ARP 格式: IP MAC Type
if (!parts[0].Contains('.') && !parts[0].Contains(':')) continue;
var ip = parts[0];
var mac = parts[1].Replace('-', ':').ToUpper();
var type = parts.Length > 2 ? parts[2] : "";
// 跳过无效 MAC
if (mac == "00:00:00:00:00:00") continue;
result.Add(new ArpEntry
{
Ip = ip,
Mac = mac,
IsStatic = String.Equals(type, "静态", StringComparison.Ordinal) ||
String.Equals(type, "static", StringComparison.OrdinalIgnoreCase),
});
}
}
catch
{
// 异常时返回空列表
}
return result;
}
}
/// <summary>ARP 条目 DTO</summary>
public class ArpEntry
{
/// <summary>IP 地址</summary>
public String Ip { get; set; } = "";
/// <summary>MAC 地址</summary>
public String Mac { get; set; } = "";
/// <summary>是否为静态绑定</summary>
public Boolean IsStatic { get; set; }
}
|