Udostępnij za pośrednictwem


All about the DHCP server callout API functions.

Ah now for the best part. I had always wanted to test this callout API thing. This is perhaps the most powerful way to leverage your Windows DHCP server. With the DHCP server callout, in a way, the whole DHCP server source code is before you for you to change and fine tune to your specific needs. In reality you really don't get the source code access but you do get all the power you would get had you really had the source code access. This is perhaps the best way to encourage people to build upon and extend your software's capability while still staying in the commercial realm and without throwing open the product's source code. I won't discuss the nitty-gritties of this callout technique as it has been properly documented here: DHCP Server callout API.

Possiblities unlimited:

Some of the exciting things that are possible with the DHCP Callout DLL:
1) Create a parallel lease database in your favorite DB say SQLServer. With this you get the power to monitor the leasing process in a very flexible way (say using SQL, you can run a query to list all those machines which got an IP address in the last 2 hours).
2) Create customized extensions to the DHCP server: This is a pretty loaded sentence. What this fact implies is that with the callout DLL, you can prevent giving IP address unless the client satifies some policy: like membership to a given user class or a given vendor class. This is pretty usefull if you want to enforce minimum security to your enterprise, just ensure that only the authenticaled users are let known the user class say 'xyz'. Now prevent leasing out IP address unless the client belongs to this user class. This can be done when you implement the function DhcpNewPktHook and set the ProcessIt flag to FALSE when you don't see the right user class in the Packet. For this you need to parse the packet which is a BYTE *. :-(

Now for the hard part: Even though this callout DLL support has been there for a while, I really don't see people using this. (Prove me wrong!) Even though the online documentation has clearly explained the technology in some good detail, there is no sample code which people can readily use. So here I am to give you exactly these: A sample implementation of the callout DLL and the registry settings to enable the callout DLL's functioning.

Sample Code:

//Mind you this is a very simple implementation of the callout DLL.

//Our callout function just logs the various states into a file (and that too incompletely..)

//But I guess you people should take it from here......

#include <windows.h>
#include <stdio.h>
#include "dhcpssdk.h"

FILE * CalloutFile;

DWORD CALLBACK DhcpAddressDelHook
(LPBYTE Packet,DWORD PacketSize,DWORD ControlCode,DWORD IpAddress,DWORD AltAddress,LPVOID Reserved,LPVOID PktContext)
{
return ERROR_SUCCESS;
}

DWORD CALLBACK DhcpAddressOfferHook
(LPBYTE Packet,DWORD PacketSize,DWORD ControlCode, DWORD IpAddress,DWORD AltAddress,DWORD AddrType,DWORD LeaseTime,LPVOID Reserved,LPVOID PktContext)
{
char PacketBuff[4096];
if(ControlCode==DHCP_GIVE_ADDRESS_NEW)
{
fprintf(CalloutFile,"Offering new address %x %d on interface %x for %d seconds\n",AltAddress,AltAddress,IpAddress,LeaseTime);
}
else if(ControlCode==DHCP_GIVE_ADDRESS_OLD)
{
fprintf(CalloutFile,"Offering old address %x %d on interface %x for %d seconds\n",AltAddress,AltAddress,IpAddress,LeaseTime);
}
if(PacketSize<4096)
{
memcpy(PacketBuff,Packet,PacketSize);
PacketBuff[PacketSize]='\0';
fprintf(CalloutFile,"Packet: %s\n",PacketBuff);
}
return ERROR_SUCCESS;
}

DWORD CALLBACK DhcpControlHook(DWORD dwControlCode,LPVOID lpReserved)
{
switch (dwControlCode)
{
case DHCP_CONTROL_START:
{
CalloutFile=fopen("callout.txt","w");
fprintf(CalloutFile,"The DHCP server has successfully started.\n");
break;
}
case DHCP_CONTROL_STOP:
{
fprintf(CalloutFile,"The DHCP server has successfully stoped.\n");
fclose(CalloutFile);
break;
}
case DHCP_CONTROL_PAUSE:
{
fprintf(CalloutFile,"The DHCP server has been paused.\n");
break;
}
case DHCP_CONTROL_CONTINUE:
{
fprintf(CalloutFile,"The DHCP server has been continued.\n");
break;
}
}
return ERROR_SUCCESS;
}

