Pergunta

Eu preciso para obter o mapeamento de MAC para IP armazenado no servidor DHCP, seja através de um programa em execução no próprio ou de preferência servidor através de um programa em execução em um dos clientes DHCP.

Eu entendo utilitário netsh pode ser usado para obter o despejo no entanto i não tiveram muito sucesso com isso.

Qualquer exemplos de trabalho ou sugestão sobre isso?

Eu tenho direitos de administrador no servidor DHCP

Editar

Eu não quero usar o cache arp como que me exigem, quer de ping broadcast (que não é permitido no Windows) ou ping o todos os endereços ip possível de sub-rede (o que leva muito tempo).

Estou certo de que DHCP servidor armazena o mapeamento do MAC para IP, como posso usar essa informação, para mapear MAC para o endereço IP?

Nenhuma solução correta

Outras dicas

Você pode usar o DHCP objetos componentes do Windows 2000 Resource Kit para isso. Mesmo que o componente é difícil de encontrar, é feita para Windows 2000, sai de suporte de vida em julho de 2010 de acordo com a Microsoft e tem muito pouca documentação, ela não funciona.

  1. Faça o download do Kit de ferramentas Resource chamado DHCP Objetos a partir por exemplo aqui se você não pode encontrá-lo no Microsoft. Isto lhe dará um arquivo .exe que por sua vez irá instalar o DHCP objetos componentes.
  2. Register o arquivo DHCPOBJS.DLL com regsvr32 ou criar um + aplicativo COM para ele. Que é aplicável depende de como o componente COM vai ser usado em seu sistema.
  3. Use o Type Library Importer tlbimp.exe para criar um wrapper gerenciado em torno DHCPOBJS.DLL agora que está registrado pelo sistema.
  4. No Visual Studio, adicione uma referência para o wrapper gerenciado. Seu nome gerado padrão é DhcpObjects.dll.

Agora você pode escrever código como este contra o 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
    }
}

O instalador também fornece um arquivo de Ajuda do Windows que contém mais documentação sobre como consultar e manipular um servidor DHCP. A seção "The Object Model" é bastante útil.

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

faria usando arp -a fazer o truque ... na minha máquina a saída que eu vejo é:

Eu tenho o endereço MAC / IP substituídos por valores falsos para mostrar os 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>

Ao descascar para fora usando System.Diagnostics.Process, você pode redirecionar a saída para um fluxo de entrada e ler a partir dele ...

Espero que isso ajude, Cumprimentos, Tom.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top