Analysis of the Use of the Boot Server Discovery Protocol in NetBoot

* Introduction

NetBoot uses the Boot Server Discovery Protocol (BSDP) to communicate network boot image options between clients and servers. BSDP is implemented within the Vendor Options of DHCP as defined in RFC 2132. Options not present within the DHCP specification are provided as vendor-specific information.

Understanding the content of the DHCP and BSDP communication between servers and clients can provide excellent insight for troubleshooting the NetBoot process. In this article I explain the components of a typical DHCP packet, dig deeper into the vendor options and BSDP-specific options, then I describe the NetBoot process from the NetBoot server perspective.

The following diagram provides a visual description of the flow of traffic between a NetBooting client, a DHCP server, and a NetBoot server during the initial phase of the NetBoot process.

Diagram of the DHCP and BSDP exchange between a NetBoot client and servers.

The first half of this phase is a standard DHCP exchange. This article will not delve into a DHCP exchange, but it is worthwhile to understand the basic anatomy of a DHCP packet.


* DHCP Packet -- Basic Components

The following is a DHCP ACK[SELECT] packet from a NetBoot server.

A DHCP ACK[SELECT] packet from a NetBoot server.
IP Header 4 = IP version
5 = IHL (Internet Hdr. Length) = 20 bytes
00 = Type of Service
0199 = 409 = packet length
a4eb = 42219 = id
0 = Flags
000 = Fragment offset
40 = 64 = ttl
11 = 17 = protocol (17 = UDP)
be3e = header checksum
0a00 010b = 10.0.1.11 = packet source
0a00 0120 = 10.0.1.32 = packet target
UDP Header
0043 = 67 = source port
0044 = 68 = target port
0185 = 389 = packet length
7966 = UDP header checksum

DHCP payload (RFC 951)
02 = 2 = opcode type (BOOTREPLY)
01 = 1 = hardware address type
06 = 6 = MAC address length
00 = 0 = hops
0000 9214 = 0x9214 = transaction ID
0000 = 0 = seconds since boot time
DHCP payload (RFC 951)
0000 = flags (unused)
0a00 0120 = Client IP Address
0000 0000 = "Your" IP address
0a00 010b = Server IP = 10.0.1.11
0000 0000 = Gateway IP address
0x0034 -- 0x0043 = Client MAC address
0x0044 -- 0x0083 = Server Hostname
0x0084 -- 0x0103 = Boot file

DHCP Vendor Extensions (RFC 1048)
6382 5363 = (99,130,83,99) = Magic #
0x0106 -- 0x0*** = Vendor options

* Vendor Specific Information Analysis

The vendor specific information portion of a DHCP packet begins at octet # 0x0104. This portion of the packet is defined by specifying the RFC 1048 "Magic Number" -- a sequence of numbers that indicates that the following portion of the packet is encoded as a sequence of code/length/value fields intended for transmitting vendor-specific information between clients and servers. I will take the packet trace from the previous page as an example:

Vendor-specific portion of a DHCP ACK[SELECT] packet from a NetBoot server.

To read the options in the vendor specific information option, start with the first octet after the magic number. Using the example above, "35" (hexadecimal) is the option "code", which, according to RFC 2132 corresponds to (ASCII 53) "DHCP Message". The length of the data in this option is "01" octets. The value of this option is contained within the next "01" octets which contains "05". This value is defined as the DHCP message "ACK" by RFC 2132.

The next code/length/value chunk starts with "36", is 4 octets long, and has the value "0a00010b". 36 corresponds to ASCII 54, which represents the "Server ID" DHCP tag. The value type of that tag is IP notation, therefore the value translates to "10.0.1.11". The full translation of this packet is described in the following table.

Code Tag Value
35 (53) DHCP Message DHCP DISCOVER
36 (54) Server ID 10.0.1.11
3c (60) Vendor Class AAPLBSDPC
11 (17) Root Path nfs:10.0.1.11:/Volumes/Sto...Restore.dmg
2b (43) Vendor Options 01010208 ... 74303031

