使用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}\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
================================================================
关注我】。(●'◡'●)
如果,您希望更容易地发现我的新博客,不妨点击一下绿色通道的【因为,我的写作热情也离不开您的肯定与支持,感谢您的阅读,我是【Jack_孟】!
本文来自博客园,作者:jack_Meng,转载请注明原文链接:https://www.cnblogs.com/mq0036/p/11842313.html
【免责声明】本文来自源于网络,如涉及版权或侵权问题,请及时联系我们,我们将第一时间删除或更改!
posted on 2019-11-12 15:19 jack_Meng 阅读(8108) 评论(0) 编辑 收藏 举报