Setting up a DHCP client on FreeBSD

 Last modified 28 June 1999

  The original version of this document pertained to setting up dhclient on a 2.2.x system. As of 3.2-Stable (actually earlier than this, but I am working with 3.2-Stable here, so that is what I am basing the updated sections on) the FreeBSD project has incorporated dhclient into the base distribution, therefore some of these steps will not apply. Because many people are still using 2.2 and have no plans to upgrade, I will continue to include those instructions here, but I will denote those areas where the process is different.

    Currently there is no streamlined way of setting up a DHCP client for FreeBSD. I have cobbled together the following procedure out of a lot of trial and error and I would like to save you the same aggravation. I hope that this text is of use to you. My experience is colored heavily by the fact that I am using the Road Runner cable modem service here in San Diego. If you have information that is pertinent to other users of dhcp I would be interested in hearing it.

    If you need more assistance with the ISC DHCP client or server you should probably visit the ISC DHCP mailing list resource page and subscribe to one or more of the support mailing lists and post your question there. They have a lot of knowledgeable people there who are willing to help.

    If you have any questions, comments or suggestions please send them to me by mailing Doug@gorean.org. Please do not be disappointed if I have no additional information to offer you though. I have included everything I know here. :)

1.  Make sure that you have BPF in your kernel

    The DHCP client depends on the existence of the Berkely Packet Filter (BPF) in your kernel. If you are using the GENERIC kernel that was originally installed with FreeBSD you do not have BPF. First, visit the kernel configuration page for the basic information on how to compile a custom kernel. While you are working on the configuration file make sure that you add the option for BPF:

pseudo-device    bpfilter    4

    After you have recompiled the kernel and rebooted  you will probably need to make your devices. As root type:

# cd /dev
# /bin/sh MAKEDEV bpf0 bpf1 bpf2 bpf3

2.  Download and install the source

This step is not necessary if you are using 3.2-Stable or later

    By far the easiest way to do this is to use the FreeBSD ports collection. This is a good general solution for adding software to any FreeBSD installation. The specific port you want is /usr/ports/net/isc-dhcp2. If you have the ports collection installed, click here to be taken straight to it. My limited experience with the Wide client in the ports was not good and I have found the person working on the ISC project to be very friendly and very much interested in cross-platform compatibility.

    If you do not wish to use the ports collection you can try installing it as a package instead. You could of course download the source from the ISC and compile it yourself, but if you are going to do that you might as well use the port.

3.  Configure the client

    Ok, now that you have the thing installed, you must set up the configuration file. You should find it in /etc, but if not you can copy the one that comes with the sources to /etc. You should definitely be using version 2.0 of the client that was recently released.

If you are using 3.2-Stable or later, the dhclient.conf file should already be in the /etc directory. If not, take a look at /usr/src/contrib/isc-dhcp/client/dhclient.conf.

# cp /usr/ports/net/isc-dhcp2/work/dhcp-2.0/client/dhclient.conf /etc
    A lot of the things in the conf file are examples and should be deleted. I use the following entries, most of which were obtained from examining my lease file.

# Defaults
timeout 60;
reboot 10;

retry 60;
select-timeout 5;
initial-interval 2;

script "/etc/dhclient-script";
# On 3.2-Stable and later the default location is /sbin and this
# statement is not needed unless you plan to override the location.

interface "ep0" {
 request subnet-mask, broadcast-address, routers, domain-name-servers,
         domain-name, host-name;
 require domain-name-servers;
 media "link2";
}

    Please note that I am not holding out on you here. :) I often get questions along the lines of, "Can you send me a copy of your configuration file, I can't get mine to work." Believe me when I say that this is my configuration file. I have nothing else to send you. Also, you might consider the ISC's recommendation of using an empty configuration file. Sometimes this actually works better than having one, especially if you have only one interface.

    Your configuration should be determined by your local needs of course. Your ISP should be able to give you the information you need (unless of course they are like Road Runner and prefer not to acknowledge that Unix exists :). The man page for dhclient.conf also suggests that you can start with an empty conf file and in most normal server configurations it should come up by itself. Then you can check the /var/db/dhclient.leases file to see what information the server sends you.

    One option I need that is not currently supported by the dhclient-script is setting the hostname. After a fairly lengthy discussion on the dhcp-client mailing list it was decided that the best way to handle local options like that is to have dhclient-script call a local configuration file that could add features not handled in the main script. This option is included in version 2.0 of dhclient, although by default the /sbin/dhclient-script file in 3.2-Stable and above uses /etc/dhclient-enter-hooks and /etc/dhclient-exit-hooks instead of dhclient-script.local.

    This is my dhclient-script.local file. I use it to start Phil Karn's excellent rrlogin program that is needed by us Road Runner users. Those who have an interest in Road Runner or cable modem service in general would be well served at his page.

