2010-02-08 26 views
8

Je dois obtenir le mappage de MAC vers IP stocké sur le serveur DHCP, soit via un programme exécuté sur le serveur lui-même, soit de préférence via un programme s'exécutant sur l'un des clients DHCP.Interrogation d'un serveur DHCP en C#

Je comprends netsh utility peut être utilisé pour obtenir la décharge mais je n'ai pas eu beaucoup de succès avec ça.

Des exemples de travail ou un indice à ce sujet?

Je possède des droits d'administrateur sur le serveur DHCP

Modifier

Je ne veux pas utiliser le cache arp car cela me obligerait soit ping de diffusion (ce qui est interdit sur les fenêtres) ou ping sur le tout IP possible adresse du sous-réseau (ce qui prend beaucoup de temps).

Je suis sûr que le serveur DHCP stocke le mappage de MAC à IP, comment puis-je utiliser cette information, pour mapper MAC à l'adresse IP?

+0

je l'ai posté sur serverfault, mais pas obtenu de réponse remarquable, je pense que cette question exige une connaissance de la façon dont a été écrit et comment peut-on pirater le serveur dhcp en elle. J'essaie de résoudre un problème de programmation ici. Si vous avez des problèmes avec une question, demandez une clôture et ne votez pas négativement, cela décourage les autres de résoudre la question. – Kazoom

+0

@bzlm j'apprécierais si vous m'aidez à trouver les réponses plutôt que la recherche de panne et le vote vers le bas, si vous sentez que la réponse n'est pas une question de programmation, vous êtes libre de voter pour clôturer les questions. J'ai dû poster double car les deux forums ont un public différent et je cherche une solution de programmation au problème que je n'ai pas trouvé sur serverfault. – Kazoom

+0

@bzlm http://bytes.com/topic/net/answers/574937-managing-dhcp-servers-using-c-another-net-lang me dire maintenant si c'est la programmation ou non. Je cherchais quelque chose sur ces lignes. – Kazoom

Répondre

0

utilisant arp -a Would faire l'affaire ... sur ma machine la sortie que je reçois est:

Je l'adresse MAC/IP remplacées par des valeurs fausses pour afficher les résultats ...

 
C:\Documents and Settings\Tom>arp -a 

Interface: 10.203.24.196 --- 0xf0007 
    Internet Address  Physical Address  Type 
    10.203.24.198   02-50-f3-10-14-06  dynamic 

C:\Documents and Settings\Tom> 

par les bombardements à l'aide System.Diagnostics.Process, vous pouvez rediriger la sortie vers un flux d'entrée et de lire ce ...

Hope this helps, Meilleures salutations, Tom.

+0

ne veulent pas utiliser le cache ARP car cela me demanderait soit de diffuser ping (qui est pas autorisé sur Windows) ou ping l'adresse IP de tous les sous-réseau possible (ce qui prend beaucoup de temps). Je suis sûr que le serveur DHCP stocke le mappage de MAC à IP, comment puis-je utiliser cette information, pour mapper MAC à l'adresse IP? – Kazoom

+0

@Kazoom Courez-vous netsh sur le serveur DHCP? Avez-vous suffisamment de droits d'administrateur pour interroger le serveur? C'est à dire. Si vous utilisez le composant logiciel enfichable MMC DHCP, pouvez-vous voir les informations? – bzlm

+0

@Kazoom: qui serait exécuté sur le serveur dhcp lui-même, vous pourriez en quelque sorte créer un webservice, sockets tcp/ip ou quelque chose pour interroger l'information à travers le client ... – t0mm13b

4

Vous pouvez utiliser le composant Objets DHCP du Kit de ressources Windows 2000 pour cela. Même si le composant est difficile à trouver, est fait pour Windows 2000, sort de la vie en Juillet 2010 selon Microsoft et a très peu de documentation, cela fonctionne.

  1. Téléchargez l'outil Kit de ressources nommé DHCP Objets de par exemple here si vous ne pouvez pas le trouver chez Microsoft. Cela vous donnera un fichier .exe qui à son tour va installer le composant des objets DHCP.
  2. Enregistrez le fichier DHCPOBJS.DLL avec regsvr32ou pour créer une application COM +. Ce qui s'applique dépend de la façon dont le composant COM va être utilisé sur votre système.
  3. Utilisez l'importateur de bibliothèque de types tlbimp.exe pour créer un wrapper géré autour de DHCPOBJS.DLL maintenant qu'il est enregistré par le système.
  4. Dans Visual Studio, ajoutez une référence à l'encapsuleur géré. Son nom généré par défaut est DhcpObjects.dll.

Maintenant, vous pouvez écrire du code comme celui-ci contre le composant:

using DhcpObjects; 
class Program { 
    static void Main(string[] args) { 
     var manager = new Manager(); 
     var server = dhcpmgr.Servers.Connect("1.2.3.4"); 
     // query server here 
    } 
} 

Le programme d'installation fournit également un fichier d'aide Windows qui contient d'autres documents sur la façon d'interroger et de manipuler un serveur DHCP. La section "Le modèle d'objet" est très utile.

1
using System; 
using System.Runtime.InteropServices; 
using System.Collections; 
using System.Net; 

namespace dhcp 
{ 
// c# class for processed clients 

public class dhcpClient 
{ 
    public string hostname { get; set; } 
    public string ip  { get; set; } 
    public string mac  { get; set; } 
} 

// structs for use with call to unmanaged code 

[StructLayout(LayoutKind.Sequential)] 
public struct DHCP_CLIENT_INFO_ARRAY 
{ 
    public uint NumElements; 
    public IntPtr Clients; 
} 

[StructLayout(LayoutKind.Sequential)] 
public struct DHCP_CLIENT_UID 
{ 
    public uint DataLength; 
    public IntPtr Data; 
} 

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)] 
public struct DHCP_CLIENT_INFO 
{ 
    public uint ip; 
    public uint subnet; 

