refactor: 枚举移入Models目录,命名空间更新为Rainbow.Entity.Models
大石头 authored at 2026-07-02 12:54:58
2.70 KiB
RainbowBridge
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; }
}