DWORD CALLBACK DhcpDeleteClientHook(DWORD IpAddress, LPBYTE HwAddress,ULONG HwAddressLength, DWORD Reserved,DWORD ClientType)
{
return ERROR_SUCCESS;
}

DWORD CALLBACK DhcpNewPktHook(LPBYTE* Packet,DWORD* PacketSize,DWORD IpAddress,LPVOID Reserved,LPVOID* PktContext,LPBOOL ProcessIt)
{
return ERROR_SUCCESS;
}

DWORD CALLBACK DhcpPktDropHook(LPBYTE* Packet,DWORD* PacketSize,DWORD ControlCode, DWORD IpAddress,LPVOID Reserved,LPVOID PktContext)
{
return ERROR_SUCCESS;
}

DWORD CALLBACK DhcpPktSendHook(LPBYTE* Packet,DWORD* PacketSize,DWORD ControlCode,DWORD IpAddress,LPVOID Reserved,LPVOID PktContext)
{
return ERROR_SUCCESS;
}

DWORD CALLBACK DhcpServerCalloutEntry(LPWSTR ChainDlls,DWORD CalloutVersion,LPDHCP_CALLOUT_TABLE CalloutTbl)
{
CalloutTbl->DhcpAddressDelHook=DhcpAddressDelHook;
CalloutTbl->DhcpControlHook=DhcpControlHook;
CalloutTbl->DhcpDeleteClientHook=DhcpDeleteClientHook;
CalloutTbl->DhcpPktDropHook=DhcpPktDropHook;
CalloutTbl->DhcpAddressDelHook=DhcpAddressDelHook;
CalloutTbl->DhcpNewPktHook=DhcpNewPktHook;
CalloutTbl->DhcpPktSendHook=DhcpPktSendHook;
return ERROR_SUCCESS;
}

The DHCP callout Cookbook:
1) After writing your program for creating the callout DLL, make sure that your DLL exports the functions DhcpServerCalloutEntry, DhcpAddressDelHook, DhcpControlHook, DhcpPktDropHook, DhcpAddressDelHook, DhcpNewPktHook and DhcpPktSendHook. These functions should be GetProcAddress'able once the DHCP Server LoadLibrary's your DLL. Otherwise you would be seeing the event 1034 logged on to your system event log.
2)One more thing, to compile this code you should be needing the Platform SDK. This is required as the header file which contains all the relevant callout data structures, dhcpssdk.h comes along with the Platform SDK. Don't forget to set your compiler's include path to the place where dhcpssdk.h is copied.
3) Last but not the least once you have created the DLL, you can copy it to any place (say c:\callout\callout.dll) in your Windows server (Windows Server 2003 or Windows 2000 Server.)
4) Now comes the registry nibbling part. As usual backup your registry. The following are the two registry entries which should be created and which are located within:
HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\DHCPServer\Parameters
1)
Name : CalloutDlls
Value : list of path/filenames for the dlls to be loaded. In our case it is c:\callout\callout.dll
Type : REG_MULTI_SZ
2)
Name : CalloutEnabled
Value :
0 = DHCP Server does not attempt load of callout.dlls
1 = DHCP Server attempts to load callout.dlls
Type : DWORD
BTW, This information is not available in the MSDN.
Now restart the DHCP service. If everything went well you should see the event 1033 logged on in your system event log: "The DHCP service has successfully loaded one or more callout DLLs." Congrats!

