Skip to content

Commit 481a217

Browse files
author
Michael Brown
committed
[autoboot] Retain initial-slash (if present) when constructing TFTP URIs
When we boot from a DHCP-supplied filename, we previously relied on the fact that the current working URI is set to tftp://[next-server]/ in order to resolve the filename into a full tftp:// URI. However, this process will eliminate the distinction between filenames with and without initial slashes: cwuri="tftp://10.0.0.1/" filename="vmlinuz" => URI="tftp://10.0.0.1/vmlinuz" cwuri="tftp://10.0.0.1/" filename="/vmlinuz" => URI="tftp://10.0.0.1/vmlinuz" This distinction is important for some TFTP servers. We now explicitly construct a string of the form "tftp://[next-server]/filename" so that a filename with an initial slash will result in a URI containing a double-slash, e.g. "tftp://10.0.0.1//vmlinuz" The TFTP code always strips a single initial slash, and so ends up presenting the correct path to the server. URIs entered explicitly by users at the command line must include a double slash if they want an initial slash presented to the TFTP server: "kernel tftp://10.0.0.1/vmlinuz" => filename="vmlinuz" "kernel tftp://10.0.0.1//vmlinuz" => filename="/vmlinuz"
1 parent 193426d commit 481a217

File tree

2 files changed

+31
-3
lines changed

2 files changed

+31
-3
lines changed

src/include/gpxe/settings.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -215,6 +215,7 @@ extern struct setting password_setting __setting;
215215
extern struct setting priority_setting __setting;
216216
extern struct setting bios_drive_setting __setting;
217217
extern struct setting uuid_setting __setting;
218+
extern struct setting next_server_setting __setting;
218219

219220
/**
220221
* Initialise a settings block

src/usr/autoboot.c

Lines changed: 30 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
#include <gpxe/settings.h>
2525
#include <gpxe/image.h>
2626
#include <gpxe/embedded.h>
27+
#include <gpxe/uri.h>
2728
#include <usr/ifmgmt.h>
2829
#include <usr/route.h>
2930
#include <usr/dhcpmgmt.h>
@@ -78,15 +79,39 @@ static int boot_embedded_image ( void ) {
7879
}
7980

8081
/**
81-
* Boot using filename
82+
* Boot using next-server and filename
8283
*
8384
* @v filename Boot filename
8485
* @ret rc Return status code
8586
*/
86-
static int boot_filename ( const char *filename ) {
87+
static int boot_next_server_and_filename ( struct in_addr next_server,
88+
const char *filename ) {
89+
struct uri *uri;
8790
struct image *image;
91+
char buf[ 23 /* tftp://xxx.xxx.xxx.xxx/ */ + strlen(filename) + 1 ];
92+
int filename_is_absolute;
8893
int rc;
8994

95+
/* Construct URI */
96+
uri = parse_uri ( filename );
97+
if ( ! uri ) {
98+
printf ( "Out of memory\n" );
99+
return -ENOMEM;
100+
}
101+
filename_is_absolute = uri_is_absolute ( uri );
102+
uri_put ( uri );
103+
if ( ! filename_is_absolute ) {
104+
/* Construct a tftp:// URI for the filename. We can't
105+
* just rely on the current working URI, because the
106+
* relative URI resolution will remove the distinction
107+
* between filenames with and without initial slashes,
108+
* which is significant for TFTP.
109+
*/
110+
snprintf ( buf, sizeof ( buf ), "tftp://%s/%s",
111+
inet_ntoa ( next_server ), filename );
112+
filename = buf;
113+
}
114+
90115
image = alloc_image();
91116
if ( ! image ) {
92117
printf ( "Out of memory\n" );
@@ -135,6 +160,7 @@ int boot_root_path ( const char *root_path ) {
135160
*/
136161
static int netboot ( struct net_device *netdev ) {
137162
char buf[256];
163+
struct in_addr next_server;
138164
int rc;
139165

140166
/* Open device and display device status */
@@ -161,10 +187,11 @@ static int netboot ( struct net_device *netdev ) {
161187
return rc;
162188

163189
/* Try to download and boot whatever we are given as a filename */
190+
fetch_ipv4_setting ( NULL, &next_server_setting, &next_server );
164191
fetch_string_setting ( NULL, &filename_setting, buf, sizeof ( buf ) );
165192
if ( buf[0] ) {
166193
printf ( "Booting from filename \"%s\"\n", buf );
167-
return boot_filename ( buf );
194+
return boot_next_server_and_filename ( next_server, buf );
168195
}
169196

170197
/* No filename; try the root path */

0 commit comments

Comments
 (0)