1 /***************************************************************************
2  * Copyright (c) 2024 Microsoft Corporation
3  *
4  * This program and the accompanying materials are made available under the
5  * terms of the MIT License which is available at
6  * https://opensource.org/licenses/MIT.
7  *
8  * SPDX-License-Identifier: MIT
9  **************************************************************************/
10 
11 
12 /**************************************************************************/
13 /**************************************************************************/
14 /**                                                                       */
15 /** NetX Duo Component                                                    */
16 /**                                                                       */
17 /**   Trivial File Transfer Protocol (TFTP) Server                        */
18 /**                                                                       */
19 /**                                                                       */
20 /**************************************************************************/
21 /**************************************************************************/
22 
23 
24 /**************************************************************************/
25 /*                                                                        */
26 /*  APPLICATION INTERFACE DEFINITION                       RELEASE        */
27 /*                                                                        */
28 /*    nxd_tftp_server.h                                   PORTABLE C      */
29 /*                                                           6.1.9        */
30 /*  AUTHOR                                                                */
31 /*                                                                        */
32 /*    Yuxin Zhou, Microsoft Corporation                                   */
33 /*                                                                        */
34 /*  DESCRIPTION                                                           */
35 /*                                                                        */
36 /*    This file defines the NetX Trivial File Transfer Protocol (TFTP)    */
37 /*    Server for NetX Duo.  It supports IPv4 and IPv6 networks.           */
38 /*    It is assumed that nx_api.h and nx_port.h have already been         */
39 /*    included, along with fx_api.h and fx_port.h.                        */
40 /*                                                                        */
41 /*  RELEASE HISTORY                                                       */
42 /*                                                                        */
43 /*    DATE              NAME                      DESCRIPTION             */
44 /*                                                                        */
45 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
46 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
47 /*                                            resulting in version 6.1    */
48 /*  10-15-2021     Yuxin Zhou               Modified comment(s), included */
49 /*                                            necessary header file,      */
50 /*                                            resulting in version 6.1.9  */
51 /*                                                                        */
52 /**************************************************************************/
53 
54 #ifndef NXD_TFTP_SERVER_H
55 #define NXD_TFTP_SERVER_H
56 
57 /* Determine if a C++ compiler is being used.  If so, ensure that standard
58    C is used to process the API information.  */
59 
60 #ifdef   __cplusplus
61 
62 /* Yes, C++ compiler is present.  Use standard C.  */
63 extern   "C" {
64 
65 #endif
66 
67 #include "nx_api.h"
68 
69 /* Define the TFTP ID.  */
70 
71 #define NXD_TFTP_SERVER_ID                          0x54465461UL
72 
73 #ifndef      NX_TFTP_NO_FILEX
74 #include    "fx_api.h"
75 #else
76 #include    "filex_stub.h"
77 #endif
78 
79 /* Define TFTP maximum error string.  */
80 
81 #ifndef NX_TFTP_ERROR_STRING_MAX
82 #define NX_TFTP_ERROR_STRING_MAX            64          /* Maximum error sting size   */
83 #endif
84 
85 
86 /* Define the maximum number of clients the TFTP Server can accommodate.  */
87 
88 #ifndef NX_TFTP_MAX_CLIENTS
89 #define NX_TFTP_MAX_CLIENTS                 10
90 #endif
91 
92 
93 /* Define TFTP UDP socket create options.  */
94 
95 #ifndef NX_TFTP_TYPE_OF_SERVICE
96 #define NX_TFTP_TYPE_OF_SERVICE             NX_IP_NORMAL
97 #endif
98 
99 #ifndef NX_TFTP_FRAGMENT_OPTION
100 #define NX_TFTP_FRAGMENT_OPTION             NX_DONT_FRAGMENT
101 #endif
102 
103 #ifndef NX_TFTP_TIME_TO_LIVE
104 #define NX_TFTP_TIME_TO_LIVE                0x80
105 #endif
106 
107 #ifndef NX_PHYSICAL_TRAILER
108 #define NX_PHYSICAL_TRAILER                 4
109 #endif
110 
111 #ifndef NX_TFTP_SERVER_PRIORITY
112 #define NX_TFTP_SERVER_PRIORITY             16
113 #endif
114 
115 #ifndef NX_TFTP_SERVER_TIME_SLICE
116 #define NX_TFTP_SERVER_TIME_SLICE           2
117 #endif
118 
119 
120 /* To enable a retransmission on client requests (e.g. resend
121    ACK and data packets, as well apply a timeout on a Client request),
122    define this option.
123 #define NX_TFTP_SERVER_RETRANSMIT_ENABLE
124 */
125 
126 
127 #ifdef  NX_TFTP_SERVER_RETRANSMIT_ENABLE
128 
129 /* Define the timer expiration for updating time remaining on a TFTP Client
130    request activity timeout (in timer ticks). */
131 #ifndef NX_TFTP_SERVER_TIMEOUT_PERIOD
132 #define NX_TFTP_SERVER_TIMEOUT_PERIOD      20
133 #endif
134 
135 /* Define the interval before retransmitting an ACK or data packet (in timer ticks).  */
136 #ifndef NX_TFTP_SERVER_RETRANSMIT_TIMEOUT
137 #define NX_TFTP_SERVER_RETRANSMIT_TIMEOUT  200
138 #endif
139 
140 /* Define the max number of retries retransmitting a data packet or ACK if no response or a previous
141    (duplicate) ACK or data packet, respectively, is received. */
142 #ifndef NX_TFTP_SERVER_MAX_RETRIES
143 #define NX_TFTP_SERVER_MAX_RETRIES         5
144 #endif
145 
146 #else
147 
148 /* Define the number of instances TFTP server receives a duplicate data or an ACK packet
149    without sending an error message. This does not utilize the retransmission timeout
150    and is available only if NX_TFTP_SERVER_RETRANSMIT_ENABLE is not defined.  */
151 
152 #ifndef NX_TFTP_MAX_CLIENT_RETRANSMITS
153 #define NX_TFTP_MAX_CLIENT_RETRANSMITS     2
154 #endif
155 
156 #endif /* NX_TFTP_SERVER_RETRANSMIT_ENABLE */
157 
158 
159 #define NX_TFTP_QUEUE_DEPTH                 5
160 
161 #define NX_TFTP_FILE_TRANSFER_MAX           512         /* 512 byte maximum file transfer                     */
162 
163 
164 /* Derive the maximum TFTP packet size, including Ethernet, IP and UDP headers, and
165    accounting for potential physical driver needs at the end of the packet.  */
166 
167 #define NX_TFTP_PACKET_SIZE                (NX_UDP_PACKET + NX_TFTP_FILE_TRANSFER_MAX + NX_PHYSICAL_TRAILER)
168 
169 
170 /* Define open types.  */
171 
172 #define NX_TFTP_OPEN_FOR_READ               0x01        /* TFTP open for reading                                */
173 #define NX_TFTP_OPEN_FOR_WRITE              0x02        /* TFTP open for writing                                */
174 
175 
176 /* Define TFTP message codes.  */
177 
178 #define NX_TFTP_CODE_READ                   0x01        /* TFTP read file request                               */
179 #define NX_TFTP_CODE_WRITE                  0x02        /* TFTP write file request                              */
180 #define NX_TFTP_CODE_DATA                   0x03        /* TFTP data packet                                     */
181 #define NX_TFTP_CODE_ACK                    0x04        /* TFTP command/data acknowledgement                    */
182 #define NX_TFTP_CODE_ERROR                  0x05        /* TFTP error message                                   */
183 
184 
185 /* Define TFTP error code constants.  */
186 
187 #define NX_TFTP_ERROR_NOT_DEFINED           0x00        /* TFTP not defined error code, see error string        */
188 #define NX_TFTP_ERROR_FILE_NOT_FOUND        0x01        /* TFTP file not found error code                       */
189 #define NX_TFTP_ERROR_ACCESS_VIOLATION      0x02        /* TFTP file access violation error code                */
190 #define NX_TFTP_ERROR_DISK_FULL             0x03        /* TFTP disk full error code                            */
191 #define NX_TFTP_ERROR_ILLEGAL_OPERATION     0x04        /* TFTP illegal operation error code                    */
192 #define NX_TFTP_CODE_ERROR                  0x05        /* TFTP client request received error code from server  */
193 #define NX_TFTP_ERROR_FILE_EXISTS           0x06        /* TFTP file already exists error code                  */
194 #define NX_TFTP_ERROR_NO_SUCH_USER          0x07        /* TFTP no such user error code                         */
195 #define NX_INVALID_TFTP_SERVER_ADDRESS      0x08        /* Invalid TFTP server IP extraced from received packet */
196 #define NX_TFTP_NO_ACK_RECEIVED             0x09        /* Did not receive TFTP server ACK response             */
197 #define NX_TFTP_INVALID_BLOCK_NUMBER        0x0A        /* Invalid block number received from Server response   */
198 #define NX_TFTP_INVALID_ADDRESS_TYPE        0x0B        /* Invalid IP version associated with client data       */
199 #define NX_TFTP_SESSION_TIMED_OUT           0x0C        /* No response from client or retransmissions limit hit */
200 
201 
202 /* Define offsets into the TFTP message buffer.  */
203 
204 #define NX_TFTP_CODE_OFFSET                 0           /* Offset to TFTP code in buffer                        */
205 #define NX_TFTP_FILENAME_OFFSET             2           /* Offset to TFTP filename in message                   */
206 #define NX_TFTP_BLOCK_NUMBER_OFFSET         2           /* Offset to TFTP block number in buffer                */
207 #define NX_TFTP_DATA_OFFSET                 4           /* Offset to TFTP data in buffer                        */
208 #define NX_TFTP_ERROR_CODE_OFFSET           2           /* Offset to TFTP error code                            */
209 #define NX_TFTP_ERROR_STRING_OFFSET         4           /* Offset to TFPT error string                          */
210 
211 
212 /* Define return code constants.  */
213 
214 #define NX_TFTP_ERROR                       0xC0        /* TFTP internal error                                  */
215 #define NX_TFTP_TIMEOUT                     0xC1        /* TFTP timeout occurred                                */
216 #define NX_TFTP_FAILED                      0xC2        /* TFTP error                                           */
217 #define NX_TFTP_NOT_OPEN                    0xC3        /* TFTP not opened error                                */
218 #define NX_TFTP_NOT_CLOSED                  0xC4        /* TFTP not closed error                                */
219 #define NX_TFTP_END_OF_FILE                 0xC5        /* TFTP end of file error                               */
220 #define NX_TFTP_POOL_ERROR                  0xC6        /* TFTP packet pool size error - less than 560 bytes    */
221 
222 
223 /* Define TFTP connection states.  */
224 
225 #define NX_TFTP_STATE_NOT_OPEN              0           /* TFTP connection not open                             */
226 #define NX_TFTP_STATE_OPEN                  1           /* TFTP connection open                                 */
227 #define NX_TFTP_STATE_WRITE_OPEN            2           /* TFTP connection open for writing                     */
228 #define NX_TFTP_STATE_END_OF_FILE           3           /* TFTP connection at end of file                       */
229 #define NX_TFTP_STATE_ERROR                 4           /* TFTP error condition                                 */
230 #define NX_TFTP_STATE_FINISHED              5           /* TFTP finished writing condition                      */
231 
232 
233 /* Define TFTP Server events.  */
234 
235 #define NX_TFTP_SERVER_RECEIVE_EVENT      0x01         /* TFTP received Client packet                           */
236 #define NX_TFTP_SERVER_TIMER_EVENT        0x02         /* TFTP timer event                                      */
237 #define NX_SERVER_TFTP_ANY_EVENT          0x0F         /* Any event                                             */
238 
239 /* Define the TFTP Server UDP port number */
240 
241 #define NX_TFTP_SERVER_PORT                 69
242 
243 /* Define the per client request structure for the TFTP Server data structure.  */
244 
245 typedef struct NX_TFTP_CLIENT_REQUEST_STRUCT
246 {
247     UINT            nx_tftp_client_request_port;                    /* Port of client request               */
248     NXD_ADDRESS     nx_tftp_client_request_ip_address;              /* IP address of client                 */
249     USHORT          nx_tftp_client_request_block_number;            /* Block number of file transfer        */
250     USHORT          nx_tftp_client_request_reserved;                /* Reserved for future use              */
251     UINT            nx_tftp_client_request_open_type;               /* Open type of client request          */
252     ULONG           nx_tftp_client_request_remaining_bytes;         /* Remaining bytes to send              */
253     UINT            nx_tftp_client_request_exact_fit;               /* Exact fit flag                       */
254     ULONG           nx_tftp_client_request_last_activity_time;      /* Time of last activity                */
255     FX_FILE         nx_tftp_client_request_file;                    /* File control block                   */
256     ULONG           nx_tftp_client_file_size;                       /* Size of file in bytes                */
257     ULONG           nx_tftp_client_previous_write_size;             /* Size of data in last data packet     */
258 #ifdef NX_TFTP_SERVER_RETRANSMIT_ENABLE
259     UINT            nx_tftp_client_retransmit_timeout;              /* Time between retransmits from server */
260     UINT            nx_tftp_client_retransmit_retries;              /* Number of retries on current data,ACK*/
261 #else
262     UINT            nx_tftp_client_request_retransmits;             /* Number of retransmits from client    */
263 #endif
264 } NX_TFTP_CLIENT_REQUEST;
265 
266 
267 /* Define the TFTP Server data structure.  */
268 
269 typedef struct NX_TFTP_SERVER_STRUCT
270 {
271     ULONG           nx_tftp_server_id;                              /* TFTP Server ID                       */
272     CHAR           *nx_tftp_server_name;                            /* Name of this TFTP client             */
273     NX_IP          *nx_tftp_server_ip_ptr;                          /* Pointer to associated IP structure   */
274     NX_PACKET_POOL *nx_tftp_server_packet_pool_ptr;                 /* Pointer to TFTP server packet pool   */
275     FX_MEDIA       *nx_tftp_server_media_ptr;                       /* Pointer to media control block       */
276     ULONG           nx_tftp_server_open_for_write_requests;         /* Number of open for write requests    */
277     ULONG           nx_tftp_server_open_for_read_requests;          /* Number of open for read requests     */
278     ULONG           nx_tftp_server_acks_received;                   /* Number of ACKs received              */
279     ULONG           nx_tftp_server_data_blocks_received;            /* Number of data blocks received       */
280     ULONG           nx_tftp_server_errors_received;                 /* Number of errors received            */
281     ULONG           nx_tftp_server_total_bytes_sent;                /* Number of total bytes sent           */
282     ULONG           nx_tftp_server_total_bytes_received;            /* Number of total bytes received       */
283     ULONG           nx_tftp_server_unknown_commands;                /* Number of unknown commands received  */
284     ULONG           nx_tftp_server_allocation_errors;               /* Number of allocation errors          */
285     ULONG           nx_tftp_server_clients_exceeded_errors;         /* Number of maximum clients errors     */
286     ULONG           nx_tftp_server_unknown_clients_errors;          /* Number of unknown clients errors     */
287     UINT            nx_tftp_server_error_code;                      /* Last error code received             */
288     CHAR            nx_tftp_server_error_string[NX_TFTP_ERROR_STRING_MAX + 1];
289     NX_TFTP_CLIENT_REQUEST                                          /* TFTP client request array            */
290                     nx_tftp_server_client_list[NX_TFTP_MAX_CLIENTS];
291     NX_UDP_SOCKET   nx_tftp_server_socket;                          /* TFTP Server UDP socket               */
292     TX_THREAD       nx_tftp_server_thread;                          /* TFTP server thread                   */
293     TX_EVENT_FLAGS_GROUP
294                     nx_tftp_server_event_flags;                     /* TFTP server thread events            */
295 #ifdef NX_TFTP_SERVER_RETRANSMIT_ENABLE
296     TX_TIMER        nx_tftp_server_timer;                           /* TFTP server activity timeout timer   */
297 #endif
298 } NX_TFTP_SERVER;
299 
300 
301 #ifndef NX_TFTP_SOURCE_CODE
302 
303 /* Application caller is present, perform API mapping.  */
304 
305 /* Determine if error checking is desired.  If so, map API functions
306    to the appropriate error checking front-ends.  Otherwise, map API
307    functions to the core functions that actually perform the work.
308    Note: error checking is enabled by default.  */
309 
310 #ifdef NX_DISABLE_ERROR_CHECKING
311 
312 /* Services without error checking.  */
313 
314 /* NetX TFTP services mapped to NetX Duo TFTP services */
315 #define nx_tftp_server_create            _nxd_tftp_server_create
316 #define nx_tftp_server_delete            _nxd_tftp_server_delete
317 #define nx_tftp_server_start             _nxd_tftp_server_start
318 #define nx_tftp_server_stop              _nxd_tftp_server_stop
319 
320 /* NetX Duo (IPv4 and IPv6 supported) TFTP services */
321 #define nxd_tftp_server_create           _nxd_tftp_server_create
322 #define nxd_tftp_server_delete           _nxd_tftp_server_delete
323 #define nxd_tftp_server_start            _nxd_tftp_server_start
324 #define nxd_tftp_server_stop             _nxd_tftp_server_stop
325 
326 #else
327 
328 /* Services with error checking.  */
329 
330 /* NetX TFTP services mapped to NetX Duo TFTP services with error checking*/
331 #define nx_tftp_server_create            _nxde_tftp_server_create
332 #define nx_tftp_server_delete            _nxde_tftp_server_delete
333 #define nx_tftp_server_start             _nxde_tftp_server_start
334 #define nx_tftp_server_stop              _nxde_tftp_server_stop
335 
336 /* NetX Duo (IPv4 and IPv6 supported) TFTP services with error checking */
337 #define nxd_tftp_server_create           _nxde_tftp_server_create
338 #define nxd_tftp_server_delete           _nxde_tftp_server_delete
339 #define nxd_tftp_server_start            _nxde_tftp_server_start
340 #define nxd_tftp_server_stop             _nxde_tftp_server_stop
341 
342 #endif   /* NX_DISABLE_ERROR_CHECKING */
343 
344 /* Define the prototypes accessible to the application software.  */
345 
346 UINT        nxd_tftp_server_create(NX_TFTP_SERVER *tftp_server_ptr, CHAR *tftp_server_name, NX_IP *ip_ptr, FX_MEDIA *media_ptr, VOID *stack_ptr, ULONG stack_size, NX_PACKET_POOL *pool_ptr);
347 UINT        nxd_tftp_server_delete(NX_TFTP_SERVER *tftp_server_ptr);
348 UINT        nxd_tftp_server_start(NX_TFTP_SERVER *tftp_server_ptr);
349 UINT        nxd_tftp_server_stop(NX_TFTP_SERVER *tftp_server_ptr);
350 
351 #else
352 
353 /* TFTP source code is being compiled, do not perform any API mapping.  */
354 
355 UINT        _nxde_tftp_server_create(NX_TFTP_SERVER *tftp_server_ptr, CHAR *tftp_server_name, NX_IP *ip_ptr, FX_MEDIA *media_ptr, VOID *stack_ptr, ULONG stack_size, NX_PACKET_POOL *pool_ptr);
356 UINT        _nxd_tftp_server_create(NX_TFTP_SERVER *tftp_server_ptr, CHAR *tftp_server_name, NX_IP *ip_ptr, FX_MEDIA *media_ptr, VOID *stack_ptr, ULONG stack_size, NX_PACKET_POOL *pool_ptr);
357 UINT        _nxde_tftp_server_delete(NX_TFTP_SERVER *tftp_server_ptr);
358 UINT        _nxd_tftp_server_delete(NX_TFTP_SERVER *tftp_server_ptr);
359 UINT        _nxde_tftp_server_start(NX_TFTP_SERVER *tftp_server_ptr);
360 UINT        _nxd_tftp_server_start(NX_TFTP_SERVER *tftp_server_ptr);
361 UINT        _nxde_tftp_server_stop(NX_TFTP_SERVER *tftp_server_ptr);
362 UINT        _nxd_tftp_server_stop(NX_TFTP_SERVER *tftp_server_ptr);
363 
364 #endif    /* NX_TFTP_SOURCE_CODE */
365 
366 /* Internal TFTP server functions */
367 
368 void        _nx_tftp_server_thread_entry(ULONG tftp_server);
369 void        _nx_tftp_server_open_for_read_process(NX_TFTP_SERVER *server_ptr, NX_PACKET *packet_ptr);
370 void        _nx_tftp_server_open_for_write_process(NX_TFTP_SERVER *server_ptr, NX_PACKET *packet_ptr);
371 VOID        _nx_tftp_server_data_process(NX_TFTP_SERVER *server_ptr, NX_PACKET *packet_ptr);
372 VOID        _nx_tftp_server_ack_process(NX_TFTP_SERVER *server_ptr, NX_PACKET *packet_ptr);
373 VOID        _nx_tftp_server_error_process(NX_TFTP_SERVER *server_ptr, NX_PACKET *packet_ptr);
374 NX_TFTP_CLIENT_REQUEST * _nx_tftp_server_find_client_request(NX_TFTP_SERVER *server_ptr, UINT port, NXD_ADDRESS *ip_address);
375 VOID        _nx_tftp_server_send_error(NX_TFTP_SERVER *server_ptr, NXD_ADDRESS *ip_address, UINT port, UINT error, CHAR *error_message);
376 VOID        _nx_tftp_server_data_present(NX_UDP_SOCKET *socket_ptr);
377 VOID        _nx_tftp_server_process_received_data(NX_TFTP_SERVER *server_ptr);
378 UINT        _nx_tftp_server_send_data(NX_TFTP_SERVER *server_ptr, NX_TFTP_CLIENT_REQUEST *client_request_ptr, UINT retransmit);
379 UINT        _nx_tftp_server_send_ack(NX_TFTP_SERVER *server_ptr, NX_TFTP_CLIENT_REQUEST *client_request_ptr, UINT retransmit);
380 #ifdef NX_TFTP_SERVER_RETRANSMIT_ENABLE
381 VOID        _nx_tftp_server_timer_process(NX_TFTP_SERVER *server_ptr);
382 VOID        _nx_tftp_server_timer_entry(ULONG tftp_server_address);
383 #endif
384 /* Determine if a C++ compiler is being used.  If so, complete the standard
385    C conditional started above.  */
386 #ifdef   __cplusplus
387         }
388 #endif
389 
390 #endif    /* NXD_TFTP_SERVER_H */
391