The Vendor Options value is "opaque". While the format follows the same code/length/value format as the Vendor Specific Information option, the option codes are defined by the vendor rather than an RFC. NetBoot leverages the Vendor Options option for communicating BSDP messages between the server and the client.

Applying the same reading technique to the Vendor Options value, we can see that the packet contains BSDP options 1, 8, and 130 (0x82). By examining the bootpd source code (or simply its debug output), you can ascertain the tags for each of these codes so that you can understand the value of that option.

Code Tag Value
01 (1) BSDP Message Type SELECT
08 (8) Selected Boot Image 0x8100052a (Image ID: 1322)
82 (130) Machine Name NetBoot001

Other BSDP options that you will see used for NetBoot are listed in the following table.

Code Tag
1 BSDP Message Type (1: LIST, 2: SELECT, 3: FAILED)
2 BSDP Version
3 Server ID
4 Server Priority
5 Reply Port
7 Default Boot Image
8 Selected Boot Image
9 Boot Image List (ID [4 octets], Name length [1 octet], Name. [n octets])

* NetBoot from bootpd's perspective

Deciphering the Vendor Options from a packet trace can be done, but it is far easier to simply allow bootpd to provide the translated information via verbose mode, especially when it comes to deciphering the BSDP-specific vendor options. To place bootpd into verbose, non-daemon mode, run the following with root privileges on Mac OS 10.4+ Server:

launchctl unload /System/Library/LaunchDaemons/bootps.plist
defaults write /System/Library/LaunchDaemons/bootps StandardOutPath /Library/Logs/bootpd.log
defaults write /System/Library/LaunchDaemons/bootps StandardErrorPath /Library/Logs/bootpd.error.log
defaults write /System/Library/LaunchDaemons/bootps ProgramArguments -array "/usr/libexec/bootpd" "-dv"
plutil -convert xml1 /System/Library/LaunchDaemons/bootps.plist
launchctl load /System/Library/LaunchDaemons/bootps.plist

To discontinue verbose mode and restore standard NetBoot server functionality:

launchctl unload /System/Library/LaunchDaemons/bootps.plist
defaults delete /System/Library/LaunchDaemons/bootps StandardOutPath
defaults delete /System/Library/LaunchDaemons/bootps StandardErrorPath
defaults write /System/Library/LaunchDaemons/bootps ProgramArguments -array "/usr/libexec/bootpd" "-v"
plutil -convert xml1 /System/Library/LaunchDaemons/bootps.plist
launchctl load /System/Library/LaunchDaemons/bootps.plist

Examine the bootpd.* logs in /Library/Logs to see the debug information. When bootpd is first fired up (e.g. when the first client tries to NetBoot), it will display basic information such as which network interfaces it is monitoring and routing information:

bootpd[27240]: server starting
bootpd[27240]: interface en0: ip 10.0.1.11 mask 255.255.0.0
default: 10.0.1.1
10.0 ==> link 4
127 ==> link 0
169.254 ==> link 4

Notice the lines that start with "bootpd" -- these lines are what you would normally see in the system.log file. The number in brackets is the process id of bootpd.

If you open the Startup Disk Preference Pane on a client machine, or NetBoot a client, then bootpd will activate. Upon activation, bootpd initializes any DHCP subnets based on information kept in NetInfo. It also reads any NetBoot configuration information kept in NetInfo. See the bootpd man page for more details on configuration information kept in NetInfo.

bootpd[27240]: opening hierarchy starting at .
bootpd[27240]: opened domain 127.0.0.1/local
bootpd[27240]: server name pixel.roscoe.bombich.com
roscoe.bombich.com
DNS 10.0.1.1
bootpd[27240]: subnets init using domain . failed:
/var/db/dhcpd_leases: No such file or directory
bootpd[27240]: bsdpd: re-reading configuration
bootpd[27240]: bsdpd: shadow file size will be set to 48 megabytes
bootpd[27240]: bsdpd: age time 00:15:00

After reading the NetInfo settings, bootpd warns that initializing subnets failed and that /var/db/dhcpd_leases does not exist. This is expected because, in this case, the NetBoot server is only providing the NetBoot service, not the DHCP service.

