放一个之前写的arp -a结果解析代码

需求

  • 接口IP192.168.1.3  => 查对应的接口序号、该接口下所有ARP记录;
  • 接口序号 0x7 => 查对应的接口IP、该接口下所有ARP记录;
  • ARP记录的IP地址 192.168.1.122 => ARP记录的MAC地址,以及所有包含该IP的接口所对应的IP、序号;
  • ARP记录的MAC地址 50-8c-f5-f6-31-34 =>  ARP记录的IP地址,以及所有包含该IP的接口所对应的IP、序号。

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text.RegularExpressions;

namespace ConsoleApp1
{
    class Program
    {
        static void Main(string[] args)
        {
            //调用 arp.exe -a,并通过重定向标准输出获取命令的结果
            Process proc = Process.Start(
                new ProcessStartInfo()
                {
                    FileName = "arp.exe",
                    Arguments = "-a",
                    UseShellExecute = false,
                    RedirectStandardOutput = true
                });
            proc.Start();
            string result = proc.StandardOutput.ReadToEnd();
            proc.WaitForExit();

            //---------------------解析命令的结果,按接口切割并单独处理
            var sections = result.Split('接');

            //以接口IP和接口ID号为索引,查arp记录(正查)
            //结果包含arp记录中的IP和MAC
            //字典的Value数据类型是ValueTuple类型,C#7或者更高的版本可以支持
            //如果你的版本不够,可以把Value的类型改成自定义结构体或者类,下同
            Dictionary<string, List<(string IfIP, string Index, string ArpIp, string MAC)>> dicIf =
                new Dictionary<string, List<(string IfIP, string Index, string ArpIp, string MAC)>>();

            //以arp记录里的IP或MAC为索引(反查),查接口
            //结果包含接口的IP和索引
            Dictionary<string, List<(string IfIP, string Index, string ArpIp, string MAC)>> dicIP =
                new Dictionary<string, List<(string IfIP, string Index, string ArpIp, string MAC)>>();
            foreach (var section in sections)
            {
                if (!section.Contains("口")) continue;//split的第一个成员是个"\r\n",跳过

                //取得接口的IP,以及接口ID号
                var match =
                    Regex.Match(
                        section, @"口.*?(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}).*?(0x[0-9a-f]+)");
                string ifIP = match.Groups[1].Value;
                string ifIndex = match.Groups[2].Value;
                dicIf[ifIP] = new List<(string IfIP, string Index, string ArpIp, string MAC)>();
                dicIf[ifIndex] = new List<(string IfIP, string Index, string ArpIp, string MAC)>();

                //用正则匹配该接口下所有的arp记录
                //Group[1]是IP,Group[2]是MAC
                var matches =
                    Regex.Matches(
                        section,
                        @"(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})\s+([0-9a-f-]{17})\s+\S+\s+",
                        RegexOptions.Singleline | RegexOptions.IgnoreCase);
                foreach (Match m in matches)
                {
                    string ip = m.Groups[1].Value;

                    //IP首段大于223,该 IP为组播地址或广播地址,不需要处理
                    string ipPrefix = ip.Split('.')[0];
                    if (Convert.ToInt32(ipPrefix) > 223) continue;

                    string mac = m.Groups[2].Value;
                    //添加正向查找记录
                    dicIf[ifIP].Add((ifIP, ifIndex, ip, mac));
                    dicIf[ifIndex].Add((ifIP, ifIndex, ip, mac));
                    //添加反向查找记录,arp条目中的ip和mac各添加一次
                    foreach (var key in new string[] { ip, mac })
                    {
                        if (dicIP.ContainsKey(key))
                        {
                            dicIP[key].Add((ifIP, ifIndex, ip, mac));
                        }
                        else
                        {
                            dicIP[key] =
                                new List<(string IfIP, string Index, string ArpIp, string MAC)>() { (ifIP, ifIndex, ip, mac) };
                        }
                    }
                }
            }
            Console.WriteLine("正向查找字典(接口ip/序号 => arp记录):");
            foreach (var key in dicIf.Keys)
            {
                Console.WriteLine(
                    $"KEY:{key}\r\nVALUES:【" +
                    $"{string.Join("\r\n", dicIf[key].Select(r => $"接口IP: {r.IfIP}, 接口序号: {r.Index}, ARP-IP: {r.ArpIp}, ARP-MAC: {r.MAC}"))}】\r\n");
            }

            Console.WriteLine("反向查找字典:(arp记录的ip/mac => 接口ip/序号)");
            foreach (var key in dicIP.Keys)
            {
                Console.WriteLine(
                    $"KEY:{key}\r\nVALUES:【" +
                    $"{string.Join("\r\n", dicIP[key].Select(r => $"接口IP: {r.IfIP}, 接口序号: {r.Index}, ARP-IP: {r.ArpIp}, ARP-MAC: {r.MAC}"))}】\r\n");
            }
            Console.Read();
        }
    }
}

