+++ /dev/null
-/** @file\r
- Definitions for the TFTP server.\r
-\r
- Copyright (c) 2011, 2012, Intel Corporation. All rights reserved.\r
- SPDX-License-Identifier: BSD-2-Clause-Patent\r
-\r
-**/\r
-\r
-#ifndef _TFTP_SERVER_H_\r
-#define _TFTP_SERVER_H_\r
-\r
-#include <errno.h>\r
-#include <stdio.h>\r
-#include <stdlib.h>\r
-#include <string.h>\r
-#include <Uefi.h>\r
-\r
-#include <Guid/EventGroup.h>\r
-\r
-#include <Library/BaseMemoryLib.h>\r
-#include <Library/DebugLib.h>\r
-#include <Library/MemoryAllocationLib.h>\r
-#include <Library/PcdLib.h>\r
-#include <Library/TimerLib.h>\r
-#include <Library/UefiApplicationEntryPoint.h>\r
-#include <Library/UefiBootServicesTableLib.h>\r
-#include <Library/UefiLib.h>\r
-#include <Protocol/BlockIo.h>\r
-\r
-#include <netinet/in.h>\r
-#include <netinet6/in6.h>\r
-\r
-#include <sys/EfiSysCall.h>\r
-#include <sys/poll.h>\r
-#include <sys/socket.h>\r
-#include <sys/stat.h>\r
-\r
-//------------------------------------------------------------------------------\r
-// Macros\r
-//------------------------------------------------------------------------------\r
-\r
-#if defined(_MSC_VER) /* Handle Microsoft VC++ compiler specifics. */\r
-#define DBG_ENTER() DEBUG (( DEBUG_ENTER_EXIT, "Entering " __FUNCTION__ "\n" )) ///< Display routine entry\r
-#define DBG_EXIT() DEBUG (( DEBUG_ENTER_EXIT, "Exiting " __FUNCTION__ "\n" )) ///< Display routine exit\r
-#define DBG_EXIT_DEC(Status) DEBUG (( DEBUG_ENTER_EXIT, "Exiting " __FUNCTION__ ", Status: %d\n", Status )) ///< Display routine exit with decimal value\r
-#define DBG_EXIT_HEX(Status) DEBUG (( DEBUG_ENTER_EXIT, "Exiting " __FUNCTION__ ", Status: 0x%08x\n", Status )) ///< Display routine exit with hex value\r
-#define DBG_EXIT_STATUS(Status) DEBUG (( DEBUG_ENTER_EXIT, "Exiting " __FUNCTION__ ", Status: %r\n", Status )) ///< Display routine exit with status value\r
-#define DBG_EXIT_TF(Status) DEBUG (( DEBUG_ENTER_EXIT, "Exiting " __FUNCTION__ ", returning %s\n", (FALSE == Status) ? L"FALSE" : L"TRUE" )) ///< Display routine with TRUE/FALSE value\r
-#else // _MSC_VER\r
-#define DBG_ENTER()\r
-#define DBG_EXIT()\r
-#define DBG_EXIT_DEC(Status)\r
-#define DBG_EXIT_HEX(Status)\r
-#define DBG_EXIT_STATUS(Status)\r
-#define DBG_EXIT_TF(Status)\r
-#endif // _MSC_VER\r
-\r
-#define DIM(x) ( sizeof ( x ) / sizeof ( x[0] )) ///< Compute the number of entries in an array\r
-\r
-//------------------------------------------------------------------------------\r
-// Constants\r
-//------------------------------------------------------------------------------\r
-\r
-#define ACK_SHIFT 4 ///< Number of samples in ACK average\r
-\r
-#define DEBUG_WINDOW 0x00000001 ///< Display the window messages\r
-#define DEBUG_TX_PACKET 0x00000002 ///< Display the transmit packet messages\r
-#define DEBUG_FILE_BUFFER 0x00000004 ///< Display the file buffer messages\r
-#define DEBUG_SERVER_TIMER 0x00000008 ///< Display the socket poll messages\r
-#define DEBUG_TFTP_REQUEST 0x00000010 ///< Display the TFTP request messages\r
-#define DEBUG_PORT_WORK 0x00000020 ///< Display the port work messages\r
-#define DEBUG_SOCKET_POLL 0x00000040 ///< Display the socket poll messages\r
-#define DEBUG_TFTP_PORT 0x00000080 ///< Display the TFTP port messages\r
-#define DEBUG_TX 0x00000100 ///< Display transmit messages\r
-#define DEBUG_RX 0x00000200 ///< Display receive messages\r
-#define DEBUG_TFTP_ACK 0x00000400 ///< Display the TFTP ACK messages\r
-#define DEBUG_ENTER_EXIT 0x00000800 ///< Display entry and exit messages\r
-\r
-#define MAX_PACKETS 8 ///< Maximum number of packets in the window\r
-\r
-#define TFTP_PORT_POLL_DELAY ( 2 * 1000 ) ///< Delay in milliseconds for attempts to open the TFTP port\r
-#define CLIENT_POLL_DELAY 50 ///< Delay in milliseconds between client polls\r
-\r
-#define TPL_TFTP_SERVER TPL_CALLBACK ///< TPL for routine synchronization\r
-\r
-/**\r
- Verify new TPL value\r
-\r
- This macro which is enabled when debug is enabled verifies that\r
- the new TPL value is >= the current TPL value.\r
-**/\r
-#ifdef VERIFY_TPL\r
-#undef VERIFY_TPL\r
-#endif // VERIFY_TPL\r
-\r
-#if !defined(MDEPKG_NDEBUG)\r
-\r
-#define VERIFY_TPL(tpl) \\r
-{ \\r
- EFI_TPL PreviousTpl; \\r
- \\r
- PreviousTpl = gBS->RaiseTPL ( TPL_HIGH_LEVEL ); \\r
- gBS->RestoreTPL ( PreviousTpl ); \\r
- if ( PreviousTpl > tpl ) { \\r
- DEBUG (( DEBUG_ERROR, "Current TPL: %d, New TPL: %d\r\n", PreviousTpl, tpl )); \\r
- ASSERT ( PreviousTpl <= tpl ); \\r
- } \\r
-}\r
-\r
-#else // MDEPKG_NDEBUG\r
-\r
-#define VERIFY_TPL(tpl)\r
-\r
-#endif // MDEPKG_NDEBUG\r
-\r
-#define TFTP_SERVER_SIGNATURE SIGNATURE_32('T','F','T','P') ///< TSDT_TFTP_SERVER memory signature\r
-\r
-//\r
-// See: http://www.rfc-editor.org/rfc/pdfrfc/rfc1350.txt.pdf\r
-//\r
-// TFTP Operations\r
-//\r
-\r
-#define TFTP_OP_READ_REQUEST 1 ///< Read request, zero terminated file name, zero terminated mode\r
-#define TFTP_OP_WRITE_REQUEST 2 ///< Write request, zero terminated file name, zero terminated mode\r
-#define TFTP_OP_DATA 3 ///< Data block, end-of-file indicated by short block\r
-#define TFTP_OP_ACK 4 ///< ACK block number\r
-#define TFTP_OP_ERROR 5 ///< Error number and explaination\r
-#define TFTP_OP_OACK 6 ///< ACK the options\r
-\r
-#define TFTP_MAX_BLOCK_SIZE 4096 ///< Maximum block size\r
-\r
-#define TFTP_ERROR_SEE_MSG 0 ///< See the error message\r
-#define TFTP_ERROR_NOT_FOUND 1 ///< File not found\r
-#define TFTP_ERROR_ACCESS_VIOLATION 2 ///< Access violation\r
-#define TFTP_ERROR_DISK_FULL 3 ///< Disk full\r
-#define TFTP_ERROR_ILLEGAL_OP 4 ///< Illegal operation\r
-#define TFTP_ERROR_UNKNOWN_XFER_ID 5 ///< Unknown transfer ID\r
-#define TFTP_ERROR_FILE_EXISTS 6 ///< File already exists\r
-#define TFTP_ERROR_NO_SUCH_USER 7 ///< No such user\r
-\r
-//------------------------------------------------------------------------------\r
-// Data Types\r
-//------------------------------------------------------------------------------\r
-\r
-/**\r
- Packet structure\r
-**/\r
-typedef struct _TFTP_PACKET TFTP_PACKET;\r
-typedef struct _TFTP_PACKET {\r
- TFTP_PACKET * pNext; ///< Next packet in list\r
- UINT64 TxTime; ///< Time the transmit was performed\r
- ssize_t TxBytes; ///< Bytes in the TX buffer\r
- UINT32 RetryCount; ///< Number of transmissions\r
- UINT16 BlockNumber; ///< Block number of this packet\r
- UINT8 TxBuffer[ 2 + 2 + TFTP_MAX_BLOCK_SIZE ]; ///< Transmit buffer\r
-} GCC_TFTP_PACKET;\r
-\r
-/**\r
- Port control structure\r
-**/\r
-typedef struct _TSDT_CONNECTION_CONTEXT TSDT_CONNECTION_CONTEXT;\r
-typedef struct _TSDT_CONNECTION_CONTEXT {\r
- //\r
- // Remote connection management\r
- //\r
- TSDT_CONNECTION_CONTEXT * pNext; ///< Next context in the connection list\r
- struct sockaddr_in6 RemoteAddress; ///< Remote address\r
- int SocketFd; ///< Socket file descriptor\r
-\r
- //\r
- // File management parameters\r
- //\r
- FILE * File; ///< NULL while file is closed\r
- UINT64 LengthInBytes; ///< Size of the file\r
- UINT64 BytesRemaining; ///< Number of bytes remaining to be sent\r
- UINT64 BytesToSend; ///< Number of bytes to send\r
- UINT64 ValidBytes; ///< Number of valid bytes in the buffer\r
- BOOLEAN bEofSent; ///< End of file sent\r
- UINT8 * pFill; ///< Next portion of the buffer to fill\r
- UINT8 * pBuffer; ///< Pointer into the file data\r
- UINT8 * pEnd; ///< End of the file data\r
- UINT8 FileData[ 2 * MAX_PACKETS * TFTP_MAX_BLOCK_SIZE ]; ///< File data to send\r
- UINT64 TimeStart; ///< Start of file transfer\r
-\r
- //\r
- // TFTP management parameters\r
- //\r
- UINT16 BlockNumber; ///< Next block to be transmitted\r
- UINT32 BlockSize; ///< Negotiated block size\r
-\r
- //\r
- // Window management\r
- //\r
- UINT32 AckCount; ///< Number of ACKs to receive before increasing the window\r
- UINT32 PacketsInWindow; ///< Number of packets in the window\r
- UINT32 Threshold; ///< Size of window when ACK count becomes logrithmic\r
- UINT32 WindowSize; ///< Size of the transmit window\r
- UINT64 MaxTimeout; ///< Maximum number of seconds to wait before retransmission\r
- UINT64 Rtt2x; ///< Twice the average round trip time in nanoseconds\r
-\r
- //\r
- // Buffer management\r
- //\r
- TFTP_PACKET * pFreeList; ///< List of free packets\r
- TFTP_PACKET * pTxHead; ///< First packet in the list of packets for transmission\r
- TFTP_PACKET * pTxTail; ///< Last packet in the list of packets for transmission\r
- TFTP_PACKET ErrorPacket; ///< Error packet\r
- TFTP_PACKET Tx[ MAX_PACKETS ];///< Transmit packets\r
-}GCC_TSDT_CONNECTION_CONTEXT;\r
-\r
-/**\r
- TFTP server control structure\r
-**/\r
-typedef struct {\r
- UINTN Signature; ///< Structure identification\r
-\r
- //\r
- // Image attributes\r
- //\r
- EFI_HANDLE ImageHandle; ///< Image handle\r
-\r
- //\r
- // Performance management\r
- //\r
- UINT64 ClockFrequency; ///< Frequency of the clock\r
- UINT64 Time1; ///< Clock value after rollover\r
- UINT64 Time2; ///< Clock value before rollover\r
- UINT64 RxTime; ///< Time when the packet was recevied\r
-\r
- //\r
- // TFTP port management\r
- //\r
- EFI_EVENT TimerEvent; ///< Timer to open TFTP port\r
- int Udpv4Index; ///< Entry for UDPv4\r
- int Udpv6Index; ///< Entry for UDPv6\r
- int Entries; ///< Number of TFTP ports\r
- struct pollfd TftpPort [ 2 ]; ///< Poll descriptor for the TFTP ports (UDP4, UDP6)\r
-\r
- //\r
- // Request management\r
- //\r
- union {\r
- struct sockaddr_in v4; ///< UDP4 address\r
- struct sockaddr_in6 v6; ///< UDP6 address\r
- } RemoteAddress; ///< Remote address\r
- ssize_t RxBytes; ///< Receive data length in bytes\r
- UINT8 RxBuffer[ 2 + 2 + TFTP_MAX_BLOCK_SIZE ]; ///< Receive buffer\r
-\r
- //\r
- // Client port management\r
- //\r
- TSDT_CONNECTION_CONTEXT * pContextList; ///< List of connection context structures\r
-} TSDT_TFTP_SERVER;\r
-\r
-//#define SERVER_FROM_SERVICE(a) CR(a, TSDT_TFTP_SERVER, ServiceBinding, TFTP_SERVER_SIGNATURE) ///< Locate DT_LAYER from service binding\r
-\r
-extern TSDT_TFTP_SERVER mTftpServer;\r
-\r
-//------------------------------------------------------------------------------\r
-// Support routines\r
-//------------------------------------------------------------------------------\r
-\r
-/**\r
- Queue data packets for transmission\r
-\r
- @param [in] pContext Connection context structure address\r
-\r
- @retval TRUE if a read error occurred\r
-\r
-**/\r
-BOOLEAN\r
-PacketFill (\r
- IN TSDT_CONNECTION_CONTEXT * pContext\r
- );\r
-\r
-/**\r
- Free the packet\r
-\r
- @param [in] pContext Address of a ::TSDT_CONNECTION_CONTEXT structure\r
- @param [in] pPacket Address of a ::TFTP_PACKET structure\r
-\r
-**/\r
-VOID\r
-PacketFree(\r
- IN TSDT_CONNECTION_CONTEXT * pContext,\r
- IN TFTP_PACKET * pPacket\r
- );\r
-\r
-/**\r
- Get a packet for transmission\r
-\r
- @param [in] pContext Address of a ::TSDT_CONNECTION_CONTEXT structure\r
-\r
- @retval Address of a ::TFTP_PACKET structure\r
-\r
-**/\r
-TFTP_PACKET *\r
-PacketGet (\r
- IN TSDT_CONNECTION_CONTEXT * pContext\r
- );\r
-\r
-/**\r
- Queue the packet for transmission\r
-\r
- @param [in] pContext Address of a ::TSDT_CONNECTION_CONTEXT structure\r
- @param [in] pPacket Address of a ::TFTP_PACKET structure\r
-\r
- @retval TRUE if a transmission error has occurred\r
-\r
-**/\r
-BOOLEAN\r
-PacketQueue (\r
- IN TSDT_CONNECTION_CONTEXT * pContext,\r
- IN TFTP_PACKET * pPacket\r
- );\r
-\r
-/**\r
- Transmit the packet\r
-\r
- @param [in] pContext Address of a ::TSDT_CONNECTION_CONTEXT structure\r
- @param [in] pPacket Address of a ::TFTP_PACKET structure\r
-\r
- @retval EFI_SUCCESS Message processed successfully\r
-\r
-**/\r
-EFI_STATUS\r
-PacketTx (\r
- IN TSDT_CONNECTION_CONTEXT * pContext,\r
- IN TFTP_PACKET * pPacket\r
- );\r
-\r
-/**\r
- Build and send an error packet\r
-\r
- @param [in] pContext The context structure address.\r
- @param [in] Error Error number for the packet\r
- @param [in] pError Zero terminated error string address\r
-\r
- @retval EFI_SUCCESS Message processed successfully\r
-\r
-**/\r
-EFI_STATUS\r
-SendError (\r
- IN TSDT_CONNECTION_CONTEXT * pContext,\r
- IN UINT16 Error,\r
- IN UINT8 * pError\r
- );\r
-\r
-/**\r
- Process the TFTP request\r
-\r
- @param [in] pOption Address of the first zero terminated option string\r
- @param [in] pValue Address to receive the value\r
-\r
- @retval EFI_SUCCESS Option translated into a value\r
-\r
-**/\r
-EFI_STATUS\r
-TftpOptionValue (\r
- IN UINT8 * pOption,\r
- IN INT32 * pValue\r
- );\r
-\r
-/**\r
- Process the TFTP request\r
-\r
- @param [in] pTftpServer The TFTP server control structure address.\r
- @param [in] pContext Connection context structure address\r
- @param [in] SocketFd Socket file descriptor\r
-\r
-**/\r
-VOID\r
-TftpProcessRequest (\r
- IN TSDT_TFTP_SERVER * pTftpServer,\r
- IN TSDT_CONNECTION_CONTEXT * pContext,\r
- IN int SocketFd\r
- );\r
-\r
-/**\r
- Process the read request\r
-\r
- @param [in] pTftpServer Address of the ::TSDT_TFTP_SERVER structure\r
- @param [in] pContext Connection context structure address\r
- @param [in] SocketFd Socket file descriptor\r
-\r
- @retval TRUE if the context should be closed\r
-\r
-**/\r
-BOOLEAN\r
-TftpRead (\r
- IN TSDT_TFTP_SERVER * pTftpServer,\r
- IN TSDT_CONNECTION_CONTEXT * pContext,\r
- IN int SocketFd\r
- );\r
-\r
-/**\r
- Update the window due to the ACK\r
-\r
- @param [in] pTftpServer Address of the ::TSDT_TFTP_SERVER structure\r
- @param [in] pContext Address of a ::TSDT_CONNECTION_CONTEXT structure\r
- @param [in] pPacket Address of a ::TFTP_PACKET structure\r
-\r
-**/\r
-VOID\r
-WindowAck (\r
- IN TSDT_TFTP_SERVER * pTftpServer,\r
- IN TSDT_CONNECTION_CONTEXT * pContext,\r
- IN TFTP_PACKET * pPacket\r
- );\r
-\r
-/**\r
- A timeout has occurred, close the window\r
-\r
- @param [in] pContext Address of a ::TSDT_CONNECTION_CONTEXT structure\r
-\r
-**/\r
-VOID\r
-WindowTimeout (\r
- IN TSDT_CONNECTION_CONTEXT * pContext\r
- );\r
-\r
-//------------------------------------------------------------------------------\r
-\r
-#endif // _TFTP_SERVER_H_\r