根據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}\t{IpAddress}\t{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("\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-1020000011467457
=====================================================================
c# 通過發送arp包獲取ip等信息
利用dns類和WMI規范獲取IP及MAC地址
在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包,利用返回並存儲在高速緩存中的IP和MAC地址對,從而獲取遠程主機的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:\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
================================================================