获得MAC地址的四个方法

 

1.使用WMI查询表Win32_NetworkAdapterConfiguration即可获得。

2.使用ARP协议。请看这里

3.使用Windows命令nbtstat,也就是通过NetBIOS请看这里

4.查询SNMP(就是一种用于监视网络设备的协议)的MIB(管理信息数据库)。但这不是一件简单的事情,需要自己创建SNMP包,发送到交换机,然后对返回的响应进行解析。

下面是代碼:

using System;
using System.Diagnostics;
using System.Management;
using System.Net;
using System.Runtime.InteropServices;
using System.Text.RegularExpressions;

namespace MACAddress
{
    
/// <summary>
    
/// MainClass 的摘要描述。
    
/// </summary>

    internal class MainClass
    
{
        
/// <summary>
        
/// 應用程式的主進入點。
        
/// </summary>

        [STAThread]
        
private static void Main(string[] args)
        
{
            GetMACByWMI();
            IPAddress[] ips 
= GetLocalIP();
            
foreach (IPAddress ip in ips)
            
{
                Console.WriteLine(GetMacByARP(ip.ToString()));
                
string mac = GetRemoteMacByNetBIOS(ip.ToString());
                
if ( mac.Length != 0 )
                    Console.WriteLine(mac);
                
else
                    Console.WriteLine(
"Fail to get MACAddress by NetBIOS");
                GetMACBySNMP(ip.ToString(),
"yourGroupName@yourVlanNumber");
            }

            Console.ReadLine();
        }


        
By WMI

        
#region By ARP

        [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);

        
public static string GetMacByARP(string clientIP)
        
{
            
string ip = clientIP;
            Int32 ldest 
= inet_addr(ip);
            Int64 macinfo 
= new Int64();
            Int32 len 
= 6;
            
try
            
{
                SendARP(ldest, 
0ref macinfo, ref len);
            }

            
catch
            
{
                
return "";
            }

            
string originalMACAddress = Convert.ToString(macinfo, 16);
            
if (originalMACAddress.Length < 12)
            
{
                originalMACAddress 
= originalMACAddress.PadLeft(12'0');
            }

            
string macAddress;
            
if (originalMACAddress != "0000" && originalMACAddress.Length == 12)
            
{
                
string mac1, mac2, mac3, mac4, mac5, mac6;
                mac1 
= originalMACAddress.Substring(102);
                mac2 
= originalMACAddress.Substring(82);
                mac3 
= originalMACAddress.Substring(62);
                mac4 
= originalMACAddress.Substring(42);
                mac5 
= originalMACAddress.Substring(22);
                mac6 
= originalMACAddress.Substring(02);
                macAddress 
= mac1 + "-" + mac2 + "-" + mac3 + "-" + mac4 + "-" + mac5 + "-" + mac6;
            }

            
else
            
{
                macAddress 
= "";
            }

            
return macAddress.ToUpper();
        }


        
public static IPAddress[] GetLocalIP()
        
{
            
string hostName = Dns.GetHostName();
            IPHostEntry ipEntry 
= Dns.GetHostByName(hostName);
            
return ipEntry.AddressList;
        }


        
#endregion


        
#region By NetBIOS
        
public static string GetRemoteMacByNetBIOS(string clientIP)
        
{
            
string ip = clientIP;
            
string dirResults = "";
            ProcessStartInfo psi 
= new ProcessStartInfo();
            Process proc 
= new Process();
            psi.FileName 
= "nbtstat.exe";
            
//psi.RedirectStandardInput = false; 
            psi.RedirectStandardOutput = true;
            psi.RedirectStandardError 
= true;
            psi.Arguments 
= "-A " + ip;
            psi.UseShellExecute 
= false;
            proc 
= Process.Start(psi);
            dirResults 
= proc.StandardOutput.ReadToEnd();
            
string error = proc.StandardError.ReadToEnd();
            proc.WaitForExit();
            dirResults 
= dirResults.Replace("\r""").Replace("\n""").Replace("\t""");
            Regex reg 
= new Regex("Mac[ ]{0,}Address[ ]{0,}=[ ]{0,}(?((.)*?))__MAC", RegexOptions.IgnoreCase | RegexOptions.Compiled);
            Match mc 
= reg.Match(dirResults + "__MAC");
            
if (mc.Success)
            
{
                
return mc.Groups["key"].Value.ToUpper();
            }

            
else
            
{
                
return "";
            }

        }

        
#endregion


        
#region By SNMP
        
public static void GetMACBySNMP(string ip,string vlan)
        
{
            
int commLength,mibLength,dataStart,dataLength;
            
string nextMib,value;
            SNMP conn 
= new SNMP();
            
string mib = "1.3.6.1.2.1.17.4.3.1.1";
            
int orgMibLength = mib.Length;
            
byte[] response = new byte[1024];

            nextMib 
= mib;

            
while ( true)
            
{
                response 
= conn.Get("getnext",ip,vlan,nextMib);
                commLength 
= Convert.ToInt16(response[6]);
                mibLength 
= Convert.ToInt16(response[23+commLength]);
                dataLength 
= Convert.ToInt16(response[25+commLength+mibLength]);
                dataStart 
= 26 + commLength + mibLength;
                value 
= BitConverter.ToString(response,dataStart,dataLength);
                nextMib 
= conn.GetNextMIB(response);

                
if ( !(nextMib.Substring(0,orgMibLength) == mib))
                
{
                    
break;
                }

                Console.WriteLine(
"{0}={1}",nextMib,value);

            }

        }

        
#endregion

    }

}


