Developed a DHCP client simulation tool sometime back. The tool can be used for testing DHCP server which are part of networking devices such as routers, IP DSLAM, etc.
The tool needs a linux environment with root login since it uses promiscuous sockets for sending and receiving DHCP packets.
Download link – dhtest.tgz (Legacy code)
Latest code – Github repo : https://github.com/saravana815/dhtest
Github download link: https://github.com/saravana815/dhtest/archive/master.zip
Basic usage
root@sargandh-laptop:/home/sargandh/Desktop/dhtest-1.1# ./dhtest
Usage: ./dhtest [ options ] -m mac_address
-r, –release # Releases obtained DHCP IP for corresponding MAC
-I, –option50-ip [ IP_address ] # Option 50 IP address on DHCP discover
-o, –option60-vci [ VCI_string ] # Vendor Class Idendifier string
-v, –vlan [ vlan_id ] # VLAN ID. Range(2 – 4094)
-t, –tos [ TOS_value ] # IP header TOS value
-i, –interface [ interface ] # Interface to use. Default eth0
-T, –timeout [ cmd_timeout ] # Command returns within specified timout in seconds
-b, –bind-ip # Listens on the obtained IP. Supported protocols – ARP and ICMP
-k, –bind-timeout [ timeout ] # Listen timout in seconds. Default 3600 seconds
-f, –bcast_flag # Sets broadcast flag on DHCP discover and request
-V, –verbose # Prints DHCP offer and ack details
dhtest version 1.1
root@sargandh-laptop:/home/sargandh/Desktop/dhtest-1.1# ./dhtest -m 00:00:11:22:33:44
DHCP discover sent – Client MAC : 00:00:11:22:33:44
DHCP offer received – Offered IP : 10.0.2.16
DHCP request sent – Client MAC : 00:00:11:22:33:44
DHCP ack received – Acquired IP: 10.0.2.16
root@sargandh-laptop:/home/sargandh/Desktop/dhtest-1.1# ./dhtest -m 00:00:11:22:33:44 -V
DHCP discover sent – Client MAC : 00:00:11:22:33:44
DHCP offer received – Offered IP : 10.0.2.16
DHCP offer details
———————————————————-
DHCP offered IP from server – 10.0.2.16
Next server IP(Probably TFTP server) – 10.0.2.4
Subnet mask – 255.255.255.0
Router/gateway – 10.0.2.2
DNS server – 72.163.128.140
DNS server – 171.70.168.183
Lease time – 1 Days 0 Hours 0 Minutes
DHCP server – 10.0.2.2
———————————————————-
DHCP request sent – Client MAC : 00:00:11:22:33:44
DHCP ack received – Acquired IP: 10.0.2.16
DHCP ack details
———————————————————-
DHCP offered IP from server – 10.0.2.16
Next server IP(Probably TFTP server) – 10.0.2.4
Subnet mask – 255.255.255.0
Router/gateway – 10.0.2.2
DNS server – 72.163.128.140
DNS server – 171.70.168.183
Lease time – 1 Days 0 Hours 0 Minutes
DHCP server – 10.0.2.2
———————————————————-
root@sargandh-laptop:/home/sargandh/Desktop/dhtest-1.1#
March 20, 2012 at 6:28 pm
Marvelous! Works like a charm on Mint 9, this was just what I was looking to troubleshoot a DHCP issue. Thanks a lot for sharing!
August 29, 2012 at 1:45 pm
perfect!
September 24, 2012 at 8:12 pm
Perfect for testing dhcp server, thanks!
November 12, 2012 at 7:27 am
i so wish this would test option 66 and 67 and report what the dhcp server sent back. i’m going crazy trying to figure out how to do that.
January 14, 2013 at 1:24 pm
Hi, this is really what I’ve been looking for but it doesn’t work all way. The release part fails to send the packet…
root@dhcpstorm:/usr/local/src/dhtest-1.1# ./dhtest -m 00:dd:02:11:55:08 -i eth1.1000 -f
DHCP discover sent – Client MAC : 00:dd:02:11:55:08
DHCP offer received – Offered IP : 10.254.200.99
DHCP request sent – Client MAC : 00:dd:02:11:55:08
DHCP ack received – Acquired IP: 10.254.200.99
root@dhcpstorm:/usr/local/src/dhtest-1.1# ./dhtest -m 00:dd:02:11:55:08 -i eth1.1000 -f -r
Paket send failure: Socket operation on non-socket
Tried to look into the code but C is not my cup of tea. Running on Ubuntu. Any ideas?
January 15, 2013 at 11:40 am
Hi JM,
I tried almost the same arguments on my system and it works.
[root@CentOS dhtest-1.1]# ./dhtest -m 00:dd:02:11:55:08 -f
DHCP discover sent – Client MAC : 00:dd:02:11:55:08
DHCP offer received – Offered IP : 10.142.98.105
DHCP request sent – Client MAC : 00:dd:02:11:55:08
DHCP ack received – Acquired IP: 10.142.98.105
[root@CentOS dhtest-1.1]# ./dhtest -m 00:dd:02:11:55:08 -f -r
DHCP release sent – Client MAC : 00:dd:02:11:55:08
The only difference I see is the use of vlan interface for getting and releasing the IP address.
Instead of trying the vlan interface, can you specify the vlan id for the tool itself
like ./dhtest -m 00:dd:02:11:55:08 -f -v 1000 and ./dhtest -m 00:dd:02:11:55:08 -f -r -v 1000
January 15, 2013 at 2:13 pm
I downgraded to Ubuntu 10 from Ubuntu 12 and then release works fine. Any plans for “DHCP renew”? Would be really nice to have.
Cheers, //JM
January 16, 2013 at 2:22 pm
Hi JM,
I am not working on this tool for a long time, so plans to add/improve the tool as of now. 🙂
Regards,
Saravana
March 5, 2013 at 3:47 am
How do you make it send multiple DHCP requests using this tool to test a DHCP server?
March 5, 2013 at 11:14 am
For every DHCP request, run the tool with different mac address as a background process.
Ex.
./dhtest -m 00:00:11:22:33:44 &
./dhtest -m 00:00:11:22:33:45 &
The better way is to write a shell script and iterate through mac address field.
March 14, 2013 at 8:43 pm
For multiple parallel calls you should slightly alter “set_rand_dhcp_xid” function, so that you don’t get the same xid if several calls occur in the same second.
For instance, change :
srand(time(NULL));
To :
srand(time(NULL) ^ (getpid()<<16));
Regards,
Nicolas.
March 15, 2013 at 6:30 pm
Hi Nicolas,
Thanks for the info and updated the set_rand_dhcp_xid function.
– srand(time(NULL));
+ srand(time(NULL) ^ (getpid() << 16));
dhcp_xid = rand() % 0xffffffff;
Regards,
Saravana
March 12, 2013 at 8:51 pm
Hello,
Thanks for sharing this tool which proved very handy 🙂
Just a note : on Linux Red Hat (build with gcc 4.1.2), it doesn’t work as is (seg faults on call to inet_ntoa).
I had to change the following:
1) add the following include:
#include
2) change all inet_ntoa calls, for instance :
/*fprintf(stdout, “DHCP offered IP from server – %s\n”, inet_ntoa(dhcph_g->dhcp_yip));*/
struct in_addr ipaddr;
ipaddr.s_addr=dhcph_g->dhcp_yip;
fprintf(stdout, “DHCP offered IP from server – %s\n”, inet_ntoa(ipaddr));
Regards,
Nicolas.
March 13, 2013 at 5:28 pm
Hi Nicolas,
Thanks for sharing the info.
I am having cent os 5 with gcc 4.12 and could not see any segmentation fault with verbose enabled.
Yes, the header file arpa/inet.h is not included and I don’t know how it got missed. May be since calls the atoi, inet_ntoa calls worked simply without inet.h
I am suspecting it might be due to platform. My VM is 32 bit x86 and i think you might be using 64 bit.
Regards,
Saravana
March 14, 2013 at 8:35 pm
Thank you for your answer.
Indeed, I’m using a 64 bit x86 as test client.
June 14, 2013 at 4:32 pm
Could you send me a working source or binary?
Regards
Gerold
June 17, 2013 at 11:48 am
Hi, The download links given on the page contains the updated source and initial source. This binary may not work if you are trying to use the tool on 64 bit system. The code needs some changes for 64 bit system.
http://www.mediafire.com/download/6k277w1rtby6xvn/dhtest-linux-1.1.tgz
Regards,
Saravana
May 12, 2013 at 11:16 pm
[…] https://sargandh.wordpress.com/2012/02/23/linux-dhcp-client-simulation-tool/ […]
October 16, 2013 at 7:39 pm
Hi,
Noticed that function.c doesn’t recognize DHCP-OFFER packet type if Broadcast flag=1 in the packets from server.
Trying to handle. If somebody know the solution will appreciate.
Thanks.
October 16, 2013 at 7:59 pm
Hi Alex,
There is no check based on broadcast flag AFAIK for receiving DHCP offer or any DHCP msg from server. Something else might be the issue.
Regards,
Saravana
October 16, 2013 at 9:26 pm
Hi Saravana,
Thanks for the fast response!
I dumped the packets during client – server exchange with BF=0 and BF=1. In the first cause everything passed well. When i received DHCP-OFFER with BF=1 DHCP-REQUEST was not generated according to the capture. Also i noticed that the packets length are different in this two causes, 342B and 336B respectively.
Maybe this is the reason.
Very useful utility but can’t use in my test environment.
Thanks!
October 23, 2013 at 10:40 am
Hi Sargandh,
Thanks for this tool. Couple of questions:
– You mentioned some changes needed for 64-bit machine. Do you have linux version of that?
– Can I give a range of mac address (e.g. 00:11:22:33:44:55 to 00:11:22:33:66:77 ) to test
client scale?
Kazi
October 25, 2013 at 4:28 pm
Hi kazi,
Can you try the latest version from github for 64 bit machine? I hope it works.
Currently the command line can take only a single mac address. One way to do the mac address scale is to create a bash script and run the tool for each mac address inside the script.
Regards,
Saravana
November 18, 2013 at 8:02 pm
I just tried the latest github version on 64bit Ubunto 12.04.3 and it worked perfectly. Thanks – very handy utility!
November 25, 2013 at 9:24 pm
Sure…Thanks
November 26, 2014 at 12:06 pm
Hi,
Anyone has the script to test with multiple MAC address?
November 27, 2014 at 10:35 am
It is very simple. You can do that in a single bash command.
for ((i=0;i<=255;i++)); do m=`printf %02x $i`; ./dhtest -m 00:00:11:22:33:$m; done
January 16, 2014 at 2:28 pm
I wanted to configure a DCHP server only on eth1 and not eth0 interface (for secure goals). This tols provided the solution in testing and configuraing the dnsmasq configuration file. Very well written code, indeed
DHTEST running on an old 2.6.18.xx kernel from Suse 10.2 (32b)
Kudos !
Cheers
—
michel marcon (aka cmic)
November 10, 2014 at 7:49 pm
Hey, excellent tool for DHCP monitoring and error solving. Thanks!!!
February 2, 2015 at 1:07 pm
Sarvanan,
Thanks , Its a very useful tool.
Do you have plans to make it available for IPV6 DHCP ? 🙂
Regards,
Sibi Alex Jacob
February 2, 2015 at 2:26 pm
Hi Sibi Alex Jacob,
I have noted few new features including IPv6 for the tool which are very useful. But currently not doing any new changes to the tool.
May be on best effort basis.
Regards,
Saravana
July 9, 2015 at 3:19 pm
Works perfectly on Ubuntu (12.4 and 14.4). Thank you very much!
August 10, 2015 at 4:59 pm
Thanks alot. this was of a big help for me
April 7, 2016 at 4:43 pm
hi can we send individual message using this tool, like i want to send only dhcp ack or dhcp decline message individual without sending discover., request messages, if possible tell me way how to do it
April 13, 2016 at 10:41 am
Hi Chetan,
If you want to send individual messages, then you can use libnet which will be much better than changing this code.
https://github.com/sam-github/libnet
http://libnet.sourceforge.net/
https://sourceforge.net/projects/libnet/
Regards,
Saravana
January 20, 2017 at 8:53 pm
I may not have the proper use case for this tool. I want to use it to detect a rogue DHCP-server.
The machine already acquired an IP, but I just want to make a DHCP-request with some fantasy MAC and then I want to detect a rogue DHCP-server. I don’t want it to act upon the OFFER, I just want to see the IP/MAC of the device that’s offering me one.
If I run this tool with another MAC than its own, I’m not getting any offers.
It seems this tool isn’t made for that.
I would really like to have such a tool
January 23, 2017 at 10:21 am
Hi,
The tool can be run with any mac-address. But it is upto the server to reply with the offer. In your case, I think the server is doing mac-address check and could be due do that the server replies for the actual mac address.
If you are not concerned about the dhcp state machine, then you can use libnet library to send individual dhcp packets.
libnet link – http://libnet.sourceforge.net/
Regards,
Saravana
March 12, 2017 at 2:58 pm
Hi all,
Idownloades the latest code from git, and tried dhtest with the new kea dhcp Server from ISC. a dhcpdump showed kea server is sending an offer, but dhtest did not show the offer packet.
exactly the same setup, using the old isc-dhcp and dttest dhtest did work perfect.
dhclient and kea server do work perfect too. doen with vmware and debian.
any ideas?
BR Martin
March 15, 2017 at 11:08 am
Hi Martin,
We need to see the DHCP offer packet contents to know why the offer packet is getting dropped.
You can share the packet capture details.
Regards,
Saravana
March 15, 2017 at 1:59 pm
Hi Saravana,
check out https://www.mycloud.ch/s/S005FFAA7751D1108C723BF6DEEB50583BE205367311665BF8308F38A12D25F4 this is a zip with two pcaps.
dhcp server:192.168.1.1, the client requests an IP and 192.168.1.40 is offered. The first setup is done with the traditional isc DHCP, the seconed with kea dhcp.
BR
Martin
March 15, 2017 at 3:15 pm
There is a problem with the way dhtest processes DHCP options. After analyzing the code, I understood there are false assumptions about positioning of option message type. There is no predefined order about DHCP options. The check_packet() function wrongly assumes message type is placed at (dhopt_pointer_g + 2).
The order of serializing DHCP options differs in Kea implementation.
March 16, 2017 at 7:06 pm
Hi Hossein,
Yes, the tool assumes the DHCP message type as the first option and hence it fails in cases where DHCP message type option is placed as non first option. Thanks for pointing this. Will try to fix this.
Regards,
Saravana
March 17, 2017 at 12:52 am
cool, thanks, looking forward to test a new version. 🙂
March 20, 2017 at 11:09 am
Hi Martin,
You can check the tool with the modified changes and reply with your results.
http://www.mediafire.com/file/mifemdt3cq92dd9
Regards,
Saravana
March 25, 2017 at 11:40 pm
Hi Saravana,
a short initial test was sucessfull. I got a full assignment of an IP within the most simple usecase ./dhtest -m , I will do some additional Tests within the next days.
BR Martin
April 3, 2017 at 4:16 pm
Hi Saravana,
I did some additional Tests, adding custom attributes, works perfect.
Thanks.
Martin
April 6, 2017 at 11:14 am
Hi Martin,
Thanks for verifying the changes. Will commit the changes to git repo.
Regards,
Saravana
May 19, 2017 at 12:43 am
Hi Saravana,
Is there a way for the tool to generate the DHCP packet where the client MAC specified on the CLI comes from the -m parameter but the source MAC of the actual packet on the wire comes from the host’s MAC and the destination MAC is either specified or maybe uses the destination MAC of the next hop router? I’m trying to have the generated request look like it is coming from a DHCP relay agent. I got close with:
./dhtest -m 00:11:22:33:44:00 -u -g 10.252.56.22 -S 10.255.14.199
Where the destination IP is the server IP specified and the source IP is the host IP. But the source MAC was the one from -m and the destination MAC was all ff’s.
Thanks,
Carl
May 19, 2017 at 7:24 pm
Hi Carl,
What you ask can be done certainly.
option #1 – Get the host mac address and gateway mac address from command line itself and use them. use dmac variable for destination mac and add a new variable for host_mac and use it as part of function build_dhpacket. This one is easy to implement. But for automated cases, this is not useful.
option #2 – Get the host mac using structure sockaddr_ll and nexthop mac address from arp table and use them. This needs more code.
If you are looking for quick fix, option #1 is easy and i think you can add them easily for your use.
Regards,
Saravana
May 24, 2017 at 1:48 am
Thanks Saravana. To confirm in option #1, are you saying use the current dmac variable (which is pulled in from the CLI using the -m switch) as the one to populate the outer packet and then new variable host_mac for the client mac address in the DHCP packet? Or the reverse of that?
Also, I see both dmac and dhmac being defined in the dhtest.c. What is dhmac defining?
Regards,
Carl
May 25, 2017 at 11:41 am
Hi Carl,
dmac variable is the broadcast mac (ffff.ffff.ffff).
int build_dhpacket(int pkt_type)
{
u_int32_t dhcp_packet_size = dhcp_hdr_size + dhopt_size;
if(!dhcp_release_flag) {
u_char dmac_tmp[ETHER_ADDR_LEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
memcpy(dmac, dmac_tmp, ETHER_ADDR_LEN);
}
dhmac is the client mac address used (used as l2 packet source mac address and as DHCP client mac address).
* So use the dhmac variable to populate the outer mac address (Inside DHCP header).
* Add two more command line argument. One for host/VM actual mac address and second for gateway mac address.
* Use host/VM mac address as L2 packet source mac and gateway mac as L2 packet dest. mac.
Try it yourself or otherwise I can add easily the option #1.
Regards,
Saravana
May 26, 2017 at 6:02 am
Thanks again Saravana. I see how it works now and have made the changes I needed!
December 28, 2017 at 9:09 am
Hi Saravana,
I need to perform load testing on dhcp server with random mac addresses as you are passing static mac address in the argument, so how can i achieve that with the help of this.
Regards,
Vishnu
January 2, 2018 at 12:51 pm
Hi Vishu,
You need to use a random number generator on bash and convert the random number number to mac address format and use it along with dhtest command.
https://www.eduonix.com/blog/shell-scripting/generating-random-numbers-in-linux-shell-scripting/
https://unix.stackexchange.com/questions/140750/generate-random-numbers-in-specific-range
Regards,
Saravana
January 5, 2018 at 10:28 am
Thanks Saravana
Great script.
January 4, 2018 at 1:44 pm
Hi Saravana,
Thanks for your tool ! Very usefull.
We need to use it with an interface on wich we put on multicast (ip link set eth3.300 multicast on).
Then “ip link show eth3.300” shows :
6: eth3.300@eth3: mtu 1500 qdisc noqueue state UP link/ether e4:11:5b:9a:0f:8f brd ff:ff:ff:ff:ff:ff
Then we try dhtest with this : dhtest -i eth3.300
We’ve got this answer so dhtest work well :
DHCP discover sent – Client MAC : e4:16:5d:9a:0f:8e
DHCP offer received – Offered IP : 192.168.222.10
DHCP request sent – Client MAC : e4:16:5d:9a:0f:8e
DHCP ack received – Acquired IP: 192.168.222.10
But when we check again our interface configuration with “ip link show eth3.300” we got :
6: eth3.300@eth3: mtu 1500 qdisc noqueue state UP
link/ether e4:11:5b:9a:0f:8f brd ff:ff:ff:ff:ff:ff
We can see that MULTICAST configuration is dropped when we use dhtest.
Can you reproduce this ?
Thanks for your help.
Regards,
January 5, 2018 at 12:12 pm
Hi Ludovic,
The dhtest tool is not going to touch or modify any configs set on the interface. This is a tool to simulate a virtual dhcp client.
Regards,
Saravana
April 4, 2018 at 6:54 pm
I have added option55 request parameters. Do you want me to send you a patch? In what way do you accept contributions?
April 5, 2018 at 2:24 pm
Hi Rok,
The project is already listed in github. github.com/saravana815/dhtest
You can send me a pull request or share the patch.
Regards,
Saravana
May 28, 2018 at 4:35 pm
Hi Saravana,
How are you ? the tools is perfect ! you did a great job ! I have an issue because I need to run it on windows using cygwing64 and it doesn’t work ! one problem is that I need to make it and it failed…. missing some libraries !! any comments or suggestions ??
Cheers
Ricardo
May 29, 2018 at 12:30 pm
Hi Ricardo,
The initial dhtest code had the support for cygwin environment also. But somehow, i left the cygwin dhtest code and used only linux for further dhtest changes. If possible, i will try to merge the cygwin specific dhtest code to mainly dhtest code that is present on github.
Added the cygwin dhtest code on – http://www.mediafire.com/file/f7jg3x2wa5x7g8g/dhtest-cygwin-1.2.tgz
It has a readme file on how to build the code. You need winpcap library.
Regards,
Saravana
January 21, 2019 at 7:43 pm
Hi Saravanan,
Fantastic tool and thank you for providing.
I am trying to send a list for option 55, but I see by default there is a predefined list (011c030f06) which results in two sets of option 55 being sent. Is there any way to disable the default option list being sent?
Also I am trying to include option 61 being the client identifier but wondering what the syntax is? I tried ‘-c 61,hex,112233445566’ but this didn’t seem to work.
Thanks for the help
January 21, 2019 at 8:04 pm
I figured the option 61 part. I needed to include 01 infront being for hardware type. So now looks like
-c 61,hex,01112233445566
February 5, 2019 at 11:12 pm
I used to be recommended this web site through my cousin. I’m not certain whether or not this publish is written through him as no one else recognize such targeted about my trouble. You’re wonderful! Thanks!
February 11, 2019 at 4:32 am
Good day! I just wish to give a huge thumbs up for the nice information you might have right here on this post. I might be coming again to your blog for more soon.