    public DHCP_CLIENT_UID mac; 

    [MarshalAs(UnmanagedType.LPWStr)] 
    public string ClientName; 

    [MarshalAs(UnmanagedType.LPWStr)] 
    public string ClientComment; 
} 

// main 

class Program 
{ 
    static void Main() 
    { 
     try 
     { 
      // get settings 

      String server, subnet; 

      Console.Write("Enter server : "); 
      server = Console.ReadLine(); 
      Console.Write("Enter subnet : "); 
      subnet = Console.ReadLine(); 

      // gather clients 

      ArrayList clients = findDhcpClients(server, subnet); 

      // output results 

      Console.WriteLine(); 

      foreach (dhcpClient d in clients) 
       Console.WriteLine(String.Format("{0,-35} {1,-15} {2,-15}", d.hostname, d.ip, d.mac)); 

      Console.WriteLine('\n' + clients.Count.ToString() + " lease(s) in total"); 
     } 

     catch (Exception e) 
     { 
      Console.WriteLine(e.ToString()); 
     } 

     Console.ReadLine(); 
    } 

    static ArrayList findDhcpClients(string server, string subnet) 
    { 
     // set up container for processed clients 

     ArrayList foundClients = new ArrayList(); 

     // make call to unmanaged code 

     uint parsedMask  = StringIPAddressToUInt32(subnet); 
     uint resumeHandle = 0; 
     uint numClientsRead = 0; 
     uint totalClients = 0; 

     IntPtr info_array_ptr; 

     uint response = DhcpEnumSubnetClients(
      server, 
      parsedMask, 
      ref resumeHandle, 
      65536, 
      out info_array_ptr, 
      ref numClientsRead, 
      ref totalClients 
      ); 

     // set up client array casted to a DHCP_CLIENT_INFO_ARRAY 
     // using the pointer from the response object above 

     DHCP_CLIENT_INFO_ARRAY rawClients = 
      (DHCP_CLIENT_INFO_ARRAY)Marshal.PtrToStructure(info_array_ptr, typeof(DHCP_CLIENT_INFO_ARRAY)); 

     // loop through the clients structure inside rawClients 
     // adding to the dchpClient collection 

     IntPtr current = rawClients.Clients; 

     for (int i = 0; i < (int)rawClients.NumElements; i++) 
     { 
      // 1. Create machine object using the struct 

      DHCP_CLIENT_INFO rawMachine = 
       (DHCP_CLIENT_INFO)Marshal.PtrToStructure(Marshal.ReadIntPtr(current), typeof(DHCP_CLIENT_INFO)); 

      // 2. create new C# dhcpClient object and add to the 
      // collection (for hassle-free use elsewhere!!) 

      dhcpClient thisClient = new dhcpClient(); 

      thisClient.ip = UInt32IPAddressToString(rawMachine.ip); 

      thisClient.hostname = rawMachine.ClientName; 

      thisClient.mac = String.Format("{0:x2}{1:x2}.{2:x2}{3:x2}.{4:x2}{5:x2}", 
       Marshal.ReadByte(rawMachine.mac.Data), 
       Marshal.ReadByte(rawMachine.mac.Data, 1), 
       Marshal.ReadByte(rawMachine.mac.Data, 2), 
       Marshal.ReadByte(rawMachine.mac.Data, 3), 
       Marshal.ReadByte(rawMachine.mac.Data, 4), 
       Marshal.ReadByte(rawMachine.mac.Data, 5)); 

      foundClients.Add(thisClient); 

      // 3. move pointer to next machine 

      current = (IntPtr)((int)current + (int)Marshal.SizeOf(typeof(IntPtr))); 
     } 

     return foundClients; 
    } 

    public static uint StringIPAddressToUInt32(string ip) 
    { 
     // convert string IP to uint IP e.g. "1.2.3.4" -> 16909060 

     IPAddress i = System.Net.IPAddress.Parse(ip); 
     byte[] ipByteArray = i.GetAddressBytes(); 

     uint ipUint = (uint)ipByteArray[0] << 24; 
     ipUint += (uint)ipByteArray[1] << 16; 
     ipUint += (uint)ipByteArray[2] << 8; 
     ipUint += (uint)ipByteArray[3]; 

     return ipUint; 
    } 

    public static string UInt32IPAddressToString(uint ip) 
    { 
     // convert uint IP to string IP e.g. 16909060 -> "1.2.3.4" 

     IPAddress i = new IPAddress(ip); 
     string[] ipArray = i.ToString().Split('.'); 

     return ipArray[3] + "." + ipArray[2] + "." + ipArray[1] + "." + ipArray[0]; 
    } 

    [DllImport("dhcpsapi.dll", SetLastError = true, CharSet = CharSet.Auto)] 
    public static extern uint DhcpEnumSubnetClients(
      string ServerIpAddress, 
      uint SubnetAddress, 
     ref uint ResumeHandle, 
      uint PreferredMaximum, 
     out IntPtr ClientInfo, 
     ref uint ElementsRead, 
     ref uint ElementsTotal 
    ); 
} 
} 
+0

nbtstat -A MICROSOFT_DHCP_SERVER_IP –

+0

il va imprimer toutes les adresses IP louées –

+1

mais ne fonctionne qu'avec le serveur DHCP MICROSOFT. Je l'ai essayé avec Linux mais je n'ai pas retourné de résultats –