2010-02-08 118 views
8

我需要通過運行在服務器本身上的程序或最好通過在其中一個DHCP客戶端上運行的程序來獲取存儲在DHCP服務器上的MAC到IP的映射。在C#中查詢DHCP服務器#

我明白netsh utility可以用來獲得轉儲,但我沒有太多的成功與此。

任何工作示例或提示呢?

我有DHCP服務器的管理權限

編輯

我不想使用ARP緩存中,要求我要麼廣播平(這是不允許在Windows上)或ping到所有可能的IP子網地址(需要很多時間)。

我確定DHCP服務器存儲MAC到IP的映射,我如何使用該信息來將MAC映射到IP地址?

+0

我已經張貼在serverfault,但沒有得到任何答覆值得注意的,我覺得這個問題,需要的DHCP服務器是如何寫的知識,怎麼能夠攻入了。我想在這裏解決一個編程問題。如果你有問題,要求封閉,不要反對,它會阻止他人解決問題。 – Kazoom 2010-02-08 22:32:25

+0

@bzlm我會很感激,如果你幫我找到答案而不是故障查找和下投票,如果你覺得答案不是一個編程問題,你可以自由投票結束問題。由於兩個論壇都有不同的受衆,所以我不得不加倍發帖,所有我尋找一個編程解決方案來解決我在serverfault找不到的問題。 – Kazoom 2010-02-09 18:17:50

+0

@bzlm http://bytes.com/topic/net/answers/574937-managing-dhcp-servers-using-c-another-net-lang 現在告訴我,如果這是編程或不。我正在尋找這些線上的東西。 – Kazoom 2010-02-09 18:27:01

回答

0

會使用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,您可以將輸出重定向到一個輸入流並從中讀取...

希望這有助於 最好的問候, 湯姆。

+0

不想要使用arp緩存,因爲這將需要我廣播ping(這是不允許在Windows上)或ping所有可能的子網IP地址(這需要很多時間)。 我確定DHCP服務器存儲MAC到IP的映射,我如何使用該信息將MAC映射到IP地址? – Kazoom 2010-02-08 21:58:11

+0

@Kazoom你在DHCP服務器上運行netsh嗎?你有足夠的管理權限來查詢服務器嗎?即如果您使用DHCP MMC管理單元,您能看到這些信息嗎? – bzlm 2010-02-08 22:04:04

+0

@Kazoom:將DHCP服務器本身上運行,你可以以某種方式創建一個Web服務,TCP/IP套接字或東西傳達給客戶查詢信息...... DHCP服務器上 – t0mm13b 2010-02-08 22:07:10

4

爲此,您可以使用Windows 2000資源工具包中的DHCP對象組件。儘管該組件很難找到,但它是爲Windows 2000製作的,根據微軟公司的報告,它在2010年7月失去了生命支持,而且幾乎沒有文檔記錄,它確實有效。

  1. 下載資源包工具名爲DHCP對象例如從here,如果你不能在微軟找到它。這將爲您提供一個.exe文件,該文件反過來將安裝DHCP Objects組件。
  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 
    } 
} 

安裝程序還提供了包含有關如何查詢和操作一臺DHCP服務器更多的文件在Windows幫助文件。 「對象模型」部分非常有用。

1
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 
    ); 
} 
} 
+0

nbtstat -A MICROSOFT_DHCP_SERVER_IP – 2010-10-13 11:43:52

+0

它將打印所有租用的IP地址 – 2010-10-13 11:43:52

+1

但只適用於MICROSOFT DHCP服務器。我用Linux試過但沒有返回任何結果 – 2010-10-13 11:45:18