2009-07-18 28 views
24

Sto cercando di capire quali dispositivi sono online e offline nella nostra LAN. Ho visto molti programmi fare una sorta di panoramica della rete grafica, presentando indirizzi IP e MAC LAN. Mi piacerebbe sapere se e come queste informazioni (ARP?) Possono essere estratte da C# /. NET?Come accedere alle informazioni del protocollo ARP tramite .NET?

Tutti gli snippet/collegamenti di codice di esempio sarebbero apprezzati.

+0

I dati potrebbero non essere disponibili tramite SNMP. – ChrisW

+0

Come stai definendo la LAN? Segmento Ethernet? Tutto in un blocco IP? –

+0

Definisco LAN come Ethernet locale, vista da "my network card" - Voglio avere un servizio/dll (qualcosa) che posso chiamare ad es. un server web o qualcosa che indicherà quali IP sono attivi nel segmento IP corrente (senza eseguire il ping di tutte le combinazioni) e quindi ottenere il MAC per ciascun IP attivo per cercare WHAT è connesso (che ci consentirebbe di fare log/visualizzare facilmente la rete corrente .) – BerggreenDK

risposta

30

Se si sa quali dispositivi sono disponibili, è possibile utilizzare Ping Class. Questo ti permetterà almeno di riempire la tabella ARP. È sempre possibile eseguire ARP -a e analizzare l'output se necessario. Ecco anche un link che mostra come pinvoke chiamare GetIpNetTable. Ho incluso degli esempi sotto di Ping Class e come accedere alla tabella ARP usando GetIpNetTable.

questo è un esempio per il Ping Classe

using System; 
using System.Net; 
using System.Net.NetworkInformation; 
using System.Text; 

namespace Examples.System.Net.NetworkInformation.PingTest 
{ 
    public class PingExample 
    { 
     // args[0] can be an IPaddress or host name. 
     public static void Main (string[] args) 
     { 
      Ping pingSender = new Ping(); 
      PingOptions options = new PingOptions(); 

      // Use the default Ttl value which is 128, 
      // but change the fragmentation behavior. 
      options.DontFragment = true; 

      // Create a buffer of 32 bytes of data to be transmitted. 
      string data = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"; 
      byte[] buffer = Encoding.ASCII.GetBytes (data); 
      int timeout = 120; 
      PingReply reply = pingSender.Send (args[0], timeout, buffer, options); 
      if (reply.Status == IPStatus.Success) 
      { 
       Console.WriteLine ("Address: {0}", reply.Address.ToString()); 
       Console.WriteLine ("RoundTrip time: {0}", reply.RoundtripTime); 
       Console.WriteLine ("Time to live: {0}", reply.Options.Ttl); 
       Console.WriteLine ("Don't fragment: {0}", reply.Options.DontFragment); 
       Console.WriteLine ("Buffer size: {0}", reply.Buffer.Length); 
      } 
     } 
    } 
} 

Questo è un esempio della GetIpNetTable.

using System; 
using System.Runtime.InteropServices; 
using System.ComponentModel; 
using System.Net; 

namespace GetIpNetTable 
{ 
    class Program 
    { 
     // The max number of physical addresses. 
     const int MAXLEN_PHYSADDR = 8; 

     // Define the MIB_IPNETROW structure. 
     [StructLayout(LayoutKind.Sequential)] 
     struct MIB_IPNETROW 
     { 
     [MarshalAs(UnmanagedType.U4)] 
     public int dwIndex; 
     [MarshalAs(UnmanagedType.U4)] 
     public int dwPhysAddrLen; 
     [MarshalAs(UnmanagedType.U1)] 
     public byte mac0; 
     [MarshalAs(UnmanagedType.U1)] 
     public byte mac1; 
     [MarshalAs(UnmanagedType.U1)] 
     public byte mac2; 
     [MarshalAs(UnmanagedType.U1)] 
     public byte mac3; 
     [MarshalAs(UnmanagedType.U1)] 
     public byte mac4; 
     [MarshalAs(UnmanagedType.U1)] 
     public byte mac5; 
     [MarshalAs(UnmanagedType.U1)] 
     public byte mac6; 
     [MarshalAs(UnmanagedType.U1)] 
     public byte mac7; 
     [MarshalAs(UnmanagedType.U4)] 
     public int dwAddr; 
     [MarshalAs(UnmanagedType.U4)] 
     public int dwType; 
     } 

     // Declare the GetIpNetTable function. 
     [DllImport("IpHlpApi.dll")] 
     [return: MarshalAs(UnmanagedType.U4)] 
     static extern int GetIpNetTable(
     IntPtr pIpNetTable, 
     [MarshalAs(UnmanagedType.U4)] 
     ref int pdwSize, 
     bool bOrder); 

     [DllImport("IpHlpApi.dll", SetLastError = true, CharSet = CharSet.Auto)] 
     internal static extern int FreeMibTable(IntPtr plpNetTable); 

     // The insufficient buffer error. 
     const int ERROR_INSUFFICIENT_BUFFER = 122; 

