我想用c#中的microsoft dhcp server management api枚举我们的microsoft dhcp服务器的所有dhcp预留条目。
这是我的代码:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
using System.Net;
using System.Windows.Forms;
using System.Collections;
namespace Sequence
{
[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;
}
class CDHCP
{
public static ArrayList findDhcpClients(string server, string subnet)
{
ArrayList foundClients = new ArrayList();
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
);
DHCP_CLIENT_INFO_ARRAY rawClients = (DHCP_CLIENT_INFO_ARRAY)Marshal.PtrToStructure(info_array_ptr, typeof(DHCP_CLIENT_INFO_ARRAY));
IntPtr current = rawClients.Clients;
for (int i = 0; i < (int)rawClients.NumElements; i++)
{
DHCP_CLIENT_INFO rawMachine = (DHCP_CLIENT_INFO)Marshal.PtrToStructure(Marshal.ReadIntPtr(current), typeof(DHCP_CLIENT_INFO));
CDHCPCLIENT thisClient = new CDHCPCLIENT();
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, 0),
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);
current = (IntPtr)((int)current + (int)Marshal.SizeOf(typeof(IntPtr)));
}
return foundClients;
}
public static uint StringIPAddressToUInt32(string ip)
{
IPAddress i = 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)
{
IPAddress i = new IPAddress(ip);
string[] ipArray = i.ToString().Split('.');
return ipArray[3] + "." + ipArray[2] + "." + ipArray[1] + "." + ipArray[0];
}
[DllImport("C:\\Windows\\System32\\dhcpsapi.dll", SetLastError = true, CharSet = CharSet.Auto)]
public static extern uint DhcpEnumSubnetClients(
string ServerIpAddress,
uint SubnetAddress,
ref uint ResumeHanle,
uint PreferredMaximum,
out IntPtr ClientInfo,
ref uint ElementsRead,
ref uint ElementsTotal);
}
}
不幸的是我在这一行得到了一个NullReferenceException:
DHCP_CLIENT_INFO_ARRAY rawClients = (DHCP_CLIENT_INFO_ARRAY)Marshal.PtrToStructure(info_array_ptr, typeof(DHCP_CLIENT_INFO_ARRAY));
我称之为这样的功能:
public void GetDHCPReservation()
{
ArrayList clients = CDHCP.findDhcpClients("192.168.1.3", "192.168.1.5");
foreach (CDHCPCLIENT c in clients)
{
MessageBox.Show(string.Format("(0,-35}{1,-15}{2,-15}", c.hostname, c.ip, c.mac));
}
}
任何人都可以帮助我吗? 提前谢谢。
答案 0 :(得分:1)
我想我刚刚解决了我的问题。
我得到NullReferenceException的原因是因为IntPtr info_array_ptr总是指向0(零)。这是因为dhcp服务器上没有足够的用户权限。在我将运行我的应用程序的用户添加到域管理员后,一切运行良好。