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

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