DhcpEnumSubnets (dhcpsapi)
Last changed: Jet0JLH-195.226.121.69

.
Summary
The DhcpEnumSubnets function returns an enumerated list of subnets defined on the DHCP server. This function returns ERROR_SUCCESS upon a successful call. If a call is made with the same ResumeHandle value and all items on the server have been enumerated, this method returns ERROR_NO_MORE_ITEMS with ElementsRead and ElementsTotal set to 0. Otherwise, it returns one of the DHCP Server Management API Error Codes.

C# Signature:

[DllImport("dhcpsapi.dll", SetLastError = true, CharSet = CharSet.Unicode)]
public static extern uint DhcpEnumSubnets(
    string ServerIpAddress,
    ref uint ResumeHandle,
    uint PreferredMaximum,
    out IntPtr EnumInfo,
    ref uint ElementsRead,
    ref uint ElementsTotal
);

VB Signature:

Declare Unicode Function DhcpEnumSubnets Lib "Dhcpsapi" (ByVal ServerIpAddress As String, ByRef ResumeHandle As Integer, ByVal PreferredMaximum As Integer, ByRef EnumInfo As IntPtr, ByRef ElementsRead As Integer, ByRef ElementsTotal As Integer) As Integer

User-Defined Types:

DHCP_IP_ARRAY

Alternative Managed API:

Do you know one? Please contribute it!

Notes:

ServerIpAddress - [in] Unicode string that specifies the IP address of the DHCP server

ResumeHandle - [in,out] Pointer to a DHCP_RESUME_HANDLE value that identifies the enumeration operation. Initially, this value should be zero, with a successful call returning the handle value used for subsequent enumeration requests. For example, if PreferredMaximum is set to 100, and 200 subnet addresses are stored on the server, the resume handle can be used after the first 100 subnets are retrieved to obtain the next 100 on a subsequent call, and so forth.

PreferredMaximum - [in] Specifies the preferred maximum number of subnet addresses to return. If the number of remaining unenumerated options is less than this value, then that amount will be returned

EnumInfo - [out] Pointer to a DHCP_IP_ARRAY [IntPtr] structure that contains the subnet IDs available on the DHCP server. If no subnets are defined, this value will be null.

ElementsRead - [out] Pointer to a DWORD value that specifies the number of subnet addresses returned in EnumInfo.

ElementsTotal - [out] Pointer to a DWORD value that specifies the number of subnets defined on the DHCP server that have not yet been enumerated

Tips & Tricks:

Make sure that ResumeHandle is 0 (zero) the first time you call this function.

Completed library DHCP functions.

http://www.rupj.net/portfolio/dhcp-web-services.html

Sample Code:

static void Main()
{
    String ServerIpAddress = "192.168.0.250";
    UInt32 DHCPResult = 0;

    IntPtr ips;
    uint nr = 0;
    uint total = 0;
    uint resumeHandle = 0;

    DHCPResult = DhcpEnumSubnets(ServerIpAddress, ref resumeHandle, 1000, out ips, ref nr, ref total);
    if (DHCPResult == 0)
    {

       DHCP_IP_ARRAY ipArray = (DHCP_IP_ARRAY)Marshal.PtrToStructure(ips, typeof(DHCP_IP_ARRAY));

       int size = (int)ipArray.NumElements;
       IntPtr outArray = ipArray.IPAddresses;
       DHCP_IP_ADDRESS[] ipAddressArray = new DHCP_IP_ADDRESS[size];
       IntPtr current = outArray;
       for (int i = 0; i < size; i++)
       {
      ipAddressArray[i] = new DHCP_IP_ADDRESS();
      Marshal.PtrToStructure(current, ipAddressArray[i]);
      Marshal.DestroyStructure(current, typeof(DHCP_IP_ADDRESS));
      current = (IntPtr)((int)current + Marshal.SizeOf(ipAddressArray[i]));

      Console.WriteLine("{0}", UInt32IPAddressToString(ipAddressArray[i].IPAddress));
       }
       Marshal.FreeCoTaskMem(outArray);

       Console.WriteLine("Elements read {0} of total {1}", nr, total);
    }
    else
    {
       int code = 0;
       unchecked
       {
      code = (int)DHCPResult;
       }
       Win32Exception winex = new Win32Exception(code);
       Console.WriteLine(winex.NativeErrorCode + " : " + winex.Message);
    }
}