效果

正向查找字典(接口ip/序号 => arp记录):
KEY:192.168.220.1
VALUES:【接口IP: 192.168.220.1, 接口序号: 0x7, ARP-IP: 192.168.220.254, ARP-MAC: 00-50-56-e6-ca-af
接口IP: 192.168.220.1, 接口序号: 0x7, ARP-IP: 192.168.220.255, ARP-MAC: ff-ff-ff-ff-ff-ff】

KEY:0x7
VALUES:【接口IP: 192.168.220.1, 接口序号: 0x7, ARP-IP: 192.168.220.254, ARP-MAC: 00-50-56-e6-ca-af
接口IP: 192.168.220.1, 接口序号: 0x7, ARP-IP: 192.168.220.255, ARP-MAC: ff-ff-ff-ff-ff-ff】

KEY:192.168.2.51
VALUES:【接口IP: 192.168.2.51, 接口序号: 0xb, ARP-IP: 192.168.2.1, ARP-MAC: 00-15-5d-02-32-03
接口IP: 192.168.2.51, 接口序号: 0xb, ARP-IP: 192.168.2.50, ARP-MAC: 00-10-18-3a-58-8b
接口IP: 192.168.2.51, 接口序号: 0xb, ARP-IP: 192.168.2.52, ARP-MAC: 00-50-56-3a-ee-69
接口IP: 192.168.2.51, 接口序号: 0xb, ARP-IP: 192.168.2.68, ARP-MAC: 4c-0b-be-04-22-3e
接口IP: 192.168.2.51, 接口序号: 0xb, ARP-IP: 192.168.2.255, ARP-MAC: ff-ff-ff-ff-ff-ff】

KEY:0xb
VALUES:【接口IP: 192.168.2.51, 接口序号: 0xb, ARP-IP: 192.168.2.1, ARP-MAC: 00-15-5d-02-32-03
接口IP: 192.168.2.51, 接口序号: 0xb, ARP-IP: 192.168.2.50, ARP-MAC: 00-10-18-3a-58-8b
接口IP: 192.168.2.51, 接口序号: 0xb, ARP-IP: 192.168.2.52, ARP-MAC: 00-50-56-3a-ee-69
接口IP: 192.168.2.51, 接口序号: 0xb, ARP-IP: 192.168.2.68, ARP-MAC: 4c-0b-be-04-22-3e
接口IP: 192.168.2.51, 接口序号: 0xb, ARP-IP: 192.168.2.255, ARP-MAC: ff-ff-ff-ff-ff-ff】

KEY:192.168.219.1
VALUES:【接口IP: 192.168.219.1, 接口序号: 0x10, ARP-IP: 192.168.219.254, ARP-MAC: 00-50-56-fb-f5-b1
接口IP: 192.168.219.1, 接口序号: 0x10, ARP-IP: 192.168.219.255, ARP-MAC: ff-ff-ff-ff-ff-ff】

KEY:0x10
VALUES:【接口IP: 192.168.219.1, 接口序号: 0x10, ARP-IP: 192.168.219.254, ARP-MAC: 00-50-56-fb-f5-b1
接口IP: 192.168.219.1, 接口序号: 0x10, ARP-IP: 192.168.219.255, ARP-MAC: ff-ff-ff-ff-ff-ff】

