iPXE
|
PXE TFTP API. More...
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <byteswap.h>
#include <ipxe/uaccess.h>
#include <ipxe/in.h>
#include <ipxe/tftp.h>
#include <ipxe/iobuf.h>
#include <ipxe/xfer.h>
#include <ipxe/open.h>
#include <ipxe/process.h>
#include <ipxe/uri.h>
#include <realmode.h>
#include <pxe.h>
Go to the source code of this file.
Data Structures | |
struct | pxe_tftp_connection |
A PXE TFTP connection. More... | |
Variables | |
static struct interface_operation | pxe_tftp_xfer_ops [] |
PXE TFTP connection interface operations. More... | |
static struct interface_descriptor | pxe_tftp_xfer_desc |
PXE TFTP connection interface descriptor. More... | |
static struct pxe_tftp_connection | pxe_tftp |
The PXE TFTP connection. More... | |
struct pxe_api_call pxe_tftp_api [] | __pxe_api_call |
PXE TFTP API. More... | |
PXE TFTP API.
Definition in file pxe_tftp.c.
FILE_LICENCE | ( | GPL2_OR_LATER_OR_UBDL | ) |
|
static |
Close PXE TFTP connection.
pxe_tftp | PXE TFTP connection |
rc | Final status code |
Definition at line 75 of file pxe_tftp.c.
References intf_shutdown(), pxe_tftp, pxe_tftp_connection::rc, rc, and pxe_tftp_connection::xfer.
Referenced by pxe_tftp_xfer_deliver(), pxenv_tftp_close(), pxenv_tftp_get_fsize(), pxenv_tftp_open(), and pxenv_tftp_read_file().
|
static |
Check flow control window.
pxe_tftp | PXE TFTP connection |
len | Length of window |
Definition at line 86 of file pxe_tftp.c.
References pxe_tftp_connection::blksize, and pxe_tftp.
|
static |
Receive new data.
pxe_tftp | PXE TFTP connection |
iobuf | I/O buffer |
meta | Transfer metadata |
rc | Return status code |
Definition at line 99 of file pxe_tftp.c.
References pxe_tftp_connection::buffer, copy_to_user(), io_buffer::data, DBG, ENOBUFS, free_iob(), iob_len(), len, pxe_tftp_connection::max_offset, meta(), pxe_tftp_connection::offset, pxe_tftp, pxe_tftp_close(), rc, pxe_tftp_connection::size, pxe_tftp_connection::start, and XFER_FL_ABS_OFFSET.
|
static |
Open PXE TFTP connection.
ipaddress | IP address |
port | TFTP server port (in network byte order) |
filename | File name |
blksize | Requested block size |
rc | Return status code |
Definition at line 171 of file pxe_tftp.c.
References AF_INET, blksize, pxe_tftp_connection::blksize, DBG, EINPROGRESS, ENOMEM, intf_init(), memset(), ntohs, NULL, port, pxe_tftp, pxe_tftp_xfer_desc, pxe_uri(), pxe_tftp_connection::rc, rc, sa, sin, sock_ntoa(), strerror(), TFTP_DEFAULT_BLKSIZE, pxe_tftp_connection::xfer, and xfer_open_uri().
Referenced by pxenv_tftp_get_fsize(), pxenv_tftp_open(), and pxenv_tftp_read_file().
|
static |
TFTP OPEN.
tftp_open | Pointer to a struct s_PXENV_TFTP_OPEN |
s_PXENV_TFTP_OPEN::ServerIPAddress | TFTP server IP address |
s_PXENV_TFTP_OPEN::GatewayIPAddress | Relay agent IP address, or 0.0.0.0 |
s_PXENV_TFTP_OPEN::FileName | Name of file to open |
s_PXENV_TFTP_OPEN::TFTPPort | TFTP server UDP port |
s_PXENV_TFTP_OPEN::PacketSize | TFTP blksize option to request |
PXENV_EXIT_SUCCESS | File was opened |
PXENV_EXIT_FAILURE | File was not opened |
s_PXENV_TFTP_OPEN::Status | PXE status code |
s_PXENV_TFTP_OPEN::PacketSize | Negotiated blksize |
PXENV_STATUS_TFTP_INVALID_PACKET_SIZE | Requested blksize too small |
Opens a TFTP connection for downloading a file a block at a time using pxenv_tftp_read().
If s_PXENV_TFTP_OPEN::GatewayIPAddress is 0.0.0.0, normal IP routing will take place. See the relevant implementation note for more details.
On x86, you must set the s_PXE::StatusCallout field to a nonzero value before calling this function in protected mode. You cannot call this function with a 32-bit stack segment. (See the relevant implementation note for more details.)
Definition at line 254 of file pxe_tftp.c.
References pxe_tftp_connection::blksize, DBG, EINPROGRESS, pxe_tftp_connection::max_offset, pxe_tftp, pxe_tftp_close(), pxe_tftp_open(), PXENV_EXIT_FAILURE, PXENV_EXIT_SUCCESS, PXENV_STATUS, pxe_tftp_connection::rc, rc, step(), tftp_open(), pxe_tftp_connection::xfer, and xfer_window().
|
static |
TFTP CLOSE.
tftp_close | Pointer to a struct s_PXENV_TFTP_CLOSE |
PXENV_EXIT_SUCCESS | File was closed successfully |
PXENV_EXIT_FAILURE | File was not closed |
s_PXENV_TFTP_CLOSE::Status | PXE status code |
None | - |
Close a connection previously opened with pxenv_tftp_open(). You must have previously opened a connection with pxenv_tftp_open().
On x86, you must set the s_PXE::StatusCallout field to a nonzero value before calling this function in protected mode. You cannot call this function with a 32-bit stack segment. (See the relevant implementation note for more details.)
Definition at line 305 of file pxe_tftp.c.
References DBG, pxe_tftp, pxe_tftp_close(), PXENV_EXIT_SUCCESS, PXENV_STATUS_SUCCESS, and tftp_close().
|
static |
TFTP READ.
tftp_read | Pointer to a struct s_PXENV_TFTP_READ |
s_PXENV_TFTP_READ::Buffer | Address of data buffer |
PXENV_EXIT_SUCCESS | Data was read successfully |
PXENV_EXIT_FAILURE | Data was not read |
s_PXENV_TFTP_READ::Status | PXE status code |
s_PXENV_TFTP_READ::PacketNumber | TFTP packet number |
s_PXENV_TFTP_READ::BufferSize | Length of data written into buffer |
Reads a single packet from a connection previously opened with pxenv_tftp_open() into the data buffer pointed to by s_PXENV_TFTP_READ::Buffer. You must have previously opened a connection with pxenv_tftp_open(). The data written into s_PXENV_TFTP_READ::Buffer is just the file data; the various network headers have already been removed.
The buffer must be large enough to contain a packet of the size negotiated via the s_PXENV_TFTP_OPEN::PacketSize field in the pxenv_tftp_open() call. It is worth noting that the PXE specification does not require the caller to fill in s_PXENV_TFTP_READ::BufferSize before calling pxenv_tftp_read(), so the PXE stack is free to ignore whatever value the caller might place there and just assume that the buffer is large enough. That said, it may be worth the caller always filling in s_PXENV_TFTP_READ::BufferSize to guard against PXE stacks that mistake it for an input parameter.
The length of the TFTP data packet will be returned via s_PXENV_TFTP_READ::BufferSize. If this length is less than the blksize negotiated via s_PXENV_TFTP_OPEN::PacketSize in the call to pxenv_tftp_open(), this indicates that the block is the last block in the file. Note that zero is a valid length for s_PXENV_TFTP_READ::BufferSize, and will occur when the length of the file is a multiple of the blksize.
The PXE specification doesn't actually state that calls to pxenv_tftp_read() will return the data packets in strict sequential order, though most PXE stacks will probably do so. The sequence number of the packet will be returned in s_PXENV_TFTP_READ::PacketNumber. The first packet in the file has a sequence number of one, not zero.
To guard against flawed PXE stacks, the caller should probably set s_PXENV_TFTP_READ::PacketNumber to one less than the expected returned value (i.e. set it to zero for the first call to pxenv_tftp_read() and then re-use the returned s_PXENV_TFTP_READ parameter block for subsequent calls without modifying s_PXENV_TFTP_READ::PacketNumber between calls). The caller should also guard against potential problems caused by flawed implementations returning the occasional duplicate packet, by checking that the value returned in s_PXENV_TFTP_READ::PacketNumber is as expected (i.e. one greater than that returned from the previous call to pxenv_tftp_read()).
On x86, you must set the s_PXE::StatusCallout field to a nonzero value before calling this function in protected mode. You cannot call this function with a 32-bit stack segment. (See the relevant implementation note for more details.)
Definition at line 374 of file pxe_tftp.c.
References pxe_tftp_connection::blkidx, pxe_tftp_connection::blksize, pxe_tftp_connection::buffer, s_PXENV_TFTP_READ::Buffer, s_PXENV_TFTP_READ::BufferSize, DBG, EINPROGRESS, pxe_tftp_connection::offset, s_PXENV_TFTP_READ::PacketNumber, pxe_tftp, PXENV_EXIT_FAILURE, PXENV_EXIT_SUCCESS, PXENV_STATUS, pxe_tftp_connection::rc, rc, real_to_user(), pxe_tftp_connection::size, pxe_tftp_connection::start, s_PXENV_TFTP_READ::Status, step(), and UNULL.
PXENV_EXIT_t pxenv_tftp_read_file | ( | struct s_PXENV_TFTP_READ_FILE * | tftp_read_file | ) |
TFTP/MTFTP read file.
tftp_read_file | Pointer to a struct s_PXENV_TFTP_READ_FILE |
s_PXENV_TFTP_READ_FILE::FileName | File name |
s_PXENV_TFTP_READ_FILE::BufferSize | Size of the receive buffer |
s_PXENV_TFTP_READ_FILE::Buffer | Address of the receive buffer |
s_PXENV_TFTP_READ_FILE::ServerIPAddress | TFTP server IP address |
s_PXENV_TFTP_READ_FILE::GatewayIPAddress | Relay agent IP address |
s_PXENV_TFTP_READ_FILE::McastIPAddress | File's multicast IP address |
s_PXENV_TFTP_READ_FILE::TFTPClntPort | Client multicast UDP port |
s_PXENV_TFTP_READ_FILE::TFTPSrvPort | Server multicast UDP port |
s_PXENV_TFTP_READ_FILE::TFTPOpenTimeOut | Time to wait for first packet |
s_PXENV_TFTP_READ_FILE::TFTPReopenDelay | MTFTP inactivity timeout |
PXENV_EXIT_SUCCESS | File downloaded successfully |
PXENV_EXIT_FAILURE | File not downloaded |
s_PXENV_TFTP_READ_FILE::Status | PXE status code |
s_PXENV_TFTP_READ_FILE::BufferSize | Length of downloaded file |
Downloads an entire file via either TFTP or MTFTP into the buffer pointed to by s_PXENV_TFTP_READ_FILE::Buffer.
The PXE specification does not make it clear how the caller requests that MTFTP be used rather than TFTP (or vice versa). One reasonable guess is that setting s_PXENV_TFTP_READ_FILE::McastIPAddress to 0.0.0.0 would cause TFTP to be used instead of MTFTP, though it is conceivable that some PXE stacks would interpret that as "use the DHCP-provided multicast IP address" instead. Some PXE stacks will not implement MTFTP at all, and will always use TFTP.
It is not specified whether or not s_PXENV_TFTP_READ_FILE::TFTPSrvPort will be used as the TFTP server port for TFTP (rather than MTFTP) downloads. Callers should assume that the only way to access a TFTP server on a non-standard port is to use pxenv_tftp_open() and pxenv_tftp_read().
If s_PXENV_TFTP_READ_FILE::GatewayIPAddress is 0.0.0.0, normal IP routing will take place. See the relevant implementation note for more details.
It is interesting to note that s_PXENV_TFTP_READ_FILE::Buffer is an ADDR32_t type, i.e. nominally a flat physical address. Some PXE NBPs (e.g. NTLDR) are known to call pxenv_tftp_read_file() in real mode with s_PXENV_TFTP_READ_FILE::Buffer set to an address above 1MB. This means that PXE stacks must be prepared to write to areas outside base memory. Exactly how this is to be achieved is not specified, though using INT 15,87 is as close to a standard method as any, and should probably be used. Switching to protected-mode in order to access high memory will fail if pxenv_tftp_read_file() is called in V86 mode; it is reasonably to expect that a V86 monitor would intercept the relatively well-defined INT 15,87 if it wants the PXE stack to be able to write to high memory.
Things get even more interesting if pxenv_tftp_read_file() is called in protected mode, because there is then absolutely no way for the PXE stack to write to an absolute physical address. You can't even get around the problem by creating a special "access everything" segment in the s_PXE data structure, because the #SEGDESC_t descriptors are limited to 64kB in size.
Previous versions of the PXE specification (e.g. WfM 1.1a) provide a separate API call, pxenv_tftp_read_file_pmode(), specifically to work around this problem. The s_PXENV_TFTP_READ_FILE_PMODE parameter block splits s_PXENV_TFTP_READ_FILE::Buffer into s_PXENV_TFTP_READ_FILE_PMODE::BufferSelector and s_PXENV_TFTP_READ_FILE_PMODE::BufferOffset, i.e. it provides a protected-mode segment:offset address for the data buffer. This API call is no longer present in version 2.1 of the PXE specification.
Etherboot makes the assumption that s_PXENV_TFTP_READ_FILE::Buffer is an offset relative to the caller's data segment, when pxenv_tftp_read_file() is called in protected mode.
On x86, you must set the s_PXE::StatusCallout field to a nonzero value before calling this function in protected mode. You cannot call this function with a 32-bit stack segment. (See the relevant implementation note for more details.)
Definition at line 480 of file pxe_tftp.c.
References pxe_tftp_connection::buffer, s_PXENV_TFTP_READ_FILE::Buffer, s_PXENV_TFTP_READ_FILE::BufferSize, DBG, EINPROGRESS, s_PXENV_TFTP_READ_FILE::FileName, pxe_tftp_connection::max_offset, phys_to_user(), pxe_tftp, pxe_tftp_close(), pxe_tftp_open(), PXENV_EXIT_FAILURE, PXENV_EXIT_SUCCESS, PXENV_STATUS, pxe_tftp_connection::rc, rc, s_PXENV_TFTP_READ_FILE::ServerIPAddress, pxe_tftp_connection::size, s_PXENV_TFTP_READ_FILE::Status, step(), and UNULL.
Referenced by pxenv_restart_tftp().
|
static |
TFTP GET FILE SIZE.
tftp_get_fsize | Pointer to a struct s_PXENV_TFTP_GET_FSIZE |
s_PXENV_TFTP_GET_FSIZE::ServerIPAddress | TFTP server IP address |
s_PXENV_TFTP_GET_FSIZE::GatewayIPAddress | Relay agent IP address |
s_PXENV_TFTP_GET_FSIZE::FileName | File name |
PXENV_EXIT_SUCCESS | File size was determined successfully |
PXENV_EXIT_FAILURE | File size was not determined |
s_PXENV_TFTP_GET_FSIZE::Status | PXE status code |
s_PXENV_TFTP_GET_FSIZE::FileSize | File size |
Determine the size of a file on a TFTP server. This uses the "tsize" TFTP option, and so will not work with a TFTP server that does not support TFTP options, or that does not support the "tsize" option.
The PXE specification states that this API call will not open a TFTP connection for subsequent use with pxenv_tftp_read(). (This is somewhat daft, since the only way to obtain the file size via the "tsize" option involves issuing a TFTP open request, but that's life.)
You cannot call pxenv_tftp_get_fsize() while a TFTP or UDP connection is open.
If s_PXENV_TFTP_GET_FSIZE::GatewayIPAddress is 0.0.0.0, normal IP routing will take place. See the relevant implementation note for more details.
On x86, you must set the s_PXE::StatusCallout field to a nonzero value before calling this function in protected mode. You cannot call this function with a 32-bit stack segment. (See the relevant implementation note for more details.)
Definition at line 551 of file pxe_tftp.c.
References DBG, EINPROGRESS, s_PXENV_TFTP_GET_FSIZE::FileName, s_PXENV_TFTP_GET_FSIZE::FileSize, pxe_tftp_connection::max_offset, pxe_tftp, pxe_tftp_close(), pxe_tftp_open(), PXENV_EXIT_FAILURE, PXENV_EXIT_SUCCESS, PXENV_STATUS, pxe_tftp_connection::rc, rc, s_PXENV_TFTP_GET_FSIZE::ServerIPAddress, s_PXENV_TFTP_GET_FSIZE::Status, and step().
|
static |
PXE TFTP connection interface operations.
Definition at line 145 of file pxe_tftp.c.
|
static |
PXE TFTP connection interface descriptor.
Definition at line 154 of file pxe_tftp.c.
Referenced by pxe_tftp_open().
|
static |
The PXE TFTP connection.
Definition at line 158 of file pxe_tftp.c.
Referenced by pxe_tftp_close(), pxe_tftp_open(), pxe_tftp_xfer_deliver(), pxe_tftp_xfer_window(), pxenv_tftp_close(), pxenv_tftp_get_fsize(), pxenv_tftp_open(), pxenv_tftp_read(), and pxenv_tftp_read_file().
struct pxe_api_call pxe_tftp_api [] __pxe_api_call |
PXE TFTP API.
Definition at line 584 of file pxe_tftp.c.