RFC 1532
Clarifications and Extensions for the Bootstrap Protocol
Part 1 of 5 ๐
RFC 1532: Clarifications and Extensions for the Bootstrap Protocol โจ
okay bestie, this is RFC 1532 ๐ and the title says it all: it's a BOOTP glow-up ๐ It came out of the Network Working Group in October 1993, written by W. Wimer at Carnegie Mellon University. It's on the Standards Track, and it updates RFC 951. There's no Obsoletes line on it, so it isn't replacing anything, just tidying up and extending the protocol ๐ฆ
Status of this Memo ๐
this one specifies an Internet standards track protocol for the Internet community, and it's asking for discussion and suggestions for improvements ๐ซถ for the current standardization state, check the "Internet Official Protocol Standards" listing. distribution of this memo is unlimited, so share it with everyone ๐ธ
Abstract ๐
okay so BOOTP was kinda loosely defined in its original spec ๐ญ the behavior of "BOOTP relay agents" (originally called BOOTP forwarding agents) only got a general description, and the client side had some gaps too. this memo is here to clarify and strengthen all of that ๐
and new issues have shown up since the original spec was written, so this memo tries to address some of those too โจ
Table of Contents ๐๏ธ
1. Introduction................................................. 2
1.1 Requirements................................................ 2
1.2 Terminology................................................. 3
1.3 Data Transmission Order..................................... 4
2. General Issues............................................... 5
2.1 General BOOTP Processing.................................... 5
2.2 Definition of the 'flags' Field............................. 5
2.3 Bit Ordering of Hardware Addresses.......................... 7
2.4 BOOTP Over IEEE 802.5 Token Ring Networks................... 8
3. BOOTP Client Behavior........................................ 9
3.1 Client use of the 'flags' field............................. 9
3.1.1 The BROADCAST flag........................................ 9
3.1.2 The remainder of the 'flags' field........................ 9
3.2 Definition of the 'secs' field.............................. 9
3.3 Use of the 'ciaddr' and 'yiaddr' fields..................... 10
3.4 Interpretation of the 'giaddr' field........................ 11
3.5 Vendor information "magic cookie"........................... 12
4. BOOTP Relay Agents........................................... 13
4.1 General BOOTP Processing for Relay Agents................... 13
4.1.1 BOOTREQUEST Messages...................................... 14
4.1.2 BOOTREPLY Messages........................................ 16
5. BOOTP Server Behavior........................................ 18
5.1 Reception of BOOTREQUEST Messages........................... 18
5.2 Use of the 'secs' field..................................... 19
5.3 Use of the 'ciaddr' field................................... 19
5.4 Strategy for Delivery of BOOTREPLY Messages................. 19
Acknowledgements................................................ 21
References...................................................... 21
Security Considerations......................................... 22
Author's Address................................................ 22
1. Introduction ๐
okay so BOOTP is a UDP/IP-based protocol that lets a booting host configure itself dynamically and without any user supervision ๐คโจ it tells the host its assigned IP address, the IP address of a boot server host, and the name of a file to load into memory and run [1]. it can also pass along other config stuff like the local subnet mask, the local time offset, the addresses of default routers, and the addresses of various Internet servers [2] ๐ง
BUT the original BOOTP spec [1] left some things open to question ๐ญ the exact behavior of BOOTP relay agents (formerly called "BOOTP forwarding agents") wasn't clearly specified. some parts of the spec actually conflict with each other, and other parts got misinterpreted, so clarification is needed. this memo fixes those problems ๐
then the IEEE 802.5 Token Ring Network showed up, and it creates a unique problem for BOOTP's particular message-transfer paradigm ๐ this memo also suggests a solution for it ๐ฆ
NOTE: Unless otherwise specified in this document or a later document, the information and requirements specified throughout this document also apply to extensions to BOOTP such as the Dynamic Host Configuration Protocol (DHCP) [3]. ๐ซถ
1.1 Requirements ๐
in this memo, the words that define how significant a particular requirement is are capitalized. here they are, with what each one means:
- "MUST" โ This word or the adjective "REQUIRED" means that the item is an absolute requirement of the specification.
- "MUST NOT" โ This phrase means that the item is an absolute prohibition of the specification.
- "SHOULD" โ This word or the adjective "RECOMMENDED" means that there may exist valid reasons in particular circumstances to ignore this item, but the full implications should be understood and the case carefully weighed before choosing a different course.
- "SHOULD NOT" โ This phrase means that there may exist valid reasons in particular circumstances when the listed behavior is acceptable or even useful, but the full implications should be understood and the case carefully weighed before implementing any behavior described with this label.
- "MAY" โ This word or the adjective "OPTIONAL" means that this item is truly optional. One vendor may choose to include the item because a particular marketplace requires it or because it enhances the product, for example; another vendor may omit the same item.
1.2 Terminology ๐
this memo uses the following terms, so let's get them straight ๐
BOOTREQUEST โ a BOOTREQUEST message is a BOOTP message sent from a BOOTP client to a BOOTP server, requesting configuration information ๐โโ๏ธ
BOOTREPLY โ a BOOTREPLY message is a BOOTP message sent from a BOOTP server to a BOOTP client, providing configuration information ๐
Silently discard โ this memo specifies several cases where a BOOTP entity is to "silently discard" a received BOOTP message. that means the entity throws the message away without further processing, and it will not send any ICMP error message as a result ๐ BUT for diagnosing problems, the entity SHOULD provide the capability of logging the error, including the contents of the silently-discarded message, and SHOULD record the event in a statistics counter ๐ (so you can still tell what happened, bestie ๐)
1.3 Data Transmission Order ๐ข
the order of transmission of the header and data in this document is resolved to the octet level ๐งฉ whenever a diagram shows a group of octets, they're transmitted in the normal order you'd read them in English. like in this diagram, the octets go out in the order they're numbered:
0 1
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| 1 | 2 |
+-------------------------------+
| 3 | 4 |
+-------------------------------+
| 5 | 6 |
+-------------------------------+
whenever an octet represents a numeric quantity, the leftmost bit in the diagram is the high order or most significant bit. so the bit labeled 0 is the most significant bit ๐ for example, this diagram represents the value 170 (decimal) โจ
0 1 2 3 4 5 6 7
+-+-+-+-+-+-+-+-+
|1 0 1 0 1 0 1 0|
+---------------+
same deal for multi-octet fields: the leftmost bit of the whole field is the most significant bit, and when a multi-octet quantity gets transmitted, the most significant octet goes first ๐
2. General Issues ๐ธ
this section covers issues of general relevance to all BOOTP entities, which means clients, servers, and relay agents ๐ซถ
2.1 General BOOTP Processing ๐
the following consistency checks SHOULD be performed on BOOTP messages:
- The IP Total Length and UDP Length must be large enough to contain the minimal BOOTP header of 300 octets (in the UDP data field) specified in [1].
NOTE: Future extensions to the BOOTP protocol may increase the size of BOOTP messages. Therefore, BOOTP messages which, according to the IP Total Length and UDP Length fields, are larger than the minimum size specified by [1] MUST also be accepted. ๐
- The
op(opcode) field of the message must contain either the code for a BOOTREQUEST (1) or the code for a BOOTREPLY (2).
BOOTP messages not meeting these consistency checks MUST be silently discarded ๐ โโ๏ธ๐
2.2 Definition of the 'flags' Field
okay so the standard BOOTP message format from [1] has a two-octet field sitting between 'secs' and 'ciaddr' ๐ right now it's just labelled "unused" with its contents left unspecified, even though Section 7.1 of [1] gives this helpful little tip โจ
"Before setting up the packet for the first time, it is a good idea to clear the entire packet buffer to all zeros; this will place all fields in their default state."
so this memo officially makes that two-octet field the 'flags' field ๐ and the most significant bit becomes the BROADCAST (B) flag ๐ก its semantics get covered in Sections 3.1.1 and 4.1.2 of this memo ๐ฆ
the leftover bits in 'flags' are reserved for future use ๐ธ clients MUST set them to zero, and servers and relay agents MUST ignore them ๐ซถ
here's what the 'flags' field looks like:
0 1
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|B| MBZ |
+-+-----------------------------+
where:
- B is the BROADCAST flag (discussed in Sections 3.1.1 and 4.1.2) ๐ฃ
- MBZ is MUST BE ZERO (reserved for future use) ๐ซง
here's the whole BOOTP message layout ๐ง the numbers in parentheses are how many octets each field takes up
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| op (1) | htype (1) | hlen (1) | hops (1) |
+---------------+---------------+---------------+---------------+
| xid (4) |
+-------------------------------+-------------------------------+
| secs (2) | flags (2) |
+-------------------------------+-------------------------------+
| ciaddr (4) |
+---------------------------------------------------------------+
| yiaddr (4) |
+---------------------------------------------------------------+
| siaddr (4) |
+---------------------------------------------------------------+
| giaddr (4) |
+---------------------------------------------------------------+
| |
| chaddr (16) |
| |
| |
+---------------------------------------------------------------+
| |
| sname (64) |
+---------------------------------------------------------------+
| |
| file (128) |
+---------------------------------------------------------------+
| |
| vend (64) |
+---------------------------------------------------------------+
2.3 Bit Ordering of Hardware Addresses
this one's all about bit order ๐ฅ it covers the bit ordering used for link-level hardware addresses in the protocol [4] on the client's link-level network (assuming ARP is defined for that network) ๐ง
the 'chaddr' field MUST be preserved exactly as the BOOTP client specified it ๐ and a relay agent MUST NOT reverse the bit ordering when it crosses between two networks that use different bit orderings ๐ โโ๏ธ
DISCUSSION:
okay so one of the main reasons 'chaddr' exists is so BOOTP servers and relay agents can talk straight to clients without using broadcasts ๐ฅฐ in practice, the contents of the the same way the normal ARP protocol would have. Clearly, interoperability can only be achieved if a consistent interpretation of the 'chaddr' field is used. ๐ซถ
as a practical example, this means that the bit ordering used for the is the opposite of the bit ordering used by a BOOTP client on a DIX ethernet network ๐
2.4 BOOTP Over IEEE 802.5 Token Ring Networks
token ring needs extra care for the client/server and client/relay agent conversations ๐ the reason is non-transparent bridging ๐
the client SHOULD send its broadcast BOOTREQUEST with an All Routes Explorer RIF โจ that lets servers and relay agents cache the return route if they want to ๐ฆ for the ones that can't cache it (because they're stateless, for example), the BOOTREPLY message SHOULD be sent to the client's hardware address, as taken from the BOOTP message, using a Spanning Tree Rooted RIF ๐ the client and the server/relay agent will record the actual bridge route through their normal ARP processing code ๐ง
DISCUSSION:
in the simplest case, an unbridged, single ring network, BOOTP's broadcast behaviour is identical to what you get on Ethernet ๐ but a BOOTP client can't know, a priori, that an 802.5 network isn't bridged ๐ honestly the server, or relay agent, probably won't know either ๐
out of the four possible scenerios, only two are interesting ๐ the first is where we assume the 802.5 network is not bridged and it is, and the second is where we assume it is bridged and it is not. In the former case, the Routing Information Field (RIF) will not be used; therefore, if the server/relay agent are on another segment of the ring, the client cannot reach it ๐ญ In the latter case, the RIF field will be used, resulting in a few extraneous bytes on the ring. It is obvious that an almost immeasurable inefficiency is to be preferred over a complete failure to communicate ๐ซถ
given that RIF fields are going to be needed, it is necesary to determine the optimum method for the client to reach the server/relay agent, and the optimum method for the response to be returned โจ
3. BOOTP Client Behavior
this section clears up a bunch of things about how BOOTP clients behave ๐
3.1 Client use of the 'flags' field
3.1.1 The BROADCAST flag
normally, BOOTP servers and relay agents try to deliver BOOTREPLY messages straight to the client with unicast delivery ๐ฎ the IP destination address (in the IP header) is set to the BOOTP 'yiaddr' address, and the link-layer destination address is set to the BOOTP hardware address ๐ฏ but some clients are unable to receive such unicast IP datagrams until they know their own IP address (thus we have a "chicken and egg" issue) ๐ฃ often, though, they can still receive broadcast IP datagrams (those with a valid IP broadcast address as the IP destination and the link-layer broadcast address as the link-layer destination) ๐ก
if a client falls into this category, it SHOULD set (to 1) the newly-defined BROADCAST flag in the 'flags' field of BOOTREPLY messages it generates ๐ that's a hint telling BOOTP servers and relay agents that they should try to broadcast their BOOTREPLY messages to the client ๐ฃ
if a client doesn't have this limitation (i.e., it's perfectly able to receive unicast BOOTREPLY messages), it SHOULD NOT set the BROADCAST flag (i.e., it SHOULD clear the BROADCAST flag to 0) ๐
DISCUSSION:
this addition is a workaround for old host implementations ๐ฐ๏ธ those implementations SHOULD be modified so they can receive unicast BOOTREPLY messages, which makes this workaround unnecessary ๐ ๏ธ overall, using this mechanism is discouraged ๐ซ
3.1.2 The remainder of the 'flags' field
the remaining bits of the 'flags' field are reserved for future use ๐ธ a client MUST set these bits to zero in every BOOTREQUEST message it generates ๐ and a client MUST ignore these bits in every BOOTREPLY message it receives ๐ซง
3.2 Definition of the 'secs' field
the 'secs' field of a BOOTREQUEST message SHOULD represent the elapsed time, in seconds, since the client sent its first BOOTREQUEST message โฑ๏ธ which means the 'secs' field of the first BOOTREQUEST message SHOULD be set to zero ๐ผ
clients SHOULD NOT set the 'secs' field to a value that stays constant across all BOOTREQUEST messages ๐ โโ๏ธ
DISCUSSION:
the original definition of 'secs' was super vague ๐ฅด it wasn't clear whether it meant the time since the first BOOTREQUEST was sent, or some other period like the time since the machine was powered up ๐ that made it way less useful as a policy control mechanism for BOOTP servers and relay agents ๐ค and some client implementations have been known to just set this field to a constant value, or to use incorrect byte-ordering ๐ incorrect byte-ordering usually makes it look like a client has been waiting much longer than it really has, so a relay agent will relay the BOOTREQUEST sooner than desired (usually immediately) ๐โโ๏ธ these implementation errors have further undermined the usefulness of the 'secs' field ๐ญ these incorrect implementations SHOULD be corrected ๐งโจ
3.3 Use of the 'ciaddr' and 'yiaddr' fields ๐ฆ
okay so if a BOOTP client doesn't know what IP address it's supposed to be using, it SHOULD set 'ciaddr' to 0.0.0.0 ๐ซถ. if the client can remember the last IP address it was given, or someone preconfigured it with an IP address some other way, it MAY fill 'ciaddr' with that address. If the client does place a non-zero IP address in the datagrams addressed to that IP address and also answer ARP requests for that IP address (if ARP is used on that network).
the BOOTP server is free to assign a different IP address (in the SHOULD adopt the IP address specified in 'yiaddr' and begin using it as soon as possible. bestie, that's the server being in charge but the client still having to take the address and run with it asap ๐
DISCUSSION:
there are a bunch of different takes on what 'ciaddr' is actually for, and sadly nobody has agreed on one correct answer ๐ญ. one take is that if a client is happy to accept whatever IP address the BOOTP server hands it, the client should always put 0.0.0.0 in 'ciaddr', no matter whether it remembers its old address. on the flip side, if the client needs a specific IP address (like the host admin hand-configured it and BOOTP is only being used to grab a boot file and/or info from the 'vend' field), then the client fills 'ciaddr' with the address it wants and ignores whatever the server put in 'yiaddr' ๐ธ. another take says the client always fills 'ciaddr' with its most recently assigned IP address (if it knows one), even if that address might be wrong. that client will still accept and use the address the server assigns in 'yiaddr'. the reason people like this one is that it helps the server figure out who the client is and/or deliver the BOOTREPLY back to it ๐ง. then there's a third (mis)interpretation that allows the client to use client has never used that address before or is not currently using that address.
the last interpretation is incorrect because it may stop the BOOTREPLY from ever reaching the client ๐. the server will usually unicast the reply to the address given in 'ciaddr', but the client may not be listening on that address yet, or the client may be plugged into the wrong subnet so normal IP routing (correctly!) sends the reply to a different subnet. the second interpretation also suffers from that same "incorrect subnet" problem ๐.
the first interpretation seems to be the safest and most likely to promote interoperability โจ๐
3.4 Interpretation of the 'giaddr' field ๐
the 'giaddr' field is kinda poorly named, ngl ๐ญ. it exists to help BOOTREQUEST messages travel from a client, through BOOTP relay agents, to servers on different networks than the client. same deal in reverse: it helps BOOTREPLY messages go from the servers, through BOOTP relay agents, back to the client. in no case does it represent a general IP router for the client to use. a BOOTP client MUST set the 'giaddr' field to zero (0.0.0.0) in all BOOTREQUEST messages it generates.
a BOOTP client MUST NOT interpret the 'giaddr' field of a BOOTREPLY message to be the IP address of an IP router. a BOOTP client SHOULD completely ignore the contents of the 'giaddr' field in BOOTREPLY messages ๐
โโ๏ธ
DISCUSSION:
the semantics of 'giaddr' were poorly defined. Section 7.5 of [1] says:
"If 'giaddr' (gateway address) is nonzero, then the packets should be forwarded there first, in order to get to the server."
in that sentence, "get to" is about the communication from the client to the server after the BOOTP exchange, like a TFTP session. unfortunately, the 'giaddr' field may hold the address of a BOOTP relay agent that isn't actually an IP router (according to [1], Section 8, fifth paragraph). in that case it's totally useless as a first hop for TFTP packets headed to the server, because by definition non-routers don't forward datagrams at the IP layer ๐ซ .
even though Section 4.1.1 of this memo now prohibits it, the 'giaddr' field might contain a broadcast address according to Section 8, sixth paragraph of [1]. that wouldn't just be useless as a router address, it could also make the client ARP for the broadcast address (since, if the client didn't get a subnet mask in the BOOTREPLY message, it couldn't recognize a subnet broadcast address). this is clearly undesirable ๐ค
to reach a non-local server, clients can grab a first-hop router address from the "Gateway" subfield of the "Vendor Information Extensions" [2] (if it's there), or through the ICMP router discovery protocol [5] or some other similar mechanism ๐
3.5 Vendor information "magic cookie" ๐
it is RECOMMENDED that a BOOTP client always fill the first four octets of the 'vend' (vendor information) field of a BOOTREQUEST with a four-octet identifier called a "magic cookie." a BOOTP client SHOULD do this even if it has no special info to send the BOOTP server through the 'vend' field. it helps the BOOTP server figure out which vendor information format it should use in its BOOTREPLY messages ๐งโโ๏ธ
if a special vendor-specific magic cookie isn't being used, a BOOTP client SHOULD use the dotted decimal value 99.130.83.99 as specified in [2]. in that case, if the client has no info to send the server, the octet right after the magic cookie SHOULD be set to the "End" tag (255), and the remaining octets of the 'vend' field SHOULD be set to zero ๐
DISCUSSION:
sometimes different operating systems or networking packages run on the same machine at different times (or even at the same time!) ๐. since the hardware address in the 'chaddr' field will probably be the same, BOOTREQUESTs from totally different BOOTP clients on the same machine will probably be hard for a BOOTP server to tell apart. if the client includes a magic cookie in its BOOTREQUESTs, the server will at least know what format the client expects and can understand in the matching BOOTREPLY messages ๐ซถ
4. BOOTP Relay Agents โจ
in lots of cases, BOOTP clients and their BOOTP server(s) don't live on the same IP network or subnet. when that happens, some kind of third-party agent is needed to shuttle BOOTP messages between clients and servers ๐. this agent was originally called a "BOOTP forwarding agent." but to avoid mixing it up with the IP forwarding function of an IP router, the name "BOOTP relay agent" is officially adopted instead ๐
DISCUSSION:
a BOOTP relay agent does a job that's different from an IP router's normal IP forwarding ๐ฆ. a router usually switches IP datagrams between networks more or less transparently, but a BOOTP relay agent is better thought of as receiving BOOTP messages as their final destination and then generating brand-new BOOTP messages because of them. it's incorrect for a relay agent implementation to just forward a BOOTP message "straight through like a regular packet" ๐ โโ๏ธ
this relay-agent functionality is most conveniently placed in the routers that connect the clients and servers, but it can also live in a host directly connected to the client subnet ๐ธ
any Internet host or router that provides BOOTP relay-agent capability MUST conform to the specifications in this memo ๐
4.1 General BOOTP Processing for Relay Agents ๐
all locally delivered UDP messages whose UDP destination port number is BOOTPS (67) get considered for special processing by the host or router's logical BOOTP relay agent ๐
for a host, locally delivered datagrams are simply all the datagrams that host normally receives, i.e., broadcast and multicast datagrams as well as unicast datagrams addressed to IP addresses of that host ๐
for a router, locally delivered datagrams are broadcast and multicast datagrams as well as unicast datagrams addressed to IP addresses of that router. these are datagrams where the router should be considered an end destination, not an intermediate switching node ๐ง. so a unicast datagram with an IP destination that doesn't match any of the router's IP addresses doesn't get considered for processing by the router's logical BOOTP relay agent ๐
hosts and routers are usually required to silently discard incoming datagrams with illegal IP source addresses. this is generally known as "Martian address filtering" ๐ฝ. one of those illegal addresses is 0.0.0.0 (or actually anything on network 0). but hosts or routers that support a BOOTP relay agent MUST accept for local delivery to the relay agent BOOTREQUEST messages whose IP source address is 0.0.0.0. BOOTREQUEST messages from legal IP source addresses MUST also be accepted โจ
a relay agent MUST silently discard any received UDP messages whose UDP destination port number is BOOTPC (68) ๐ซ
DISCUSSION:
there shouldn't be any reason for a relay agent to process messages addressed to the BOOTPC port ๐. reading the original BOOTP specification [1] carefully will show this. still, some relay agent implementations incorrectly relay those messages anyway ๐ค
the consistency checks specified in Section 2.1 SHOULD be performed by the relay agent. BOOTP messages that don't meet these consistency checks MUST be silently discarded ๐ซถ
4.1.1 BOOTREQUEST Messages
okay bestie, first things first ๐: some configuration mechanism MUST exist to switch the relaying of BOOTREQUEST messages on or off, and relaying MUST be disabled by default ๐ โโ๏ธ. nobody forwards anything without someone saying so.
when the BOOTP relay agent gets a BOOTREQUEST, it MAY look at the secs (seconds since client began booting) field and use it as one factor in deciding whether to relay. if you build a policy like that, its threshold SHOULD be configurable โ๏ธ
DISCUSSION:
honestly, this secs thing hasn't really been proven useful yet ๐คทโโ๏ธ see Section 3.2 for the tea.
the relay agent MUST silently discard BOOTREQUEST messages whose [source text missing here ๐ญ] provided to set this threshold to a smaller value if desired by the network manager. the default setting for a configurable threshold SHOULD be 4 ๐
if the relay agent does decide to relay the request, it MUST examine the 'giaddr' ("gateway" IP address) field. if that field is zero, the relay agent MUST fill it with the IP address of the interface the request came in on. if that interface has more than one IP address logically tied to it, the relay agent SHOULD pick one and use it consistently for every BOOTP message it relays ๐ if 'giaddr' already holds a non-zero value, it MUST NOT be modified. and the relay agent MUST NOT, under any circumstances, stuff a broadcast address into 'giaddr', even though [1] (Section 8, sixth paragraph) kinda suggests it. absolutely not ๐
the value of the hops field MUST be incremented โจ
all other BOOTP fields MUST be preserved intact ๐ซถ
then the request gets relayed to its new destination (or destinations). this destination MUST be configurable. and this destination config SHOULD be independent of the destination config for any other so-called "broadcast forwarders" (e.g., for the UDP-based TFTP, DNS, Time, etc. protocols) ๐ฆ
DISCUSSION:
the network manager might want the relay destination to be unicast, multicast, broadcast, or a mix ๐ a configurable list of destination IP addresses gives you great flexibility, and more flexible schemes are encouraged. for example, sending to the limited broadcast address (255.255.255.255) on specific physical interfaces might be the move. BUT, if the BOOTREQUEST came in as a broadcast, the relay agent MUST NOT rebroadcast it on the physical interface it came from ๐ โโ๏ธ
a relay agent MUST use the same destination (or set of destinations) for all BOOTREQUEST messages it relays from a given client ๐
DISCUSSION:
at least one known relay agent implementation uses round-robin to balance load across multiple BOOTP servers. every new BOOTREQUEST goes to the next server on the list. so multiple back-to-back BOOTREQUESTs from one client end up at different servers ๐ฉ
unfortunately, this well-intentioned scheme clashes with DHCP [3] and maybe other BOOTP variants that rely on multiple BOOTREQUEST and BOOTREPLY exchanges between clients and servers. so all BOOTREQUEST messages from a given client MUST be relayed to the same destination (or set of destinations) ๐ฅน
one way to keep that rule and still get some load-balancing perks is to hash the client's link-layer address (or some other reliable client-identifying info) and use the hash to pick the destination (or set of destinations). the simplest option, obviously, is no load balancing at all: just relay ALL received BOOTREQUEST messages to the same destination (or set of destinations) ๐ง
when the relay agent sends the request on to its next destination, it may set the IP Time-To-Live field to either the default value for new datagrams the relay agent originates, or to the TTL of the original BOOTREQUEST decremented by (at least) one โณ
DISCUSSION:
as an extra precaution against BOOTREQUEST loops, it's better to use the decremented TTL from the original BOOTREQUEST. unfortunately, that can be tricky to pull off in some implementations ๐
if the BOOTREQUEST has a UDP checksum (i.e., the UDP checksum is non-zero), the checksum must be recalculated before the request is transmitted ๐งฎ
4.1.2 BOOTREPLY Messages
BOOTP relay agents only relay BOOTREPLY messages to BOOTP clients ๐ it's the responsibility of BOOTP servers to send BOOTREPLY messages directly to the relay agent [source text missing here ๐ญ] identified in the BOOTREPLY messages it receives are intended for BOOTP clients on its directly-connected networks.
when a relay agent gets a BOOTREPLY message, it should look at the BOOTP 'giaddr', 'yiaddr', 'chaddr', 'htype', and [source text missing here ๐ญ] for the relay agent to deliver the BOOTREPLY message to the client ๐ฌ
the 'giaddr' field can be used to figure out which logical interface the reply has to go out from (the host or router interface connected to the same network as the BOOTP client) ๐บ๏ธ if the content of 'giaddr' doesn't match one of the relay agent's directly-connected logical interfaces, the BOOTREPLY message MUST be silently discarded ๐๏ธ
the 'htype', 'hlen', and 'chaddr' fields supply the client's link-layer hardware type, hardware address length, and hardware address, as defined in the ARP protocol [4] and the Assigned Numbers document [6]. the 'yiaddr' field is the client's IP address, as assigned by the BOOTP server ๐ฆ
the relay agent SHOULD check the newly-defined BROADCAST flag (see Sections 2.2 and 3.1.1 for more deets). if that flag is set to 1, the reply SHOULD go out as an IP broadcast, using the IP limited broadcast address 255.255.255.255 as the IP destination and the link-layer broadcast address as the link-layer destination ๐ฃ if the BROADCAST flag is cleared (0), the reply SHOULD go out as an IP unicast to the IP address in the 'yiaddr' field, with the link-layer address from the 'chaddr' field ๐ฏ if unicasting isn't possible, the reply MAY be sent as a broadcast instead. in that case it SHOULD go to the link-layer broadcast address, using 255.255.255.255 as the IP destination address ๐ธ
DISCUSSION:
the BROADCAST flag got added to the protocol as a workaround to help certain client implementations play nice ๐
the 'flags' field was previously defined in [1] as just an "unused" field, so old client or server implementations might accidentally and unknowingly set the new BROADCAST flag. this is expected to be rare (most implementations seem to zero out the field), but those interactions still have to be considered ๐ง if an old client or server sets the BROADCAST flag to 1 by mistake, conforming relay agents will generate broadcast BOOTREPLY messages to the matching client. the BOOTREPLY messages should still properly reach the client, at the cost of one (otherwise unnecessary) extra broadcast. that's no worse than a server or relay agent that always broadcasts its BOOTREPLY messages ๐คทโโ๏ธ
older client or server implementations that accidentally set the BROADCAST flag SHOULD be corrected so they properly comply with this newer specification ๐ ๏ธ
all BOOTP fields MUST be preserved intact ๐ซถ the relay agent MUST NOT modify any BOOTP field of the BOOTREPLY message when relaying it to the client ๐
the reply MUST have its UDP destination port set to BOOTPC (68) ๐ฏ
if the BOOTREPLY has a UDP checksum (i.e., the UDP checksum is non-zero), the checksum must be recalculated before the reply is transmitted ๐งฎ
5. BOOTP Server Behavior โจ
this section clears up how BOOTP servers are supposed to behave ๐ง
5.1 Reception of BOOTREQUEST Messages
all received UDP messages whose UDP destination port number is BOOTPS (67) are considered for processing by the BOOTP server ๐
hosts and routers are usually required to silently discard incoming datagrams with illegal IP source addresses. this is generally called "Martian address filtering" ๐ฝ one of those illegal addresses is 0.0.0.0 (or really anything on network 0). however, hosts or routers that support a BOOTP server MUST accept, for local delivery to the server, BOOTREQUEST messages whose IP source address is 0.0.0.0. BOOTREQUEST messages from legal IP source addresses MUST also be accepted ๐
a BOOTP server MUST silently discard any received UDP messages whose UDP destination port number is BOOTPC (68) ๐ซ
DISCUSSION:
there shouldn't be any reason for a BOOTP server to process messages addressed to the BOOTPC port ๐ read the original BOOTP specification [1] carefully and you'll see it too.
the consistency checks specified in Section 2.1 SHOULD be performed by the BOOTP server. BOOTP messages that don't pass these consistency checks MUST be silently discarded ๐๏ธ
5.2 Use of the 'secs' field
when the BOOTP server receives a BOOTREQUEST message, it MAY use the value of the 'secs' (seconds since client began booting) field as a factor in deciding whether and/or how to reply to the request โฑ๏ธ
DISCUSSION:
same tea as before: this feature hasn't necessarily been shown to be useful yet. see Section 3.2 ๐ซ
5.3 Use of the 'ciaddr' field
clients have interpreted the 'ciaddr' field in various ways, so check Section 3.3 for the full story ๐ต๏ธโโ๏ธ a BOOTP server SHOULD be ready to handle those different interpretations. in general, the [source text missing here ๐ญ] client; the contents of the 'ciaddr', 'chaddr', 'htype', and 'hlen' fields, and probably other information (perhaps in the 'file' and [source text missing here ๐ญ] respond to a given client ๐งฉ
BOOTP servers SHOULD preserve the contents of the 'ciaddr' field in BOOTREPLY messages. the contents of 'ciaddr' in a BOOTREPLY message SHOULD exactly match the contents of 'ciaddr' in the corresponding BOOTREQUEST message ๐ช
DISCUSSION:
it has been suggested that a client may want to use the contents of [source text missing here ๐ญ] indeed intended for it. the rest of that thought got cut off in my copy, so I can't fill it in ๐
[editor's note: this part's source text contains 17 MUST keywords, not 18. I haven't added any. The source is also missing several words in 4.1.1, 4.1.2, and 5.3, marked above.]
5.4 Strategy for Delivery of BOOTREPLY Messages ๐
Okay so once the BOOTP server has whipped up a proper BOOTREPLY message, that BOOTREPLY message must be properly delivered to the client ๐
The server SHOULD check the ciaddr field first ๐ If ciaddr is non-zero, the BOOTREPLY SHOULD go out as an IP unicast to whatever IP address is in ciaddr. The UDP destination port MUST be set to BOOTPC (68) ๐ซถ Heads up though, the server MUST be aware of the problems in Section 3.3, because that part is lowkey messy ๐ญ The server MAY also choose to ignore ciaddr and act like it holds 0.0.0.0 (and then keep going with the rest of the delivery algorithm below) ๐ฆ
Next up, the server SHOULD check the giaddr field ๐
If it's non-zero, the server SHOULD send the BOOTREPLY as an IP unicast to the IP address in giaddr. The UDP destination port MUST be set to BOOTPS (67) ๐ง This basically delivers the BOOTREPLY straight to the BOOTP relay agent closest to the client, and then the relay agent handles the final delivery to the client, which is so iconic ๐ If the BOOTP server somehow knows that a certain client can't receive unicast BOOTREPLY messages (like the network manager explicitly told the server that's the case), the server MAY set the newly-defined BROADCAST flag so that relay agents SHOULD broadcast the BOOTREPLY to the client ๐ Otherwise, the server MUST preserve the state of the BROADCAST flag so the relay agent can act on it correctly ๐
If giaddr is set to 0.0.0.0, then the client is chilling on one of the same networks as the BOOTP server ๐ The server SHOULD examine the newly-defined BROADCAST flag (see Sections 2.2, 3.1.1 and 4.1.2 for more information) โจ If that flag is set to 1, or the server has prior knowledge that the client can't receive unicast BOOTREPLY messages, the reply SHOULD be sent as an IP broadcast, using the IP limited broadcast address 255.255.255.255 as the IP destination address and the link-layer broadcast address as the link-layer destination address ๐ข If the BROADCAST flag is cleared (0), the reply SHOULD be sent as an IP unicast to the IP address in the field ๐ฏ If unicasting isn't possible, the reply MAY be sent as a broadcast, and in that case it SHOULD go to the link-layer broadcast address with 255.255.255.255 as the IP destination address ๐ No matter what, the UDP destination port MUST be set to BOOTPC (68) ๐
DISCUSSION ๐ฌ
Adding the BROADCAST flag to the protocol is basically a workaround, and it helps promote interoperability with certain client implementations. It's giving "we had to patch it so everyone can get along" ๐ซถ
Here's the summary table for how the server decides delivery of BOOTREPLY messages, based on what's in the BOOTREQUEST messages ๐
BOOTREQUEST fields BOOTREPLY values for UDP, IP, link-layer
+-----------------------+-----------------------------------------+
| 'ciaddr' 'giaddr' B | UDP dest IP destination link dest |
+-----------------------+-----------------------------------------+
| non-zero X X | BOOTPC (68) 'ciaddr' normal |
| 0.0.0.0 non-zero X | BOOTPS (67) 'giaddr' normal |
| 0.0.0.0 0.0.0.0 0 | BOOTPC (68) 'yiaddr' 'chaddr' |
| 0.0.0.0 0.0.0.0 1 | BOOTPC (68) 255.255.255.255 broadcast |
+-----------------------+-----------------------------------------+
B = BROADCAST flag
X = Don't care
normal = determine from the given IP destination using normal
IP routing mechanisms and/or ARP as for any other
normal datagram
Acknowledgements ๐
The author would like to thank Gary Malkin for his contribution of the "BOOTP over IEEE 802.5 Token Ring Networks" section, and Steve Deering for his observations on the problems associated with the 'giaddr' field ๐ธ
Ralph Droms and the many members of the IETF Dynamic Host Configuration and Router Requirements working groups provided ideas for this memo, plus encouragement to write it ๐
Philip Almquist and David Piscitello offered many helpful suggestions for improving the clarity, accuracy, and organization of this memo. These contributions are graciously acknowledged โจ
References ๐
[1] Croft, B., and J. Gilmore, "Bootstrap Protocol (BOOTP)", RFC 951,
Stanford University and Sun Microsystems, September 1985.
[2] Reynolds, J., "BOOTP Vendor Information Extensions", RFC 1497,
USC/Information Sciences Institute, August 1993. This RFC is
occasionally reissued with a new number. Please be sure to
consult the latest version.
[3] Droms, R., "Dynamic Host Configuration Protocol", RFC 1531,
Bucknell University, October 1993.
[4] Plummer, D., "An Ethernet Address Resolution Protocol", STD 37,
RFC 826, MIT, November 1982.
[5] Deering, S., "ICMP Router Discovery Messages", RFC 1256, Xerox
PARC, September 1991.
[6] Reynolds, J., and J. Postel, "Assigned Numbers", STD 2, RFC 1340,
USC/Information Sciences Institute, July, 1992. This RFC is
periodically reissued with a new number. Please be sure to
consult the latest version.
Security Considerations ๐จ
Bestie, this part is serious, so read it carefully ๐ญ
There are many factors which make BOOTP in its current form quite insecure. BOOTP is built directly upon UDP and IP, which are as yet inherently insecure themselves ๐ Furthermore, BOOTP is generally intended to make maintenance of remote and/or diskless hosts easier. While perhaps not impossible, configuring such hosts with passwords or keys may be difficult and inconvenient. This makes it difficult to provide any form of reasonable authentication between servers and clients ๐
Unauthorized BOOTP servers may easily be set up. Such servers can then send false and potentially disruptive information to clients, such as incorrect or duplicate IP addresses, incorrect routing information (including spoof routers, etc.), incorrect domain nameserver addresses (such as spoof nameservers), and so on. Clearly, once this "seed" mis-information is planted, an attacker can further compromise the affected systems ๐ฅ
Unauthorized BOOTP relay agents may present some of the same problems as unauthorized BOOTP servers ๐ง๏ธ
Malicious BOOTP clients could masquerade as legitimate clients and retrieve information intended for those legitimate clients. Where dynamic allocation of resources is used, a malicious client could claim all resources for itself, thereby denying resources to legitimate clients ๐ค
Author's Address ๐๏ธ
Walt Wimer
Network Development
Carnegie Mellon University
5000 Forbes Avenue
Pittsburgh, PA 15213-3890
Phone: (412) 268-6252
EMail: Walter.Wimer@CMU.EDU
๐ฆ where this page comes from
- ietf: rfc1532 1993-10
- ๐ girlified by claude-haiku-5-5 on : a language model's rewrite of the original, under its terms