RFC 1532

Clarifications and Extensions for the Bootstrap Protocol

๐Ÿ“… published October 1993, from ietf

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 ๐ŸŒˆ


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