zoukankan      html  css  js  c++  java
  • 使用ARP获取局域网内设备IP和MAC地址

    根据Arp列表数据,查询本地设备在线状态

    使用 arp -a 获得所有内网地址,首先看Mod对象

        public struct MacIpPair
        {
            public string HostName;
            public string MacAddress;
            public string IpAddress;
    
            public override string ToString()
            {
                string str = "";
                str += $"HostName:{HostName}	{IpAddress}	{MacAddress}";
                return str;
            }
    
        }

    其次看看查询方法:

            public List<MacIpPair> GetAllMacAddressesAndIppairs()
            {
                List<MacIpPair> mip = new List<MacIpPair>();
                System.Diagnostics.Process pProcess = new System.Diagnostics.Process();
                pProcess.StartInfo.FileName = "arp";
                pProcess.StartInfo.Arguments = "-a ";
                pProcess.StartInfo.UseShellExecute = false;
                pProcess.StartInfo.RedirectStandardOutput = true;
                pProcess.StartInfo.CreateNoWindow = true;
                pProcess.Start();
                string cmdOutput = pProcess.StandardOutput.ReadToEnd();
                string pattern = @"(?<ip>([0-9]{1,3}.?){4})s*(?<mac>([a-f0-9]{2}-?){6})";
    
                foreach (Match m in Regex.Matches(cmdOutput, pattern, RegexOptions.IgnoreCase))
                {
                    mip.Add(new MacIpPair()
                    {
                        MacAddress = m.Groups["mac"].Value,
                        IpAddress = m.Groups["ip"].Value
                    });
                }
    
                return mip;
            }

    在写个调用就可以了:

        class Program
        {
            static void Main(string[] args)
            {
                var arp = new Comm.ArpHelper();
                var i = arp.GetLocalIpInfo();
                Console.WriteLine(i.ToString());
    
                var l = arp.GetAllMacAddressesAndIppairs();
                l.ForEach(x =>
                {
                    //Console.WriteLine($"IP:{x.IpAddress}    Mac:{x.MacAddress}");
                    Console.WriteLine(x.ToString());
                });
    
    
                Console.WriteLine("
    ==================================================
    ");
    
    
                Console.WriteLine("本地网卡信息:");
                Console.WriteLine(arp.GetLocalIpInfo() + " == " + arp.getLocalMac());
    
                string ip = "192.168.68.42";
                Console.Write("
    
    远程 " + ip + " 主机名信息:");
                var hName = arp.GetRemoteHostName(ip);
                Console.WriteLine(hName);
    
                Console.WriteLine("
    
    远程主机 " + hName + " 网卡信息:");
                string[] temp = arp.getRemoteIP(hName);
                for (int j = 0; j < temp.Length; j++)
                {
                    Console.WriteLine("远程IP信息:" + temp[j]);
                }
    
                Console.WriteLine("
    
    远程主机MAC :");
                Console.WriteLine(arp.getRemoteMac("192.168.68.21", "192.168.68.255"));
                Console.WriteLine(arp.getRemoteMac("192.168.68.21", "192.168.68.44"));
    
                Console.ReadKey();
            }
        }

    出处:https://segmentfault.com/q/1010000008600333/a-1020000011467457

    =====================================================================

    c# 通过发送arp包获取ip等信息

    利用dns类和WMI规范获取IPMAC地址

    C#编程中,要获取主机名和主机IP地址,是比较容易的.它提供的Dns,可以轻松的取得主机名和IP地址.

    示例:
    string strHostName = Dns.GetHostName(); //
    得到本机的主机名
    IPHostEntry ipEntry = Dns.GetHostByName(strHostName); //
    取得本机IP
    string strAddr = ipEntry.AddressList[0].ToString(); //
    假设本地主机为单网卡

    在这段代码中使用了两个类,一个是Dns,另一个为IPHostEntry,二者都存在于命名空间System.Net.
    Dns
    类主要是从域名系统(DNS)中检索关于特定主机的信息,上面的代码第一行就从本地的DNS中检索出本地主机名.
    IPHostEntry
    类则将一个域名系统或主机名与一组IP地址相关联,它与DNS类一起使用,用于获取主机的IP地址组.
    要获取远程主机的IP地址,其方法也是大同小异.

    在获取了IP地址后,如果还需要取得网卡的MAC地址,就需要进一步探究了.
    这里又分两种情况,一是本机MAC地址,二是远程主机MAC地址.二者的获取是完全不同的.
    在获取本机的MAC地址时,可以使用WMI规范,通过SELECT语句提取MAC地址..NET框架中,WMI规范的实现定义在System.Management命名空间中.
    ManagementObjectSearcher
    类用于根据指定的查询检索管理对象的集合
    ManagementObjectCollection
    类为管理对象的集合,下例中由检索对象返回管理对象集合赋值给它.

    示例:
    ManagementObjectSearcher query =new ManagementObjectSearcher("SELECT * FROM Win32_NetworkAdapterConfiguration") ;
    ManagementObjectCollection queryCollection = query.Get();
    foreach( ManagementObject mo in queryCollection )
    {
       if(mo["IPEnabled"].ToString() == "True")
       mac = mo["MacAddress"].ToString();
    }

    获取远程主机的MAC地址时,需要借用API函数SendARP.该函数使用ARP协议,向目的主机发送ARP,利用返回并存储在高速缓存中的IPMAC地址对,从而获取远程主机的MAC地址.

    示例:
    Int32 ldest= inet_addr(remoteIP); //
    目的ip
    Int32 lhost= inet_addr(localIP); //
    本地ip
    try
    {
       Int64 macinfo = new Int64();
       Int32 len = 6;
       int res = SendARP(ldest,0, ref macinfo, ref len); //
    发送ARP
       return Convert.ToString(macinfo,16);
    }
    catch(Exception err)
    {
       Console.WriteLine("Error:{0}",err.Message);
    }
    return 0.ToString();

    但使用该方式获取MAC时有一个很大的限制,就是只能获取同网段的远程主机MAC地址.因为在标准网络协议下,ARP包是不能跨网段传输的,故想通过ARP协议是无法查询跨网段设备MAC地址的。

    示例程序全部代码:

    using System.Net;
    using System;
    using System.Management;
    using System.Runtime.InteropServices;
    using System.Collections.Generic;
    using System.Text;
    using System.Text.RegularExpressions;
    
        public class ArpHelper
        {
    
    
            [DllImport("Iphlpapi.dll")]
            private static extern int SendARP(Int32 dest, Int32 host, ref Int64 mac, ref Int32 length);
            [DllImport("Ws2_32.dll")]
            private static extern Int32 inet_addr(string ip);
    
            //使用arp -a命令获取ip和mac地址
            public List<MacIpPair> GetAllMacAddressesAndIppairs()
            {
                List<MacIpPair> mip = new List<MacIpPair>();
                System.Diagnostics.Process pProcess = new System.Diagnostics.Process();
                pProcess.StartInfo.FileName = "arp";
                pProcess.StartInfo.Arguments = "-a ";
                pProcess.StartInfo.UseShellExecute = false;
                pProcess.StartInfo.RedirectStandardOutput = true;
                pProcess.StartInfo.CreateNoWindow = true;
                pProcess.Start();
                string cmdOutput = pProcess.StandardOutput.ReadToEnd();
                string pattern = @"(?<ip>([0-9]{1,3}.?){4})s*(?<mac>([a-f0-9]{2}-?){6})";
    
                foreach (Match m in Regex.Matches(cmdOutput, pattern, RegexOptions.IgnoreCase))
                {
                    mip.Add(new MacIpPair()
                    {
                        MacAddress = m.Groups["mac"].Value,
                        IpAddress = m.Groups["ip"].Value
                    });
                }
    
                return mip;
            }
    
            //获取本机的IP
            public MacIpPair GetLocalIpInfo()
            {
                string strHostName = Dns.GetHostName(); //得到本机的主机名
                IPHostEntry ipEntry = Dns.GetHostByName(strHostName); //取得本机IP
                string strAddr = ipEntry.AddressList[0].ToString(); //假设本地主机为单网卡
    
                string mac = "";
                ManagementObjectSearcher query = new ManagementObjectSearcher("SELECT * FROM Win32_NetworkAdapterConfiguration");
                ManagementObjectCollection queryCollection = query.Get();
                foreach (ManagementObject mo in queryCollection)
                {
                    if (mo["IPEnabled"].ToString() == "True")
                        mac = mo["MacAddress"].ToString();
                }
    
                return new MacIpPair { HostName = strHostName, IpAddress = strAddr, MacAddress = mac };
            }
    
            //获取本机的MAC
            public string getLocalMac()
            {
                string mac = null;
                ManagementObjectSearcher query = new ManagementObjectSearcher("SELECT * FROM Win32_NetworkAdapterConfiguration");
                ManagementObjectCollection queryCollection = query.Get();
                foreach (ManagementObject mo in queryCollection)
                {
                    if (mo["IPEnabled"].ToString() == "True")
                        mac = mo["MacAddress"].ToString();
                }
                return (mac);
            }
    
            //根据主机名获取远程主机IP
            public string[] getRemoteIP(string RemoteHostName)
            {
                IPHostEntry ipEntry = Dns.GetHostByName(RemoteHostName);
                IPAddress[] IpAddr = ipEntry.AddressList;
                string[] strAddr = new string[IpAddr.Length];
                for (int i = 0; i < IpAddr.Length; i++)
                {
                    strAddr[i] = IpAddr[i].ToString();
                }
                return strAddr;
            }
    
            //根据ip获取远程主机名
            public string GetRemoteHostName(string ip)
            {
                var d = Dns.GetHostEntry(ip);
                return d.HostName;
            }
    
            //获取远程主机MAC
            public string getRemoteMac(string localIP, string remoteIP)
            {
                string res = "FFFFFFFFFFFF";
                Int32 rdest = inet_addr(remoteIP); //目的ip 
                Int32 lhost = inet_addr(localIP); //本地ip 
    
                try
                {
                    //throw new Exception();
                    Int64 macinfo = new Int64();
                    Int32 len = 6;
                    int sendRes = SendARP(rdest, lhost, ref macinfo, ref len);
                    var mac = Convert.ToString(macinfo, 16);
    
    
                    return formatMacAddres(mac);
                }
                catch (Exception err)
                {
                    Console.WriteLine("Error:{0}", err.Message);
                }
                return formatMacAddres(res);
            }
    
            private string formatMacAddres(string macAdd)
            {
                StringBuilder sb = new StringBuilder();
                macAdd = macAdd.Length == 11 ? "0" + macAdd : macAdd;
                if (macAdd.Length == 12)
                {
                    int i = 0;
                    while (i < macAdd.Length)
                    {
                        string tmp = macAdd.Substring(i, 2) + "-";
                        sb.Insert(0, tmp);
                        //sb.Append(tmp, 0, tmp.Length);
                        i += 2;
                    }
                }
                else
                {
                    sb = new StringBuilder("000000000000");
                }
                return sb.ToString().Trim('-').ToUpper();
    
            }
    
        }

    出处:https://www.cnblogs.com/purplenight/articles/2688241.html

    ============================================================

    C#通过SendARP()获取WinCE设备的Mac网卡物理地址

    ARP(Address Resolution Protocol) 即 地址解析协议,是根据IP地址获取物理地址的一个TCP/IP协议

    SendARP(Int32 dest, Int32 host, out Int64 mac, out Int32 length)

    ①dest:访问的目标IP地址,既然获取本机网卡地址,写本机IP即可 这个地址比较特殊,必须从十进制点分地址转换成32位有符号整数  在C#中为Int32;

    ②host:源IP地址,即时发送者的IP地址,这里可以随便填写,填写Int32整数即可;

    ③mac:返回的目标MAC地址(十进制),我们将其转换成16进制后即是想要的结果用out参数加以接收;

    ④length:返回的是pMacAddr目标MAC地址(十进制)的长度,用out参数加以接收。

    如果使用的是C++或者C语言可以直接调用 inet_addr("192.168.0.×××")得到 参数dest 是关键

    现在用C#来获取,首先需要导入"ws2_32.dll"这个库,这个库中存在inet_addr(string cp)这个方法,之后我们就可以调用它了。

    
    
    1
    2
    3
    4
    5
    //首先,要引入命名空间:using System.Runtime.InteropServices;
    1 using System.Runtime.InteropServices;
    //接下来导入C:WindowsSystem32下的"ws2_32.dll"动态链接库,先去文件夹中搜索一下,文件夹中没有Iphlpapi.dll的在下面下载
    2 [DllImport("ws2_32.dll")]
    3 private static extern int inet_addr(string ip);//声明方法
    Iphlpapi.dll的点击 这里 下载
    1
     
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    //第二 调用方法
    Int32 desc = inet_addr("192.168.0.××");
     
    /*由于个别WinCE设备是不支持"ws2_32.dll"动态库的,所以我们需要自己实现inet_addr()方法
     
    输入是点分的IP地址格式(如A.B.C.D)的字符串,从该字符串中提取出每一部分,为int,假设得到4个int型的A,B,C,D,
     
    ,IP = D<<24 + C<<16 + B<<8 + A(网络字节序),即inet_addr(string ip)的返回结果,
    我们也可以把该IP转换为主机字节序的结果,转换方法一样 A<<24 + B<<16 + C<<8 + D
    */

      

     

    接下来是完整代码

    
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    using System;
    using System.Runtime.InteropServices;
    using System.Net;
    using System.Diagnostics;
    using System.Net.Sockets;
     
    public class MacAddressDevice
        {
            [DllImport("Iphlpapi.dll")]
            private static extern int SendARP(Int32 dest, Int32 host, ref Int64 mac, ref Int32 length);
     
            //获取本机的IP
            public static byte[] GetLocalIP()
            {
                //得到本机的主机名
                string strHostName = Dns.GetHostName();
                try
                {
                    //取得本机所有IP(IPV4 IPV6 ...)
                    IPAddress[] ipAddress = Dns.GetHostEntry(strHostName).AddressList;
                    byte[] host = null;
                    foreach (var ip in ipAddress)
                    {
                        while (ip.GetAddressBytes().Length == 4)
                        {
                            host = ip.GetAddressBytes();
                            break;
                        }
                        if (host != null)
                            break;
                    }
                    return host;
                }
                catch (Exception)
                {
                    return null;
                }
     
            }
     
            // 获取本地主机MAC地址
            public static string GetLocalMac(byte[] ip)
            {
           if(ip == null)
           return null;   
     
                int host = (int)((ip[0]) + (ip[1] << 8) + (ip[2] << 16) + (ip[3] << 24));
                try
                {
                    Int64 macInfo = 0;
                    Int32 len = 0;
                    int res = SendARP(host, 0, out macInfo, out len);
                    return Convert.ToString(macInfo, 16);
                }
                catch (Exception err)
                {
                    Console.WriteLine("Error:{0}", err.Message);
                }
                return null;
            }
     
        }
    }
    
    

    最终取得Mac地址

    
    
    1
    2
    3
    4
    //本机Mac地址
    string Mac = GetLocalMac(GetLocalIP());
     
    //得到Mac地址是小写的,或者前后次序颠倒的,自己转换为正常的即可。

    出处:https://www.cnblogs.com/JourneyOfFlower/p/SendARP.html

    ================================================================

  • 相关阅读:
    学习:恢复被孤立的数据库dbo (转)
    学习:SharePoint编程提升权限的方法(转)
    SQL行列互换
    前台用js、jquery出现错误很多是由于IE缓存
    关于dialog首次加载的时候隐藏的一个问题
    要取某个对象的值,先要判断对象是否为空的简便写法(记)
    写js或者jquery的时候最重要的调试,再也不用alert弹出对象
    嵌入式软件测试的十大秘诀
    SIMULINK sfunction的设计
    关于java解压zip与rar的问题
  • 原文地址:https://www.cnblogs.com/mq0036/p/11842313.html
Copyright © 2011-2022 走看看