استعلام خادم DHCP في C #
سؤال
أحتاج إلى الحصول على تعيين MAC إلى IP المخزنة على خادم DHCP، إما من خلال برنامج يعمل على الخادم نفسه أو يفضل من خلال برنامج يعمل على أحد عملاء DHCP.
أفهم فائدة Netsh يمكن استخدامها للحصول على تفريغ ولكن ليس لدي الكثير من النجاح مع ذلك.
أي أمثلة عمل أو تلميح على ذلك؟
لدي حقوق المسؤول على خادم DHCP
يحرر
لا أريد استخدام ذاكرة التخزين المؤقت ARP كما سيتطلب مني إما بث بينغ (غير مسموح به على Windows) أو Ping كل عنوان IP الممكن للشبكة الفرعية (التي تستغرق الكثير من الوقت).
أنا متأكد من أن خادم DHCP يخزن تعيين Mac إلى IP، كيف يمكنني استخدام هذه المعلومات، لتعيين Mac إلى عنوان IP؟
لا يوجد حل صحيح
نصائح أخرى
يمكنك استعمال ال مكون كائنات DHCP من طقم موارد Windows 2000 لهذا. على الرغم من صعوبة العثور على المكون، فإنه مصنوع لنظام التشغيل Windows 2000، يخرج من دعم الحياة في يوليو 2010 وفقا ل Microsoft ولديه وثائق القليل جدا، فإنه يعمل.
- قم بتنزيل أداة Resource Kit المسماة كائنات DHCP. من على سبيل المثال هنا إذا لم تتمكن من العثور عليه في Microsoft. سيعطيك هذا ملف .exe الذي سيقوم بدوره بتثبيت مكون كائنات DHCP.
- سجل
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
}
}
يوفر Installer أيضا ملف تعليمات Windows يحتوي على مزيد من الوثائق حول كيفية الاستعلام والتلاعب بخادم DHCP. القسم "نموذج الكائن" مفيد للغاية.
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 استبدال قيم Bogus لإظهار النتائج ...
C: الوثائق والإعدادات Tom> ARP -A واجهة: 10.203.24.196 --- 0xF0007 عنوان الإنترنت العنوان الفعلي نوع 10.203.24.198 02-50-F3-10-14-06 الديناميكي C: المستندات والإعدادات Tom>
عن طريق القصف باستخدام System.Diagnostics.Process
, ، يمكنك إعادة توجيه الإخراج إلى دفق الإدخال وقراءة منه ...
نأمل أن يساعد هذا، مع أطيب التحيات، توم.