From 795645ee6948ea48d15815a44aa36e89c75a2be5 Mon Sep 17 00:00:00 2001
From: Tyson Whitehead <twhitehead@gmail.com>
Date: Thu, 29 Dec 2011 12:30:17 -0500
Subject: [PATCH] Include PXE info from boot server too instead of just DHCP
 server

 * DHCP is preferred for PXE options (PXE spec Section 2.4.1)
 * Boot server is preferred for default server and boot image
---
 docs/grub.texi             |   11 +++++++++++
 grub-core/fs/i386/pc/pxe.c |   23 +++++++++++++++++++++++
 2 files changed, 34 insertions(+), 0 deletions(-)

diff --git a/docs/grub.texi b/docs/grub.texi
index b11e383..ad90144 100644
--- a/docs/grub.texi
+++ b/docs/grub.texi
@@ -1934,6 +1934,10 @@ The boot file name provided by DHCP.  Read-only.
 The name of the DHCP server responsible for these boot parameters.
 Read-only.
 
+@item net_pxe_boot_server_name
+The name of the boot server responsible for these boot parameters.
+Read-only.
+
 @item pxe_blksize
 The PXE transfer block size.  Read-write, defaults to 512.
 
@@ -2447,6 +2451,7 @@ These variables have special meaning to GRUB.
 * menu_color_normal::
 * net_pxe_boot_file::
 * net_pxe_dhcp_server_name::
+* net_pxe_boot_server_name::
 * net_pxe_domain::
 * net_pxe_extensionspath::
 * net_pxe_hostname::
@@ -2690,6 +2695,12 @@ The default is the value of @samp{color_normal} (@pxref{color_normal}).
 @xref{Network}.
 
 
+@node net_pxe_boot_server_name
+@subsection net_pxe_boot_server_name
+
+@xref{Network}.
+
+
 @node net_pxe_domain
 @subsection net_pxe_domain
 
diff --git a/grub-core/fs/i386/pc/pxe.c b/grub-core/fs/i386/pc/pxe.c
index 4304881..8aeb51a 100644
--- a/grub-core/fs/i386/pc/pxe.c
+++ b/grub-core/fs/i386/pc/pxe.c
@@ -501,6 +501,7 @@ grub_pxe_detect (void)
   if (! pxenv)
     return;
 
+  /* DHCP PXE options take precedence over boot server (2.4.1) */
   ci.packet_type = GRUB_PXENV_PACKET_TYPE_DHCP_ACK;
   ci.buffer = 0;
   ci.buffer_size = 0;
@@ -517,10 +518,32 @@ grub_pxe_detect (void)
 	       : sizeof (bp->mac_addr));
   set_env_limn_ro ("net_pxe_boot_file", (char *) bp->boot_file,
 		   sizeof (bp->boot_file));
+  set_env_limn_ro ("net_pxe_boot_server_name", (char *) bp->server_name,
+		   sizeof (bp->server_name));
   set_env_limn_ro ("net_pxe_dhcp_server_name", (char *) bp->server_name,
 		   sizeof (bp->server_name));
   parse_dhcp_vendor (&bp->vendor, sizeof (bp->vendor));
+
   grub_pxe_pxenv = pxenv;
+
+  /* Boot server PXE options add and override boot file/server */
+  ci.packet_type = GRUB_PXENV_PACKET_TYPE_CACHED_REPLY;
+  ci.buffer = 0;
+  ci.buffer_size = 0;
+  grub_pxe_call (GRUB_PXENV_GET_CACHED_INFO, &ci, pxe_rm_entry);
+  if (ci.status)
+    return;
+
+  bp = LINEAR (ci.buffer);
+
+  grub_pxe_default_server_ip = bp->server_ip;
+  grub_register_variable_hook ("net_pxe_boot_file", 0, 0);
+  grub_register_variable_hook ("net_pxe_boot_server_name", 0, 0);
+  set_env_limn_ro ("net_pxe_boot_file", (char *) bp->boot_file,
+		   sizeof (bp->boot_file));
+  set_env_limn_ro ("net_pxe_boot_server_name", (char *) bp->server_name,
+		   sizeof (bp->server_name));
+  parse_dhcp_vendor (&bp->vendor, sizeof (bp->vendor));
 }
 
 void
-- 
1.7.5.4