     static void Main(string[] args) 
     { 
     // The number of bytes needed. 
     int bytesNeeded = 0; 

     // The result from the API call. 
     int result = GetIpNetTable(IntPtr.Zero, ref bytesNeeded, false); 

     // Call the function, expecting an insufficient buffer. 
     if (result != ERROR_INSUFFICIENT_BUFFER) 
     { 
      // Throw an exception. 
      throw new Win32Exception(result); 
     } 

     // Allocate the memory, do it in a try/finally block, to ensure 
     // that it is released. 
     IntPtr buffer = IntPtr.Zero; 

     // Try/finally. 
     try 
     { 
      // Allocate the memory. 
      buffer = Marshal.AllocCoTaskMem(bytesNeeded); 

      // Make the call again. If it did not succeed, then 
      // raise an error. 
      result = GetIpNetTable(buffer, ref bytesNeeded, false); 

      // If the result is not 0 (no error), then throw an exception. 
      if (result != 0) 
      { 
       // Throw an exception. 
       throw new Win32Exception(result); 
      } 

      // Now we have the buffer, we have to marshal it. We can read 
      // the first 4 bytes to get the length of the buffer. 
      int entries = Marshal.ReadInt32(buffer); 

      // Increment the memory pointer by the size of the int. 
      IntPtr currentBuffer = new IntPtr(buffer.ToInt64() + 
       Marshal.SizeOf(typeof(int))); 

      // Allocate an array of entries. 
      MIB_IPNETROW[] table = new MIB_IPNETROW[entries]; 

      // Cycle through the entries. 
      for (int index = 0; index < entries; index++) 
      { 
       // Call PtrToStructure, getting the structure information. 
       table[index] = (MIB_IPNETROW) Marshal.PtrToStructure(new 
        IntPtr(currentBuffer.ToInt64() + (index * 
        Marshal.SizeOf(typeof(MIB_IPNETROW)))), typeof(MIB_IPNETROW)); 
      } 

      for (int index = 0; index < entries; index++) 
      { 
       MIB_IPNETROW row = table[index]; 
       IPAddress ip=new IPAddress(BitConverter.GetBytes(row.dwAddr)); 
       Console.Write("IP:"+ip.ToString()+"\t\tMAC:"); 

       Console.Write(row.mac0.ToString("X2") + '-'); 
       Console.Write(row.mac1.ToString("X2") + '-'); 
       Console.Write(row.mac2.ToString("X2") + '-'); 
       Console.Write(row.mac3.ToString("X2") + '-'); 
       Console.Write(row.mac4.ToString("X2") + '-'); 
       Console.WriteLine(row.mac5.ToString("X2")); 

      } 
     } 
     finally 
     { 
      // Release the memory. 
      FreeMibTable(buffer); 
     } 
     } 
    } 
} 
+0

Ci scusiamo, ma l'idea era di scoprire quali macchine sono attualmente online. Non conosciamo l'IP al momento della connessione, poiché potrebbero provenire da wireless e ottenere l'IP tramite DHCP. So che potremmo bloccare i router, ma l'idea era di cercare l'indirizzo MAC dall'ARP + per raccogliere l'elenco corrente di dispositivi collegati alla rete. – BerggreenDK

+0

Sai come ottenere l'indirizzo MAC da un numero IP? – BerggreenDK

+0

Grandi cose! Questo devo testare. L'ho segnato come risposta ora. Molte grazie! Mi porta avanti ... "un salto da gigante": o) – BerggreenDK

2

Si spera che si stia cercando di ottenere gli indirizzi MAC da un indirizzo IP e non viceversa.

Ecco un link di esempio di un ragazzo:

ARP Resolver

non l'ho provato, ci faccia sapere come funziona.

+0

Grazie per il collegamento, ma questo esempio non richiede quanto segue: utilizzando Tamir.IPLib; utilizzando Tamir.IPLib.Packets; utilizzando Tamir.IPLib.Util; ??? – BerggreenDK

+0

Sto anche cercando di scoprire come/se è possibile creare una versione "C#" di commandprompt "arp -a" ... non chiamando un comando command nascosto, ma semplicemente eseguendo il comando ARP tramite codice in qualche modo. Come ho capito finora, il comando ARP elenca l'IP attualmente disponibile + i loro indirizzi MAC visti da "questa scheda di rete" ... e ciò andrebbe perfettamente alle nostre esigenze. – BerggreenDK

+1

Il comando ARP sta inviando byte non elaborati su un socket per ottenere ciò. La classe nel collegamento può risolvere un indirizzo MAC da un indirizzo IP, è questo che ti serve o hai bisogno di "scoprire" in qualche modo gli indirizzi IP? Le istruzioni di utilizzo in alto provengono da SharpPcap.dll, che è scaricabile e open source dal link che ho postato sopra. – jonathanpeppers

-4

Ricerca Google per "fingbox". Sembra che tu stia provando a rilevare i guasti?

Questo è un dispositivo rivelatore di intrusione che è completamente legale e fa bene sapere chi trasporta usando il wifi, su quali porte. A volte mostra anche l'indirizzo MAC e può eseguire il ping. Ha un sacco di altre funzionalità.

+0

Si tratta di eseguire il test dal CODE non acquistando un'app o un hardware. So di Fingbox, è arrivato MOLTO più tardi della mia domanda iniziale. – BerggreenDK

Problemi correlati