diff --git a/grub-core/net/bootp.c b/grub-core/net/bootp.c index 2908cda3d..79a5482a6 100644 --- a/grub-core/net/bootp.c +++ b/grub-core/net/bootp.c @@ -186,7 +186,9 @@ grub_net_configure_by_dhcp_ack (const char *name, int mask = -1; char server_ip[sizeof ("xxx.xxx.xxx.xxx")]; const grub_uint8_t *opt; - grub_uint8_t opt_len; + grub_uint8_t opt_len, overload = 0; + const char *boot_file = 0, *server_name = 0; + grub_size_t boot_file_len, server_name_len; addr.type = GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV4; addr.ipv4 = bp->your_ip; @@ -205,9 +207,36 @@ grub_net_configure_by_dhcp_ack (const char *name, if (!inter) return 0; - if (size > OFFSET_OF (boot_file, bp)) - grub_env_set_net_property (name, "boot_file", bp->boot_file, - sizeof (bp->boot_file)); + opt = find_dhcp_option (bp, size, GRUB_NET_DHCP_OVERLOAD, &opt_len); + if (opt && opt_len == 1) + overload = *opt; + + opt = find_dhcp_option (bp, size, GRUB_NET_DHCP_TFTP_SERVER_NAME, &opt_len); + if (opt && opt_len) + { + server_name = (const char *) opt; + server_name_len = opt_len; + } + else if (size > OFFSET_OF (server_name, bp) && !(overload & GRUB_DHCP_OPT_OVERLOAD_SNAME) && + bp->server_name[0]) + { + server_name = bp->server_name; + server_name_len = sizeof (bp->server_name); + } + + opt = find_dhcp_option (bp, size, GRUB_NET_DHCP_BOOTFILE_NAME, &opt_len); + if (opt && opt_len) + { + boot_file = (const char *) opt; + boot_file_len = opt_len; + } + else if (size > OFFSET_OF (boot_file, bp) && !(overload && GRUB_DHCP_OPT_OVERLOAD_FILE) && + bp->boot_file[0]) + { + boot_file = bp->boot_file; + boot_file_len = sizeof (bp->boot_file); + } + if (bp->server_ip) { grub_snprintf (server_ip, sizeof (server_ip), "%d.%d.%d.%d", @@ -238,35 +267,38 @@ grub_net_configure_by_dhcp_ack (const char *name, *device = grub_xasprintf ("tftp,%s", server_ip); grub_print_error (); } - if (size > OFFSET_OF (server_name, bp) - && bp->server_name[0]) + + if (server_name) { - grub_env_set_net_property (name, "dhcp_server_name", bp->server_name, - sizeof (bp->server_name)); + grub_env_set_net_property (name, "dhcp_server_name", server_name, server_name_len); if (is_def && !grub_net_default_server) { - grub_net_default_server = grub_strdup (bp->server_name); + grub_net_default_server = grub_strdup (server_name); grub_print_error (); } if (device && !*device) { - *device = grub_xasprintf ("tftp,%s", bp->server_name); + *device = grub_xasprintf ("tftp,%s", server_name); grub_print_error (); } } - if (size > OFFSET_OF (boot_file, bp) && path) + if (boot_file) { - *path = grub_strndup (bp->boot_file, sizeof (bp->boot_file)); - grub_print_error (); - if (*path) + grub_env_set_net_property (name, "boot_file", boot_file, boot_file_len); + if (path) { - char *slash; - slash = grub_strrchr (*path, '/'); - if (slash) - *slash = 0; - else - **path = 0; + *path = grub_strndup (boot_file, boot_file_len); + grub_print_error (); + if (*path) + { + char *slash; + slash = grub_strrchr (*path, '/'); + if (slash) + *slash = 0; + else + **path = 0; + } } } diff --git a/include/grub/net.h b/include/grub/net.h index 49bf39eb2..c77a77312 100644 --- a/include/grub/net.h +++ b/include/grub/net.h @@ -461,6 +461,8 @@ enum GRUB_NET_BOOTP_ROOT_PATH = 0x11, GRUB_NET_BOOTP_EXTENSIONS_PATH = 0x12, GRUB_NET_DHCP_OVERLOAD = 52, + GRUB_NET_DHCP_TFTP_SERVER_NAME = 66, + GRUB_NET_DHCP_BOOTFILE_NAME = 67, GRUB_NET_BOOTP_END = 0xff };