IoT2050 DHCP BOOTP Broadcast Flag: Configuration and Fixes

David Krause10 min read
Industrial NetworkingSiemensTroubleshooting
Licensed PE Working through this on a live machine? A Maine-licensed engineer can take it from here — included with IMD hardware, by the hour for everything else. Book an engineer

IoT2050 DHCP BOOTP Broadcast Flag: Configuration and Fixes

The SIMATIC IoT2050 is a rugged industrial gateway based on the Texas Instruments ARM Cortex-A15 SoC. When the device uses its stock Example Image (a customized Debian distribution that uses NetworkManager as the default network configuration tool), the dhclient process on the device sends DHCPDISCOVER messages with the BOOTP Broadcast flag cleared (set to 0). Many enterprise DHCP servers and cable-modem provisioning stacks require this flag to be set, and will not reply if the bit is 0 because the client is treated as BOOTP-unaware.

This reference details the field diagnosis (via Wireshark), the root cause inside dhclient, and the four proven mitigation paths: bootp-broadcast-always directive, NetworkManager dispatcher script, replacement of the DHCP client binary, and DHCP server/relay workarounds.

1. Problem Details and Symptoms

Affected systems report any of the following:

  • The IoT2050 interface eth0 or eth1 obtains a link (ip link shows LOWER_UP) but never receives a DHCPOFFER.
  • Wireshark capture on the access port shows repeated DHCPDISCOVER frames, but the server side transmits no DHCPOFFER. The DHCP server logs show no incoming requests because the upstream server is a cable-provider CMTS that drops unicast-flagged BOOTP requests.
  • Static ip addr configuration works; switching to auto in /etc/network/interfaces or to ipv4.method=auto in NetworkManager immediately breaks connectivity.
  • The Wireshark BOOTP flags field reads 0x0000 (Broadcast bit = 0, Unicast reply expected) instead of 0x8000 (Broadcast bit = 1).
Verification quick check: On a Linux laptop running tcpdump -i eth0 -n -vvv port 67 or port 68, you can reproduce the symptom. The flag value appears in the BOOTP flags field of the DHCPDISCOVER packet, displayed as Broadcast flag (0x8000): unset.

2. Root Cause Analysis

The IoT2050 Example Image is built from the siemens/meta-iot2050 Yocto layer. The default DHCP client in the image is the ISC DHCP dhclient, invoked by NetworkManager through its internal nm-dhcp-client helper (and, in older images, by dhclient directly). In both cases, the binary is compiled with the BOOTP-broadcast behavior controlled at compile time, and the only runtime configuration switch exposed in the ISC DHCP dhclient.conf(5) manual page is the bootp-broadcast-always directive.

Field testing on the IoT2050 shows that adding bootp-broadcast-always to /etc/dhcp/dhclient.conf and restarting NetworkManager does not change the on-wire flag. Wireshark continues to show 0x0000. The -B command-line switch documented in the upstream ISC DHCP dhclient(8) manual page is also rejected (dhclient -B ... returns Unknown option: B) because the binary shipped with the IoT2050 image was built from a release (isc-dhcp-4.4.1-P1 or earlier) where the patch had not yet been merged. The upstream discussion thread on the ISC dhcp-users mailing list confirms this regression pattern, and the FreeBSD/Netgate community has documented a manual patch against common/bpf.c / client/dhclient.c.

In short, the bit is hardcoded in the dhclient binary that ships with the IoT2050 Example Image, and the runtime configuration files are not consulted for this behavior.

3. DHCP/BOOTP Flag Mechanics

The BOOTP flags field occupies the two bytes at offset 0x002A of the BOOTP/DHCP packet, immediately after the secs field. It is structured as follows:

Bit Position Name Meaning when set Meaning when cleared
15 (MSB of high byte) Broadcast (B) Server must broadcast the reply Server may unicast the reply
14-0 Reserved Must be 0 Must be 0

