DHCPD stopping, my fix... for 4.1.0

Friesen, Don SSBC:EX Don.Friesen at gov.bc.ca
Tue Jan 12 20:56:02 UTC 2010


   From reading the archive I see a number of reports of what we've been
seeing.  It's triggered by a workstation with a valid dynamic lease on a
remote network, configured to unicast its DHCPRequest to the server that
granted its lease.  This bypasses the relay.  On the server side, the
client gets assigned a fixed-address... while the dynamic lease remains
active.  When the client requests a lease extension, the server goes to
send a NAK... and stops.   It may very well be a DLPI issue, that's
beyond my scope.  I copied some code from the routine that ACKs to the
one that NAKs.  My server now correctly sends the NAK and the
workstation DISCOVERs its fixed-address.

   I made the following changes to the 'nak_lease' routine in
'server/dhcp.c' to fix my particular problem...  output of a "diff -u":

--- server/dhcp.c.ORIGINAL	Thu Jan  7 15:01:33 2010
+++ server/dhcp.c	Tue Jan 12 11:46:13 2010
@@ -1381,6 +1381,7 @@
 	if (packet->interface->address_count)
 		raw.siaddr = packet->interface->addresses[0];
 	raw.giaddr = packet -> raw -> giaddr;
+	raw.ciaddr = packet -> raw -> ciaddr;
 	memcpy (raw.chaddr, packet -> raw -> chaddr, sizeof raw.chaddr);
 	raw.hlen = packet -> raw -> hlen;
 	raw.htype = packet -> raw -> htype;
@@ -1387,7 +1388,7 @@
 
 	raw.xid = packet -> raw -> xid;
 	raw.secs = packet -> raw -> secs;
-	raw.flags = packet -> raw -> flags | htons (BOOTP_BROADCAST);
+	raw.flags = packet -> raw -> flags;
 	raw.hops = packet -> raw -> hops;
 	raw.op = BOOTREPLY;
 
@@ -1428,10 +1429,10 @@
 	if (outgoing.packet_length < BOOTP_MIN_LEN)
 		outgoing.packet_length = BOOTP_MIN_LEN;
 
-	/* If this was gatewayed, send it back to the gateway.
-	   Otherwise, broadcast it on the local network. */
+	/* If this was gatewayed, send it back to the gateway. */
 	if (raw.giaddr.s_addr) {
 		to.sin_addr = raw.giaddr;
+	        raw.flags |= htons (BOOTP_BROADCAST);
 		if (raw.giaddr.s_addr != htonl (INADDR_LOOPBACK))
 			to.sin_port = local_port;
 		else
@@ -1444,13 +1445,27 @@
 					      from, &to, &hto);
 			return;
 		}
+
+	   /* If it comes from a client that already knows its address
+	      and is not requesting a broadcast response, and we can
+	      unicast to a client without using the ARP protocol, sent
it
+	      directly to that client. */
+	} else if (raw.ciaddr.s_addr &&
+         		can_unicast_without_arp (packet -> interface)) {
+	      to.sin_addr = raw.ciaddr;
+	      to.sin_port = remote_port;
+
+	/* Otherwise, broadcast it on the local network. */
 	} else {
+	        raw.flags |= htons (BOOTP_BROADCAST);
 		to.sin_addr = limited_broadcast;
 		to.sin_port = remote_port;
 	}
 
 	errno = 0;
-	result = send_packet (packet -> interface,
+	result = send_packet ((fallback_interface
+		      		? fallback_interface : packet ->
interface),
 			      packet, &raw, outgoing.packet_length,
 			      from, &to, (struct hardware *)0);
 }


    My supervisor hopes that the unicast NAK can make it into production
code, so we can avoid having to work this fix in with each release we
upgrade to.  The DHCPRequest packet this services looks like:

DHCP: ----- Dynamic Host Configuration Protocol -----
DHCP: 
DHCP: Hardware address type (htype) =  1 (Ethernet (10Mb))
DHCP: Hardware address length (hlen) = 6 octets
DHCP: Relay agent hops = 0
DHCP: Transaction ID = 0x6d8fc30
DHCP: Time since boot = 0 seconds
DHCP: Flags = 0x0000
DHCP: Client address (ciaddr) = 192.168.213.114
DHCP: Your client address (yiaddr) = 0.0.0.0
DHCP: Next server address (siaddr) = 0.0.0.0
DHCP: Relay agent address (giaddr) = 0.0.0.0
DHCP: Client hardware address (chaddr) = 00:03:47:CC:E3:3D
DHCP: 
DHCP: ----- (Options) field options -----
DHCP: 
DHCP: Message type = DHCPREQUEST
DHCP: Client Identifier =       0x01 0x00 0x03 0x47 0xCC 0xE3 0x3D
(unprintable)
DHCP: Client Hostname = Fungus
DHCP: Client Class Identifier = "MSFT 5.0"
DHCP: Requested Options:
DHCP:    1 (Subnet Mask)
DHCP:   15 (DNS Domain Name)
DHCP:    3 (Router)
DHCP:    6 (DNS Servers)
DHCP:   44 (NetBIOS RFC 1001/1002 Name Servers)
DHCP:   46 (NetBIOS Node Type)
DHCP:   47 (NetBIOS Scope)
DHCP:   31 (Perform Router Discovery Flag)
DHCP:   33 (Static Routes)
DHCP:   43 (Vendor Specific Options)


   We are running 4.1.0.  I looked in 4.1.1rc1, and see the same problem
with nak_lease not supporting a unicast NAK to a remote network.

P.S.  This is my first post to a list, and I hope I have not infringed
on any etiquette.


Don Friesen



-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.isc.org/pipermail/dhcp-users/attachments/20100112/ff74ed75/attachment.html>


More information about the dhcp-users mailing list