A walk-in guest with no reservation
Picture a traveler arriving at a row of hotels with no reservation, asking loudly enough for every hotel on the street to hear: "does anyone have a room?" That's DHCP's (Dynamic Host Configuration Protocol's) entire opening move, and it has to be shouted, since the device doesn't have an IP address yet and can't address a single specific server directly. One hotel calls back: "yes, room 204 is free, here are the house rules." The traveler shouts their acceptance loud enough for every other hotel to hear too, in case more than one offered a room, so the others know to stop holding theirs. The chosen hotel confirms: checked in.
DORA: Discover, Offer, Request, Acknowledge
| Step | Direction | Broadcast? | UDP port (src → dst) | Contains |
|---|---|---|---|---|
| Discover | Client → segment | Yes | 68 → 67 | "I need an IP address" |
| Offer | Server → segment | Usually | 67 → 68 | Proposed IP, lease time, subnet mask, gateway, DNS servers |
| Request | Client → segment | Yes | 68 → 67 | "I accept the offered IP", visible to every server that offered |
| Acknowledge | Server → segment | Usually | 67 → 68 | Confirms the lease is now active |
DHCP on the wire: Ethernet, IP, and UDP headers
A Discover message can't be addressed to anyone specific, so that shows up at every single layer wrapped around it. Here's exactly what a Discover packet's headers look like, stacked from the bottom up.
| Port | Used by | Role |
|---|---|---|
| 67 | DHCP server | Listens here for client broadcasts, replies from here |
| 68 | DHCP client | Listens here for server replies, sends from here |
Almost everything else on this site, DNS included, has a client pick a random ephemeral source port (see Ports & Sockets) and send to a server's well-known port. DHCP can't quite do that: before an address is assigned, there's no real socket to speak of yet, and a broadcast reply has to reach every listening client on the segment, not one specific socket. Both sides use fixed, well-known ports instead, 67 and 68, so any DHCP client and server can find each other's traffic without needing a socket already set up.
Three roles: Client, server, and relay
Everything above assumes the client and server share the same local segment. Broadcasts don't cross routers (see Collision Domain vs Broadcast Domain), so a DHCP server living on a different subnet would never hear a client's Discover at all, unless a third role bridges the gap.
- DHCP client: the device requesting an address. It has no idea, and doesn't need to know, whether it's talking to a server on its own segment or one several hops away.
- DHCP server: holds one or more address pools (scopes), tracks which addresses are currently leased to which client, and answers Discover and Request messages from its configured scopes.
- DHCP relay agent: almost always the client's own default gateway router, configured with an
ip helper-addresspointing at the real server. It listens for DHCP broadcasts on its local interface and forwards them as a unicast to that server elsewhere, then relays the server's reply back down to the local segment.
The relay does one more important thing on the way out: it stamps the packet's giaddr (gateway IP address) field with its own local interface's IP. That's how the remote server knows which scope to actually hand out an address from, and it's also the address the server sends its reply back to.
Discover has to be a broadcast because the client genuinely has no address to send from or to yet. Request is a broadcast for a different reason: if more than one DHCP server replied with an Offer, broadcasting the acceptance lets every server see which offer won, so the ones that lost know to release the address they'd tentatively reserved instead of holding it forever.