根据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; }
出处: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
================================================================
利用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
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地址是小写的,或者前后次序颠倒的,自己转换为正常的即可。
|