---
title: DHCP
source: 'https://academia.sh/en/courses/network-models/dhcp'
course: 'Network Models and Protocols'
language: en
updated: '2026-08-17T18:07:07+00:00'
license: 'CC BY-SA 4.0'
---

# DHCP

The four steps of dynamic address leasing, lease duration and renewal thresholds, deriving pools from the example plan, and the relay agent's role.

The previous lessons assumed every address on the example network was assigned by hand.
That assumption holds for the ten machines in the server room; it does not hold for the
hundred devices on the guest wireless network. Entering address, mask, gateway, and name
server information into every device one by one is not feasible.

This lesson's question is where a device gets these four pieces of information the
moment it joins the network. The answer starts with a chicken-and-egg problem: for the
device to request the information, it needs an address, but it is requesting because it
does not have one.

## Talking Without an Address

The problem is solved at the link layer. The device uses the **unspecified address**
`0.0.0.0` instead of its own address and writes the **limited broadcast address**
`255.255.255.255` as the destination. At the frame level, the destination becomes the
broadcast address `ff:ff:ff:ff:ff:ff`. This broadcast reaches every device in the
broadcast domain; whichever one distributes configuration replies.

**DHCP (Dynamic Host Configuration Protocol)** is the protocol that carries out this
exchange. It runs over UDP; the client uses port 68, the server port 67. The
transport-layer choice is forced: a protocol that requires connection setup cannot be
used when there is no address yet.

## The Four Steps

Leasing is completed with four messages.

| Step | Message | Direction | Addressing | Information carried |
|---|---|---|---|---|
| 1 | Discover | Client → Broadcast | `0.0.0.0` → `255.255.255.255` | Client's hardware address, transaction ID |
| 2 | Offer | Server → Client | Server address → Broadcast or unicast | Proposed address, mask, gateway, lease duration |
| 3 | Request | Client → Broadcast | `0.0.0.0` → `255.255.255.255` | Accepted offer and the server's identifier |
| 4 | Acknowledge | Server → Client | Server address → Broadcast or unicast | Lease finalization and options |

Why the third step is sent **as a broadcast** is not obvious at first glance: the client
already knows which server made the offer. The reason is that multiple servers may be
present. When the request goes out as a broadcast, the servers whose offers were not
accepted see it too and release the address they had reserved. Without the broadcast,
those addresses would sit reserved uselessly for an entire lease period.

In the second step, because the client does not yet have an address, the server's reply
contains an oddity: the reply must be sent to an address that has not been assigned yet.
Implementations resolve this two ways — either sending the reply as a broadcast, or
building the frame directly to the client's hardware address. The client indicates which
it prefers with a flag in the discover message.

## Options

The real value of the lease is the configuration information that comes along with the
address. These are carried in **option** fields:

| Option | Information carried | Value on the example network (administration section) |
|---|---|---|
| Subnet mask | Network/host boundary | `255.255.255.224` |
| Router | Default gateway | `192.168.10.193` |
| Name server | Resolver addresses | `192.168.10.226` |
| Domain name | Search suffix | The organization's internal domain |
| Lease duration | Validity | In seconds |
| Server identifier | Who issued the lease | The server's address |
| Renewal thresholds | T1 and T2 | Fractions of the lease duration |

The mask's presence in this list recalls the observation from the Subnetting lesson: an
address alone is incomplete information. The lease delivers the address together with
its mask.

## Lease Duration and Renewal

An address is not granted permanently; it is **leased**. At the end of the period, the
lease expires and the address returns to the pool. The reason it is time-limited is to
prevent devices that connect once and leave from holding their addresses indefinitely.

The client does not wait out the period; it attempts renewal at two thresholds:

| Threshold | Timing | Behavior |
|---|---|---|
| T1 | 50% of the lease duration | Direct renewal request to the server that issued the lease |
| T2 | 87.5% of the lease duration | Broadcast rebinding request to any server |
| Expiration | 100% | Address is released, process starts over |

For an eight-hour lease, T1 arrives at four hours, T2 at seven. If renewal succeeds, the
period restarts from zero and the address does not change. This is why a device mostly
keeps the same address even when the lease duration is short.

Choosing the lease duration is a trade-off. A short duration returns released addresses
to the pool quickly and prevents pool exhaustion on a busy guest network; in exchange,
renewal traffic increases. A long duration reduces traffic; in exchange, released
addresses stay blocked for a long time and configuration changes propagate late.

## The Example Network's Pools

The plan finalized in the Variable-Length Subnetting lesson must be translated into a
leasing configuration. In each subnet, addresses split into three: the first address
reserved for the router, a range reserved for manual assignment, and the remainder as
the dynamic pool.

