60#define EINVAL_BLKSIZE __einfo_error ( EINFO_EINVAL_BLKSIZE )
61#define EINFO_EINVAL_BLKSIZE __einfo_uniqify \
62 ( EINFO_EINVAL, 0x01, "Invalid blksize" )
63#define EINVAL_TSIZE __einfo_error ( EINFO_EINVAL_TSIZE )
64#define EINFO_EINVAL_TSIZE __einfo_uniqify \
65 ( EINFO_EINVAL, 0x02, "Invalid tsize" )
66#define EINVAL_MC_NO_PORT __einfo_error ( EINFO_EINVAL_MC_NO_PORT )
67#define EINFO_EINVAL_MC_NO_PORT __einfo_uniqify \
68 ( EINFO_EINVAL, 0x03, "Missing multicast port" )
69#define EINVAL_MC_NO_MC __einfo_error ( EINFO_EINVAL_MC_NO_MC )
70#define EINFO_EINVAL_MC_NO_MC __einfo_uniqify \
71 ( EINFO_EINVAL, 0x04, "Missing multicast mc" )
72#define EINVAL_MC_INVALID_MC __einfo_error ( EINFO_EINVAL_MC_INVALID_MC )
73#define EINFO_EINVAL_MC_INVALID_MC __einfo_uniqify \
74 ( EINFO_EINVAL, 0x05, "Missing multicast IP" )
75#define EINVAL_MC_INVALID_IP __einfo_error ( EINFO_EINVAL_MC_INVALID_IP )
76#define EINFO_EINVAL_MC_INVALID_IP __einfo_uniqify \
77 ( EINFO_EINVAL, 0x06, "Invalid multicast IP" )
78#define EINVAL_MC_INVALID_PORT __einfo_error ( EINFO_EINVAL_MC_INVALID_PORT )
79#define EINFO_EINVAL_MC_INVALID_PORT __einfo_uniqify \
80 ( EINFO_EINVAL, 0x07, "Invalid multicast port" )
81#define ENOENT_NOT_FOUND __einfo_error ( EINFO_ENOENT_NOT_FOUND )
82#define EINFO_ENOENT_NOT_FOUND __einfo_uniqify \
83 ( EINFO_ENOENT, 0x01, "Not found" )
165#define MTFTP_MAX_TIMEOUTS 3
169 { .name =
"tftp.client" };
173 { .name =
"tftp.server" };
202 DBGC ( tftp,
"TFTP %p finished with status %d (%s)\n",
234 memset ( &server, 0,
sizeof ( server ) );
239 DBGC ( tftp,
"TFTP %p could not open socket: %s\n",
266 local, local ) ) != 0 ) {
267 DBGC ( tftp,
"TFTP %p could not open multicast "
283 unsigned int num_blocks;
287 if ( filesize <= tftp->filesize )
303 num_blocks = ( ( filesize / tftp->
blksize ) + 1 );
305 DBGC ( tftp,
"TFTP %p could not resize bitmap to %d blocks: "
320 .sin_addr.s_addr =
htonl ( 0xefff0101 ),
321 .sin_port =
htons ( 3001 ),
349 const char *path = ( tftp->
uri->
path + 1 );
355 DBGC ( tftp,
"TFTP %p requesting \"%s\"\n", tftp, path );
358 len = (
sizeof ( *rrq ) +
strlen ( path ) + 1
373 rrq =
iob_put ( iobuf,
sizeof ( *rrq ) );
376 "%s%coctet", path, 0 ) + 1 );
380 "blksize%c%zd%ctsize%c0",
386 "multicast%c", 0 ) + 1 );
411 DBGC2 ( tftp,
"TFTP %p sending ACK for block %d\n", tftp,
block );
419 ack =
iob_put ( iobuf,
sizeof ( *ack ) );
444 DBGC2 ( tftp,
"TFTP %p sending ERROR %d: %s\n", tftp,
errcode,
454 err =
iob_put ( iobuf, msglen );
511 DBGC ( tftp,
"TFTP %p attempting reopen\n", tftp );
517 DBGC ( tftp,
"TFTP %p timeout %d waiting for MTFTP "
521 DBGC ( tftp,
"TFTP %p falling back to plain "
536 sizeof ( tftp->
bitmap ) );
572 DBGC ( tftp,
"TFTP %p got invalid blksize \"%s\"\n",
576 DBGC ( tftp,
"TFTP %p blksize=%d\n", tftp, tftp->
blksize );
593 DBGC ( tftp,
"TFTP %p got invalid tsize \"%s\"\n",
597 DBGC ( tftp,
"TFTP %p tsize=%ld\n", tftp, tftp->
tsize );
625 DBGC ( tftp,
"TFTP %p multicast missing port,mc\n", tftp );
631 DBGC ( tftp,
"TFTP %p multicast missing mc\n", tftp );
637 if (
strtoul ( mc, &mc_end, 0 ) == 0 )
640 DBGC ( tftp,
"TFTP %p multicast invalid mc %s\n", tftp, mc );
643 DBGC ( tftp,
"TFTP %p is%s the master client\n",
646 socket.sin.sin_family =
AF_INET;
648 DBGC ( tftp,
"TFTP %p multicast invalid IP address "
649 "%s\n", tftp,
addr );
652 DBGC ( tftp,
"TFTP %p multicast IP address %s\n",
653 tftp,
inet_ntoa ( socket.sin.sin_addr ) );
656 DBGC ( tftp,
"TFTP %p multicast invalid port %s\n",
660 DBGC ( tftp,
"TFTP %p multicast port %d\n",
661 tftp,
ntohs ( socket.sin.sin_port ) );
707 DBGC ( tftp,
"TFTP %p received unknown option \"%s\" = \"%s\"\n",
731 if (
len <
sizeof ( *oack ) ) {
732 DBGC ( tftp,
"TFTP %p received underlength OACK packet "
733 "length %zd\n", tftp,
len );
750 DBGC ( tftp,
"TFTP %p received OACK with malformed "
751 "option name:\n", tftp );
756 DBGC ( tftp,
"TFTP %p received OACK missing value "
757 "for option \"%s\"\n", tftp,
name );
763 DBGC ( tftp,
"TFTP %p received OACK with malformed "
764 "value for option \"%s\":\n", tftp,
name );
809 DBGC ( tftp,
"TFTP %p received underlength DATA packet "
810 "length %zd\n", tftp,
iob_len ( iobuf ) );
818 DBGC ( tftp,
"TFTP %p received data block 0\n", tftp );
833 DBGC ( tftp,
"TFTP %p received overlength DATA packet "
845 DBGC ( tftp,
"TFTP %p could not deliver data: %s\n",
906 DBGC ( tftp,
"TFTP %p received underlength ERROR packet "
907 "length %zd\n", tftp,
len );
911 DBGC ( tftp,
"TFTP %p received ERROR packet with code %d, message "
944 DBGC ( tftp,
"TFTP %p received underlength packet length "
945 "%zd\n", tftp,
len );
949 DBGC ( tftp,
"TFTP %p received packet without source port\n",
958 DBGC ( tftp,
"TFTP %p using remote port %d\n", tftp,
961 sizeof ( tftp->
peer ) ) != 0 ) {
962 DBGC ( tftp,
"TFTP %p received packet from wrong source (got "
968 switch (
common->opcode ) {
979 DBGC ( tftp,
"TFTP %p received strange packet type %d\n",
1088 unsigned int default_port,
1090 unsigned int flags ) {
1103 tftp =
zalloc (
sizeof ( *tftp ) );
1135 DBGC ( tftp,
"TFTP %p could not create request: %s\n",
1213 static struct in_addr tftp_server = { 0 };
1214 struct in_addr new_tftp_server;
1215 char uri_string[32];
1228 if ( new_tftp_server.
s_addr &&
1230 DBGC ( &tftp_server,
"TFTP server changed %s => ",
1232 DBGC ( &tftp_server,
"%s\n",
inet_ntoa ( new_tftp_server ) );
1233 snprintf ( uri_string,
sizeof ( uri_string ),
1234 "tftp://%s/",
inet_ntoa ( new_tftp_server ) );
1240 tftp_server = new_tftp_server;
#define NULL
NULL pointer (VOID *)
struct arbelprm_rc_send_wqe rc
pseudo_bit_t value[0x00020]
struct arbelprm_completion_with_error error
int bitmap_resize(struct bitmap *bitmap, unsigned int new_length)
Resize bitmap.
void bitmap_set(struct bitmap *bitmap, unsigned int bit)
Set bit in bitmap.
Bitmaps for multicast downloads.
static void bitmap_free(struct bitmap *bitmap)
Free bitmap resources.
static unsigned int bitmap_first_gap(struct bitmap *bitmap)
Get first gap within bitmap.
static int bitmap_full(struct bitmap *bitmap)
Check to see if bitmap is full.
struct bofm_section_header done
uint16_t offset
Offset to command line.
void churi(struct uri *uri)
Change working URI.
uint32_t next
Next descriptor address.
uint32_t addr
Buffer address.
uint8_t data[48]
Additional event data.
uint8_t meta
Metadata flags.
uint64_t address
Base address.
#define __einfo_errortab(einfo)
#define AF_INET
IPv4 Internet addresses.
#define DHCP_EB_FEATURE_TFTP
TFTP protocol.
#define FEATURE_PROTOCOL
Network protocols.
#define FILE_LICENCE(_licence)
Declare a particular licence as applying to a file.
#define EINVAL
Invalid argument.
#define ETIMEDOUT
Connection timed out.
#define ENOMEM
Not enough space.
#define ENOTSUP
Operation not supported.
#define EACCES
Permission denied.
#define ENOTTY
Inappropriate I/O control operation.
#define FILE_SECBOOT(_status)
Declare a file's UEFI Secure Boot permission status.
struct ib_cm_common common
Dynamic Host Configuration Protocol.
#define __profiler
Declare a profiler.
static void profile_stop(struct profiler *profiler)
Stop profiling.
static void profile_start(struct profiler *profiler)
Start profiling.
#define __settings_applicator
Declare a settings applicator.
Transport-network layer interface.
void * memcpy(void *dest, const void *src, size_t len) __nonnull
void * memset(void *dest, int character, size_t len) __nonnull
void intf_close(struct interface *intf, int rc)
Close an object interface.
void intf_plug_plug(struct interface *a, struct interface *b)
Plug two object interfaces together.
void intf_shutdown(struct interface *intf, int rc)
Shut down an object interface.
void intf_restart(struct interface *intf, int rc)
Shut down and restart an object interface.
#define INTF_DESC(object_type, intf, operations)
Define an object interface descriptor.
static void intf_init(struct interface *intf, struct interface_descriptor *desc, struct refcnt *refcnt)
Initialise an object interface.
#define INTF_OP(op_type, object_type, op_func)
Define an object interface operation.
void free_iob(struct io_buffer *iobuf)
Free I/O buffer.
#define iob_put(iobuf, len)
#define iob_disown(iobuf)
Disown an I/O buffer.
static size_t iob_len(struct io_buffer *iobuf)
Calculate length of data in an I/O buffer.
#define iob_pull(iobuf, len)
static size_t iob_tailroom(struct io_buffer *iobuf)
Calculate available space at end of an I/O buffer.
char * inet_ntoa(struct in_addr in)
Convert IPv4 address to dotted-quad notation.
int inet_aton(const char *string, struct in_addr *in)
Parse IPv4 address.
#define FEATURE(category, text, feature_opt, version)
Declare a feature.
void * zalloc(size_t size)
Allocate cleared memory.
uint8_t block[3][8]
DES-encrypted blocks.
uint32_t end
Ending offset.
int xfer_open_socket(struct interface *intf, int semantics, struct sockaddr *peer, struct sockaddr *local)
Open socket.
Data transfer interface opening.
#define __uri_opener
Register a URI opener.
uint32_t blksize
Cipher block size.
static void(* free)(struct refcnt *refcnt))
#define ref_put(refcnt)
Drop reference to object.
#define ref_init(refcnt, free)
Initialise a reference counter.
int xfer_open_named_socket(struct interface *xfer, int semantics, struct sockaddr *peer, const char *name, struct sockaddr *local)
Open named socket.
void start_timer(struct retry_timer *timer)
Start timer.
void stop_timer(struct retry_timer *timer)
Stop timer.
static void start_timer_nodelay(struct retry_timer *timer)
Start timer with no delay.
int fetch_ipv4_setting(struct settings *settings, const struct setting *setting, struct in_addr *inp)
Fetch value of IPv4 address setting.
#define container_of(ptr, type, field)
Get containing structure.
char * strerror(int errno)
Retrieve string representation of error number.
unsigned long strtoul(const char *string, char **endp, int base)
Convert string to numeric value.
char * strchr(const char *src, int character)
Find character within a string.
size_t strnlen(const char *src, size_t max)
Get length of string.
int memcmp(const void *first, const void *second, size_t len)
Compare memory regions.
int strcasecmp(const char *first, const char *second)
Compare case-insensitive strings.
char * strcpy(char *dest, const char *src)
Copy string.
size_t strlen(const char *src)
Get length of string.
An object interface descriptor.
An object interface operation.
void * data
Start of data.
A long option, as used for getopt_long()
const char * name
Long name of this option.
A data structure for storing profiling information.
sa_family_t st_family
Socket address family (part of struct sockaddr)
uint16_t st_port
TCP/IP port.
Generalized socket address structure.
A TFTP acknowledgement (ACK) packet.
The common header of all TFTP packets.
A TFTP data (DATA) packet.
A TFTP error (ERROR) packet.
A TFTP options acknowledgement (OACK) packet.
int(* process)(struct tftp_request *tftp, char *value)
Option processor.
const char * name
Option name.
struct interface socket
Transport layer interface.
struct sockaddr_tcpip peer
Peer address.
struct uri * uri
URI being fetched.
unsigned long tsize
File size.
struct retry_timer timer
Retransmission timer.
struct refcnt refcnt
Reference count.
unsigned int port
Server port.
unsigned int flags
Request flags.
unsigned int blksize
Data block size.
struct interface xfer
Data transfer interface.
unsigned int mtftp_timeouts
MTFTP timeout count.
struct interface mc_socket
Multicast transport layer interface.
size_t filesize
Maximum known length.
struct bitmap bitmap
Block bitmap.
A TFTP read request (RRQ) packet.
A Uniform Resource Identifier.
const char * path
Path (after URI decoding)
const char * host
Host name.
static struct interface_operation tftp_mc_socket_operations[]
TFTP multicast socket operations.
static int tftp_rx(struct tftp_request *tftp, struct io_buffer *iobuf, struct xfer_metadata *meta)
Receive new data.
static void tftp_close(struct tftp_request *tftp, int rc)
Terminate download.
void tftp_set_mtftp_address(struct in_addr address)
Set MTFTP multicast address.
#define EINVAL_MC_NO_PORT
static int tftp_send_error(struct tftp_request *tftp, int errcode, const char *errmsg)
Transmit ERROR (Abort)
@ TFTP_FL_RRQ_MULTICAST
Request multicast option.
@ TFTP_FL_MTFTP_RECOVERY
Perform MTFTP recovery on timeout.
@ TFTP_FL_SEND_ACK
Send ACK packets.
@ TFTP_FL_RRQ_SIZES
Request blksize and tsize options.
static int tftm_open(struct interface *xfer, struct uri *uri)
Initiate TFTM download.
static int tftp_reopen(struct tftp_request *tftp)
Reopen TFTP socket.
#define EINVAL_MC_INVALID_MC
#define EINVAL_MC_INVALID_PORT
static int tftp_presize(struct tftp_request *tftp, size_t filesize)
Presize TFTP receive buffers and block bitmap.
static struct interface_descriptor tftp_xfer_desc
TFTP data transfer interface descriptor.
static int tftp_socket_deliver(struct tftp_request *tftp, struct io_buffer *iobuf, struct xfer_metadata *meta)
Receive new data via socket.
static struct interface_operation tftp_socket_operations[]
TFTP socket operations.
static void tftp_free(struct refcnt *refcnt)
Free TFTP request.
static struct tftp_option tftp_options[]
Recognised TFTP options.
#define EINFO_ENOENT_NOT_FOUND
static struct sockaddr_in tftp_mtftp_socket
MTFTP multicast receive address.
static int tftp_process_blksize(struct tftp_request *tftp, char *value)
Process TFTP "blksize" option.
static void tftp_timer_expired(struct retry_timer *timer, int fail)
Handle TFTP retransmission timer expiry.
static int tftp_send_rrq(struct tftp_request *tftp)
Transmit RRQ.
static int tftp_core_open(struct interface *xfer, struct uri *uri, unsigned int default_port, struct sockaddr *multicast, unsigned int flags)
Initiate TFTP/TFTM/MTFTP download.
static struct interface_descriptor tftp_socket_desc
TFTP socket interface descriptor.
void tftp_set_mtftp_port(unsigned int port)
Set MTFTP multicast port.
static int tftp_process_tsize(struct tftp_request *tftp, char *value)
Process TFTP "tsize" option.
static int tftp_rx_oack(struct tftp_request *tftp, void *buf, size_t len)
Receive OACK.
static int tftp_reopen_mc(struct tftp_request *tftp, struct sockaddr *local)
Reopen TFTP multicast socket.
static int mtftp_open(struct interface *xfer, struct uri *uri)
Initiate MTFTP download.
static int tftp_process_multicast(struct tftp_request *tftp, char *value)
Process TFTP "multicast" option.
static int tftp_send_ack(struct tftp_request *tftp)
Transmit ACK.
static size_t tftp_xfer_window(struct tftp_request *tftp)
Check flow control window.
#define EINVAL_MC_INVALID_IP
static int tftp_rx_data(struct tftp_request *tftp, struct io_buffer *iobuf)
Receive DATA.
static int tftp_process_option(struct tftp_request *tftp, const char *name, char *value)
Process TFTP option.
static struct interface_descriptor tftp_mc_socket_desc
TFTP multicast socket interface descriptor.
#define MTFTP_MAX_TIMEOUTS
Maximum number of MTFTP open requests before falling back to TFTP.
static int tftp_errcode_to_rc(unsigned int errcode)
Convert TFTP error code to return status code.
static int tftp_open(struct interface *xfer, struct uri *uri)
Initiate TFTP download.
static int tftp_rx_error(struct tftp_request *tftp, void *buf, size_t len)
Receive ERROR.
static int tftp_apply_settings(void)
Apply TFTP configuration settings.
static void tftp_done(struct tftp_request *tftp, int rc)
Mark TFTP request as complete.
static struct interface_operation tftp_xfer_operations[]
TFTP data transfer interface operations.
static int tftp_send_packet(struct tftp_request *tftp)
Transmit next relevant packet.
#define TFTP_ACK
Data block acknowledgement opcode.
#define TFTP_DATA
Data block opcode.
#define TFTP_ERR_ACCESS_DENIED
Access violation.
#define TFTP_ERROR
Error opcode.
#define TFTP_ERR_ILLEGAL_OP
Illegal TFTP operation.
#define TFTP_ERR_FILE_NOT_FOUND
File not found.
#define MTFTP_PORT
Default MTFTP server port.
#define TFTP_PORT
Default TFTP server port.
#define TFTP_OACK
Options acknowledgement opcode.
#define TFTP_RRQ
Read request opcode.
#define TFTP_DEFAULT_BLKSIZE
Default TFTP data block size.
uint32_t data_len
Microcode data size (or 0 to indicate 2000 bytes)
unsigned int uri_port(const struct uri *uri, unsigned int default_port)
Get port from URI.
struct uri * parse_uri(const char *uri_string)
Parse URI.
Uniform Resource Identifiers.
static struct uri * uri_get(struct uri *uri)
Increment URI reference count.
static void uri_put(struct uri *uri)
Decrement URI reference count.
int snprintf(char *buf, size_t size, const char *fmt,...)
Write a formatted string to a buffer.
size_t xfer_window(struct interface *intf)
Check flow control window.
int xfer_deliver(struct interface *intf, struct io_buffer *iobuf, struct xfer_metadata *meta)
Deliver datagram.
struct io_buffer * xfer_alloc_iob(struct interface *intf, size_t len)
Allocate I/O buffer.
int xfer_seek(struct interface *intf, off_t offset)
Seek to position.
int xfer_deliver_iob(struct interface *intf, struct io_buffer *iobuf)
Deliver datagram as I/O buffer without metadata.
Data transfer interfaces.
#define XFER_FL_ABS_OFFSET
Offset is absolute.