Back to home page

LXR

 
 

    


File indexing completed on 2025-05-11 08:24:14

0001 /* SPDX-License-Identifier: BSD-2-Clause */
0002 
0003 /**
0004  * @file
0005  *
0006  * @ingroup RTEMSImplTFTPFS
0007  *
0008  * @brief This header file provides interfaces and functions used to
0009  *   implement the TFTP file system.
0010  *
0011  * This file declares the public functions of the Trivial File
0012  * Transfer Protocol (TFTP) file system.
0013  */
0014 
0015 /*
0016  * Copyright (C) 1998 W. Eric Norum <eric@norum.ca>
0017  * Copyright (C) 2022 embedded brains GmbH & Co. KG
0018  *
0019  * Redistribution and use in source and binary forms, with or without
0020  * modification, are permitted provided that the following conditions
0021  * are met:
0022  * 1. Redistributions of source code must retain the above copyright
0023  *    notice, this list of conditions and the following disclaimer.
0024  * 2. Redistributions in binary form must reproduce the above copyright
0025  *    notice, this list of conditions and the following disclaimer in the
0026  *    documentation and/or other materials provided with the distribution.
0027  *
0028  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
0029  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
0030  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
0031  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
0032  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
0033  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
0034  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
0035  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
0036  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
0037  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
0038  * POSSIBILITY OF SUCH DAMAGE.
0039  */
0040 
0041 #ifndef _RTEMS_TFTP_H
0042 #define _RTEMS_TFTP_H
0043 
0044 #ifdef __cplusplus
0045 extern "C" {
0046 #endif
0047 
0048 #include <stdint.h>
0049 #include <rtems/fs.h>
0050 
0051 /**
0052  * @brief Do not call directly, use mount().
0053  *
0054  * @ingroup RTEMSImplTFTPFS
0055  *
0056  * Filesystem Mount table entry.
0057  */
0058 int rtems_tftpfs_initialize(
0059   rtems_filesystem_mount_table_entry_t *mt_entry,
0060   const void *data
0061 );
0062 
0063 /**
0064  * @defgroup RTEMSAPITFTPFS Trivial File Transfer Protocol (TFTP) API
0065  *
0066  * @ingroup RTEMSAPIIO
0067  *
0068  * @brief The TFTP client library provides an API to read files from and
0069  *   to write files to remote servers using the Trivial File Transfer
0070  *   Protocol (TFTP).
0071  *
0072  * See the _RTEMS Filesystem Design Guide_ Chapter _Trivial FTP Client
0073  * Filesystem_.
0074  *
0075  * Usage as TFTP File System
0076  * =========================
0077  *
0078  * To open `/bootfiles/image` on `hostname` for reading:
0079  *
0080  *     fd = open ("/TFTP/hostname:bootfiles/image", O_RDONLY);
0081  *
0082  * The `TFTP` is the mount path and the `hostname` must be
0083  *
0084  * + an IPv4 address (like `127.0.0.1`) or
0085  * + the (full-qualified) name of an IPv4 host (acceptable to
0086  *  `gethostbyname()`)
0087  *
0088  * IPv6 is currently not supported. `bootfiles/image` is a path on the
0089  * TFTP server `hostname` where the file (here `image`) can be found.
0090  *
0091  * Usage of TFTP Client
0092  * ====================
0093  *
0094  * The pseudo-code below shows the principal usage for reading a file.
0095  *
0096  * @code
0097  *   int res;
0098  *   ssize_t bytes;
0099  *   void *tftp_handle;
0100  *   tftp_net_config config;
0101  *   const size_t buffer_size = 4000;
0102  *   char data_buffer[buffer_size];
0103  *
0104  *   tftp_initialize_net_config( &config );
0105  *   config.options.window_size = 1; // Set desired config values
0106  *
0107  *   res = tftp_open(
0108  *     "127.0.0.1",
0109  *     "filename.txt",
0110  *     true, // is_for_reading
0111  *     &config,
0112  *     &tftp_handle
0113  *   );
0114  *
0115  *   if ( res != 0 || tftp_handle == NULL ) {
0116  *     // Error
0117  *   }
0118  *
0119  *   // Use tftp_read() (probably in a loop) ...
0120  *   bytes = tftp_read(
0121  *     tftp_handle,
0122  *     data_buffer,
0123  *     buffer_size
0124  *   );
0125  *   // ... or use tftp_write() instead when the file is open for writing.
0126  *
0127  *   res = tftp_close( tftp_handle );
0128  *
0129  *   if ( res != 0 ) {
0130  *     // Error ... check! Especially when writing!
0131  *   }
0132  * @endcode
0133  *
0134  * @{
0135  */
0136 
0137 /*
0138  * The functions below use of the TFTP client library standalone
0139  * - i.e. without going through the file system.
0140  */
0141 
0142 /**
0143  * @brief This block size meets RFC 1350 and avoids the sending of
0144  *   the `blksize` option to the TFTP server.
0145  */
0146 #define TFTP_RFC1350_BLOCK_SIZE 512
0147 
0148 /**
0149  * @brief This window size avoids the sending of the `windowsize`
0150  *   option to the TFTP server.
0151  *
0152  * This effectively mimics the operation defined in RFC 1350 which
0153  * does not know any window size.
0154  */
0155 #define TFTP_RFC1350_WINDOW_SIZE 1
0156 
0157 /**
0158  * @brief This block size is suggested in RFC 2348 and is used as
0159  *   default if no different block size is provided.
0160  */
0161 #define TFTP_DEFAULT_BLOCK_SIZE 1456
0162 
0163 /**
0164  * @brief This window size is suggested in RFC 2348 and is used as
0165  *   default if no different window size is provided.
0166  */
0167 #define TFTP_DEFAULT_WINDOW_SIZE 8
0168 
0169 /**
0170  * @brief This structure represents TFTP options negotiated between
0171  *   client and server.
0172  *
0173  * RFC 2347 is the basis for the TFTP option.
0174  */
0175 typedef struct tftp_options {
0176   /**
0177    * @brief This member represents the desired size of a data block.
0178    *
0179    * The TFTP blocksize option is introduced in RFC 2348.  It defines the
0180    * number of octets in the data packets transferred.  Valid values
0181    * range between 8 and 65464 octets, inclusive.  Values larger
0182    * than 1468 may cause packet fragmentation over standard Ethernet.
0183    * A value of 512 will prevent this option from being sent to
0184    * the server.
0185    *
0186    * The default value is 1456.
0187    */
0188   uint16_t block_size;
0189 
0190   /**
0191    * @brief This member represents the desired size of a window.
0192    *
0193    * The TFTP windowsize option is introduced in RFC 7440.  It defines the
0194    * number of data packets send before the receiver must send an
0195    * acknowledgment packet.  Valid values range between 1 and 65535
0196    * packets, inclusive.  Simple TFTP servers usually do not support this
0197    * option.  This option may negatively contribute to network
0198    * congestion.  This can be avoided by using a window size of 1.
0199    * A value of 1 will prevent this option from being sent to
0200    * the server.
0201    *
0202    * The default value is 8.
0203    */
0204   uint16_t window_size;
0205 } tftp_options;
0206 
0207 /**
0208  * @brief This structure represents configuration value used by the TFTP
0209  *   client.
0210  *
0211  * As defaults the values suggested in RFC 7440 are used.
0212  */
0213 typedef struct tftp_net_config {
0214   /**
0215    * @brief This member defines how many attempts are made to send a
0216    *   network packet to the server.
0217    *
0218    * Repetitions occur when the server does not response to a packet
0219    * send by the client within a timeout period.  When the here defined
0220    * number of repetitions is reached and the server does still not
0221    * respond, the connection is considered broken and the file transfer
0222    * is ended with an error.
0223    *
0224    * The default value is 6.
0225    */
0226   uint16_t retransmissions;
0227 
0228   /**
0229    * @brief This member defines the port on which the server is listening
0230    *   for incoming connections.
0231    *
0232    * The default port number is 69.
0233    */
0234   uint16_t server_port;
0235 
0236   /**
0237    * @brief This member defines the maximum time in milliseconds the
0238    *   client waits for an answer packet from the server.
0239    *
0240    * If the time out is exceeded, the client will re-transmit the last
0241    * packet it send to the server.  In case @c window_size is larger one,
0242    * several packets may subject to re-transmission.
0243    *
0244    * Note that this timeout applies only after the first re-transmission
0245    * of a packet. The timeout till the first re-transmission is
0246    * @c first_timeout.
0247    *
0248    * The default value is 1000ms.
0249    */
0250   uint32_t timeout;
0251 
0252   /**
0253    * @brief This member defines the maximum time in milliseconds the
0254    *   client waits for the first answer packet from the server.
0255    *
0256    * The @c first_timeout is used instead of the regular @c timeout
0257    * for the first wait-period directly after the client sends a packet
0258    * for the first time to the server.  That is, this is the timeout
0259    * of the first re-transmission.  For any following re-transmissions
0260    * of the current packet the regular @c timeout is used.
0261    *
0262    * The default value is 400ms.
0263    */
0264   uint32_t first_timeout;
0265 
0266   /**
0267    * @brief This member represents the options to be sent to the server.
0268    *
0269    * These option values are sent to the server.  Yet, the server may
0270    *
0271    *   + ignore one or all options
0272    *   + ask the client to use a different value for an option
0273    *   + reject the whole request with an error
0274    *
0275    * If the server rejects a request with options, the current client
0276    * implementation will automatically send a second request without
0277    * options.  Hence, the user should be aware that the actual file
0278    * transfer may not use the option values specified here.
0279    */
0280   tftp_options options;
0281 } tftp_net_config;
0282 
0283 /**
0284  * @brief Set all members of a @c tftp_net_config structure to their
0285  *   default values.
0286  *
0287  * @param config references a @c tftp_net_config structure.
0288  *   The values are set to the defaults defined in
0289  *   @ref tftp_net_config "`type tftp_net_config`".
0290  */
0291 void tftp_initialize_net_config(
0292   tftp_net_config *config
0293 );
0294 
0295 /**
0296  * @brief Opens and starts a TFTP client session to read or write a
0297  *   single file.
0298  *
0299  * This directive resolves the hostname or IP address, establishes a connection
0300  * to the TFTP server and initiates the data transfer.  It will not return
0301  * before an error is encountered or the TFTP server has responded to the
0302  * read or write request with a network packet.
0303  *
0304  * TFTP uses timeouts (of unspecified length).  It does not know keep-alive
0305  * messages.  If the client does not respond to the server in due time,
0306  * the server sets the connection faulty and drops it.  To avoid this
0307  * the user of this code must read or write enough data fast enough.
0308  *
0309  * "Enough data" means at least so much data which fills a single data
0310  * packet or all packets of a window if windows are used.  The data
0311  * can be read or written in anything from one single large chunk to
0312  * byte-by-byte pieces.  The point is, one cannot pause the reading
0313  * or writing for longer periods of time.
0314  *
0315  * @param hostname is the IPv4 address as string or the name of the TFTP
0316  *   server to connect to.
0317  * @param path is the pathname at the TFTP server side of the file to
0318  *   read or write.  According to RFC 1350 the path must be in
0319  *   NETASCII.  This is ASCII as defined in "USA Standard Code for
0320  *   Information Interchange" with the modifications specified in "Telnet
0321  *   Protocol Specification".
0322  * @param is_for_reading indicated whether the file is to be read or written.
0323  *   A value of @c true indicates that the file is intended to be read from
0324  *   the server.  A value of @c false indicates that the file is to be
0325  *   written to the server.
0326  * @param config either references a structure defining the configuration
0327  *   values for this file transfer or is @c NULL.  If it is @c NULL, default
0328  *   configuration values are used.  See @ref tftp_net_config
0329  *   "type tftp_net_config" for a description and the defaults values.
0330  *   This function copies the data so that the memory pointed to by
0331  *   @c config can be used for other purposes after the call returns.
0332  * @param[out] tftp_handle references a place where a handle of the connection
0333  *   can be stored.  On success a pointer to a handle is stored.  On failure
0334  *   (return value other than 0) a @c NULL pointer is stored.  This handle
0335  *   must be provided to all further calls to @c tftp_read(),
0336  *   @c tftp_write(), and @c tftp_close().
0337  *
0338  *   When this directive stores a non-NULL pointer in this place, a call
0339  *   to @c tftp_close() is mandatory to release allocated resources.
0340  *   This parameter cannot be @c NULL.
0341  *
0342  * @retval 0 When the client session was opened successfully.
0343  * @return Returns a POSIX @c errno value in case an error occurred.
0344  */
0345 int tftp_open(
0346   const char  *hostname,
0347   const char  *path,
0348   bool   is_for_reading,
0349   const tftp_net_config *config,
0350   void **tftp_handle
0351 );
0352 
0353 /**
0354  * @brief Read data from a TFTP server.
0355  *
0356  * This directive attempts to read data from a TFTP connection open for
0357  * reading.
0358  *
0359  * Upon success, the buffer is always filled with @c count bytes of received
0360  * data with the exception when the end of the file has been reached.
0361  *
0362  * TFTP cannot recover from errors.  Once an error is reported, the
0363  * connection must be and can only be closed.
0364  *
0365  * @param tftp_handle is the reference returned by a call to tftp_open().
0366  *   The file must be opened for reading.
0367  * @param[out] buffer references a memory area into which the received
0368  *   data is written.
0369  * @param count defines the size of the @c buffer in bytes.
0370  *
0371  * @retval 0 The end of the file has been reached.  There is no more data.
0372  * @return If greater or equal to 0, returns the number of bytes written
0373  *   into the buffer.  If the return value is negative, an error occurred.
0374  *   In this case the negated value is a POSIX @c errno value.
0375  */
0376 ssize_t tftp_read(
0377   void   *tftp_handle,
0378   void   *buffer,
0379   size_t  count
0380 );
0381 
0382 /**
0383  * @brief Write data to a TFTP server.
0384  *
0385  * This directive attempts to write data to a TFTP connection open for
0386  * writing.
0387  *
0388  * On a successful call, all data in the @c buffer will be used.  Yet, this
0389  * does not imply that all data is actually sent.  This depends on
0390  * whether a whole data packet or window can be filled.
0391  *
0392  * TFTP cannot recover from errors.  Once an error is reported, the connection
0393  * must be and can only be closed.
0394  *
0395  * @param tftp_handle is the reference returned by a call to tftp_open().
0396  *   The file must be opened for writing.
0397  * @param buffer references a memory area which contains the data to be
0398  *   sent.
0399  * @param count defines the size of the data in @c buffer in bytes.
0400  *
0401  * @return If greater or equal to 0, returns the number of bytes used
0402  *   from the buffer.  The value is always @c count on a successful call.
0403  *   If the return value is negative, an error occurred.  In this case
0404  *   the negated value is a POSIX @c errno value.
0405  */
0406 ssize_t tftp_write(
0407   void       *tftp_handle,
0408   const void *buffer,
0409   size_t      count
0410 );
0411 
0412 /**
0413  * @brief Close a TFTP client connection.
0414  *
0415  * This directive sends all data which are still stored in a write buffer
0416  * to the server (if any), tells the server that the connection ends (if
0417  * required by RFC 1350) and releases any resources allocated at the
0418  * client side.
0419  *
0420  * @note Especially, when writing a file to the server, the return
0421  * code of `tftp_close()` should be checked.  Invoking
0422  * `tftp_close()` triggers the sending of the last -- not
0423  * completely filled -- data block.  This may fail the same way as any
0424  * `tftp_write()` may fail.  Therefore, an error returned by
0425  * `tftp_close()` likely indicates that the file was not
0426  * completely transferred.
0427  *
0428  * @param tftp_handle is the reference returned by a call to tftp_open().
0429  *   If this parameter is @c NULL, the directive call is a no-op.
0430  *
0431  * @retval 0 When the client session was closed successfully.
0432  * @return Returns a POSIX @c errno value in case an error occurred.
0433  */
0434 int tftp_close(
0435   void *tftp_handle
0436 );
0437 
0438 /** @} */
0439 
0440 #ifdef __cplusplus
0441 }
0442 #endif
0443 
0444 #endif