]> git.proxmox.com Git - mirror_edk2.git/blame - AppPkg/Applications/Sockets/TftpServer/TftpServer.h
AppPkg: Replace BSD License with BSD+Patent License
[mirror_edk2.git] / AppPkg / Applications / Sockets / TftpServer / TftpServer.h
CommitLineData
4684b66f 1/** @file\r
2 Definitions for the TFTP server.\r
3\r
bcb96695
MK
4 Copyright (c) 2011, 2012, Intel Corporation. All rights reserved.\r
5 SPDX-License-Identifier: BSD-2-Clause-Patent\r
4684b66f 6\r
7**/\r
8\r
9#ifndef _TFTP_SERVER_H_\r
10#define _TFTP_SERVER_H_\r
11\r
12#include <errno.h>\r
f6e5cdd5 13#include <stdio.h>\r
4684b66f 14#include <stdlib.h>\r
15#include <string.h>\r
16#include <Uefi.h>\r
17\r
18#include <Guid/EventGroup.h>\r
19\r
20#include <Library/BaseMemoryLib.h>\r
21#include <Library/DebugLib.h>\r
f6e5cdd5 22#include <Library/MemoryAllocationLib.h>\r
4684b66f 23#include <Library/PcdLib.h>\r
f6e5cdd5 24#include <Library/TimerLib.h>\r
4684b66f 25#include <Library/UefiApplicationEntryPoint.h>\r
26#include <Library/UefiBootServicesTableLib.h>\r
27#include <Library/UefiLib.h>\r
28#include <Protocol/BlockIo.h>\r
29\r
30#include <netinet/in.h>\r
f6e5cdd5 31#include <netinet6/in6.h>\r
4684b66f 32\r
33#include <sys/EfiSysCall.h>\r
34#include <sys/poll.h>\r
35#include <sys/socket.h>\r
460f337b 36#include <sys/stat.h>\r
4684b66f 37\r
38//------------------------------------------------------------------------------\r
39// Macros\r
40//------------------------------------------------------------------------------\r
41\r
42#if defined(_MSC_VER) /* Handle Microsoft VC++ compiler specifics. */\r
f6e5cdd5 43#define DBG_ENTER() DEBUG (( DEBUG_ENTER_EXIT, "Entering " __FUNCTION__ "\n" )) ///< Display routine entry\r
44#define DBG_EXIT() DEBUG (( DEBUG_ENTER_EXIT, "Exiting " __FUNCTION__ "\n" )) ///< Display routine exit\r
45#define DBG_EXIT_DEC(Status) DEBUG (( DEBUG_ENTER_EXIT, "Exiting " __FUNCTION__ ", Status: %d\n", Status )) ///< Display routine exit with decimal value\r
46#define DBG_EXIT_HEX(Status) DEBUG (( DEBUG_ENTER_EXIT, "Exiting " __FUNCTION__ ", Status: 0x%08x\n", Status )) ///< Display routine exit with hex value\r
47#define DBG_EXIT_STATUS(Status) DEBUG (( DEBUG_ENTER_EXIT, "Exiting " __FUNCTION__ ", Status: %r\n", Status )) ///< Display routine exit with status value\r
48#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
4684b66f 49#else // _MSC_VER\r
50#define DBG_ENTER()\r
51#define DBG_EXIT()\r
52#define DBG_EXIT_DEC(Status)\r
53#define DBG_EXIT_HEX(Status)\r
54#define DBG_EXIT_STATUS(Status)\r
55#define DBG_EXIT_TF(Status)\r
56#endif // _MSC_VER\r
57\r
58#define DIM(x) ( sizeof ( x ) / sizeof ( x[0] )) ///< Compute the number of entries in an array\r
59\r
60//------------------------------------------------------------------------------\r
61// Constants\r
62//------------------------------------------------------------------------------\r
63\r
f6e5cdd5 64#define ACK_SHIFT 4 ///< Number of samples in ACK average\r
65\r
66#define DEBUG_WINDOW 0x00000001 ///< Display the window messages\r
67#define DEBUG_TX_PACKET 0x00000002 ///< Display the transmit packet messages\r
68#define DEBUG_FILE_BUFFER 0x00000004 ///< Display the file buffer messages\r
69#define DEBUG_SERVER_TIMER 0x00000008 ///< Display the socket poll messages\r
70#define DEBUG_TFTP_REQUEST 0x00000010 ///< Display the TFTP request messages\r
71#define DEBUG_PORT_WORK 0x00000020 ///< Display the port work messages\r
72#define DEBUG_SOCKET_POLL 0x00000040 ///< Display the socket poll messages\r
73#define DEBUG_TFTP_PORT 0x00000080 ///< Display the TFTP port messages\r
74#define DEBUG_TX 0x00000100 ///< Display transmit messages\r
75#define DEBUG_RX 0x00000200 ///< Display receive messages\r
76#define DEBUG_TFTP_ACK 0x00000400 ///< Display the TFTP ACK messages\r
77#define DEBUG_ENTER_EXIT 0x00000800 ///< Display entry and exit messages\r
78\r
79#define MAX_PACKETS 8 ///< Maximum number of packets in the window\r
4684b66f 80\r
81#define TFTP_PORT_POLL_DELAY ( 2 * 1000 ) ///< Delay in milliseconds for attempts to open the TFTP port\r
82#define CLIENT_POLL_DELAY 50 ///< Delay in milliseconds between client polls\r
83\r
84#define TPL_TFTP_SERVER TPL_CALLBACK ///< TPL for routine synchronization\r
85\r
86/**\r
87 Verify new TPL value\r
88\r
89 This macro which is enabled when debug is enabled verifies that\r
90 the new TPL value is >= the current TPL value.\r
91**/\r
92#ifdef VERIFY_TPL\r
93#undef VERIFY_TPL\r
94#endif // VERIFY_TPL\r
95\r
96#if !defined(MDEPKG_NDEBUG)\r
97\r
98#define VERIFY_TPL(tpl) \\r
99{ \\r
100 EFI_TPL PreviousTpl; \\r
101 \\r
102 PreviousTpl = gBS->RaiseTPL ( TPL_HIGH_LEVEL ); \\r
103 gBS->RestoreTPL ( PreviousTpl ); \\r
104 if ( PreviousTpl > tpl ) { \\r
105 DEBUG (( DEBUG_ERROR, "Current TPL: %d, New TPL: %d\r\n", PreviousTpl, tpl )); \\r
106 ASSERT ( PreviousTpl <= tpl ); \\r
107 } \\r
108}\r
109\r
110#else // MDEPKG_NDEBUG\r
111\r
112#define VERIFY_TPL(tpl)\r
113\r
114#endif // MDEPKG_NDEBUG\r
115\r
116#define TFTP_SERVER_SIGNATURE SIGNATURE_32('T','F','T','P') ///< TSDT_TFTP_SERVER memory signature\r
117\r
118//\r
119// See: http://www.rfc-editor.org/rfc/pdfrfc/rfc1350.txt.pdf\r
120//\r
121// TFTP Operations\r
122//\r
123\r
124#define TFTP_OP_READ_REQUEST 1 ///< Read request, zero terminated file name, zero terminated mode\r
125#define TFTP_OP_WRITE_REQUEST 2 ///< Write request, zero terminated file name, zero terminated mode\r
126#define TFTP_OP_DATA 3 ///< Data block, end-of-file indicated by short block\r
127#define TFTP_OP_ACK 4 ///< ACK block number\r
128#define TFTP_OP_ERROR 5 ///< Error number and explaination\r
129#define TFTP_OP_OACK 6 ///< ACK the options\r
130\r
131#define TFTP_MAX_BLOCK_SIZE 4096 ///< Maximum block size\r
132\r
f6e5cdd5 133#define TFTP_ERROR_SEE_MSG 0 ///< See the error message\r
134#define TFTP_ERROR_NOT_FOUND 1 ///< File not found\r
135#define TFTP_ERROR_ACCESS_VIOLATION 2 ///< Access violation\r
136#define TFTP_ERROR_DISK_FULL 3 ///< Disk full\r
137#define TFTP_ERROR_ILLEGAL_OP 4 ///< Illegal operation\r
138#define TFTP_ERROR_UNKNOWN_XFER_ID 5 ///< Unknown transfer ID\r
139#define TFTP_ERROR_FILE_EXISTS 6 ///< File already exists\r
140#define TFTP_ERROR_NO_SUCH_USER 7 ///< No such user\r
141\r
4684b66f 142//------------------------------------------------------------------------------\r
143// Data Types\r
144//------------------------------------------------------------------------------\r
145\r
f6e5cdd5 146/**\r
147 Packet structure\r
148**/\r
149typedef struct _TFTP_PACKET TFTP_PACKET;\r
150typedef struct _TFTP_PACKET {\r
151 TFTP_PACKET * pNext; ///< Next packet in list\r
152 UINT64 TxTime; ///< Time the transmit was performed\r
153 ssize_t TxBytes; ///< Bytes in the TX buffer\r
154 UINT32 RetryCount; ///< Number of transmissions\r
155 UINT16 BlockNumber; ///< Block number of this packet\r
156 UINT8 TxBuffer[ 2 + 2 + TFTP_MAX_BLOCK_SIZE ]; ///< Transmit buffer\r
157} GCC_TFTP_PACKET;\r
158\r
4684b66f 159/**\r
160 Port control structure\r
161**/\r
162typedef struct _TSDT_CONNECTION_CONTEXT TSDT_CONNECTION_CONTEXT;\r
163typedef struct _TSDT_CONNECTION_CONTEXT {\r
164 //\r
165 // Remote connection management\r
166 //\r
f6e5cdd5 167 TSDT_CONNECTION_CONTEXT * pNext; ///< Next context in the connection list\r
168 struct sockaddr_in6 RemoteAddress; ///< Remote address\r
169 int SocketFd; ///< Socket file descriptor\r
4684b66f 170\r
171 //\r
172 // File management parameters\r
173 //\r
f6e5cdd5 174 FILE * File; ///< NULL while file is closed\r
4684b66f 175 UINT64 LengthInBytes; ///< Size of the file\r
f6e5cdd5 176 UINT64 BytesRemaining; ///< Number of bytes remaining to be sent\r
177 UINT64 BytesToSend; ///< Number of bytes to send\r
178 UINT64 ValidBytes; ///< Number of valid bytes in the buffer\r
4684b66f 179 BOOLEAN bEofSent; ///< End of file sent\r
f6e5cdd5 180 UINT8 * pFill; ///< Next portion of the buffer to fill\r
4684b66f 181 UINT8 * pBuffer; ///< Pointer into the file data\r
182 UINT8 * pEnd; ///< End of the file data\r
f6e5cdd5 183 UINT8 FileData[ 2 * MAX_PACKETS * TFTP_MAX_BLOCK_SIZE ]; ///< File data to send\r
184 UINT64 TimeStart; ///< Start of file transfer\r
185\r
186 //\r
187 // TFTP management parameters\r
188 //\r
189 UINT16 BlockNumber; ///< Next block to be transmitted\r
190 UINT32 BlockSize; ///< Negotiated block size\r
191\r
192 //\r
193 // Window management\r
194 //\r
195 UINT32 AckCount; ///< Number of ACKs to receive before increasing the window\r
196 UINT32 PacketsInWindow; ///< Number of packets in the window\r
197 UINT32 Threshold; ///< Size of window when ACK count becomes logrithmic\r
198 UINT32 WindowSize; ///< Size of the transmit window\r
199 UINT64 MaxTimeout; ///< Maximum number of seconds to wait before retransmission\r
200 UINT64 Rtt2x; ///< Twice the average round trip time in nanoseconds\r
4684b66f 201\r
202 //\r
203 // Buffer management\r
204 //\r
f6e5cdd5 205 TFTP_PACKET * pFreeList; ///< List of free packets\r
206 TFTP_PACKET * pTxHead; ///< First packet in the list of packets for transmission\r
207 TFTP_PACKET * pTxTail; ///< Last packet in the list of packets for transmission\r
208 TFTP_PACKET ErrorPacket; ///< Error packet\r
209 TFTP_PACKET Tx[ MAX_PACKETS ];///< Transmit packets\r
4684b66f 210}GCC_TSDT_CONNECTION_CONTEXT;\r
211\r
212/**\r
213 TFTP server control structure\r
214**/\r
215typedef struct {\r
216 UINTN Signature; ///< Structure identification\r
217\r
218 //\r
219 // Image attributes\r
220 //\r
221 EFI_HANDLE ImageHandle; ///< Image handle\r
222\r
f6e5cdd5 223 //\r
224 // Performance management\r
225 //\r
226 UINT64 ClockFrequency; ///< Frequency of the clock\r
227 UINT64 Time1; ///< Clock value after rollover\r
228 UINT64 Time2; ///< Clock value before rollover\r
229 UINT64 RxTime; ///< Time when the packet was recevied\r
230\r
4684b66f 231 //\r
232 // TFTP port management\r
233 //\r
4684b66f 234 EFI_EVENT TimerEvent; ///< Timer to open TFTP port\r
f6e5cdd5 235 int Udpv4Index; ///< Entry for UDPv4\r
236 int Udpv6Index; ///< Entry for UDPv6\r
237 int Entries; ///< Number of TFTP ports\r
238 struct pollfd TftpPort [ 2 ]; ///< Poll descriptor for the TFTP ports (UDP4, UDP6)\r
4684b66f 239\r
240 //\r
241 // Request management\r
242 //\r
f6e5cdd5 243 union {\r
244 struct sockaddr_in v4; ///< UDP4 address\r
245 struct sockaddr_in6 v6; ///< UDP6 address\r
246 } RemoteAddress; ///< Remote address\r
247 ssize_t RxBytes; ///< Receive data length in bytes\r
248 UINT8 RxBuffer[ 2 + 2 + TFTP_MAX_BLOCK_SIZE ]; ///< Receive buffer\r
4684b66f 249\r
250 //\r
251 // Client port management\r
252 //\r
253 TSDT_CONNECTION_CONTEXT * pContextList; ///< List of connection context structures\r
254} TSDT_TFTP_SERVER;\r
255\r
256//#define SERVER_FROM_SERVICE(a) CR(a, TSDT_TFTP_SERVER, ServiceBinding, TFTP_SERVER_SIGNATURE) ///< Locate DT_LAYER from service binding\r
257\r
258extern TSDT_TFTP_SERVER mTftpServer;\r
259\r
260//------------------------------------------------------------------------------\r
261// Support routines\r
262//------------------------------------------------------------------------------\r
263\r
264/**\r
f6e5cdd5 265 Queue data packets for transmission\r
4684b66f 266\r
f6e5cdd5 267 @param [in] pContext Connection context structure address\r
4684b66f 268\r
f6e5cdd5 269 @retval TRUE if a read error occurred\r
4684b66f 270\r
271**/\r
f6e5cdd5 272BOOLEAN\r
273PacketFill (\r
274 IN TSDT_CONNECTION_CONTEXT * pContext\r
4684b66f 275 );\r
276\r
277/**\r
f6e5cdd5 278 Free the packet\r
4684b66f 279\r
f6e5cdd5 280 @param [in] pContext Address of a ::TSDT_CONNECTION_CONTEXT structure\r
281 @param [in] pPacket Address of a ::TFTP_PACKET structure\r
4684b66f 282\r
283**/\r
284VOID\r
f6e5cdd5 285PacketFree(\r
286 IN TSDT_CONNECTION_CONTEXT * pContext,\r
287 IN TFTP_PACKET * pPacket\r
288 );\r
289\r
290/**\r
291 Get a packet for transmission\r
292\r
293 @param [in] pContext Address of a ::TSDT_CONNECTION_CONTEXT structure\r
294\r
295 @retval Address of a ::TFTP_PACKET structure\r
296\r
297**/\r
298TFTP_PACKET *\r
299PacketGet (\r
4684b66f 300 IN TSDT_CONNECTION_CONTEXT * pContext\r
301 );\r
302\r
f6e5cdd5 303/**\r
304 Queue the packet for transmission\r
305\r
306 @param [in] pContext Address of a ::TSDT_CONNECTION_CONTEXT structure\r
307 @param [in] pPacket Address of a ::TFTP_PACKET structure\r
308\r
309 @retval TRUE if a transmission error has occurred\r
310\r
311**/\r
312BOOLEAN\r
313PacketQueue (\r
314 IN TSDT_CONNECTION_CONTEXT * pContext,\r
315 IN TFTP_PACKET * pPacket\r
316 );\r
317\r
318/**\r
319 Transmit the packet\r
320\r
321 @param [in] pContext Address of a ::TSDT_CONNECTION_CONTEXT structure\r
322 @param [in] pPacket Address of a ::TFTP_PACKET structure\r
323\r
324 @retval EFI_SUCCESS Message processed successfully\r
325\r
326**/\r
327EFI_STATUS\r
328PacketTx (\r
329 IN TSDT_CONNECTION_CONTEXT * pContext,\r
330 IN TFTP_PACKET * pPacket\r
331 );\r
332\r
4684b66f 333/**\r
334 Build and send an error packet\r
335\r
4684b66f 336 @param [in] pContext The context structure address.\r
337 @param [in] Error Error number for the packet\r
338 @param [in] pError Zero terminated error string address\r
339\r
340 @retval EFI_SUCCESS Message processed successfully\r
341\r
342**/\r
343EFI_STATUS\r
f6e5cdd5 344SendError (\r
4684b66f 345 IN TSDT_CONNECTION_CONTEXT * pContext,\r
346 IN UINT16 Error,\r
347 IN UINT8 * pError\r
348 );\r
349\r
350/**\r
f6e5cdd5 351 Process the TFTP request\r
4684b66f 352\r
f6e5cdd5 353 @param [in] pOption Address of the first zero terminated option string\r
354 @param [in] pValue Address to receive the value\r
4684b66f 355\r
f6e5cdd5 356 @retval EFI_SUCCESS Option translated into a value\r
4684b66f 357\r
358**/\r
359EFI_STATUS\r
f6e5cdd5 360TftpOptionValue (\r
361 IN UINT8 * pOption,\r
362 IN INT32 * pValue\r
4684b66f 363 );\r
364\r
365/**\r
f6e5cdd5 366 Process the TFTP request\r
4684b66f 367\r
f6e5cdd5 368 @param [in] pTftpServer The TFTP server control structure address.\r
369 @param [in] pContext Connection context structure address\r
370 @param [in] SocketFd Socket file descriptor\r
4684b66f 371\r
372**/\r
373VOID\r
f6e5cdd5 374TftpProcessRequest (\r
375 IN TSDT_TFTP_SERVER * pTftpServer,\r
376 IN TSDT_CONNECTION_CONTEXT * pContext,\r
377 IN int SocketFd\r
4684b66f 378 );\r
379\r
380/**\r
f6e5cdd5 381 Process the read request\r
4684b66f 382\r
f6e5cdd5 383 @param [in] pTftpServer Address of the ::TSDT_TFTP_SERVER structure\r
384 @param [in] pContext Connection context structure address\r
385 @param [in] SocketFd Socket file descriptor\r
4684b66f 386\r
f6e5cdd5 387 @retval TRUE if the context should be closed\r
4684b66f 388\r
389**/\r
f6e5cdd5 390BOOLEAN\r
391TftpRead (\r
392 IN TSDT_TFTP_SERVER * pTftpServer,\r
393 IN TSDT_CONNECTION_CONTEXT * pContext,\r
394 IN int SocketFd\r
4684b66f 395 );\r
396\r
397/**\r
f6e5cdd5 398 Update the window due to the ACK\r
4684b66f 399\r
f6e5cdd5 400 @param [in] pTftpServer Address of the ::TSDT_TFTP_SERVER structure\r
401 @param [in] pContext Address of a ::TSDT_CONNECTION_CONTEXT structure\r
402 @param [in] pPacket Address of a ::TFTP_PACKET structure\r
4684b66f 403\r
404**/\r
f6e5cdd5 405VOID\r
406WindowAck (\r
407 IN TSDT_TFTP_SERVER * pTftpServer,\r
408 IN TSDT_CONNECTION_CONTEXT * pContext,\r
409 IN TFTP_PACKET * pPacket\r
4684b66f 410 );\r
411\r
412/**\r
f6e5cdd5 413 A timeout has occurred, close the window\r
4684b66f 414\r
f6e5cdd5 415 @param [in] pContext Address of a ::TSDT_CONNECTION_CONTEXT structure\r
4684b66f 416\r
417**/\r
f6e5cdd5 418VOID\r
419WindowTimeout (\r
4684b66f 420 IN TSDT_CONNECTION_CONTEXT * pContext\r
421 );\r
422\r
423//------------------------------------------------------------------------------\r
424\r
425#endif // _TFTP_SERVER_H_\r