58 #define EINVAL_BLKSIZE __einfo_error ( EINFO_EINVAL_BLKSIZE ) 59 #define EINFO_EINVAL_BLKSIZE __einfo_uniqify \ 60 ( EINFO_EINVAL, 0x01, "Invalid blksize" ) 61 #define EINVAL_TSIZE __einfo_error ( EINFO_EINVAL_TSIZE ) 62 #define EINFO_EINVAL_TSIZE __einfo_uniqify \ 63 ( EINFO_EINVAL, 0x02, "Invalid tsize" ) 64 #define EINVAL_MC_NO_PORT __einfo_error ( EINFO_EINVAL_MC_NO_PORT ) 65 #define EINFO_EINVAL_MC_NO_PORT __einfo_uniqify \ 66 ( EINFO_EINVAL, 0x03, "Missing multicast port" ) 67 #define EINVAL_MC_NO_MC __einfo_error ( EINFO_EINVAL_MC_NO_MC ) 68 #define EINFO_EINVAL_MC_NO_MC __einfo_uniqify \ 69 ( EINFO_EINVAL, 0x04, "Missing multicast mc" ) 70 #define EINVAL_MC_INVALID_MC __einfo_error ( EINFO_EINVAL_MC_INVALID_MC ) 71 #define EINFO_EINVAL_MC_INVALID_MC __einfo_uniqify \ 72 ( EINFO_EINVAL, 0x05, "Missing multicast IP" ) 73 #define EINVAL_MC_INVALID_IP __einfo_error ( EINFO_EINVAL_MC_INVALID_IP ) 74 #define EINFO_EINVAL_MC_INVALID_IP __einfo_uniqify \ 75 ( EINFO_EINVAL, 0x06, "Invalid multicast IP" ) 76 #define EINVAL_MC_INVALID_PORT __einfo_error ( EINFO_EINVAL_MC_INVALID_PORT ) 77 #define EINFO_EINVAL_MC_INVALID_PORT __einfo_uniqify \ 78 ( EINFO_EINVAL, 0x07, "Invalid multicast port" ) 160 #define MTFTP_MAX_TIMEOUTS 3 164 { .
name =
"tftp.client" };
168 { .
name =
"tftp.server" };
192 DBGC ( tftp,
"TFTP %p finished with status %d (%s)\n",
224 memset ( &server, 0,
sizeof ( server ) );
229 DBGC ( tftp,
"TFTP %p could not open socket: %s\n",
256 local, local ) ) != 0 ) {
257 DBGC ( tftp,
"TFTP %p could not open multicast " 273 unsigned int num_blocks;
277 if ( filesize <= tftp->filesize )
293 num_blocks = ( ( filesize / tftp->
blksize ) + 1 );
295 DBGC ( tftp,
"TFTP %p could not resize bitmap to %d blocks: " 310 .sin_addr.s_addr =
htonl ( 0xefff0101 ),
311 .sin_port =
htons ( 3001 ),
339 const char *path = ( tftp->
uri->
path + 1 );
345 DBGC ( tftp,
"TFTP %p requesting \"%s\"\n", tftp, path );
348 len = (
sizeof ( *rrq ) +
strlen ( path ) + 1
363 rrq =
iob_put ( iobuf,
sizeof ( *rrq ) );
366 "%s%coctet", path, 0 ) + 1 );
370 "blksize%c%zd%ctsize%c0",
376 "multicast%c", 0 ) + 1 );
401 DBGC2 ( tftp,
"TFTP %p sending ACK for block %d\n", tftp,
block );
409 ack =
iob_put ( iobuf,
sizeof ( *ack ) );
434 DBGC2 ( tftp,
"TFTP %p sending ERROR %d: %s\n", tftp,
errcode,
444 err =
iob_put ( iobuf, msglen );
501 DBGC ( tftp,
"TFTP %p attempting reopen\n", tftp );
507 DBGC ( tftp,
"TFTP %p timeout %d waiting for MTFTP " 511 DBGC ( tftp,
"TFTP %p falling back to plain " 526 sizeof ( tftp->
bitmap ) );
562 DBGC ( tftp,
"TFTP %p got invalid blksize \"%s\"\n",
566 DBGC ( tftp,
"TFTP %p blksize=%d\n", tftp, tftp->
blksize );
583 DBGC ( tftp,
"TFTP %p got invalid tsize \"%s\"\n",
587 DBGC ( tftp,
"TFTP %p tsize=%ld\n", tftp, tftp->
tsize );
615 DBGC ( tftp,
"TFTP %p multicast missing port,mc\n", tftp );
621 DBGC ( tftp,
"TFTP %p multicast missing mc\n", tftp );
627 if (
strtoul ( mc, &mc_end, 0 ) == 0 )
630 DBGC ( tftp,
"TFTP %p multicast invalid mc %s\n", tftp, mc );
633 DBGC ( tftp,
"TFTP %p is%s the master client\n",
636 socket.sin.sin_family =
AF_INET;
638 DBGC ( tftp,
"TFTP %p multicast invalid IP address " 639 "%s\n", tftp,
addr );
642 DBGC ( tftp,
"TFTP %p multicast IP address %s\n",
643 tftp,
inet_ntoa ( socket.sin.sin_addr ) );
646 DBGC ( tftp,
"TFTP %p multicast invalid port %s\n",
650 DBGC ( tftp,
"TFTP %p multicast port %d\n",
651 tftp,
ntohs ( socket.sin.sin_port ) );
697 DBGC ( tftp,
"TFTP %p received unknown option \"%s\" = \"%s\"\n",
721 if (
len <
sizeof ( *oack ) ) {
722 DBGC ( tftp,
"TFTP %p received underlength OACK packet " 723 "length %zd\n", tftp,
len );
740 DBGC ( tftp,
"TFTP %p received OACK with malformed " 741 "option name:\n", tftp );
746 DBGC ( tftp,
"TFTP %p received OACK missing value " 747 "for option \"%s\"\n", tftp,
name );
753 DBGC ( tftp,
"TFTP %p received OACK with malformed " 754 "value for option \"%s\":\n", tftp,
name );
799 DBGC ( tftp,
"TFTP %p received underlength DATA packet " 800 "length %zd\n", tftp,
iob_len ( iobuf ) );
808 DBGC ( tftp,
"TFTP %p received data block 0\n", tftp );
823 DBGC ( tftp,
"TFTP %p received overlength DATA packet " 835 DBGC ( tftp,
"TFTP %p could not deliver data: %s\n",
896 DBGC ( tftp,
"TFTP %p received underlength ERROR packet " 897 "length %zd\n", tftp,
len );
901 DBGC ( tftp,
"TFTP %p received ERROR packet with code %d, message " 934 DBGC ( tftp,
"TFTP %p received underlength packet length " 935 "%zd\n", tftp,
len );
939 DBGC ( tftp,
"TFTP %p received packet without source port\n",
948 DBGC ( tftp,
"TFTP %p using remote port %d\n", tftp,
951 sizeof ( tftp->
peer ) ) != 0 ) {
952 DBGC ( tftp,
"TFTP %p received packet from wrong source (got " 958 switch (
common->opcode ) {
969 DBGC ( tftp,
"TFTP %p received strange packet type %d\n",
1078 unsigned int default_port,
1080 unsigned int flags ) {
1093 tftp =
zalloc (
sizeof ( *tftp ) );
1125 DBGC ( tftp,
"TFTP %p could not create request: %s\n",
1203 static struct in_addr tftp_server = { 0 };
1204 struct in_addr new_tftp_server;
1205 char uri_string[32];
1218 if ( new_tftp_server.
s_addr &&
1220 DBGC ( &tftp_server,
"TFTP server changed %s => ",
1222 DBGC ( &tftp_server,
"%s\n",
inet_ntoa ( new_tftp_server ) );
1223 snprintf ( uri_string,
sizeof ( uri_string ),
1224 "tftp://%s/",
inet_ntoa ( new_tftp_server ) );
1230 tftp_server = new_tftp_server;
#define iob_pull(iobuf, len)
unsigned int mtftp_timeouts
MTFTP timeout count.
#define EINVAL
Invalid argument.
struct interface socket
Transport layer interface.
An object interface operation.
struct arbelprm_rc_send_wqe rc
void intf_close(struct interface *intf, int rc)
Close an object interface.
void intf_restart(struct interface *intf, int rc)
Shut down and restart an object interface.
#define MTFTP_PORT
Default MTFTP server port.
Dynamic Host Configuration Protocol.
#define iob_put(iobuf, len)
void intf_shutdown(struct interface *intf, int rc)
Shut down an object interface.
static void uri_put(struct uri *uri)
Decrement URI reference count.
int xfer_deliver_iob(struct interface *intf, struct io_buffer *iobuf)
Deliver datagram as I/O buffer without metadata.
static void start_timer_nodelay(struct retry_timer *timer)
Start timer with no delay.
A TFTP options acknowledgement (OACK) packet.
unsigned long strtoul(const char *string, char **endp, int base)
Convert string to numeric value.
static struct uri * uri_get(struct uri *uri)
Increment URI reference count.
static int tftp_errcode_to_rc(unsigned int errcode)
Convert TFTP error code to return status code.
#define FEATURE_PROTOCOL
Network protocols.
static int tftp_reopen(struct tftp_request *tftp)
Reopen TFTP socket.
static void bitmap_free(struct bitmap *bitmap)
Free bitmap resources.
uint32_t next
Next descriptor address.
#define XFER_FL_ABS_OFFSET
Offset is absolute.
#define ref_init(refcnt, free)
Initialise a reference counter.
static int mtftp_open(struct interface *xfer, struct uri *uri)
Initiate MTFTP download.
int xfer_open_socket(struct interface *intf, int semantics, struct sockaddr *peer, struct sockaddr *local)
Open socket.
static struct interface_descriptor tftp_xfer_desc
TFTP data transfer interface descriptor.
#define EINVAL_MC_INVALID_IP
static int tftp_apply_settings(void)
Apply TFTP configuration settings.
int fetch_ipv4_setting(struct settings *settings, const struct setting *setting, struct in_addr *inp)
Fetch value of IPv4 address setting.
void free_iob(struct io_buffer *iobuf)
Free I/O buffer.
uint64_t address
Base address.
sa_family_t st_family
Socket address family (part of struct sockaddr)
struct arbelprm_completion_with_error error
static int tftp_process_multicast(struct tftp_request *tftp, char *value)
Process TFTP "multicast" option.
struct bitmap bitmap
Block bitmap.
static int tftp_process_option(struct tftp_request *tftp, const char *name, char *value)
Process TFTP option.
#define MTFTP_MAX_TIMEOUTS
Maximum number of MTFTP open requests before falling back to TFTP.
static int tftp_process_tsize(struct tftp_request *tftp, char *value)
Process TFTP "tsize" option.
#define ENOENT
No such file or directory.
void intf_plug_plug(struct interface *a, struct interface *b)
Plug two object interfaces together.
uint32_t blksize
Block size for this segment.
struct uri_opener tftp_uri_opener __uri_opener
TFTP URI opener.
#define EINVAL_MC_INVALID_PORT
int strcasecmp(const char *first, const char *second)
Compare case-insensitive strings.
A TFTP data (DATA) packet.
struct io_buffer * xfer_alloc_iob(struct interface *intf, size_t len)
Allocate I/O buffer.
uint32_t data_len
Microcode data size (or 0 to indicate 2000 bytes)
struct refcnt refcnt
Reference count.
#define EACCES
Permission denied.
A data structure for storing profiling information.
static int tftp_presize(struct tftp_request *tftp, size_t filesize)
Presize TFTP receive buffers and block bitmap.
Uniform Resource Identifiers.
sa_family_t sin_family
Socket address family (part of struct sockaddr)
static void profile_stop(struct profiler *profiler)
Stop profiling.
unsigned int blksize
Data block size.
size_t xfer_window(struct interface *intf)
Check flow control window.
#define TFTP_ACK
Data block acknowledgement opcode.
#define ENOTSUP
Operation not supported.
Data transfer interfaces.
static void tftp_timer_expired(struct retry_timer *timer, int fail)
Handle TFTP retransmission timer expiry.
#define ENOMEM
Not enough space.
#define iob_disown(iobuf)
Disown an I/O buffer.
static struct interface_descriptor tftp_socket_desc
TFTP socket interface descriptor.
static int tftp_rx_error(struct tftp_request *tftp, void *buf, size_t len)
Receive ERROR.
void * memcpy(void *dest, const void *src, size_t len) __nonnull
unsigned int flags
Request flags.
#define TFTP_ERR_ILLEGAL_OP
Illegal TFTP operation.
void churi(struct uri *uri)
Change working URI.
struct interface xfer
Data transfer interface.
static int tftp_send_error(struct tftp_request *tftp, int errcode, const char *errmsg)
Transmit ERROR (Abort)
#define container_of(ptr, type, field)
Get containing structure.
Request blksize and tsize options.
A long option, as used for getopt_long()
static struct interface_descriptor tftp_mc_socket_desc
TFTP multicast socket interface descriptor.
static int tftp_open(struct interface *xfer, struct uri *uri)
Initiate TFTP download.
FEATURE(FEATURE_PROTOCOL, "TFTP", DHCP_EB_FEATURE_TFTP, 1)
const char * path
Path (after URI decoding)
struct interface mc_socket
Multicast transport layer interface.
static int tftp_rx_data(struct tftp_request *tftp, struct io_buffer *iobuf)
Receive DATA.
static userptr_t size_t offset
Offset of the first segment within the content.
const char * scheme
URI protocol name.
#define EINVAL_MC_NO_PORT
Transport-network layer interface.
char * strcpy(char *dest, const char *src)
Copy string.
int bitmap_resize(struct bitmap *bitmap, unsigned int new_length)
Resize bitmap.
struct settings_applicator tftp_settings_applicator __settings_applicator
TFTP settings applicator.
static int tftp_send_rrq(struct tftp_request *tftp)
Transmit RRQ.
static void profile_start(struct profiler *profiler)
Start profiling.
static void tftp_free(struct refcnt *refcnt)
Free TFTP request.
static void tftp_close(struct tftp_request *tftp, int rc)
Terminate download.
static void tftp_done(struct tftp_request *tftp, int rc)
Mark TFTP request as complete.
int xfer_seek(struct interface *intf, off_t offset)
Seek to position.
pseudo_bit_t value[0x00020]
uint16_t st_port
TCP/IP port.
Generalized socket address structure.
An object interface descriptor.
static int tftp_send_packet(struct tftp_request *tftp)
Transmit next relevant packet.
static int tftp_process_blksize(struct tftp_request *tftp, char *value)
Process TFTP "blksize" option.
char * strerror(int errno)
Retrieve string representation of error number.
void tftp_set_mtftp_address(struct in_addr address)
Set MTFTP multicast address.
static void(* free)(struct refcnt *refcnt))
const char * name
Long name of this option.
void * zalloc(size_t size)
Allocate cleared memory.
uint16_t sin_port
TCP/IP port (part of struct sockaddr_tcpip)
static int tftp_socket_deliver(struct tftp_request *tftp, struct io_buffer *iobuf, struct xfer_metadata *meta)
Receive new data via socket.
char * strchr(const char *src, int character)
Find character within a string.
static size_t iob_len(struct io_buffer *iobuf)
Calculate length of data in an I/O buffer.
static struct sockaddr_in tftp_mtftp_socket
MTFTP multicast receive address.
#define INTF_OP(op_type, object_type, op_func)
Define an object interface operation.
int inet_aton(const char *string, struct in_addr *in)
Parse IPv4 address.
static int tftm_open(struct interface *xfer, struct uri *uri)
Initiate TFTM download.
static struct tftp_option tftp_options[]
Recognised TFTP options.
static size_t iob_tailroom(struct io_buffer *iobuf)
Calculate available space at end of an I/O buffer.
int xfer_deliver(struct interface *intf, struct io_buffer *iobuf, struct xfer_metadata *meta)
Deliver datagram.
char * inet_ntoa(struct in_addr in)
Convert IPv4 address to dotted-quad notation.
size_t strlen(const char *src)
Get length of string.
Data transfer interface opening.
size_t strnlen(const char *src, size_t max)
Get length of string.
The common header of all TFTP packets.
struct ib_cm_common common
#define TFTP_ERR_ACCESS_DENIED
Access violation.
const char * host
Host name.
#define TFTP_PORT
Default TFTP server port.
#define TFTP_ERROR
Error opcode.
void bitmap_set(struct bitmap *bitmap, unsigned int bit)
Set bit in bitmap.
#define EINVAL_MC_INVALID_MC
A TFTP read request (RRQ) packet.
#define TFTP_OACK
Options acknowledgement opcode.
static int tftp_rx(struct tftp_request *tftp, struct io_buffer *iobuf, struct xfer_metadata *meta)
Receive new data.
void start_timer(struct retry_timer *timer)
Start timer.
static int tftp_reopen_mc(struct tftp_request *tftp, struct sockaddr *local)
Reopen TFTP multicast socket.
static int tftp_send_ack(struct tftp_request *tftp)
Transmit ACK.
Perform MTFTP recovery on timeout.
static struct profiler tftp_client_profiler __profiler
Client profiler.
FILE_LICENCE(GPL2_OR_LATER_OR_UBDL)
struct retry_timer timer
Retransmission timer.
struct in_addr sin_addr
IPv4 address.
#define INTF_DESC(object_type, intf, operations)
Define an object interface descriptor.
void stop_timer(struct retry_timer *timer)
Stop timer.
Bitmaps for multicast downloads.
unsigned int port
Server port.
static int tftp_rx_oack(struct tftp_request *tftp, void *buf, size_t len)
Receive OACK.
uint8_t block[3][8]
DES-encrypted blocks.
#define ENOTTY
Inappropriate I/O control operation.
#define TFTP_ERR_FILE_NOT_FOUND
File not found.
void * data
Start of data.
void tftp_set_mtftp_port(unsigned int port)
Set MTFTP multicast port.
unsigned int uri_port(const struct uri *uri, unsigned int default_port)
Get port from URI.
uint32_t end
Ending offset.
#define TFTP_DEFAULT_BLKSIZE
Default TFTP data block size.
uint8_t data[48]
Additional event data.
static unsigned int bitmap_first_gap(struct bitmap *bitmap)
Get first gap within bitmap.
static struct interface_operation tftp_socket_operations[]
TFTP socket operations.
static struct interface_operation tftp_xfer_operations[]
TFTP data transfer interface operations.
int(* apply)(void)
Apply updated settings.
int snprintf(char *buf, size_t size, const char *fmt,...)
Write a formatted string to a buffer.
A Uniform Resource Identifier.
#define DHCP_EB_FEATURE_TFTP
TFTP protocol.
#define TFTP_DATA
Data block opcode.
struct uri * uri
URI being fetched.
static void intf_init(struct interface *intf, struct interface_descriptor *desc, struct refcnt *refcnt)
Initialise an object interface.
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.
unsigned long tsize
File size.
struct sockaddr_tcpip peer
Peer address.
static int bitmap_full(struct bitmap *bitmap)
Check to see if bitmap is full.
static struct interface_operation tftp_mc_socket_operations[]
TFTP multicast socket operations.
int memcmp(const void *first, const void *second, size_t len)
Compare memory regions.
#define NULL
NULL pointer (VOID *)
#define ETIMEDOUT
Connection timed out.
Request multicast option.
const char * name
Option name.
struct bofm_section_header done
#define AF_INET
IPv4 Internet addresses.
static size_t tftp_xfer_window(struct tftp_request *tftp)
Check flow control window.
#define TFTP_RRQ
Read request opcode.
A TFTP acknowledgement (ACK) packet.
size_t filesize
Maximum known length.
int xfer_open_named_socket(struct interface *xfer, int semantics, struct sockaddr *peer, const char *name, struct sockaddr *local)
Open named socket.
A TFTP error (ERROR) packet.
#define ref_put(refcnt)
Drop reference to object.
if(natsemi->flags &NATSEMI_64BIT) return 1
struct uri * parse_uri(const char *uri_string)
Parse URI.
void * memset(void *dest, int character, size_t len) __nonnull