Monday, September 14, 2015

Just some quick points about DHCP

Okay, so everybody knows DHCP pretty well.

I just want to point out a few little details as background for a future post:

DHCP Relays Can Change Things
The first point is about those times when the DHCP client and server aren't on the same segment.

In these cases, a DHCP relay (usually running on a router) scoops up the helpless client's broadcast packets and fires them at the far away DHCP server. The server's replies are sent back to the relay, and the relay transmits them onto the client subnet.

The DHCP relay can change several things when relaying these packets:
  • It increments the bootp hop counter.
  • It populates the relay agent field in the bootp header (The DHCP server uses this to identify the subnet where the client is looking for a lease).
  • It can introduce additional DHCP options to the request.
The last one is particularly interesting. When a DHCP relay adds information to a client message, it can be used by the DHCP server for decision-making or logging purposes. Alternatively, the added information can be used by the DHCP relay itself: Because the relay's addition will be echoed back by the server, the relay can parse information it added to a DISCOVER message when relaying the resulting OFFER message back toward the client.

DHCP servers shortcut ARP
Consider the following DHCP offer sent to a client:

1:  14:11:09.966124 a4:93:4c:46:d3:3f (oui Unknown) > 40:6c:8f:38:26:60 (oui Unknown), ethertype IPv4 (0x0800), length 342: (tos 0x0, ttl 255, id 30511, offset 0, flags [none], proto UDP (17), length 328)  
2:    192.168.26.254.bootps > 192.168.26.225.bootpc: BOOTP/DHCP, Reply, length 300, hops 1, xid 0x91b0d169, Flags [none]  
3:        Your-IP 192.168.26.225  
4:        Gateway-IP 192.168.26.254  
5:        Client-Ethernet-Address 40:6c:8f:38:26:60 (oui Unknown)  
6:        Vendor-rfc1048 Extensions  
7:         Magic Cookie 0x63825363  
8:         DHCP-Message Option 53, length 1: Offer  
9:         Server-ID Option 54, length 4: 192.168.5.13  
10:         Lease-Time Option 51, length 4: 7200  
11:         Subnet-Mask Option 1, length 4: 255.255.255.224  
12:         Default-Gateway Option 3, length 4: 192.168.26.254  
13:         Domain-Name-Server Option 6, length 4: localhost  
14:         Domain-Name Option 15, length 5: "a.net"  

Line 2 indicates that it's a unicast IP packet, sent to 192.168.26.225. Line 1 tells us the packet arrived in a unicast Ethernet frame. Nothing too unusual looking about it.

But how did the DHCP relay encapsulate this IP packet into that Ethernet frame? Usually the dMAC seen in the frame header is the result of an ARP query. That can't work in this case: The client won't answer an ARP query for 192.168.26.225 because it doesn't yet own that address.

The encapsulation seen here skipped over ARP. Instead, the relay pulled the dMAC from the DHCP payload (line 5). Nifty.

DHCP Clients use Raw Sockets
Everything we know about learning bridges and interface promiscuity applies here. The IP layer in the client system receives this frame because it was sent to the unicast MAC address and the client's NIC allowed it in.

Line 2 indicates that it's also a unicast IP packet, sent to 192.168.26.225.

But this is the DHCP OFFER. The client doesn't yet own the address to which the offer is sent. In fact, the client don't even know that the address available for its use until it gets to line 3 (a bootp option inside a UDP datagram inside this IP packet). The client won't have actually leased this address until it Requests this address from the server, and the server ACKs the request.

So how can the client receive this IP packet, when it's sent to an address that nobody owns?

The answer is Raw Sockets. Raw sockets give a privileged program the ability to undercut various layers (UDP and IP in this case) of the OS stack, and send/receive messages directly. This is also probably how the DHCP relay encapsulated the offer (skipping ARP) in the first place.

The details of raw socket implementations are specific to the operating system, but usually include the ability to specify an interface and to apply a filter, so that the application doesn't have to process every message on the wire.

8 comments:

  1. Just two small notes:

    The dest MAC in the reply will be the all-one MAC if the client asks so with the "broadcast flag" in the request. This is uncommon today, but I still see it with old/oddball equipment, and not all relays support that flag.

    The dest IP of the reply is the subnet broadcast: from the article it is not very clear to me if you meant that at that time, for the client, it is just an ordinary unicast address, or if you misread 255 for 225.

    ReplyDelete
    Replies
    1. Hi Michele,

      Thanks for pointing out the broadcast flag. I've not seen it used.

      I'm fuzzy about your comment regarding dest IP. Line 2 sure looks like a unicast to me. I suspect one of us is confused :)

      Delete
  2. It was me confusing 225 and 255 after all...

    ReplyDelete
    Replies
    1. That confused me for a minute as well - the traffic dump shows .225, but Chris' explanation references .255 (the paragraph beginning 'Line 2 indicates that...').
      I suspect it's a typo in the text, because the dump is unicast.

      Delete
    2. Ah, yes. There's the source of confusion. Thank you for pointing it out, 8:51 Anon.

      Fixed.

      Delete
  3. Both paragraphs beginning with "Line 2 indicates" incorrectly reference 192.168.26.255 instead of the actual IP address in the DHCP offer example (192.168.26.225). Slightly confusing, especially since .255 would be the broadcast address for the example subnet.

    ReplyDelete
  4. I liked your work and the way in which you have shared this article here about testing and tagging sydney for us .It is a beneficial and helpful article for us. Thanks for sharing an article like this.

    ReplyDelete