Blame SOURCES/0257-bootp-Add-processing-DHCPACK-packet-from-HTTP-Boot.patch

d41074
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
a85e8e
From: Michael Chang <mchang@suse.com>
a85e8e
Date: Thu, 14 Jul 2016 18:45:14 +0800
d41074
Subject: [PATCH] bootp: Add processing DHCPACK packet from HTTP Boot
a85e8e
a85e8e
The vendor class identifier with the string "HTTPClient" is used to denote the
a85e8e
packet as responding to HTTP boot request. In DHCP4 config, the filename for
a85e8e
HTTP boot is the URL of the boot file while for PXE boot it is the path to the
a85e8e
boot file. As a consequence, the next-server becomes obseleted because the HTTP
a85e8e
URL already contains the server address for the boot file. For DHCP6 config,
a85e8e
there's no difference definition in existing config as dhcp6.bootfile-url can
a85e8e
be used to specify URL for both HTTP and PXE boot file.
a85e8e
a85e8e
This patch adds processing for "HTTPClient" vendor class identifier in DHCPACK
a85e8e
packet by treating it as HTTP format, not as the PXE format.
a85e8e
a85e8e
Signed-off-by: Michael Chang <mchang@suse.com>
a85e8e
Signed-off-by: Ken Lin <ken.lin@hpe.com>
a85e8e
---
a85e8e
 grub-core/net/bootp.c | 68 +++++++++++++++++++++++++++++++++++++++++++++++++--
a85e8e
 include/grub/net.h    |  1 +
a85e8e
 2 files changed, 67 insertions(+), 2 deletions(-)
a85e8e
a85e8e
diff --git a/grub-core/net/bootp.c b/grub-core/net/bootp.c
d41074
index dd4660601e2..d47ad80a2ad 100644
a85e8e
--- a/grub-core/net/bootp.c
a85e8e
+++ b/grub-core/net/bootp.c
a85e8e
@@ -20,6 +20,7 @@
a85e8e
 #include <grub/env.h>
a85e8e
 #include <grub/i18n.h>
a85e8e
 #include <grub/command.h>
a85e8e
+#include <grub/net.h>
a85e8e
 #include <grub/net/ip.h>
a85e8e
 #include <grub/net/netbuff.h>
a85e8e
 #include <grub/net/udp.h>
a85e8e
@@ -254,6 +255,11 @@ parse_dhcp_vendor (const char *name, const void *vend, int limit, int *mask)
a85e8e
                                      taglength);
a85e8e
           break;
a85e8e
 
a85e8e
+        case GRUB_NET_BOOTP_VENDOR_CLASS_IDENTIFIER:
a85e8e
+          grub_env_set_net_property (name, "vendor_class_identifier", (const char *) ptr,
a85e8e
+                                     taglength);
a85e8e
+	  break;
a85e8e
+
a85e8e
 	case GRUB_NET_BOOTP_EXTENSIONS_PATH:
a85e8e
           grub_env_set_net_property (name, "extensionspath", (const char *) ptr,
a85e8e
                                      taglength);
a85e8e
@@ -356,6 +362,66 @@ grub_net_configure_by_dhcp_ack (const char *name,
a85e8e
     }
a85e8e
 #endif
a85e8e
 
