使用ARP獲取局域網內設備IP和MAC地址

 

根據Arp列表數據,查詢本地設備在線狀態html

使用 arp -a 得到全部內網地址,首先看Mod對象編程

    public struct MacIpPair
    {
        public string HostName;
        public string MacAddress;
        public string IpAddress;

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

    }

其次看看查詢方法:c#

        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;
        }

在寫個調用就能夠了:segmentfault

    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("\r\n==================================================\r\n");


            Console.WriteLine("本地網卡信息:");
            Console.WriteLine(arp.GetLocalIpInfo() + " == " + arp.getLocalMac());

            string ip = "192.168.68.42";
            Console.Write("\n\r遠程 " + ip + " 主機名信息:");
            var hName = arp.GetRemoteHostName(ip);
            Console.WriteLine(hName);

            Console.WriteLine("\n\r遠程主機 " + hName + " 網卡信息:");
            string[] temp = arp.getRemoteIP(hName);
            for (int j = 0; j < temp.Length; j++)
            {
                Console.WriteLine("遠程IP信息:" + temp[j]);
            }

            Console.WriteLine("\n\r遠程主機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-1020000011467457api

=====================================================================緩存

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框架

============================================================ide

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:\Windows\System32下的"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

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

相關文章
相關標籤/搜索