e153146
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
e153146
From: Michael Chang <mchang@suse.com>
e153146
Date: Wed, 10 Jul 2019 23:58:28 +0200
e153146
Subject: [PATCH] bootp: Add processing DHCPACK packet from HTTP Boot
e153146
e153146
The vendor class identifier with the string "HTTPClient" is used to denote the
e153146
packet as responding to HTTP boot request. In DHCP4 config, the filename for
e153146
HTTP boot is the URL of the boot file while for PXE boot it is the path to the
e153146
boot file. As a consequence, the next-server becomes obseleted because the HTTP
e153146
URL already contains the server address for the boot file. For DHCP6 config,
e153146
there's no difference definition in existing config as dhcp6.bootfile-url can
e153146
be used to specify URL for both HTTP and PXE boot file.
e153146
e153146
This patch adds processing for "HTTPClient" vendor class identifier in DHCPACK
e153146
packet by treating it as HTTP format, not as the PXE format.
e153146
e153146
Signed-off-by: Michael Chang <mchang@suse.com>
e153146
Signed-off-by: Ken Lin <ken.lin@hpe.com>
e153146
---
e153146
 grub-core/net/bootp.c | 55 +++++++++++++++++++++++++++++++++++++++++++++++++++
e153146
 include/grub/net.h    |  1 +
e153146
 2 files changed, 56 insertions(+)
e153146
e153146
diff --git a/grub-core/net/bootp.c b/grub-core/net/bootp.c
bd7cb17
index 68c4df681b5..0b430489329 100644
e153146
--- a/grub-core/net/bootp.c
e153146
+++ b/grub-core/net/bootp.c
e153146
@@ -20,6 +20,7 @@
e153146
 #include <grub/env.h>
e153146
 #include <grub/i18n.h>
e153146
 #include <grub/command.h>
e153146
+#include <grub/net.h>
e153146
 #include <grub/net/ip.h>
e153146
 #include <grub/net/netbuff.h>
e153146
 #include <grub/net/udp.h>
bd7cb17
@@ -500,6 +501,60 @@ grub_net_configure_by_dhcp_ack (const char *name,
e153146
   if (opt && opt_len)
e153146
     grub_env_set_net_property (name, "rootpath", (const char *) opt, opt_len);
e153146
 
e153146
+  opt = find_dhcp_option (bp, size, GRUB_NET_BOOTP_VENDOR_CLASS_IDENTIFIER, &opt_len);
e153146
+  if (opt && opt_len)
e153146
+    {
e153146
+      grub_env_set_net_property (name, "vendor_class_identifier", (const char *) opt, opt_len);
e153146
+      if (opt && grub_strcmp (opt, "HTTPClient") == 0)
e153146
+        {
e153146
+          char *proto, *ip, *pa;
e153146
+
e153146
+          if (!dissect_url (bp->boot_file, &proto, &ip, &pa))
e153146
+            return inter;
e153146
+
e153146
+          grub_env_set_net_property (name, "boot_file", pa, grub_strlen (pa));
e153146
+          if (is_def)
e153146
+            {
e153146
+              grub_net_default_server = grub_strdup (ip);
e153146
+              grub_env_set ("net_default_interface", name);
e153146
+             grub_env_export ("net_default_interface");
e153146
+            }
e153146
+          if (device && !*device)
e153146
+            {
e153146
+              *device = grub_xasprintf ("%s,%s", proto, ip);
e153146
+              grub_print_error ();
e153146
+            }
e153146
+          if (path)
e153146
+            {
e153146
+              *path = grub_strdup (pa);
e153146
+              grub_print_error ();
e153146
+              if (*path)
e153146
+                {
e153146
+                  char *slash;
e153146
+                  slash = grub_strrchr (*path, '/');
e153146
+                  if (slash)
e153146
+                    *slash = 0;
e153146
+                  else
e153146
+                    **path = 0;
e153146
+                }
e153146
+            }
e153146
+          grub_net_add_ipv4_local (inter, mask);
e153146
+          inter->dhcp_ack = grub_malloc (size);
e153146
+          if (inter->dhcp_ack)
e153146
+            {
e153146
+              grub_memcpy (inter->dhcp_ack, bp, size);
e153146
+              inter->dhcp_acklen = size;
e153146
+            }
e153146
+          else
e153146
+            grub_errno = GRUB_ERR_NONE;
e153146
+
e153146
+          grub_free (proto);
e153146
+          grub_free (ip);
e153146
+          grub_free (pa);
e153146
+          return inter;
e153146
+        }
e153146
+    }
e153146
+
e153146
   opt = find_dhcp_option (bp, size, GRUB_NET_BOOTP_EXTENSIONS_PATH, &opt_len);
e153146
   if (opt && opt_len)
e153146
     grub_env_set_net_property (name, "extensionspath", (const char *) opt, opt_len);
e153146
diff --git a/include/grub/net.h b/include/grub/net.h
bd7cb17
index 543251f7273..42af7de250a 100644
e153146
--- a/include/grub/net.h
e153146
+++ b/include/grub/net.h
bd7cb17
@@ -531,6 +531,7 @@ enum
bd7cb17
     GRUB_NET_DHCP_MESSAGE_TYPE = 53,
bd7cb17
     GRUB_NET_DHCP_SERVER_IDENTIFIER = 54,
bd7cb17
     GRUB_NET_DHCP_PARAMETER_REQUEST_LIST = 55,
bd7cb17
+    GRUB_NET_BOOTP_VENDOR_CLASS_IDENTIFIER = 60,
bd7cb17
     GRUB_NET_BOOTP_CLIENT_ID = 61,
bd7cb17
     GRUB_NET_DHCP_TFTP_SERVER_NAME = 66,
bd7cb17
     GRUB_NET_DHCP_BOOTFILE_NAME = 67,