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

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