Back to home page

LXR

 
 

    


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

0001 /* SPDX-License-Identifier: BSD-2-Clause */
0002 
0003 /**
0004  * @file
0005  *
0006  * @ingroup RTEMSTestSuiteTestsTFTPFS
0007  *
0008  * @brief This header file provides interfaces and functions used to
0009  *   implement the UDP network fake for tftpfs tests.
0010  *
0011  * Definitions and declarations of data structures and functions.
0012  */
0013 
0014 /*
0015  * Copyright (C) 2022 embedded brains GmbH & Co. KG
0016  *
0017  * Redistribution and use in source and binary forms, with or without
0018  * modification, are permitted provided that the following conditions
0019  * are met:
0020  * 1. Redistributions of source code must retain the above copyright
0021  *    notice, this list of conditions and the following disclaimer.
0022  * 2. Redistributions in binary form must reproduce the above copyright
0023  *    notice, this list of conditions and the following disclaimer in the
0024  *    documentation and/or other materials provided with the distribution.
0025  *
0026  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
0027  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
0028  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
0029  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
0030  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
0031  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
0032  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
0033  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
0034  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
0035  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
0036  * POSSIBILITY OF SUCH DAMAGE.
0037  */
0038 
0039 #include <stddef.h>
0040 #include <stdint.h>
0041 #include <stdbool.h>
0042 #include <sys/types.h> /* ssize_t */
0043 
0044 #ifndef _TFTPFS_UDP_NETWORK_FAKE_H
0045 #define _TFTPFS_UDP_NETWORK_FAKE_H
0046 
0047 #ifdef __cplusplus
0048 extern "C" {
0049 #endif
0050 
0051 
0052 /**
0053  * @defgroup RTEMSTestSuiteTestsTFTPFS Test suite for libtftpsfs tests
0054  *
0055  * @ingroup RTEMSTestSuitesFilesystem
0056  *
0057  * @brief This test suite provides a tests for libtftpfs.
0058  *
0059  * There are some additional files relevant for the TFTP test suite:
0060  *
0061  * - `spec/build/testsuites/fstests/grp.yml`\n
0062  *   This file specifies how the RTEMS WAF build system has to compile, link
0063  *   and install all filesystem test suites.  The TFTP test suite must
0064  *   be mentioned in this file to be build.
0065  *
0066  * - `spec/build/testsuites/fstests/tftpfs.yml`\n
0067  *   This file specifies how the RTEMS WAF build system has to compile, link
0068  *   and install the TFTP test suite.
0069  *
0070  * - `Doxygen`\n
0071  *    At variable `INPUT` the test suite is included to be processed by the
0072  *    Doxygen documentation generator.
0073  *
0074  * See also the _RTEMS Filesystem Design Guide_ Chapter _Trivial FTP Client
0075  * Filesystem_.
0076  *
0077  * @{
0078  */
0079 
0080 #define TFTP_STD_PORT               69
0081 #define TFTP_MAX_IP_ADDR_STRLEN     (16 * 2 + 7 + 1)
0082 #define TFTP_MAX_ERROR_STRLEN       20
0083 #define TFTP_MAX_OPTIONS_SIZE       40
0084 
0085 /**
0086  * @brief IP address strings and server names resolved by network fake
0087  *   functions like inet_aton() and gethostbyname().
0088  */
0089 #define TFTP_KNOWN_IPV4_ADDR0_STR   "127.0.0.1"
0090 #define TFTP_KNOWN_IPV4_ADDR0_ARRAY 127, 0, 0, 1
0091 #define TFTP_KNOWN_SERVER0_NAME     "server.tftp"
0092 #define TFTP_KNOWN_SERVER0_IPV4     "10.7.0.2"
0093 #define TFTP_KNOWN_SERVER0_ARRAY    10, 7, 0, 2
0094 
0095 /**
0096  * @brief The faked socket() function (i.e. socket interaction) must return
0097  *   a file descriptor equal or larger than @c TFTP_FIRST_FD
0098  *   or -1.
0099  */
0100 #define TFTP_FIRST_FD 33333
0101 
0102 typedef enum Tftp_Action_kind {
0103   TFTP_IA_KIND_SOCKET,
0104   TFTP_IA_KIND_CLOSE,
0105   TFTP_IA_KIND_BIND,
0106   TFTP_IA_KIND_SENDTO,
0107   TFTP_IA_KIND_RECVFROM
0108 } Tftp_Action_kind;
0109 
0110 typedef struct Tftp_Action {
0111   Tftp_Action_kind kind;
0112   union {
0113     struct {
0114       int domain;
0115       int type;
0116       int protocol;
0117       int result;
0118     } socket;
0119     struct {
0120       int fd;
0121       int result;
0122     } close;
0123     struct {
0124       int fd;
0125       int family;
0126       uint16_t port;
0127       const char *addr_str;
0128       int result;
0129     } bind;
0130     struct {
0131       int fd;
0132       const void *buf;
0133       size_t len;
0134       int flags;
0135       uint16_t dest_port;
0136       const char *dest_addr_str;
0137       int addrlen;
0138       ssize_t result;
0139     } sendto;
0140     struct {
0141       int fd;
0142       void *buf;
0143       size_t len;
0144       int flags;
0145       uint32_t timeout_ms;
0146       uint16_t src_port;
0147       char src_addr_str[TFTP_MAX_IP_ADDR_STRLEN];
0148       int addrlen;
0149       ssize_t result;
0150     } recvfrom;
0151   } data;
0152 } Tftp_Action;
0153 
0154 /**
0155  * @brief Carry out interactions with TFTP client.
0156  *
0157  * @c Tftp_Interaction_fn() is called to
0158  *
0159  *   * check that the fake network function has been called with the expected
0160  *     arguments (in @c act)
0161  *   * define values which shall be returned (to be stored in @c act)
0162  *
0163  * The function should not call @c T_assert_*() but use @c T_*().
0164  *  Otherwise, it is unlikely that the test can terminate the client in
0165  *  @c teardown().
0166  *
0167  * @param[in,out] act The actual arguments provided by the TFTP client
0168  *   to the network function.  Moreover, storage to store the results
0169  *   to be returned to the TFTP client.
0170  * @param data Arbitrary data area allocated when the interaction is created
0171  *   by @c _Tftp_Append_interaction()
0172  *
0173  * @retval true if the client behaved as expected.
0174  * @retval false if the test shall fail.
0175  */
0176 typedef bool (*Tftp_Interaction_fn)( Tftp_Action *act, void *data );
0177 typedef struct Tftp_Interaction Tftp_Interaction;
0178 typedef struct Tftp_Interaction {
0179   Tftp_Interaction *next;
0180   Tftp_Action_kind kind;
0181   Tftp_Interaction_fn fn;
0182   void *data[0];
0183 } Tftp_Interaction;
0184 
0185 /**
0186  * @brief Initialize and free the singleton control object.
0187  *
0188  * Invoke @c _Tftp_Reset() in @c setup() and @c teardown() of the test.
0189  */
0190 void _Tftp_Reset( void );
0191 
0192 /**
0193  * @brief Create an interaction and append it to the sequence of expected
0194  *   interactions.
0195  *
0196  * This allocates memory for an interaction and additional specific data
0197  * for the function @c fn() parameter @c data.  The interaction is
0198  * initialized and appended at the end of the sequence of expected interactions.
0199  * If an error occurs a @c T_assert_*() macro is called. Hence, this function
0200  * never returns @c NULL.
0201  *
0202  * @param kind Defines which interaction is expected.  Note that it cannot
0203  *   happen that @c fn is called for a different network function.
0204  * @param fn A function which is called to handle the interaction.
0205  *   See @c Tftp_Interaction_fn()
0206  * @param size The size of a memory area which is given to @c fn() as
0207  *   @c data argument when it is invoked.  This can be used to provide
0208  *   private data to the function.
0209  *
0210  * @return A pointer to a memory area of size @c size.  The same pointer
0211  *   will be provided to @c fn as argument @c data when invoked.
0212  */
0213 void *_Tftp_Append_interaction(
0214   Tftp_Action_kind kind,
0215   Tftp_Interaction_fn fn,
0216   size_t size
0217 );
0218 
0219 
0220 /**
0221  * @brief Have all queued interactions been processed?
0222  *
0223  * At the end of a test, it should be checked whether all queued interactions
0224  * have been consumed by the TFTP client.
0225  *
0226  * @retval true All queued interactions have been processed.
0227  * @retval false At least one queued interactions has not yet been processed.
0228  */
0229 bool _Tftp_Has_no_more_interactions( void );
0230 
0231 /*
0232  * TFTP details from RFC1350, RFC2347, RFC2348 and RFC7440
0233  *
0234  * Note: The RFCs require modes and options to be case in-sensitive.
0235  */
0236 
0237 #define TFTP_MODE_NETASCII     "netascii"
0238 #define TFTP_MODE_OCTET        "octet"
0239 #define TFTP_OPTION_BLKSIZE    "blksize"
0240 #define TFTP_OPTION_TIMEOUT    "timeout"
0241 #define TFTP_OPTION_TSIZE      "tsize"
0242 #define TFTP_OPTION_WINDOWSIZE "windowsize"
0243 
0244 #define TFTP_WINDOW_SIZE_MIN   1
0245 #define TFTP_BLOCK_SIZE_MIN    8
0246 #define TFTP_BLOCK_SIZE_MAX    65464
0247 
0248 typedef enum Tftp_Opcode {
0249   TFTP_OPCODE_RRQ   = 1,
0250   TFTP_OPCODE_WRQ   = 2,
0251   TFTP_OPCODE_DATA  = 3,
0252   TFTP_OPCODE_ACK   = 4,
0253   TFTP_OPCODE_ERROR = 5,
0254   TFTP_OPCODE_OACK  = 6,
0255 } Tftp_Opcode;
0256 
0257 typedef enum Tftp_Error_code {
0258   TFTP_ERROR_CODE_NOT_DEFINED = 0,
0259   TFTP_ERROR_CODE_NOT_FOUND   = 1,
0260   TFTP_ERROR_CODE_NO_ACCESS   = 2,
0261   TFTP_ERROR_CODE_DISK_FULL   = 3,
0262   TFTP_ERROR_CODE_ILLEGAL     = 4,
0263   TFTP_ERROR_CODE_UNKNOWN_ID  = 5,
0264   TFTP_ERROR_CODE_FILE_EXISTS = 6,
0265   TFTP_ERROR_CODE_NO_USER     = 7,
0266   TFTP_ERROR_CODE_OPTION_NEGO = 8,
0267 } Tftp_Error_code;
0268 
0269 typedef struct Tftp_Packet {
0270   uint16_t opcode;
0271   union {
0272     struct {
0273       char opts[0];
0274     } rrq;
0275     struct {
0276       char opts[0];
0277     } wrq;
0278     struct {
0279       uint16_t block_num;
0280       uint8_t bytes[0];
0281     } data;
0282     struct {
0283       uint16_t block_num;
0284     } ack;
0285     struct {
0286       uint16_t error_code;
0287       char err_msg[0];
0288     } error;
0289     struct {
0290       char opts[0];
0291     } oack;
0292   } content;
0293 } Tftp_Packet;
0294 
0295 /**
0296  * @brief Provides a human readable description for an error code from an TFTP
0297  *   error packet.
0298  *
0299  * @param error_code The error code from the TFTP error packet in host byte
0300  *   order.
0301  *
0302  * @return A pointer to a string describing the error.  If the error code is
0303  *   unknown, a pointer to "Unknown error code" is returned.  Do not change the
0304  *   the string as a pointer to the very same string will be returned by future
0305  *   calls.
0306  */
0307 const char *_Tftp_Get_error_str( uint16_t error_code );
0308 
0309 /** @} */
0310 
0311 #ifdef __cplusplus
0312 }
0313 #endif
0314 
0315 #endif /* _TFTPFS_UDP_NETWORK_FAKE_H */