2010-02-08 44 views
8

Necesito obtener la asignación de MAC a IP almacenada en el servidor DHCP, ya sea a través de un programa que se ejecuta en el servidor o preferiblemente a través de un programa que se ejecuta en uno de los clientes DHCP.Consultando un servidor DHCP en C#

Entiendo netsh utility se puede utilizar para obtener el volcado, sin embargo, no he tenido mucho éxito con eso.

¿Algún ejemplo de funcionamiento o sugerencia al respecto?

tengo derechos de administrador en el servidor DHCP

Editar

no quiero utilizar la caché ARP, ya que ello requeriría notificación para la emisión de ping (que no está permitido en las ventanas) o ping a la posible ip dirección de la subred (que toma mucho tiempo).

Estoy seguro de que el servidor DHCP almacena la asignación de MAC a IP, ¿cómo puedo usar esa información, para asignar MAC a la dirección IP?

+0

que he publicado en serverfault, pero no obtuvo ninguna respuesta notable, me siento de esta pregunta requiere el conocimiento de cómo se escribió el servidor DHCP y ¿cómo se puede cortar en ella. Estoy tratando de resolver un problema de programación aquí. Si tiene problemas con la pregunta, solicite un cierre y no vote negativamente, desalienta a los demás a resolver la pregunta. – Kazoom

+0

@bzlm, agradecería que me ayudaran a encontrar las respuestas en lugar de buscar fallas y votar abajo, si siente que la respuesta no es una pregunta de programación, puede votar libremente para cerrar las preguntas. Tuve que publicar dos veces, ya que ambos foros tienen una audiencia diferente y todos estoy buscando una solución de programación para el problema que no encontré en serverfault. – Kazoom

+0

@bzlm http://bytes.com/topic/net/answers/574937-managing-dhcp-servers-using-c-another-net-lang ahora dime si esto es programación o no. estaba buscando algo en estas líneas. – Kazoom

Respuesta

0

haría con arp -a hacer el truco ... en mi máquina de la salida que recibo es:

tengo la dirección MAC/IP reemplazados por valores falsos para mostrar los resultados ...

 
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> 
Por

bombardeos a cabo utilizando System.Diagnostics.Process, puede redirigir la salida a un flujo de entrada y leer de él ...

Espero que esto ayude, saludos, Tom.

+0

no quiero usar la memoria caché de arp ya que eso me requeriría transmitir ping (que es no permitido en Windows) o hacer ping a todas las direcciones IP posibles de la subred (lo que requiere mucho tiempo). Estoy seguro de que el servidor DHCP almacena la asignación de MAC a IP, ¿cómo puedo usar esa información, para asignar MAC a la dirección IP? – Kazoom

+0

@Kazoom ¿Está ejecutando netsh en el servidor DHCP? ¿Tiene suficientes derechos administrativos para consultar el servidor? Es decir. si usa el complemento DHCP MMC, ¿puede ver la información? – bzlm

+0

@Kazoom: que se ejecutaría en el servidor dhcp mismo, de alguna manera podría crear un servicio web, sockets tcp/ip o algo para consultar la información al cliente ... – t0mm13b

4

Puede utilizar el DHCP objetos componentes del Kit de recursos de Windows 2000 para esto. A pesar de que el componente es difícil de encontrar, está hecho para Windows 2000, se retira del soporte vital en julio de 2010 según Microsoft y tiene muy poca documentación, funciona.

  1. descargar la herramienta Kit de recursos nombrado DHCP Objetos de, por ejemplo here si no lo puede encontrar en Microsoft. Esto le dará un archivo .exe que a su vez instalará el componente Objetos DHCP.
  2. Registre el archivo DHCPOBJS.DLL con regsvr32o cree una aplicación COM + para ello. Lo que es aplicable depende de cómo se va a usar el componente COM en su sistema.
  3. Use el importador de biblioteca de tipos tlbimp.exe para crear un contenedor administrado alrededor de DHCPOBJS.DLL ahora que está registrado por el sistema.
  4. En Visual Studio, agregue una referencia al contenedor administrado. Su nombre generado por defecto es DhcpObjects.dll.

Ahora se puede escribir código como este contra el componente:

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 
    } 
} 

El instalador también proporciona un archivo de Ayuda de Windows que contiene documentación adicional sobre cómo consultar y manipular un servidor DHCP. La sección "El modelo de objetos" es bastante útil.

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

imprimirá todas las direcciones IP arrendadas –

+1

pero solo funciona con el servidor MICROSOFT DHCP. Lo intenté con Linux pero no devolvió ningún resultado –