473,414 Members | 1,876 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,414 software developers and data experts.

DHCP with P/Invoke

Hello,

I'm working on an application to allow our network team to use a small
application to make DHCP reservations on our Microsoft DHCP Server.

The problem is you have to use P/Invoke to do it, and from what I've
found on the web and in this newsgroup is that it's not easy, however I
believe it can/has been done.

At the moment I'm just trying to find out information about an existing
reservation but I'm getting stuck. I read the newsgroup article
'P/Invoke with DHCP management API' which got me started but the last
comment made on 2006-01-01 didn't make sense to me and I can't get the
damn thing to work, in my test console app.

Here is the code I am using, could someone point me in the right
direction please?:

using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;

namespace DHCP
{
class Program
{
static void Main(string[] args)
{
String ServerIpAddress = "192.168.0.250";

UInt32 DHCPResult = 0;
try
{
DhcpApi.DHCP_SEARCH_INFO searchInfo = new
DhcpApi.DHCP_SEARCH_INFO();
DhcpApi.DHCP_SEARCH_INFO_TYPE searchInfoType =
DhcpApi.DHCP_SEARCH_INFO_TYPE.DhcpClientIpAddress;

searchInfo.SearchType = searchInfoType;
searchInfo.ClientIpAddress =
DhcpApi.ConvertIPAddress("192.168.0.5");

DhcpApi.DHCP_CLIENT_INFO clientInfo = new
DhcpApi.DHCP_CLIENT_INFO();

DHCPResult = DhcpApi.DhcpGetClientInfo(ServerIpAddress,
ref searchInfo, ref clientInfo);
Console.WriteLine(DHCPResult.ToString() + " Client
Info: " + clientInfo.ClientName);
}
catch (Exception ex)
{

Console.WriteLine("******************************* *********************************************");
Console.WriteLine("ERROR: \t" + DHCPResult.ToString());
Console.WriteLine("MESSAGE: \t" + ex.Message);
Console.WriteLine();
Console.WriteLine("FULL DETAILS:");
Console.WriteLine(ex.ToString());

Console.WriteLine("******************************* *********************************************");
}

Console.ReadKey(true);
}
}

public class DhcpApi
{
/// <summary>
/// The DhcpGetClientInfo function returns information about a
specific DHCP client.
/// </summary>
/// <param name="ServerIpAddress">[in] Unicode string that
specifies the IP address of the DHCP server.</param>
/// <param name="SearchInfo">[in] DHCP_SEARCH_INFO structure
that contains the parameters for the search. </param>
/// <param name="ClientInfo">[out] Pointer to a
DHCP_CLIENT_INFO structure that contains information describing the DHCP
client that most closely matches the provided search parameters. If no
client is found, this parameter will be null.</param>
/// <returns>This function returns ERROR_SUCCESS upon a
successful call. Otherwise, it returns one of the DHCP Server Management
API Error Codes.</returns>
[DllImport("dhcpsapi.dll", SetLastError = true,CharSet =
CharSet.Unicode)]
public static extern UInt32
DhcpGetClientInfo([MarshalAs(UnmanagedType.LPWStr)]String
ServerIpAddress, ref DHCP_SEARCH_INFO SearchInfo, ref DHCP_CLIENT_INFO
ClientInfo);

/// <summary>
/// The DHCP_SEARCH_INFO_TYPE enumeration defines the set of
possible
/// attributes used to search DHCP client information records.
/// </summary>
public enum DHCP_SEARCH_INFO_TYPE : int
{
/// <summary>
/// The search will be performed against the assigned DHCP
client IP address, represented as a 32-bit unsigned integer value.
/// </summary>
DhcpClientIpAddress = 0,
/// <summary>
/// The search will be performed against the MAC address of
the DHCP client network interface device, represented as a
DHCP_BINARY_DATA structure.
/// </summary>
DhcpClientHardwareAddress = 1,
/// <summary>
/// The search will be performed again the DHCP client's
network name, represented as a Unicode string.
/// </summary>
DhcpClientName = 2
}

/// <summary>
/// The DHCP_SEARCH_INFO structure defines the DHCP client record
/// data used to search against for particular server operations.
/// </summary>
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public struct DHCP_SEARCH_INFO
{
// typedef struct _DHCP_CLIENT_SEARCH_INFO {
// DHCP_SEARCH_INFO_TYPE SearchType;
// union {
// DHCP_IP_ADDRESS ClientIpAddress;
// DHCP_CLIENT_UID ClientHardwareAddress;
// LPWSTR ClientName;
// } SearchInfo;
//} DHCP_SEARCH_INFO, *LPDHCP_SEARCH_INFO;

public DHCP_SEARCH_INFO_TYPE SearchType;
public UInt32 ClientIpAddress;
}
/// <summary>
/// The DHCP_CLIENT_INFO structure defines a client information
record
/// used by the DHCP server.
/// </summary>
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public struct DHCP_CLIENT_INFO
{
//
************************************************** **************************
// DHCP_IP_ADDRESS Specifies an IP address, with the first
byte containing
// the first number in the address, the second byte
containing the second
// number, the third byte containing the third number, and
the last byte
// containing the last number in the address. For example,
the address
// 192.1.1.10 is represented as 11000000 00000001 00000001
00001010 (binary),
// or 3221291274 (decimal).
//
************************************************** **************************
public UInt32 ClientIpAddress;
public UInt32 SubnetMask;
public DHCP_BINARY_DATA ClientHardwareAddress;
[MarshalAs(UnmanagedType.LPWStr)]
public String ClientName;
[MarshalAs(UnmanagedType.LPWStr)]
public String ClientComment;
public DATE_TIME ClientLeaseExpires;
public DHCP_HOST_INFO OwnerHost;
}
}
}
I'm also hoping to implement the following API functions in the future,
if anyone has any pointers on these as well! ;o):