SNMP Class


using System;
using System.Net;
using System.Net.Sockets;
using System.Text;

namespace MACAddress
{
    
/**//// <summary>
    
/// SNMP 的摘要描述。
    
/// </summary>

    public class SNMP
    
{
        
public SNMP()
        
{
        }


        
public byte[] Get(string request, string host, string community, string mibString)
        
{
            
byte[] packet = new byte[1024];
            
byte[] mib = new byte[1024];
            
int snmpLen;
            
int comLen = community.Length;
            
string[] mibVals = mibString.Split('.');
            
int mibLen = mibVals.Length;
            
int cnt = 0;
            
int temp;
            
int orgmibLen = mibLen;
            
int pos = 0;
            
for (int i = 0; i < orgmibLen; i++)
            
{
                temp 
= Convert.ToInt16(mibVals[i]);
                
if (temp > 127)
                
{
                    mib[cnt] 
= Convert.ToByte(128 + (temp / 128));
                    mib[cnt 
+ 1= Convert.ToByte(temp - ((temp / 128* 128));
                    cnt 
+= 2;
                    mibLen
++;
                }

                
else
                
{
                    mib[cnt] 
= Convert.ToByte(temp);
                    cnt
++;
                }

            }


            snmpLen 
= 29 + comLen + mibLen - 1;
            packet[pos
++= 0x30;
            packet[pos
++= Convert.ToByte(snmpLen - 2);

            packet[pos
++= 0x02;
            packet[pos
++= 0x01;
            packet[pos
++= 0x00;

            packet[pos
++= 0x04;
            packet[pos
++= Convert.ToByte(comLen);
            
byte[] data = Encoding.ASCII.GetBytes(community);
            
for (int i = 0; i < data.Length; i++)
            
{
                packet[pos
++= data[i];
            }


            
if (request == "get")
            
{
                packet[pos
++= 0xA0;
            }

            
else
            
{
                packet[pos
++= 0xA1;
            }

            packet[pos
++= Convert.ToByte(20 + mibLen - 1);

            packet[pos
++= 0x02;
            packet[pos
++= 0x04;
            packet[pos
++= 0x00;
            packet[pos
++= 0x00;
            packet[pos
++= 0x00;
            packet[pos
++= 0x01;

            packet[pos
++= 0x02;
            packet[pos
++= 0x01;
            packet[pos
++= 0x00;

            packet[pos
++= 0x02;
            packet[pos
++= 0x01;
            packet[pos
++= 0x00;

            packet[pos
++= 0x30;

            packet[pos
++= Convert.ToByte(6 + mibLen - 1);
            packet[pos
++= 0x30;
            packet[pos
++= Convert.ToByte(6 + mibLen - 1 - 2);
            packet[pos
++= 0x06;
            packet[pos
++= Convert.ToByte(mibLen - 1);

            packet[pos
++= 0x2b;
            
for (int i = 2; i < mibLen; i++)
            
{
                packet[pos
++= Convert.ToByte(mib[i]);
            }

            packet[pos
++= 0x05;
            packet[pos
++= 0x00;

            Socket sock 
= new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
            sock.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReceiveTimeout, 
5000);
            IPHostEntry ihe 
= Dns.Resolve(host);
            IPEndPoint iep 
= new IPEndPoint(ihe.AddressList[0], 161);
            EndPoint ep 
= (EndPoint) iep;
            sock.SendTo(packet, snmpLen, SocketFlags.None, iep);

            
try
            
{
                
int recv = sock.ReceiveFrom(packet, ref ep);
            }

            
catch (SocketException)
            
{
                packet[
0= 0xff;
            }

            
return packet;
        }


        
public string GetNextMIB(byte[] mibIn)
        
{
            
string output = "1.3";
            
int commLength = mibIn[6];
            
int mibStart = 6 + commLength + 17;
            
int mibLength = mibIn[mibStart] - 1;
            mibStart 
+= 2;
            
int mibValue;

            
for (int i = mibStart; i < mibStart + mibLength; i++)
            
{
                mibValue 
= Convert.ToInt16(mibIn[i]);
                
if (mibValue > 128)
                
{
                    mibValue 
= (mibValue / 128* 128 + Convert.ToInt16(mibIn[i + 1]);
                    i
++;
                }

                output 
+= "." + mibValue;
            }

            
return output;
        }

    }

}


 如果还有其它方法,请告诉我。

posted @ 2005-07-13 13:17 风满袖 阅读(9248) 评论(16)  编辑 收藏 网摘 所属分类: C#

  回复  引用  查看    
#1楼 2005-07-13 14:53 | gooshoose      
public class MACAddress
{
public MACAddress()
{
//
// TODO: 在此处添加构造函数逻辑
//
}

[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);

public static string GetRemoteMAC(string remoteIP)
{
string ReturnValue="";

ProcessStartInfo psi = new ProcessStartInfo();
psi.FileName = "nbtstat.exe";
psi.RedirectStandardInput = false;
psi.RedirectStandardOutput = true;
psi.Arguments = "-A " + remoteIP;
psi.UseShellExecute = false;
Process ps = Process.Start(psi);
string strEnd = ps.StandardOutput.ReadToEnd();
ps.WaitForExit();
string[] strs = strEnd.Split('\n');
foreach(string s in strs)
{
if(s.Trim().ToLower().IndexOf("mac address") != -1)
{
ReturnValue= s.Substring(s.IndexOf("Address =") + 10,17);
break;
}
}

return ReturnValue;
}
}

  回复  引用  查看    
#2楼 [楼主]2005-07-13 15:03 | James      
@gooshoose
也是使用ARP协议的方法.

thx

  回复  引用    
#3楼 2005-07-13 15:36 | Kvd [未注册用户]
请问下双网卡情况下应该怎么搞定
希望能交流一下
iamdongyi@gmail.com

  回复  引用  查看    
#4楼 [楼主]2005-07-13 15:41 | James      
@Kvd :
一樣的.
比如你使用WMI來獲取,你可以得到多個網卡的IP,MAC地址.

  回复  引用  查看    
#5楼 2005-07-13 22:00 | 小陆      
有一个简单的方法:
先判断操作系统, 如果是windows2000和xp, 调用shell命令: ipconfig /all, 如果是linux, 调用/sbin/ifconfig -all, 如果是别的什么操作系统调用对应的命令, 肯定会有这个命令. 捕捉命令的输出, 分析内容, 得到mac地址.
n个网卡都能搞定.

  回复  引用  查看    
#6楼 [楼主]2005-07-14 09:01 | James      
@小陆 :
你說的是一個辦法,其實我也用了,但只限於windows.

  回复  引用  查看    
#7楼 2005-08-01 16:13 | haizheng      
我也用过这个SNMP类,但是我有一个问题,在实现一个SNMP request中绑定多个变量时,如何解析这多个变量的值,不知你作过着方面的应用没有!
  回复  引用  查看    
#8楼 [楼主]2005-08-02 08:59 | James      
◎:haizheng
这个我还没有做过。我想大概需要自己按照其规范创建SNMP包,发送到交换机,或者发送多个包,每次取回不同的内容。

  回复  引用  查看    
#9楼 2005-08-02 13:45 | haizheng      
想了解SNMP包如何解包!
  回复  引用  查看    
#10楼 [楼主]2005-08-02 14:29 | James      
@haizheng :
前不久看了SNMP相关的内容,但比较粗略。
让我了解下子,我在下面的开发中会用到SNMP。

不过使用SNMP编程不是一件容易的事情。

  回复  引用    
#11楼 2005-09-26 09:28 | tangchaoqing@gmail.com [未注册用户]
我想通过asp.net访问客户端的网卡MAC怎么办?
  回复  引用  查看    
#12楼 [楼主]2005-09-26 10:19 | 风满袖      
使用WMI远程查询。
WMI既可以查询本机,也可以查询远程主机。

  回复  引用    
#13楼 2005-11-25 16:48 | 老章 [未注册用户]
对于多网卡的情况, 注意在SendArp()中的第二个参数, 应填写正确对应的IP地址即可.
  回复  引用    
#14楼 2005-11-25 16:50 | 老章 [未注册用户]
SendArp是相对来说, 最简单的方式. 但是需要注意的是, 该方法并不更新arp列表. 所以使用该方法, 用户应该自己维护一个简单的ARP列表.
  回复  引用    
#15楼 2005-11-25 16:52 | 老章 [未注册用户]
SNMP在MICROSOFT中有一整套的SDK API, 都以Snmp打头, 有兴趣可以看一下.
在其它操作系统下, 我不知道.

  回复  引用    
#16楼 2005-11-25 16:53 | 老章 [未注册用户]
有兴趣可以讨论
chinazwb@tom.com

  回复  引用  查看    
#17楼 [楼主]2005-11-28 09:05 | 风满袖      
非常感谢老章!

发表评论



姓名 [登录] [注册] 
主页
Email (仅博主可见) 
验证码 *  验证码看不清,换一张
内容(请不要发表任何与政治相关的内容)  
  登录  使用高级评论   新用户注册   返回页首      

导航: 网站首页 社区 新闻 博问 闪存 网摘 招聘 .NET频道 知识库 找找看 Google站内搜索



China-pub 计算机图书网上专卖店!6.5万品种 2-8折!
China-Pub 计算机绝版图书按需印刷服务

相关文章:

相关链接: