From 53d2d9e3c37d6170341818a254e18d341ee15511 Mon Sep 17 00:00:00 2001 From: Michael Brown Date: Wed, 26 Aug 2015 22:35:42 +0100 Subject: [uri] Generalise tftp_uri() to pxe_uri() Merge the functionality of parse_next_server_and_filename() and tftp_uri() into a single pxe_uri(), which takes a server address (IPv4/IPv6/none) and a filename, and produces a URI using the rule: - if the filename is a hierarchical absolute URI (i.e. includes a scheme such as "http://" or "tftp://") then use that URI and ignore the server address, - otherwise, if the server address is recognised (according to sa_family) then construct a TFTP URI based on the server address, port, and filename - otherwise fail. Signed-off-by: Michael Brown --- src/usr/autoboot.c | 89 ++++++++++++++++++++---------------------------------- 1 file changed, 32 insertions(+), 57 deletions(-) (limited to 'src/usr') diff --git a/src/usr/autoboot.c b/src/usr/autoboot.c index 9125438..8c6b690 100644 --- a/src/usr/autoboot.c +++ b/src/usr/autoboot.c @@ -87,33 +87,6 @@ __weak int pxe_menu_boot ( struct net_device *netdev __unused ) { return -ENOTSUP; } -/** - * Parse next-server and filename into a URI - * - * @v next_server Next-server address - * @v filename Filename - * @ret uri URI, or NULL on failure - */ -static struct uri * parse_next_server_and_filename ( struct in_addr next_server, - const char *filename ) { - struct uri *uri; - - /* Parse filename */ - uri = parse_uri ( filename ); - if ( ! uri ) - return NULL; - - /* Construct a TFTP URI for the filename, if applicable */ - if ( next_server.s_addr && filename[0] && ! uri_is_absolute ( uri ) ) { - uri_put ( uri ); - uri = tftp_uri ( next_server, 0, filename ); - if ( ! uri ) - return NULL; - } - - return uri; -} - /** The "keep-san" setting */ const struct setting keep_san_setting __setting ( SETTING_SANBOOT_EXTRA, keep-san ) = { @@ -250,11 +223,17 @@ 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 = { 0 }; + union { + struct sockaddr sa; + struct sockaddr_in sin; + } next_server; char *raw_filename = NULL; struct uri *uri = NULL; char *filename; + /* Initialise server address */ + memset ( &next_server, 0, sizeof ( next_server ) ); + /* If we have a filename, fetch it along with the next-server * setting from the same settings block. */ @@ -263,20 +242,27 @@ struct uri * fetch_next_server_and_filename ( struct settings *settings ) { fetch_string_setting_copy ( settings, &filename_setting, &raw_filename ); fetch_ipv4_setting ( settings, &next_server_setting, - &next_server ); + &next_server.sin.sin_addr ); + } + if ( ! raw_filename ) + goto err_fetch; + + /* Populate server address */ + if ( next_server.sin.sin_addr.s_addr ) { + next_server.sin.sin_family = AF_INET; + printf ( "Next server: %s\n", + inet_ntoa ( next_server.sin.sin_addr ) ); } /* Expand filename setting */ - filename = expand_settings ( raw_filename ? raw_filename : "" ); + filename = expand_settings ( raw_filename ); if ( ! filename ) 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 ); + + /* Construct URI */ + uri = pxe_uri ( &next_server.sa, filename ); if ( ! uri ) goto err_parse; @@ -284,6 +270,7 @@ struct uri * fetch_next_server_and_filename ( struct settings *settings ) { free ( filename ); err_expand: free ( raw_filename ); + err_fetch: return uri; } @@ -301,9 +288,11 @@ static struct uri * fetch_root_path ( struct settings *settings ) { /* Fetch root-path setting */ fetch_string_setting_copy ( settings, &root_path_setting, &raw_root_path ); + if ( ! raw_root_path ) + goto err_fetch; /* Expand filename setting */ - root_path = expand_settings ( raw_root_path ? raw_root_path : "" ); + root_path = expand_settings ( raw_root_path ); if ( ! root_path ) goto err_expand; @@ -318,6 +307,7 @@ static struct uri * fetch_root_path ( struct settings *settings ) { free ( root_path ); err_expand: free ( raw_root_path ); + err_fetch: return uri; } @@ -378,32 +368,19 @@ int netboot ( struct net_device *netdev ) { goto err_pxe_menu_boot; } - /* Fetch next server and filename */ + /* Fetch next server and filename (if any) */ filename = fetch_next_server_and_filename ( NULL ); - if ( ! filename ) - goto err_filename; - if ( ! uri_has_path ( filename ) ) { - /* Ignore empty filename */ - uri_put ( filename ); - filename = NULL; - } - /* Fetch root path */ + /* Fetch root path (if any) */ root_path = fetch_root_path ( NULL ); - if ( ! root_path ) - goto err_root_path; - if ( ! uri_is_absolute ( root_path ) ) { - /* Ignore empty root path */ - uri_put ( root_path ); - root_path = NULL; - } /* If we have both a filename and a root path, ignore an - * unsupported URI scheme in the root path, since it may - * represent an NFS root. + * unsupported or missing URI scheme in the root path, since + * it may represent an NFS root. */ if ( filename && root_path && - ( xfer_uri_opener ( root_path->scheme ) == NULL ) ) { + ( ! ( uri_is_absolute ( root_path ) || + ( xfer_uri_opener ( root_path->scheme ) == NULL ) ) ) ) { printf ( "Ignoring unsupported root path\n" ); uri_put ( root_path ); root_path = NULL; @@ -424,9 +401,7 @@ int netboot ( struct net_device *netdev ) { err_uriboot: err_no_boot: uri_put ( root_path ); - err_root_path: uri_put ( filename ); - err_filename: err_pxe_menu_boot: err_dhcp: err_ifopen: -- cgit v1.1