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) andSName
(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 thefile
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
- no comment is made about
- DHCP Options RFC2132 further specifies that DHCP option 66 is used to “identify a TFTP server when the
- 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].”
- “There are two commonly accepted methods to discover this [configuration, e.g. TFTP] server via DHCP; the
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
- 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
by default dnsmasq will re-use the
sname
andfile
fields as option space, per RFC2131; use thedhcp-no-override
option to not do thisto set
siaddr
: use the “virtual” DHCP optionserver-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. leavesname
empty)
- use
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