DHCP, ARP & ICMP
Why This Matters
You plug a new server into the network. Within seconds, it has an IP address, a subnet mask, a default gateway, and DNS server addresses. You did not configure any of this. How did it know?
DHCP gave it an IP address. ARP let it find the gateway's MAC address so it could actually
send packets. And when you run ping to verify connectivity, that is ICMP doing the work.
These three protocols operate largely behind the scenes, but they are foundational to how networks actually function. When DHCP fails, machines come up with no network configuration (or worse, a link-local address that goes nowhere). When ARP breaks, machines have IP addresses but cannot communicate with anything on their local network. And ICMP is the first tool you reach for when diagnosing any connectivity problem.
Understanding DHCP, ARP, and ICMP transforms you from someone who "just plugs things in and hopes" to someone who understands what happens at every step and can diagnose when things go wrong.
Try This Right Now
# See your current DHCP lease information
cat /var/lib/dhcp/dhclient.leases 2>/dev/null || \
cat /var/lib/dhclient/dhclient.leases 2>/dev/null || \
cat /var/lib/NetworkManager/*.lease 2>/dev/null || \
echo "Check: journalctl -u NetworkManager | grep -i dhcp"
# See your ARP cache (IP-to-MAC address mappings)
ip neigh show
# Send ICMP echo requests (ping)
ping -c 4 8.8.8.8
# Trace the path to a destination using ICMP
tracepath 8.8.8.8
DHCP: Dynamic Host Configuration Protocol
DHCP automatically assigns IP addresses and network configuration to devices. Without DHCP, you would need to manually configure every single device on the network -- every server, every laptop, every phone, every IoT device. That does not scale.
The DORA Process
DHCP uses a four-step process often remembered as DORA: Discover, Offer, Request, Acknowledge.
+------------------------------------------------------------------+
| DHCP DORA PROCESS |
+------------------------------------------------------------------+
| |
| Client (no IP yet) DHCP Server |
| | | |
| | 1. DHCP DISCOVER (broadcast) | |
| | "Is there a DHCP server out there?"| |
| | src: 0.0.0.0 dst: 255.255.255.255 | |
| |------------------------------------>| |
| | | |
| | 2. DHCP OFFER | |
| | "I can offer you 192.168.1.100" | |
| | + subnet mask, gateway, DNS, lease | |
| |<------------------------------------| |
| | | |
| | 3. DHCP REQUEST (broadcast) | |
| | "I'll take 192.168.1.100 please" | |
| |------------------------------------>| |
| | | |
| | 4. DHCP ACKNOWLEDGE | |
| | "Confirmed. It's yours for 24h" | |
| |<------------------------------------| |
| | | |
| Client now has: |
| IP: 192.168.1.100 |
| Mask: 255.255.255.0 |
| Gateway: 192.168.1.1 |
| DNS: 8.8.8.8, 8.8.4.4 |
| Lease: 86400 seconds (24 hours) |
| |
+------------------------------------------------------------------+
Step 1 - Discover: The client has no IP address, so it sends a broadcast message to the entire local network (destination 255.255.255.255, source 0.0.0.0). "Is there a DHCP server out there?"
Step 2 - Offer: Any DHCP server on the network responds with an offer: an available IP address and all the configuration parameters.
Step 3 - Request: The client broadcasts a request for the offered address. This is broadcast (not unicast) so that if multiple DHCP servers made offers, the others know the client chose a different server.
Step 4 - Acknowledge: The server confirms the lease. The client can now use the IP address for the duration of the lease.
Why Broadcasts?
The Discover and Request are sent as broadcasts because the client does not yet have an IP address -- it cannot send unicast traffic. The DHCP server knows to listen for these broadcasts on UDP port 67, and the client listens on UDP port 68.
DHCP Lease Lifecycle
+------------------------------------------------------------------+
| DHCP LEASE TIMELINE |
+------------------------------------------------------------------+
| |
| |--- Lease obtained ---|--- 50% (T1) ---|--- 87.5% (T2) ---| |
| 0 T1 T2 Expiry |
| | | | | |
| | Using the IP address | Try to renew | Try to rebind | |
| | normally | with same | with ANY DHCP | |
| | | server | server | |
| | | (unicast) | (broadcast) | |
| |
+------------------------------------------------------------------+
At T1 (50% of lease duration), the client tries to renew its lease with the same DHCP server using unicast. If successful, the lease timer resets.
At T2 (87.5% of lease duration), if T1 renewal failed, the client broadcasts a request to any DHCP server on the network.
If neither renewal succeeds, the lease expires and the client must start the DORA process again.
DHCP on Linux: dhclient
dhclient is the traditional DHCP client on Linux:
# Request a new DHCP lease
sudo dhclient eth0
# Release the current lease
sudo dhclient -r eth0
# Request a lease with verbose output
sudo dhclient -v eth0
# View the current lease
cat /var/lib/dhcp/dhclient.leases
A lease file looks like:
lease {
interface "eth0";
fixed-address 192.168.1.100;
option subnet-mask 255.255.255.0;
option routers 192.168.1.1;
option domain-name-servers 8.8.8.8, 8.8.4.4;
option domain-name "example.com";
renew 4 2026/02/22 10:00:00;
rebind 4 2026/02/22 22:00:00;
expire 5 2026/02/23 01:00:00;
}
Distro Note: Different distributions use different DHCP clients. Ubuntu 18.04+ uses
netplanwithsystemd-networkd, which has a built-in DHCP client. Fedora and RHEL useNetworkManager, which has its own DHCP handling. Thedhclientcommand may not be present on newer systems. OnNetworkManagersystems, usenmcliinstead:nmcli device show eth0 | grep -i dhcp nmcli connection show "Wired connection 1" | grep -i dhcp
Watching DHCP in Real-Time
# Watch DHCP traffic with tcpdump
sudo tcpdump -i eth0 -n port 67 or port 68
# Watch DHCP activity in the system journal
journalctl -f -u NetworkManager | grep -i dhcp
# Or:
journalctl -f -u systemd-networkd | grep -i dhcp
Think About It: What happens when you plug a server into a network with no DHCP server? The client sends Discovers and gets no response. After timing out, many systems auto-configure a "link-local" address in the
169.254.0.0/16range (APIPA). This address allows local-only communication but cannot reach the internet.
ARP: Address Resolution Protocol
ARP solves a fundamental problem: your machine knows the IP address it wants to reach (Layer 3), but the Ethernet frame needs a MAC address (Layer 2). How does it find the MAC address for a given IP?
How ARP Works
+------------------------------------------------------------------+
| ARP RESOLUTION PROCESS |
+------------------------------------------------------------------+
| |
| Host A (192.168.1.100) Host B (192.168.1.200) |
| MAC: aa:aa:aa:aa:aa:aa MAC: bb:bb:bb:bb:bb:bb |
| | | |
| | 1. ARP Request (broadcast) | |
| | "Who has 192.168.1.200? | |
| | Tell 192.168.1.100" | |
| |------------------------------------>| |
| | (sent to ff:ff:ff:ff:ff:ff) | |
| | | |
| | 2. ARP Reply (unicast) | |
| | "192.168.1.200 is at | |
| | bb:bb:bb:bb:bb:bb" | |
| |<------------------------------------| |
| | | |
| Host A now knows: |
| 192.168.1.200 -> bb:bb:bb:bb:bb:bb |
| Stores this in its ARP cache. |
| |
+------------------------------------------------------------------+
Step 1: Host A needs to send a packet to 192.168.1.200 but only knows the IP address.
It broadcasts an ARP request to ff:ff:ff:ff:ff:ff (every device on the LAN): "Who has
192.168.1.200? Tell 192.168.1.100."
Step 2: Host B recognizes its own IP address and replies directly (unicast) to Host A: "192.168.1.200 is at bb:bb:bb:bb:bb:bb."
Host A stores this mapping in its ARP cache and can now send the Ethernet frame.
Important ARP Detail
ARP only works within the same broadcast domain (same subnet / same VLAN). If the destination IP is on a different network, the sending host ARPs for the default gateway's MAC address and sends the packet to the router. The router then handles forwarding it to the correct network.
Host wants to reach 8.8.8.8 (different network):
1. "8.8.8.8 is not on my local subnet"
2. "I need to send it to my gateway: 192.168.1.1"
3. ARP for 192.168.1.1 -> router's MAC address
4. Send the IP packet (dst: 8.8.8.8) inside an Ethernet
frame (dst: router's MAC)
5. Router receives it, looks up the route for 8.8.8.8,
and forwards it onward
The ARP Cache
Every system maintains an ARP cache -- a table of recently resolved IP-to-MAC mappings:
# View the ARP cache
ip neigh show
192.168.1.1 dev eth0 lladdr aa:bb:cc:dd:ee:ff REACHABLE
192.168.1.50 dev eth0 lladdr 11:22:33:44:55:66 STALE
192.168.1.75 dev eth0 FAILED
| State | Meaning |
|---|---|
REACHABLE | Recently confirmed, entry is valid |
STALE | Entry has not been confirmed recently, may be outdated |
DELAY | Waiting to confirm the entry |
FAILED | ARP resolution failed (host did not respond) |
PERMANENT | Manually added static entry |
INCOMPLETE | ARP request sent, no response yet |
Managing the ARP Cache
# View the ARP cache
ip neigh show
# Delete a specific entry
sudo ip neigh del 192.168.1.50 dev eth0
# Flush the entire ARP cache
sudo ip neigh flush all
# Add a static ARP entry (permanent)
sudo ip neigh add 192.168.1.10 lladdr 00:11:22:33:44:55 dev eth0
# The older arp command (from net-tools)
arp -n # View cache
sudo arp -d 192.168.1.50 # Delete entry
sudo arp -s 192.168.1.10 00:11:22:33:44:55 # Add static entry
Hands-On: Watching ARP
# Terminal 1: Watch ARP traffic
sudo tcpdump -i eth0 -nn arp
# Terminal 2: Flush the cache and ping a local host
sudo ip neigh flush all
ping -c 1 192.168.1.1
# In Terminal 1, you should see:
# ARP, Request who-has 192.168.1.1 tell 192.168.1.100
# ARP, Reply 192.168.1.1 is-at aa:bb:cc:dd:ee:ff
# Check the ARP cache -- the entry should now be there
ip neigh show | grep 192.168.1.1
ARP and arping
arping is a specialized tool that sends ARP requests and measures responses:
# Install arping
# Debian/Ubuntu
sudo apt install arping
# Fedora/RHEL (part of iputils)
sudo dnf install iputils
# Send ARP requests to verify a host is reachable at Layer 2
sudo arping -c 3 192.168.1.1
# Output:
# ARPING 192.168.1.1 from 192.168.1.100 eth0
# Unicast reply from 192.168.1.1 [aa:bb:cc:dd:ee:ff] 0.823ms
# Unicast reply from 192.168.1.1 [aa:bb:cc:dd:ee:ff] 0.721ms
# Unicast reply from 192.168.1.1 [aa:bb:cc:dd:ee:ff] 0.654ms
This is useful when ping fails (maybe ICMP is blocked by a firewall) but you want to
verify that a host is physically present on the network.
Think About It: What happens if two devices on the same network have the same IP address? Both will respond to ARP requests, and traffic will be unpredictably delivered to one or the other. This is called an IP conflict and causes intermittent, maddening connectivity issues. Some systems detect this and log warnings.
ICMP: Internet Control Message Protocol
ICMP is a Layer 3 protocol used for diagnostics and error reporting. It is not used to transfer data between applications -- instead, it carries control messages about the network itself.
The two most common ICMP tools you will use daily are ping and traceroute/tracepath.
ICMP Message Types
| Type | Code | Name | Description |
|---|---|---|---|
| 0 | 0 | Echo Reply | Response to a ping |
| 3 | 0 | Destination Unreachable: Network | Cannot reach the network |
| 3 | 1 | Destination Unreachable: Host | Cannot reach the host |
| 3 | 3 | Destination Unreachable: Port | No service on that port (UDP) |
| 3 | 13 | Destination Unreachable: Filtered | Firewall blocked it |
| 8 | 0 | Echo Request | Ping request |
| 11 | 0 | Time Exceeded | TTL expired (used by traceroute) |
ping: Testing Connectivity
ping sends ICMP Echo Request packets and waits for Echo Reply packets. It is the first
tool you reach for when diagnosing connectivity.
# Basic ping
ping 8.8.8.8
# Send exactly 4 pings
ping -c 4 8.8.8.8
# Set a timeout (seconds)
ping -c 4 -W 2 8.8.8.8
# Change the interval between pings (default: 1 second)
ping -c 4 -i 0.5 8.8.8.8
# Set the packet size (default: 64 bytes)
ping -c 4 -s 1400 8.8.8.8
# Ping with a deadline (total seconds to run)
ping -w 5 8.8.8.8
Reading ping Output
ping -c 4 8.8.8.8
PING 8.8.8.8 (8.8.8.8) 56(84) bytes of data.
64 bytes from 8.8.8.8: icmp_seq=1 ttl=118 time=12.3 ms
64 bytes from 8.8.8.8: icmp_seq=2 ttl=118 time=11.8 ms
64 bytes from 8.8.8.8: icmp_seq=3 ttl=118 time=12.1 ms
64 bytes from 8.8.8.8: icmp_seq=4 ttl=118 time=11.9 ms
--- 8.8.8.8 ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 3004ms
rtt min/avg/max/mdev = 11.800/12.025/12.300/0.183 ms
| Field | Meaning |
|---|---|
icmp_seq | Sequence number (detect out-of-order or lost packets) |
ttl | Time To Live (how many router hops until the packet is dropped) |
time | Round-trip time in milliseconds |
packet loss | Percentage of pings that did not get a reply |
rtt | Round-trip time statistics: min/average/max/standard deviation |
What ping Results Tell You
+-----------------------------------------------------+
| INTERPRETING PING RESULTS |
+-----------------------------------------------------+
| |
| All replies, 0% loss, low time: |
| --> Connectivity is good |
| |
| All replies, 0% loss, high time: |
| --> Network congestion or long path |
| |
| Some replies, >0% loss: |
| --> Packet loss -- network problem, overloaded |
| link, or intermittent issue |
| |
| No replies, 100% loss: |
| --> Host is down, unreachable, or ICMP is |
| blocked by a firewall |
| |
| "Destination Host Unreachable": |
| --> A router on the path cannot reach the host |
| (Layer 3 routing issue) |
| |
| "Request timed out" (no output at all): |
| --> Packets are being silently dropped |
| (typically a firewall) |
| |
+-----------------------------------------------------+
WARNING: Many servers and firewalls intentionally block ICMP. A host that does not respond to
pingis not necessarily down. Always verify with other methods (TCP connection on a known port, for example:nc -zv host 22).
traceroute and tracepath: Tracing the Path
traceroute and tracepath show the route packets take from your machine to a destination.
They work by exploiting the IP TTL (Time To Live) field.
How it works:
- Send a packet with TTL=1. The first router decrements it to 0 and sends back an ICMP "Time Exceeded" message. Now you know the first hop.
- Send a packet with TTL=2. The second router sends back Time Exceeded. Now you know the second hop.
- Continue until the destination is reached.
# tracepath (no root required, uses UDP)
tracepath 8.8.8.8
# traceroute (may require root for ICMP mode)
traceroute 8.8.8.8
# traceroute using TCP (useful when ICMP is blocked)
sudo traceroute -T -p 443 8.8.8.8
# traceroute using ICMP
sudo traceroute -I 8.8.8.8
Reading tracepath Output
tracepath 8.8.8.8
1?: [LOCALHOST] pmtu 1500
1: gateway 0.321ms
1: gateway 0.262ms
2: 10.0.0.1 1.234ms asymm 3
3: 192.168.100.1 5.678ms
4: isp-router.example.net 10.234ms
5: 72.14.236.216 11.567ms reached
Resume: pmtu 1500 hops 5 back 5
| Field | Meaning |
|---|---|
| Hop number | Distance in routers from you |
| Hostname/IP | The router at that hop |
| Time | Round-trip time to that hop |
* * * | No response (router does not reply or ICMP is blocked) |
asymm | Asymmetric route (return path is different) |
Hands-On: Comparing Paths
# Trace to different destinations and compare paths
tracepath 8.8.8.8 # Google DNS
tracepath 1.1.1.1 # Cloudflare DNS
tracepath github.com # GitHub
# Notice where the paths diverge -- that's where the internet
# exchanges traffic between different networks
Distro Note:
tracepathis included iniputilson most distributions.tracerouteis a separate package:sudo apt install traceroute(Debian/Ubuntu) orsudo dnf install traceroute(Fedora/RHEL). If neither is available,mtris an excellent alternative that combines ping and traceroute:sudo apt install mtr-tiny.
Practical Troubleshooting: Putting It All Together
Here is a systematic approach using all three protocols:
Scenario: New Server Cannot Reach the Internet
# Step 1: Did we get an IP from DHCP?
ip addr show eth0
# Look for an "inet" line
# If 169.254.x.x --> DHCP failed (link-local address)
# If no "inet" --> no IP at all
# Step 2: If no DHCP, try requesting manually
sudo dhclient -v eth0
# Watch the DORA process. Does it get an offer?
# Step 3: Can we reach the local network? (ARP test)
ip route show # What is the gateway?
sudo arping -c 3 192.168.1.1 # Can we reach it at Layer 2?
# Step 4: Can we ping the gateway? (ICMP test)
ping -c 3 192.168.1.1
# Step 5: Can we reach the internet?
ping -c 3 8.8.8.8
# Step 6: Where does the path break?
tracepath 8.8.8.8
# Look for where the responses stop
# Step 7: Can we resolve DNS?
dig google.com
# If ping by IP works but DNS fails, the problem is DNS
Scenario: Intermittent Connectivity
# Long-running ping to detect packet loss patterns
ping -c 100 192.168.1.1
# Use mtr for continuous traceroute (combines ping + traceroute)
mtr 8.8.8.8
# Check ARP -- is the MAC address flapping?
watch -n 1 'ip neigh show | grep 192.168.1.1'
# If the MAC address keeps changing, there might be a duplicate IP
# or a network loop
Scenario: Can Ping by IP, Cannot Resolve Names
# Verify DNS is the issue
ping -c 1 8.8.8.8 # Works
ping -c 1 google.com # Fails
# Check DNS configuration
cat /etc/resolv.conf
# Is there a nameserver configured?
# Test DNS directly
dig @8.8.8.8 google.com # Does a known-good DNS server work?
dig @$(grep nameserver /etc/resolv.conf | head -1 | awk '{print $2}') google.com
# Does the configured DNS server work?
# If the configured server fails, fix /etc/resolv.conf or
# check if the DNS server is reachable
ping -c 1 $(grep nameserver /etc/resolv.conf | head -1 | awk '{print $2}')
Debug This
A newly provisioned virtual machine has an IP address (192.168.1.50/24) and can ping
itself and the gateway (192.168.1.1). But it cannot ping any other machine on the same
subnet (e.g., 192.168.1.100).
ping -c 3 192.168.1.1 # Works
ping -c 3 192.168.1.100 # "Destination Host Unreachable"
ip neigh show # 192.168.1.100 FAILED
Diagnosis:
The ARP resolution for 192.168.1.100 is failing. The VM sends ARP requests but gets no
reply. Possible causes:
-
The target host is down -- Verify that
192.168.1.100is actually powered on and has its interface up. -
VLAN mismatch -- The VM and the target might be on different VLANs, even though they have addresses in the same subnet. VLANs create separate Layer 2 broadcast domains.
-
VM network mode -- If this is a VM, check the virtual switch configuration. The VM might be in "NAT" mode (its own private network) instead of "bridged" mode (shared network with the host).
-
Firewall blocking ARP -- Unusual, but some host firewalls or security tools can block ARP. Check
iptables -Land any bridge-level filtering (ebtables).
Resolution:
# Check from the target side -- can it see the ARP request?
# On 192.168.1.100:
sudo tcpdump -i eth0 arp
# Check the VM's virtual switch settings
# (depends on your hypervisor: VirtualBox, KVM, VMware)
# If VLAN mismatch, check the switch port configuration
# or the virtual switch VLAN tagging
What Just Happened?
+------------------------------------------------------------------+
| CHAPTER RECAP |
+------------------------------------------------------------------+
| |
| DHCP: Automatic IP configuration using DORA process. |
| Discover -> Offer -> Request -> Acknowledge |
| Lease-based: IP is "rented" for a specific duration. |
| Renewal at 50% (T1) and 87.5% (T2) of lease time. |
| |
| ARP: Resolves IP addresses to MAC addresses on the LAN. |
| Broadcast request, unicast reply. |
| ARP cache: ip neigh show |
| arping: test Layer 2 reachability |
| |
| ICMP: Network diagnostics and error reporting. |
| ping: test host reachability and latency |
| tracepath/traceroute: discover the network path |
| ICMP types: Echo (ping), Destination Unreachable, |
| Time Exceeded (traceroute) |
| |
| Troubleshooting order: |
| DHCP (do I have an IP?) -> ARP (can I reach local hosts?) |
| -> ICMP (can I reach remote hosts?) -> DNS (can I resolve?) |
| |
+------------------------------------------------------------------+
Try This
-
DHCP Observation: On a test machine or VM, release your DHCP lease and watch the DORA process in real-time:
# Terminal 1: Watch DHCP traffic sudo tcpdump -i eth0 -nn port 67 or port 68 # Terminal 2: Release and renew sudo dhclient -r eth0 # Release sudo dhclient -v eth0 # Request new lease -
ARP Exploration: Flush your ARP cache, then ping several machines on your local network. Watch the ARP cache populate:
sudo ip neigh flush all ping -c 1 192.168.1.1 ip neigh show ping -c 1 192.168.1.100 ip neigh show -
Ping Patterns: Run a long-duration ping to your gateway and to an internet host simultaneously. Compare packet loss and latency:
ping -c 100 192.168.1.1 > /tmp/gateway-ping.txt & ping -c 100 8.8.8.8 > /tmp/internet-ping.txt & wait tail -3 /tmp/gateway-ping.txt tail -3 /tmp/internet-ping.txt -
Tracepath Investigation: Run
tracepathto three different destinations on different continents. Compare the number of hops and latency at each hop. Where does the latency jump significantly? (Usually at intercontinental links.) -
arping vs ping: Find a host on your network that responds to
pingbut not toarping, or vice versa. What does this tell you about the host's firewall configuration? -
Bonus Challenge: Set up a small DHCP server using
dnsmasqon a test network. Configure it to hand out addresses in a specific range with a custom lease time, gateway, and DNS server. Connect a client and verify the full DORA process withtcpdump.# Example dnsmasq config (/etc/dnsmasq.conf): # interface=eth1 # dhcp-range=10.0.0.100,10.0.0.200,255.255.255.0,1h # dhcp-option=3,10.0.0.1 # Gateway # dhcp-option=6,8.8.8.8 # DNS server