mirror of
https://github.com/ipxe/ipxe
synced 2025-12-26 17:42:47 +03:00
[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 <mcb30@ipxe.org>
This commit is contained in:
@@ -36,6 +36,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||
#include <ctype.h>
|
||||
#include <ipxe/vsprintf.h>
|
||||
#include <ipxe/params.h>
|
||||
#include <ipxe/tcpip.h>
|
||||
#include <ipxe/uri.h>
|
||||
|
||||
/**
|
||||
@@ -711,30 +712,50 @@ struct uri * resolve_uri ( const struct uri *base_uri,
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct TFTP URI from next-server and filename
|
||||
* Construct URI from server address and filename
|
||||
*
|
||||
* @v next_server Next-server address
|
||||
* @v port Port number, or zero to use the default port
|
||||
* @v sa_server Server address
|
||||
* @v filename Filename
|
||||
* @ret uri URI, or NULL on failure
|
||||
*
|
||||
* TFTP filenames specified via the DHCP next-server field often
|
||||
* PXE TFTP filenames specified via the DHCP next-server field often
|
||||
* contain characters such as ':' or '#' which would confuse the
|
||||
* generic URI parser. We provide a mechanism for directly
|
||||
* constructing a TFTP URI from the next-server and filename.
|
||||
*/
|
||||
struct uri * tftp_uri ( struct in_addr next_server, unsigned int port,
|
||||
const char *filename ) {
|
||||
struct uri * pxe_uri ( struct sockaddr *sa_server, const char *filename ) {
|
||||
char buf[ 6 /* "65535" + NUL */ ];
|
||||
struct uri uri;
|
||||
struct sockaddr_tcpip *st_server =
|
||||
( ( struct sockaddr_tcpip * ) sa_server );
|
||||
struct uri tmp;
|
||||
struct uri *uri;
|
||||
|
||||
memset ( &uri, 0, sizeof ( uri ) );
|
||||
uri.scheme = "tftp";
|
||||
uri.host = inet_ntoa ( next_server );
|
||||
if ( port ) {
|
||||
snprintf ( buf, sizeof ( buf ), "%d", port );
|
||||
uri.port = buf;
|
||||
/* Fail if filename is empty */
|
||||
if ( ! ( filename && filename[0] ) )
|
||||
return NULL;
|
||||
|
||||
/* If filename is a hierarchical absolute URI, then use that
|
||||
* URI. (We accept only hierarchical absolute URIs, since PXE
|
||||
* filenames sometimes start with DOS drive letters such as
|
||||
* "C:\", which get misinterpreted as opaque absolute URIs.)
|
||||
*/
|
||||
uri = parse_uri ( filename );
|
||||
if ( uri && uri_is_absolute ( uri ) && ( ! uri->opaque ) )
|
||||
return uri;
|
||||
uri_put ( uri );
|
||||
|
||||
/* Otherwise, construct a TFTP URI directly */
|
||||
memset ( &tmp, 0, sizeof ( tmp ) );
|
||||
tmp.scheme = "tftp";
|
||||
tmp.host = sock_ntoa ( sa_server );
|
||||
if ( ! tmp.host )
|
||||
return NULL;
|
||||
if ( st_server->st_port ) {
|
||||
snprintf ( buf, sizeof ( buf ), "%d",
|
||||
ntohs ( st_server->st_port ) );
|
||||
tmp.port = buf;
|
||||
}
|
||||
uri.path = filename;
|
||||
return uri_dup ( &uri );
|
||||
tmp.path = filename;
|
||||
uri = uri_dup ( &tmp );
|
||||
return uri;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user