diff options
author | Michael Brown | 2015-08-26 23:35:42 +0200 |
---|---|---|
committer | Michael Brown | 2015-09-02 14:38:53 +0200 |
commit | 53d2d9e3c37d6170341818a254e18d341ee15511 (patch) | |
tree | 53cd2b5a20c37d270e3046d4823e62d3337ca7c2 /src/core | |
parent | [pxe] Populate ciaddr in fake PXE Boot Server ACK packet (diff) | |
download | ipxe-53d2d9e3c37d6170341818a254e18d341ee15511.tar.gz ipxe-53d2d9e3c37d6170341818a254e18d341ee15511.tar.xz ipxe-53d2d9e3c37d6170341818a254e18d341ee15511.zip |
[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>
Diffstat (limited to 'src/core')
-rw-r--r-- | src/core/uri.c | 53 |
1 files changed, 37 insertions, 16 deletions
diff --git a/src/core/uri.c b/src/core/uri.c index 30f8f6ca..4ae34685 100644 --- a/src/core/uri.c +++ b/src/core/uri.c @@ -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; - - 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; + struct sockaddr_tcpip *st_server = + ( ( struct sockaddr_tcpip * ) sa_server ); + struct uri tmp; + struct uri *uri; + + /* 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; } |