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