FreeBSD as a DHCP Client

DHCP is a protocol for dynamically assigning configuration information, such as IP addresses, to groups of workstations. A basic DHCP configuration is extremely simple under FreeBSD.

FreeBSD comes with ISC's DHCP client version 2.0 installed. Version 3.0 is available from ISC and works well. If you need to release your lease from time to time, it would probably be worth upgrading to 3.0, but otherwise there is little notable difference between the two versions of the client.

DHCP is enabled by specifying "DHCP" as the ifconfig argument in your /etc/rc.conf file:

	ifconfig_fxp0="DHCP"		# fxp0 is my ethernet device
	pccard_ifconfig="DHCP"		# this is for pccard adapters

In most cases, this is enough. The /etc/rc.network or /etc/pccard_ether scripts read these variables and cause /sbin/dhclient to be executed. This program broadcasts DHCP packets onto the network and waits for a response from the DHCP server. When a lease has been established, various networking components are configured and the program puts itself in the background where it can continue renewing the lease.

DHCP Client Configuration

Depending on how DHCP services is set up on your network, you might have to tailor the configuration of your DHCP client. This is done by adding directives to the /etc/dhclient.conf file. There is a man page on this file, so read it.

My site used a device that provided dynamic DNS for the DHCP clients. By default, dhclient sends the fully qualified domain name of the workstation to the DHCP server. Our DHCP server was appending the company's domain to the end of that, so it looked like "venom.coreth.com.example.com". I added a line to the configuration file to specify the hostname:

	send host-name "venom";

This took care of that problem. I also added options to append my search domain to the end of the what I got from the server. Finally, I sometimes used my laptop at a site that didn't provide DNS server addresses via DHCP, so I had to provide a default list in my configuration:

	append domain-name " coreth.com";
	default domain-name-servers 206.52.3.2 206.52.3.10;

bpfilter in the Kernel

Under FreeBSD, dhclient requires support for the Berkeley Packet Filter in the kernel. So, for that matter, does dhcpd and the relay agent. This is enabled in the kernel config with the line:

	pseudo-device   bpf             #Berkeley packet filter

These days, this is included with the GENERIC kernel, so if you don't know how to build a kernel, you needn't worry about it. Some administrators like to take this out for security purposes where it's not needed.

DHCP Option 81

Many sites are beginning to use the new DHCP Option 81, FQDN (Fully Qualified Domain Name). The purpose of this DHCP option is two-fold. It allows the client to announce its FQDN to the DHCP server, and it sets up negotiation between the client and the server as to who will handle dynamic DNS (forward and reverse) for the DHCP client.

ISC's DHCP client does not really have support for this. Version 3.0 allows you to specify this option, but it is not fully implemented. The data to be supplied with this option is somewhat binary in nature. There are a few (three?) leading bytes and then the domain which should be encoded as it is for DNS packets. If you have to get this working, you might be able to place the non-ascii characters in the string by escaping them, and of course you'll have to get familiar with how the option works.

It is worth noting that Option 81 has not reached RFC status. It is still a draft specification with the DHC working group of the IETF. Microsoft has implemented this with Active Directory, and everyone is playing catch-up, including the standards community.

Releasing

The DHCP specification has a RELEASE function, which notifies the server that the client has relinquished the lease. This isn't necessary for normal option, and its use has essentially been relegated to troubleshooting broken DHCP leases. This means it gets used all the time under Windows and not at all under Unix. However, there are a couple of situations where releasing is necessary. The most common is when you want to move a device from one subnet to another, particularly if both subnets are served by the same DHCP server.

Version 2.0 of dhclient does not have a release option. You can kill the daemon, but it never sends a RELEASE message to the server. If you must have this functionality, you must upgrade to version 3.0 of the client. The source code is available from ISC, and it builds simply and cleanly under FreeBSD. Note that a client, a server, and a relay agent are all bundled together in the same source distribution, and without taking steps to prevent it, all of those things will get installed on your machine. It's not a big deal, unless you start the server or the relay agent on your workstation, which will cause other DHCP clients on your subnet to fail.

With version 3.0 of dhclient installed, you can just execute the program with the -r option:

	/sbin/dhclient -r

This will send a RELEASE message to the server and signal the dhclient process running in the background to terminate.

First Packet

If you run dhclient at the command line and pay attention, you may notice that the first DISCOVER packet never seems to get a response. I believe this is a bug with bpf(4). dhclient uses bpf to listen for DHCP packets. I have observed that, under FreeBSD, the first packet (sent or received, I'm not sure) after opening a bpf device gets lost.

Someone should fix that.

Wishes

I'm just going to whine here for a minute. I use DHCP on my laptop to handle address assignment when moving between client locations. All of the clients I frequently visit use DHCP, so it works out well. However, I have identified a serious lacking. Two of my customers put me behind proxy based firewalls. That is a good thing. However, DHCP doesn't communicate to me what the address of the proxy server is, nor does my web browser really offer me a means to modify this setting except from the menu.

There is a DHCP option to specify a "Web Server", but it wasn't really designed for this (its actual intent is pretty stupid, really). So right now, I manually change this in my browser every time I change locations, but I'm thinking about ways to deal with this. I've even thought about setting up Apache on my laptop as a proxy to chain the proxy (or not) based on the lease I get. However, that's clearly lame.