Upon initialization, bootpd will also search the configured NetBoot sharepoints for valid NetBoot sets. In verbose mode, each set is listed along with the sharepoint that it resides upon, its name, Identifier, Type, BootFile, Disk Image, and supported architecture(s).

NetBoot image sharepoints
NetBootSP1: path /Volumes/Storage/Library/NetBoot/NetBootSP1
NetBoot client sharepoints
NetBootClients0: path /Volumes/Storage/Library/NetBoot/NetBootClients0
Sharepoint Name Identifier Type BootFile Image(s)
NetBootSP1 3.2.2 PPC test 0x81000621 NFS booter NetRestore.dmg [ppc]
NetBootSP1 3.2.2 test 0x8100052a NFS booter NetRestore.dmg [i386]
NetBootSP1 iMac 0x810001d6 NFS booter NetRestore.dmg [i386]
NetBootSP1 NetRestore 0x81001389 NFS booter NetRestore.dmg [ppc]
NetBootSP1 Tiger Server 0x81000065 NFS booter Install.dmg [ppc]
NetBootSP1 Tiger 0x810000c8 NFS booter Install.dmg [ppc]

Finally, bootpd will read the client bindings database kept at /var/db/bsdpd_clients. When a client NetBoots and chooses the default NetBoot set, or when you choose a NetBoot set in the Startup Disk Preference Pane, the server records that choice in this bindings database keyed by client MAC address. In the following case, the bindings database is empty (has not been created yet).

/var/db/bsdpd_clients: No such file or directory destination address 255.255.255.255


* Client and Server Activity Upon Client's First Network Boot

The following transcript of bootpd output shows the communication between a NetBooting client and a NetBoot server. In this particular case, the client has never NetBooted from this server before, DHCP is handled by another server, the NetBoot server and client are in the same subnet, and there is only one NetBoot server within broadcast range.

1) Client issues a DHCP DISCOVER

When a client machine issues a DHCP DISCOVER via broadcast, bootpd prints the following information. There are three notable sections in this output: standard DHCP information (i.e. that covered by RFC 951), DHCP Vendor Options (i.e. that covered by RFC 2132), and BSDP Extensions (allowed by RFC 2132, but not documented outside the source of bootpd). In the following packet only, I have delineated these sections with comment markers.

---------------- Client Request --------------------
### DHCP Info (RFC 951) ###
op = BOOTREQUEST
htype = 1
flags = 0
hlen = 6
hops = 0
xid = 37395
secs = 4
ciaddr = 0.0.0.0
yiaddr = 0.0.0.0
siaddr = 0.0.0.0
giaddr = 0.0.0.0
chaddr = 0:16:cb:ca:7b:35
sname =
file =

### DHCP Vendor Options (RFC 2132) ###
options:
Options count is 6
dhcp_message_type (uint8): DISCOVER 0x1
parameter_request_list (uint8_mult): {0x1, 0x3, 0x43, 0x2b, 0x3c}
client_identifier (uint8_mult): {0x1, 0x0, 0x16, 0xcb, 0xca, 0x7b, 0x35}
vendor_class_identifier (string): AAPLBSDPC/i386/MacBookPro1,1
vendor_specific (opaque):
0000 02 02 01 00 ....

end (none):

### BSDP-specific Vendor Options ###
bootpd[27240]: BSDP DISCOVER [en0] 1,0:16:cb:ca:7b:35 arch=i386 sysid=MacBookPro1,1
BSDP Options count is 1
version: 0x100
bootpd[27240]: service time 0.000730 seconds
destination address 255.255.255.255

Additional discussion:

Of particular note is the information provided in the Vendor Options section. A NetBooting client must provide two pieces of information to elicit a response from a NetBoot server. First, it indicates its Vendor Class as AAPLBSDPC, its architecture, and its system identification string as determined from firmware. Second, it requests the Vendor Class (option 60, 0x3c) and Vendor Options (option 43, 0x2b) parameters in the parameter request list. When bootpd detects a DISCOVER packet with these options requested, it determines if the client identifier (MAC address) has a record in the bindings database (/var/db/bsdpd_clients). The server response in the affirmative case will be described later, in this case, the client does not have a record in the bindings database and this packet is ignored by bootpd.

