RFC 1542
Clarifications and Extensions for the Bootstrap Protocol
Clarifications and Extensions for the Bootstrap Protocol ๐
okay bestie, this is RFC 1542 ๐ It was written by W. Wimer at Carnegie Mellon University, it's dated October 1993, it's a Standards Track doc in the Network Working Group, and it updates RFC 951 and obsoletes RFC 1532 ๐ฆ The RFC 1532 thing is a whole story (more on that in the Abstract โจ)
Status of this Memo ๐
This RFC specifies an Internet standards track protocol for the Internet community, and it's asking everyone for discussion and suggestions for improvements ๐ซถ For the current standardization state and status of this protocol, check the current edition of the "Internet Official Protocol Standards." And distribution of this memo is unlimited, so share away ๐
Abstract โจ
so BOOTP was kinda loosely defined in its original spec ๐ The behavior of "BOOTP relay agents" (which were originally called "BOOTP forwarding agents") only got a general description, and the client side was a little messy too. This memo is here to clarify and strengthen all of that ๐ช It's being reissued as RFC 1542 because some errors slipped into RFC 1532 during editing ๐ญ
New issues have also popped up since the original spec was written, and this memo tries to handle some of those too ๐ฅ
Table of Contents ๐ธ
1. Introduction................................................. 2
1.1 Requirements................................................ 3
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.............................. 10
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................... 14
4.1.1 BOOTREQUEST Messages...................................... 14
4.1.2 BOOTREPLY Messages........................................ 17
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................. 20
Acknowledgements................................................ 21
References...................................................... 22
Security Considerations......................................... 23
Author's Address................................................ 23
1. Introduction ๐ธ
the Bootstrap Protocol (BOOTP) is a UDP/IP-based protocol that lets a host boot up and configure itself dynamically, no babysitting required ๐ง It tells a 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].
the problem is the original BOOTP spec [1] left a bunch of stuff up for debate ๐ How BOOTP relay agents (formerly called "BOOTP forwarding agents") were supposed to behave wasn't clearly specified. Some parts of the spec actually conflict with each other, and other parts got misinterpreted, so clarification was needed. This memo handles those issues ๐
then the IEEE 802.5 Token Ring Network came along, and it creates a unique problem for BOOTP's message-transfer paradigm ๐ This memo also suggests a solution for that ๐ฆ
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]. (so yes, this applies to DHCP too unless something says otherwise ๐ซถ)
1.1 Requirements ๐
in this memo, the words that define how important a requirement is get capitalized. Here they are, and yes, they're serious ๐ซก
- "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:
- 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 discards the message without further processing, and it won't 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 ๐
1.3 Data Transmission Order ๐ข
the order of transmission for the header and data in this document is resolved all the way down 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. For example, 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 number, the leftmost bit in the diagram is the high order (most significant) bit. So the bit labeled 0 is the most significant one. For example, this diagram shows the value 170 in decimal ๐งฎ
0 1 2 3 4 5 6 7
+-+-+-+-+-+-+-+-+
|1 0 1 0 1 0 1 0|
+---------------+
same vibe for multi-octet fields: the leftmost bit of the whole field is the most significant bit, and when a multi-octet number gets sent, the most significant octet goes first ๐
2. General Issues ๐งฉ
this section covers stuff that matters to all BOOTP entities: 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. (so bigger messages are totally welcome, no drama ๐ธ)
- 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 that don't pass these consistency checks MUST be silently discarded. ๐๏ธ no cap, that's the rule ๐
(to be continued โจ๐ฆ)
2.2 Definition of the 'flags' Field โจ
okay so the standard BOOTP message format from [1] has this two-octet field chilling between secs and ciaddr ๐ฆ. it's literally just labeled "unused" and nobody said what goes in it ๐. Section 7.1 of [1] does give this lowkey good advice:
"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 is like "bet, we're officially naming this field flags" ๐
the most significant bit gets to be the BROADCAST (B) flag ๐ฃ. we talk about what it actually does in Sections 3.1.1 and 4.1.2.
the rest of the bits are reserved for future use ๐ฎ. they MUST be set to zero by clients and ignored by servers and relay agents. no exceptions, bestie ๐
here's the layout ๐
0 1
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|B| MBZ |
+-+-----------------------------+
and the key ๐
where:
B BROADCAST flag (discussed in Sections 3.1.1 and 4.1.2)
MBZ MUST BE ZERO (reserved for future use)
now for the full BOOTP message format ๐ง 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 ๐งฒ
the bit ordering for link-level hardware addresses in the chaddr field SHOULD match the ordering ARP [4] uses on the client's link-level network (assuming ARP is defined for that network) ๐
the chaddr field MUST be kept exactly as the BOOTP client wrote it. a relay agent MUST NOT flip the bit ordering of chaddr, even if it's relaying a BOOTREQUEST between two networks that order bits differently ๐
โโ๏ธ
DISCUSSION:
the whole reason chaddr exists is so BOOTP servers and relay agents can talk straight to clients without broadcasting ๐ก. in practice, the chaddr contents often get used to make an ARP-cache entry, the same way normal ARP would ๐๏ธ. so yeah, interoperability only works if everyone reads chaddr the same way ๐ซถ
for example, a BOOTP client on an IEEE 802.5 Token Ring network uses the opposite bit ordering from a BOOTP client on a DIX ethernet network. wild, right? ๐คฏ
2.4 BOOTP Over IEEE 802.5 Token Ring Networks ๐
client/server and client/relay agent interactions need extra care on IEEE 802.5 networks, because of 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 the return route (because they're stateless, for example), the BOOTREPLY SHOULD be sent to the client's hardware address, taken from the BOOTP message, with a Spanning Tree Rooted RIF ๐ณ. the actual bridge route then gets recorded by the client and the server or relay agent through normal ARP processing ๐
DISCUSSION:
in the simplest case, an unbridged, single ring network, BOOTP broadcasting works exactly like it does on Ethernet ๐ฅฐ. the problem is that a BOOTP client can't know, ahead of time, that its 802.5 network isn't bridged. the server or relay agent probably won't know either ๐คทโโ๏ธ
there are four possible scenarios, but only two are actually interesting ๐:
- the assumption is "not bridged" and the network IS bridged. then the RIF won't be used, so if the server or relay agent sits on another segment of the ring, the client can't reach it ๐
- the assumption is "bridged" and the network is NOT. then the RIF gets used, which adds a few extra bytes on the ring ๐ง
the second one is totally the lesser evil. a tiny inefficiency beats a complete failure to communicate ๐ซ
since we're assuming RIF fields will be needed, we have to figure out the optimum way for the client to reach the server or relay agent, AND the optimum way for the response to come back ๐ฏ
3. BOOTP Client Behavior ๐
this section clears up a few 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 using unicast. 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 chaddr address. the catch is that some clients can't receive unicast IP datagrams until they already know their own IP address. it's a total "chicken and egg" situation ๐๐ฅ still, a lot of them can receive broadcast IP datagrams (ones with a valid IP broadcast address as the IP destination and the link-layer broadcast address as the link-layer destination) ๐ข
if a client is in that boat, it SHOULD set (to 1) the newly-defined BROADCAST flag in the flags field of the BOOTREPLY messages it generates ๐ฉ. that's a hint telling servers and relay agents to broadcast their BOOTREPLY messages to the client ๐
if a client doesn't have that limitation (it can totally receive unicast BOOTREPLY messages), it SHOULD NOT set the BROADCAST flag (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 would make this workaround unnecessary. in general, 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 it generates. a client MUST ignore these bits in every BOOTREPLY it receives ๐ซถ
3.2 Definition of the 'secs' field โฑ๏ธ
the secs field of a BOOTREQUEST message SHOULD represent the number of seconds elapsed since the client sent its first BOOTREQUEST message โณ. which means the secs field of that very first BOOTREQUEST SHOULD be set to zero 0๏ธโฃ
clients SHOULD NOT set secs 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 counted from the first BOOTREQUEST or from something else, like when the client machine was powered up. that made it pretty useless as a policy control mechanism for BOOTP servers and relay agents ๐. on top of that, some client implementations have been known to just set this field to a constant value, or to use the wrong byte ordering. the wrong byte ordering makes it look like a client has been waiting way longer than it really has, so a relay agent ends up relaying the BOOTREQUEST sooner than intended (usually immediately) ๐โโ๏ธ๐จ. these implementation errors made secs even less useful ๐ค. those 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 should be using, it SHOULD set the 'ciaddr' field to 0.0.0.0 ๐ซถ. If the client can remember the last IP address it was given, or it was preconfigured with one some other way, it MAY fill 'ciaddr' with that address. But if it DOES put a non-zero address in 'ciaddr', it MUST be prepared to accept incoming unicast datagrams sent to that address AND answer ARP requests for it (if ARP is used on that network) ๐
โจ.
The BOOTP server is totally free to hand out a different IP address (in 'yiaddr') than the one the client put in 'ciaddr' ๐ฆ. The client SHOULD adopt the address in 'yiaddr' and start using it as soon as possible ๐ธ.
DISCUSSION: ๐ฌ
ngl this part is a whole debate ๐. People have different takes on what 'ciaddr' is even for, and there's no agreed single correct answer. One take is that if a client is happy to accept whatever address the server assigns, it should always put 0.0.0.0 in 'ciaddr', even if it remembers an old address. The flip side is that if the client needs a specific IP address (say the admin hand-configured it and BOOTP is only being used to grab a boot file and/or info from the 'vend' field), then it fills 'ciaddr' with the address it wants and ignores whatever 'yiaddr' says ๐ค.
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. This client still accepts and uses the address in 'yiaddr'. The reason people like this one is that it helps the server identify the client and/or deliver the BOOTREPLY to it ๐ง.
Then there's a third (mis)interpretation, where the client uses 'ciaddr' to ask for whatever IP it wants, even if it's never used that address before or isn't using it right now. Honestly, this one is giving chaos ๐.
That last one is just incorrect, because it can stop the BOOTREPLY from ever reaching the client. The server will usually unicast the reply to the address in 'ciaddr', but the client might not be listening on that address yet, or it might be plugged into the wrong subnet, so normal IP routing (correctly!) sends the reply somewhere else ๐ญ.
The second take also has the "incorrect subnet" problem ๐.
The first interpretation seems to be the safest and the most likely to keep everyone interoperable ๐.
3.4. Interpretation of the 'giaddr' field ๐
The 'giaddr' field is kinda poorly named, not gonna lie ๐. Its whole job is to help BOOTREQUEST messages get from a client, through BOOTP relay agents, to servers on different networks than the client. Likewise, it helps BOOTREPLY messages travel from the servers, through relay agents, back to the client. It is NEVER a general IP router for the client to use ๐ซ. A BOOTP client MUST set 'giaddr' 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 as 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 honestly not well 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 ๐ฆ. The problem is that 'giaddr' might 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 useless as a first hop for TFTP packets going 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, 'giaddr' might contain a broadcast address according to Section 8, sixth paragraph of [1]. That's not only useless as a router address, it could also make the client ARP for the broadcast address. (If the client didn't get a subnet mask in the BOOTREPLY, it wouldn't be able to recognize a subnet broadcast address.) This is clearly undesirable, bestie ๐
โโ๏ธ.
To reach a server that isn't local, clients can get 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 to the BOOTP server through the 'vend' field ๐ซถ. It helps the server figure out which vendor information format to 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 this case, if the client has no info to send to 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!) ๐คฏ. The hardware address in the 'chaddr' field will probably be the same every time, so BOOTREQUESTs from totally different BOOTP clients on the same machine will be super hard for a BOOTP server to tell apart ๐ต. If the client includes a magic cookie in its BOOTREQUESTs, though, the server will at least know what format the client expects and can understand in the matching BOOTREPLY messages ๐.
4. BOOTP Relay Agents โจ
In a lot 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 carry 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 hereby adopted instead ๐ .
DISCUSSION: ๐ฌ
A BOOTP relay agent does a different job from an IP router's normal IP forwarding ๐ฆ. A router normally switches IP datagrams between networks more or less transparently. A BOOTP relay agent is better thought of as receiving BOOTP messages as their final destination, and then generating brand-new BOOTP messages as a result ๐ง . 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 put in the routers that connect the clients and servers, but it can also live in a host that's 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 count as the end destination, not just 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 that contain illegal IP source addresses. This is generally known as "Martian address filtering" ๐ป. One of those illegal addresses is 0.0.0.0 (or really anything on network 0). But hosts or routers that support a BOOTP relay agent MUST accept BOOTREQUEST messages whose IP source address is 0.0.0.0 for local delivery to the relay agent ๐ซถ. 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 need for a relay agent to process messages addressed to the BOOTPC port. If you read the original BOOTP specification [1] carefully, you'll see 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 pass these consistency checks MUST be silently discarded ๐๏ธ.
4.1.1 BOOTREQUEST Messages
okay so ๐ some configuration mechanism MUST exist to turn the relaying of BOOTREQUEST messages on or off. And relaying MUST be disabled by default, no cap ๐
When the BOOTP relay agent gets a BOOTREQUEST message, it MAY use the value of the 'secs' (seconds since client began booting) field of the request as a factor in deciding whether to relay it ๐ฆ. If a policy mechanism like that is implemented, its threshold SHOULD be configurable โจ.
DISCUSSION: To date, this feature of the BOOTP protocol has not necessarily been shown to be useful ๐. See Section 3.2 for a discussion.
The relay agent MUST silently discard BOOTREQUEST messages whose 'hops' field exceeds the value 16 ๐ซ. A configuration option SHOULD be provided to set this threshold to a smaller value if the network manager wants that ๐. 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 this field is zero, the relay agent MUST fill it with the IP address of the interface the request was received on. If that interface has more than one IP address logically associated with it, the relay agent SHOULD choose one of them and use it consistently for all BOOTP messages it relays ๐ . If the 'giaddr' field contains some non-zero value, the 'giaddr' field MUST NOT be modified. The relay agent MUST NOT, under any circumstances, fill the 'giaddr' field with a broadcast address, even though [1] (Section 8, sixth paragraph) kinda suggests it ๐ โโ๏ธ.
The value of the 'hops' field MUST be incremented โจ. All other BOOTP fields MUST be preserved intact ๐ซถ.
At this point the request gets relayed to its new destination (or destinations). This destination MUST be configurable. Further, this destination configuration SHOULD be independent of the destination configuration 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 an IP unicast, multicast, broadcast, or some combo ๐ฐ. A configurable list of destination IP addresses gives you lots of flexibility, and more flexible configuration schemes are super encouraged ๐. For example, it might be nice to send to the limited broadcast address (255.255.255.255) on specific physical interfaces. However, if the BOOTREQUEST message was received as a broadcast, the relay agent MUST NOT rebroadcast the BOOTREQUEST 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 a round-robin scheme to balance load across multiple BOOTP servers ๐ก. Each time it gets a new BOOTREQUEST message, it relays it to the next BOOTP server in a list of servers. So with this relay agent, multiple consecutive BOOTREQUEST messages from a given client end up at different servers ๐ญ. Unfortunately, this well-intentioned scheme reacts badly with DHCP [3] and maybe other variations of the BOOTP protocol that depend on multiple exchanges of BOOTREQUEST and BOOTREPLY messages between clients and servers ๐. Therefore, all BOOTREQUEST messages from a given client MUST be relayed to the same destination (or set of destinations). One way to meet this requirement while still getting some load-balancing benefit is to hash the client's link-layer address (or some other reliable client-identifying information) and use the hash value to pick the relay destination (or set of destinations) ๐ง . The simplest solution, of course, is to skip load balancing and just relay ALL received BOOTREQUEST messages to the same destination (or set of destinations) ๐ซ . When transmitting the request to its next destination, the relay agent may set the IP Time-To-Live field to either the default value for new datagrams originated by the relay agent, or to the TTL of the original BOOTREQUEST decremented by (at least) one ๐ฆ. As an extra precaution against BOOTREQUEST loops, it is preferable to use the decremented TTL from the original BOOTREQUEST ๐ก๏ธ. Unfortunately, this may be difficult to do in some implementations ๐ฉ.
If the BOOTREQUEST has a UDP checksum (i.e., the UDP checksum is non-zero), the checksum must be recalculated before transmitting the request ๐.
4.1.2 BOOTREPLY Messages
BOOTP relay agents relay BOOTREPLY messages only to BOOTP clients ๐ฏ. It's the responsibility of BOOTP servers to send BOOTREPLY messages directly to the relay agent identified in the 'giaddr' field. So a relay agent can assume that every BOOTREPLY message it receives is meant for BOOTP clients on its directly-connected networks ๐ฅฐ.
When a relay agent receives a BOOTREPLY message, it should examine the BOOTP 'giaddr', 'yiaddr', 'chaddr', 'htype', and 'hlen' fields ๐. These fields should give it enough info to deliver the BOOTREPLY message to the client.
The 'giaddr' field can be used to identify the logical interface the reply must be sent from (i.e., the host or router interface connected to the same network as the BOOTP client) ๐ฃ๏ธ. If the content of the 'giaddr' field 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 link-layer hardware type, hardware address length, and hardware address of the client, as defined in the ARP protocol [4] and the Assigned Numbers document [6] ๐. The 'yiaddr' field is the IP address of the client, as assigned by the BOOTP server ๐ก.
The relay agent SHOULD examine the newly-defined BROADCAST flag (see Sections 2.2 and 3.1.1 for more info) ๐ฉ. If this flag is set to 1, 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 specified by the 'yiaddr' field and the link-layer address specified in the 'chaddr' field ๐ฏ. If unicasting isn't possible, the reply MAY be sent as a broadcast, in which case it SHOULD be sent to the link-layer broadcast address using the IP limited broadcast address 255.255.255.255 as the IP destination address ๐.
DISCUSSION: The BROADCAST flag got added to the protocol as a workaround to help with interoperability with certain client implementations ๐ฉน. Note that since the 'flags' field was previously defined in [1] simply as an "unused" field, it's possible that old client or server implementations may accidentally and unknowingly set the new BROADCAST flag ๐. It's actually expected that this will be rare (most implementations seem to zero out this field), but interactions with such implementations 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 corresponding client. The BOOTREPLY messages should still properly reach the client, at the cost of one (otherwise unnecessary) extra broadcast. This is 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 to 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 transmitting the reply โป๏ธ.
5. BOOTP Server Behavior
This section clarifies the behavior of BOOTP servers ๐.
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 containing illegal IP source addresses. This is generally known as "Martian address filtering." One of these illegal addresses is 0.0.0.0 (or actually 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 should be no need for a BOOTP server to process messages addressed to the BOOTPC port. Careful reading of the original BOOTP specification [1] will show this ๐. The consistency checks specified in Section 2.1 SHOULD be performed by the BOOTP server ๐ง. BOOTP messages that don't meet 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 of the request as a factor in deciding whether and/or how to reply to the request โฑ๏ธ.
DISCUSSION: To date, this feature of the BOOTP protocol has not necessarily been shown to be useful ๐. See Section 3.2 for a discussion.
5.3 Use of the 'ciaddr' field
There have been various client interpretations of the 'ciaddr' field, so Section 3.3 should be consulted ๐ค. A BOOTP server SHOULD be prepared to deal with these varying interpretations ๐ซก. In general, the 'ciaddr' field SHOULD NOT be trusted as a sole key for identifying a client. The contents of the 'ciaddr', 'chaddr', 'htype', and 'hlen' fields, and probably other info (perhaps in the 'file' and 'vend' fields), SHOULD all be considered together when deciding how to 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's been suggested that a client may want to use the contents of 'ciaddr' to double-check that a particular BOOTREPLY message was really meant for it ๐ต๏ธโโ๏ธโจ.
5.4. Strategy for Delivery of BOOTREPLY Messages ๐ฌ
Okay bestie, so once the BOOTP server has cooked up a shiny BOOTREPLY message ๐ณ, that message must be properly delivered to the client. No skipping this step, it's giving main character stakes โจ
The server SHOULD first check the 'ciaddr' field ๐. If the 'ciaddr' field is non-zero, the BOOTREPLY message SHOULD be sent as an IP unicast to the IP address identified in the 'ciaddr' field. The UDP destination port MUST be set to BOOTPC (68). But ngl, the server MUST be aware of the problems identified in Section 3.3 ๐. The server MAY choose to ignore the 'ciaddr' field and act as if the 'ciaddr' field contains 0.0.0.0 (and thus continue with the rest of the delivery algorithm below) ๐ฆ.
Next up, the server SHOULD check the 'giaddr' field ๐. If this field is non-zero, the server SHOULD send the BOOTREPLY as an IP unicast to the IP address identified in the 'giaddr' field. The UDP destination port MUST be set to BOOTPS (67). This action delivers the BOOTREPLY message directly to the BOOTP relay agent closest to the client, and then the relay agent handles the final delivery to the client ๐ง. If the BOOTP server has prior knowledge that a particular client cannot receive unicast BOOTREPLY messages (for example, the network manager has explicitly configured the server with that knowledge), the server MAY set the newly-defined BROADCAST flag to indicate that relay agents SHOULD broadcast the BOOTREPLY message to the client. Otherwise, the server MUST preserve the state of the BROADCAST flag so that the relay agent can correctly act upon it ๐ซถ.
If the 'giaddr' field is set to 0.0.0.0, then the client lives 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 this flag is set to 1, or the server has prior knowledge that the client is unable to 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 specified by the 'yiaddr' field and the link-layer address specified in the 'chaddr' field. If unicasting is not possible, the reply MAY be sent as a broadcast, in which case it SHOULD be sent to the link-layer broadcast address using the IP limited broadcast address 255.255.255.255 as the IP destination address. In any case, the UDP destination port MUST be set to BOOTPC (68) ๐ .
Discussion:
Adding the BROADCAST flag was a little workaround ๐ ๏ธ to help promote interoperability with certain client implementations ๐ค. Here's the cheat sheet for how the server picks delivery based on what's in the BOOTREQUEST ๐:
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 ๐ซถ
Huge thanks to Gary Malkin for his contribution of the "BOOTP over IEEE 802.5 Token Ring Networks" section, and to 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, as well as 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 1541, 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 ๐
Okay, this is the scary part ๐ฌ. BOOTP in its current form is quite insecure, for a bunch of reasons. It's 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. So it's hard to provide any form of reasonable authentication between servers and clients ๐ฅบ.
Unauthorized BOOTP servers are super easy to set up ๐. They can then send false and potentially disruptive information to clients, like 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: rfc1542 1993-10
- ๐ girlified by claude-haiku-5-5 on : a language model's rewrite of the original, under its terms