summaryrefslogtreecommitdiffstats
path: root/src/usr/autoboot.c
diff options
context:
space:
mode:
authorMichael Brown2013-06-24 17:14:36 +0200
committerMichael Brown2013-06-24 17:14:36 +0200
commit936134ed460618e18cc05d677a442d43d5e739a1 (patch)
tree3d892399341016b9295cdf6a6fd0c480994d15ec /src/usr/autoboot.c
parent[build] Work around bug in gcc >= 4.8 (diff)
downloadipxe-936134ed460618e18cc05d677a442d43d5e739a1.tar.gz
ipxe-936134ed460618e18cc05d677a442d43d5e739a1.tar.xz
ipxe-936134ed460618e18cc05d677a442d43d5e739a1.zip
[autoboot] Use next-server from filename's settings block
Locate the settings block containing the filename, and search only that settings block for the next-server address. This avoids problems caused by misconfigured DHCP servers which provide a next-server address (often defaulting to the DHCP server's own IP address) even when not providing a filename. Originally-implemented-by: Alex Williamson <alex.williamson@redhat.com> Signed-off-by: Michael Brown <mcb30@ipxe.org>
Diffstat (limited to 'src/usr/autoboot.c')
-rw-r--r--src/usr/autoboot.c39
1 files changed, 25 insertions, 14 deletions
diff --git a/src/usr/autoboot.c b/src/usr/autoboot.c
index b2d288ea..70f883a5 100644
--- a/src/usr/autoboot.c
+++ b/src/usr/autoboot.c
@@ -251,31 +251,42 @@ static void close_all_netdevs ( void ) {
* @ret uri URI, or NULL on failure
*/
struct uri * fetch_next_server_and_filename ( struct settings *settings ) {
- struct in_addr next_server;
- char buf[256];
+ struct in_addr next_server = { 0 };
+ char *raw_filename = NULL;
+ struct uri *uri = NULL;
char *filename;
- struct uri *uri;
- /* Fetch next-server setting */
- fetch_ipv4_setting ( settings, &next_server_setting, &next_server );
- if ( next_server.s_addr )
- printf ( "Next server: %s\n", inet_ntoa ( next_server ) );
+ /* Determine settings block containing the filename, if any */
+ settings = fetch_setting_origin ( settings, &filename_setting );
- /* Fetch filename setting */
- fetch_string_setting ( settings, &filename_setting,
- buf, sizeof ( buf ) );
- if ( buf[0] )
- printf ( "Filename: %s\n", buf );
+ /* If we have a filename, fetch it along with next-server */
+ if ( settings ) {
+ fetch_ipv4_setting ( settings, &next_server_setting,
+ &next_server );
+ if ( fetch_string_setting_copy ( settings, &filename_setting,
+ &raw_filename ) < 0 )
+ goto err_fetch;
+ }
/* Expand filename setting */
- filename = expand_settings ( buf );
+ filename = expand_settings ( raw_filename ? raw_filename : "" );
if ( ! filename )
- return NULL;
+ goto err_expand;
/* Parse next server and filename */
+ if ( next_server.s_addr )
+ printf ( "Next server: %s\n", inet_ntoa ( next_server ) );
+ if ( filename[0] )
+ printf ( "Filename: %s\n", filename );
uri = parse_next_server_and_filename ( next_server, filename );
+ if ( ! uri )
+ goto err_parse;
+ err_parse:
free ( filename );
+ err_expand:
+ free ( raw_filename );
+ err_fetch:
return uri;
}