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 Component                                                        */
16 /**                                                                       */
17 /**   Trivial File Transfer Protocol (TFTP) Client                        */
18 /**                                                                       */
19 /**************************************************************************/
20 /**************************************************************************/
21 
22 #define NX_TFTP_SOURCE_CODE
23 
24 
25 /* Force error checking to be disabled in this module */
26 
27 #ifndef NX_DISABLE_ERROR_CHECKING
28 #define NX_DISABLE_ERROR_CHECKING
29 #endif
30 
31 
32 /* Include necessary system files.  */
33 
34 #include    "nx_api.h"
35 #include    "nx_ip.h"
36 #include    "nx_ipv6.h"
37 #include    "nxd_tftp_client.h"
38 
39 /* Bring in externs for caller checking code.  */
40 
41 NX_CALLER_CHECKING_EXTERNS
42 
43 
44 /**************************************************************************/
45 /*                                                                        */
46 /*  FUNCTION                                               RELEASE        */
47 /*                                                                        */
48 /*    _nxde_tftp_client_create                            PORTABLE C      */
49 /*                                                           6.1          */
50 /*  AUTHOR                                                                */
51 /*                                                                        */
52 /*    Yuxin Zhou, Microsoft Corporation                                   */
53 /*                                                                        */
54 /*  DESCRIPTION                                                           */
55 /*                                                                        */
56 /*    This function checks for errors in the TFTP client create call.     */
57 /*                                                                        */
58 /*                                                                        */
59 /*  INPUT                                                                 */
60 /*                                                                        */
61 /*    tftp_client_ptr                       Pointer to TFTP client        */
62 /*    tftp_client_name                      Name of TFTP client           */
63 /*    ip_ptr                                Pointer to IP instance        */
64 /*    pool_ptr                              Pointer to packet pool        */
65 /*    ip_type                               IP type                       */
66 /*                                                                        */
67 /*  OUTPUT                                                                */
68 /*                                                                        */
69 /*    status                                Completion status             */
70 /*    NX_PTR_ERROR                          Invalid pointer input         */
71 /*    NX_INVALID_PARAMETERS                 Invalid non pointer input     */
72 /*                                                                        */
73 /*  CALLS                                                                 */
74 /*                                                                        */
75 /*    _nxd_tftp_client_create               Actual client create call     */
76 /*                                                                        */
77 /*  CALLED BY                                                             */
78 /*                                                                        */
79 /*    Application Code                                                    */
80 /*                                                                        */
81 /*  RELEASE HISTORY                                                       */
82 /*                                                                        */
83 /*    DATE              NAME                      DESCRIPTION             */
84 /*                                                                        */
85 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
86 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
87 /*                                            resulting in version 6.1    */
88 /*                                                                        */
89 /**************************************************************************/
_nxde_tftp_client_create(NX_TFTP_CLIENT * tftp_client_ptr,CHAR * tftp_client_name,NX_IP * ip_ptr,NX_PACKET_POOL * pool_ptr,UINT ip_type)90 UINT  _nxde_tftp_client_create(NX_TFTP_CLIENT *tftp_client_ptr, CHAR *tftp_client_name, NX_IP *ip_ptr, NX_PACKET_POOL *pool_ptr, UINT ip_type)
91 {
92 
93 UINT    status;
94 
95 
96     /* Check for invalid input pointers.  */
97     if ((ip_ptr == NX_NULL) || (ip_ptr -> nx_ip_id != NX_IP_ID) ||
98         (tftp_client_ptr == NX_NULL) || (tftp_client_ptr -> nx_tftp_client_id == NXD_TFTP_CLIENT_ID) ||
99         (pool_ptr == NX_NULL))
100         return(NX_PTR_ERROR);
101 
102     /* Check for valid IP version*/
103     if ((ip_type != NX_IP_VERSION_V4) && (ip_type != NX_IP_VERSION_V6))
104     {
105         return NX_INVALID_PARAMETERS;
106     }
107 
108     /* Call actual client create function.  */
109     status =  _nxd_tftp_client_create(tftp_client_ptr, tftp_client_name, ip_ptr, pool_ptr, ip_type);
110 
111     /* Return completion status.  */
112     return(status);
113 }
114 
115 /**************************************************************************/
116 /*                                                                        */
117 /*  FUNCTION                                               RELEASE        */
118 /*                                                                        */
119 /*    _nxd_tftp_client_create                             PORTABLE C      */
120 /*                                                           6.1          */
121 /*  AUTHOR                                                                */
122 /*                                                                        */
123 /*    Yuxin Zhou, Microsoft Corporation                                   */
124 /*                                                                        */
125 /*  DESCRIPTION                                                           */
126 /*                                                                        */
127 /*    This function creates a TFTP client on the specified IP. In doing   */
128 /*    so this function creates an UDP socket for subsequent TFTP          */
129 /*    transfers.                                                          */
130 /*                                                                        */
131 /*                                                                        */
132 /*  INPUT                                                                 */
133 /*                                                                        */
134 /*    tftp_client_ptr                       Pointer to TFTP client        */
135 /*    tftp_client_name                      Name of TFTP client           */
136 /*    ip_ptr                                Pointer to IP instance        */
137 /*    pool_ptr                              Pointer to TFTP pool          */
138 /*    ip_type                               IP type                       */
139 /*                                                                        */
140 /*  OUTPUT                                                                */
141 /*                                                                        */
142 /*    NX_SUCCESS                            Successful completion status  */
143 /*    status                                Actual completion status      */
144 /*                                                                        */
145 /*  CALLS                                                                 */
146 /*                                                                        */
147 /*    nx_udp_socket_bind                    Bind the UDP socket           */
148 /*    nx_udp_socket_create                  Create a UDP socket           */
149 /*    nx_udp_socket_delete                  Delete the UDP socket         */
150 /*                                                                        */
151 /*  CALLED BY                                                             */
152 /*                                                                        */
153 /*    Application Code                                                    */
154 /*                                                                        */
155 /*  RELEASE HISTORY                                                       */
156 /*                                                                        */
157 /*    DATE              NAME                      DESCRIPTION             */
158 /*                                                                        */
159 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
160 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
161 /*                                            resulting in version 6.1    */
162 /*                                                                        */
163 /**************************************************************************/
_nxd_tftp_client_create(NX_TFTP_CLIENT * tftp_client_ptr,CHAR * tftp_client_name,NX_IP * ip_ptr,NX_PACKET_POOL * pool_ptr,UINT ip_type)164 UINT  _nxd_tftp_client_create(NX_TFTP_CLIENT *tftp_client_ptr, CHAR *tftp_client_name, NX_IP *ip_ptr, NX_PACKET_POOL *pool_ptr, UINT ip_type)
165 {
166 
167 UINT    status;
168 
169 
170     /* Clear the TFTP server structure.  */
171     memset((void *) tftp_client_ptr, 0, sizeof(NX_TFTP_CLIENT));
172 
173     /* Setup the TFTP client data structure.  */
174 
175     /* Save the TFTP client name.  */
176     tftp_client_ptr -> nx_tftp_client_name =  tftp_client_name;
177 
178     /* Save the TFTP IP pointer.  */
179     tftp_client_ptr -> nx_tftp_client_ip_ptr =  ip_ptr;
180 
181     /* Save the TFTP packet pool pointer.  */
182     tftp_client_ptr -> nx_tftp_client_packet_pool_ptr =  pool_ptr;
183 
184     /* Initialize the server port number.  This can change after the open request.  */
185     tftp_client_ptr -> nx_tftp_client_server_port =  NX_TFTP_SERVER_PORT;
186 
187     /* Setup the current state to not open.  */
188     tftp_client_ptr -> nx_tftp_client_state =  NX_TFTP_STATE_NOT_OPEN;
189 
190     /* Default the client network interface to the primary interface. */
191     tftp_client_ptr -> nx_tftp_client_interface_index = 0;
192 
193     /* Create the UDP socket.  */
194     status =  nx_udp_socket_create(ip_ptr, &(tftp_client_ptr -> nx_tftp_client_socket), tftp_client_name,
195                           NX_TFTP_TYPE_OF_SERVICE,  NX_TFTP_FRAGMENT_OPTION, NX_TFTP_TIME_TO_LIVE, NX_TFTP_QUEUE_DEPTH);
196 
197     /* Determine if an error occurred.   */
198     if (status)
199     {
200 
201         /* Yes, return error code.  */
202         return(status);
203     }
204 
205     /* Now, bind the socket to a port number.  */
206 
207     /* Let NetX decide which port. */
208     status =  nx_udp_socket_bind(&(tftp_client_ptr -> nx_tftp_client_socket), NX_TFTP_SOURCE_PORT, NX_WAIT_FOREVER);
209 
210     /* Determine if an error occurred.  */
211     if (status)
212     {
213 
214         /* Delete the UDP socket.  */
215         nx_udp_socket_delete(&(tftp_client_ptr -> nx_tftp_client_socket));
216 
217         /* Yes, return error code.  */
218         return(status);
219     }
220 
221     /* Otherwise, all is okay.  Set the TFTP ID to indicate success.  */
222     tftp_client_ptr -> nx_tftp_client_id =  NXD_TFTP_CLIENT_ID;
223 
224     NX_PARAMETER_NOT_USED(ip_type);
225 
226     /* Return success to the caller.  */
227     return(NX_SUCCESS);
228 }
229 
230 
231 /**************************************************************************/
232 /*                                                                        */
233 /*  FUNCTION                                               RELEASE        */
234 /*                                                                        */
235 /*    _nxde_tftp_client_delete                            PORTABLE C      */
236 /*                                                           6.1          */
237 /*  AUTHOR                                                                */
238 /*                                                                        */
239 /*    Yuxin Zhou, Microsoft Corporation                                   */
240 /*                                                                        */
241 /*  DESCRIPTION                                                           */
242 /*                                                                        */
243 /*    This function checks for errors in the TFTP client delete call.     */
244 /*                                                                        */
245 /*                                                                        */
246 /*  INPUT                                                                 */
247 /*                                                                        */
248 /*    tftp_client_ptr                       Pointer to TFTP client        */
249 /*                                                                        */
250 /*  OUTPUT                                                                */
251 /*                                                                        */
252 /*    status                                Completion status             */
253 /*    NX_PTR_ERROR                          Invalid pointer input         */
254 /*                                                                        */
255 /*  CALLS                                                                 */
256 /*                                                                        */
257 /*    _nxd_tftp_client_delete               Actual client delete call     */
258 /*                                                                        */
259 /*  CALLED BY                                                             */
260 /*                                                                        */
261 /*    Application Code                                                    */
262 /*                                                                        */
263 /*  RELEASE HISTORY                                                       */
264 /*                                                                        */
265 /*    DATE              NAME                      DESCRIPTION             */
266 /*                                                                        */
267 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
268 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
269 /*                                            resulting in version 6.1    */
270 /*                                                                        */
271 /**************************************************************************/
_nxde_tftp_client_delete(NX_TFTP_CLIENT * tftp_client_ptr)272 UINT  _nxde_tftp_client_delete(NX_TFTP_CLIENT *tftp_client_ptr)
273 {
274 
275 UINT    status;
276 
277 
278     /* Check for invalid input pointers.  */
279     if ((tftp_client_ptr == NX_NULL) || (tftp_client_ptr -> nx_tftp_client_id != NXD_TFTP_CLIENT_ID))
280         return(NX_PTR_ERROR);
281 
282     /* Check for appropriate caller.  */
283     NX_THREADS_ONLY_CALLER_CHECKING
284 
285     /* Call actual client delete function.  */
286     status =  _nxd_tftp_client_delete(tftp_client_ptr);
287 
288     /* Return completion status.  */
289     return(status);
290 }
291 
292 
293 /**************************************************************************/
294 /*                                                                        */
295 /*  FUNCTION                                               RELEASE        */
296 /*                                                                        */
297 /*    _nxd_tftp_client_delete                             PORTABLE C      */
298 /*                                                           6.1          */
299 /*  AUTHOR                                                                */
300 /*                                                                        */
301 /*    Yuxin Zhou, Microsoft Corporation                                   */
302 /*                                                                        */
303 /*  DESCRIPTION                                                           */
304 /*                                                                        */
305 /*    This function deletes a TFTP client on the specified IP.            */
306 /*                                                                        */
307 /*                                                                        */
308 /*  INPUT                                                                 */
309 /*                                                                        */
310 /*    tftp_client_ptr                       Pointer to TFTP client        */
311 /*                                                                        */
312 /*  OUTPUT                                                                */
313 /*                                                                        */
314 /*    NX_SUCCESS                            Successful completion status  */
315 /*                                                                        */
316 /*  CALLS                                                                 */
317 /*                                                                        */
318 /*    nx_udp_socket_unbind                  Unbind the UDP socket         */
319 /*    nx_udp_socket_delete                  Delete the UDP socket         */
320 /*                                                                        */
321 /*  CALLED BY                                                             */
322 /*                                                                        */
323 /*    Application Code                                                    */
324 /*                                                                        */
325 /*  RELEASE HISTORY                                                       */
326 /*                                                                        */
327 /*    DATE              NAME                      DESCRIPTION             */
328 /*                                                                        */
329 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
330 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
331 /*                                            resulting in version 6.1    */
332 /*                                                                        */
333 /**************************************************************************/
_nxd_tftp_client_delete(NX_TFTP_CLIENT * tftp_client_ptr)334 UINT  _nxd_tftp_client_delete(NX_TFTP_CLIENT *tftp_client_ptr)
335 {
336 
337     /* Unbind the TFTP client UDP socket.  */
338     nx_udp_socket_unbind(&(tftp_client_ptr -> nx_tftp_client_socket));
339 
340     /* Delete the TFTP client UDP socket.  */
341     nx_udp_socket_delete(&(tftp_client_ptr -> nx_tftp_client_socket));
342 
343     /* Clear the TFTP client ID.  */
344     tftp_client_ptr -> nx_tftp_client_id =  0;
345 
346     /* Return success to the caller.  */
347     return(NX_SUCCESS);
348 }
349 
350 /**************************************************************************/
351 /*                                                                        */
352 /*  FUNCTION                                               RELEASE        */
353 /*                                                                        */
354 /*    _nxde_tftp_client_set_interface                     PORTABLE C      */
355 /*                                                           6.1          */
356 /*  AUTHOR                                                                */
357 /*                                                                        */
358 /*    Yuxin Zhou, Microsoft Corporation                                   */
359 /*                                                                        */
360 /*  DESCRIPTION                                                           */
361 /*                                                                        */
362 /*    This function checks for errors in the TFTP client set interface    */
363 /*    call.                                                               */
364 /*                                                                        */
365 /*                                                                        */
366 /*  INPUT                                                                 */
367 /*                                                                        */
368 /*    tftp_client_ptr                       Pointer to TFTP client        */
369 /*    if_index                              Interface for tftp messages   */
370 /*                                                                        */
371 /*  OUTPUT                                                                */
372 /*                                                                        */
373 /*    status                                Completion status             */
374 /*    NX_PTR_ERROR                          Invalid pointer input         */
375 /*    NX_INVALID_INTERFACE                  Invalid interface index input */
376 /*                                                                        */
377 /*  CALLS                                                                 */
378 /*                                                                        */
379 /*    _nxd_tftp_client_set_interface        Actual set interface call     */
380 /*                                                                        */
381 /*  CALLED BY                                                             */
382 /*                                                                        */
383 /*    Application Code                                                    */
384 /*                                                                        */
385 /*  RELEASE HISTORY                                                       */
386 /*                                                                        */
387 /*    DATE              NAME                      DESCRIPTION             */
388 /*                                                                        */
389 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
390 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
391 /*                                            resulting in version 6.1    */
392 /*                                                                        */
393 /**************************************************************************/
_nxde_tftp_client_set_interface(NX_TFTP_CLIENT * tftp_client_ptr,UINT if_index)394 UINT  _nxde_tftp_client_set_interface(NX_TFTP_CLIENT *tftp_client_ptr, UINT if_index)
395 {
396 
397 UINT    status;
398 
399     /* Check for invalid input pointer input.  */
400     if (tftp_client_ptr == NX_NULL)
401         return(NX_PTR_ERROR);
402 
403     /* Verify a valid index as been supplied. */
404     if (if_index >= NX_MAX_PHYSICAL_INTERFACES)
405     {
406         return NX_TFTP_INVALID_INTERFACE;
407     }
408 
409     /* Check for appropriate caller.  */
410     NX_THREADS_ONLY_CALLER_CHECKING
411 
412     /* Call actual client delete function.  */
413     status =  _nxd_tftp_client_set_interface(tftp_client_ptr, if_index);
414 
415     /* Return completion status.  */
416     return(status);
417 }
418 
419 
420 /**************************************************************************/
421 /*                                                                        */
422 /*  FUNCTION                                               RELEASE        */
423 /*                                                                        */
424 /*    _nxd_tftp_client_set_interface                      PORTABLE C      */
425 /*                                                           6.1          */
426 /*  AUTHOR                                                                */
427 /*                                                                        */
428 /*    Yuxin Zhou, Microsoft Corporation                                   */
429 /*                                                                        */
430 /*  DESCRIPTION                                                           */
431 /*                                                                        */
432 /*    This function sets the physical interface which the TFTP client     */
433 /*    sends and receives TFTP packets.                                    */
434 /*                                                                        */
435 /*                                                                        */
436 /*  INPUT                                                                 */
437 /*                                                                        */
438 /*    tftp_client_ptr                       Pointer to TFTP client        */
439 /*    if_index                              Interface for tftp messages   */
440 /*                                                                        */
441 /*  OUTPUT                                                                */
442 /*                                                                        */
443 /*    NX_SUCCESS                            Successful completion status  */
444 /*    NX_INVALID_INTERFACE                  Invalid interface index input */
445 /*                                                                        */
446 /*  CALLS                                                                 */
447 /*                                                                        */
448 /*    nx_udp_socket_unbind                  Unbind the UDP socket         */
449 /*    nx_udp_socket_delete                  Delete the UDP socket         */
450 /*                                                                        */
451 /*  CALLED BY                                                             */
452 /*                                                                        */
453 /*    Application Code                                                    */
454 /*                                                                        */
455 /*  RELEASE HISTORY                                                       */
456 /*                                                                        */
457 /*    DATE              NAME                      DESCRIPTION             */
458 /*                                                                        */
459 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
460 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
461 /*                                            resulting in version 6.1    */
462 /*                                                                        */
463 /**************************************************************************/
_nxd_tftp_client_set_interface(NX_TFTP_CLIENT * tftp_client_ptr,UINT if_index)464 UINT  _nxd_tftp_client_set_interface(NX_TFTP_CLIENT *tftp_client_ptr, UINT if_index)
465 {
466 
467 
468     /* Set the TFTP client interface index.  */
469     tftp_client_ptr -> nx_tftp_client_interface_index = if_index;
470 
471     /* Return success to the caller.  */
472     return(NX_SUCCESS);
473 }
474 
475 
476 
477 /**************************************************************************/
478 /*                                                                        */
479 /*  FUNCTION                                               RELEASE        */
480 /*                                                                        */
481 /*    _nxde_tftp_client_error_info_get                    PORTABLE C      */
482 /*                                                           6.1          */
483 /*  AUTHOR                                                                */
484 /*                                                                        */
485 /*    Yuxin Zhou, Microsoft Corporation                                   */
486 /*                                                                        */
487 /*  DESCRIPTION                                                           */
488 /*                                                                        */
489 /*    This function checks for errors in the TFTP error information       */
490 /*    get call.                                                           */
491 /*                                                                        */
492 /*    Note: error_string pointer points to string generated by internal   */
493 /*    logic and it is always NULL-terminated.                             */
494 /*                                                                        */
495 /*  INPUT                                                                 */
496 /*                                                                        */
497 /*    tftp_client_ptr                       Pointer to TFTP client        */
498 /*    error_code                            Pointer to destination for    */
499 /*                                            error code                  */
500 /*    error_string                          Pointer to destination for    */
501 /*                                            the error string            */
502 /*                                                                        */
503 /*  OUTPUT                                                                */
504 /*                                                                        */
505 /*    status                                Completion status             */
506 /*    NX_PTR_ERROR                          Invalid pointer input         */
507 /*                                                                        */
508 /*  CALLS                                                                 */
509 /*                                                                        */
510 /*    _nxd_tftp_client_error_info_get        Actual get error info call   */
511 /*                                                                        */
512 /*  CALLED BY                                                             */
513 /*                                                                        */
514 /*    Application Code                                                    */
515 /*                                                                        */
516 /*  RELEASE HISTORY                                                       */
517 /*                                                                        */
518 /*    DATE              NAME                      DESCRIPTION             */
519 /*                                                                        */
520 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
521 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
522 /*                                            resulting in version 6.1    */
523 /*                                                                        */
524 /**************************************************************************/
_nxde_tftp_client_error_info_get(NX_TFTP_CLIENT * tftp_client_ptr,UINT * error_code,CHAR ** error_string)525 UINT  _nxde_tftp_client_error_info_get(NX_TFTP_CLIENT *tftp_client_ptr, UINT *error_code, CHAR **error_string)
526 {
527 
528 UINT    status;
529 
530 
531     /* Check for invalid input pointers.  */
532     if ((tftp_client_ptr == NX_NULL) || (tftp_client_ptr -> nx_tftp_client_id != NXD_TFTP_CLIENT_ID) ||
533         (error_code == NX_NULL) || (error_string == NX_NULL))
534         return(NX_PTR_ERROR);
535 
536     /* Check for appropriate caller.  */
537     NX_THREADS_ONLY_CALLER_CHECKING
538 
539     /* Call actual client error information get function.  */
540     status =  _nxd_tftp_client_error_info_get(tftp_client_ptr, error_code, error_string);
541 
542     /* Return completion status.  */
543     return(status);
544 }
545 
546 /**************************************************************************/
547 /*                                                                        */
548 /*  FUNCTION                                               RELEASE        */
549 /*                                                                        */
550 /*    _nxd_tftp_client_error_info_get                     PORTABLE C      */
551 /*                                                           6.1          */
552 /*  AUTHOR                                                                */
553 /*                                                                        */
554 /*    Yuxin Zhou, Microsoft Corporation                                   */
555 /*                                                                        */
556 /*  DESCRIPTION                                                           */
557 /*                                                                        */
558 /*    This function picks up the error code and error string for the      */
559 /*    specified TFTP client instance.                                     */
560 /*                                                                        */
561 /*    Note: error_string pointer points to string generated by internal   */
562 /*    logic and it is always NULL-terminated.                             */
563 /*                                                                        */
564 /*  INPUT                                                                 */
565 /*                                                                        */
566 /*    tftp_client_ptr                       Pointer to TFTP client        */
567 /*    error_code                            Pointer to destination for    */
568 /*                                            error code                  */
569 /*    error_string                          Pointer to destination for    */
570 /*                                            the error string            */
571 /*                                                                        */
572 /*  OUTPUT                                                                */
573 /*                                                                        */
574 /*    NX_SUCCESS                           Successful completion status   */
575 /*                                                                        */
576 /*  CALLS                                                                 */
577 /*                                                                        */
578 /*    None                                                                */
579 /*                                                                        */
580 /*  CALLED BY                                                             */
581 /*                                                                        */
582 /*    Application Code                                                    */
583 /*                                                                        */
584 /*  RELEASE HISTORY                                                       */
585 /*                                                                        */
586 /*    DATE              NAME                      DESCRIPTION             */
587 /*                                                                        */
588 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
589 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
590 /*                                            resulting in version 6.1    */
591 /*                                                                        */
592 /**************************************************************************/
_nxd_tftp_client_error_info_get(NX_TFTP_CLIENT * tftp_client_ptr,UINT * error_code,CHAR ** error_string)593 UINT  _nxd_tftp_client_error_info_get(NX_TFTP_CLIENT *tftp_client_ptr, UINT *error_code, CHAR **error_string)
594 {
595 
596     /* Return the error code and the error string.  */
597     *error_code =    tftp_client_ptr -> nx_tftp_client_error_code;
598     *error_string =  &(tftp_client_ptr -> nx_tftp_client_error_string[0]);
599 
600     /* Return success to the caller.  */
601     return(NX_SUCCESS);
602 }
603 
604 
605 /**************************************************************************/
606 /*                                                                        */
607 /*  FUNCTION                                               RELEASE        */
608 /*                                                                        */
609 /*    _nxde_tftp_client_file_close                        PORTABLE C      */
610 /*                                                           6.1          */
611 /*  AUTHOR                                                                */
612 /*                                                                        */
613 /*    Yuxin Zhou, Microsoft Corporation                                   */
614 /*                                                                        */
615 /*  DESCRIPTION                                                           */
616 /*                                                                        */
617 /*    This function checks for errors in the TFTP file close call.        */
618 /*                                                                        */
619 /*                                                                        */
620 /*  INPUT                                                                 */
621 /*                                                                        */
622 /*    tftp_client_ptr                       Pointer to TFTP client        */
623 /*    ip_type                               IP type                       */
624 /*                                                                        */
625 /*  OUTPUT                                                                */
626 /*                                                                        */
627 /*    status                                Completion status             */
628 /*    NX_PTR_ERROR                          Invalid pointer input         */
629 /*    NX_INVALID_PARAMETERS                 Invalid non pointer input     */
630 /*                                                                        */
631 /*  CALLS                                                                 */
632 /*                                                                        */
633 /*    _nxd_tftp_client_file_close           Actual client file close      */
634 /*                                                                        */
635 /*  CALLED BY                                                             */
636 /*                                                                        */
637 /*    Application Code                                                    */
638 /*                                                                        */
639 /*  RELEASE HISTORY                                                       */
640 /*                                                                        */
641 /*    DATE              NAME                      DESCRIPTION             */
642 /*                                                                        */
643 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
644 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
645 /*                                            resulting in version 6.1    */
646 /*                                                                        */
647 /**************************************************************************/
_nxde_tftp_client_file_close(NX_TFTP_CLIENT * tftp_client_ptr,UINT ip_type)648 UINT  _nxde_tftp_client_file_close(NX_TFTP_CLIENT *tftp_client_ptr, UINT ip_type)
649 {
650 
651 UINT    status;
652 
653 
654     /* Check for invalid input pointers.  */
655     if ((tftp_client_ptr == NX_NULL) || (tftp_client_ptr -> nx_tftp_client_id != NXD_TFTP_CLIENT_ID))
656         return(NX_PTR_ERROR);
657 
658     /* Check for valid IP version*/
659     if ((ip_type != NX_IP_VERSION_V4) && (ip_type != NX_IP_VERSION_V6))
660     {
661         return NX_INVALID_PARAMETERS;
662     }
663 
664     /* Check for appropriate caller.  */
665     NX_THREADS_ONLY_CALLER_CHECKING
666 
667     /* Call actual client file close function.  */
668     status =  _nxd_tftp_client_file_close(tftp_client_ptr, ip_type);
669 
670     /* Return completion status.  */
671     return(status);
672 }
673 
674 /**************************************************************************/
675 /*                                                                        */
676 /*  FUNCTION                                               RELEASE        */
677 /*                                                                        */
678 /*    _nxd_tftp_client_file_close                         PORTABLE C      */
679 /*                                                           6.1          */
680 /*  AUTHOR                                                                */
681 /*                                                                        */
682 /*    Yuxin Zhou, Microsoft Corporation                                   */
683 /*                                                                        */
684 /*  DESCRIPTION                                                           */
685 /*                                                                        */
686 /*    This function closes the previously opened TFTP file.               */
687 /*                                                                        */
688 /*                                                                        */
689 /*  INPUT                                                                 */
690 /*                                                                        */
691 /*    tftp_client_ptr                       Pointer to TFTP client        */
692 /*    ip_type                               IP type                       */
693 /*                                                                        */
694 /*  OUTPUT                                                                */
695 /*                                                                        */
696 /*    NX_SUCCESS                            Successful completion status  */
697 /*    status                                Actual completion status      */
698 /*                                                                        */
699 /*  CALLS                                                                 */
700 /*                                                                        */
701 /*    nx_packet_allocate                    Allocate packet for 0-length  */
702 /*                                            data packet                 */
703 /*    nxd_udp_socket_send                   Send UDP data packet          */
704 /*                                                                        */
705 /*  CALLED BY                                                             */
706 /*                                                                        */
707 /*    Application Code                                                    */
708 /*                                                                        */
709 /*  RELEASE HISTORY                                                       */
710 /*                                                                        */
711 /*    DATE              NAME                      DESCRIPTION             */
712 /*                                                                        */
713 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
714 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
715 /*                                            resulting in version 6.1    */
716 /*                                                                        */
717 /**************************************************************************/
_nxd_tftp_client_file_close(NX_TFTP_CLIENT * tftp_client_ptr,UINT ip_type)718 UINT  _nxd_tftp_client_file_close(NX_TFTP_CLIENT *tftp_client_ptr, UINT ip_type)
719 {
720 
721 NX_PACKET   *packet_ptr;
722 UCHAR       *buffer_ptr;
723 UINT        status;
724 
725 
726     /* Determine if the file is still open for writing.  */
727     if (tftp_client_ptr -> nx_tftp_client_state == NX_TFTP_STATE_WRITE_OPEN)
728     {
729 
730         /* Allocate a new packet for the final data message.  */
731         if (ip_type == NX_IP_VERSION_V4)
732         {
733             status =  nx_packet_allocate(tftp_client_ptr -> nx_tftp_client_packet_pool_ptr, &packet_ptr, NX_IPv4_UDP_PACKET, NX_NO_WAIT);
734         }
735         else
736         {
737             status =  nx_packet_allocate(tftp_client_ptr -> nx_tftp_client_packet_pool_ptr, &packet_ptr, NX_IPv6_UDP_PACKET, NX_NO_WAIT);
738         }
739 
740         /* Determine if an error occurred trying to allocate a packet.  */
741         if (status != NX_SUCCESS)
742         {
743 
744             /* Enter error state.  */
745             tftp_client_ptr -> nx_tftp_client_state =  NX_TFTP_STATE_ERROR;
746 
747             /* Return error condition.  */
748             return(status);
749         }
750 
751         if (4u > ((ULONG)(packet_ptr -> nx_packet_data_end) - (ULONG)(packet_ptr -> nx_packet_append_ptr)))
752         {
753             /* Return the unsent packet to the packet pool. */
754             nx_packet_release(packet_ptr);
755 
756             /* Enter error state.  */
757             tftp_client_ptr -> nx_tftp_client_state =  NX_TFTP_STATE_ERROR;
758 
759             return(NX_SIZE_ERROR);
760         }
761 
762         packet_ptr -> nx_packet_append_ptr = packet_ptr -> nx_packet_prepend_ptr;
763 
764         /* Now, build the TFTP 0-data length message.  */
765 
766         /* Setup a pointer to the packet payload.  */
767         buffer_ptr =  packet_ptr -> nx_packet_prepend_ptr;
768 
769         /* Initial byte is always zero.  */
770         *buffer_ptr++ =  0;
771 
772         /* Set the ACK code.  */
773         *buffer_ptr++ =  NX_TFTP_CODE_DATA;
774 
775         /* Put the block number in.  */
776         *buffer_ptr++ =  (UCHAR) ((UCHAR) (tftp_client_ptr -> nx_tftp_client_block_number >> 8));
777         *buffer_ptr =    (UCHAR) ((UCHAR) (tftp_client_ptr -> nx_tftp_client_block_number & 0xFF));
778 
779         /* Adjust the packet pointers and length.  */
780         packet_ptr -> nx_packet_length =  4;
781         packet_ptr -> nx_packet_append_ptr =  packet_ptr -> nx_packet_append_ptr + 4;
782 
783         /* Send the 0-length data packet out.  */
784         status = nxd_udp_socket_send(&(tftp_client_ptr -> nx_tftp_client_socket), packet_ptr,
785                                      &tftp_client_ptr -> nx_tftp_client_server_ip,
786                                      tftp_client_ptr -> nx_tftp_client_server_port);
787 
788         /* Determine if an error occurred trying to sending the packet.  */
789         if (status)
790         {
791 
792             /* Return the unsent packet to the packet pool. */
793             nx_packet_release(packet_ptr);
794 
795             /* Enter error state.  */
796             tftp_client_ptr -> nx_tftp_client_state =  NX_TFTP_STATE_ERROR;
797 
798             /* Return error condition.  */
799             return(status);
800         }
801     }
802 
803     /* Indicate the client is finished with the file. */
804     tftp_client_ptr -> nx_tftp_client_state =  NX_TFTP_STATE_FINISHED;
805 
806     /* Return success to the caller.  */
807     return(NX_SUCCESS);
808 }
809 
810 
811 /**************************************************************************/
812 /*                                                                        */
813 /*  FUNCTION                                               RELEASE        */
814 /*                                                                        */
815 /*    _nxe_tftp_client_file_open                          PORTABLE C      */
816 /*                                                           6.1          */
817 /*  AUTHOR                                                                */
818 /*                                                                        */
819 /*    Yuxin Zhou, Microsoft Corporation                                   */
820 /*                                                                        */
821 /*  DESCRIPTION                                                           */
822 /*                                                                        */
823 /*    This function checks for errors in the TFTP file open call.         */
824 /*                                                                        */
825 /*    Note: The string length of file_name is limited by the packet       */
826 /*    payload size.                                                       */
827 /*                                                                        */
828 /*  INPUT                                                                 */
829 /*                                                                        */
830 /*    tftp_client_ptr                       Pointer to TFTP client        */
831 /*    file_name                             Pointer to file name          */
832 /*    server_ip_address                     IP address of TFTP server     */
833 /*    open_type                             Open for read or write        */
834 /*    wait_option                           Timeout for the open request  */
835 /*                                                                        */
836 /*  OUTPUT                                                                */
837 /*                                                                        */
838 /*    status                                Completion status             */
839 /*    NX_PTR_ERROR                          Invalid pointer input         */
840 /*    NX_IP_ADDRESS_ERROR                   Invalid address supplied      */
841 /*    NX_OPTION_ERROR                       Invalid TFTP option supplied  */
842 /*                                                                        */
843 /*  CALLS                                                                 */
844 /*                                                                        */
845 /*    _nx_tftp_client_file_open             Actual client file open       */
846 /*                                                                        */
847 /*  CALLED BY                                                             */
848 /*                                                                        */
849 /*    Application Code                                                    */
850 /*                                                                        */
851 /*  RELEASE HISTORY                                                       */
852 /*                                                                        */
853 /*    DATE              NAME                      DESCRIPTION             */
854 /*                                                                        */
855 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
856 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
857 /*                                            resulting in version 6.1    */
858 /*                                                                        */
859 /**************************************************************************/
_nxe_tftp_client_file_open(NX_TFTP_CLIENT * tftp_client_ptr,CHAR * file_name,ULONG server_ip_address,UINT open_type,ULONG wait_option)860 UINT  _nxe_tftp_client_file_open(NX_TFTP_CLIENT *tftp_client_ptr, CHAR *file_name, ULONG server_ip_address, UINT open_type, ULONG wait_option)
861 {
862 
863 #ifndef NX_DISABLE_IPV4
864 UINT    status;
865 
866 
867     /* Check for invalid input pointers.  */
868     if ((tftp_client_ptr == NX_NULL) || (tftp_client_ptr -> nx_tftp_client_id != NXD_TFTP_CLIENT_ID))
869         return(NX_PTR_ERROR);
870 
871     /* Check for an invalid server IP address.  */
872     if (server_ip_address == 0)
873         return(NX_IP_ADDRESS_ERROR);
874 
875     /* Check for illegal open option type. */
876     if ((open_type != NX_TFTP_OPEN_FOR_READ) && (open_type != NX_TFTP_OPEN_FOR_WRITE))
877         return(NX_OPTION_ERROR);
878 
879     /* Check for appropriate caller.  */
880     NX_THREADS_ONLY_CALLER_CHECKING
881 
882     /* Call actual client file open function.  */
883     status =  _nx_tftp_client_file_open(tftp_client_ptr, file_name, server_ip_address, open_type, wait_option);
884 
885     /* Return completion status.  */
886     return(status);
887 #else
888     NX_PARAMETER_NOT_USED(tftp_client_ptr);
889     NX_PARAMETER_NOT_USED(file_name);
890     NX_PARAMETER_NOT_USED(server_ip_address);
891     NX_PARAMETER_NOT_USED(open_type);
892     NX_PARAMETER_NOT_USED(wait_option);
893 
894     return(NX_NOT_SUPPORTED);
895 #endif /* NX_DISABLE_IPV4 */
896 }
897 
898 /**************************************************************************/
899 /*                                                                        */
900 /*  FUNCTION                                               RELEASE        */
901 /*                                                                        */
902 /*    _nx_tftp_client_file_open                           PORTABLE C      */
903 /*                                                           6.1          */
904 /*  AUTHOR                                                                */
905 /*                                                                        */
906 /*    Yuxin Zhou, Microsoft Corporation                                   */
907 /*                                                                        */
908 /*  DESCRIPTION                                                           */
909 /*                                                                        */
910 /*    This function opens a TFTP file.                                    */
911 /*                                                                        */
912 /*    Note: The string length of file_name is limited by the packet       */
913 /*    payload size.                                                       */
914 /*                                                                        */
915 /*  INPUT                                                                 */
916 /*                                                                        */
917 /*    tftp_client_ptr                       Pointer to TFTP client        */
918 /*    file_name                             Pointer to file name          */
919 /*    tftp_server_address                   IP address of TFTP server     */
920 /*    open_type                             Open for read or write        */
921 /*    wait_option                           Timeout for the open request  */
922 /*                                                                        */
923 /*  OUTPUT                                                                */
924 /*                                                                        */
925 /*    status                                Completion status             */
926 /*                                                                        */
927 /*  CALLS                                                                 */
928 /*                                                                        */
929 /*    _nx_tftp_client_file_open_internal    Actual open service           */
930 /*                                                                        */
931 /*  CALLED BY                                                             */
932 /*                                                                        */
933 /*    Application Code                                                    */
934 /*                                                                        */
935 /*  RELEASE HISTORY                                                       */
936 /*                                                                        */
937 /*    DATE              NAME                      DESCRIPTION             */
938 /*                                                                        */
939 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
940 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
941 /*                                            resulting in version 6.1    */
942 /*                                                                        */
943 /**************************************************************************/
_nx_tftp_client_file_open(NX_TFTP_CLIENT * tftp_client_ptr,CHAR * file_name,ULONG server_ip_address,UINT open_type,ULONG wait_option)944 UINT  _nx_tftp_client_file_open(NX_TFTP_CLIENT *tftp_client_ptr, CHAR *file_name, ULONG server_ip_address, UINT open_type, ULONG wait_option)
945 {
946 #ifndef NX_DISABLE_IPV4
947 UINT        status;
948 
949 
950 NXD_ADDRESS server_address;
951 
952     /* Create the IPv4 address block. Set the version to IPv4. */
953     server_address.nxd_ip_version = NX_IP_VERSION_V4;
954     server_address.nxd_ip_address.v4 = server_ip_address;
955 
956     /* Call the actual file open service. */
957     status = _nx_tftp_client_file_open_internal(tftp_client_ptr, file_name, &server_address, open_type, wait_option, NX_IP_VERSION_V4);
958 
959 
960     /* Return the completion status. */
961     return status;
962 #else
963     NX_PARAMETER_NOT_USED(tftp_client_ptr);
964     NX_PARAMETER_NOT_USED(file_name);
965     NX_PARAMETER_NOT_USED(server_ip_address);
966     NX_PARAMETER_NOT_USED(open_type);
967     NX_PARAMETER_NOT_USED(wait_option);
968 
969     return(NX_NOT_SUPPORTED);
970 #endif /* NX_DISABLE_IPV4 */
971 }
972 
973 
974 /**************************************************************************/
975 /*                                                                        */
976 /*  FUNCTION                                               RELEASE        */
977 /*                                                                        */
978 /*    _nxde_tftp_client_file_open                         PORTABLE C      */
979 /*                                                           6.1          */
980 /*  AUTHOR                                                                */
981 /*                                                                        */
982 /*    Yuxin Zhou, Microsoft Corporation                                   */
983 /*                                                                        */
984 /*  DESCRIPTION                                                           */
985 /*                                                                        */
986 /*    This function checks for errors in the TFTP file open call.         */
987 /*                                                                        */
988 /*    Note: The string length of file_name is limited by the packet       */
989 /*    payload size.                                                       */
990 /*                                                                        */
991 /*  INPUT                                                                 */
992 /*                                                                        */
993 /*    tftp_client_ptr                       Pointer to TFTP client        */
994 /*    file_name                             Pointer to file name          */
995 /*    server_ip_address                     IP address of TFTP server     */
996 /*    open_type                             Open for read or write        */
997 /*    wait_option                           Timeout for the open request  */
998 /*    ip_type                               IP type                       */
999 /*                                                                        */
1000 /*  OUTPUT                                                                */
1001 /*                                                                        */
1002 /*    status                                Completion status             */
1003 /*    NX_PTR_ERROR                          Invalid pointer input         */
1004 /*    NX_INVALID_PARAMETERS                 Invalid non pointer input     */
1005 /*    NX_IP_ADDRESS_ERROR                   Invalid address supplied      */
1006 /*    NX_OPTION_ERROR                       Invalid TFTP option supplied  */
1007 /*                                                                        */
1008 /*  CALLS                                                                 */
1009 /*                                                                        */
1010 /*    _nxd_tftp_client_file_open            Actual client file open       */
1011 /*                                                                        */
1012 /*  CALLED BY                                                             */
1013 /*                                                                        */
1014 /*    Application Code                                                    */
1015 /*                                                                        */
1016 /*  RELEASE HISTORY                                                       */
1017 /*                                                                        */
1018 /*    DATE              NAME                      DESCRIPTION             */
1019 /*                                                                        */
1020 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
1021 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
1022 /*                                            resulting in version 6.1    */
1023 /*                                                                        */
1024 /**************************************************************************/
_nxde_tftp_client_file_open(NX_TFTP_CLIENT * tftp_client_ptr,CHAR * file_name,NXD_ADDRESS * server_ip_address,UINT open_type,ULONG wait_option,UINT ip_type)1025 UINT  _nxde_tftp_client_file_open(NX_TFTP_CLIENT *tftp_client_ptr, CHAR *file_name, NXD_ADDRESS *server_ip_address, UINT open_type, ULONG wait_option, UINT ip_type)
1026 {
1027 
1028 UINT    status;
1029 
1030 
1031     /* Check for invalid input pointers.  */
1032     if ((tftp_client_ptr == NX_NULL) || (tftp_client_ptr -> nx_tftp_client_id != NXD_TFTP_CLIENT_ID))
1033         return(NX_PTR_ERROR);
1034 
1035     /* Check for an invalid server IP address.  */
1036     if (!server_ip_address)
1037         return(NX_IP_ADDRESS_ERROR);
1038 
1039     /* Check for valid IP version*/
1040     if ((ip_type != NX_IP_VERSION_V4) && (ip_type != NX_IP_VERSION_V6))
1041     {
1042         return NX_INVALID_PARAMETERS;
1043     }
1044 
1045     /* Check for illegal open option type. */
1046     if ((open_type != NX_TFTP_OPEN_FOR_READ) && (open_type != NX_TFTP_OPEN_FOR_WRITE))
1047         return(NX_OPTION_ERROR);
1048 
1049     /* Check for appropriate caller.  */
1050     NX_THREADS_ONLY_CALLER_CHECKING
1051 
1052     /* Call actual client file open function.  */
1053     status =  _nxd_tftp_client_file_open(tftp_client_ptr, file_name, server_ip_address, open_type, wait_option, ip_type);
1054 
1055     /* Return completion status.  */
1056     return(status);
1057 }
1058 
1059 
1060 /**************************************************************************/
1061 /*                                                                        */
1062 /*  FUNCTION                                               RELEASE        */
1063 /*                                                                        */
1064 /*    _nxd_tftp_client_file_open                          PORTABLE C      */
1065 /*                                                           6.1          */
1066 /*  AUTHOR                                                                */
1067 /*                                                                        */
1068 /*    Yuxin Zhou, Microsoft Corporation                                   */
1069 /*                                                                        */
1070 /*  DESCRIPTION                                                           */
1071 /*                                                                        */
1072 /*    This function opens a TFTP file received over IPv4 or IPv6 networks.*/
1073 /*                                                                        */
1074 /*    Note: The string length of file_name is limited by the packet       */
1075 /*    payload size.                                                       */
1076 /*                                                                        */
1077 /*  INPUT                                                                 */
1078 /*                                                                        */
1079 /*    tftp_client_ptr                       Pointer to TFTP client        */
1080 /*    file_name                             Pointer to file name          */
1081 /*    tftp_server_address                   IP address of TFTP server     */
1082 /*    open_type                             Open for read or write        */
1083 /*    wait_option                           Timeout for the open request  */
1084 /*    ip_type                               IP type                       */
1085 /*                                                                        */
1086 /*  OUTPUT                                                                */
1087 /*                                                                        */
1088 /*    status                                Completion status             */
1089 /*    NX_TFTP_INVALID_IP_VERSION            Unsupported IP protocol       */
1090 /*    NX_TFTP_NO_ACK_RECEIVED               ACK not received from Server  */
1091 /*    NX_TFTP_NOT_CLOSED                    TFTP client file already open */
1092 /*    NX_TFTP_INVALID_SERVER_ADDRESS        Reply from unknown Server     */
1093 /*                                                                        */
1094 /*  CALLS                                                                 */
1095 /*                                                                        */
1096 /*    _nx_tftp_client_file_open_internal    Actual open service           */
1097 /*                                                                        */
1098 /*  CALLED BY                                                             */
1099 /*                                                                        */
1100 /*    Application Code                                                    */
1101 /*                                                                        */
1102 /*  RELEASE HISTORY                                                       */
1103 /*                                                                        */
1104 /*    DATE              NAME                      DESCRIPTION             */
1105 /*                                                                        */
1106 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
1107 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
1108 /*                                            resulting in version 6.1    */
1109 /*                                                                        */
1110 /**************************************************************************/
_nxd_tftp_client_file_open(NX_TFTP_CLIENT * tftp_client_ptr,CHAR * file_name,NXD_ADDRESS * server_ip_address,UINT open_type,ULONG wait_option,UINT ip_type)1111 UINT  _nxd_tftp_client_file_open(NX_TFTP_CLIENT *tftp_client_ptr, CHAR *file_name, NXD_ADDRESS *server_ip_address, UINT open_type, ULONG wait_option, UINT ip_type)
1112 {
1113 
1114 UINT        status;
1115 
1116 
1117     /* Call the actual file open service. */
1118     status = _nx_tftp_client_file_open_internal(tftp_client_ptr, file_name, server_ip_address, open_type, wait_option, ip_type);
1119 
1120     /* Return the completion status. */
1121     return status;
1122 }
1123 
1124 
1125 /**************************************************************************/
1126 /*                                                                        */
1127 /*  FUNCTION                                               RELEASE        */
1128 /*                                                                        */
1129 /*    _nx_tftp_client_file_open_internal                  PORTABLE C      */
1130 /*                                                           6.1          */
1131 /*  AUTHOR                                                                */
1132 /*                                                                        */
1133 /*    Yuxin Zhou, Microsoft Corporation                                   */
1134 /*                                                                        */
1135 /*  DESCRIPTION                                                           */
1136 /*                                                                        */
1137 /*    This function opens a TFTP file received.                           */
1138 /*                                                                        */
1139 /*                                                                        */
1140 /*  INPUT                                                                 */
1141 /*                                                                        */
1142 /*    tftp_client_ptr                       Pointer to TFTP client        */
1143 /*    file_name                             Pointer to file name          */
1144 /*    tftp_server_address                   IP address of TFTP server     */
1145 /*    open_type                             Open for read or write        */
1146 /*    wait_option                           Timeout for the open request  */
1147 /*    ip_type                               IP type                       */
1148 /*                                                                        */
1149 /*  OUTPUT                                                                */
1150 /*                                                                        */
1151 /*    status                                Completion status             */
1152 /*    NX_TFTP_INVALID_IP_VERSION            Unsupported IP protocol       */
1153 /*    NX_TFTP_NO_ACK_RECEIVED               ACK not received from Server  */
1154 /*    NX_TFTP_NOT_CLOSED                    TFTP client file already open */
1155 /*    NX_TFTP_INVALID_SERVER_ADDRESS        Reply from unknown Server     */
1156 /*                                                                        */
1157 /*  CALLS                                                                 */
1158 /*                                                                        */
1159 /*    nx_packet_allocate                    Allocate packet for TFTP      */
1160 /*                                            request or data             */
1161 /*    nx_packet_release                     Release packet                */
1162 /*    nx_udp_socket_receive                 Receive UDP data packet       */
1163 /*    nxd_udp_socket_send                   Send UDP data packet          */
1164 /*    nxd_udp_source_extract                Extract IP and port from msg  */
1165 /*                                                                        */
1166 /*  CALLED BY                                                             */
1167 /*                                                                        */
1168 /*    Application Code                                                    */
1169 /*                                                                        */
1170 /*  RELEASE HISTORY                                                       */
1171 /*                                                                        */
1172 /*    DATE              NAME                      DESCRIPTION             */
1173 /*                                                                        */
1174 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
1175 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
1176 /*                                            resulting in version 6.1    */
1177 /*                                                                        */
1178 /**************************************************************************/
_nx_tftp_client_file_open_internal(NX_TFTP_CLIENT * tftp_client_ptr,CHAR * file_name,NXD_ADDRESS * server_ip_address,UINT open_type,ULONG wait_option,UINT ip_type)1179 UINT  _nx_tftp_client_file_open_internal(NX_TFTP_CLIENT *tftp_client_ptr, CHAR *file_name, NXD_ADDRESS *server_ip_address, UINT open_type, ULONG wait_option, UINT  ip_type)
1180 
1181 {
1182 
1183 UINT        status;
1184 UINT        i;
1185 NXD_ADDRESS ip_address;
1186 
1187 UINT        port;
1188 UCHAR       *buffer_ptr;
1189 NX_PACKET   *packet_ptr;
1190 UINT        matching = NX_FALSE;
1191 
1192 
1193     /* Determine if the TFTP instance is already open.  */
1194     if ((tftp_client_ptr -> nx_tftp_client_state == NX_TFTP_STATE_OPEN) ||
1195         (tftp_client_ptr -> nx_tftp_client_state == NX_TFTP_STATE_WRITE_OPEN))
1196     {
1197 
1198         /* This instance is already open, return an error.  */
1199         return(NX_TFTP_NOT_CLOSED);
1200     }
1201 
1202     /* Enter the open state.  */
1203     tftp_client_ptr -> nx_tftp_client_state =  NX_TFTP_STATE_OPEN;
1204 
1205     /* Save the server's IP address.  */
1206 
1207     if (ip_type == NX_IP_VERSION_V6)
1208     {
1209 
1210 #ifndef FEATURE_NX_IPV6
1211         return NX_TFTP_INVALID_IP_VERSION;
1212 #else
1213         COPY_NXD_ADDRESS(server_ip_address, &tftp_client_ptr -> nx_tftp_client_server_ip);
1214 #endif
1215     }
1216     else
1217     {
1218 
1219 #ifndef NX_DISABLE_IPV4
1220         /* If not IPv6, assume the client IP request is using IPv4 if not explicitly specified. */
1221         tftp_client_ptr -> nx_tftp_client_server_ip.nxd_ip_version = ip_type;
1222         tftp_client_ptr -> nx_tftp_client_server_ip.nxd_ip_address.v4 = server_ip_address -> nxd_ip_address.v4;
1223 #else
1224         return NX_TFTP_INVALID_IP_VERSION;
1225 #endif /* NX_DISABLE_IPV4 */
1226     }
1227 
1228     /* Initialize the server port number.  This can change after the open request.  */
1229     tftp_client_ptr -> nx_tftp_client_server_port =  NX_TFTP_SERVER_PORT;
1230 
1231     /* Clear the error code.  */
1232     tftp_client_ptr -> nx_tftp_client_error_code =    0;
1233 
1234     /* Specify that the first block.  */
1235     tftp_client_ptr -> nx_tftp_client_block_number =  1;
1236 
1237     /* Allocate a packet for initial open request message. Determine whether we are sending
1238        IPv4 or IPv6 packets.   */
1239 
1240     if (ip_type == NX_IP_VERSION_V4)
1241     {
1242 
1243         status =  nx_packet_allocate((tftp_client_ptr -> nx_tftp_client_ip_ptr) -> nx_ip_default_packet_pool,
1244                                      &packet_ptr, NX_IPv4_UDP_PACKET, wait_option);
1245     }
1246     else
1247     {
1248 
1249         status =  nx_packet_allocate((tftp_client_ptr -> nx_tftp_client_ip_ptr) -> nx_ip_default_packet_pool,
1250                                      &packet_ptr, NX_IPv6_UDP_PACKET, wait_option);
1251     }
1252 
1253     /* Determine if an error occurred trying to allocate a packet.  */
1254     if (status != NX_SUCCESS)
1255     {
1256 
1257         /* Enter error state.  */
1258         tftp_client_ptr -> nx_tftp_client_state =  NX_TFTP_STATE_ERROR;
1259 
1260         /* Return error condition.  */
1261         return(status);
1262     }
1263 
1264     packet_ptr -> nx_packet_append_ptr = packet_ptr -> nx_packet_prepend_ptr;
1265 
1266     /* Now, build the TFTP open request.  */
1267 
1268     /* Setup a pointer to the packet payload.  */
1269     buffer_ptr =  packet_ptr -> nx_packet_prepend_ptr;
1270 
1271     /* Initial byte is always zero.  */
1272     *buffer_ptr++ =  0;
1273 
1274     /* Determine the type of open requested.  */
1275     if (open_type == NX_TFTP_OPEN_FOR_READ)
1276         *buffer_ptr++ =  NX_TFTP_CODE_READ;
1277     else
1278         *buffer_ptr++ =  NX_TFTP_CODE_WRITE;
1279 
1280     /* Now place the file name in the buffer.  */
1281     i = 0;
1282     while (file_name[i] && (ULONG)(packet_ptr -> nx_packet_data_end - buffer_ptr) > 7u)
1283     {
1284 
1285         /* Store character of file name into request.  */
1286         *buffer_ptr++ =  (UCHAR) file_name[i];
1287         i++;
1288     }
1289 
1290     /* Place a NULL after the file name.  */
1291     *buffer_ptr++ =  NX_NULL;
1292 
1293     /* Now place the mode string.  */
1294     *buffer_ptr++ =  (UCHAR) 'O';
1295     *buffer_ptr++ =  (UCHAR) 'C';
1296     *buffer_ptr++ =  (UCHAR) 'T';
1297     *buffer_ptr++ =  (UCHAR) 'E';
1298     *buffer_ptr++ =  (UCHAR) 'T';
1299 
1300     /* Place a NULL after the mode.  */
1301     *buffer_ptr++ =  NX_NULL;
1302 
1303     /* Adjust the packet length and the append pointer.  */
1304     packet_ptr -> nx_packet_append_ptr =  buffer_ptr;
1305     packet_ptr -> nx_packet_length =  (ULONG)(buffer_ptr - packet_ptr -> nx_packet_prepend_ptr);
1306 
1307     /* Now send the open request to the TFTP server.  */
1308     status =  nxd_udp_socket_send(&(tftp_client_ptr -> nx_tftp_client_socket), packet_ptr,
1309                                     server_ip_address, tftp_client_ptr -> nx_tftp_client_server_port);
1310 
1311 
1312     /* Check for error condition.  */
1313     if (status != NX_SUCCESS)
1314     {
1315 
1316         nx_packet_release(packet_ptr);
1317 
1318         /* Enter error state.  */
1319         tftp_client_ptr -> nx_tftp_client_state =  NX_TFTP_STATE_ERROR;
1320 
1321         /* Return error condition.  */
1322         return(status);
1323     }
1324 
1325     /* Determine if the TFTP file was open for writing.  */
1326     if (open_type == NX_TFTP_OPEN_FOR_WRITE)
1327     {
1328 
1329         /* Change to the open for writing state.  */
1330         tftp_client_ptr -> nx_tftp_client_state =  NX_TFTP_STATE_WRITE_OPEN;
1331 
1332         /* Open for write request is present.  We now need to wait for the ACK of block number 0
1333            from the server.  */
1334         status =  nx_udp_socket_receive(&(tftp_client_ptr -> nx_tftp_client_socket), &packet_ptr, wait_option);
1335 
1336         /* Check the return status.  */
1337         if (status != NX_SUCCESS)
1338         {
1339 
1340             /* Enter error state.  */
1341             tftp_client_ptr -> nx_tftp_client_state =  NX_TFTP_STATE_ERROR;
1342 
1343             /* Return error condition.  */
1344             return(status);
1345         }
1346 
1347         /* Check for valid packet length (The minimum TFTP header size is ACK packet, four bytes).  */
1348         if (packet_ptr -> nx_packet_length < 4)
1349         {
1350 
1351             /* Release the packet. */
1352             nx_packet_release(packet_ptr);
1353 
1354             /* Return.  */
1355             return(NX_INVALID_PACKET);
1356         }
1357 
1358         /* Extract the source IP and port numbers.  */
1359         status = nxd_udp_source_extract(packet_ptr, &ip_address, &port);
1360 
1361 
1362         /* Check for an invalid server IP address.  */
1363 
1364 #ifndef NX_DISABLE_IPV4
1365         if ((ip_type == NX_IP_VERSION_V4)&&
1366            (ip_address.nxd_ip_address.v4 == tftp_client_ptr -> nx_tftp_client_server_ip.nxd_ip_address.v4))
1367         {
1368 
1369             matching = NX_TRUE;
1370         }
1371         else
1372 #endif /* NX_DISABLE_IPV4 */
1373 #ifdef FEATURE_NX_IPV6
1374         if (ip_type == NX_IP_VERSION_V6)
1375         {
1376 
1377             if (CHECK_IPV6_ADDRESSES_SAME(&ip_address.nxd_ip_address.v6[0], &tftp_client_ptr -> nx_tftp_client_server_ip.nxd_ip_address.v6[0]))
1378             {
1379 
1380                 matching = NX_TRUE;
1381             }
1382         }
1383         else
1384 #endif
1385         {
1386             /* Release the packet.  */
1387             nx_packet_release(packet_ptr);
1388 
1389             return NX_TFTP_INVALID_IP_VERSION;
1390         }
1391 
1392         /* Do we have a match? */
1393         if (!matching)
1394         {
1395             /* No, invalid IP address!  */
1396 
1397             /* Enter error state.  */
1398             tftp_client_ptr -> nx_tftp_client_state =  NX_TFTP_STATE_ERROR;
1399 
1400             /* Release the packet.  */
1401             nx_packet_release(packet_ptr);
1402 
1403             /* Return error condition.  */
1404             return(NX_TFTP_INVALID_SERVER_ADDRESS);
1405         }
1406 
1407         /* Save the source port since the server can change its port.  */
1408         tftp_client_ptr -> nx_tftp_client_server_port =  port;
1409 
1410         /* Check for valid server ACK.  */
1411 
1412         /* Setup a pointer to the packet payload.  */
1413         buffer_ptr =  packet_ptr -> nx_packet_prepend_ptr;
1414 
1415         /* Check for valid ACK message.  */
1416         if ((buffer_ptr[0] != 0) || (buffer_ptr[1] != NX_TFTP_CODE_ACK) ||
1417             (buffer_ptr[2] != 0) || (buffer_ptr[3] != 0) ||
1418             (packet_ptr -> nx_packet_length != 4))
1419         {
1420 
1421             UINT code;
1422 
1423             /* Enter error state.  */
1424             tftp_client_ptr -> nx_tftp_client_state =  NX_TFTP_STATE_ERROR;
1425 
1426             /* Get the error status from the server message. */
1427             buffer_ptr++;
1428             code =  *(buffer_ptr);
1429 
1430             /* If this is a server error, save it to the TFTP client. */
1431             if (code == NX_TFTP_CODE_ERROR)
1432             {
1433 
1434                 buffer_ptr++;
1435                 tftp_client_ptr -> nx_tftp_client_error_code =  ((UINT) (*buffer_ptr)) << 8;
1436                 buffer_ptr++;
1437                 tftp_client_ptr -> nx_tftp_client_error_code |= (UINT) (*buffer_ptr);
1438                 buffer_ptr++;
1439 
1440                 /* Loop to save error message to TFTP Client.  */
1441                 tftp_client_ptr -> nx_tftp_client_error_string[sizeof(tftp_client_ptr -> nx_tftp_client_error_string) - 1] =  NX_NULL;
1442                 for (i = 0; i < NX_TFTP_ERROR_STRING_MAX; i++)
1443                 {
1444 
1445                     /* Store desired file name.  */
1446                     tftp_client_ptr -> nx_tftp_client_error_string[i] =  (CHAR) *buffer_ptr++;
1447 
1448                     /* Check for NULL character.  */
1449                     if (tftp_client_ptr -> nx_tftp_client_error_string[i] == NX_NULL)
1450                     {
1451                         break;
1452                     }
1453                 }
1454 
1455                 /* Release the packet.  */
1456                 nx_packet_release(packet_ptr);
1457 
1458                 /* Return error condition.  */
1459                 return(NX_TFTP_CODE_ERROR);
1460             }
1461             /* Unknown code, not an error or an ACK. */
1462             else
1463             {
1464 
1465                 /* Release the packet.  */
1466                 nx_packet_release(packet_ptr);
1467 
1468                 /* Return error condition.  */
1469                 return(NX_TFTP_NO_ACK_RECEIVED);
1470             }
1471         }
1472 
1473         /* Release the packet.  */
1474         nx_packet_release(packet_ptr);
1475     }
1476 
1477     /* Otherwise, return success!  */
1478     return(NX_SUCCESS);
1479 }
1480 
1481 
1482 /**************************************************************************/
1483 /*                                                                        */
1484 /*  FUNCTION                                               RELEASE        */
1485 /*                                                                        */
1486 /*    _nxde_tftp_client_file_read                         PORTABLE C      */
1487 /*                                                           6.1          */
1488 /*  AUTHOR                                                                */
1489 /*                                                                        */
1490 /*    Yuxin Zhou, Microsoft Corporation                                   */
1491 /*                                                                        */
1492 /*  DESCRIPTION                                                           */
1493 /*                                                                        */
1494 /*    This function checks for errors in the TFTP file read call.         */
1495 /*                                                                        */
1496 /*                                                                        */
1497 /*  INPUT                                                                 */
1498 /*                                                                        */
1499 /*    tftp_client_ptr                       Pointer to TFTP client        */
1500 /*    packet_ptr                            Pointer to destination for    */
1501 /*                                            return packet pointer       */
1502 /*    wait_option                           Timeout for the read request  */
1503 /*    ip_type                               IP type                       */
1504 /*                                                                        */
1505 /*  OUTPUT                                                                */
1506 /*                                                                        */
1507 /*    status                                Completion status             */
1508 /*    NX_PTR_ERROR                          Invalid pointer input         */
1509 /*    NX_INVALID_PARAMETERS                 Invalid non pointer input     */
1510 /*                                                                        */
1511 /*  CALLS                                                                 */
1512 /*                                                                        */
1513 /*    _nxd_tftp_client_file_read             Actual client file read      */
1514 /*                                                                        */
1515 /*  CALLED BY                                                             */
1516 /*                                                                        */
1517 /*    Application Code                                                    */
1518 /*                                                                        */
1519 /*  RELEASE HISTORY                                                       */
1520 /*                                                                        */
1521 /*    DATE              NAME                      DESCRIPTION             */
1522 /*                                                                        */
1523 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
1524 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
1525 /*                                            resulting in version 6.1    */
1526 /*                                                                        */
1527 /**************************************************************************/
_nxde_tftp_client_file_read(NX_TFTP_CLIENT * tftp_client_ptr,NX_PACKET ** packet_ptr,ULONG wait_option,UINT ip_type)1528 UINT  _nxde_tftp_client_file_read(NX_TFTP_CLIENT *tftp_client_ptr, NX_PACKET **packet_ptr, ULONG wait_option, UINT ip_type)
1529 {
1530 
1531 UINT    status;
1532 
1533 
1534     /* Check for invalid input pointers.  */
1535     if ((tftp_client_ptr == NX_NULL) || (tftp_client_ptr -> nx_tftp_client_id != NXD_TFTP_CLIENT_ID) ||
1536         (packet_ptr == NX_NULL))
1537         return(NX_PTR_ERROR);
1538 
1539     /* Check for valid IP version*/
1540     if ((ip_type != NX_IP_VERSION_V4) && (ip_type != NX_IP_VERSION_V6))
1541     {
1542         return NX_INVALID_PARAMETERS;
1543     }
1544 
1545     /* Check for appropriate caller.  */
1546     NX_THREADS_ONLY_CALLER_CHECKING
1547 
1548     /* Call actual client file read function.  */
1549     status =  _nxd_tftp_client_file_read(tftp_client_ptr, packet_ptr, wait_option, ip_type);
1550 
1551     /* Return completion status.  */
1552     return(status);
1553 }
1554 
1555 /**************************************************************************/
1556 /*                                                                        */
1557 /*  FUNCTION                                               RELEASE        */
1558 /*                                                                        */
1559 /*    _nxd_tftp_client_file_read                          PORTABLE C      */
1560 /*                                                           6.1          */
1561 /*  AUTHOR                                                                */
1562 /*                                                                        */
1563 /*    Yuxin Zhou, Microsoft Corporation                                   */
1564 /*                                                                        */
1565 /*  DESCRIPTION                                                           */
1566 /*                                                                        */
1567 /*    This function reads a buffer from a previously opened TFTP file.    */
1568 /*                                                                        */
1569 /*                                                                        */
1570 /*  INPUT                                                                 */
1571 /*                                                                        */
1572 /*    tftp_client_ptr                       Pointer to TFTP client        */
1573 /*    packet_ptr                            Pointer to destination for    */
1574 /*                                            return packet pointer       */
1575 /*    wait_option                           Timeout for the read request  */
1576 /*    ip_type                               IP type                       */
1577 /*                                                                        */
1578 /*  OUTPUT                                                                */
1579 /*                                                                        */
1580 /*    status                                Completion status             */
1581 /*    NX_TFTP_CLIENT_NOT_OPEN               Requested file not open       */
1582 /*    NX_TFTP_INVALID_SERVER_ADDRESS        Reply from unknown Server     */
1583 /*    NX_TFTP_INVALID_IP_VERSION            Unsupported IP protocol       */
1584 /*    NX_TFTP_END_OF_FILE                   No more data in file          */
1585 /*    NX_TFTP_INVALID_BLOCK_NUMBER          Mismatching block number in   */
1586 /*                                            received TFTP packet        */
1587 /*    NX_TFTP_CODE_ERROR                    Unknown TFTP code received    */
1588 /*                                                                        */
1589 /*  CALLS                                                                 */
1590 /*                                                                        */
1591 /*    nx_packet_allocate                    Allocate packet for ACK packet*/
1592 /*    nx_packet_release                     Release packet                */
1593 /*    nx_udp_socket_receive                 Receive UDP data packet       */
1594 /*    nxd_udp_socket_send                   Send TFTP ACK packet          */
1595 /*    nxd_udp_source_extract                Extract IP and port from msg  */
1596 /*                                                                        */
1597 /*  CALLED BY                                                             */
1598 /*                                                                        */
1599 /*    Application Code                                                    */
1600 /*                                                                        */
1601 /*  RELEASE HISTORY                                                       */
1602 /*                                                                        */
1603 /*    DATE              NAME                      DESCRIPTION             */
1604 /*                                                                        */
1605 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
1606 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
1607 /*                                            resulting in version 6.1    */
1608 /*                                                                        */
1609 /**************************************************************************/
_nxd_tftp_client_file_read(NX_TFTP_CLIENT * tftp_client_ptr,NX_PACKET ** packet_ptr,ULONG wait_option,UINT ip_type)1610 UINT  _nxd_tftp_client_file_read(NX_TFTP_CLIENT *tftp_client_ptr, NX_PACKET **packet_ptr, ULONG wait_option, UINT ip_type)
1611 {
1612 
1613 UCHAR       *buffer_ptr;
1614 UINT        status;
1615 NXD_ADDRESS ip_address;
1616 UINT        port;
1617 UINT        i;
1618 USHORT      block_number;
1619 UCHAR       code;
1620 NX_PACKET   *ack_packet;
1621 UINT         matching = NX_FALSE;
1622 UCHAR       resend_ACK_packet = NX_FALSE;
1623 
1624 
1625     /* Determine if we are still in an open state.  */
1626     if (tftp_client_ptr -> nx_tftp_client_state != NX_TFTP_STATE_OPEN)
1627     {
1628 
1629         /* This instance is not open, return an error.  */
1630         if (tftp_client_ptr -> nx_tftp_client_state == NX_TFTP_STATE_END_OF_FILE)
1631             return(NX_TFTP_END_OF_FILE);
1632         else
1633             return(NX_TFTP_NOT_OPEN);
1634     }
1635 
1636     /* Read the next block of the file.  */
1637     status =  nx_udp_socket_receive(&(tftp_client_ptr -> nx_tftp_client_socket), packet_ptr, wait_option);
1638 
1639     /* Check the return status.  */
1640     if (status != NX_SUCCESS)
1641     {
1642 
1643         /* Check for the type of error.  */
1644         if (status != NX_NO_PACKET)
1645         {
1646 
1647             /* Serious error, enter error state.  */
1648             tftp_client_ptr -> nx_tftp_client_state =  NX_TFTP_STATE_ERROR;
1649         }
1650 
1651         /* Return error condition.  */
1652         return(status);
1653     }
1654 
1655     /* Check for valid packet length (The minimum TFTP header size is ACK packet, four bytes).  */
1656     if ((*packet_ptr) -> nx_packet_length < 4)
1657     {
1658 
1659         /* Release the packet. */
1660         nx_packet_release(*packet_ptr);
1661 
1662         /* Return.  */
1663         return(NX_INVALID_PACKET);
1664     }
1665 
1666     /* At this point, we have a block of the file from the server.  */
1667 
1668     /* Extract the source IP and port numbers.  */
1669     nxd_udp_source_extract(*packet_ptr, &ip_address, &port);
1670 
1671     /* Check for an invalid server IP address.  */
1672 
1673 #ifndef NX_DISABLE_IPV4
1674     if (ip_type == NX_IP_VERSION_V4)
1675     {
1676 
1677         if (ip_address.nxd_ip_address.v4 == tftp_client_ptr -> nx_tftp_client_server_ip.nxd_ip_address.v4)
1678         {
1679             matching = NX_TRUE;
1680         }
1681     }
1682     else
1683 #endif /* NX_DISABLE_IPV4 */
1684 #ifdef FEATURE_NX_IPV6
1685     if (ip_type == NX_IP_VERSION_V6)
1686     {
1687         if (CHECK_IPV6_ADDRESSES_SAME(&ip_address.nxd_ip_address.v6[0], &tftp_client_ptr -> nx_tftp_client_server_ip.nxd_ip_address.v6[0]))
1688         {
1689 
1690             matching = NX_TRUE;
1691         }
1692     }
1693     else
1694 #endif
1695     {
1696 
1697         /* Release the packet.  */
1698         nx_packet_release(*packet_ptr);
1699 
1700         return NX_TFTP_INVALID_IP_VERSION;
1701     }
1702 
1703     /* Do we have a match? */
1704     if (matching == NX_FALSE)
1705     {
1706 
1707         /* No, Invalid IP address!  */
1708 
1709         /* Enter error state.  */
1710         tftp_client_ptr -> nx_tftp_client_state =  NX_TFTP_STATE_ERROR;
1711 
1712         /* Release the packet.  */
1713         nx_packet_release(*packet_ptr);
1714 
1715         /* Set packet pointer to NULL.  */
1716         *packet_ptr =  NX_NULL;
1717 
1718         /* Return error condition.  */
1719         return(NX_TFTP_INVALID_SERVER_ADDRESS);
1720     }
1721 
1722     /* Save the source port since the server can change its port.  */
1723     tftp_client_ptr -> nx_tftp_client_server_port =  port;
1724 
1725     /* Setup a pointer to the buffer.  */
1726     buffer_ptr =  (*packet_ptr) -> nx_packet_prepend_ptr;
1727 
1728     /* Pickup the type of packet.  */
1729     buffer_ptr++;
1730     code =  *buffer_ptr;
1731 
1732     /* Is a data packet present?  */
1733     if (code == NX_TFTP_CODE_DATA)
1734     {
1735 
1736         /* Yes, a data packet is present.  */
1737 
1738         /* Pickup the block number.  */
1739         buffer_ptr++;
1740         block_number = (USHORT)((*buffer_ptr) << 8);
1741         buffer_ptr++;
1742         block_number = (USHORT)(block_number | (*buffer_ptr));
1743 
1744         /* Check if the server didn't receive last TFTP ACK. */
1745         if ((USHORT)(tftp_client_ptr -> nx_tftp_client_block_number - 1) == block_number)
1746         {
1747 
1748             /*  The Server will resend previous packet till it times out.
1749                 set a flag to indicate we need to resend the ACK packet to
1750                 prevent this. */
1751             resend_ACK_packet = NX_TRUE;
1752         }
1753         /* Is there a block number match (greater than 1) ?  */
1754         else if (tftp_client_ptr -> nx_tftp_client_block_number != block_number)
1755         {
1756 
1757             /* Block numbers don't match.  Invalid packet or old data packet. Discard it. */
1758 
1759             /* Release the packet.  */
1760             nx_packet_release(*packet_ptr);
1761 
1762             /* Set packet pointer to NULL.  */
1763             *packet_ptr =  NX_NULL;
1764 
1765             /* Return error condition.  */
1766             return(NX_TFTP_INVALID_BLOCK_NUMBER);
1767         }
1768 
1769         /* Valid block number, end ACK back to server.  */
1770 
1771         /* Allocate a new packet for the ACK message.  Determine whether we are sending
1772            IPv4 or IPv6 packets.   */
1773 
1774         if (ip_type == NX_IP_VERSION_V4)
1775         {
1776 
1777             status =  nx_packet_allocate(tftp_client_ptr -> nx_tftp_client_packet_pool_ptr, &ack_packet, NX_IPv4_UDP_PACKET, wait_option);
1778         }
1779         else
1780         {
1781 
1782             status =  nx_packet_allocate(tftp_client_ptr -> nx_tftp_client_packet_pool_ptr, &ack_packet, NX_IPv6_UDP_PACKET, wait_option);
1783         }
1784 
1785         /* Determine if an error occurred trying to allocate a packet.  */
1786         if (status != NX_SUCCESS)
1787         {
1788 
1789             /* Enter error state.  */
1790             tftp_client_ptr -> nx_tftp_client_state =  NX_TFTP_STATE_ERROR;
1791 
1792             /* Release the data packet.  */
1793             nx_packet_release(*packet_ptr);
1794 
1795             /* Set packet pointer to NULL.  */
1796             *packet_ptr =  NX_NULL;
1797 
1798             /* Return error condition.  */
1799             return(status);
1800         }
1801 
1802         if (4u > ((ULONG)(ack_packet -> nx_packet_data_end) - (ULONG)(ack_packet -> nx_packet_append_ptr)))
1803         {
1804             nx_packet_release(*packet_ptr);
1805 
1806             nx_packet_release(ack_packet);
1807             return(NX_SIZE_ERROR);
1808         }
1809 
1810         ack_packet -> nx_packet_append_ptr = ack_packet -> nx_packet_prepend_ptr;
1811 
1812         /* Valid block number, we need to send an ACK back to server. So now
1813            build the TFTP ACK message.  */
1814 
1815         /* Setup a pointer to the packet payload.  */
1816         buffer_ptr =  ack_packet -> nx_packet_prepend_ptr;
1817 
1818         /* Initial byte is always zero.  */
1819         *buffer_ptr++ =  0;
1820 
1821         /* Set the ACK code.  */
1822         *buffer_ptr++ =  NX_TFTP_CODE_ACK;
1823 
1824         /* Put the block number in.  */
1825         *buffer_ptr++ =  (UCHAR) (block_number >> 8);
1826         *buffer_ptr =    (UCHAR) (block_number & 0xFF);
1827 
1828         /* Adjust the ACK packet pointers and length.  */
1829         ack_packet -> nx_packet_length =  4;
1830         ack_packet -> nx_packet_append_ptr =  ack_packet -> nx_packet_append_ptr + 4;
1831 
1832         /* Send the ACK packet out.  */
1833         status = nxd_udp_socket_send(&(tftp_client_ptr -> nx_tftp_client_socket), ack_packet,
1834                                      &tftp_client_ptr -> nx_tftp_client_server_ip,
1835                                      tftp_client_ptr -> nx_tftp_client_server_port);
1836 
1837         /* Check error status. */
1838         if (status != NX_SUCCESS)
1839         {
1840             nx_packet_release(*packet_ptr);
1841 
1842             nx_packet_release(ack_packet);
1843             return status;
1844         }
1845 
1846         /* If we received a duplicate data packet, release it here. */
1847         if (resend_ACK_packet == NX_TRUE)
1848         {
1849 
1850             /* ACK for previous packet sent, so we can release this duplicate packet. */
1851             nx_packet_release(*packet_ptr);
1852 
1853             /* Set packet pointer to NULL.  */
1854             *packet_ptr =  NX_NULL;
1855 
1856             /* Do not handle as an error. Indicate the TFTP Client is still downloading a file. */
1857             return NX_TFTP_INVALID_BLOCK_NUMBER;
1858         }
1859 
1860         /* Adjust the packet to position past the TFTP header.  */
1861         (*packet_ptr) -> nx_packet_length =       (*packet_ptr) -> nx_packet_length - 4;
1862         (*packet_ptr) -> nx_packet_prepend_ptr =  (*packet_ptr) -> nx_packet_prepend_ptr + 4;
1863 
1864         /* Check for end of file condition. Anything less than 512 bytes signals an end of file.  */
1865         if ((*packet_ptr) -> nx_packet_length < NX_TFTP_FILE_TRANSFER_MAX)
1866         {
1867 
1868             /* End of file is present.  */
1869 
1870             /* Mark the state as end of file.  */
1871             tftp_client_ptr -> nx_tftp_client_state =  NX_TFTP_STATE_END_OF_FILE;
1872 
1873 
1874             /* Return EOF condition.  */
1875             return(NX_TFTP_END_OF_FILE);
1876 
1877         }
1878         else
1879         {
1880 
1881             /* More packets are still required.  Increment the block number.  */
1882             tftp_client_ptr -> nx_tftp_client_block_number++;
1883         }
1884 
1885         /* Return a successful status.  */
1886         return(NX_SUCCESS);
1887     }
1888     else if (code == NX_TFTP_CODE_ERROR)
1889     {
1890 
1891         /* Error code received.  */
1892 
1893         /* Change the state to error.  */
1894         tftp_client_ptr -> nx_tftp_client_state =  NX_TFTP_STATE_ERROR;
1895 
1896         /* Save the error code and message.  */
1897         buffer_ptr++;
1898         tftp_client_ptr -> nx_tftp_client_error_code =  (((UINT) (*buffer_ptr)) << 8);
1899         buffer_ptr++;
1900         tftp_client_ptr -> nx_tftp_client_error_code |=  (UINT) (*buffer_ptr);
1901         buffer_ptr++;
1902 
1903         /* Loop to save error message.  */
1904         for (i = 0; (i < (sizeof(tftp_client_ptr -> nx_tftp_client_error_string) -1)) && (*buffer_ptr); i++)
1905         {
1906 
1907             /* Store desired file name.  */
1908             tftp_client_ptr -> nx_tftp_client_error_string[i] =  (CHAR) *buffer_ptr++;
1909         }
1910 
1911         /* Set NULL terminator.  */
1912         tftp_client_ptr -> nx_tftp_client_error_string[i]  = NX_NULL;
1913 
1914         /* Release the packet.  */
1915         nx_packet_release(*packet_ptr);
1916 
1917         /* Return a failed status.  */
1918         return(NX_TFTP_CODE_ERROR);
1919     }
1920     /* This could be an ack from the previous file write. Just ignore it. */
1921     else if (code == NX_TFTP_CODE_ACK)
1922     {
1923 
1924         /* Release the data packet.  */
1925         nx_packet_release(*packet_ptr);
1926 
1927         /* Not an error. */
1928         return NX_SUCCESS;
1929     }
1930    else
1931     {
1932 
1933         /* Change the state to error.  */
1934         tftp_client_ptr -> nx_tftp_client_state =  NX_TFTP_STATE_ERROR;
1935 
1936         /* Release the packet.  */
1937         nx_packet_release(*packet_ptr);
1938 
1939         /* Return a failed status.  */
1940         return(NX_TFTP_FAILED);
1941     }
1942 }
1943 
1944 
1945 /**************************************************************************/
1946 /*                                                                        */
1947 /*  FUNCTION                                               RELEASE        */
1948 /*                                                                        */
1949 /*    _nxde_tftp_client_file_write                        PORTABLE C      */
1950 /*                                                           6.1          */
1951 /*  AUTHOR                                                                */
1952 /*                                                                        */
1953 /*    Yuxin Zhou, Microsoft Corporation                                   */
1954 /*                                                                        */
1955 /*  DESCRIPTION                                                           */
1956 /*                                                                        */
1957 /*    This function checks for errors in the TFTP file write call.        */
1958 /*                                                                        */
1959 /*                                                                        */
1960 /*  INPUT                                                                 */
1961 /*                                                                        */
1962 /*    tftp_client_ptr                       Pointer to TFTP client        */
1963 /*    packet_ptr                            Pointer to packet             */
1964 /*    wait_option                           Timeout for the write request */
1965 /*    ip_type                               IP type                       */
1966 /*                                                                        */
1967 /*  OUTPUT                                                                */
1968 /*                                                                        */
1969 /*    status                                Completion status             */
1970 /*    NX_PTR_ERROR                          Invalid pointer input         */
1971 /*    NX_INVALID_PARAMETERS                 Invalid non pointer input     */
1972 /*                                                                        */
1973 /*  CALLS                                                                 */
1974 /*                                                                        */
1975 /*    _nxd_tftp_client_file_write           Actual client file write      */
1976 /*                                                                        */
1977 /*  CALLED BY                                                             */
1978 /*                                                                        */
1979 /*    Application Code                                                    */
1980 /*                                                                        */
1981 /*  RELEASE HISTORY                                                       */
1982 /*                                                                        */
1983 /*    DATE              NAME                      DESCRIPTION             */
1984 /*                                                                        */
1985 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
1986 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
1987 /*                                            resulting in version 6.1    */
1988 /*                                                                        */
1989 /**************************************************************************/
_nxde_tftp_client_file_write(NX_TFTP_CLIENT * tftp_client_ptr,NX_PACKET * packet_ptr,ULONG wait_option,UINT ip_type)1990 UINT  _nxde_tftp_client_file_write(NX_TFTP_CLIENT *tftp_client_ptr, NX_PACKET *packet_ptr, ULONG wait_option, UINT ip_type)
1991 {
1992 
1993 UINT    status;
1994 
1995 
1996     /* Check for invalid input pointers.  */
1997     if ((tftp_client_ptr == NX_NULL) || (tftp_client_ptr -> nx_tftp_client_id != NXD_TFTP_CLIENT_ID) ||
1998         (packet_ptr == NX_NULL))
1999         return(NX_PTR_ERROR);
2000 
2001     /* Check for valid IP version*/
2002     if ((ip_type != NX_IP_VERSION_V4) && (ip_type != NX_IP_VERSION_V6))
2003     {
2004         return NX_INVALID_PARAMETERS;
2005     }
2006 
2007     /* Check for appropriate caller.  */
2008     NX_THREADS_ONLY_CALLER_CHECKING
2009 
2010     /* Call actual client file write function.  */
2011     status =  _nxd_tftp_client_file_write(tftp_client_ptr, packet_ptr, wait_option, ip_type);
2012 
2013     /* Return completion status.  */
2014     return(status);
2015 }
2016 
2017 
2018 /**************************************************************************/
2019 /*                                                                        */
2020 /*  FUNCTION                                               RELEASE        */
2021 /*                                                                        */
2022 /*    _nxd_tftp_client_file_write                         PORTABLE C      */
2023 /*                                                           6.1          */
2024 /*  AUTHOR                                                                */
2025 /*                                                                        */
2026 /*    Yuxin Zhou, Microsoft Corporation                                   */
2027 /*                                                                        */
2028 /*  DESCRIPTION                                                           */
2029 /*                                                                        */
2030 /*    This function writes a buffer to a previously opened TFTP file.     */
2031 /*                                                                        */
2032 /*                                                                        */
2033 /*  INPUT                                                                 */
2034 /*                                                                        */
2035 /*    tftp_client_ptr                       Pointer to TFTP client        */
2036 /*    packet_ptr                            Pointer to packet             */
2037 /*    wait_option                           Timeout for the write request */
2038 /*    ip_type                               IP type                       */
2039 /*                                                                        */
2040 /*  OUTPUT                                                                */
2041 /*                                                                        */
2042 /*    status                                Completion status             */
2043 /*    NX_TFTP_INVALID_IP_VERSION            Unsupported IP protocol       */
2044 /*    NX_TFTP_NO_ACK_RECEIVED               ACK not received from Server  */
2045 /*                                                                        */
2046 /*  CALLS                                                                 */
2047 /*                                                                        */
2048 /*    nx_packet_release                     Release packet                */
2049 /*    nx_udp_socket_receive                 Receive UDP data packet       */
2050 /*    nxd_udp_socket_send                   Send TFTP ACK packet          */
2051 /*    nxd_udp_source_extract                Extract IP and port           */
2052 /*                                                                        */
2053 /*  CALLED BY                                                             */
2054 /*                                                                        */
2055 /*    Application Code                                                    */
2056 /*                                                                        */
2057 /*  RELEASE HISTORY                                                       */
2058 /*                                                                        */
2059 /*    DATE              NAME                      DESCRIPTION             */
2060 /*                                                                        */
2061 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
2062 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
2063 /*                                            resulting in version 6.1    */
2064 /*                                                                        */
2065 /**************************************************************************/
_nxd_tftp_client_file_write(NX_TFTP_CLIENT * tftp_client_ptr,NX_PACKET * packet_ptr,ULONG wait_option,UINT ip_type)2066 UINT  _nxd_tftp_client_file_write(NX_TFTP_CLIENT *tftp_client_ptr, NX_PACKET *packet_ptr, ULONG wait_option, UINT ip_type)
2067 {
2068 
2069 UCHAR       *buffer_ptr;
2070 UINT        status;
2071 ULONG       length;
2072 NXD_ADDRESS ip_address;
2073 UINT        port;
2074 UINT        matching = NX_FALSE;
2075 
2076 
2077     /* Determine if we are still in an open state.  */
2078     if (tftp_client_ptr -> nx_tftp_client_state != NX_TFTP_STATE_WRITE_OPEN)
2079     {
2080 
2081         /* This instance is not open, return an error.  */
2082         return(NX_TFTP_NOT_OPEN);
2083     }
2084 
2085     /* Save the length of the TFTP write data.  */
2086     length =  packet_ptr -> nx_packet_length;
2087 
2088     /* Place the TFTP information in front of the data packet.  */
2089     packet_ptr -> nx_packet_prepend_ptr =  packet_ptr -> nx_packet_prepend_ptr - 4;
2090     packet_ptr -> nx_packet_length =       packet_ptr -> nx_packet_length + 4;
2091 
2092     /* Setup a pointer to the buffer.  */
2093     buffer_ptr =  packet_ptr -> nx_packet_prepend_ptr;
2094 
2095     /* Set the TFTP data code.  */
2096     *buffer_ptr++ =  0;
2097     *buffer_ptr++ =  NX_TFTP_CODE_DATA;
2098 
2099     /* Set the block number.  */
2100     *buffer_ptr++ =  (UCHAR) (tftp_client_ptr -> nx_tftp_client_block_number >> 8);
2101     *buffer_ptr++ =  (UCHAR) (tftp_client_ptr -> nx_tftp_client_block_number & 0xFF);
2102 
2103     /* Send the data packet out.  */
2104     status =  nxd_udp_socket_send(&(tftp_client_ptr -> nx_tftp_client_socket), packet_ptr,
2105                     &tftp_client_ptr -> nx_tftp_client_server_ip, tftp_client_ptr -> nx_tftp_client_server_port);
2106 
2107     /* Determine if an error occurred trying to send the packet.  */
2108     if (status)
2109     {
2110 
2111         /* Enter error state.  */
2112         tftp_client_ptr -> nx_tftp_client_state =  NX_TFTP_STATE_ERROR;
2113 
2114         /* Release the data packet.  */
2115         nx_packet_release(packet_ptr);
2116 
2117         /* Return error condition.  */
2118         return(status);
2119     }
2120 
2121     /* We now need to wait for the ACK for this write request.  */
2122     status =  nx_udp_socket_receive(&(tftp_client_ptr -> nx_tftp_client_socket), &packet_ptr, wait_option);
2123 
2124     /* Check the return status.  */
2125     if (status)
2126     {
2127 
2128         /* Return error code, the application may rebuild another packet and try again.  */
2129 
2130         /* Return error condition.  */
2131         return(NX_TFTP_TIMEOUT);
2132     }
2133 
2134     /* Check for valid packet length (The minimum TFTP header size is ACK packet, four bytes).  */
2135     if (packet_ptr -> nx_packet_length < 4)
2136     {
2137 
2138         /* Release the packet. */
2139         nx_packet_release(packet_ptr);
2140 
2141         /* Return.  */
2142         return(NX_INVALID_PACKET);
2143     }
2144 
2145     /* Extract the source IP and port numbers.  */
2146     nxd_udp_source_extract(packet_ptr, &ip_address, &port);
2147 
2148     /* Check for an invalid server IP address.  */
2149 
2150 #ifndef NX_DISABLE_IPV4
2151     if (ip_type == NX_IP_VERSION_V4)
2152     {
2153 
2154         if (ip_address.nxd_ip_address.v4 == tftp_client_ptr -> nx_tftp_client_server_ip.nxd_ip_address.v4)
2155         {
2156             matching = NX_TRUE;
2157         }
2158     }
2159     else
2160 #endif /* NX_DISABLE_IPV4 */
2161 #ifdef FEATURE_NX_IPV6
2162     if (ip_type == NX_IP_VERSION_V6)
2163     {
2164         if (CHECK_IPV6_ADDRESSES_SAME(&ip_address.nxd_ip_address.v6[0], &tftp_client_ptr -> nx_tftp_client_server_ip.nxd_ip_address.v6[0]))
2165         {
2166 
2167             matching = NX_TRUE;
2168         }
2169     }
2170     else
2171 #endif
2172     {
2173         /* Release the packet.  */
2174         nx_packet_release(packet_ptr);
2175 
2176         return NX_TFTP_INVALID_IP_VERSION;
2177     }
2178 
2179     /* Do we have a match? */
2180     if (!matching)
2181     {
2182 
2183         /* No, Invalid IP address!  */
2184 
2185         /* Enter error state.  */
2186         tftp_client_ptr -> nx_tftp_client_state =  NX_TFTP_STATE_ERROR;
2187 
2188         /* Release the packet.  */
2189         nx_packet_release(packet_ptr);
2190 
2191         /* Return error condition.  */
2192         return(NX_TFTP_INVALID_SERVER_ADDRESS);
2193     }
2194 
2195     /* Setup a pointer to the buffer.  */
2196     buffer_ptr =  (packet_ptr) -> nx_packet_prepend_ptr;
2197 
2198     /* Check for valid ACK message.  */
2199     if ((buffer_ptr[0] != 0) || (buffer_ptr[1] != NX_TFTP_CODE_ACK) ||
2200         (buffer_ptr[2] != ((UCHAR) (tftp_client_ptr -> nx_tftp_client_block_number >> 8))) ||
2201         (buffer_ptr[3] != ((UCHAR) (tftp_client_ptr -> nx_tftp_client_block_number & 0xFF))) ||
2202         (packet_ptr -> nx_packet_length != 4))
2203     {
2204 
2205         UINT code;
2206 
2207         /* Enter error state.  */
2208         tftp_client_ptr -> nx_tftp_client_state =  NX_TFTP_STATE_ERROR;
2209 
2210         /* Get the error status from the server message. */
2211         buffer_ptr++;
2212         code =  *(buffer_ptr);
2213 
2214         /* Check if this is a error reported by the server. If so save it to
2215            the TFTP Client. */
2216         if (code == NX_TFTP_CODE_ERROR)
2217         {
2218             UINT i;
2219 
2220             buffer_ptr++;
2221             tftp_client_ptr -> nx_tftp_client_error_code =  ((UINT) (*buffer_ptr)) << 8;
2222             buffer_ptr++;
2223             tftp_client_ptr -> nx_tftp_client_error_code |= (UINT) (*buffer_ptr);
2224             buffer_ptr++;
2225 
2226             /* Loop to save error message.  */
2227             for (i = 0; (i < (sizeof(tftp_client_ptr -> nx_tftp_client_error_string) -1)) && (*buffer_ptr); i++)
2228             {
2229 
2230                 /* Store desired file name.  */
2231                 tftp_client_ptr -> nx_tftp_client_error_string[i] =  (CHAR) *buffer_ptr++;
2232             }
2233 
2234             /* Set NULL terminator.  */
2235             tftp_client_ptr -> nx_tftp_client_error_string[i]  = NX_NULL;
2236 
2237             /* Release the packet.  */
2238             nx_packet_release(packet_ptr);
2239 
2240             /* Return error condition.  */
2241             return(NX_TFTP_CODE_ERROR);
2242         }
2243         /* Unknown code, not an error or an ACK. */
2244         else
2245         {
2246 
2247             /* Release the packet.  */
2248             nx_packet_release(packet_ptr);
2249 
2250             /* Return error condition.  */
2251             return(NX_TFTP_NO_ACK_RECEIVED);
2252         }
2253     }
2254 
2255     /* At this point, everything is okay.  */
2256 
2257     /* Release the ACK packet.  */
2258     nx_packet_release(packet_ptr);
2259 
2260     /* Check the length to see if we have the end of the file.  */
2261     if (length < NX_TFTP_FILE_TRANSFER_MAX)
2262     {
2263 
2264         /* Yes, this is the last packet.  */
2265 
2266         /* Enter into the finished state.  */
2267         tftp_client_ptr -> nx_tftp_client_state =  NX_TFTP_STATE_FINISHED;
2268     }
2269     else
2270     {
2271 
2272         /* More blocks to transfer still, increment the block number.  */
2273         tftp_client_ptr -> nx_tftp_client_block_number++;
2274     }
2275 
2276     /* Return success to the caller.  */
2277     return(NX_SUCCESS);
2278 }
2279 
2280 
2281 /**************************************************************************/
2282 /*                                                                        */
2283 /*  FUNCTION                                               RELEASE        */
2284 /*                                                                        */
2285 /*    _nxde_tftp_client_packet_allocate                   PORTABLE C      */
2286 /*                                                           6.1          */
2287 /*  AUTHOR                                                                */
2288 /*                                                                        */
2289 /*    Yuxin Zhou, Microsoft Corporation                                   */
2290 /*                                                                        */
2291 /*  DESCRIPTION                                                           */
2292 /*                                                                        */
2293 /*    This function checks for errors in the TFTP packet allocate call.   */
2294 /*                                                                        */
2295 /*                                                                        */
2296 /*  INPUT                                                                 */
2297 /*                                                                        */
2298 /*    pool_ptr                              Pointer to packet pool        */
2299 /*    packet_ptr                            Pointer to destination for    */
2300 /*                                            pointer of newly allocated  */
2301 /*                                            packet                      */
2302 /*    wait_option                           Timeout for the request       */
2303 /*    ip_type                               IP type                       */
2304 /*                                                                        */
2305 /*  OUTPUT                                                                */
2306 /*                                                                        */
2307 /*    status                                Completion status             */
2308 /*    NX_PTR_ERROR                          Invalid pointer input         */
2309 /*    NX_INVALID_PARAMETERS                 Invalid non pointer input     */
2310 /*                                                                        */
2311 /*  CALLS                                                                 */
2312 /*                                                                        */
2313 /*    _nxd_tftp _client_file_write          Actual client file write      */
2314 /*                                                                        */
2315 /*  CALLED BY                                                             */
2316 /*                                                                        */
2317 /*    Application Code                                                    */
2318 /*                                                                        */
2319 /*  RELEASE HISTORY                                                       */
2320 /*                                                                        */
2321 /*    DATE              NAME                      DESCRIPTION             */
2322 /*                                                                        */
2323 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
2324 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
2325 /*                                            resulting in version 6.1    */
2326 /*                                                                        */
2327 /**************************************************************************/
_nxde_tftp_client_packet_allocate(NX_PACKET_POOL * pool_ptr,NX_PACKET ** packet_ptr,ULONG wait_option,UINT ip_type)2328 UINT  _nxde_tftp_client_packet_allocate(NX_PACKET_POOL *pool_ptr, NX_PACKET **packet_ptr, ULONG wait_option, UINT ip_type)
2329 {
2330 
2331 UINT    status;
2332 
2333 
2334     /* Check for invalid input pointers.  */
2335     if ((pool_ptr == NX_NULL) || (packet_ptr == NX_NULL))
2336         return(NX_PTR_ERROR);
2337 
2338     /* Check for valid IP version*/
2339     if ((ip_type != NX_IP_VERSION_V4) && (ip_type != NX_IP_VERSION_V6))
2340     {
2341         return NX_INVALID_PARAMETERS;
2342     }
2343 
2344     /* Check for appropriate caller.  */
2345     NX_THREADS_ONLY_CALLER_CHECKING
2346 
2347     /* Call actual client packet allocate function.  */
2348     status =  _nxd_tftp_client_packet_allocate(pool_ptr, packet_ptr, wait_option, ip_type);
2349 
2350     /* Return completion status.  */
2351     return(status);
2352 }
2353 
2354 
2355 /**************************************************************************/
2356 /*                                                                        */
2357 /*  FUNCTION                                               RELEASE        */
2358 /*                                                                        */
2359 /*    _nxd_tftp_client_packet_allocate                    PORTABLE C      */
2360 /*                                                           6.1          */
2361 /*  AUTHOR                                                                */
2362 /*                                                                        */
2363 /*    Yuxin Zhou, Microsoft Corporation                                   */
2364 /*                                                                        */
2365 /*  DESCRIPTION                                                           */
2366 /*                                                                        */
2367 /*    This function allocates a packet with extra room for the TFTP       */
2368 /*    control information.                                                */
2369 /*                                                                        */
2370 /*                                                                        */
2371 /*  INPUT                                                                 */
2372 /*                                                                        */
2373 /*    pool_ptr                              Pointer to packet pool        */
2374 /*    packet_ptr                            Pointer to destination for    */
2375 /*                                            pointer of newly allocated  */
2376 /*                                            packet                      */
2377 /*    wait_option                           Timeout for the request       */
2378 /*    ip_type                               IP type                       */
2379 /*                                                                        */
2380 /*  OUTPUT                                                                */
2381 /*                                                                        */
2382 /*    status                                Completion status             */
2383 /*                                                                        */
2384 /*  CALLS                                                                 */
2385 /*                                                                        */
2386 /*    nx_packet_allocate                    Allocate packet               */
2387 /*                                                                        */
2388 /*  CALLED BY                                                             */
2389 /*                                                                        */
2390 /*    Application Code                                                    */
2391 /*                                                                        */
2392 /*  RELEASE HISTORY                                                       */
2393 /*                                                                        */
2394 /*    DATE              NAME                      DESCRIPTION             */
2395 /*                                                                        */
2396 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
2397 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
2398 /*                                            resulting in version 6.1    */
2399 /*                                                                        */
2400 /**************************************************************************/
_nxd_tftp_client_packet_allocate(NX_PACKET_POOL * pool_ptr,NX_PACKET ** packet_ptr,ULONG wait_option,UINT ip_type)2401 UINT  _nxd_tftp_client_packet_allocate(NX_PACKET_POOL *pool_ptr, NX_PACKET **packet_ptr, ULONG wait_option, UINT ip_type)
2402 {
2403 
2404 UINT    status;
2405 
2406 
2407     /* Allocate a new packet.  Determine whether we are sending IPv4 or IPv6 packets.   */
2408     if (ip_type == NX_IP_VERSION_V4)
2409     {
2410 
2411         status =  nx_packet_allocate(pool_ptr, packet_ptr, NX_IPv4_UDP_PACKET, wait_option);
2412     }
2413     else
2414     {
2415 
2416         status =  nx_packet_allocate(pool_ptr, packet_ptr, NX_IPv6_UDP_PACKET, wait_option);
2417     }
2418 
2419     /* Determine if an error is present.  */
2420     if (status)
2421     {
2422 
2423         /* Return the error code from the allocate routine.  */
2424         return(status);
2425     }
2426 
2427     (*packet_ptr) -> nx_packet_append_ptr = (*packet_ptr) -> nx_packet_prepend_ptr;
2428 
2429     /* Successful packet allocation.  Adjust the prepend and append pointers forward to
2430        accommodate the TFTP header.  */
2431     (*packet_ptr) -> nx_packet_prepend_ptr +=  4;
2432     (*packet_ptr) -> nx_packet_append_ptr  +=  4;
2433 
2434     /* Return success to the caller.  */
2435     return(NX_SUCCESS);
2436 }
2437 
2438