diff options
Diffstat (limited to 'testsuites/fstests/tftpfs/tftpfs_udp_network_fake.h')
-rw-r--r-- | testsuites/fstests/tftpfs/tftpfs_udp_network_fake.h | 315 |
1 files changed, 315 insertions, 0 deletions
diff --git a/testsuites/fstests/tftpfs/tftpfs_udp_network_fake.h b/testsuites/fstests/tftpfs/tftpfs_udp_network_fake.h new file mode 100644 index 0000000000..2c5860882f --- /dev/null +++ b/testsuites/fstests/tftpfs/tftpfs_udp_network_fake.h @@ -0,0 +1,315 @@ +/* SPDX-License-Identifier: BSD-2-Clause */ + +/** + * @file + * + * @ingroup RTEMSTestSuiteTestsTFTPFS + * + * @brief This header file provides interfaces and functions used to + * implement the UDP network fake for tftpfs tests. + * + * Definitions and declarations of data structures and functions. + */ + +/* + * Copyright (C) 2022 embedded brains GmbH (http://www.embedded-brains.de) + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <stddef.h> +#include <stdint.h> +#include <stdbool.h> +#include <sys/types.h> /* ssize_t */ + +#ifndef _TFTPFS_UDP_NETWORK_FAKE_H +#define _TFTPFS_UDP_NETWORK_FAKE_H + +#ifdef __cplusplus +extern "C" { +#endif + + +/** + * @defgroup RTEMSTestSuiteTestsTFTPFS Test suite for libtftpsfs tests + * + * @ingroup RTEMSTestSuites + * + * @brief This test suite provides a tests for libtftpfs. + * + * There are some additional files relevant for the TFTP test suite: + * + * - `spec/build/testsuites/fstests/grp.yml`\n + * This file specifies how the RTEMS WAF build system has to compile, link + * and install all filesystem test suites. The TFTP test suite must + * be mentioned in this file to be build. + * + * - `spec/build/testsuites/fstests/tftpfs.yml`\n + * This file specifies how the RTEMS WAF build system has to compile, link + * and install the TFTP test suite. + * + * - `Doxygen`\n + * At variable `INPUT` the test suite is included to be processed by the + * Doxygen documentation generator. + * + * See also the _RTEMS Filesystem Design Guide_ Chapter _Trivial FTP Client + * Filesystem_. + * + * @{ + */ + +#define TFTP_STD_PORT 69 +#define TFTP_MAX_IP_ADDR_STRLEN (16 * 2 + 7 + 1) +#define TFTP_MAX_ERROR_STRLEN 20 +#define TFTP_MAX_OPTIONS_SIZE 40 + +/** + * @brief IP address strings and server names resolved by network fake + * functions like inet_aton() and gethostbyname(). + */ +#define TFTP_KNOWN_IPV4_ADDR0_STR "127.0.0.1" +#define TFTP_KNOWN_IPV4_ADDR0_ARRAY 127, 0, 0, 1 +#define TFTP_KNOWN_SERVER0_NAME "server.tftp" +#define TFTP_KNOWN_SERVER0_IPV4 "10.7.0.2" +#define TFTP_KNOWN_SERVER0_ARRAY 10, 7, 0, 2 + +/** + * @brief The faked socket() function (i.e. socket interaction) must return + * a file descriptor equal or larger than @c TFTP_FIRST_FD + * or -1. + */ +#define TFTP_FIRST_FD 33333 + +typedef enum Tftp_Action_kind { + TFTP_IA_KIND_SOCKET, + TFTP_IA_KIND_CLOSE, + TFTP_IA_KIND_BIND, + TFTP_IA_KIND_SENDTO, + TFTP_IA_KIND_RECVFROM +} Tftp_Action_kind; + +typedef struct Tftp_Action { + Tftp_Action_kind kind; + union { + struct { + int domain; + int type; + int protocol; + int result; + } socket; + struct { + int fd; + int result; + } close; + struct { + int fd; + int family; + uint16_t port; + const char *addr_str; + int result; + } bind; + struct { + int fd; + const void *buf; + size_t len; + int flags; + uint16_t dest_port; + const char *dest_addr_str; + int addrlen; + ssize_t result; + } sendto; + struct { + int fd; + void *buf; + size_t len; + int flags; + uint32_t timeout_ms; + uint16_t src_port; + char src_addr_str[TFTP_MAX_IP_ADDR_STRLEN]; + int addrlen; + ssize_t result; + } recvfrom; + } data; +} Tftp_Action; + +/** + * @brief Carry out interactions with TFTP client. + * + * @c Tftp_Interaction_fn() is called to + * + * * check that the fake network function has been called with the expected + * arguments (in @c act) + * * define values which shall be returned (to be stored in @c act) + * + * The function should not call @c T_assert_*() but use @c T_*(). + * Otherwise, it is unlikely that the test can terminate the client in + * @c teardown(). + * + * @param[in,out] act The actual arguments provided by the TFTP client + * to the network function. Moreover, storage to store the results + * to be returned to the TFTP client. + * @param data Arbitrary data area allocated when the interaction is created + * by @c _Tftp_Append_interaction() + * + * @retval true if the client behaved as expected. + * @retval false if the test shall fail. + */ +typedef bool (*Tftp_Interaction_fn)( Tftp_Action *act, void *data ); +typedef struct Tftp_Interaction Tftp_Interaction; +typedef struct Tftp_Interaction { + Tftp_Interaction *next; + Tftp_Action_kind kind; + Tftp_Interaction_fn fn; + void *data[0]; +} Tftp_Interaction; + +/** + * @brief Initialize and free the singleton control object. + * + * Invoke @c _Tftp_Reset() in @c setup() and @c teardown() of the test. + */ +void _Tftp_Reset( void ); + +/** + * @brief Create an interaction and append it to the sequence of expected + * interactions. + * + * This allocates memory for an interaction and additional specific data + * for the function @c fn() parameter @c data. The interaction is + * initialized and appended at the end of the sequence of expected interactions. + * If an error occurs a @c T_assert_*() macro is called. Hence, this function + * never returns @c NULL. + * + * @param kind Defines which interaction is expected. Note that it cannot + * happen that @c fn is called for a different network function. + * @param fn A function which is called to handle the interaction. + * See @c Tftp_Interaction_fn() + * @param size The size of a memory area which is given to @c fn() as + * @c data argument when it is invoked. This can be used to provide + * private data to the function. + * + * @return A pointer to a memory area of size @c size. The same pointer + * will be provided to @c fn as argument @c data when invoked. + */ +void *_Tftp_Append_interaction( + Tftp_Action_kind kind, + Tftp_Interaction_fn fn, + size_t size +); + + +/** + * @brief Have all queued interactions been processed? + * + * At the end of a test, it should be checked whether all queued interactions + * have been consumed by the TFTP client. + * + * @retval true All queued interactions have been processed. + * @retval false At least one queued interactions has not yet been processed. + */ +bool _Tftp_Has_no_more_interactions( void ); + +/* + * TFTP details from RFC1350, RFC2347, RFC2348 and RFC7440 + * + * Note: The RFCs require modes and options to be case in-sensitive. + */ + +#define TFTP_MODE_NETASCII "netascii" +#define TFTP_MODE_OCTET "octet" +#define TFTP_OPTION_BLKSIZE "blksize" +#define TFTP_OPTION_TIMEOUT "timeout" +#define TFTP_OPTION_TSIZE "tsize" +#define TFTP_OPTION_WINDOWSIZE "windowsize" + +#define TFTP_WINDOW_SIZE_MIN 1 +#define TFTP_BLOCK_SIZE_MIN 8 +#define TFTP_BLOCK_SIZE_MAX 65464 + +typedef enum Tftp_Opcode { + TFTP_OPCODE_RRQ = 1, + TFTP_OPCODE_WRQ = 2, + TFTP_OPCODE_DATA = 3, + TFTP_OPCODE_ACK = 4, + TFTP_OPCODE_ERROR = 5, + TFTP_OPCODE_OACK = 6, +} Tftp_Opcode; + +typedef enum Tftp_Error_code { + TFTP_ERROR_CODE_NOT_DEFINED = 0, + TFTP_ERROR_CODE_NOT_FOUND = 1, + TFTP_ERROR_CODE_NO_ACCESS = 2, + TFTP_ERROR_CODE_DISK_FULL = 3, + TFTP_ERROR_CODE_ILLEGAL = 4, + TFTP_ERROR_CODE_UNKNOWN_ID = 5, + TFTP_ERROR_CODE_FILE_EXISTS = 6, + TFTP_ERROR_CODE_NO_USER = 7, + TFTP_ERROR_CODE_OPTION_NEGO = 8, +} Tftp_Error_code; + +typedef struct Tftp_Packet { + uint16_t opcode; + union { + struct { + char opts[0]; + } rrq; + struct { + char opts[0]; + } wrq; + struct { + uint16_t block_num; + uint8_t bytes[0]; + } data; + struct { + uint16_t block_num; + } ack; + struct { + uint16_t error_code; + char err_msg[0]; + } error; + struct { + char opts[0]; + } oack; + } content; +} Tftp_Packet; + +/** + * @brief Provides a human readable description for an error code from an TFTP + * error packet. + * + * @param error_code The error code from the TFTP error packet in host byte + * order. + * + * @return A pointer to a string describing the error. If the error code is + * unknown, a pointer to "Unknown error code" is returned. Do not change the + * the string as a pointer to the very same string will be returned by future + * calls. + */ +const char *_Tftp_Get_error_str( uint16_t error_code ); + +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif /* _TFTPFS_UDP_NETWORK_FAKE_H */ |