2) Client issues a DHCP REQUEST

Unseen prior to this packet is a DHCP OFFER packet that was sent to the client from another DHCP server. While the DHCP OFFER was sent to the broadcast address, it was sent to port 68, which only the client is listening to. bootpd is bound to port 67, which is the server-listening port for DHCP and BSDP.

Here, the client issues a DHCP REQUEST for a specific IP address in response to another DHCP Server's DHCP OFFER. bootpd ignores this packet as well in this case because it is not the server identified in the server_identifier option.

---------------- Client Request --------------------
op = BOOTREQUEST
htype = 1
flags = 0
hlen = 6
hops = 0
xid = 37395
secs = 4
ciaddr = 0.0.0.0
yiaddr = 0.0.0.0
siaddr = 0.0.0.0
giaddr = 0.0.0.0
chaddr = 0:16:cb:ca:7b:35
sname =
file =
options:
Options count is 8
dhcp_message_type (uint8): REQUEST 0x3
parameter_request_list (uint8_mult): {0x1, 0x3, 0x43, 0x2b, 0x3c}
client_identifier (uint8_mult): {0x1, 0x0, 0x16, 0xcb, 0xca, 0x7b, 0x35}
vendor_class_identifier (string): AAPLBSDPC/i386/MacBookPro1,1
requested_ip_address (ip): 10.0.1.32
server_identifier (ip): 10.0.1.1
vendor_specific (opaque):
0000 02 02 01 00 ....

end (none):
bootpd[27240]: service time 0.000403 seconds
destination address 10.0.1.11

3) Client issues a BSDP INFORM[LIST]

Having obtained an IP address and no BSDP response, the client now advertises its desire to collect a list of available NetBoot servers and NetBoot images. To elicit that response, it broadcasts an INFORM packet with a BSDP "LIST" message.

---------------- Client Request --------------------
op = BOOTREQUEST
htype = 1
flags = 0
hlen = 6
hops = 0
xid = 37396
secs = 4
ciaddr = 10.0.1.32
yiaddr = 0.0.0.0
siaddr = 0.0.0.0
giaddr = 0.0.0.0
chaddr = 0:16:cb:ca:7b:35
sname =
file =
options:
Options count is 6
dhcp_message_type (uint8): INFORM 0x8
parameter_request_list (uint8_mult): {0x2b, 0x3c}
client_identifier (uint8_mult): {0x1, 0x0, 0x16, 0xcb, 0xca, 0x7b, 0x35}
vendor_class_identifier (string): AAPLBSDPC/i386/MacBookPro1,1
vendor_specific (opaque):
0000 01 01 01 02 02 01 00 .......

end (none):
bootpd[27240]: BSDP INFORM [en0] 1,0:16:cb:ca:7b:35 arch=i386 sysid=MacBookPro1,1
BSDP Options count is 2
message type: LIST (0x1)
version: 0x100

4) Server responds with a BSDP ACK[LIST]

The NetBoot server responds to the NetBoot client's LIST request with a BOOTREPLY that includes three BSDP options: Message type, server priority, and the ID of the default image that is available to this particular client. It is important to note that there can be multiple default NetBoot sets indicated in Server Admin because the defaults are filtered based on architecture and per-NetBoot-set Model filters. Only one image ID is returned to the client.

=================== Server Reply =====================
op = BOOTREPLY
htype = 1
flags = 0
hlen = 6
hops = 0
xid = 37396
secs = 0
ciaddr = 10.0.1.32
yiaddr = 0.0.0.0
siaddr = 10.0.1.11
giaddr = 0.0.0.0
chaddr = 0:16:cb:ca:7b:35
sname = pixel.roscoe.bombich.com
file =
options:
Options count is 5
dhcp_message_type (uint8): ACK 0x5
server_identifier (ip): 10.0.1.11
vendor_class_identifier (string): AAPLBSDPC
vendor_specific (opaque):
0000 01 01 01 04 02 80 00 07 04 81 00 05 2a ............*

