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

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