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

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