Networking
DHCP
Leasing an IP address in four packets — the DORA handshake
DHCP (Dynamic Host Configuration Protocol) automatically leases an IP address, subnet mask, default gateway, and DNS servers to a host over UDP ports 67 and 68 using the four-step DORA handshake — Discover, Offer, Request, Acknowledge. Standardized in RFC 2131 (March 1997) as the successor to BOOTP, it lets a device with no address at all bootstrap a full network configuration from a shared pool, so an office of thousands of laptops never needs a single hand-typed IP. Addresses are handed out as time-bounded leases that clients renew at the T1 (50%) and T2 (87.5%) timers before they expire.
- HandshakeDORA — Discover / Offer / Request / Ack
- TransportUDP · server port 67 · client port 68
- StandardRFC 2131 / 2132 (1997), successor to BOOTP
- Renewal timersT1 = 50%, T2 = 87.5% of lease
- Cross-subnetRelay agent stamps
giaddr - SecurityDHCP snooping (trusted vs untrusted ports)
Interactive visualization
Press play, or step through manually. The visualization is yours to drive — try it before reading on.
Watch the 60-second explainer
A condensed visual walkthrough — narrated, captioned, under a minute.
Why DHCP matters
Every device that speaks IP needs at minimum four things: an address, a subnet mask (so it knows which hosts are local), a default gateway (the router to reach everything else), and at least one DNS server (to turn names into addresses). Configuring those by hand on ten thousand laptops, phones, and IoT sensors — and keeping them collision-free as machines come and go — is impossible at scale. DHCP centralizes the whole job in one server (or a redundant pair) and a pool of addresses. A brand-new device that has never touched the network can join, get a working configuration, and be routing packets within a few hundred milliseconds, with no human involved.
That is why DHCP is one of the most-run protocols on Earth: it fires every time a phone joins Wi-Fi, every time a laptop wakes from sleep, every time a data-center VM boots. Its correctness properties — no two hosts get the same address, an offline host's address is eventually reclaimed, and a client keeps its address across reboots when possible — are what make large, churning networks livable.
How DHCP works: the DORA handshake
The initial acquisition is four messages. A useful mnemonic is that the client and server each speak twice, alternating:
- D — DHCPDISCOVER. The client has no IP yet, so it broadcasts: source
0.0.0.0, destination255.255.255.255, UDP src port 68 → dst port 67. It includes its MAC inchaddrand a randomxid(transaction ID) that ties the whole exchange together. It may include Option 50 (Requested IP) to ask for a previous address. - O — DHCPOFFER. Every server that hears the Discover reserves a candidate address and replies with an Offer: the proposed
yiaddr("your IP address"), the lease time, and options for gateway, DNS, and mask. On a network with multiple DHCP servers, the client can receive several offers. - R — DHCPREQUEST. The client picks one offer and broadcasts a Request that names the chosen server in Option 54 (Server Identifier) and the accepted address in Option 50. Because it is a broadcast, the servers whose offers were not chosen see it too and release their reserved addresses back to the pool.
- A — DHCPACK. The chosen server commits the binding in its lease database and sends the Acknowledge with the final lease time and the full option set. Only now does the client configure the address on its interface. (If the server can no longer honor the offer, it sends a DHCPNAK instead and the client restarts.)
The client should verify the address is unused with a gratuitous ARP before binding; if a reply comes back, it sends a DHCPDECLINE and the server blacklists that address. When the client is done (say, gracefully shutting down), it may send a DHCPRELEASE to return the lease early.
The lease lifecycle and the T1/T2 timers
A DHCP address is not owned, it is leased for a bounded duration (Option 51). The client runs two renewal timers relative to when the lease began:
- T1 (renewal timer, default 50% of the lease). The client enters the RENEWING state and unicasts a DHCPREQUEST straight to the server it originally leased from. A successful ACK resets the whole lease clock. This is a quiet, no-broadcast conversation between just those two.
- T2 (rebinding timer, default 87.5% — i.e. 7/8 — of the lease). If the original server never answered by T2, the client assumes it may be down and enters REBINDING: it broadcasts a DHCPREQUEST so any server on the subnet can renew or reassign the lease.
- Expiry. If nothing answers by the end of the lease, the client must stop using the address, drop back to the INIT state, and run full DORA again.
The 50% / 87.5% split is deliberate: it gives the client two full retry windows — one polite unicast phase and one desperate broadcast phase — before it is ever forced to give up a working address. Short leases (minutes) suit high-churn guest Wi-Fi where addresses must recycle fast; long leases (days) suit stable offices and reduce broadcast traffic.
Crossing subnets: the relay agent
DORA begins with a broadcast, and routers do not forward broadcasts — so by default a client can only reach a DHCP server on its own subnet. In practice you want one central server for the whole campus. The bridge is a relay agent (Cisco calls it an ip helper-address): the router itself listens for DHCP broadcasts, then unicasts them to the configured server's address.
The relay does one more critical thing: it writes its own subnet-facing interface address into the giaddr ("gateway IP address") field of the packet. The server reads giaddr to figure out which subnet the client is on, and therefore which address pool (scope) to draw from. Without that field the server would have no way to know a relayed request came from the 10.2.0.0/24 floor versus the 10.9.0.0/24 floor. Relay Agent Information (Option 82) can add further port/circuit detail that snooping and IPAM systems rely on.
DHCP options: more than an address
The last field of a DHCP packet is a variable-length options list, a sequence of (code, length, value) tuples terminated by option 255. This is where the real configuration lives. A handful you meet constantly:
| Option | Name | What it configures |
|---|---|---|
| 1 | Subnet Mask | Which addresses are on-link vs remote |
| 3 | Router | Default gateway(s) |
| 6 | Domain Name Server | DNS resolver addresses |
| 15 | Domain Name | DNS search suffix |
| 51 | IP Address Lease Time | Lease duration in seconds |
| 53 | DHCP Message Type | DISCOVER / OFFER / REQUEST / ACK / NAK / … |
| 54 | Server Identifier | Which server the client accepted |
| 50 | Requested IP Address | Address the client wants (e.g. its last one) |
| 82 | Relay Agent Information | Circuit/remote-ID stamped by the relay |
The magic cookie 99.130.83.99 (0x63825363) precedes the options field and is the byte pattern that distinguishes a DHCP packet from a plain BOOTP one — it is the historical seam where DHCP grew out of BOOTP while staying wire-compatible.
DHCP vs static IP vs reservation
| DHCP (dynamic) | DHCP reservation | Static IP | |
|---|---|---|---|
| Address stability | May change per lease | Same address, tied to MAC | Fixed forever |
| Configured where | Central server pool | Central server (per-MAC) | On the device, by hand |
| Gateway/DNS learned | Automatically | Automatically | Typed manually |
| Scales to thousands? | Yes | Yes | No (error-prone) |
| Survives server outage? | Only until lease expires | Only until lease expires | Yes (no dependency) |
| Best for | Laptops, phones, guests | Printers, cameras — findable but managed | Routers, DNS servers, the DHCP server itself |
The DHCP server itself must have a static address — a chicken-and-egg rule people forget. Reservations are the underrated middle ground: you get the "always the same address" property of static without touching the device, because the mapping lives in one place you can audit.
Security: rogue servers and DHCP snooping
DHCP has no authentication in its base form. Any host on the LAN can answer a DISCOVER — including an attacker who hands out a malicious default gateway and DNS server, silently routing all your traffic through their machine (a classic man-in-the-middle). A misconfigured home router plugged into a corporate port causes the same damage by accident.
DHCP snooping is the switch-level defense. You mark the ports that legitimately face DHCP servers (or uplinks toward them) as trusted; every other port is untrusted. The switch then drops any server-sourced message (OFFER, ACK, NAK) that arrives on an untrusted port — so a rogue server plugged into a random desk jack is simply ignored. As a side effect the switch builds a binding table of legitimate MAC ↔ IP ↔ port ↔ VLAN tuples, which is the foundation for Dynamic ARP Inspection (stops ARP spoofing) and IP Source Guard (stops address spoofing). A companion control, port security / rate-limiting the number of DHCP requests, blunts DHCP starvation, where an attacker forges thousands of MACs to drain the entire pool.
How the DORA exchange works (pseudocode)
A stripped-down client state machine, showing the branch between renew (unicast) and rebind (broadcast):
def dhcp_client(iface):
xid = random_32bit()
# --- INIT: no address yet, must broadcast ---
broadcast(DHCPDISCOVER, src="0.0.0.0", dst="255.255.255.255",
chaddr=iface.mac, xid=xid,
options={53: "DISCOVER", 50: iface.last_ip}) # ask for prior IP if any
offers = collect(DHCPOFFER, xid=xid, timeout=4) # may be several servers
best = choose(offers) # usually first / longest lease
# --- SELECTING: name the chosen server so others withdraw ---
broadcast(DHCPREQUEST, xid=xid,
options={53: "REQUEST", 54: best.server_id, 50: best.yiaddr})
ack = wait_for(DHCPACK_or_NAK, xid=xid, timeout=4)
if ack.type == "NAK":
return dhcp_client(iface) # rejected — restart DORA
# ARP-probe the address before we commit it
if arp_probe(ack.yiaddr): # someone answered -> conflict
unicast(DHCPDECLINE, dst=ack.server_id, options={50: ack.yiaddr})
return dhcp_client(iface)
iface.bind(ack.yiaddr, mask=ack.opt(1), gw=ack.opt(3), dns=ack.opt(6))
lease = ack.opt(51) # seconds
t1, t2 = ack.opt(58, lease*0.50), ack.opt(59, lease*0.875)
started = now()
# --- BOUND: sit on the address, watch the clock ---
while True:
if now() - started >= t2: # REBINDING — server may be dead, ask anyone
ack = broadcast_request(ack.yiaddr, xid=random_32bit())
elif now() - started >= t1: # RENEWING — quiet unicast to our server
ack = unicast_request(ack.yiaddr, to=ack.server_id, xid=random_32bit())
else:
sleep_until(started + t1); continue
if ack and ack.type == "ACK": # renewed: reset the clock
lease, started = ack.opt(51), now()
t1, t2 = lease*0.50, lease*0.875
elif now() - started >= lease: # nothing answered in time — give up the address
iface.unbind()
return dhcp_client(iface) # back to INIT, full DORA
Note the two nuances that trip people up: the DHCPREQUEST during acquisition is a broadcast (so losing servers withdraw), but the renewal request at T1 is a unicast to a known server. And every retry uses a fresh xid for a new transaction — during acquisition the wanted address rides in Option 50, but a renewal/rebind carries the current address in the ciaddr field instead (Option 50 and Option 54 are omitted).
Common misconceptions and pitfalls
- "The client can just pick any address it likes." No — the client proposes with Option 50, but the server owns the pool and can NAK. The gratuitous-ARP check exists precisely because the server's database is not omniscient about unmanaged static hosts.
- "DHCP uses TCP." No — it is UDP (67/68), because at DISCOVER time the client has no IP to complete a TCP handshake. Reliability is handled by client retransmission with the same
xid. - "A relay agent is a second DHCP server." No — it forwards, it does not allocate. It never owns a pool; it only unicasts broadcasts to the real server and stamps
giaddr. - "Renewal always broadcasts." No — T1 renewal is a unicast to the original server; only the T2 rebind broadcasts. Confusing the two makes packet captures look wrong.
- "169.254.x.x came from DHCP." The opposite — a
169.254.0.0/16address is APIPA / link-local, the fallback a host self-assigns when no DHCP server answered. It is a symptom of a broken or unreachable DHCP path, often a missing relay or a full pool. - "Two DHCP servers on one subnet is fine if pools don't overlap." Risky — without split-scope coordination or a failover protocol, races and duplicate offers cause churn. Use a DHCP failover protocol (such as the ISC failover state machine, or RFC 3074 load-balancing across a shared scope) or explicitly non-overlapping split scopes.
Frequently asked questions
What does DORA stand for in DHCP?
DORA is the four-message exchange that leases an address: Discover, Offer, Request, Acknowledge. The client broadcasts a DHCPDISCOVER to find any server; each server replies with a DHCPOFFER proposing an address; the client broadcasts a DHCPREQUEST naming the server it accepted (which tells the others to withdraw their offers); the server confirms with a DHCPACK carrying the lease and options. Only after the ACK does the client bind the address to its interface.
Which UDP ports does DHCP use, and why is it broadcast?
DHCP runs over UDP: the server listens on port 67 and the client on port 68. It must use broadcast at first because the client has no IP address yet — it cannot be the target of a unicast reply, and it does not know the server's address. The DHCPDISCOVER is sent from 0.0.0.0 to 255.255.255.255, and the server's offer is broadcast back (or unicast if the client sets the broadcast flag to 0 and can accept unicast before binding).
What are the T1 and T2 timers in a DHCP lease?
T1 and T2 govern renewal. T1 defaults to 50% of the lease duration: at T1 the client tries to renew by unicasting a DHCPREQUEST directly to the leasing server (RENEWING state). T2 defaults to 87.5% (7/8) of the lease: if the original server never answered, at T2 the client broadcasts a DHCPREQUEST to reach any server (REBINDING state). If the lease fully expires with no ACK, the client must relinquish the address and restart DORA from scratch.
What is a DHCP relay agent and when do you need one?
A relay agent (IP helper) forwards DHCP messages between subnets so one central server can serve many broadcast domains. Routers do not forward broadcasts, so without a relay a client's DHCPDISCOVER never leaves its LAN. The relay unicasts the request to the configured server, stamps the giaddr field with the interface it received the packet on, and the server uses giaddr to pick the correct address pool for that subnet. This is the DHCPv4 equivalent of an IPv6 relay-forward message.
What is the difference between DHCP and a static IP?
With DHCP the address is leased dynamically from a pool and can change between leases; the client learns its gateway, DNS, and other options automatically. A static IP is configured by hand on the device and never changes, which is why servers, printers, and routers usually use one. The middle ground is a DHCP reservation: the server always hands the same address to a given MAC, giving you a fixed address that is still centrally managed.
What is DHCP snooping and what attack does it stop?
DHCP snooping is a switch security feature that classifies ports as trusted or untrusted and drops DHCPOFFER and DHCPACK messages arriving on untrusted ports. This blocks a rogue DHCP server — an attacker who hands out a malicious default gateway or DNS to perform a man-in-the-middle. The switch also builds a binding table of MAC-IP-port pairs, which underpins Dynamic ARP Inspection and IP Source Guard.
How does DHCP avoid handing out an address that is already in use?
Two safeguards. Before committing an offer, the server may ping (ICMP echo) the candidate address to check no unmanaged host is using it. Before accepting an ACK, the client should send a gratuitous ARP (ARP probe) for its new address; if another host replies, the client sends a DHCPDECLINE and the server marks the address as bad. Together these catch overlapping static assignments and rogue duplicates that the lease database alone cannot see.