C# で DHCP サーバーにクエリを実行する
質問
DHCP サーバー自体で実行されているプログラム、またはできれば DHCP クライアントの 1 つで実行されているプログラムを介して、DHCP サーバーに保存されている MAC から IP へのマッピングを取得する必要があります。
わかりました netshユーティリティ ダンプを取得するために使用できますが、あまり成功しませんでした。
それに関する実際の例やヒントはありますか?
DHCPサーバーの管理者権限を持っています
編集
arp キャッシュを使用すると、ブロードキャスト ping (Windows では許可されていません) またはサブネットのすべての可能な IP アドレスに ping を実行する必要があるため (これには時間がかかります)、使用したくありません。
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
を使用して砲撃することで、あなたが入力ストリームに出力をリダイレクトすることができますし、それから読んで...
これが、お役に立てば幸い 宜しくお願いします、 トムます。