Получить удаленный MAC-адрес через IPv6 - PullRequest
5 голосов
/ 03 ноября 2010

Можно ли получить MAC от другого ПК в той же сети через IPv6 (без WMI)?С IPv4 это просто (ARP).

IPv6 использует «Протокол обнаружения соседей» (NDP) для получения MAC-адреса.Есть ли в .Net методы для этого?

Ответы [ 4 ]

3 голосов
/ 03 ноября 2010

Вы можете запустить внешнюю команду "netsh int ipv6 show lie" и отфильтровать интересующий вас хост. Вы должны были связаться с ним как раз перед этим, чтобы вы знали, что он находится в NC.

Если вам нужен API для этого, используйте GetIpNetTable2 или, точнее, ResolveIpNetEntry2 . Я сомневаюсь, что для этого есть .NET API, поэтому вам придется использовать PInvoke.

2 голосов
/ 03 ноября 2010

Ответ Мартина был для Windows, но это если вы используете GNU / Linux или другой * nix-сервер.

Вы хотите использовать функцию neigh команды ip для отображения соседей 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 в одном списке.)

Кроме того, если вы хотите узнать MAC-адреса всех машин IPv6 в локальной сети, а не просто тех, о которых вы уже знаете, сначала вы должны проверить их, тогда ищи соседей:

$ 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!
0 голосов
/ 06 ноября 2012

Ответ @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
}
0 голосов
/ 21 августа 2012

Вот мой код:

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;

        }
...