end (none):
BSDP Options count is 3
message type: LIST (0x1)
server priority: 0x8000
default boot image: 0x8100052a
bootpd[27240]: NetBoot: [1,0:16:cb:ca:7b:35] BSDP ACK[LIST] sent 10.0.1.32 pktsize 300
bootpd[27240]: service time 0.001589 seconds
destination address 10.0.1.11

5) Client re-sends the INFORM[LIST] several times during collection mode

The client may resend the INFORM[LIST] packet several times during the discovery and collection phase to assure that it is getting a complete list of available servers and NetBoot images (some servers may be slower than others). This collection phase typically takes 2-4 seconds. The NetBoot server responds to each LIST request with the same ACK[LIST] request as it responded with the first time.

The repeated packets are not listed here because the client requests and server replies are exactly the same as in steps 3 and 4.

6) Client chooses a server and image and sends a BSDP INFORM[SELECT] message

Having collected a complete list of NetBoot servers, the client chooses the server with the highest priority. The server's priority is simply a measurement of how many clients are listed in the NetBoot bindings database (not necessarily the number of clients currently booted from the server). When the client has made this choice, it assembles a DHCP INFORM packet with the BSDP message_type option set to SELECT (0x02). Included in this response is the server ID and selected boot image. This message is broadcast such that other NetBoot servers are aware of the choice as well. When a NetBoot server gets notice that the client has selected another NetBoot server, it deletes any binding records for that client in the bindings database (that makes more sense if you consider the case of a user choosing a different NetBoot image in the Startup Disk Preference Pane).

When bootpd receives an INFORM[SELECT] with the server ID matching itself, it recognizes the appropriate reply file (booter) and prepares a response.

---------------- Client Request --------------------
op = BOOTREQUEST
htype = 1
flags = 0
hlen = 6
hops = 0
xid = 37396
secs = 7
ciaddr = 10.0.1.32
yiaddr = 0.0.0.0
siaddr = 0.0.0.0
giaddr = 0.0.0.0
chaddr = 0:16:cb:ca:7b:35
sname =
file =
options:
Options count is 6
dhcp_message_type (uint8): INFORM 0x8
parameter_request_list (uint8_mult): {0x2b, 0x3c}
client_identifier (uint8_mult): {0x1, 0x0, 0x16, 0xcb, 0xca, 0x7b, 0x35}
vendor_class_identifier (string): AAPLBSDPC/i386/MacBookPro1,1
vendor_specific (opaque):
0000 01 01 02 02 02 01 00 08 04 81 00 05 2a 03 04 0a ............*...
0010 00 01 0b ...

end (none):
bootpd[27240]: BSDP INFORM [en0] 1,0:16:cb:ca:7b:35 arch=i386 sysid=MacBookPro1,1
BSDP Options count is 4
message type: SELECT (0x2)
version: 0x100
selected boot image: 0x8100052a
server identifier: 10.0.1.11
bootpd[27240]: replyfile /private/tftpboot/NetBoot/NetBootSP1/3.2.2 test.nbi/i386/booter

7) Server replies with an ACK[SELECT] packet containing NetBoot details

In response to an INFORM[SELECT] choosing this server, bootpd replies with an ACK[SELECT]. This packet provides the client with the selected boot image ID, the machine name, the NetBoot image root path, and the path to the booter file. The client stores this entire packet in RAM for future reference during the boot process. bootpd then creates a record for this client in the NetBoot bindings database.

