diff --git a/src/core/cachedhcp.c b/src/core/cachedhcp.c index 21cb382ad..6518cc2b1 100644 --- a/src/core/cachedhcp.c +++ b/src/core/cachedhcp.c @@ -33,6 +33,7 @@ FILE_SECBOOT ( PERMITTED ); #include #include #include +#include #include /** @file @@ -194,6 +195,50 @@ static int cachedhcp_apply ( struct cached_dhcp_packet *cache, return 0; } +/** + * Get URI from cached DHCP packet + * + * @v cache Cached DHCP packet + * @ret uri URI, or NULL if not defined + */ +static struct uri * cachedhcp_uri ( struct cached_dhcp_packet *cache ) { + struct dhcp_packet *dhcppkt = cache->dhcppkt; + struct settings *settings = &dhcppkt->settings; + struct uri *uri = NULL; + union { + struct sockaddr sa; + struct sockaddr_in sin; + } next_server; + char *filename; + + /* Fetch next-server address */ + memset ( &next_server, 0, sizeof ( next_server ) ); + next_server.sin.sin_family = AF_INET; + fetch_ipv4_setting ( settings, &next_server_setting, + &next_server.sin.sin_addr ); + if ( next_server.sin.sin_addr.s_addr ) { + DBGC ( colour, "CACHEDHCP %s has next-server %s\n", + cache->name, inet_ntoa ( next_server.sin.sin_addr ) ); + } + + /* Fetch filename */ + fetch_string_setting_copy ( settings, &filename_setting, &filename ); + if ( ! filename ) + goto err_filename; + DBGC ( colour, "CACHEDHCP %s has filename %s\n", + cache->name, filename ); + + /* Construct URI */ + uri = pxe_uri ( &next_server.sa, filename ); + if ( ! uri ) + goto err_uri; + + err_uri: + free ( filename ); + err_filename: + return uri; +} + /** * Record cached DHCP packet * @@ -208,6 +253,7 @@ int cachedhcp_record ( struct cached_dhcp_packet *cache, unsigned int vlan, struct dhcp_packet *dhcppkt; struct dhcp_packet *tmp; struct dhcphdr *dhcphdr; + struct uri *uri; unsigned int i; size_t len; @@ -261,6 +307,12 @@ int cachedhcp_record ( struct cached_dhcp_packet *cache, unsigned int vlan, cache->dhcppkt = dhcppkt; cache->vlan = vlan; + /* Set current working URI, if defined in this packet */ + uri = cachedhcp_uri ( cache ); + if ( uri ) + churi ( uri ); + uri_put ( uri ); + return 0; } diff --git a/src/interface/efi/efi_autoexec.c b/src/interface/efi/efi_autoexec.c index b63ac1602..4bb5a7a11 100644 --- a/src/interface/efi/efi_autoexec.c +++ b/src/interface/efi/efi_autoexec.c @@ -131,17 +131,20 @@ static int efi_autoexec_network ( EFI_HANDLE handle, struct image **image ) { goto err_open; } - /* Attempt download */ - rc = imgacquire ( EFI_AUTOEXEC_NAME, EFI_AUTOEXEC_TIMEOUT, image ); - if ( rc != 0 ) { - DBGC ( device, "EFI %s could not download %s: %s\n", + /* Attempt download from current working URI, then from root */ + if ( ( rc = imgacquire ( EFI_AUTOEXEC_NAME, EFI_AUTOEXEC_TIMEOUT, + image ) != 0 ) && + ( rc = imgacquire ( "/" EFI_AUTOEXEC_NAME, EFI_AUTOEXEC_TIMEOUT, + image ) != 0 ) ) { + DBGC ( device, "EFI %s could not download [/]%s: %s\n", efi_handle_name ( device ), EFI_AUTOEXEC_NAME, strerror ( rc ) ); + goto err_acquire; } + err_acquire: /* Ensure network exchanges have completed */ sync ( EFI_AUTOEXEC_SYNC_TIMEOUT ); - err_open: err_cwuri: mnptemp_destroy ( netdev );