diff --git a/grub-core/kern/main.c b/grub-core/kern/main.c index 19dc988..a1dcde6 100644 --- a/grub-core/kern/main.c +++ b/grub-core/kern/main.c @@ -142,8 +142,9 @@ grub_set_prefix_and_root (void) if (pptr[0]) path = grub_strdup (pptr); } - if ((!device || device[0] == ',' || !device[0]) || !path) - grub_machine_get_bootlocation (&fwdevice, &fwpath); + + /* Call unconditionally as it also configures the network. */ + grub_machine_get_bootlocation (&fwdevice, &fwpath); if (!device && fwdevice) device = fwdevice; diff --git a/grub-core/net/bootp.c b/grub-core/net/bootp.c index ed15941..38b0836 100644 --- a/grub-core/net/bootp.c +++ b/grub-core/net/bootp.c @@ -161,33 +161,14 @@ parse_dhcp_vendor (const char *name, const void *vend, int limit, int *mask) #define OFFSET_OF(x, y) ((grub_size_t)((grub_uint8_t *)((y)->x) - (grub_uint8_t *)(y))) -struct grub_net_network_level_interface * -grub_net_configure_by_dhcp_ack (const char *name, - struct grub_net_card *card, - grub_net_interface_flags_t flags, - const struct grub_net_bootp_packet *bp, - grub_size_t size, - int is_def, char **device, char **path) +void +grub_net_process_dhcp_ack (struct grub_net_network_level_interface *inter, + const struct grub_net_bootp_packet *bp, + grub_size_t size, + int is_def, char **device, char **path) { - grub_net_network_level_address_t addr; - grub_net_link_level_address_t hwaddr; - struct grub_net_network_level_interface *inter; int mask = -1; - addr.type = GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV4; - addr.ipv4 = bp->your_ip; - - if (device) - *device = 0; - if (path) - *path = 0; - - grub_memcpy (hwaddr.mac, bp->mac_addr, - bp->hw_len < sizeof (hwaddr.mac) ? bp->hw_len - : sizeof (hwaddr.mac)); - hwaddr.type = GRUB_NET_LINK_LEVEL_PROTOCOL_ETHERNET; - - inter = grub_net_add_addr (name, card, &addr, &hwaddr, flags); if (bp->gateway_ip) { grub_net_network_level_netaddress_t target; @@ -199,7 +180,7 @@ grub_net_configure_by_dhcp_ack (const char *name, target.ipv4.masksize = 32; gw.type = GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV4; gw.ipv4 = bp->gateway_ip; - rname = grub_xasprintf ("%s:gw", name); + rname = grub_xasprintf ("%s:gw", inter->name); if (rname) grub_net_add_route_gw (rname, target, gw); grub_free (rname); @@ -207,14 +188,12 @@ grub_net_configure_by_dhcp_ack (const char *name, target.type = GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV4; target.ipv4.base = bp->gateway_ip; target.ipv4.masksize = 32; - grub_net_add_route (name, target, inter); + grub_net_add_route (inter->name, target, inter); } if (size > OFFSET_OF (boot_file, bp)) - set_env_limn_ro (name, "boot_file", (char *) bp->boot_file, + set_env_limn_ro (inter->name, "boot_file", (char *) bp->boot_file, sizeof (bp->boot_file)); - if (is_def) - grub_net_default_server = 0; if (is_def && !grub_net_default_server && bp->server_ip) { grub_net_default_server = grub_xasprintf ("%d.%d.%d.%d", @@ -225,12 +204,6 @@ grub_net_configure_by_dhcp_ack (const char *name, grub_print_error (); } - if (is_def) - { - grub_env_set ("net_default_interface", name); - grub_env_export ("net_default_interface"); - } - if (device && !*device && bp->server_ip) { *device = grub_xasprintf ("tftp,%d.%d.%d.%d", @@ -243,7 +216,7 @@ grub_net_configure_by_dhcp_ack (const char *name, if (size > OFFSET_OF (server_name, bp) && bp->server_name[0]) { - set_env_limn_ro (name, "dhcp_server_name", (char *) bp->server_name, + set_env_limn_ro (inter->name, "dhcp_server_name", (char *) bp->server_name, sizeof (bp->server_name)); if (is_def && !grub_net_default_server) { @@ -257,7 +230,8 @@ grub_net_configure_by_dhcp_ack (const char *name, } } - if (size > OFFSET_OF (boot_file, bp) && path) + if (size > OFFSET_OF (boot_file, bp) && path && !*path + && bp->boot_file[0]) { *path = grub_strndup (bp->boot_file, sizeof (bp->boot_file)); grub_print_error (); @@ -272,9 +246,47 @@ grub_net_configure_by_dhcp_ack (const char *name, } } if (size > OFFSET_OF (vendor, bp)) - parse_dhcp_vendor (name, &bp->vendor, size - OFFSET_OF (vendor, bp), &mask); + parse_dhcp_vendor (inter->name, &bp->vendor, size - OFFSET_OF (vendor, bp), &mask); grub_net_add_ipv4_local (inter, mask); - +} + + +struct grub_net_network_level_interface * +grub_net_configure_by_dhcp_ack (const char *name, + struct grub_net_card *card, + grub_net_interface_flags_t flags, + const struct grub_net_bootp_packet *bp, + grub_size_t size, + int is_def, char **device, char **path) +{ + grub_net_network_level_address_t addr; + grub_net_link_level_address_t hwaddr; + struct grub_net_network_level_interface *inter; + + addr.type = GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV4; + addr.ipv4 = bp->your_ip; + + if (device) + *device = 0; + if (path) + *path = 0; + + grub_memcpy (hwaddr.mac, bp->mac_addr, + bp->hw_len < sizeof (hwaddr.mac) ? bp->hw_len + : sizeof (hwaddr.mac)); + hwaddr.type = GRUB_NET_LINK_LEVEL_PROTOCOL_ETHERNET; + + inter = grub_net_add_addr (name, card, &addr, &hwaddr, flags); + + if (is_def) + { + grub_env_set ("net_default_interface", name); + grub_env_export ("net_default_interface"); + grub_net_default_server = 0; + } + + grub_net_process_dhcp_ack (inter, bp, size, is_def, device, path); + inter->dhcp_ack = grub_malloc (size); if (inter->dhcp_ack) { diff --git a/grub-core/net/drivers/i386/pc/pxe.c b/grub-core/net/drivers/i386/pc/pxe.c index 3e75b2e..0a2ed82 100644 --- a/grub-core/net/drivers/i386/pc/pxe.c +++ b/grub-core/net/drivers/i386/pc/pxe.c @@ -360,15 +360,24 @@ static void grub_pc_net_config_real (char **device, char **path) { struct grub_net_bootp_packet *bp; + struct grub_net_network_level_interface *inter; bp = grub_pxe_get_cached (GRUB_PXENV_PACKET_TYPE_DHCP_ACK); if (!bp) return; - grub_net_configure_by_dhcp_ack ("pxe", &grub_pxe_card, 0, - bp, GRUB_PXE_BOOTP_SIZE, - 1, device, path); + inter = grub_net_configure_by_dhcp_ack ("pxe", &grub_pxe_card, 0, + bp, GRUB_PXE_BOOTP_SIZE, + 1, device, path); + + /* Boot server PXE options add and override boot file/server */ + bp = grub_pxe_get_cached (GRUB_PXENV_PACKET_TYPE_CACHED_REPLY); + + + if (bp) + grub_net_process_dhcp_ack (inter, bp, GRUB_PXE_BOOTP_SIZE, + 1, device, path); } static struct grub_preboot *fini_hnd; diff --git a/include/grub/net.h b/include/grub/net.h index 788516a..507f985 100644 --- a/include/grub/net.h +++ b/include/grub/net.h @@ -444,6 +444,12 @@ grub_net_configure_by_dhcp_ack (const char *name, grub_size_t size, int is_def, char **device, char **path); +void +grub_net_process_dhcp_ack (struct grub_net_network_level_interface *inter, + const struct grub_net_bootp_packet *bp, + grub_size_t size, + int is_def, char **device, char **path); + grub_err_t grub_net_add_ipv4_local (struct grub_net_network_level_interface *inf, int mask);