通过IPv6获取远程MAC地址

5

在同一IPv6网络中,是否可以通过另一台PC获取MAC地址(无需使用WMI)? 使用IPv4很容易(ARP)。

IPv6使用“邻居发现协议”(NDP)来获取MAC地址。 .Net中是否有任何方法可以实现这一点?


OSX标签在这里有什么意义?问题和已接受的答案看起来与OSX完全无关... - ivan
4个回答

3
你可以运行外部命令"netsh int ipv6 show neigh",并过滤出你感兴趣的主机。在此之前,你应该已经与它联系过,所以你知道它在NC中。
如果你想要一个API,使用GetIpNetTable2或更直接地使用ResolveIpNetEntry2。我怀疑这方面没有.NET API,所以你需要使用PInvoke。

谢谢。我认为这应该解决我的问题。我尝试了一下,但是在5分钟内让它工作并不简单;)。如果我有结果,我会再次联系您。 - Fabian

2

Martin的答案是针对Windows的,但如果您正在使用GNU/Linux或其他*nix系统,则需要以下操作。

您可以使用ip命令的neigh函数来显示IPv6邻居,如下所示:

$ ip -6 neigh
fe80::200:ff:fe00:0 dev eth0 lladdr 00:0e:54:24:23:21 router REACHABLE
fe80::202:b0ff:fe01:2abe dev eth0 lladdr 00:02:b0:02:2a:be DELAY

(专业技巧:您可以省略“-6”,在同一列表中查看IPv4 ARP和IPv6 ND。)
此外,如果您想查找局域网上所有IPv6机器的MAC地址,而不仅仅是您已知道的那些,您应该先对它们进行ping,然后查找邻居。
$ ping6 ff02::1%eth0
64 bytes from fe80::221:84ff:fe42:86ef: icmp_seq=1 ttl=64 time=0.053 ms # <-- you
64 bytes from fe80::200:ff:fe00:0: icmp_seq=1 ttl=64 time=2.37 ms (DUP!)
64 bytes from fe80::202:b0ff:fe01:2abe: icmp_seq=1 ttl=64 time=2.38 ms (DUP!)
64 bytes from fe80::215:abff:fe63:f6fa: icmp_seq=1 ttl=64 time=2.66 ms (DUP!)

$ ip -6 neigh
fe80::200:ff:fe00:0 dev eth0 lladdr 00:0e:54:24:23:21 router REACHABLE
fe80::202:b0ff:fe01:2abe dev eth0 lladdr 00:02:b0:02:2a:be DELAY
fe80::215:abff:fe63:f6fa dev eth0 lladdr 00:02:15:ab:f6:fa DELAY # <-- a new one!

非常感谢您的回复。尽管她不完全符合,因为我是在C#和.Net上工作。但她还是帮了我很多。 - Fabian

0
如果行解析代码得到改进,@Alex的答案会更好。以下是一种方法:
public static string netsh(String IPv6)
{
    IPAddress wanted;
    if (!IPAddress.TryParse(IPv6, out wanted))
        throw new ArgumentException("Can't parse as an IPAddress", "IPv6");

    Regex re = new Regex("^([0-9A-F]\S+)\s+(\S+)\s+(\S+)", RegexOptions.IgnoreCase);

    // ... the code that runs netsh and gathers the output.

        Match m = re.Match(output);
        if (m.Success)
        {
            // [0] is the entire line
            // [1] is the IP Address string
            // [2] is the MAC Address string
            // [3] is the status (Permanent, Stale, ...)
            //
            IPAddress found;
            if (IPAddress.TryParse(m.Groups[1].Value, out found))
            {
                 if(wanted.Equals(found))
                 {
                      return m.Groups[2].Value;
                 }
            }
        }

    // ... the code that finishes the loop on netsh output and returns failure
}

-1
这是我的代码:
public static string netsh(String IPv6)
         {
           Process p = new Process();
           p.StartInfo.FileName = "netsh.exe";
           String command = "int ipv6 show neigh"; 
           Console.WriteLine(command);
           p.StartInfo.Arguments = command;
           p.StartInfo.UseShellExecute = false;
           p.StartInfo.RedirectStandardOutput = true;
           p.Start();

          String output = "go";
          while (output!=null){
            try
             {
               output = p.StandardOutput.ReadLine();
             }
             catch (Exception)
             {
               output = null;
             }
             if (output.Contains(IPv6))
             {
               // Nimmt die Zeile in der sich die IPv6 Addresse und die MAC Addresse des Clients befindet
               // Löscht den IPv6 Eintrag, entfernt alle Leerzeichen und kürzt den String auf 17 Zeichen, So erschein die MacAddresse im Format "33-33-ff-0d-57-00"

               output = output.Replace(IPv6, "").Replace(" ", "").TrimToMaxLength(17) ;
               return output;
             }
           }
           return null;

        }

我怀疑这个投票是因为这段代码解析非常脆弱。如果IPv6参数与netsh输出的大小写不同,它将失败。如果IPv6参数完全合法和正确,但在前导零或折叠零字段方面做出不同选择,则它将失败。如果IPv6参数是出现在一行上的内容的子集,它将给出一个错误的匹配结果。 - Jesse Chisholm

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接