Comments

  • Anonymous
    February 25, 2005
    The comment has been removed
  • Anonymous
    February 26, 2005
    The comment has been removed
  • Anonymous
    February 26, 2005
    The comment has been removed
  • Anonymous
    February 27, 2005
    I have an idea that should work in theory.

    I want to give a scope to all authorized computers and a private scope to all others.

    The computers will exist on the same physical network, but on different subnets.

    I do have a reason for my madness
  • Anonymous
    March 01, 2005
    The comment has been removed
  • Anonymous
    March 10, 2005
    Hi,

    I've just read your article http://weblogs.asp.net/anto_rocks/archive/2005/02/25/380510.aspx, I built the dll from your source code and installed it on my server, sure enough up popped the event number 1033, it seemed that everything went well. Now I paused, and resumed my server, to check it was working correctly, but the text file callout.txt remained blank. I've also been playing with DhcpEnumSubnetClients, with equally low success rates. Both your dll and the code I wrote to make use of the DhcpEnumSubnetClients function look like they should work, but both are returning nothing.

    Is there something that I need to install on my server? (it's a windows 2003 server, if that makes any difference) Is there a redistributable or some such that I need to install?

    Any help would be gratefully received.
    Regards,
    Rob
  • Anonymous
    March 10, 2005
    You do not need anything further than a Win2K3 server. I assume the file was created by the DHCP server but you don't see anything there. I don't get understand why this should be happening. Maybe we are missing something. Did u change the registry? Maybe there is someone else in the blogosphere who can help Rob??
  • Anonymous
    March 18, 2005
    This is what I obtained. Can you explain this?

    Value obtained from file system volume descriptor pointer: 0x347cb00
    The old setting was THU JAN 01 00:00:00 1970
    Accepted system dates are greater than THU DEC 27 00:00:00 1990
    ramdrv:/ - Volume is OK
    tffsdrv: DOS mounting Complete
    tffsdrv:/ - Volume is OK

    nvdrv: DOS mounting Complete
    nvdrv:/ - Volume is OK

    0x34b97c8 (tStartup): WARNING: RAM db is deleted
  • Anonymous
    May 23, 2005
    RePost:
    http://www.yeyan.cn/Programming/DHCPServerAPIfunctions.aspx
  • Anonymous
    May 23, 2005
    check out this: http://blogs.msdn.com/anto_rocks/archive/2005/05/24/421353.aspx
  • Anonymous
    May 30, 2005
    Does anyone know how to dissect the lpbyte packet parameter and get the hostname requesting the IP address?

    Thanks.
  • Anonymous
    June 06, 2005
    The comment has been removed
  • Anonymous
    December 21, 2005
    Hello,

    I'm lucky to find the article and the web site. It is very useful for me to develop an external dll of a DHCP server.

    I am planing to reject to offer address to some machine. How can I do it?

    Thanks
  • Anonymous
    January 04, 2006
    well, DhcpNewPktHook may fit your needs,

    set the (LPBOOL ProcessIt) flag with FALSE, DHCP will drop the packet, you can add your own judgement to process it. be care LPBOOL. it is a point;
  • Anonymous
    February 22, 2006
    Very nice blog!
  • Anonymous
    March 24, 2006
    I want to assign IPs from a different pools depending on the network card.

    I have a W2K3 server with 4 network cards and I want a range of IPs for every card. I conect a group of clients to every card and I can know what group of clients belong with the IP of the client in a proxy application.

    I can make the DLL in VS2005 C#?

    GREAT!!!
  • Anonymous
    April 04, 2006
    I ave included the callout.dll in windows2003 server.everthing sems to be fine but the dll is not able to log the messages when a new client request for an ipaddress from DHCP server.

    please help
  • Anonymous
    May 09, 2006
    Hi
    Dear
    I want to use your method that is a very good
    way to have an extention to DHCP
    But when I make this DLL in VC++.Net 2003 and make regitery changes I have a very bad Error
    1034 : The sepscified procedure could not bE found
    My server Is Win 2003
    and i dont know exactly where i should paste your code sample
    I make an Class Lib in VC++.Net 2003 and paste the sample code in cpp file what is wrong
    Please Help Me?
    Please
    Best regards
    Meenavee
  • Anonymous
    June 10, 2006
    I have taken a looka t using the DHCP call out but I need some assistants in tryin to determine how to manipulate the response. I understan I need to modify the packet contents before being sent. Again I think I need to use the call out DhcpNewPktHook. I can not figure out how to refrenece the portion of the packet?
    Any quick sample on how to make this call? or perhaps does someone know who might help. All I want is help on changing various response fields such as gateway & mask values. Please help I am my witts end.

    Cheers,
    Scrappy
  • Anonymous
    June 15, 2006
    I work at an ISP and I am trying to use these API functions to migrate our DSL Customers from Static IP's to DHCP. In order for me to sell this the transition must be seamless. Our Router will append Option 82 which contains the ATM Virtual Circuit that is assigned to the customer. I have a working DLL that will disect the packet and get the Virtual Circuit information out, and then it will Query our MySQL database to reference ther Virtual Circuit to there old Static IP. Now all I need to do is send the IP that I get from the Database, how can I do this, should I use DHCPPacketSendHook?
  • Anonymous
    July 17, 2006
    Hi, this is certainly the most useful BLOG on the subject. Thanks Anton.

    Is it possible to hook into the server callout functions using c#.net or vb.net? Is so , how do I call it?

    phil
  • Anonymous
    August 27, 2006
    The comment has been removed
  • Anonymous
    December 18, 2006
    Ah now for the best part. I had always wanted to test this callout API thing. This is perhaps the most powerful way to leverage your Windows DHCP server. With the DHCP server callout, in a way, the whole DHCP server source code is before you for you to change and fine tune to your specific needs. In reality you really don't get the source code access but you do get all the power you would get had you really had the source code access. This is perhaps the best way to encourage people to build upon and extend your software's capability while still staying in the commercial&nbsp;realm and without throwing open the product's source code.&nbsp;I won't discuss the&nbsp;nitty-gritties of this callout technique as it has been properly documented&nbsp;here: DHCP Server callout API.I do not agree. Go to http://www.hotelsmall.info/laurel_Italy/abstruse_Lombardia/gimp_Milan_1.html
  • Anonymous
    January 16, 2007
    Ah now for the best part. I had always wanted to test this callout API thing. This is perhaps the most powerful way to leverage your Windows DHCP server. With the DHCP server callout, in a way, the whole DHCP server source code is before you for you to change and fine tune to your specific needs. In reality you really don't get the source code access but you do get all the power you would get had you really had the source code access. This is perhaps the best way to encourage people to build upon and extend your software's capability while still staying in the commercial&nbsp;realm and without throwing open the product's source code.&nbsp;I won't discuss the&nbsp;nitty-gritties of this callout technique as it has been properly documented&nbsp;here: DHCP Server callout API.I do not agree. Go to http://www.myromehotel.info/toll_France/caisson_Pays%20de%20la%20Loire/crayon_La%20Baule_1.html
  • Anonymous
    May 03, 2007
    Great post. The MSDN documentation on this stuff is ok, but it contains a flaw in not telling us that the registry value required is "CalloutDlls". Without that info no-one is going to be able to use this stuff, and this is the only place I was able to find it.
  • Anonymous
    August 06, 2007
    Has anyone managed to use DHCPPacketSendHook or DhcpNewPktHook to modify the packet and add more options for example. I understand the API reasonably well, however it isn't obvious how to handle memory allocation/freeing etc when extending the packet. Has anyone done this?
  • Anonymous
    August 14, 2007
    Ah now for the best part. I had always wanted to test this callout API thing. This is perhaps the most powerful way to leverage your Windows DHCP server. With the DHCP server callout, in a way, the whole DHCP server source code is before you for you to change and fine tune to your specific needs. In reality you really don't get the source code access but you do get all the power you would get had you really had the source code access. This is perhaps the best way to encourage people to build upon and extend your software's capability while still staying in the commercial&nbsp;realm and without throwing open the product's source code.&nbsp;I won't discuss the&nbsp;nitty-gritties of this callout technique as it has been properly documented&nbsp;here: DHCP Server callout API.I do not agree. Go to http://apartments.waw.pl/
  • Anonymous
    December 29, 2007
    Hi,The good work. I am researching DHCP for detect new computer when plug in LAN, so You could share your code to me .Thanks very muchRegards,
  • Anonymous
    December 29, 2007
    My email: vuongkimson@gmail.com
  • Anonymous
    March 26, 2008
    Is there a way not to allow the dhcp server to assign an IP to a machine until you make a reservation for the machine, without using the call out api?for example, on a Linux machine, you can configure the Linux DHCP server with option "ignore unknown-clients" to forbid the server assign IPs to unknown machines.ThankDave
  • Anonymous
    January 20, 2009
    PingBack from http://www.hilpers-esp.com/387544-concesion-direcciones-por-dhcp
  • Anonymous
    April 07, 2010
    the asp.net C# code for the code you written in C
  • Anonymous
    January 07, 2014
    The comment has been removed