[DllImport("dhcpsapi.dll", SetLastError = true, CharSet = CharSet.Unicode)]
public static extern uint DhcpEnumSubnets(
    string ServerIpAddress,
    ref uint ResumeHandle,
    uint PreferredMaximum,
    out IntPtr EnumInfo,
    ref uint ElementsRead,
    ref uint ElementsTotal
);

[StructLayout(LayoutKind.Sequential)]
public struct DHCP_IP_ARRAY
{
    public uint NumElements;
    public IntPtr IPAddresses;
}

/// This is a custom type/class
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public class DHCP_IP_ADDRESS
{
    public UInt32 IPAddress;
}

public static string UInt32IPAddressToString(UInt32 ipAddress)
{
    IPAddress ipA = new IPAddress(ipAddress);
    string[] sIp = ipA.ToString().Split('.');

    return sIp[3] + "." + sIp[2] + "." + sIp[1] + "." + sIp[0];
}

VB Signature:

Sample Code:

Declare Unicode Function DhcpEnumSubnets Lib "Dhcpsapi" (ByVal ServerIpAddress As String, ByRef ResumeHandle As UInteger, ByVal PreferredMaximum As UInteger, ByRef EnumInfo As IntPtr, ByRef ElementsRead As UInteger, ByRef ElementsTotal As UInteger) As UInteger

    Sub main()
    Dim ServerIpAddress As String = "192.168.0.250"
    Dim DHCPResult As UInt32 = 0

    Dim ips As IntPtr
    Dim nr As UInteger = 0
    Dim total As UInteger = 0
    Dim resumeHandle As UInteger = 0
    DHCPResult = DhcpEnumSubnets(ServerIpAddress, resumeHandle, 1000, ips, nr, total)
    If DHCPResult = 0 Then
        Dim ipArray As DHCP_IP_ARRAY = CType(Marshal.PtrToStructure(ips, GetType(DHCP_IP_ARRAY)), DHCP_IP_ARRAY)
        Dim size As Integer = CType(ipArray.NumElements, Integer)
        Dim outArray As IntPtr = ipArray.IPAddresses
        Dim ipAddressArray() As DHCP_IP_ADDRESS = New DHCP_IP_ADDRESS((size) - 1) {}
        Dim current As IntPtr = outArray
        Dim i As Integer = 0
        Do While (i < size)
        ipAddressArray(i) = New DHCP_IP_ADDRESS
        Marshal.PtrToStructure(current, ipAddressArray(i))
        Marshal.DestroyStructure(current, GetType(DHCP_IP_ADDRESS))
        current = CType((CType(current, Integer) + Marshal.SizeOf(ipAddressArray(i))), IntPtr)
        Console.WriteLine("{0}", UInt32IPAddressToString(ipAddressArray(i).IPAddress))
        i = (i + 1)
        Loop

        Marshal.FreeCoTaskMem(outArray)
        Console.WriteLine("Elements read {0} of total {1}", nr, total)
    Else
        Dim code As Integer = 0
        code = CType(DHCPResult, Integer)
        Dim winex As Win32Exception = New Win32Exception(code)
        Console.WriteLine((winex.NativeErrorCode + (" : " + winex.Message)))
    End If

    End Sub

    <StructLayout(LayoutKind.Sequential)>
    Public Structure DHCP_IP_ARRAY
    Public NumElements As UInteger
    Public IPAddresses As IntPtr
    End Structure

    ' This is a custom type/class
    <StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Ansi)>
    Public Class DHCP_IP_ADDRESS
    Public IPAddress As UInt32
    End Class

    Public Shared Function UInt32IPAddressToString(ByVal ipAddress As UInt32) As String
    Dim ipA As Net.IPAddress = New Net.IPAddress(ipAddress)
    Dim sIp() As String = ipA.ToString.Split(Microsoft.VisualBasic.ChrW(46))
    Return (sIp(3) + ("." + (sIp(2) + ("." + (sIp(1) + ("." + sIp(0)))))))
    End Function

Documentation