a85e8e
+  if (size > OFFSET_OF (vendor, bp))
a85e8e
+    {
a85e8e
+      char *cidvar;
a85e8e
+      const char *cid;
a85e8e
+
a85e8e
+      parse_dhcp_vendor (name, &bp->vendor, size - OFFSET_OF (vendor, bp), &mask);
a85e8e
+      cidvar = grub_xasprintf ("net_%s_%s", name, "vendor_class_identifier");
a85e8e
+      cid = grub_env_get (cidvar);
a85e8e
+      grub_free (cidvar);
a85e8e
+
a85e8e
+      if (cid && grub_strcmp (cid, "HTTPClient") == 0)
a85e8e
+	{
a85e8e
+	  char *proto, *ip, *pa;
a85e8e
+
a85e8e
+	  if (!dissect_url (bp->boot_file, &proto, &ip, &pa))
a85e8e
+	    return inter;
a85e8e
+
a85e8e
+	  grub_env_set_net_property (name, "boot_file", pa, grub_strlen (pa));
a85e8e
+	  if (is_def)
a85e8e
+	    {
a85e8e
+	      grub_net_default_server = grub_strdup (ip);
a85e8e
+	      grub_env_set ("net_default_interface", name);
a85e8e
+	      grub_env_export ("net_default_interface");
a85e8e
+	    }
a85e8e
+	  if (device && !*device)
a85e8e
+	    {
a85e8e
+	      *device = grub_xasprintf ("%s,%s", proto, ip);
a85e8e
+	      grub_print_error ();
a85e8e
+	    }
a85e8e
+	  if (path)
a85e8e
+	    {
a85e8e
+	      *path = grub_strdup (pa);
a85e8e
+	      grub_print_error ();
a85e8e
+	      if (*path)
a85e8e
+		{
a85e8e
+		  char *slash;
a85e8e
+		  slash = grub_strrchr (*path, '/');
a85e8e
+		  if (slash)
a85e8e
+		    *slash = 0;
a85e8e
+		  else
a85e8e
+		    **path = 0;
a85e8e
+		}
a85e8e
+	    }
a85e8e
+	  grub_net_add_ipv4_local (inter, mask);
a85e8e
+	  inter->dhcp_ack = grub_malloc (size);
a85e8e
+	  if (inter->dhcp_ack)
a85e8e
+	    {
a85e8e
+	      grub_memcpy (inter->dhcp_ack, bp, size);
a85e8e
+	      inter->dhcp_acklen = size;
a85e8e
+	    }
a85e8e
+	  else
a85e8e
+	    grub_errno = GRUB_ERR_NONE;
a85e8e
+
a85e8e
+	  grub_free (proto);
a85e8e
+	  grub_free (ip);
a85e8e
+	  grub_free (pa);
a85e8e
+	  return inter;
a85e8e
+	}
a85e8e
+    }
a85e8e
+
a85e8e
   if (size > OFFSET_OF (boot_file, bp))
a85e8e
     grub_env_set_net_property (name, "boot_file", bp->boot_file,
a85e8e
                                sizeof (bp->boot_file));
a85e8e
@@ -417,8 +483,6 @@ grub_net_configure_by_dhcp_ack (const char *name,
a85e8e
 	    **path = 0;
a85e8e
 	}
a85e8e
     }
a85e8e
-  if (size > OFFSET_OF (vendor, bp))
a85e8e
-    parse_dhcp_vendor (name, &bp->vendor, size - OFFSET_OF (vendor, bp), &mask);
a85e8e
   grub_net_add_ipv4_local (inter, mask);
a85e8e
   
a85e8e
   inter->dhcp_ack = grub_malloc (size);
a85e8e
diff --git a/include/grub/net.h b/include/grub/net.h
d41074
index 8ecfbb49221..1ec827b9bf3 100644
a85e8e
--- a/include/grub/net.h
a85e8e
+++ b/include/grub/net.h
a85e8e
@@ -498,6 +498,7 @@ enum
a85e8e
     GRUB_NET_BOOTP_DOMAIN = 0x0f,
a85e8e
     GRUB_NET_BOOTP_ROOT_PATH = 0x11,
a85e8e
     GRUB_NET_BOOTP_EXTENSIONS_PATH = 0x12,
a85e8e
+    GRUB_NET_BOOTP_VENDOR_CLASS_IDENTIFIER = 0x3c,
a85e8e
     GRUB_NET_BOOTP_CLIENT_ID = 0x3d,
a85e8e
     GRUB_NET_BOOTP_CLIENT_UUID = 0x61,
a85e8e
     GRUB_NET_BOOTP_END = 0xff