=================== Server Reply =====================
op = BOOTREPLY
htype = 1
flags = 0
hlen = 6
hops = 0
xid = 37396
secs = 0
ciaddr = 10.0.1.32
yiaddr = 0.0.0.0
siaddr = 10.0.1.11
giaddr = 0.0.0.0
chaddr = 0:16:cb:ca:7b:35
sname = pixel.roscoe.bombich.com
file = /private/tftpboot/NetBoot/NetBootSP1/3.2.2 test.nbi/i386/booter
options:
Options count is 6
dhcp_message_type (uint8): ACK 0x5
server_identifier (ip): 10.0.1.11
vendor_class_identifier (string): AAPLBSDPC
root_path (string): nfs:10.0.1.11:/Volumes/Storage/Library/NetBoot/NetBootSP1:3.2.2 test.nbi/NetInstall-Restore.dmg
vendor_specific (opaque):
0000 01 01 02 08 04 81 00 05 2a 82 0a 4e 65 74 42 6f ........*..NetBo
0010 6f 74 30 30 31 ot001

end (none):
BSDP Options count is 3
message type: SELECT (0x2)
selected boot image: 0x8100052a
machine name: NetBoot001
bootpd[27240]: NetBoot: [1,0:16:cb:ca:7b:35] BSDP ACK[SELECT] sent 10.0.1.32 pktsize 381
bootpd[27240]: service time 0.004187 seconds


* Client and Server Activity Upon Client's Subsequent Network Boot(s)

The communication that occurs between a NetBooting client and a NetBoot server on subsequent boots is much abbreviated compared to the initial boot. In this particular case, the client has already NetBooted from this server before (it has a binding record in the server's /var/db/bsdpd_clients bindings database), DHCP is handled by another server, the NetBoot server and client are in the same subnet, and there is only one NetBoot server within broadcast range.

1) Client issues a DHCP DISCOVER

This is the exact same DISCOVER packet as in the previous section. This time, however, the server finds a match for the client ID in the NetBoot bindings database and recognizes a reply file for the client. It then prepares a reply to the client immediately.

---------------- Client Request --------------------
op = BOOTREQUEST
htype = 1
flags = 0
hlen = 6
hops = 0
xid = 37395
secs = 4
ciaddr = 0.0.0.0
yiaddr = 0.0.0.0
siaddr = 0.0.0.0
giaddr = 0.0.0.0
chaddr = 0:16:cb:ca:7b:35
sname =
file =
options:
Options count is 6
dhcp_message_type (uint8): DISCOVER 0x1
parameter_request_list (uint8_mult): {0x1, 0x3, 0x43, 0x2b, 0x3c}
client_identifier (uint8_mult): {0x1, 0x0, 0x16, 0xcb, 0xca, 0x7b, 0x35}
vendor_class_identifier (string): AAPLBSDPC/i386/MacBookPro1,1
vendor_specific (opaque):
0000 02 02 01 00 ....

end (none):
bootpd[27259]: BSDP DISCOVER [en0] 1,0:16:cb:ca:7b:35 NetBoot001 arch=i386 sysid=MacBookPro1,1
BSDP Options count is 1
version: 0x100
bootpd[27259]: replyfile /private/tftpboot/NetBoot/NetBootSP1/3.2.2 test.nbi/i386/booter
bootpd[27259]: replying to 0.0.0.0

2) Server responds with a BSDP OFFER

Because the client already has a binding with this server, the server issues a BSDP OFFER to the client. This offer contains everything the client needs to immediately begin NetBooting: a server identifier, a boot file path, a selected NetBoot image ID, a NetBoot image root path, and a machine name. Note that this OFFER is sent to the broadcast address because the client does not yet have an IP address. The message is tagged with the client's MAC address, though, so only the requesting client will (should) use the message.

=================== Server Reply =====================
op = BOOTREPLY
htype = 1
flags = 0
hlen = 6
hops = 0
xid = 37395
secs = 0
ciaddr = 0.0.0.0
yiaddr = 0.0.0.0
siaddr = 10.0.1.11
giaddr = 0.0.0.0
chaddr = 0:16:cb:ca:7b:35
sname = pixel.roscoe.bombich.com
file = /private/tftpboot/NetBoot/NetBootSP1/3.2.2 test.nbi/i386/booter
options:
Options count is 6
dhcp_message_type (uint8): OFFER 0x2
server_identifier (ip): 10.0.1.11
vendor_class_identifier (string): AAPLBSDPC
root_path (string): nfs:10.0.1.11:/Volumes/Storage/Library/NetBoot/NetBootSP1:3.2.2 test.nbi/NetInstall-Restore.dmg
vendor_specific (opaque):
0000 08 04 81 00 05 2a 82 0a 4e 65 74 42 6f 6f 74 30 .....*..NetBoot0
0010 30 31 01

