This morning, my wife reminded me that I said I would "fix" her computer. Her laptop had always required a reboot after waking or unhibernating in order to get an IP address from the DHCP server. Now it refused to get one at all.
The DHCP server is embedded in one of those SMC wireless cable modem doodads that Rogers hands out. This isn't the first problem we've had with it (the WiFi cuts out when we use the microwave oven, and is weak to begin with), so I was tempted to get it replaced, but chances are the next box would have the same problems.
Her laptop runs Windows Vista 64-bit. I ran
ipconfig /renew
, and sure enough, it timed out before getting an IP address and returned some error about the DHCP server not responding. I knew something wasn't right, because all the other devices on the network have been getting DHCP leases without difficulty.
If you're not sure how DHCP works, here is the (oversimplified) Coles Notes.
"Hey, is there a DHCP server out there? I need an address please!"
A computer without an IP address must use the address 0.0.0.0
. It sends out a broadcast packet (a unicast packet to 255.255.255.255
) called DHCPDISCOVER
.
"I'm a DHCP server. How would you like the address 192.168.0.123?"
The DHCP server monitors broadcast packets, and when it hears a DHCPDISCOVER
it checks its inventory of available addresses and provisions one for the requestor. It then sends a reply called an DHCPOFFER
that notifies the client that it has provisioned an address for it. How does it send a message to a client without an IP address? The hardware MAC address is used to identify the unique requestor.
"That's a nice one! I'll take it."
It's now up to the client to accept or decline the address assignment. Under normal circumstances, there will only be one DHCPOFFER
, and the client will accept it. It does so by replying with a formal DHCPREQUEST
for the address that was offered by the server.
"OK. It's yours for the next 12 hours." The server finalizes the transaction by confirming a lease. It sends a DHCPACK
packet that confirms the assignment and establishes a lease. Once the lease has expired, the client must request a new address, even if it is reassigned the same one.
So back to my problem. Why isn't the client getting a lease. The best way of finding out is to use a packet sniffer. I fired up
Wireshark[
^] on my desktop and started sniffing. A packet sniffer listens passively on the network and reports every packet it encounters. This isn't particularly useful on switched networks because all communications are between each node and the switch, keeping nodes out of conversations that don't involve them; however DHCP uses broadcast messages, so they get sent to all nodes by the switch.
I tried
ipconfig /renew
again. Sure enough, I saw the client's
DHCPDISCOVER
packet, immediately followed by a
DHCPOFFER
response from the server. But then... nothing. The client wasn't sending a
DHCPREQUEST
.
I had enough information to check the Google. A search for
vista dhcp dhcprequest
led me right to
KB928233: Windows Vista cannot obtain an IP address from certain routers or from certain non-Microsoft DHCP servers[
^]. I followed the instructions in the article, changing a registry setting, and sure enough it worked. Problem solved.
One thing however bugged me about that article. It describes a problem in which the server does not respond to a
DHCPDISCOVER
packet in which the DHCP
broadcast
bit is set. I examined the conversation in Wireshark again. Actually, the server responded correctly to the packet, returning a
DHCPOFFER
that also had the
broadcast
bit set. I referred to
RFP 2131[
^]:
Normally, DHCP servers and BOOTP relay agents attempt to deliver
DHCPOFFER, DHCPACK and DHCPNAK messages directly to the client using
uicast delivery. The IP destination address (in the IP header) is
set to the DHCP 'yiaddr' address and the link-layer destination
address is set to the DHCP 'chaddr' address. Unfortunately, some
client implementations are unable to receive such unicast IP
datagrams until the implementation has been configured with a valid
IP address (leading to a deadlock in which the client's IP address
cannot be delivered until the client has been configured with an IP
address).
A client that cannot receive unicast IP datagrams until its protocol
software has been configured with an IP address SHOULD set the
BROADCAST bit in the 'flags' field to 1 in any DHCPDISCOVER or
DHCPREQUEST messages that client sends. The BROADCAST bit will
provide a hint to the DHCP server and BOOTP relay agent to broadcast
any messages to the client on the client's subnet. A client that can
receive unicast IP datagrams before its protocol software has been
configured SHOULD clear the BROADCAST bit to 0. The BOOTP
clarifications document discusses the ramifications of the use of the
BROADCAST bit [21].
A server or relay agent sending or relaying a DHCP message directly
to a DHCP client (i.e., not to a relay agent specified in the
'giaddr' field) SHOULD examine the BROADCAST bit in the 'flags'
field. If this bit is set to 1, the DHCP message SHOULD be sent as
an IP broadcast using an IP broadcast address (preferably 0xffffffff)
as the IP destination address and the link-layer broadcast address as
the link-layer destination address. If the BROADCAST bit is cleared
to 0, the message SHOULD be sent as an IP unicast to the IP address
specified in the 'yiaddr' field and the link-layer address specified
in the 'chaddr' field. If unicasting is not possible, the message
MAY be sent as an IP broadcast using an IP broadcast address
(preferably 0xffffffff) as the IP destination address and the link-
layer broadcast address as the link-layer destination address.
In our case, the
broadcast
bit need not be set because the operating system is able to receive the packet. The server replied correctly by sending its reply as a broadcast packet to
255.255.255.255
, leaving the
broadcast
bit set. It seems this is the problem. Vista appears to ignore
DHCPOFFER
packets if the
broadcast
bit is set, even if it initiated the request with the bit set.
Today's lessons:
- Don't assume common protocols like DHCP will just work, or that they are implemented correctly.
- Packet sniffers like Wireshark are invaluable in quickly diagnosing layer 2 and 3 problems.
- Knowing what to search for will often lead you directly to a workaround.
- A workaround is not a solution.