DhcpGetClientInfo
DhcpDeleteClientInfo
DhcpCreateClientInfo
DhcpSetClientInfo
DhcpEnumSubnetClients

Cheers,

Richard W.
--
Google First. Ask Later.
Sep 1 '06 #1
5 7603
Richard,
>At the moment I'm just trying to find out information about an existing
reservation but I'm getting stuck. I read the newsgroup article
'P/Invoke with DHCP management API' which got me started but the last
comment made on 2006-01-01 didn't make sense to me and I can't get the
damn thing to work, in my test console app.
What he's saying is that you have to change the method signature to

public static extern UInt32 DhcpGetClientInfo(String ServerIpAddress,
ref DHCP_SEARCH_INFO SearchInfo, out IntPtr ClientInfo);

and then make the calling code

IntPtr pClientInfo;
DHCPResult = DhcpApi.DhcpGetClientInfo(ServerIpAddress, ref
searchInfo, out pClientInfo);
if (DHCPResult == 0 && pClientInfo != IntPtr.Zero)
{
DHCP_CLIENT_INFO clientInfo =
(DHCP_CLIENT_INFO)Marshal.PtrToStructure(pClientIn fo,
typeof(DHCP_CLIENT_INFO));
...
}

Mattias

--
Mattias Sjögren [C# MVP] mattias @ mvps.org
http://www.msjogren.net/dotnet/ | http://www.dotnetinterop.com
Please reply only to the newsgroup.
Sep 3 '06 #2
Mattias,
What he's saying is that you have to change the method signature to

public static extern UInt32 DhcpGetClientInfo(String ServerIpAddress,
ref DHCP_SEARCH_INFO SearchInfo, out IntPtr ClientInfo);

and then make the calling code

IntPtr pClientInfo;
DHCPResult = DhcpApi.DhcpGetClientInfo(ServerIpAddress, ref
searchInfo, out pClientInfo);
if (DHCPResult == 0 && pClientInfo != IntPtr.Zero)
{
DHCP_CLIENT_INFO clientInfo =
(DHCP_CLIENT_INFO)Marshal.PtrToStructure(pClientIn fo,
typeof(DHCP_CLIENT_INFO));
...
}
Thank you very much, that's got it working a treat. :o)

I can move on now, I'm sure I'll have more questions about this how
topic so watch this thread people!! ;o)

Cheers,

Richard
Sep 4 '06 #3
Mattias,

You mention in the thread 'Problem Creating Structures with P/Invoke'
that when using the struct DHCP_IP_ARRAY that you should dereference the
pointer to retrieve the addresses with Marshal.Copy().

I've been trying all morning to do it, but can't seem to get my head
round it. Could you offer some assistance again please? I get the code
below working but I'm trying to retrieve a list of the subnets returned
not just the number.

....
{
DHCP_IP_ARRAY ips = new DHCP_IP_ARRAY();
uint nr = 0, total = 0, resumeHandle = 0;

DhcpEnumSubnets("192.168.0.250", ref resumeHandle, 1000, ref ips,
ref nr, ref total);

Console.WriteLine("Elements read {0} of total {1}", nr, total);
}

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

