C# 获取 ARP 映射


        /// <summary>
        /// 引入windowsAPI
        /// </summary>
        public class LibArp
        {
            //用于转换ip地址  
            [DllImport("ws2_32.dll")]
            public static extern int inet_addr(string cp);

            //用于发送APR包(根据APR协议!)  
            [DllImport("IPHLPAPI.dll")]
            public static extern int SendARP(int DestIP, int ScrIP, ref long pMacAddr, ref int PhyAddrLen);
        }

        /// <summary>
        /// 根据ARP映射获取指定IP的MAC地址
        /// </summary>
        /// <param name="IP"></param>
        /// <returns></returns>
        public string GetMACAddressByIP(string IP)
        {
            StringBuilder MacRouteBuilder = new StringBuilder();
            string macRoute;
            try
            {
                int ldest = LibArp.inet_addr(IP); //将IP地址从 点数格式转换成无符号长整型  
                long macinfo = new long();
                int len = 6;
                //SendARP函数发送一个地址解析协议(ARP)请求获得指定的目的地IPv4地址相对应的物理地址  
                LibArp.SendARP(ldest, 0, ref macinfo, ref len);
                string TmpMac = Convert.ToString(macinfo, 16).PadLeft(12, '0');//转换成16进制  
                //  
                for (int i = 10; i >= 0; i = i - 2)//反过来读取,原因可以查看接口函数sendApr!  
                {
                    MacRouteBuilder.Append(TmpMac.Substring(i, 2).ToUpper());
                    if (i >= 2)
                    {
                        MacRouteBuilder.Append("-");
                    }
                }
            }
            catch (Exception Mye)
            {
                MacRouteBuilder.Append("获取远程主机的MAC错误:");
                MacRouteBuilder.Append(Mye.ToString());
            }
            macRoute = MacRouteBuilder.ToString();
            return macRoute;
        }

        /// <summary>
        /// 获取ARP查询字符串
        /// </summary>
        /// <returns></returns>
        private static string GetARPResult()
        {
            Process p = null;
            string output = string.Empty;
            try
            {
                p = Process.Start(new ProcessStartInfo("arp", "-a")
                {
                    CreateNoWindow = true,
                    UseShellExecute = false,
                    RedirectStandardOutput = true
                });
                output = p.StandardOutput.ReadToEnd();
            }
            catch (Exception ex)
            {
                throw new Exception("IPInfo: Error Retrieving 'arp -a' Results", ex);
            }
            finally
            {
                if (p != null)
                {
                    p.Close();
                }
            }
            return output;
        }

        /// <summary>
        /// 获取IP地址与Mac地址对应数据表
        /// </summary>
        /// <returns>Mac-IP</returns>
        public static List<string[]> GetIPInfo()
        {
            try
            {
                var list = new List<string[]>();
                var ArpResult = GetARPResult();
                foreach (var arp in ArpResult.Split(new char[] { '\n', '\r' }))
                {
                    if (!string.IsNullOrEmpty(arp))
                    {
                        var OArp = arp.Split(new char[] { ' ', '\t' });
                        var pieces = (from piece in OArp
                                      where !string.IsNullOrEmpty(piece)
                                      select piece).ToArray();
                        if (pieces.Length == 3)
                        {
                            //pieces[1]Mac
                            //pieces[0]IP
                            list.Add(new string[2] { pieces[1], pieces[0] });
                        }
                    }
                }
                return list;
            }
            catch (Exception ex)
            {
                throw new Exception("IPInfo: Error Parsing 'arp -a' results", ex);
            }
        }

这是 获取局域网 所有主机 arp 映射

using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
using System.ComponentModel;
using System.Net;

namespace PreviewDemo
{
    public class GetIPNetTable
    {
        // The max number of physical addresses.
        const int MAXLEN_PHYSADDR = 8;

        // Define the MIB_IPNETROW structure.
        [StructLayout(LayoutKind.Sequential)]
        struct MIB_IPNETROW
        {
            [MarshalAs(UnmanagedType.U4)]
            public int dwIndex;
            [MarshalAs(UnmanagedType.U4)]
            public int dwPhysAddrLen;
            [MarshalAs(UnmanagedType.U1)]
            public byte mac0;
            [MarshalAs(UnmanagedType.U1)]
            public byte mac1;
            [MarshalAs(UnmanagedType.U1)]
            public byte mac2;
            [MarshalAs(UnmanagedType.U1)]
            public byte mac3;
            [MarshalAs(UnmanagedType.U1)]
            public byte mac4;
            [MarshalAs(UnmanagedType.U1)]
            public byte mac5;
            [MarshalAs(UnmanagedType.U1)]
            public byte mac6;
            [MarshalAs(UnmanagedType.U1)]
            public byte mac7;
            [MarshalAs(UnmanagedType.U4)]
            public int dwAddr;
            [MarshalAs(UnmanagedType.U4)]
            public int dwType;
        }

