2010-04-02 32 views
13

Estoy desarrollando una aplicación de seguridad para el hogar. Una cosa que me gustaría hacer es apagarla y encenderla automáticamente según esté o no en casa. Tengo un teléfono con Wifi que se conecta automáticamente a mi red cuando estoy en casa.Haga ping o indique si un dispositivo se encuentra en la red mediante MAC en C#

El teléfono se conecta y obtiene su dirección a través de DHCP. Si bien podría configurarlo para usar una IP estática, preferiría no hacerlo. ¿Existe algún tipo de 'Ping' o equivalente en C#/.Net que pueda tomar la dirección MAC de un dispositivo y decirme si está actualmente activo en la red o no?

Edit: Para aclarar, estoy ejecutando software en una PC que me gustaría poder detectar el teléfono en la misma LAN.

Edit: Aquí está el código que se me ocurrió, gracias a la ayuda de spoulson. Detecta de manera confiable si alguno de los teléfonos que me interesan está o no en la casa.

private bool PhonesInHouse() 
{ 

    Ping p = new Ping(); 
    // My home network is 10.0.23.x, and the DHCP 
    // pool runs from 10.0.23.2 through 10.0.23.127. 

    int baseaddr = 10; 
    baseaddr <<= 8; 
    baseaddr += 0; 
    baseaddr <<= 8; 
    baseaddr += 23; 
    baseaddr <<= 8; 

    // baseaddr is now the equivalent of 10.0.23.0 as an int. 

    for(int i = 2; i<128; i++) { 
     // ping every address in the DHCP pool, in a separate thread so 
     // that we can do them all at once 
     IPAddress ip = new IPAddress(IPAddress.HostToNetworkOrder(baseaddr + i)); 
     Thread t = new Thread(() => 
      { try { Ping p = new Ping(); p.Send(ip, 1000); } catch { } }); 
     t.Start(); 
    } 

    // Give all of the ping threads time to exit 

    Thread.Sleep(1000); 

    // We're going to parse the output of arp.exe to find out 
    // if any of the MACs we're interested in are online 

    ProcessStartInfo psi = new ProcessStartInfo(); 
    psi.Arguments = "-a"; 
    psi.FileName = "arp.exe"; 
    psi.RedirectStandardOutput = true; 
    psi.UseShellExecute = false; 
    psi.CreateNoWindow = true; 

    bool foundone = false; 
    using (Process pro = Process.Start(psi)) 
    { 
     using (StreamReader sr = pro.StandardOutput) 
     { 
      string s = sr.ReadLine(); 

      while (s != null) 
      { 
       if (s.Contains("Interface") || 
        s.Trim() == "" || 
        s.Contains("Address")) 
       { 
        s = sr.ReadLine(); 
        continue; 
       } 
       string[] parts = s.Split(new char[] { ' ' }, 
        StringSplitOptions.RemoveEmptyEntries); 

       // config.Phones is an array of strings, each with a MAC 
       // address in it. 
       // It's up to you to format them in the same format as 
       // arp.exe 
       foreach (string mac in config.Phones) 
       { 
        if (mac.ToLower().Trim() == parts[1].Trim().ToLower()) 
        { 
         try 
         { 
          Ping ping = new Ping(); 
          PingReply pingrep = ping.Send(parts[0].Trim()); 
          if (pingrep.Status == IPStatus.Success) 
          { 
           foundone = true; 
          } 
         } 
         catch { } 
         break; 
        } 
       } 
       s = sr.ReadLine(); 
      } 
     } 
    } 

    return foundone; 
} 
+1

Esta pregunta puede ayudarlo http://stackoverflow.com/questions/1148778/how-do-i-access-arp-protocol-information-through-net. Le ayudará a obtener el MAC desde una IP. O use "arp -a" y analice la salida. –

+0

¿Puedes hacerlo al revés? ¿Como tener una aplicación en su teléfono que detecta cuándo está en la red doméstica y luego le dice a su aplicación en casa que está dentro del alcance? Por lo general, puede hacer que el teléfono le notifique cuando se conecta. – jvilalta

+0

¿Era esta la versión final del script? – cDima

Respuesta

2

Un enfoque diferente es utilizar las herramientas ping y arp. Como los paquetes ARP solo pueden permanecer en el mismo dominio de difusión, puede hacer ping a la dirección de difusión de su red y cada cliente responderá con una respuesta ARP. Cada una de esas respuestas se almacenan en caché en su tabla ARP, que puede ver con el comando arp -a. Así que el resumen:

rem Clear ARP cache 
netsh interface ip delete arpcache 

rem Ping broadcast addr for network 192.168.1.0 
ping -n 1 192.168.1.255 

rem View ARP cache to see if the MAC addr is listed 
arp -a 

Algunos de éstos se puede hacer en código administrado, tales como en el espacio de nombres System.Net.NetworkInformation.

Nota: La eliminación de la memoria caché ARP puede tener un efecto marginal en el rendimiento de la red al borrar las entradas en caché de otros servidores locales. Sin embargo, la memoria caché generalmente se borra cada 20 minutos o menos de todos modos.

+0

OK, ahora que estoy en casa y tengo tiempo para jugar con esto, lo intenté, y el único los dispositivos que recoge son mi PC de escritorio y mi servidor de archivos. Echa de menos la mayoría de los otros dispositivos en la red (adaptador inalámbrico, teléfono, impresora, otra computadora portátil, un par de máquinas virtuales ...) El único dispositivo que detecta se encuentra a dos conmutadores de distancia. –

+1

Para probar, intente hacer ping a uno de esos dispositivos perdidos por IP, luego marque 'arp -a'. Si eso funciona, entonces tal vez el dispositivo no responda a los pings de transmisión. :/Tal vez este no es el mejor enfoque después de todo. – spoulson

1

Se podría utilizar el RARP protocol para transmitir una petición de quién posee esa dirección MAC. El propietario responderá con su dirección IP. No conozco ninguna herramienta o biblioteca RARP que recomendar, por lo que puede considerar escribir su propia capa de red para enviar/recibir estos paquetes.

+1

necesitará enchufes sin procesar para hacer esto - díganos cuándo lo ha hecho porque nos gustaría ver – pm100

Cuestiones relacionadas