[DllImport("dhcpsapi.dll", SetLastError = true, CharSet = CharSet.Unicode)]
public static extern uint DhcpEnumSubnets(
string ServerIP,
ref uint resumeHandle,
uint PerferedMax,
ref DHCP_IP_ARRAY ipAddresses,
ref uint ElementsRead,
ref uint ElementsTotal);

Cheers,

Richard
Sep 4 '06 #4
Richard,
>You mention in the thread 'Problem Creating Structures with P/Invoke'
that when using the struct DHCP_IP_ARRAY that you should dereference the
pointer to retrieve the addresses with Marshal.Copy().

I've been trying all morning to do it, but can't seem to get my head
round it. Could you offer some assistance again please?
Looks like it's pretty much the same issue as in your last post. The
parameter is actually a pointer to a pointer to the struct. So try it
like this:
>[DllImport("dhcpsapi.dll", SetLastError = true, CharSet = CharSet.Unicode)]
public static extern uint DhcpEnumSubnets(
string ServerIP,
ref uint resumeHandle,
uint PerferedMax,
out IntPtr ipAddresses,
ref uint ElementsRead,
ref uint ElementsTotal);
If the argument comes back non-null, you can use
Marshal.PtrToStructure or Marshal.Copy to retrieve the DHCP_IP_ARRAY
data.
Mattias

--
Mattias Sjögren [C# MVP] mattias @ mvps.org
http://www.msjogren.net/dotnet/ | http://www.dotnetinterop.com
Please reply only to the newsgroup.
Sep 4 '06 #5
Mattias,
Looks like it's pretty much the same issue as in your last post. The
parameter is actually a pointer to a pointer to the struct. So try it
like this:
>[DllImport("dhcpsapi.dll", SetLastError = true, CharSet = CharSet.Unicode)]
public static extern uint DhcpEnumSubnets(
string ServerIP,
ref uint resumeHandle,
uint PerferedMax,
out IntPtr ipAddresses,
> ref uint ElementsRead,
ref uint ElementsTotal);

If the argument comes back non-null, you can use
Marshal.PtrToStructure or Marshal.Copy to retrieve the DHCP_IP_ARRAY
data.
Thank you, I've got this bit working, although I had to work hard to get
it back into a decent format.

If there are any glaring mistakes then let me know, but the code below
does work for me. Also if any one has a better (more efficient method)
for converting the UInt32 IP Address back in to a dot notation IP
Address then please post here! ;o)

Now onto the next bit. Anyone got some pointers on searching for a
MAC/Hardware Address on the DHCP server using DhcpGetClientInfo? I can
retrieve the ClientInfo structure back if I search for the IP Address
but not if I use the hardware address or client name.

Code for others who search this thread, I'll stick it up on the
pinvoke.net (wiki) when I get a chance:

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

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

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

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];
}

Regards,

Richard
Sep 6 '06 #6

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

3
by: Leszek Gruszka | last post by:
How to get static IP adresses from DHCP?
5
by: Steve | last post by:
Hi Folks, I'm trying to create a c# class to manage a DHCP subnet using the win api (dhcpsapi.dll). Currently I can't even instanciate my class, instead I receive the error:...
3
by: jmd.msdn | last post by:
Hello. Is it possible to obtain programmatically, with .net 2.0 + C# + Active Directory or P/Invoke, a list of the authorized current DHCP servers in a forest/domain ? And, if the above...
2
by: WhatHappend | last post by:
I have converted a .Net 1.0 application to .Net 2.0 and the web service invocations have delay of around 10seconds on each intial access. After the first access subsequent access are fast (After a...
0
by: GHUM | last post by:
Hello, I need to get a list of active leases on a windows dhcp server. Experts from Microsoft statet: """" A: Go to the Address leases of each scope in the DHCP snap-in and dump the leases...
1
by: Screenbert | last post by:
After finding nothing anywhere in google I am posting this so everyone can benefit by it. The formating is not pretty since I copied it from my word document, but you should benefit by it. ...
0
by: screenbert | last post by:
Managing DHCP Servers using C# They said it was impossible. It couldn't be done. But you can in fact manage DHCP servers using C#. This includes creating and deleting Scopes, SuperScopes,...
7
by: ixeye | last post by:
Anybody else ever had a problem like this? Windows 2003 Domain with 180 machines, 21 of them with XP SP2 Laptop Wireless access to the domain, on three different WIFI AP. Randomly (and luckily...
7
by: =?Utf-8?B?VGhlTWFkSGF0dGVy?= | last post by:
Quick q: If I open a socket on my computer and eventualy the dhcp changes the address of my computer, what happens? Will it drop the connection? Thanks in advance for any help on the topic.
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.