Quick-and-Dirty IPv4 Link-Local Addressing

Often developers making low-cost network hardware products implement DNS-Based Service Discovery and Multicast DNS because the benefits are clear and obvious, but decide to forego IPv4 Link-Local addressing, because, "it doesn't do anything that you can't already do with a DHCP server." They will say, "In our target market there will always be a DHCP server on the network." This faulty logic stems I think from two factors: understimating the benefit of Link-Local addressing, and overestimating the cost of implementing it:

The Benefit

If you use a crossover Ethernet cable to connect two devices, then if the devices don't implement link-local addressing (assuming instead that there will always be a DHCP server on every network) then you end up in the sad situation of having two devices that are perfectly well connected physically, but unable to communicate using IP due to a mere limitation of software. Most modern Ethernet chips implement automatic crossover detection, so these days you don't even need the special crossover cable to connect two devices. For many years Mac OS and Windows have both implemented IPv4LL, so this message is really aimed at all the developers making all the devices that connect to them. Either IPv6 or IPv4 link-local addressing solves this problem, but since most low-cost devices that don't yet implement IPv6, IPv4LL is the simple pragmatic solution in today's world.

If this seems like an imagined scenario, consider this: it's already real. Every network printer sold today from every major printer vendor already implements IPv4LL and the other Zeroconf protocols (DNS-SD and mDNS). If you connect your laptop computer to the printer over Ethernet, the printer just magically shows up in the print dialog (on the Mac) or in the Bonjour for Windows Printer Setup Wizard (on Windows). We shouldn't even find this surprising. We should expect this ease-of-use from all network devices. You can connect a printer to your computer with a USB cable and have it work. Why shouldn't TCP/IP over Ethernet work just as well as USB?

With the prices of 802.11 wireless chipsets continuing to fall while the speed and range improves, and no "Wireless USB" products anywhere to be seen, TCP/IP over 802.11 becomes the natural substitute for a wireless USB connection. As with the Ethernet example above, this is also true today with printers. A typical 802.11 wireless printer ships with its wireless interface configured to advertise a peer-to-peer network. Even if the user does no configuration or setup whatsoever, and just connects to the printer's wireless network from their computer, that's all the setup that's necessary for the two devices to configure IPv4LL addresses, discover each other with DNS-SD/mDNS, and print successfully. Even in the case where the user does intend to do more configuration, IPv4LL + mDNS + DNS-SD remains the easiest and most reliable way to establish that first connection to the printer's embedded web server, which the user then uses to set up the printer the way they want, including configuring it to join their existing wireless network instead of advertising one of its own. Much of the original appeal of USB was its ease-of-use at a time when TCP/IP networking was hard to set up and configure. With Zero Configuration Networking erasing that deficiency, the argument for building a printer or similar device with USB instead of Ethernet (or wireless USB instead of 802.11) becomes a lot less compelling.

The Cost

Many developers do see the benefit of IPv4LL, but imagine it will be a lot more work to implement than it really is. Most of the low-cost network hardware products we're talking about already have a DHCP client. If you have a DHCP client, then RFC 2131 already requires it to verify using ARP that the assigned address is not already in use (as described in "IPv4 Address Conflict Detection"), and that small piece of work also gives you most of what you need for a simple minimal IPv4LL implementation. With just two easy changes to the code, you can extend your DHCP client to provide IPv4LL capability too:

  1. In your code that sends DHCP DISCOVER packets and waits for a response from a DHCP server, make it timeout after five seconds, and then just generate a "fake" DHCP ACK packet containing a random 169.254.x.x address.
  2. Your standard DHCP client code will then probe using ACD to see if this address is in use. If it finds it is in use, then it will reject the address. In the normal case this means sending a DHCP DECLINE packet to the server. You just need to add some special case code that skips sending this packet for 169.254.x.x addresses.

After rejecting the address that was found to be in use, your standard DHCP code then returns to the "DHCP DISCOVER" stage, and tries again to get a new address. After another five-second timeout, your code generates a new "fake" DHCP ACK packet containing a new random 169.254.x.x address, and the process repeats. Some developers have worried about how many tries it might take before the device finds an available address. Remember that there are over 65,000 possible IPv4LL addresses, and typically only a handful of devices on the network (or maybe even just two), so it's exceedingly rare for there to be even one address collision, much less two or three.

Now you have a DHCP client that works and configures a usable address even on a network with no DHCP server!

Page maintained by Stuart Cheshire
(Check out my latest construction project: Swimming pool by Swan Pools)