Post

DHCP + TFTP

DHCP + TFTP

Let’s take a walk down memory lane…

In the beginning … there was BOOTP (RFC951). Then, BOOTP begat DHCP (RFC2131). The problem is bits of BOOTP are embedded in DHCP and certain situations raise all kinds of ambiguities and broken systems. TFTP is one of these situations.

  • TFTP information is embedded within BOOTP in the SIAddr (server IP address, aka “next server” IP address) and SName (Server Name) fields
  • RFC951 (BOOTP) defines:
    • siaddr : “[boot] server IP address; returned in bootreply by server”
    • sname: “If the client wishes to restrict booting to a particular server name [string], it may [use sname to do so]“; in other words, this field is provided by the client
    • RFC951 allows for generic “boot server” protocols, TFTP being one
  • RFC2131 (DHCP) defines:
    • siaddr “clarifies” the field as “IP address of next server to use in bootstrap; returned in DHCPOFFER, DHCPACK by server”
      • “bootstrap” is not defined, presumably inherited from BOOTP
    • sname: this field, and its neighbour the file field, are optionally reused for DHCP options (that is, the 64+128 bytes that these two fields occupy in the BOOTP message are packed with DHCP options)
      • DHCP Options RFC2132 further specifies that DHCP option 66 is used to “identify a TFTP server when the sname field in the DHCP header has been used for DHCP options” (and Option 67 is the filename)
        • no comment is made about siaddr when Option 66 is provided
        • note that many DHCP servers will not deliver options that the client hasn’t requested, by default. i.e. if a client doesn’t request Option 66 in the discover, it won’t get one in the offer
  • RFC5859 (TFTP Server Address Option for DHCPv4), which introduces new DHCP Options that can be beneficial for certain TFTP clients (e.g. VOIP systems), notes:
    • “There are two commonly accepted methods to discover this [configuration, e.g. TFTP] server via DHCP; the sname field in the DHCP header [RFC2131] and the “TFTP Server Name” option (66) [RFC2132].”

Option 66 is a string and may contain only a single server name. Many (most/all?) clients will handle an IP address (as a string) as well. RFC5859 introduced Option 150 that can contain a list of one or more IP addresses. If Option 150 is present, Option 66 should be ignored.

So, in short we have enough ambiguity to result in all kinds of implementation variations.

dnsmasq

  • dnsmasq provides a handful of TFTP options/services, including a TFTP implementation (--enable-tftp)

    • it implements behaviour intended to work “with most clients”, which can mean doing things that are potentially unexpected/ambiguous (use the source, Luke), for example setting DHCP Option 66 will also set the sname field to the same string
  • by default dnsmasq will re-use the sname and file fields as option space, per RFC2131; use the dhcp-no-override option to not do this

  • to set siaddr: use the “virtual” DHCP option server-ip-address (ref):

    1
    
    dhcp-option=option:server-ip-address,10.12.0.30
    
  • to set sname / DHCP Option 66 (tftp_server_name):

    1
    
    dhcp-option=66,"10.12.0.30"
    
  • that will send the given string to all clients as the sname field, but only deliver Option 66 to clients that ask for it

    • use dhcp-option-force to forcibly deliver the option, only (i.e. leave sname empty)
  • aside: when specifying an IP address, it must be quoted as a string

Misc

  • macOS’ ipconfig is borken wrt. presenting Option 66 (tftp_server_name) incorrectly as a sequence of IP addresses (ip_multi) rather than the single string it is
This post is licensed under CC BY 4.0 by the author.