2 Definitions for the TFTP server.
4 Copyright (c) 2011, 2012, Intel Corporation
5 All rights reserved. This program and the accompanying materials
6 are licensed and made available under the terms and conditions of the BSD License
7 which accompanies this distribution. The full text of the license may be found at
8 http://opensource.org/licenses/bsd-license.php
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
15 #ifndef _TFTP_SERVER_H_
16 #define _TFTP_SERVER_H_
24 #include <Guid/EventGroup.h>
26 #include <Library/BaseMemoryLib.h>
27 #include <Library/DebugLib.h>
28 #include <Library/MemoryAllocationLib.h>
29 #include <Library/PcdLib.h>
30 #include <Library/TimerLib.h>
31 #include <Library/UefiApplicationEntryPoint.h>
32 #include <Library/UefiBootServicesTableLib.h>
33 #include <Library/UefiLib.h>
34 #include <Protocol/BlockIo.h>
36 #include <netinet/in.h>
37 #include <netinet6/in6.h>
39 #include <sys/EfiSysCall.h>
41 #include <sys/socket.h>
44 //------------------------------------------------------------------------------
46 //------------------------------------------------------------------------------
48 #if defined(_MSC_VER) /* Handle Microsoft VC++ compiler specifics. */
49 #define DBG_ENTER() DEBUG (( DEBUG_ENTER_EXIT, "Entering " __FUNCTION__ "\n" )) ///< Display routine entry
50 #define DBG_EXIT() DEBUG (( DEBUG_ENTER_EXIT, "Exiting " __FUNCTION__ "\n" )) ///< Display routine exit
51 #define DBG_EXIT_DEC(Status) DEBUG (( DEBUG_ENTER_EXIT, "Exiting " __FUNCTION__ ", Status: %d\n", Status )) ///< Display routine exit with decimal value
52 #define DBG_EXIT_HEX(Status) DEBUG (( DEBUG_ENTER_EXIT, "Exiting " __FUNCTION__ ", Status: 0x%08x\n", Status )) ///< Display routine exit with hex value
53 #define DBG_EXIT_STATUS(Status) DEBUG (( DEBUG_ENTER_EXIT, "Exiting " __FUNCTION__ ", Status: %r\n", Status )) ///< Display routine exit with status value
54 #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
58 #define DBG_EXIT_DEC(Status)
59 #define DBG_EXIT_HEX(Status)
60 #define DBG_EXIT_STATUS(Status)
61 #define DBG_EXIT_TF(Status)
64 #define DIM(x) ( sizeof ( x ) / sizeof ( x[0] )) ///< Compute the number of entries in an array
66 //------------------------------------------------------------------------------
68 //------------------------------------------------------------------------------
70 #define ACK_SHIFT 4 ///< Number of samples in ACK average
72 #define DEBUG_WINDOW 0x00000001 ///< Display the window messages
73 #define DEBUG_TX_PACKET 0x00000002 ///< Display the transmit packet messages
74 #define DEBUG_FILE_BUFFER 0x00000004 ///< Display the file buffer messages
75 #define DEBUG_SERVER_TIMER 0x00000008 ///< Display the socket poll messages
76 #define DEBUG_TFTP_REQUEST 0x00000010 ///< Display the TFTP request messages
77 #define DEBUG_PORT_WORK 0x00000020 ///< Display the port work messages
78 #define DEBUG_SOCKET_POLL 0x00000040 ///< Display the socket poll messages
79 #define DEBUG_TFTP_PORT 0x00000080 ///< Display the TFTP port messages
80 #define DEBUG_TX 0x00000100 ///< Display transmit messages
81 #define DEBUG_RX 0x00000200 ///< Display receive messages
82 #define DEBUG_TFTP_ACK 0x00000400 ///< Display the TFTP ACK messages
83 #define DEBUG_ENTER_EXIT 0x00000800 ///< Display entry and exit messages
85 #define MAX_PACKETS 8 ///< Maximum number of packets in the window
87 #define TFTP_PORT_POLL_DELAY ( 2 * 1000 ) ///< Delay in milliseconds for attempts to open the TFTP port
88 #define CLIENT_POLL_DELAY 50 ///< Delay in milliseconds between client polls
90 #define TPL_TFTP_SERVER TPL_CALLBACK ///< TPL for routine synchronization
95 This macro which is enabled when debug is enabled verifies that
96 the new TPL value is >= the current TPL value.
102 #if !defined(MDEPKG_NDEBUG)
104 #define VERIFY_TPL(tpl) \
106 EFI_TPL PreviousTpl; \
108 PreviousTpl = gBS->RaiseTPL ( TPL_HIGH_LEVEL ); \
109 gBS->RestoreTPL ( PreviousTpl ); \
110 if ( PreviousTpl > tpl ) { \
111 DEBUG (( DEBUG_ERROR, "Current TPL: %d, New TPL: %d\r\n", PreviousTpl, tpl )); \
112 ASSERT ( PreviousTpl <= tpl ); \
116 #else // MDEPKG_NDEBUG
118 #define VERIFY_TPL(tpl)
120 #endif // MDEPKG_NDEBUG
122 #define TFTP_SERVER_SIGNATURE SIGNATURE_32('T','F','T','P') ///< TSDT_TFTP_SERVER memory signature
125 // See: http://www.rfc-editor.org/rfc/pdfrfc/rfc1350.txt.pdf
130 #define TFTP_OP_READ_REQUEST 1 ///< Read request, zero terminated file name, zero terminated mode
131 #define TFTP_OP_WRITE_REQUEST 2 ///< Write request, zero terminated file name, zero terminated mode
132 #define TFTP_OP_DATA 3 ///< Data block, end-of-file indicated by short block
133 #define TFTP_OP_ACK 4 ///< ACK block number
134 #define TFTP_OP_ERROR 5 ///< Error number and explaination
135 #define TFTP_OP_OACK 6 ///< ACK the options
137 #define TFTP_MAX_BLOCK_SIZE 4096 ///< Maximum block size
139 #define TFTP_ERROR_SEE_MSG 0 ///< See the error message
140 #define TFTP_ERROR_NOT_FOUND 1 ///< File not found
141 #define TFTP_ERROR_ACCESS_VIOLATION 2 ///< Access violation
142 #define TFTP_ERROR_DISK_FULL 3 ///< Disk full
143 #define TFTP_ERROR_ILLEGAL_OP 4 ///< Illegal operation
144 #define TFTP_ERROR_UNKNOWN_XFER_ID 5 ///< Unknown transfer ID
145 #define TFTP_ERROR_FILE_EXISTS 6 ///< File already exists
146 #define TFTP_ERROR_NO_SUCH_USER 7 ///< No such user
148 //------------------------------------------------------------------------------
150 //------------------------------------------------------------------------------
155 typedef struct _TFTP_PACKET TFTP_PACKET
;
156 typedef struct _TFTP_PACKET
{
157 TFTP_PACKET
* pNext
; ///< Next packet in list
158 UINT64 TxTime
; ///< Time the transmit was performed
159 ssize_t TxBytes
; ///< Bytes in the TX buffer
160 UINT32 RetryCount
; ///< Number of transmissions
161 UINT16 BlockNumber
; ///< Block number of this packet
162 UINT8 TxBuffer
[ 2 + 2 + TFTP_MAX_BLOCK_SIZE
]; ///< Transmit buffer
166 Port control structure
168 typedef struct _TSDT_CONNECTION_CONTEXT TSDT_CONNECTION_CONTEXT
;
169 typedef struct _TSDT_CONNECTION_CONTEXT
{
171 // Remote connection management
173 TSDT_CONNECTION_CONTEXT
* pNext
; ///< Next context in the connection list
174 struct sockaddr_in6 RemoteAddress
; ///< Remote address
175 int SocketFd
; ///< Socket file descriptor
178 // File management parameters
180 FILE * File
; ///< NULL while file is closed
181 UINT64 LengthInBytes
; ///< Size of the file
182 UINT64 BytesRemaining
; ///< Number of bytes remaining to be sent
183 UINT64 BytesToSend
; ///< Number of bytes to send
184 UINT64 ValidBytes
; ///< Number of valid bytes in the buffer
185 BOOLEAN bEofSent
; ///< End of file sent
186 UINT8
* pFill
; ///< Next portion of the buffer to fill
187 UINT8
* pBuffer
; ///< Pointer into the file data
188 UINT8
* pEnd
; ///< End of the file data
189 UINT8 FileData
[ 2 * MAX_PACKETS
* TFTP_MAX_BLOCK_SIZE
]; ///< File data to send
190 UINT64 TimeStart
; ///< Start of file transfer
193 // TFTP management parameters
195 UINT16 BlockNumber
; ///< Next block to be transmitted
196 UINT32 BlockSize
; ///< Negotiated block size
201 UINT32 AckCount
; ///< Number of ACKs to receive before increasing the window
202 UINT32 PacketsInWindow
; ///< Number of packets in the window
203 UINT32 Threshold
; ///< Size of window when ACK count becomes logrithmic
204 UINT32 WindowSize
; ///< Size of the transmit window
205 UINT64 MaxTimeout
; ///< Maximum number of seconds to wait before retransmission
206 UINT64 Rtt2x
; ///< Twice the average round trip time in nanoseconds
211 TFTP_PACKET
* pFreeList
; ///< List of free packets
212 TFTP_PACKET
* pTxHead
; ///< First packet in the list of packets for transmission
213 TFTP_PACKET
* pTxTail
; ///< Last packet in the list of packets for transmission
214 TFTP_PACKET ErrorPacket
; ///< Error packet
215 TFTP_PACKET Tx
[ MAX_PACKETS
];///< Transmit packets
216 }GCC_TSDT_CONNECTION_CONTEXT
;
219 TFTP server control structure
222 UINTN Signature
; ///< Structure identification
227 EFI_HANDLE ImageHandle
; ///< Image handle
230 // Performance management
232 UINT64 ClockFrequency
; ///< Frequency of the clock
233 UINT64 Time1
; ///< Clock value after rollover
234 UINT64 Time2
; ///< Clock value before rollover
235 UINT64 RxTime
; ///< Time when the packet was recevied
238 // TFTP port management
240 EFI_EVENT TimerEvent
; ///< Timer to open TFTP port
241 int Udpv4Index
; ///< Entry for UDPv4
242 int Udpv6Index
; ///< Entry for UDPv6
243 int Entries
; ///< Number of TFTP ports
244 struct pollfd TftpPort
[ 2 ]; ///< Poll descriptor for the TFTP ports (UDP4, UDP6)
247 // Request management
250 struct sockaddr_in v4
; ///< UDP4 address
251 struct sockaddr_in6 v6
; ///< UDP6 address
252 } RemoteAddress
; ///< Remote address
253 ssize_t RxBytes
; ///< Receive data length in bytes
254 UINT8 RxBuffer
[ 2 + 2 + TFTP_MAX_BLOCK_SIZE
]; ///< Receive buffer
257 // Client port management
259 TSDT_CONNECTION_CONTEXT
* pContextList
; ///< List of connection context structures
262 //#define SERVER_FROM_SERVICE(a) CR(a, TSDT_TFTP_SERVER, ServiceBinding, TFTP_SERVER_SIGNATURE) ///< Locate DT_LAYER from service binding
264 extern TSDT_TFTP_SERVER mTftpServer
;
266 //------------------------------------------------------------------------------
268 //------------------------------------------------------------------------------
271 Queue data packets for transmission
273 @param [in] pContext Connection context structure address
275 @retval TRUE if a read error occurred
280 IN TSDT_CONNECTION_CONTEXT
* pContext
286 @param [in] pContext Address of a ::TSDT_CONNECTION_CONTEXT structure
287 @param [in] pPacket Address of a ::TFTP_PACKET structure
292 IN TSDT_CONNECTION_CONTEXT
* pContext
,
293 IN TFTP_PACKET
* pPacket
297 Get a packet for transmission
299 @param [in] pContext Address of a ::TSDT_CONNECTION_CONTEXT structure
301 @retval Address of a ::TFTP_PACKET structure
306 IN TSDT_CONNECTION_CONTEXT
* pContext
310 Queue the packet for transmission
312 @param [in] pContext Address of a ::TSDT_CONNECTION_CONTEXT structure
313 @param [in] pPacket Address of a ::TFTP_PACKET structure
315 @retval TRUE if a transmission error has occurred
320 IN TSDT_CONNECTION_CONTEXT
* pContext
,
321 IN TFTP_PACKET
* pPacket
327 @param [in] pContext Address of a ::TSDT_CONNECTION_CONTEXT structure
328 @param [in] pPacket Address of a ::TFTP_PACKET structure
330 @retval EFI_SUCCESS Message processed successfully
335 IN TSDT_CONNECTION_CONTEXT
* pContext
,
336 IN TFTP_PACKET
* pPacket
340 Build and send an error packet
342 @param [in] pContext The context structure address.
343 @param [in] Error Error number for the packet
344 @param [in] pError Zero terminated error string address
346 @retval EFI_SUCCESS Message processed successfully
351 IN TSDT_CONNECTION_CONTEXT
* pContext
,
357 Process the TFTP request
359 @param [in] pOption Address of the first zero terminated option string
360 @param [in] pValue Address to receive the value
362 @retval EFI_SUCCESS Option translated into a value
372 Process the TFTP request
374 @param [in] pTftpServer The TFTP server control structure address.
375 @param [in] pContext Connection context structure address
376 @param [in] SocketFd Socket file descriptor
381 IN TSDT_TFTP_SERVER
* pTftpServer
,
382 IN TSDT_CONNECTION_CONTEXT
* pContext
,
387 Process the read request
389 @param [in] pTftpServer Address of the ::TSDT_TFTP_SERVER structure
390 @param [in] pContext Connection context structure address
391 @param [in] SocketFd Socket file descriptor
393 @retval TRUE if the context should be closed
398 IN TSDT_TFTP_SERVER
* pTftpServer
,
399 IN TSDT_CONNECTION_CONTEXT
* pContext
,
404 Update the window due to the ACK
406 @param [in] pTftpServer Address of the ::TSDT_TFTP_SERVER structure
407 @param [in] pContext Address of a ::TSDT_CONNECTION_CONTEXT structure
408 @param [in] pPacket Address of a ::TFTP_PACKET structure
413 IN TSDT_TFTP_SERVER
* pTftpServer
,
414 IN TSDT_CONNECTION_CONTEXT
* pContext
,
415 IN TFTP_PACKET
* pPacket
419 A timeout has occurred, close the window
421 @param [in] pContext Address of a ::TSDT_CONNECTION_CONTEXT structure
426 IN TSDT_CONNECTION_CONTEXT
* pContext
429 //------------------------------------------------------------------------------
431 #endif // _TFTP_SERVER_H_