#!/bin/sh

PATH=/bin:/sbin:/usr/bin

if [ "$CALLOUT_STATE" = "end" ]; then

 if [ x$reason = xBOUND -o x$reason = xREBOOT ]; then

  if [ x$new_host_name != x ]; then
    if [ x$new_domain_name != x ]; then
      hostname $new_host_name.$new_domain_name
      echo New Hostname: $new_host_name.$new_domain_name
    else
      hostname $new_host_name
      echo New Hostname: $new_host_name
    fi
  fi

 /etc/dhclient-rrlogin &

 fi
fi

    Once you have the files situated the way you want them, fire it up and make sure it is working. As root I simply type

# dhclient ep0
which fires it up for my 3Com 3c509 card.

4.  Configuring FreeBSD To Use DHCP

    Now that dhclient is working, you want to set FreeBSD's configuration files up to use it during boot. There is no facility to do this directly, however you can use the hooks in the rc.network script to start it automatically and thereby use the network configuration options in rc.conf as they were intended. Unfortunately, due to recent changes in the FreeBSD configuration system it will be necessary to comment out the hostname setting in /etc/defaults/rc.conf as well as making sure that you set (or do not set) things appropriately in /etc/rc.conf, or /etc/rc.conf.local.  In /etc/rc.conf (or /etc/rc.conf.local) make the following changes.

# If dhcp will be setting your hostname for you, comment this out in
# /etc/defaults/rc.conf
# If you have a static hostname set it in /etc/rc.conf[.local] as
# you normally would
#hostname="my.domain.name"
. . .
# Make sure you define your network interfaces even if they will
# be configured by dhcp (so that the start script catches them).
network_interfaces="ep0 lo0"    # List of network interfaces (lo0 is loopback).
ifconfig_lo0="inet 127.0.0.1"   # default loopback device configuration.
# But do not let rc.network configure it.
#ifconfig_ep0="inet 204.210.32.25  netmask 255.255.255.0"
. . .
# This is almost certainly going to be something you get from dhcp.
defaultrouter="NO"              # Set to default gateway (or NO).

    In /etc/rc.network you will see the following (no changes need to be made).

# Set up all the network interfaces, calling startup scripts if needed
    for ifn in ${network_interfaces}; do
            if [ -e /etc/start_if.${ifn} ]; then
                    . /etc/start_if.${ifn}
            fi
. . .

    You can take advantage of this by creating a script that starts dhcp. The script should have a suffix named after the interface you want to key it to. For instance mine is called /etc/start_if.ep0. Since all I need to do is start dhcp, it is very simple.

#!/bin/sh

/usr/local/sbin/dhclient ep0

5.  Reboot And Give It A Go

    At this point everything should be in place, you can reboot your system and it will use dhcp to configure your interface. If it does not work for some reason, double-check the configuration files and try running dhclient by itself and make sure that part of it is working. Also make sure that you do not have any conflicting instructions in /etc/rc.local or /usr/local/etc/rc.d.

6.  DHCP on other networks

According to one thoughtful @Home user, here is what you need to set up DHCP:

  Here is what the minimal config file looke like for a COX@Home
  customer.

        # Defaults
        script "/usr/local/etc/dhclient-script";

        interface "ep0" {
        send host-name "<the hostname cox gives you*>" ;
        }

#  * When COX installs @Home ona windows based system they fill in
#    the computer name field. This can be found by right clicking
#    on Network Neiborhood then clicking the Identity TAB.
 

With that entry in there and following the rest of your instructions it
came up like clock work.


Good luck! :)