I'm trying to boot a bank of Raspberry Pi 3 Model B and B+ devices. I'm using ISC's KEA DHCP server (v1.5.0) to boot these from. Unfortunately these need to boot over a different network than the kea server and tftp servers (so I'm using cisco ip helper-address to forward with Option 82). The key problem I seem to be having is getting the PIs to contact the TFTP server after receiving the DHCP response packet. Debugging so far seems to indicate that my Option 43 is missing a "255" at the end of the option string and/or the Pi isn't respecting the boot servers defined by option#43,code#8...

Anyway, here is a code snippit of the KEA config I'm working with:

"Dhcp4": {
    ...global options...,
    "option-def": [
          "name": "PXE_Discovery_Control",
          "code": 6,
          "space": "vendor-encapsulated-options-space",
          "type": "uint8",
          "array": false
          "name": "PXE_Boot_Servers",
          "code": 8,
          "space": "vendor-encapsulated-options-space",
          "type": "record",
          "array": true,
          "record-types": "uint16,uint8,ipv4-address"
          "name": "PXE_Boot_Menu",
          "code": 9,
          "space": "vendor-encapsulated-options-space",
          "type": "record",
          "array": false,
          "record-types": "uint16,uint8,string"
          "name": "PXE_Menu_Prompt",
          "code": 10,
          "space": "vendor-encapsulated-options-space",
          "type": "record",
          "array": false,
          "record-types": "uint8,string"
    "client-classes": [
        { "name": "PXEClient",
          "test": "substring(option[vendor-class-identifier].text,0,9) == 'PXEClient'"

        { "name": "rPI",
          "test": "member('PXEClient') and (substring(pkt4.mac,0,3) == 0xb827eb)",
          "option-data": [
            { "name": "boot-file-name",
              "data": "bootcode.bin"},

            { "name": "vendor-class-identifier",
              "data": "PXEClient" },

            { "name": "vendor-encapsulated-options" },

            // ** required **
            // type 0 = local boot
            // desclen (cannot be zero)
            // description
            // Note: "0,20,Raspberry Pi Boot   " fails, trailing spaces removed by kea
            { "name": "PXE_Boot_Menu",
              "data": "0,17,Raspberry Pi Boot",

            // ** required **
            // bit 0 - disable broadcast discovery
            // bit 1 - disable multicast discovery
            // bit 2 - only use/accept servers in PXE_BOOT_SERVERS
            // bit 3 - download the boot file in DHCP offer packet
            // bit 4-7 set to zero
            { "name": "PXE_Discovery_Control",
              "data": "11",

            { "name": "PXE_Boot_Servers",
              "data": "0,1,",

            // ** required **
            // Amount of time in seconds before accepting the first menu
            // prompt as well as the prompt string
            { "name": "PXE_Menu_Prompt",
              "data": "0,PXE",
"subnet4": [ ...etc... ]
    (defined in a subnet) "next-server": ""

The PXEClient is broken into different classes as I have other client-classes that are for booting VMs, HP hardware, etc. All my problems currently are with the Raspberry PIs.

I've been trying to get the TFTP server defined either as option #43, code #8 or as the Server-IP via the next-server command. Neither seems to get the PI to actually pull from the TFTP server.

What I see in the DHCP response packet to the PI is the following:

dhcp64.company.com.bootps > tower2-rtr1-g0-1.company.com.bootps: [udp sum ok] BOOTP/DHCP, Reply, length 391, hops 1, xid 0x26f30339, Flags [none] (0x0000)
      Your-IP c-111-111-222-10.rev.company.com
      Server-IP tftp.company.com
      Gateway-IP tower2-rtr1-g0-1.company.com
      Client-Ethernet-Address b8:27:eb:15:2a:36 (oui Unknown)
      Vendor-rfc1048 Extensions
        Magic Cookie 0x63825363
        Subnet-Mask Option 1, length 4:
        Default-Gateway Option 3, length 4: tower2-rtr.company.com
        Domain-Name-Server Option 6, length 8: dns.quad9.net,rpz-public-resolver1.rrdns.pch.net
        Domain-Name Option 15, length 16: "company.com"
        Vendor-Option Option 43, length 40:
        Lease-Time Option 51, length 4: 14400
        DHCP-Message Option 53, length 1: Offer
        Server-ID Option 54, length 4: dhcp64.company.com
        RN Option 58, length 4: 7200
        RB Option 59, length 4: 12600
        Vendor-Class Option 60, length 9: "PXEClient"
        BF Option 67, length 12: "bootcode.bin"
        Agent-Information Option 82, length 14: 
          Remote-ID SubOption 2, length 12: ^B^J^@^@M-^S\[^B^A^@^@^@
        END Option 255, length 0

A few things to note from this tcpdump... Option 43 isn't being terminated with a 255 (does kea do that automatically? Does tcpdump just assume it ends that way and not display the final 255?)

When the PI pulls this DHCP request, there are a couple seconds before it does it again for a total of 4 times before the PI stops trying... It never does make a request to the TFTP server that I can see.

There is a mention in the Raspberry Pi documentation that due to a bug, some PIs require the string "Raspberry Pi Boot " have three spaces after it. I've been trying with kea to have three spaces inserted after "Boot" but with no luck, kea keeps truncating the spaces.

So, the main questions:

  1. Is option #43 terminated correctly in the tcpdump?
  2. If not, how do I get the 255 added to the venor-encapsulated-options-space
  3. Does the Raspberry Pi know how to use Option#43,Code#8? or is it dependent upon "next-server" for its definition?
  4. How can I add 3 spaces to my vendor string for option#43,Code#9?
  5. and of course lastly... what the heck am I missing or forgetting?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.