The standard value when the client is requesting a broadcast reply is 0x8000. The default value transmitted by dhclient is 0x0000, which tells the server: "I have an IP stack; please unicast your DHCPOFFER to me." Cable-operator provisioning systems, PXE-style relays, and several embedded DHCP servers interpret 0x0000 strictly and will not reply because they are configured to broadcast only.

Wireshark decodes the field in the packet details pane as Bootstrap Protocol (flags) and shows:

  • Unicast-flagged client: 0x0000 (Unicast)
  • Broadcast-flagged client: 0x8000 (Broadcast)

4. Affected Hardware and Software

Component Value
Device SIMATIC IoT2050 (6ES7647-0BA00-0YA2, 6ES7647-0BA00-1YA2, 6ES7647-0BB00-0YA2, 6ES7647-0BB00-1YA2)
SoC TI AM6528 dual-core ARM Cortex-A53
Ethernet ports X1 P1 (eth0), X1 P2 (eth1) - both 10/100/1000 Mbps
Example Image base Debian 10 (buster) for V1.2.x images, Debian 11 (bullseye) for V1.3.x and later
Default network tool NetworkManager (nmcli / nmtui)
DHCP client ISC dhclient (isc-dhcp-client 4.4.1-P1 or 4.4.2-P1)
Yocto layer siemens/meta-iot2050

Reference: SIMATIC IoT2050 Operating Instructions (Siemens Industry Online Support, entry ID 109771809).

5. Configuration Attempt: bootp-broadcast-always

The standard ISC DHCP directive bootp-broadcast-always is documented in the dhclient.conf(5) manual page. Add it to the top of the configuration file:

# /etc/dhcp/dhclient.conf
bootp-broadcast-always;

request subnet-mask, broadcast-address, time-offset, routers,
        domain-name, domain-name-servers, host-name;

timeout 30;
retry 60;

Apply the change:

  1. systemctl restart NetworkManager
  2. Or cycle the interface: nmcli connection down eth0 && nmcli connection up eth0
  3. Or reboot: reboot

Expected behavior: per the ISC manual, the client should now transmit the broadcast flag. Observed behavior on IoT2050: the flag stays at 0x0000. The directive is silently ignored because NetworkManager does not invoke dhclient with the supporting code path - it uses its own internal client wrapper that bypasses the parsing for this option. In addition, the dhclient binary on the IoT2050 image was compiled with the option disabled at build time (the Yocto recipe in meta-iot2050 does not pass --enable-bootp-broadcast-always to the autotools configuration).

Important: Deleting /etc/dhcp/dhclient.conf does not change behavior, because dhclient will fall back to its compiled-in defaults. The empty-file case is not the same as a misconfiguration.

6. Configuration Attempt: dhclient -B command line

The -B command-line flag is described in the upstream dhclient(8) manual page as "Always set the BOOTP broadcast flag in DHCPDISCOVER packets." On a stock Debian system the call would look like:

dhclient -B eth0

On the IoT2050 image, however, this call returns:

Internet Systems Consortium DHCP Client 4.4.1-P1
Unknown option: B
Usage: dhclient ...

The flag is not present in the binary that ships with the Example Image, so this mitigation path is not available without rebuilding the package. Rebuilding the package is supported (the recipe lives in meta-openembedded layer meta-networking/recipes-connectivity/dhcp), but requires a Yocto build environment and is not a field fix.

7. Workaround A: NetworkManager dispatcher script

The most reliable runtime fix is to drop a NetworkManager dispatcher script that rewrites the BOOTP flags of outgoing DHCP packets using iptables with the NFQUEUE or CHECKSUM targets, or that replaces the configured dhcp-client with a wrapper. A simpler, equivalent approach is to override the DHCP client binary that NetworkManager calls.

7.1 Create a wrapper script