```python
import ipaddress

# (section, block, addresses reserved for manual assignment, expected dynamic clients)
SECTIONS = [
    ("Guest wireless", "192.168.10.0/25", 9, 100),
    ("Lab", "192.168.10.128/26", 5, 45),
    ("Administration", "192.168.10.192/27", 9, 11),
    ("Server room", "192.168.10.224/28", 13, 0),
    ("Link", "192.168.10.240/30", 1, 0),
]

for name, cidr, reserved, expected in SECTIONS:
    net = ipaddress.ip_network(cidr)
    addrs = list(net.hosts())
    router = addrs[0]
    manual = addrs[1:1 + reserved]
    pool = addrs[1 + reserved:]
    manual_text = (f"{manual[0]}-{manual[-1]}" if manual else "none")
    pool_text = (f"{pool[0]}-{pool[-1]} ({len(pool)})" if pool else "none")
    print(f"{name:18s} {cidr:20s} router={str(router):15s} "
          f"manual={manual_text:31s} pool={pool_text:35s} "
          f"spare={len(pool) - expected if pool else 0}")
```

```
Guest wireless     192.168.10.0/25      router=192.168.10.1    manual=192.168.10.2-192.168.10.10      pool=192.168.10.11-192.168.10.126 (116)  spare=16
Lab                192.168.10.128/26    router=192.168.10.129  manual=192.168.10.130-192.168.10.134   pool=192.168.10.135-192.168.10.190 (56)  spare=11
Administration     192.168.10.192/27    router=192.168.10.193  manual=192.168.10.194-192.168.10.202   pool=192.168.10.203-192.168.10.222 (20)  spare=9
Server room        192.168.10.224/28    router=192.168.10.225  manual=192.168.10.226-192.168.10.238   pool=none                                spare=0
Link               192.168.10.240/30    router=192.168.10.241  manual=192.168.10.242-192.168.10.242   pool=none                                spare=0
```

The server room and link networks have no dynamic pool; server addresses must not
change, and both ends of the point-to-point link are routers.

The pool margins are meaningful. The guest network has 116 addresses for an expected
100 devices; the 16-address margin covers more devices connecting at once than expected.
The lease duration should be kept short on this network: the addresses of devices that
come and go should return to the pool quickly.

## Reserved Addresses and Fixed Leasing

The manual assignment range is the set of addresses the leasing server never touches.
But there is a second way to give a device a fixed address: **reservation**. The server
always hands out the same IP address to a particular hardware address.

The client the course has been tracking is configured this way:

| Hardware address | Assigned address | Method |
|---|---|---|
| `00:00:5e:00:53:01` | `192.168.10.196` | Reservation |

The difference between the two methods is administrative. With manual assignment, the
configuration lives on the device; when the mask or gateway changes, every device must
be visited individually. With reservation, the configuration is centralized; the device
still gets its address through leasing, but always the same one. When a network-wide
option changes, it changes in one place.

The hardware address that reservation relies on may not stay fixed on devices that
rotate their address for privacy. In that case, the reservation does not hold, and the
device gets an address from the pool.

## The Relay Agent

The discover message goes out as a broadcast, and a broadcast does not cross a router.
The example network has five subnets; placing a separate leasing server in each is an
unnecessary administrative burden.

The solution is the **relay agent**. The router captures the broadcast arriving on its
interface, forwards it to the central server as a unicast packet, and adds a field to
the message indicating which interface it came from. The server decides which pool to
serve from by looking at that field.

If `192.168.10.226` in the server room provides both name resolution and leasing
service on the example network, relaying is configured on every internal interface of
the router. A client in the administration section's discover message reaches the
server carrying `192.168.10.193` in the interface field, and the server serves an
address from the administration pool.

## Failure Patterns

**Rogue leasing server.** If a device added to the broadcast domain sends out leasing
offers, clients accept whichever offer arrives first. A wrong gateway or wrong name
server can get distributed. The countermeasure operates at the switch level: leasing
replies are only allowed to arrive from designated ports.

**Pool exhaustion.** If every address in the pool is leased, new clients cannot get an
address. The symptom is that some devices work and others do not. The measure is to
monitor pool occupancy and adjust the lease duration to demand.

**Falling back to a link-local address.** An interface that cannot get an address picks
one for itself from the `169.254.0.0/16` block. A device carrying an address in this
block is a direct sign that leasing failed: the server is unreachable, relaying is not
configured, or the pool is exhausted.

**Address conflict.** If a manually assigned address falls inside the pool range, that
same address can also get leased out. This is why the manual assignment range is kept
outside the pool when building the plan.

## Summary

- The client talks without an address: source `0.0.0.0`, destination
  `255.255.255.255`; the protocol uses ports 67 and 68 over UDP.
- Leasing is completed with four messages; the third step goes out as a broadcast so
  that servers whose offers were not accepted release their addresses.
- The mask, gateway, name server, and lease duration are delivered along with the
  address.
- Renewal is attempted at the 50% and 87.5% thresholds of the lease duration; the
  address does not change on a successful renewal.
- In the example plan, the guest pool is 116 addresses, the lab 56, administration 20;
  the server room and link networks have no dynamic pool.
- Because broadcasts do not cross a router, networks with many subnets use a relay
  agent; an address from the `169.254.0.0/16` block indicates that leasing failed.

## Next Step

Every device on the example network now has an address; but all of these addresses
come from the private-use block and are not routed on the public Internet. The
organization has exactly one public address: `203.0.113.10`. The next lesson covers how
hundreds of private addresses go outbound through a single public address, how the
translation table is kept, and what this mechanism does to end-to-end connectivity.
