2010-04-02 11 views
13

Sto sviluppando un'applicazione di sicurezza domestica. Una cosa che mi piacerebbe fare è spegnerla e riaccenderla automaticamente a seconda che io sia a casa o meno. Ho un telefono con Wifi che si connette automaticamente alla mia rete quando sono a casa.Ping o altrimenti dire se un dispositivo è sulla rete da MAC in C#

Il telefono si connette e riceve l'indirizzo tramite DHCP. Mentre potrei configurarlo per usare un IP statico, preferirei di no. Esiste un tipo di "Ping" o equivalente in C#/.Net che può prendere l'indirizzo MAC di un dispositivo e dirmi se è attualmente attivo o meno sulla rete?

Modifica: Per chiarire, sto eseguendo il software su un PC che mi piacerebbe essere in grado di rilevare il telefono sulla stessa LAN.

Modifica: Ecco il codice che ho trovato, grazie all'aiuto di spoulson. Rileva in modo affidabile se qualcuno dei telefoni che mi interessa sia o meno in 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

Questa domanda potrebbe essere utile http://stackoverflow.com/questions/1148778/how-do-i-access-arp-protocol-information-through-net. Ti aiuterà a ottenere il MAC da un IP. Oppure usa "arp -a" e analizza l'output. –

+0

Puoi farlo al contrario? Come avere un'applicazione sul telefono che rileva quando si trova sulla rete domestica e poi comunica a casa l'applicazione che è nel raggio d'azione? Di solito è possibile ottenere il telefono per avvisarti quando si connette. – jvilalta

+0

Era questa la versione finale della sceneggiatura? – cDima

risposta

2

Un approccio diverso è quello di utilizzare gli strumenti ping e arp. Poiché i pacchetti ARP possono rimanere nello stesso dominio di trasmissione, è possibile eseguire il ping all'indirizzo di broadcast della rete e ogni client risponderà con una risposta ARP. Ciascuna di queste risposte è memorizzata nella cache della tabella ARP, che è possibile visualizzare con il comando arp -a. Quindi la riduzione di attività:

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 

Alcuni di questi può essere fatto in codice gestito, come ad esempio nel System.Net.NetworkInformation namespace.

Nota: la cancellazione della cache ARP può influire marginalmente sulle prestazioni della rete eliminando le voci memorizzate nella cache di altri server locali. Tuttavia, in genere la cache viene cancellata ogni 20 minuti o meno.

+0

OK, ora che sono a casa e ho tempo per giocare con questo, l'ho appena provato e l'unico i dispositivi che raccoglie sono il mio PC desktop e il mio file server. Manca la maggior parte degli altri dispositivi sulla rete (adattatore wireless, telefono, stampante, altro computer portatile, un paio di macchine virtuali ...) L'unico dispositivo che prende è due switch di distanza. –

+1

Per testare, prova a pingare uno di quei dispositivi persi per IP, quindi controlla 'arp -a'. Se funziona, forse il dispositivo non risponde ai messaggi di trasmissione. :/Forse questo non è l'approccio migliore, dopo tutto. – spoulson

1

È possibile utilizzare il RARP protocol per trasmettere una richiesta di chi possiede tale indirizzo MAC. Il proprietario risponderà con il suo indirizzo IP. Non conosco uno strumento o una libreria RARP da consigliare, quindi potresti considerare di scrivere il tuo livello di rete per inviare/ricevere questi pacchetti.

+1

per fare questo ci servono socket grezzi - facci sapere quando lo hai fatto perché vorremmo vedere – pm100

Problemi correlati