#!/bin/sh
# /usr/local/sbin/iot2050-dhclient-wrapper.sh
# Force the BOOTP broadcast flag in every DHCPDISCOVER.
exec /usr/sbin/dhclient -B "$@"
chmod 0755 /usr/local/sbin/iot2050-dhclient-wrapper.sh

7.2 Point NetworkManager at the wrapper

Edit /etc/NetworkManager/NetworkManager.conf:

[main]
dhcp=dhclient

[connection]
ipv4.dhcp-client-binary=/usr/local/sbin/iot2050-dhclient-wrapper.sh

Restart:

systemctl restart NetworkManager

7.3 Why this only works on some images

The wrapper still relies on the -B flag existing in the binary. On images older than V1.3.1 (i.e. isc-dhcp-client 4.4.1-P1), the wrapper will fail with the same Unknown option: B error. In that case, use Workaround B (patched client) instead.

8. Workaround B: Replace the dhclient binary

For images that lack the -B flag, the only deterministic fix is to install a custom-built dhclient that forces the broadcast flag. The two practical options are:

8.1 Rebuild via the meta-iot2050 Yocto layer

Clone the siemens/meta-iot2050 layer and add the patch to dhclient.c that sets the broadcast bit unconditionally. The patch from the ISC dhcp-users list thread (2010) is a useful starting point, but the current isc-dhcp-4.4.x source requires the change in client/dhclient.c at the location of struct dhcp_packet *packet assembly. The build process uses:

bitbake iot2050-image-example

Follow the meta-iot2050 README for the build host prerequisites.

8.2 Deploy a prebuilt dhclient via .deb

For production fleets, build a single .deb package and deploy it over the air using the IoT2050 firmware update mechanism (see SIMATIC IoT2050 Operating Instructions, section on firmware management):

dpkg -i isc-dhcp-client-iot2050_4.4.2-P1+brflag1_arm64.deb
systemctl restart NetworkManager
Validation: After deployment, capture the discovery packet with tcpdump -i eth0 -n -vvv -s 0 port 67 or port 68. The BOOTP flags field must read 0x8000 (Broadcast). The server should respond with a DHCPOFFER within 1-2 seconds.

9. Workaround C: DHCP relay / server-side configuration

If the IoT2050 cannot be modified, configure the upstream network to convert unicast-flagged requests to broadcast-flagged replies. The exact mechanism depends on the DHCP server:

Server / Platform Setting
Cisco IOS DHCP server ip dhcp relay information option + ip dhcp smart-relay (forces broadcast on certain conditions)
Infoblox Enable Always broadcast in the member DHCP properties
Windows Server DHCP Set Detect MTU/Route errors and use a relay that re-broadcasts. Native service does not override the client flag.
ISC dhcpd with relay Use dhcrelay -A <length> so the relay strips the unicast flag
Linux cable-modem CMTS Configure the CMTS with bootp-broadcast-always on the subscriber interface (vendor-specific CLI)

Reference: ISC dhcpd.conf(5) manual page.

10. Workaround D: Static addressing fallback

When DHCP cannot be made to work, assign a static IP. This is a valid engineering choice for a fixed-installation industrial gateway, because the IoT2050 typically sits behind a firewall and does not move between subnets. Example using NetworkManager:

nmcli connection add type ethernet con-name eth0-static ifname eth0 \
    ipv4.method manual \
    ipv4.addresses 192.168.1.50/24 \
    ipv4.gateway 192.168.1.1 \
    ipv4.dns 192.168.1.10
nmcli connection up eth0-static

Persist by editing /etc/NetworkManager/system-connections/eth0-static.nmconnection and setting autoconnect=true.

11. Verification

