Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / operating-systems / Windows

Sniffing out the case of the hearing-impaired DHCP client

4.91/5 (9 votes)
25 Dec 2011CPOL4 min read 34.5K  
How I discovered that Windows Vista doesn't always play nice with DHCP servers. Google is great for finding answers if you know the right question.
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.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)