diff -Naur grub-cvs-clean/ChangeLog grub-cvs/ChangeLog
--- grub-cvs-clean/ChangeLog	2005-09-28 18:00:54.000000000 -0500
+++ grub-cvs/ChangeLog	2005-10-24 00:23:28.850358968 -0500
@@ -1,3 +1,43 @@
+2005-10-23  Andy Goth  <unununium@openverse.com>
+
+	This patch splits ARP_SERVER into ARP_DHCPSERVER and ARP_TFTPSERVER.
+
+        * netboot/etherboot.h: Replaced ARP_SERVER with ARP_DHCPSERVER and
+	ARP_TFTPSERVER, thereby adding another slot to the ARP table.  Since
+	DHCP and TFTP are done in separate phases, this step isn't strictly
+	necessary (we've done fine so far, eh?), but it does make it easier to
+	debug a setup where DHCP and TFTP are served by different machines.
+
+	* netboot/main.c: Added support for separate ARP_DHCPSERVER and
+	ARP_TFTPSERVER.  By default, the TFTP server is assumed to be the same
+	as the DHCP server, as reported in bootpreply.  This is compatible
+	with the previous version, but the previous version didn't work for me
+	(bootpreply->bp_siaddr is 0.0.0.0), hence this patch.  So I can't say
+	for certain that I haven't broken anything.  By the way, why did I
+	have a problem to begin with?  Incompatibility with udhcpd?
+
+	* netboot/main.c: Replaced ARP_SERVER with ARP_TFTPSERVER or
+	ARP_DHCPSERVER, whichever was appropriate in context.
+	
+	* netboot/main.c: "ifconfig --server" adjusts ARP_TFTPSERVER because
+	ARP_DHCPSERVER isn't contacted by IP address.  There is no way to set
+	the DHCP MAC or IP addresses except by running "dhcp".
+
+	* netboot/main.c: In print_network_configuration(), print the IP
+	addresses of both the TFTP server and the DHCP/BOOTP server.
+
+	* netboot/main.c: On RFC2132_SRV_ID, change the IP address associated
+	with ARP_DHCPSERVER.  I don't bother zeroing the MAC address since the
+	DHCP server is never contacted again; as far as I can tell, setting
+	the IP address at this point is purely cosmetic.  ARP_TFTPSERVER is
+	left untouched--- it is initialized from bootpreply and modified only
+	by RFC2132_VENDOR_TFTPSERVER.
+
+	* netboot/main.c: Added support for RFC2132_VENDOR_TFTPSERVER, which
+	allows the DHCP server to supply a name the TFTP server.
+
+	* netboot/fsys_tftp.c: Replaced ARP_SERVER with ARP_TFTPSERVER.
+
 2005-09-29  Yoshinori K. Okuji  <okuji@enbug.org>
 
 	* docs/multiboot.texi: Fix a bug in the byte order of
diff -Naur grub-cvs-clean/netboot/etherboot.h grub-cvs/netboot/etherboot.h
--- grub-cvs-clean/netboot/etherboot.h	2002-05-08 02:12:29.000000000 -0500
+++ grub-cvs/netboot/etherboot.h	2005-10-24 00:13:16.229491496 -0500
@@ -106,11 +106,12 @@
 				- sizeof (struct udphdr))
 
 #define ARP_CLIENT	0
-#define ARP_SERVER	1
+#define ARP_DHCPSERVER	1
 #define ARP_GATEWAY	2
 #define ARP_ROOTSERVER	3
 #define ARP_SWAPSERVER	4
-#define MAX_ARP		ARP_SWAPSERVER+1
+#define ARP_TFTPSERVER	5
+#define MAX_ARP		6
 
 #define	RARP_REQUEST	3
 #define	RARP_REPLY	4
@@ -193,6 +194,7 @@
 #define RFC2132_PARAM_LIST	55
 #define RFC2132_MAX_SIZE	57
 #define RFC2132_VENDOR_CLASS_ID	60
+#define RFC2132_VENDOR_TFTPSERVER	66
 
 #define DHCPDISCOVER		1
 #define DHCPOFFER		2
diff -Naur grub-cvs-clean/netboot/fsys_tftp.c grub-cvs/netboot/fsys_tftp.c
--- grub-cvs-clean/netboot/fsys_tftp.c	2004-04-15 06:50:29.000000000 -0500
+++ grub-cvs/netboot/fsys_tftp.c	2005-10-24 00:13:16.244489216 -0500
@@ -76,7 +76,7 @@
 #ifdef TFTP_DEBUG
 	      grub_printf ("Maybe initial request was lost.\n");
 #endif
