Running new dhcpd instance on same physical interface

sthaug at sthaug at
Sun Aug 2 10:00:42 UTC 2009

> > Provided all of the server activity is IP unicast, there is a (seldom
> > used, often broken, and poorly documented) way to build the DHCP
> > server to "USE_SOCKETS" (#define in includes/site.h).  With this build
> > method, the server can not be guaranteed to be RFC 2131 compliant in
> > messages it can receive or transmit (raw sockets work around that for
> > us).
> It would be nice if USE_SOCKETS or a similar mechanism could become
> "first class citizens" - then those of us with clients exclusively 
> behind relay agents could drop all broadcast handling etc.

I now several DHCP servers running on my FreeBSD box, bound to several
different IP addresses on the same physical interface. I tried this
once before, but got lost in a twisty little maze of code.

I needed several dhcpd's on the same physical interface because a few
of my clients shouldn't have the domain name/name servers that the rest
want (in fact they shouldn't have any at all), and ISC DHCP has no way
to "unset" a configuration parameter, as mentioned by Dave Hankins in

This time I followed the inspiration of Christof Chen in

Note that this assumes that your dhcpd's do *not* need to handle any
broadcast traffic (i.e. all your DHCP clients are behind relay agents).

What you need to do, then, is:

1. Edit includes/site.h to define USE_SOCKETS and USE_BPF_HWADDR:

-/* #define USE_SOCKETS */
+#define USE_SOCKETS

2. Run your usual ./configure

3. Edit generated includes/config.h to get rid of USE_BPF definition:

 /* Define to 1 to use the Berkeley Packet Filter interface code. */
-#define USE_BPF ""
+/* #define USE_BPF "" */

4. Patch common/bpf.c with patch included at the end of this message.

5. Compile and install dhcpd.

6. Edit your dhcpd.conf to include the "local-address" configuration

7. And then you can run several dhcpd's on the same machine.

There is another issue which is still not covered, namely OMAPI. If you
define an omapi-port it will still be bound to INADDR_ANY, so only one
of your dhcpd's on the same machine can use OMAPI. In my case this was
not a significant limitation (but it is a limitation that should be easy
to fix if necessary).

As an aside, since dhcpd wants an interface parameter, it might be nice
if, when USE_SOCKETS is defined, dhcpd simply used the IP address of this
interface instead of needing the "local-address" configuration parameter.
This can be done with a one-line change to if_register_socket():

--- common/socket.c.orig	2008-08-29 19:48:57.000000000 +0200
+++ common/socket.c	2009-08-01 16:04:32.000000000 +0200
@@ -158,7 +158,7 @@
 		addr->sin_family = AF_INET;
 		addr->sin_port = local_port;
-		       &local_address,
+		       &info->addresses[0].s_addr,
 #ifdef HAVE_SA_LEN
 		addr->sin_len = sizeof(*addr);

I am, however, not at all sure that this is the best way to solve the

In any case, below is the necessary patch to bpf.c.

Steinar Haug, Nethelp consulting, sthaug at
--- common/bpf.c.orig	2007-08-23 11:49:51.000000000 +0200
+++ common/bpf.c	2009-07-31 13:36:42.000000000 +0200
@@ -34,7 +34,7 @@
 #include "dhcpd.h"
 #if defined (USE_BPF_SEND) || defined (USE_BPF_RECEIVE)	\
-				|| defined (USE_LPF_RECEIVE)
+	|| defined (USE_LPF_RECEIVE) || defined(USE_BPF_HWADDR)
 # if defined (USE_LPF_RECEIVE)
 #  include <asm/types.h>
 #  include <linux/filter.h>
@@ -55,7 +55,7 @@
 #include "includes/netinet/if_ether.h"
+#if defined(USE_BPF_RECEIVE) || defined(USE_BPF_HWADDR)
 #include <ifaddrs.h>
@@ -547,7 +547,9 @@
 		interface_dereference (&fbi, MDL);
+#endif /* USE_BPF_RECEIVE */
+#if defined (USE_BPF_RECEIVE) || defined(USE_BPF_HWADDR)
 get_hw_addr(const char *name, struct hardware *hw) {
 	struct ifaddrs *ifa;
@@ -603,4 +605,4 @@
+#endif /* defined (USE_BPF_RECEIVE) || defined(USE_BPF_HWADDR) */

More information about the dhcp-users mailing list