1. Home
  2. Computer Networks
  3. ARP & DHCP

ARP & DHCP

How does a new laptop get an IP address, and how does it find the MAC address of the next device? Watch the four DHCP messages (DORA) and ARP's broadcast question and unicast answer in 3D.

Interactive 3DBeginner14 min readCNUpdated

Drag to rotate · Right-drag to pan · Click, then scroll to zoom · Space play · ←→ step

What's happening

Pseudocode

    Try this in the 3D model

    • Press DHCP get an address. Which two of the four messages are broadcasts, and why is the REQUEST one of them?
    • Look at the OFFER. How is the message addressed to A, when A does not have an IP address yet?
    • Press ARP same subnet. Who receives the request, who answers, and is the answer broadcast?
    • Press ARP via gateway for 8.8.8.8. Whose MAC address ends up in the frame, and whose IP address is the destination?
    • Press ARP same subnet twice without clearing the cache. What changes the second time?

    What a host needs before it can talk

    A laptop that has just joined a network needs several things:

    It needs It gets it from
    An IP address, a subnet mask, a default gateway and a DNS server DHCP (automatically from a server)
    The MAC address of the next device on the link ARP (by asking the LAN)

    IP addresses are logical and can change. MAC addresses are physical and identify a network card on one link. A frame is delivered by MAC address, a packet is routed by IP address, so every host needs a way to map one to the other. See subnetting for how the mask divides addresses.

    DHCP: getting an address (DORA)

    Run DHCP get an address in the 3D model. Host A is plugged in with no address:

    # Message Direction What it says
    1 Discover broadcast, A → everybody “Is there a DHCP server?” Source IP 0.0.0.0, destination 255.255.255.255, UDP port 68 → 67.
    2 Offer server → A “You can have 192.168.1.100, mask /24, gateway .1, DNS 8.8.8.8, lease 8 hours.” Addressed to A’s MAC.
    3 Request broadcast, A → everybody “I accept 192.168.1.100 from server 192.168.1.1.”
    4 Acknowledge server → A “Confirmed. It is yours for 8 hours.”

    Why is the Request a broadcast when A already knows the server? Several servers may have sent offers. By broadcasting, A tells all of them whose offer it took, and the others return their addresses to the pool. DHCP runs over UDP: the server listens on port 67, the client on port 68.

    Leases

    An address is only leased. At 50% of the lease time (T1) the client asks the same server to renew. If that fails, at 87.5% (T2) it asks any server. When the lease expires, the client must stop using the address and begin again with a Discover.

    Good to know

    • A DHCP relay agent on the router lets one DHCP server serve many subnets, by forwarding the broadcasts of each subnet as unicasts to the server.
    • A client that finds no server gives itself a link-local address in 169.254.0.0/16 (APIPA), which only works on the local link.
    • The server can assign the same address every time to a given MAC (a reservation), which is how you get a stable IP without configuring the host.

    ARP: finding the MAC address

    Suppose A (192.168.1.100) wants to send a packet to B (192.168.1.20). First A checks its subnet mask to decide where B is:

    192.168.1.100  AND  255.255.255.0  =  192.168.1.0
    192.168.1.20   AND  255.255.255.0  =  192.168.1.0     same network → send it directly to B
    8.8.8.8        AND  255.255.255.0  =  8.8.8.0         different network → send it to the gateway

    Then A needs the MAC address of the next hop (B, or the gateway). It looks in its ARP cache. If the entry is missing:

    1. A broadcasts an ARP request: “Who has 192.168.1.20? Tell 192.168.1.100”. The destination MAC is FF:FF:FF:FF:FF:FF, so the switch floods it to every port.
    2. Every host examines the target IP. Everybody except B ignores it.
    3. B sends an ARP reply straight back to A (unicast): “192.168.1.20 is at BB:22.”
    4. A stores the pair in its ARP cache (entries expire after a few minutes) and sends the frame to BB:22. Later packets skip steps 1 to 3.

    ARP is not carried inside IP: it sits directly on Ethernet. It works only inside one LAN; a router never forwards an ARP broadcast.

    The IP address stays, the MAC address changes

    Press ARP via gateway. A wants to reach 8.8.8.8. It cannot reach it directly, so it does ARP for the router, 192.168.1.1, and gets EE:01. The frame is:

    Field Value
    Destination MAC EE:01 (the router)
    Destination IP 8.8.8.8 (the final destination)

    At each router the frame is taken apart, the destination IP is looked up in the routing table, and a new frame with new MAC addresses is built for the next link. IP addresses stay the same end to end; MAC addresses change at every hop.

    Other things ARP does

    • Gratuitous ARP: a host announces its own IP → MAC mapping (after a change, or to check whether another host already uses its address).
    • Proxy ARP: a router answers for hosts behind it.
    • ARP spoofing: ARP has no authentication, so an attacker can send false replies and redirect traffic to itself. Defences include static entries and dynamic ARP inspection on switches.
    • IPv6 has no ARP; it uses Neighbor Discovery (NDP).

    Code

    import ipaddress
    
    # ---------------- DHCP ----------------
    class DhcpServer:
        def __init__(self, network, first, last, gateway, dns, lease=8 * 3600):
            self.net = ipaddress.ip_network(network)
            self.pool = [ipaddress.ip_address(first) + i
                         for i in range(int(ipaddress.ip_address(last)) - int(ipaddress.ip_address(first)) + 1)]
            self.gateway, self.dns, self.lease = gateway, dns, lease
            self.leases = {}                               # MAC -> IP
    
        def discover(self, mac):
            """DHCPDISCOVER arrives: offer the client's old address, else the first free one."""
            taken = set(self.leases.values())
            ip = self.leases.get(mac) or next(p for p in self.pool if p not in taken)
            return {'type': 'OFFER', 'ip': str(ip), 'mask': str(self.net.netmask), 'gateway': self.gateway,
                    'dns': self.dns, 'lease': self.lease}
    
        def request(self, mac, ip):
            """DHCPREQUEST arrives: if the address is still free (or ours), bind it and acknowledge."""
            owner = [m for m, a in self.leases.items() if str(a) == ip]
            if owner and owner[0] != mac:
                return {'type': 'NAK'}
            self.leases[mac] = ipaddress.ip_address(ip)
            return {'type': 'ACK', 'ip': ip, 'lease': self.lease}
    
    server = DhcpServer('192.168.1.0/24', '192.168.1.100', '192.168.1.200', '192.168.1.1', '8.8.8.8')
    offer = server.discover('AA:11')
    print(offer)
    # {'type': 'OFFER', 'ip': '192.168.1.100', 'mask': '255.255.255.0', 'gateway': '192.168.1.1', 'dns': '8.8.8.8', 'lease': 28800}
    print(server.request('AA:11', offer['ip']))
    # {'type': 'ACK', 'ip': '192.168.1.100', 'lease': 28800}
    print(server.discover('BB:22')['ip'])                  # the next client gets the next address
    # 192.168.1.101
    
    # ---------------- ARP ----------------
    class Host:
        def __init__(self, ip, mac, mask='255.255.255.0', gateway='192.168.1.1'):
            self.ip, self.mac, self.mask, self.gateway = ip, mac, mask, gateway
            self.arp_cache = {}                            # IP -> MAC
    
    def next_hop(host, dst_ip):
        """Same subnet: deliver directly. Otherwise: hand the packet to the default gateway."""
        net = ipaddress.ip_network(f'{host.ip}/{host.mask}', strict=False)
        return dst_ip if ipaddress.ip_address(dst_ip) in net else host.gateway
    
    def resolve(host, lan, dst_ip, log):
        """Return the destination MAC for the next hop, sending an ARP request if it is not cached."""
        hop = next_hop(host, dst_ip)
        if hop not in host.arp_cache:
            log.append(f'ARP request (broadcast): who has {hop}? tell {host.ip}')
            for other in lan:                              # the broadcast reaches everybody
                if other.ip == hop:                        # only the owner answers
                    log.append(f'ARP reply (unicast to {host.mac}): {hop} is at {other.mac}')
                    host.arp_cache[hop] = other.mac
        return host.arp_cache[hop]
    
    a = Host('192.168.1.100', 'AA:11')
    b = Host('192.168.1.20', 'BB:22')
    r = Host('192.168.1.1', 'EE:01')
    lan = [a, b, r]
    
    log = []
    print(resolve(a, lan, '192.168.1.20', log))            # same subnet: ask for B itself
    # BB:22
    print(resolve(a, lan, '8.8.8.8', log))                 # other network: ask for the gateway
    # EE:01
    print(resolve(a, lan, '192.168.1.20', log))            # cached: no new ARP request
    # BB:22
    print(*log, sep='\n')
    # ARP request (broadcast): who has 192.168.1.20? tell 192.168.1.100
    # ARP reply (unicast to AA:11): 192.168.1.20 is at BB:22
    # ARP request (broadcast): who has 192.168.1.1? tell 192.168.1.100
    # ARP reply (unicast to AA:11): 192.168.1.1 is at EE:01
    print(a.arp_cache)
    # {'192.168.1.20': 'BB:22', '192.168.1.1': 'EE:01'}

    Common mistakes

    • Saying ARP finds the MAC address of the final destination. It finds the MAC of the next hop, which is the gateway for remote destinations.
    • Thinking the ARP reply is a broadcast. The request is broadcast; the reply is unicast to the asker.
    • Believing ARP crosses routers. It stays inside one broadcast domain (one subnet / VLAN).
    • Forgetting that DHCP Discover and Request are broadcasts, while Offer and Ack go to the client. (In some implementations the Offer and Ack are also broadcast; the model shows the usual unicast version.)
    • Mixing up DHCP ports. The server uses UDP 67 and the client uses UDP 68.
    • Confusing ARP with DNS. DNS maps a name to an IP address; ARP maps an IP address to a MAC address.

    Complexity at a glance

    Case / operationTimeWhy
    DHCP exchange4 messages (DORA)Discover and Request are broadcasts; Offer and Ack go back to the client.
    ARP resolution1 broadcast + 1 unicastOnly for the first packet to a neighbour; later packets use the cache.
    Lease renewalat 50% of the lease (T1)Then at 87.5% (T2) to any server, and at 100% the address must be given up.
    Extra spaceOne lease per client (server); one IP → MAC entry per neighbour (client)

    Quick check

    Test yourself — pick an answer to see if you got it.

    1. What do the letters in DORA stand for?

    2. Why does a client broadcast its DHCPDISCOVER?

    3. What does ARP find out?

    4. Host A (192.168.1.100/24) sends a packet to 8.8.8.8. Which MAC address is in the destination field of the Ethernet frame?

    5. Who answers an ARP request, and how?

    Saved in this browser.
    Spotted a mistake or a bug in the 3D model?

    Report a mistake

    in ARP & DHCP. Thank you — every report makes the lesson better for the next reader.

    We'll also include a link to the step of the 3D model you're on and your browser type, so we can reproduce it.