How DHCP uses raw sockets
  • 24 Sep 2018
  • 3 Minutes to read
  • Contributors
  • Dark
    Light
  • PDF

How DHCP uses raw sockets

  • Dark
    Light
  • PDF

Article Summary

Question:

How does DHCP use raw sockets?  Is it possible not to use them?

Answer:

The DHCP protocol has some odd requirements to really work properly: being able to transmit to and receive packets sent to the all-ones limited broadcast address (255.255.255.255), and being able to send a unicast without an ARP.

In order to both reliably receive and transmit these packets in a way that conforms with RFC 2131, we have to use platform-flavor specific raw sockets. For example, on SUSE that's what we call "LPF" - the Linux version of the BPF device. You should see LPF/interface/MAC lines logged when dhcpd starts, these are the raw sockets initializing.

When operating in this mode, dhcpd opens the raw sockets, and a backup BSD/UDP socket (called the "fallback interface"), which you will be seeing in netstat.

This mode of operation is the default at compile time, because it is the most compatible and general.

The raw socket:

  • Receives all DHCP packets - so the DHCP packet sent to the server must come in on the interface the socket is opened on.
  • Transmits directed unicasts (w/out ARP), and special RFC 2131 complying all-ones limited broadcasts (rather than the subnet broadcast address you may get from the BSD/UDP interface).  These are needed in clients' initial configuration stage (when the client does not yet have an address configured).

The BSD/UDP socket:

  • Is read from to empty it and free up buffers, but all packets read from this socket are immediately discarded.  The reason for this is that in the expected operating mode, these packets are all duplicates of packets received via the raw socket.
  • Is used to transmit routed unicasts, so we don't have to implement IP routing in 'dhcpd'.  This is used to reply to any relay agent, or to reply to clients apparently in the RENEWING state.

You can compile raw socket behaviour out, and it may sometimes be advisable for performance and simplicity reasons, but administrators should understand the limitation that the DHCP server will no longer be able to send unicast replies to clients on the same broadcast domain as the DHCP server. Any clients for who this would be a problem must instead be situated where they are reached via relay agents. It may be hard to maintain this limitation in an installed system across administrators, as networks grow and ebb. Raw sockets do not negatively impact most users' performance in a meaningful way, so it is not recommended to disable it.

Disabling raw sockets in DHCP
From 4.1-ESV-R3 and 4.2.2 onwards, you can use experimental configure option --enable-use-sockets. Note that this feature is Operating System-dependent - it will not work in all environments. Also note, however, that it is specifically intended and recommended for users of Solaris 11: Building ISC DHCP on Solaris 11.

Prior to the introduction of the --enable-use-sockets option you could disable raw socket behaviour by defining USE_SOCKETS in site.h.

In an implementation where raw socket behaviour is compiled out, the server uses regular BSD/UDP socket(s), and no raw sockets.  A fallback interface is not opened in this case.  On some platforms, a BSD socket is opened for every interface, if that platform has a way to bind sockets to interfaces.  These may however still appear to be as being bound on INADDR-ANY.  (Most linuxes operate this way, but the behaviour may depend on the kernel or libc versions - it checks if you have SO_BINDTODEVICE defined). 

Note for users of the packaged version of ISC DHCP distributed by Oracle on Solaris 11
This distributed build of ISC DHCP does not use raw sockets. The ability to only broadcast offers and acknowledgements on Solaris 11 has been logged to Oracle as bug 17423148.