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