59 #define EINVAL_BLKSIZE __einfo_error ( EINFO_EINVAL_BLKSIZE ) 60 #define EINFO_EINVAL_BLKSIZE __einfo_uniqify \ 61 ( EINFO_EINVAL, 0x01, "Invalid blksize" ) 62 #define EINVAL_TSIZE __einfo_error ( EINFO_EINVAL_TSIZE ) 63 #define EINFO_EINVAL_TSIZE __einfo_uniqify \ 64 ( EINFO_EINVAL, 0x02, "Invalid tsize" ) 65 #define EINVAL_MC_NO_PORT __einfo_error ( EINFO_EINVAL_MC_NO_PORT ) 66 #define EINFO_EINVAL_MC_NO_PORT __einfo_uniqify \ 67 ( EINFO_EINVAL, 0x03, "Missing multicast port" ) 68 #define EINVAL_MC_NO_MC __einfo_error ( EINFO_EINVAL_MC_NO_MC ) 69 #define EINFO_EINVAL_MC_NO_MC __einfo_uniqify \ 70 ( EINFO_EINVAL, 0x04, "Missing multicast mc" ) 71 #define EINVAL_MC_INVALID_MC __einfo_error ( EINFO_EINVAL_MC_INVALID_MC ) 72 #define EINFO_EINVAL_MC_INVALID_MC __einfo_uniqify \ 73 ( EINFO_EINVAL, 0x05, "Missing multicast IP" ) 74 #define EINVAL_MC_INVALID_IP __einfo_error ( EINFO_EINVAL_MC_INVALID_IP ) 75 #define EINFO_EINVAL_MC_INVALID_IP __einfo_uniqify \ 76 ( EINFO_EINVAL, 0x06, "Invalid multicast IP" ) 77 #define EINVAL_MC_INVALID_PORT __einfo_error ( EINFO_EINVAL_MC_INVALID_PORT ) 78 #define EINFO_EINVAL_MC_INVALID_PORT __einfo_uniqify \ 79 ( EINFO_EINVAL, 0x07, "Invalid multicast port" ) 80 #define ENOENT_NOT_FOUND __einfo_error ( EINFO_ENOENT_NOT_FOUND ) 81 #define EINFO_ENOENT_NOT_FOUND __einfo_uniqify \ 82 ( EINFO_ENOENT, 0x01, "Not found" ) 164 #define MTFTP_MAX_TIMEOUTS 3 168 { .
name =
"tftp.client" };
172 { .
name =
"tftp.server" };
201 DBGC ( tftp,
"TFTP %p finished with status %d (%s)\n",
233 memset ( &server, 0,
sizeof ( server ) );
238 DBGC ( tftp,
"TFTP %p could not open socket: %s\n",
265 local, local ) ) != 0 ) {
266 DBGC ( tftp,
"TFTP %p could not open multicast " 282 unsigned int num_blocks;
286 if ( filesize <= tftp->filesize )
302 num_blocks = ( ( filesize / tftp->
blksize ) + 1 );
304 DBGC ( tftp,
"TFTP %p could not resize bitmap to %d blocks: " 319 .sin_addr.s_addr =
htonl ( 0xefff0101 ),
320 .sin_port =
htons ( 3001 ),
348 const char *path = ( tftp->
uri->
path + 1 );
354 DBGC ( tftp,
"TFTP %p requesting \"%s\"\n", tftp, path );
357 len = (
sizeof ( *rrq ) +
strlen ( path ) + 1
372 rrq =
iob_put ( iobuf,
sizeof ( *rrq ) );
375 "%s%coctet", path, 0 ) + 1 );
379 "blksize%c%zd%ctsize%c0",
385 "multicast%c", 0 ) + 1 );
410 DBGC2 ( tftp,
"TFTP %p sending ACK for block %d\n", tftp,
block );
418 ack =
iob_put ( iobuf,
sizeof ( *ack ) );
443 DBGC2 ( tftp,
"TFTP %p sending ERROR %d: %s\n", tftp,
errcode,
453 err =
iob_put ( iobuf, msglen );
510 DBGC ( tftp,
"TFTP %p attempting reopen\n", tftp );
516 DBGC ( tftp,
"TFTP %p timeout %d waiting for MTFTP " 520 DBGC ( tftp,
"TFTP %p falling back to plain " 535 sizeof ( tftp->
bitmap ) );
571 DBGC ( tftp,
"TFTP %p got invalid blksize \"%s\"\n",
575 DBGC ( tftp,
"TFTP %p blksize=%d\n", tftp, tftp->
blksize );
592 DBGC ( tftp,
"TFTP %p got invalid tsize \"%s\"\n",
596 DBGC ( tftp,
"TFTP %p tsize=%ld\n", tftp, tftp->
tsize );
624 DBGC ( tftp,
"TFTP %p multicast missing port,mc\n", tftp );
630 DBGC ( tftp,
"TFTP %p multicast missing mc\n", tftp );
636 if (
strtoul ( mc, &mc_end, 0 ) == 0 )
639 DBGC ( tftp,
"TFTP %p multicast invalid mc %s\n", tftp, mc );
642 DBGC ( tftp,
"TFTP %p is%s the master client\n",
645 socket.sin.sin_family =
AF_INET;
647 DBGC ( tftp,
"TFTP %p multicast invalid IP address " 648 "%s\n", tftp,
addr );
651 DBGC ( tftp,
"TFTP %p multicast IP address %s\n",
652 tftp,
inet_ntoa ( socket.sin.sin_addr ) );
655 DBGC ( tftp,
"TFTP %p multicast invalid port %s\n",
659 DBGC ( tftp,
"TFTP %p multicast port %d\n",
660 tftp,
ntohs ( socket.sin.sin_port ) );
706 DBGC ( tftp,
"TFTP %p received unknown option \"%s\" = \"%s\"\n",
730 if (
len <
sizeof ( *oack ) ) {
731 DBGC ( tftp,
"TFTP %p received underlength OACK packet " 732 "length %zd\n", tftp,
len );
749 DBGC ( tftp,
"TFTP %p received OACK with malformed " 750 "option name:\n", tftp );
755 DBGC ( tftp,
"TFTP %p received OACK missing value " 756 "for option \"%s\"\n", tftp,
name );
762 DBGC ( tftp,
"TFTP %p received OACK with malformed " 763 "value for option \"%s\":\n", tftp,
name );
808 DBGC ( tftp,
"TFTP %p received underlength DATA packet " 809 "length %zd\n", tftp,
iob_len ( iobuf ) );
817 DBGC ( tftp,
"TFTP %p received data block 0\n", tftp );
832 DBGC ( tftp,
"TFTP %p received overlength DATA packet " 844 DBGC ( tftp,
"TFTP %p could not deliver data: %s\n",
905 DBGC ( tftp,
"TFTP %p received underlength ERROR packet " 906 "length %zd\n", tftp,
len );
910 DBGC ( tftp,
"TFTP %p received ERROR packet with code %d, message " 943 DBGC ( tftp,
"TFTP %p received underlength packet length " 944 "%zd\n", tftp,
len );
948 DBGC ( tftp,
"TFTP %p received packet without source port\n",
957 DBGC ( tftp,
"TFTP %p using remote port %d\n", tftp,
960 sizeof ( tftp->
peer ) ) != 0 ) {
961 DBGC ( tftp,
"TFTP %p received packet from wrong source (got " 967 switch (
common->opcode ) {
978 DBGC ( tftp,
"TFTP %p received strange packet type %d\n",
1087 unsigned int default_port,
1089 unsigned int flags ) {
1102 tftp =
zalloc (
sizeof ( *tftp ) );
1134 DBGC ( tftp,
"TFTP %p could not create request: %s\n",
1212 static struct in_addr tftp_server = { 0 };
1213 struct in_addr new_tftp_server;
1214 char uri_string[32];
1227 if ( new_tftp_server.
s_addr &&
1229 DBGC ( &tftp_server,
"TFTP server changed %s => ",
1231 DBGC ( &tftp_server,
"%s\n",
inet_ntoa ( new_tftp_server ) );
1232 snprintf ( uri_string,
sizeof ( uri_string ),
1233 "tftp://%s/",
inet_ntoa ( new_tftp_server ) );
1239 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.
#define __einfo_errortab(einfo)
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.
void intf_plug_plug(struct interface *a, struct interface *b)
Plug two object interfaces together.
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.
#define EINFO_ENOENT_NOT_FOUND
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.
pseudo_bit_t value[0x00020]
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.
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.
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.
struct errortab tftp_errors [] __errortab
Human-readable error messages.
int snprintf(char *buf, size_t size, const char *fmt,...)
Write a formatted string to a buffer.
A Uniform Resource Identifier.
uint16_t offset
Offset to command line.
uint32_t blksize
Cipher block size.
#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