-	      if (! udp_transmit (arptable[ARP_SERVER].ipaddr.s_addr,
+	      if (! udp_transmit (arptable[ARP_TFTPSERVER].ipaddr.s_addr,
 				  ++iport, TFTP_PORT, len, &tp))
 		return 0;
 	      
@@ -90,7 +90,7 @@
 # ifdef TFTP_DEBUG
 	      grub_printf ("<REXMT>\n");
 # endif
-	      udp_transmit (arptable[ARP_SERVER].ipaddr.s_addr,
+	      udp_transmit (arptable[ARP_TFTPSERVER].ipaddr.s_addr,
 			    iport, oport,
 			    TFTP_MIN_PACKET, &tp);
 	      continue;
@@ -166,7 +166,7 @@
 			 + sizeof (tp.ip) + sizeof (tp.udp)
 			 + sizeof (tp.opcode) + sizeof (tp.u.err.errcode)
 			 + 1);
-		  udp_transmit (arptable[ARP_SERVER].ipaddr.s_addr,
+		  udp_transmit (arptable[ARP_TFTPSERVER].ipaddr.s_addr,
 				iport, ntohs (tr->udp.src),
 				len, &tp);
 		  return 0;
@@ -220,7 +220,7 @@
       grub_printf ("ACK\n");
 #endif
       /* Ack.  */
-      udp_transmit (arptable[ARP_SERVER].ipaddr.s_addr, iport,
+      udp_transmit (arptable[ARP_TFTPSERVER].ipaddr.s_addr, iport,
 		    oport, TFTP_MIN_PACKET, &tp);
       
       if (abort)
@@ -294,7 +294,7 @@
   }
 #endif
   /* Send the packet.  */
-  return udp_transmit (arptable[ARP_SERVER].ipaddr.s_addr, ++iport,
+  return udp_transmit (arptable[ARP_TFTPSERVER].ipaddr.s_addr, ++iport,
 		       TFTP_PORT, len, &tp);
 }
 
diff -Naur grub-cvs-clean/netboot/main.c grub-cvs/netboot/main.c
--- grub-cvs-clean/netboot/main.c	2004-05-20 17:17:27.000000000 -0500
+++ grub-cvs/netboot/main.c	2005-10-24 00:13:16.245489064 -0500
@@ -121,8 +121,16 @@
     {
       etherboot_printf ("Address: %@\n", arptable[ARP_CLIENT].ipaddr.s_addr);
       etherboot_printf ("Netmask: %@\n", netmask);
-      etherboot_printf ("Server: %@\n", arptable[ARP_SERVER].ipaddr.s_addr);
       etherboot_printf ("Gateway: %@\n", arptable[ARP_GATEWAY].ipaddr.s_addr);
+      etherboot_printf (
+#ifdef NO_DHCP_SUPPORT
+			"BOOTP Server: %@\n",
+#else
+      			"DHCP Server: %@\n",
+#endif
+			arptable[ARP_DHCPSERVER].ipaddr.s_addr);
+      etherboot_printf ("TFTP Server: %@\n",
+			arptable[ARP_TFTPSERVER].ipaddr.s_addr);
     }
 }
 
@@ -171,11 +179,11 @@
   /* Clear out the ARP entry.  */
   grub_memset (arptable[ARP_GATEWAY].node, 0, ETH_ALEN);
   
-  if (svr && ! inet_aton (svr, &arptable[ARP_SERVER].ipaddr)) 
+  if (svr && ! inet_aton (svr, &arptable[ARP_TFTPSERVER].ipaddr)) 
     return 0;
 
   /* Likewise.  */
-  grub_memset (arptable[ARP_SERVER].node, 0, ETH_ALEN);
+  grub_memset (arptable[ARP_TFTPSERVER].node, 0, ETH_ALEN);
   
   if (ip || sm)
     {
@@ -321,7 +329,7 @@
   len = (grub_sprintf ((char *) tp.u.rrq, "%s%coctet%cblksize%c%d",
 		       name, 0, 0, 0, TFTP_MAX_PACKET)
 	 + sizeof (tp.ip) + sizeof (tp.udp) + sizeof (tp.opcode) + 1);
-  if (! udp_transmit (arptable[ARP_SERVER].ipaddr.s_addr, ++iport,
+  if (! udp_transmit (arptable[ARP_TFTPSERVER].ipaddr.s_addr, ++iport,
 		      TFTP_PORT, len, &tp))
     return 0;
   
@@ -340,7 +348,7 @@
 	  if (! block && retry++ < MAX_TFTP_RETRIES)
 	    {
 	      /* Maybe initial request was lost.  */
-	      if (! udp_transmit (arptable[ARP_SERVER].ipaddr.s_addr,
+	      if (! udp_transmit (arptable[ARP_TFTPSERVER].ipaddr.s_addr,
 				  ++iport, TFTP_PORT, len, &tp))
 		return 0;
 	      
@@ -354,7 +362,7 @@
 #ifdef MDEBUG
 	      grub_printf ("<REXMT>\n");
 #endif
-	      udp_transmit (arptable[ARP_SERVER].ipaddr.s_addr,
+	      udp_transmit (arptable[ARP_TFTPSERVER].ipaddr.s_addr,
 			    iport, oport,
 			    TFTP_MIN_PACKET, &tp);
 	      continue;
@@ -411,7 +419,7 @@
 			 + sizeof (tp.ip) + sizeof (tp.udp)
 			 + sizeof (tp.opcode) + sizeof (tp.u.err.errcode)
 			 + 1);
-		  udp_transmit (arptable[ARP_SERVER].ipaddr.s_addr,
+		  udp_transmit (arptable[ARP_TFTPSERVER].ipaddr.s_addr,
 				iport, ntohs (tr->udp.src),
 				len, &tp);
 		  return 0;
@@ -446,7 +454,7 @@
       tp.opcode = htons (TFTP_ACK);
       oport = ntohs (tr->udp.src);
       /* Ack.  */
-      udp_transmit (arptable[ARP_SERVER].ipaddr.s_addr, iport,
+      udp_transmit (arptable[ARP_TFTPSERVER].ipaddr.s_addr, iport,
 		    oport, TFTP_MIN_PACKET, &tp);
       
       if ((unsigned short) (block - prevblock) != 1)
@@ -829,9 +837,9 @@
 	      if (arpreply->opcode == htons (RARP_REPLY)
 		  && ! grub_memcmp (arpreply->thwaddr, ptr, ETH_ALEN))
 		{
-		  grub_memmove ((char *) arptable[ARP_SERVER].node,
+		  grub_memmove ((char *) arptable[ARP_DHCPSERVER].node,
 				arpreply->shwaddr, ETH_ALEN);
-		  grub_memmove ((char *) &arptable[ARP_SERVER].ipaddr,
+		  grub_memmove ((char *) &arptable[ARP_DHCPSERVER].ipaddr,
 				arpreply->sipaddr, sizeof (in_addr));
 		  grub_memmove ((char *) &arptable[ARP_CLIENT].ipaddr,
 				arpreply->tipaddr, sizeof (in_addr));
@@ -906,10 +914,13 @@
 #endif
 #endif /* ! NO_DHCP_SUPPORT */
 	      netmask = default_netmask ();
-	      arptable[ARP_SERVER].ipaddr.s_addr
+	      arptable[ARP_DHCPSERVER].ipaddr.s_addr
+		= bootpreply->bp_siaddr.s_addr;
+	      arptable[ARP_TFTPSERVER].ipaddr.s_addr
 		= bootpreply->bp_siaddr.s_addr;
 	      /* Kill arp.  */
-	      grub_memset (arptable[ARP_SERVER].node, 0, ETH_ALEN);
+	      grub_memset (arptable[ARP_DHCPSERVER].node, 0, ETH_ALEN);
+	      grub_memset (arptable[ARP_TFTPSERVER].node, 0, ETH_ALEN);
 	      arptable[ARP_GATEWAY].ipaddr.s_addr
 		= bootpreply->bp_giaddr.s_addr;
 	      /* Kill arp.  */
@@ -1047,10 +1058,21 @@
       else if (c == RFC2132_SRV_ID)
 	{
 	  grub_memmove ((char *) &dhcp_server, p + 2, sizeof (in_addr));
+	  grub_memmove ((char *) &arptable[ARP_DHCPSERVER].ipaddr.s_addr,
+			p + 2, sizeof (in_addr));
 #ifdef DEBUG
 	  etherboot_printf ("dhcp_server = %@\n", dhcp_server.s_addr);
 #endif
 	}
+      else if (c == RFC2132_VENDOR_TFTPSERVER
+	       && TAG_LEN(p) >= 7
+	       && TAG_LEN(p) <= 15)
+	{
+	  char tftpsrv_str[16];
+	  grub_memmove (tftpsrv_str, p + 2, TAG_LEN(p));
+	  tftpsrv_str[TAG_LEN(p)] = '\000';
+	  ifconfig (NULL, NULL, NULL, tftpsrv_str);
+	}
 #endif /* ! NO_DHCP_SUPPORT */
       else if (c == RFC1533_VENDOR_MAGIC
 	       && TAG_LEN(p) >= 6
