DHCP relay enables multi-subnet DHCP
Without a relay agent, DHCP broadcasts do not cross router boundaries. Configure relay agents on every subnet that uses DHCP.
The previous chapters established how switches forward frames, how VLANs segment traffic, and how routers move packets between subnets. Those mechanisms move data, but they do not answer a basic question: how does a device get an IP address, find a hostname, or synchronize its clock? Network services fill that gap.
Every device on an IP network needs at least 3 things: an IP address, a way to resolve names to addresses, and an accurate clock. Configuring these manually on hundreds of devices is error-prone and does not scale. Network services automate this configuration and keep the configuration consistent across the entire network.
DHCP (Dynamic Host Configuration Protocol) assigns IP addresses, subnet masks, default gateways, and DNS server addresses to clients automatically. DHCP uses a 4-step exchange called DORA (Discover, Offer, Request, Acknowledge).
At the start of the process, the client has no IP address. The client sends a broadcast on UDP port 67. The server responds with an offer, the client accepts, and the server confirms.
The transaction ID (xid) is a random 32-bit number chosen by the client. The xid matches requests to responses when multiple DHCP servers respond.
The client renews at 50% of the lease time (T1) by unicasting to the server. When that renewal is unsuccessful, the client broadcasts at 87.5% (T2). When both attempts are unsuccessful, the lease expires and the client restarts DORA.
The DHCPOFFER and DHCPACK messages carry DHCP options, each identified by a numeric code. These options deliver configuration beyond the IP address.
| Option | Name | Purpose |
|---|---|---|
| 1 | Subnet Mask | Defines the network portion of the address |
| 3 | Router (Default Gateway) | Tells the client where to send non-local traffic |
| 6 | DNS Servers | Delivers 1 or more DNS resolver addresses |
| 15 | Domain Name | Sets the client’s DNS search domain |
| 51 | Lease Time | Duration in seconds before the client renews |
| 66 | TFTP Server Name | Points to a server for firmware or config downloads |
| 67 | Bootfile Name | Specifies the file to download from the TFTP server |
| 150 | TFTP Server Address | Cisco-specific alternative to option 66 |
Options 66 and 67 matter in OT environments where IP phones and thin clients download firmware at boot. A misconfigured option 66 causes devices to halt their boot sequence silently.
DHCP uses broadcast, and routers do not forward broadcasts. In a multi-subnet network, a DHCP relay agent (also called an IP helper) solves this. The relay agent listens for DHCP broadcasts on the local subnet, wraps the broadcasts in a unicast packet addressed to the DHCP server on a remote subnet, and forwards the server’s response back to the client.
The giaddr (Gateway IP Address) field tells the server which subnet the client belongs to. The server uses giaddr to select the correct address pool. Without a relay agent, clients on remote subnets never receive an address.
On Hirschmann HiOS, configure the relay agent at Routing → DHCP Relay Agent and specify the DHCP server IP.
When a client sends a DHCPDISCOVER and receives no response, the client assigns an address from the APIPA (Automatic Private IP Addressing) range: 169.254.0.0/16. APIPA addresses are link-local only. APIPA addresses allow communication with other APIPA devices on the same segment but do not reach any routed network.
When a device shows a 169.254.x.x address, DHCP was unsuccessful. Common causes: no DHCP server on the subnet, no relay agent configured, the DHCP server’s address pool is exhausted, or a firewall blocks UDP ports 67/68.
The following script captures live DHCP traffic and decodes each message type. The script makes spotting rogue DHCP servers or unsuccessful renewals straightforward.
from scapy.all import sniff, DHCP, BOOTP, Ether, IP
DHCP_MSG_TYPES = {1: "DISCOVER", 2: "OFFER", 3: "REQUEST", 4: "DECLINE", 5: "ACK", 6: "NAK", 7: "RELEASE", 8: "INFORM"}
def decode_dhcp(pkt): if not pkt.haslayer(DHCP): return bootp = pkt[BOOTP] dhcp_options = {opt[0]: opt[1] for opt in pkt[DHCP].options if isinstance(opt, tuple)} msg_type = DHCP_MSG_TYPES.get(dhcp_options.get("message-type", 0), "UNKNOWN") client_mac = pkt[Ether].src offered_ip = bootp.yiaddr if bootp.yiaddr != "0.0.0.0" else "none" server_id = dhcp_options.get("server_id", "unknown") print(f"[DHCP {msg_type:8s}] client={client_mac} offered={offered_ip} server={server_id}") if msg_type == "OFFER": # Two OFFERs from different servers for the same DISCOVER = rogue server print(f" gateway={dhcp_options.get('router', 'none')} " f"dns={dhcp_options.get('name_server', 'none')}")
sniff(iface="eth0", filter="udp port 67 or udp port 68", prn=decode_dhcp, store=False)Running this script on a mirror port reveals every DHCP exchange on the segment. 2 OFFER messages from different server IDs for the same DISCOVER indicate a rogue DHCP server.
DHCP relay enables multi-subnet DHCP
Without a relay agent, DHCP broadcasts do not cross router boundaries. Configure relay agents on every subnet that uses DHCP.
DORA is the 4-step handshake
Discover, Offer, Request, Acknowledge. The transaction ID (xid) matches requests to responses.
Static IPs for OT-critical devices
Use DHCP for HMIs and workstations. Assign static addresses to PLCs, drives, and safety controllers.
DHCP assigns addresses, but devices still need to translate hostnames into those addresses. The next page covers DNS, the distributed database that maps names to IPs.