C#에서 DHCP 서버 쿼리
문제
서버 자체에서 실행되는 프로그램을 통해 또는 바람직하게는 DHCP 클라이언트 중 하나에서 실행되는 프로그램을 통해 DHCP 서버에 저장된 MAC에서 IP로의 매핑을 가져와야합니다.
이해합니다 Netsh 유틸리티 덤프를 얻는 데 사용될 수는 있지만 그로 인해 큰 성공을 거두지 못했습니다.
작업 예 또는 힌트가 있습니까?
DHCP 서버에 관리자 권한이 있습니다
편집하다
ARP 캐시를 사용하고 싶지 않기 때문에 핑 (Windows에서는 허용되지 않음) 또는 서브넷의 모든 IP 주소 (많은 시간이 걸리기)를 핑해야합니다.
DHCP 서버는 Mac을 IP에 매핑하는 것을 확신합니다. 해당 정보를 어떻게 사용하여 Mac을 IP 주소로 매핑 할 수 있습니까?
올바른 솔루션이 없습니다
다른 팁
당신은 사용할 수 있습니다 DHCP 객체 구성 요소 ~로부터 Windows 2000 리소스 키트 이것을 위해. 구성 요소는 찾기가 어렵지만 Windows 2000을 위해 만들어졌지만 Microsoft에 따르면 2010 년 7 월에 생명 지원을 중단하고 문서가 거의 없지만 작동합니다.
- 이름이 지정된 리소스 키트 도구를 다운로드하십시오 DHCP 객체 예를 들어 여기 Microsoft에서 찾을 수 없다면. 이렇게하면 DHCP 객체 구성 요소를 설치하는 .exe 파일이 제공됩니다.
- 등록
DHCPOBJS.DLL
파일regsvr32
또는 com+ 응용 프로그램을 만듭니다. 적용 가능한 것은 COM 구성 요소가 시스템에서 어떻게 사용되는지에 따라 다릅니다. - 유형 라이브러리 수입업자를 사용하십시오
tlbimp.exe
관리하는 래퍼를 만들기 위해DHCPOBJS.DLL
이제 시스템에 의해 등록되었습니다. - 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
}
}
설치 프로그램은 또한 DHCP 서버를 쿼리하고 조작하는 방법에 대한 추가 설명서가 포함 된 Windows 도움말 파일을 제공합니다. "객체 모델"섹션이 매우 도움이됩니다.
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
);
}
}
사용합니다 arp -a
트릭을 수행 ... 내 컴퓨터에서 내가 얻는 출력은 다음과 같습니다.
결과를 보여주기 위해 가짜 값으로 대체 된 Mac/IP 주소가 있습니다 ...
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>
사용을 쫓아내어 System.Diagnostics.Process
, 출력을 입력 스트림으로 리디렉션하고 읽을 수 있습니다 ...
이것이 도움이되기를 바랍니다.