سؤال

أحتاج إلى الحصول على تعيين MAC إلى IP المخزنة على خادم DHCP، إما من خلال برنامج يعمل على الخادم نفسه أو يفضل من خلال برنامج يعمل على أحد عملاء DHCP.

أفهم فائدة Netsh يمكن استخدامها للحصول على تفريغ ولكن ليس لدي الكثير من النجاح مع ذلك.

أي أمثلة عمل أو تلميح على ذلك؟

لدي حقوق المسؤول على خادم DHCP

يحرر

لا أريد استخدام ذاكرة التخزين المؤقت ARP كما سيتطلب مني إما بث بينغ (غير مسموح به على Windows) أو Ping كل عنوان IP الممكن للشبكة الفرعية (التي تستغرق الكثير من الوقت).

أنا متأكد من أن خادم DHCP يخزن تعيين Mac إلى IP، كيف يمكنني استخدام هذه المعلومات، لتعيين Mac إلى عنوان IP؟

لا يوجد حل صحيح

نصائح أخرى

يمكنك استعمال ال مكون كائنات DHCP من طقم موارد Windows 2000 لهذا. على الرغم من صعوبة العثور على المكون، فإنه مصنوع لنظام التشغيل Windows 2000، يخرج من دعم الحياة في يوليو 2010 وفقا ل Microsoft ولديه وثائق القليل جدا، فإنه يعمل.

  1. قم بتنزيل أداة Resource Kit المسماة كائنات DHCP. من على سبيل المثال هنا إذا لم تتمكن من العثور عليه في Microsoft. سيعطيك هذا ملف .exe الذي سيقوم بدوره بتثبيت مكون كائنات DHCP.
  2. سجل DHCPOBJS.DLL ملف مع regsvr32 أو إنشاء تطبيق 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
    }
}

يوفر 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, ، يمكنك إعادة توجيه الإخراج إلى دفق الإدخال وقراءة منه ...

نأمل أن يساعد هذا، مع أطيب التحيات، توم.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top