反向查找字典:(arp记录的ip/mac => 接口ip/序号)
KEY:192.168.220.254
VALUES:【接口IP: 192.168.220.1, 接口序号: 0x7, ARP-IP: 192.168.220.254, ARP-MAC: 00-50-56-e6-ca-af】

KEY:00-50-56-e6-ca-af
VALUES:【接口IP: 192.168.220.1, 接口序号: 0x7, ARP-IP: 192.168.220.254, ARP-MAC: 00-50-56-e6-ca-af】

KEY:192.168.220.255
VALUES:【接口IP: 192.168.220.1, 接口序号: 0x7, ARP-IP: 192.168.220.255, ARP-MAC: ff-ff-ff-ff-ff-ff】

KEY:ff-ff-ff-ff-ff-ff
VALUES:【接口IP: 192.168.220.1, 接口序号: 0x7, ARP-IP: 192.168.220.255, ARP-MAC: ff-ff-ff-ff-ff-ff
接口IP: 192.168.2.51, 接口序号: 0xb, ARP-IP: 192.168.2.255, ARP-MAC: ff-ff-ff-ff-ff-ff
接口IP: 192.168.219.1, 接口序号: 0x10, ARP-IP: 192.168.219.255, ARP-MAC: ff-ff-ff-ff-ff-ff】

KEY:192.168.2.1
VALUES:【接口IP: 192.168.2.51, 接口序号: 0xb, ARP-IP: 192.168.2.1, ARP-MAC: 00-15-5d-02-32-03】

KEY:00-15-5d-02-32-03
VALUES:【接口IP: 192.168.2.51, 接口序号: 0xb, ARP-IP: 192.168.2.1, ARP-MAC: 00-15-5d-02-32-03】

KEY:192.168.2.50
VALUES:【接口IP: 192.168.2.51, 接口序号: 0xb, ARP-IP: 192.168.2.50, ARP-MAC: 00-10-18-3a-58-8b】

KEY:00-10-18-3a-58-8b
VALUES:【接口IP: 192.168.2.51, 接口序号: 0xb, ARP-IP: 192.168.2.50, ARP-MAC: 00-10-18-3a-58-8b】

KEY:192.168.2.52
VALUES:【接口IP: 192.168.2.51, 接口序号: 0xb, ARP-IP: 192.168.2.52, ARP-MAC: 00-50-56-3a-ee-69】

KEY:00-50-56-3a-ee-69
VALUES:【接口IP: 192.168.2.51, 接口序号: 0xb, ARP-IP: 192.168.2.52, ARP-MAC: 00-50-56-3a-ee-69】

KEY:192.168.2.68
VALUES:【接口IP: 192.168.2.51, 接口序号: 0xb, ARP-IP: 192.168.2.68, ARP-MAC: 4c-0b-be-04-22-3e】

KEY:4c-0b-be-04-22-3e
VALUES:【接口IP: 192.168.2.51, 接口序号: 0xb, ARP-IP: 192.168.2.68, ARP-MAC: 4c-0b-be-04-22-3e】

KEY:192.168.2.255
VALUES:【接口IP: 192.168.2.51, 接口序号: 0xb, ARP-IP: 192.168.2.255, ARP-MAC: ff-ff-ff-ff-ff-ff】

KEY:192.168.219.254
VALUES:【接口IP: 192.168.219.1, 接口序号: 0x10, ARP-IP: 192.168.219.254, ARP-MAC: 00-50-56-fb-f5-b1】

KEY:00-50-56-fb-f5-b1
VALUES:【接口IP: 192.168.219.1, 接口序号: 0x10, ARP-IP: 192.168.219.254, ARP-MAC: 00-50-56-fb-f5-b1】

KEY:192.168.219.255
VALUES:【接口IP: 192.168.219.1, 接口序号: 0x10, ARP-IP: 192.168.219.255, ARP-MAC: ff-ff-ff-ff-ff-ff】
分类: articles