end (none):
bootpd[27259]: BSDP OFFER sent [1,0:16:cb:ca:7b:35] pktsize 378
BSDP Options count is 2
selected boot image: 0x8100052a
machine name: NetBoot001
bootpd[27259]: service time 0.003723 seconds
destination address 255.255.255.255

3) Client sends a DHCP REQUEST to the DHCP server

This is the same request as in step two of the Initial Boot Sequence. This packet is ignored by the NetBoot server. As soon as the client obtains an IP address, it begins phase two of the NetBoot process.

---------------- Client Request --------------------
op = BOOTREQUEST
htype = 1
flags = 0
hlen = 6
hops = 0
xid = 37395
secs = 4
ciaddr = 0.0.0.0
yiaddr = 0.0.0.0
siaddr = 0.0.0.0
giaddr = 0.0.0.0
chaddr = 0:16:cb:ca:7b:35
sname =
file =
options:
Options count is 8
dhcp_message_type (uint8): REQUEST 0x3
parameter_request_list (uint8_mult): {0x1, 0x3, 0x43, 0x2b, 0x3c}
client_identifier (uint8_mult): {0x1, 0x0, 0x16, 0xcb, 0xca, 0x7b, 0x35}
vendor_class_identifier (string): AAPLBSDPC/i386/MacBookPro1,1
requested_ip_address (ip): 10.0.1.32
server_identifier (ip): 10.0.1.1
vendor_specific (opaque):
0000 02 02 01 00 ....

end (none):
bootpd[27259]: service time 0.000414 seconds


* Closing remarks

A while back I received an email from a colleague who had become very frustrated with NetBoot. He was trying to Netboot a MacBook Pro but the machine simply refused -- it immediately rebooted from the local hard drive. After staring at packet traces, he finally asked if I could help. My first question was, "Is the NetBoot server running at least 10.4.4?". He said yes, it was running 10.4.5 Server. "And you created the images on an Intel machine, right?" The answer was yes. It appeared that he was doing everything correctly. I gave him instructions on putting the bootpd service in debug mode, and a few minutes later he sent me the verbose output.

I immediately noticed that bootpd was not indicating anything about the architecture of the NetBoot images present. I asked "Are you SURE the server is running 10.4.5?" He double-checked, indeed it was running 10.4.5. I stared at the verbose output for a few more minutes, then concluded that, while they may think they are running 10.4.5, they most certainly are not running the bootpd that came with it. When I suggested that something must have gone wrong with the update, the sysadmin of the server broke in and asked, "I recompiled the bootpd code myself, could that be causing problems?" We had a good laugh over that one! After replacing the bootpd binary with a known good bootpd binary from another 10.4.5 server, all was good.

You can troubleshoot many NetBoot issues by simply watching what occurs on the screen of the Netbooting client. Troubleshooting the early stages of the NetBoot process, however, can be a difficult task even when you have a screenful of packet traces. Fortunately, the daemon in charge of the NetBoot service, bootpd, digests much of this information and presents it to the system administrator in a readable form. With knowledge of how the BSDP "handshake" occurs, a reference of the various BSDP vendor-specific options, and examples of bootpd debug output, I hope you will be better prepared to tackle challenging NetBoot issues.

References:
bootpd source code (Requires an ADC account)
bootpd man page
ADC on iTunes: WWDC 2006, Information Technologies Track, Session 517 NetBoot for Large Networks (Requires an ADC account)
Troubleshooting NetBoot from the client perspective

History:
4/13/2007: Initial publication
2/15/2008: Fixed several entries in the first table, they did not match the hex of the packet indicated above the table.
2/3/2010: Modified the instructions for placing bootpd into debug mode such that you do not need to keep an open sheel running the bootpd process.

footer shadow