DHCP and DNS for Arduino

For anyone experimenting with the Internet of Things with Arduino one of the bigger missing pieces in the standard Arduino distribution is the lack of DHCP and DNS. DHCP means you don't have to hard-code the IP address of your Arduino, it can just ask the nearest router to give it one, and DNS lets you connect to sites by providing the domain name (e.g. www.mcqn.com) rather than having to find the IP address (e.g. 80.82.118.27).

For the past eighteen months or so, I've been using Jordan Terrell's DHCP library, coupled with the DNS client that I've written, and which has been available on the MCQN googlecode site.

It's always been my intention to help get these pretty essential parts of the Ethernet library moved into the official distribution, but client work had conspired to keep me too busy until recently.

Just as I was getting back to tidying up the rough edges on the code Arduino 0019 was released, which contained a much reworked Ethernet library which uses the SPI library. Unfortunately, that also broke both Jordan's DHCP code and my DNS client.

I've now finished porting both the DHCP (with Jordan's permission) and DNS code to the new Ethernet library, and will be working out if we can get it added to the official distribution over the coming weeks. In the meantime, it would be useful to get feedback on whether anyone has problems with it, and also provide it for people who want to use it.

To use it, unpack either the zip or the tar.gz file below into the arduino/libraries/ folder on your machine. Both the zip and the tar.gz contain the same files, I'm just providing two versions so you can choose your preferred compression type.

Ethernet-DHCP-DNS.zip
Ethernet-DHCP-DNS.tar.gz

There's a new example included, DNSExample, which shows how you'd modify the standard WebClient example to use both DHCP and DNS.

There have also been a few changes to the UDP code - it now supports more than one UDP instance (and doesn't have the global one defined, you'll need a "UdpClass Udp;" line in your sketch if you've been using it) and has extra methods to support sending and receiving large datagrams (which wouldn't otherwise fit into memory).

It has been tested on Arduino 0021 on Linux, but should work on any of the Arduino releases after 0018. If you use it I'd be grateful to hear details of how you get on and what systems you use it against (what router for example).

Hi, I have been following

Hi,

I have been following this thread with interest, do you have any news on the core portation?

Cheeers!

Hi Luis, The code has been

Hi Luis,

The code has been accepted into the core Arduino distribution (although there were a few API changes along the way) and will be in Arduino 1.0 when that is released.

Thanks for posting this

Thanks for posting this code! I have been searching for a DHCP and DNS library for the Arduino and this looks like the only one that is current.

I have downloaded the examples and tried running the DNSExample in both arduino-0021 and arduino-0022. In both cases the code hangs on the line: Dhcp.beginWithDHCP(mac)

I am not sure what I can do to trace down the issue, as I don't quite have the technical background of Xinantecatl. Any suggestions on how to trouble shoot this? Is the best way to debug the Dhcp.cpp file just to have it log everything it is doing to the serial port?

I am also curious how it is going to get these included in the core? I am following the requests on code.google.com for both of these to be included.

Thanks again for your work on this! It is going to make my Arduino projects much easier to maintain.

Hi Shawn, Do you ever get an

Hi Shawn,

Do you ever get an error from the Dhcp.beginWithDHCP(mac) line? When I'm debugging these sorts of problems I usually log things to the serial port. As long as you call Serial.begin(9600); before the calls to Dhcp.beginWithDHCP in setup then you can add Serial.print... lines in Dhcp.cpp to track things down.

Things are progressing with getting the code added to the core. I've got an implementation of both the DHCP and DNS changes on my fork of the Arduino code on github - https://github.com/amcewen/Arduino. Hopefully it will be in the next release.

Cheers,

Adrian.

Hello, Thanks to you for the

Hello,

Thanks to you for the DNS/DHCP libs.
I wanted to start writing my own libraries since the one I found were broken since 0019 version.Your's will spare me lot of time..

I haven't started to use it yet,but I will soon and tell you the results I have with it.

I have few cosmetic suggestions/questions concerning your libraries(after I've read it a bit):

You should write arguments in header's functions.The lack of them just make the whole library less readable/understandable.For example:
void getDnsServerIp(uint8_t*);
I think this should be written at least as in the main module:
void getDnsServerIp(uint8_t *dest);
That way,it's possible to know what the argument is without having to read the module.It's not a lazyness concern,it's just that a lot of people aren't top-notch programmers and since there's no documentation (except sources),it's just something that would make it easier to use the library.

I would remove the global Dhcp Object.I think it's better to have the programmer allocate it by himself(like you did for the udp object).

I would rename the "beginWithDHCP" method to just "begin".Since the object is clearly a Dhcp object,it would be more "standard" to have it named like that. Moreover,it would enforce the coherence between libraries.

Hope it doesn't bother you.
Thanks for the libs..Great work.

Hi Guillaume, I agree with

Hi Guillaume,

I agree with you on providing argument names, but it seems that in lots of the Arduino code they're omitted. I'm slowly adding them as I work through the code (and the DHCP code is mostly written by Jordan) but haven't done a complete pass through to add them.

When the DHCP code gets accepted into the core Arduino distribution it will be merged into the Ethernet class and will use begin rather than beginWithDHCP.

Cheers,

Adrian.

I really like DNS and DHCP

I really like DNS and DHCP with 021, thank you. Your library seems to have some behavior that was in the original Ethernet library that was fixed in Ethernet2. I learned that by working with Pachube. The client.connect in not reliable. Sometimes it connects and other times it does not. What is common is that when the shield will not connect the L led on the shield is dim. Later you can reset the Arduino and it will connect. Any ideas?

It is based on the original

It is based on the original Ethernet library, so that would explain why it has common behaviour. I hadn't realised there were fixes in Ethernet2 that hadn't been moved over to the core library. Do you know what the fixes are? It would be good to get them migrated over.

Adrian, I stumbled over this

Adrian,

I stumbled over this blog in search of a DHCP/DNS client for Arduino. I immediately downloaded your libraries, but had a hard time getting the DNS example to run.

I finally traced it down to UdpClass::readPacketData and UdpClass::readPacketByte. Both methods allow more data to be read than is available in the received UDP packet. As a side effect, the value of UdpClass::available() goes negative after reading more data than is available.

In my case, for some reason the DHCP library didn't call UdpClass::readPacketReachedEnd exactly when the whole packet was read and ended up in an infinite loop.

I also noted an issue in the DNS library. My DNS has 3 NICs, therefore multiple IP addresses. For each DNS query it picks one of the 3 IP addresses randomly as the server address in the DNS query answer. Therefore, for 2 out of 3 queries the address in the answer does not correspond to the address in the query. You have a check in there that results in a return code of -2 if the addresses do not match. Given the fact, that no other program on my network objects to my DNS setup, I removed this check in the DNS library and then finally the DNS example worked.

As an FYI, I am running DHCP and DNS on Mac OS X 10.5 Server.

Other than the issues above, the libraries work great and thanks for putting them out there.

Thanks for the feedback. I

Thanks for the feedback.

I think the reading more data than is available will be fixed by the changes in issue 416 of the core library, so once the DHCP/DNS code moves into the core (which I'm working on at the moment) it should be fixed.

It's quite possible that there are problems with the DNS client talking to slightly less ordinary setups, as I haven't been able to test it against lots of different systems, so thanks for taking the time to let me know what you've found.