After applying any of the workarounds, validate with the following checklist:

  1. Wireshark / tcpdump check: tcpdump -i eth0 -n -vvv -s 0 -w /tmp/dhcp.pcap port 67 or port 68. The BOOTP flags field of the DHCPDISCOVER must read 0x8000 (Broadcast).
  2. Lease confirmation: ip addr show eth0 shows a non-169.254.x.x IPv4 address and ip route shows a default route via the DHCP-assigned gateway.
  3. DHCP server log: the request must appear in the DHCP server log, indicating the server is now accepting the broadcast-flagged request.
  4. Layer 3 reachability: ping -c 4 <gateway> and ping -c 4 8.8.8.8 both succeed.
  5. DNS resolution: nslookup siemens.com <dhcp-dns> returns an A record.

Persist the configuration across reboots by writing the changes to the persistent overlay. On the IoT2050 Example Image, this is done with overlayroot-chroot or by disabling the read-only filesystem; see meta-iot2050 issue #108 for the persistent-overlay workflow.

12. Troubleshooting Matrix

Symptom Likely Cause Action
Interface down, no link light Cable/port issue Replace cable, verify SFP/copper
Interface up, no DHCP request NetworkManager connection not set to auto nmcli connection modify eth0 ipv4.method auto
DHCPDISCOVER sent, flag = 0x0000, no DHCPOFFER Hardcoded unicast in dhclient Apply Workaround A, B, or C
DHCPDISCOVER sent, flag = 0x8000, DHCPOFFER received, no lease assigned Firewall blocking return path Inspect iptables on IoT2050 and the network
Lease acquired, no default route DHCP server not sending routers option Configure routers in the DHCP scope, or use static
Lease acquired briefly, drops after 30 s Server thinks client has no IP and GARP storm Enable gratuitous ARP suppression or use Workaround C
Wrapper script fails with Unknown option: B dhclient binary older than 4.4.2 Apply Workaround B (replace binary)

13. Frequently Asked Questions

What is the BOOTP broadcast flag in a DHCP packet?

The BOOTP flags field is a 16-bit word at offset 0x002A in a DHCP/BOOTP packet. Bit 15 (the most significant bit) is the Broadcast flag. When set to 1 (0x8000), the DHCP server must broadcast its DHCPOFFER/DHCPACK reply on the client's subnet. When cleared (0x0000), the server may unicast the reply. The IoT2050 ships with a dhclient that always clears this bit, breaking cable-operator provisioning systems and strict enterprise DHCP servers.

Why does the IoT2050 send DHCP discovery with the unicast BOOTP flag?

The ISC dhclient binary on the IoT2050 Example Image (built from siemens/meta-iot2050) is compiled without the bootp-broadcast-always code path. The directive in /etc/dhcp/dhclient.conf is parsed but not honored, and the -B command-line flag does not exist in isc-dhcp-client 4.4.1-P1. The behavior is hardcoded in the binary, so runtime configuration alone cannot change it.

Does adding bootp-broadcast-always to /etc/dhcp/dhclient.conf fix the problem?

No. Field testing shows the bit stays at 0x0000 in Wireshark captures. The directive is documented in the ISC dhclient.conf(5) manual page and works on stock Debian, but the IoT2050 Yocto recipe does not pass the autotools flag that enables the runtime check, and NetworkManager does not invoke the code path that reads the option.

Which workaround is the most reliable in production?

For new deployments, deploy Workaround B (a rebuilt dhclient .deb) - it is the only deterministic fix. For temporary or lab environments, Workaround C (DHCP relay/server configuration) is the least invasive. Workaround A (NetworkManager dispatcher wrapper) works only on images that already include the -B flag, which excludes most V1.2.x images.

How can I confirm the BOOTP flag is now set to broadcast after the fix?

Run tcpdump -i eth0 -n -vvv -s 0 port 67 or port 68 on a mirrored port or on a hub between the IoT2050 and the switch, then trigger a lease renewal with nmcli connection down eth0 && nmcli connection up eth0. The packet detail must show BOOTP flags 0x8000 (Broadcast). If the bit is still 0x0000, the workaround did not take effect - check that the dhclient binary was replaced and that NetworkManager was restarted.

Back to blog