The vendor class identifier with the string "HTTPClient" is used to indicate that the packet is responding to an HTTP boot request. In the DHCPv4 configuration, the boot_file for HTTP boot specifies the URL of the boot file, while for PXE boot, it specifies the path to the boot file. Consequently, the next-server field becomes obsolete, as the HTTP URL already encodes the server address for the boot file.
In DHCPv6 configuration, no ambiguity in the boot_file, as dhcp6.bootfile-url is used to specify the URL for both HTTP and PXE boot files. This update adds processing for the "HTTPClient" vendor class identifier in DHCPACK packets, interpreting it as an HTTP format rather than a PXE format. Signed-off-by: Ken Lin <ken....@hpe.com> Signed-off-by: Robbie Harwood <rharw...@redhat.com> Signed-off-by: Michael Chang <mch...@suse.com> --- grub-core/net/bootp.c | 28 +++++++++++++++++++++++++++- include/grub/net.h | 1 + 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/grub-core/net/bootp.c b/grub-core/net/bootp.c index cca7143e0..8bf0ca782 100644 --- a/grub-core/net/bootp.c +++ b/grub-core/net/bootp.c @@ -20,6 +20,7 @@ #include <grub/env.h> #include <grub/i18n.h> #include <grub/command.h> +#include <grub/net.h> #include <grub/net/ip.h> #include <grub/net/netbuff.h> #include <grub/net/udp.h> @@ -333,6 +334,9 @@ grub_net_configure_by_dhcp_ack (const char *name, grub_uint8_t opt_len, overload = 0; const char *boot_file = 0, *server_name = 0; grub_size_t boot_file_len, server_name_len; + char *vci_server_name = NULL; + char *vci_boot_file = NULL; + char *vci_protocol = NULL; addr.type = GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV4; addr.ipv4 = bp->your_ip; @@ -382,6 +386,20 @@ grub_net_configure_by_dhcp_ack (const char *name, boot_file_len = sizeof (bp->boot_file); } + opt = find_dhcp_option (bp, size, GRUB_NET_BOOTP_VENDOR_CLASS_IDENTIFIER, &opt_len); + if (opt && opt_len) + { + grub_env_set_net_property (name, "vendor_class_identifier", (const char *) opt, opt_len); + if (grub_strncmp ((const char *) opt, "HTTPClient", opt_len) == 0 + && dissect_url (bp->boot_file, &vci_protocol, &vci_server_name, &vci_boot_file)) + { + server_name = vci_server_name; + server_name_len = grub_strlen (vci_server_name); + boot_file = vci_boot_file; + boot_file_len = grub_strlen (vci_boot_file); + } + } + if (bp->server_ip) { grub_snprintf (server_ip, sizeof (server_ip), "%d.%d.%d.%d", @@ -423,7 +441,7 @@ grub_net_configure_by_dhcp_ack (const char *name, } if (device && !*device) { - *device = grub_xasprintf ("tftp,%s", server_name); + *device = grub_xasprintf ("%s,%s", vci_protocol ? : "tftp", server_name); grub_print_error (); } } @@ -526,7 +544,12 @@ grub_net_configure_by_dhcp_ack (const char *name, val = grub_malloc (2 * opt_len + 4 + 1); if (!val) + { + grub_free (vci_protocol); + grub_free (vci_boot_file); + grub_free (vci_server_name); return inter; + } for (i = 0; i < opt_len; i++) { @@ -552,6 +575,9 @@ grub_net_configure_by_dhcp_ack (const char *name, else grub_errno = GRUB_ERR_NONE; + grub_free (vci_protocol); + grub_free (vci_boot_file); + grub_free (vci_server_name); return inter; } diff --git a/include/grub/net.h b/include/grub/net.h index 3e2704e3a..e7d75b93a 100644 --- a/include/grub/net.h +++ b/include/grub/net.h @@ -530,6 +530,7 @@ enum GRUB_NET_DHCP_MESSAGE_TYPE = 53, GRUB_NET_DHCP_SERVER_IDENTIFIER = 54, GRUB_NET_DHCP_PARAMETER_REQUEST_LIST = 55, + GRUB_NET_BOOTP_VENDOR_CLASS_IDENTIFIER = 60, GRUB_NET_BOOTP_CLIENT_ID = 61, GRUB_NET_DHCP_TFTP_SERVER_NAME = 66, GRUB_NET_DHCP_BOOTFILE_NAME = 67, -- 2.47.1 _______________________________________________ Grub-devel mailing list Grub-devel@gnu.org https://lists.gnu.org/mailman/listinfo/grub-devel