        // Declare the GetIpNetTable function.
        [DllImport("IpHlpApi.dll")]
        [return: MarshalAs(UnmanagedType.U4)]
        static extern int GetIpNetTable(
           IntPtr pIpNetTable,
           [MarshalAs(UnmanagedType.U4)]
         ref int pdwSize,
           bool bOrder);

        [DllImport("IpHlpApi.dll", SetLastError = true, CharSet = CharSet.Auto)]
        internal static extern int FreeMibTable(IntPtr plpNetTable);

        // The insufficient buffer error.
        const int ERROR_INSUFFICIENT_BUFFER = 122;

        /// <summary>
        /// 获取
        /// </summary>
        public static List<ArpIP> Get_IPNetTable()
        {
            List<ArpIP> ArrArpIP = new List<ArpIP>();
            // The number of bytes needed.
            int bytesNeeded = 0;

            // The result from the API call.
            int result = GetIpNetTable(IntPtr.Zero, ref bytesNeeded, false);

            // Call the function, expecting an insufficient buffer.
            if (result != ERROR_INSUFFICIENT_BUFFER)
            {
                // Throw an exception.
                throw new Win32Exception(result);
            }

            // Allocate the memory, do it in a try/finally block, to ensure
            // that it is released.
            IntPtr buffer = IntPtr.Zero;

            // Try/finally.
            try
            {
                // Allocate the memory.
                buffer = Marshal.AllocCoTaskMem(bytesNeeded);

                // Make the call again. If it did not succeed, then
                // raise an error.
                result = GetIpNetTable(buffer, ref bytesNeeded, false);

                // If the result is not 0 (no error), then throw an exception.
                if (result != 0)
                {
                    // Throw an exception.
                    throw new Win32Exception(result);
                }

                // Now we have the buffer, we have to marshal it. We can read
                // the first 4 bytes to get the length of the buffer.
                int entries = Marshal.ReadInt32(buffer);

                // Increment the memory pointer by the size of the int.
                IntPtr currentBuffer = new IntPtr(buffer.ToInt64() +
                   Marshal.SizeOf(typeof(int)));

                // Allocate an array of entries.
                MIB_IPNETROW[] table = new MIB_IPNETROW[entries];

                // Cycle through the entries.
                for (int index = 0; index < entries; index++)
                {
                    // Call PtrToStructure, getting the structure information.
                    table[index] = (MIB_IPNETROW)Marshal.PtrToStructure(new
                       IntPtr(currentBuffer.ToInt64() + (index *
                       Marshal.SizeOf(typeof(MIB_IPNETROW)))), typeof(MIB_IPNETROW));
                }

                for (int index = 0; index < entries; index++)
                {
                    MIB_IPNETROW row = table[index];
                    IPAddress ip = new IPAddress(BitConverter.GetBytes(row.dwAddr));
                    Console.Write("IP:" + ip.ToString() + "\t\tMAC:");
                    Console.Write(row.mac0.ToString("X2") + '-');
                    Console.Write(row.mac1.ToString("X2") + '-');
                    Console.Write(row.mac2.ToString("X2") + '-');
                    Console.Write(row.mac3.ToString("X2") + '-');
                    Console.Write(row.mac4.ToString("X2") + '-');
                    Console.WriteLine(row.mac5.ToString("X2"));
                    ArrArpIP.Add(new ArpIP(ip.ToString(), row.mac0.ToString("X2")));
                    ArrArpIP.Add(new ArpIP(ip.ToString(), row.mac1.ToString("X2")));
                    ArrArpIP.Add(new ArpIP(ip.ToString(), row.mac2.ToString("X2")));
                    ArrArpIP.Add(new ArpIP(ip.ToString(), row.mac3.ToString("X2")));
                    ArrArpIP.Add(new ArpIP(ip.ToString(), row.mac4.ToString("X2")));
                    ArrArpIP.Add(new ArpIP(ip.ToString(), row.mac5.ToString("X2")));
                    ArrArpIP.Add(new ArpIP(ip.ToString(), row.mac6.ToString("X2")));
                    ArrArpIP.Add(new ArpIP(ip.ToString(), row.mac7.ToString("X2")));
                }
            }
            finally
            {
                // Release the memory.
                FreeMibTable(buffer);
            }
            return ArrArpIP;
        }

        public class ArpIP
        {
            public ArpIP(string _IPAddress, string _MacAddress)
            {
                IPAddress = _IPAddress;
                MacAddress = _MacAddress;
            }
            public string IPAddress { get; set; }
            public string MacAddress { get; set; }
        }
    }
}

 

  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值