在C#中查询DHCP服务器

我需要通过在服务器上运行的程序或者最好通过在其中一个DHCP客户端上运行的程序来获得存储在DHCP服务器上的MAC到IP的映射。

我知道netsh实用程序可以用来获得转储,但我没有太多的成功。

任何工作的例子或提示呢?

我有DHCP服务器上的pipe理权限

编辑

我不想使用ARPcaching,因为这将要求我广播ping(这是不允许在Windows上)或ping所有可能的子网IP地址(这需要大量的时间)。

我确信DHCP服务器存储MAC到IP的映射,我如何使用这些信息来映射MAC到IP地址?

Solutions Collecting From Web of "在C#中查询DHCP服务器"

您可以使用Windows 2000资源工具包中DHCP对象组件 即使这个组件很难找到,是为Windows 2000制作的,根据微软的说法在2010年7月失去了生命支持,而且几乎没有文档,它确实可行。

  1. 如果您在Microsoft找不到,请下载名为“ DHCP Objects”的资源工具包工具。 这将给你一个.exe文件,反过来将安装DHCP对象组件。
  2. regsvr32注册DHCPOBJS.DLL文件为其创建一个COM +应用程序。 哪个适用取决于COM组件将如何在您的系统上使用。
  3. 使用类型库导入程序tlbimp.exe创建一个围绕着DHCPOBJS.DLL的托管包装,现在它已被系统注册。
  4. 在Visual Studio中,添加对托管包装的引用。 它的默认生成名称是DhcpObjects.dll

现在,您可以针对组件编写这样的代码:

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

安装程序还提供Windows帮助文件,其中包含有关如何查询和操作DHCP服务器的更多文档。 “对象模型”部分是相当有帮助的。

将使用arp -a做的伎俩…在我的机器上我得到的输出是:

我有MAC / IP地址取代伪造的值来显示结果…

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

接口:10.203.24.196 --- 0xf0007
   Internet地址物理地址类型
   10.203.24.198 02-50-f3-10-14-06动态

 C:\ Documents and Settings \ Tom>

通过使用System.Diagnostics.Process脱壳,可以将输出重定向到输入流并从中读取…

希望这有助于,最好的问候,汤姆。

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