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