Ping o comunque dire se un dispositivo è in rete da MAC in C #
-
24-09-2019 - |
Domanda
sto sviluppando un'applicazione di sicurezza a casa. Una cosa che mi piacerebbe fare è automaticamente spegnerlo e sulla base di se o non sono a casa. Ho un telefono cellulare con Wifi che si collega automaticamente alla rete quando sono a casa.
Il telefono si connette e riceve il suo indirizzo tramite DHCP. Mentre potrei configurarlo per usare un IP statico, io non preferisco. C'è qualche tipo di 'ping' o equivalente in C # / .Net che può prendere l'indirizzo MAC di un dispositivo e ditemi se sia o non è attualmente attivo sulla rete?
Modifica:. del software Per chiarire, io sono in esecuzione su un PC che mi piacerebbe avere essere in grado di rilevare il telefono sulla stessa LAN
Modifica Ecco il codice che ho fornito, grazie all'aiuto di spoulson. Rileva in modo affidabile o meno qualsiasi dei telefoni che mi interessano sono 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;
}
Soluzione
Un approccio diverso è quello di utilizzare gli strumenti e ping
arp
. Dal momento che i pacchetti ARP possono rimanere solo nello stesso dominio di broadcast, è possibile eseguire il ping indirizzo di broadcast della rete e ogni cliente risponderà con una risposta ARP. Ognuna di queste risposte vengono tenuti nella vostra 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: svuotare la cache ARP può avere un effetto marginale sulle prestazioni della rete cancellando le voci memorizzate nella cache di altri server locali. Tuttavia, la cache viene cancellata di solito ogni 20 minuti o meno in ogni caso.
Altri suggerimenti
Si potrebbe utilizzare il RARP protocollo per trasmettere una richiesta di chi possiede tale indirizzo MAC. Il proprietario risponderà con il suo indirizzo IP. Non so di uno strumento di RARP o una libreria di raccomandare, quindi si può non crei il proprio livello di rete per inviare / ricevere questi pacchetti.