import of dnsmasq-2.42.tar.gz
diff --git a/src/rfc2131.c b/src/rfc2131.c
index 9ac595e..8b3110c 100644
--- a/src/rfc2131.c
+++ b/src/rfc2131.c
@@ -82,7 +82,8 @@
 static unsigned char *option_find(struct dhcp_packet *mess, size_t size, int opt_type, int minsize);
 static unsigned char *option_find1(unsigned char *p, unsigned char *end, int opt, int minsize);
 static size_t dhcp_packet_size(struct dhcp_packet *mess, struct dhcp_netid *netid);
-static void clear_packet(struct dhcp_packet *mess, unsigned char *end);
+static void clear_packet(struct dhcp_packet *mess, unsigned char *end, unsigned char *agent_id);
+static void restore_agent_id(unsigned char *agent_id, struct dhcp_packet *mess, unsigned char *real_end);
 static void do_options(struct dhcp_context *context,
 		       struct dhcp_packet *mess,
 		       unsigned char *real_end, 
@@ -436,7 +437,7 @@
 	      lease_set_expires(lease, 0xffffffff, now); /* infinite lease */
 	      lease_set_interface(lease, int_index);
 	      
-	      clear_packet(mess, end);
+	      clear_packet(mess, end, NULL);
 	      do_options(context, mess, end, NULL,  
 			 hostname, netid, subnet_addr, 0, 0, NULL);
 	    }
@@ -750,7 +751,7 @@
 	}
        
       time = calc_time(context, config, option_find(mess, sz, OPTION_LEASE_TIME, 4));
-      clear_packet(mess, end);
+      clear_packet(mess, end, agent_id);
       option_put(mess, end, OPTION_MESSAGE_TYPE, 1, DHCPOFFER);
       option_put(mess, end, OPTION_SERVER_IDENTIFIER, INADDRSZ, ntohl(context->local.s_addr));
       option_put(mess, end, OPTION_LEASE_TIME, 4, time);
@@ -889,11 +890,13 @@
 	  log_packet("NAK", &mess->yiaddr, emac, emac_len, iface_name, message);
 	  
 	  mess->yiaddr.s_addr = 0;
-	  clear_packet(mess, end);
+	  clear_packet(mess, end, agent_id);
 	  option_put(mess, end, OPTION_MESSAGE_TYPE, 1, DHCPNAK);
 	  option_put(mess, end, OPTION_SERVER_IDENTIFIER, INADDRSZ, 
 		     ntohl(context ? context->local.s_addr : fallback.s_addr));
 	  option_put_string(mess, end, OPTION_MESSAGE, message, borken_opt);
+	  /* DHCPNAK gets agent-id too */
+	  restore_agent_id(agent_id, mess, end);
 	  /* This fixes a problem with the DHCP spec, broadcasting a NAK to a host on 
 	     a distant subnet which unicast a REQ to us won't work. */
 	  if (!unicast_dest || mess->giaddr.s_addr != 0 || 
@@ -970,7 +973,7 @@
 	
 	  log_packet("ACK", &mess->yiaddr, emac, emac_len, iface_name, hostname);  
 	  
-	  clear_packet(mess, end);
+	  clear_packet(mess, end, agent_id);
 	  option_put(mess, end, OPTION_MESSAGE_TYPE, 1, DHCPACK);
 	  option_put(mess, end, OPTION_SERVER_IDENTIFIER, INADDRSZ, ntohl(context->local.s_addr));
 	  option_put(mess, end, OPTION_LEASE_TIME, 4, time);
@@ -1015,7 +1018,7 @@
 	  netid = &context->netid;
 	}
        
-      clear_packet(mess, end);
+      clear_packet(mess, end, agent_id);
       option_put(mess, end, OPTION_MESSAGE_TYPE, 1, DHCPACK);
       option_put(mess, end, OPTION_SERVER_IDENTIFIER, INADDRSZ, ntohl(context->local.s_addr));
 
@@ -1462,14 +1465,29 @@
     }
 }
 
-static void clear_packet(struct dhcp_packet *mess, unsigned char *end)
+static void clear_packet(struct dhcp_packet *mess, unsigned char *end, unsigned char *agent_id)
 {
+  /* don't clear agent_id */
+  if (agent_id)
+    end = agent_id;
+
   memset(mess->sname, 0, sizeof(mess->sname));
   memset(mess->file, 0, sizeof(mess->file));
   memset(&mess->options[0] + sizeof(u32), 0, end - (&mess->options[0] + sizeof(u32)));
   mess->siaddr.s_addr = 0;
 }
 
+static void restore_agent_id(unsigned char *agent_id, struct dhcp_packet *mess, unsigned char *real_end)
+{ 
+  if (agent_id)
+    {
+      unsigned char *p = dhcp_skip_opts(&mess->options[0] + sizeof(u32));
+      memmove(p, agent_id, real_end - agent_id);
+      p += real_end - agent_id;
+      memset(p, 0, real_end - p); /* in case of overlap */
+    }
+}
+
 static void do_options(struct dhcp_context *context,
 		       struct dhcp_packet *mess,
 		       unsigned char *real_end, 
@@ -1784,13 +1802,7 @@
     }
   
   /* move agent_id back down to the end of the packet */
-  if (agent_id)
-    {
-      p = dhcp_skip_opts(&mess->options[0] + sizeof(u32));
-      memmove(p, agent_id, real_end - agent_id);
-      p += real_end - agent_id;
-      memset(p, 0, real_end - p); /* in case of overlap */
-    }
+  restore_agent_id(agent_id, mess, real_end);
 
   /* restore BOOTP anti-overload hack */
   if (!req_options || (daemon->options & OPT_NO_OVERRIDE))