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