1 /***************************************************************************
2  * Copyright (c) 2024 Microsoft Corporation
3  *
4  * This program and the accompanying materials are made available under the
5  * terms of the MIT License which is available at
6  * https://opensource.org/licenses/MIT.
7  *
8  * SPDX-License-Identifier: MIT
9  **************************************************************************/
10 
11 
12 /**************************************************************************/
13 /**************************************************************************/
14 /**                                                                       */
15 /** NetX Duo Component                                                    */
16 /**                                                                       */
17 /**   TELNET Protocol (TELNET)                                            */
18 /**                                                                       */
19 /**************************************************************************/
20 /**************************************************************************/
21 
22 #define NX_TELNET_SOURCE_CODE
23 
24 
25 /* Force error checking to be disabled in this module */
26 
27 #ifndef NX_DISABLE_ERROR_CHECKING
28 #define NX_DISABLE_ERROR_CHECKING
29 #endif
30 
31 /* Include necessary system files.  */
32 
33 #include    "nx_api.h"
34 #include    "nx_ip.h"
35 #include    "nxd_telnet_server.h"
36 #include    "stdio.h"
37 #include    "string.h"
38 
39 
40 /* Bring in externs for caller checking code.  */
41 
42 NX_CALLER_CHECKING_EXTERNS
43 
44 
45 
46 /**************************************************************************/
47 /*                                                                        */
48 /*  FUNCTION                                               RELEASE        */
49 /*                                                                        */
50 /*    _nxe_telnet_server_create                           PORTABLE C      */
51 /*                                                           6.1          */
52 /*  AUTHOR                                                                */
53 /*                                                                        */
54 /*    Yuxin Zhou, Microsoft Corporation                                   */
55 /*                                                                        */
56 /*  DESCRIPTION                                                           */
57 /*                                                                        */
58 /*    This function checks for errors in the TELNET server create call.   */
59 /*                                                                        */
60 /*                                                                        */
61 /*  INPUT                                                                 */
62 /*                                                                        */
63 /*    server_ptr                            Pointer to TELNET server      */
64 /*    server_name                           Name of TELNET server         */
65 /*    ip_ptr                                Pointer to IP instance        */
66 /*    stack_ptr                             Server thread's stack pointer */
67 /*    stack_size                            Server thread's stack size    */
68 /*    new_connection                        Pointer to user's new         */
69 /*                                            connection function         */
70 /*    receive_data                          Pointer to user's receive     */
71 /*                                            data function               */
72 /*    connection_end                        Pointer to user's end of      */
73 /*                                            connection function         */
74 /*                                                                        */
75 /*  OUTPUT                                                                */
76 /*                                                                        */
77 /*    status                                Completion status             */
78 /*                                                                        */
79 /*  CALLS                                                                 */
80 /*                                                                        */
81 /*    _nx_telnet_server_create              Actual server create call     */
82 /*                                                                        */
83 /*  CALLED BY                                                             */
84 /*                                                                        */
85 /*    Application Code                                                    */
86 /*                                                                        */
87 /*  RELEASE HISTORY                                                       */
88 /*                                                                        */
89 /*    DATE              NAME                      DESCRIPTION             */
90 /*                                                                        */
91 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
92 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
93 /*                                            resulting in version 6.1    */
94 /*                                                                        */
95 /**************************************************************************/
_nxe_telnet_server_create(NX_TELNET_SERVER * server_ptr,CHAR * server_name,NX_IP * ip_ptr,VOID * stack_ptr,ULONG stack_size,void (* new_connection)(struct NX_TELNET_SERVER_STRUCT * telnet_server_ptr,UINT logical_connection),void (* receive_data)(struct NX_TELNET_SERVER_STRUCT * telnet_server_ptr,UINT logical_connection,NX_PACKET * packet_ptr),void (* connection_end)(struct NX_TELNET_SERVER_STRUCT * telnet_server_ptr,UINT logical_connection))96 UINT  _nxe_telnet_server_create(NX_TELNET_SERVER *server_ptr, CHAR *server_name, NX_IP *ip_ptr, VOID *stack_ptr, ULONG stack_size,
97             void (*new_connection)(struct NX_TELNET_SERVER_STRUCT *telnet_server_ptr, UINT logical_connection),
98             void (*receive_data)(struct NX_TELNET_SERVER_STRUCT *telnet_server_ptr, UINT logical_connection, NX_PACKET *packet_ptr),
99             void (*connection_end)(struct NX_TELNET_SERVER_STRUCT *telnet_server_ptr, UINT logical_connection))
100 {
101 
102 UINT        status;
103 
104 
105     /* Check for invalid input pointers.  */
106     if ((ip_ptr == NX_NULL) || (ip_ptr -> nx_ip_id != NX_IP_ID) ||
107         (server_ptr == NX_NULL) || (server_ptr -> nx_telnet_server_id == NX_TELNET_SERVER_ID) ||
108         (stack_ptr == NX_NULL) || (new_connection == NX_NULL) || (receive_data == NX_NULL) || (connection_end == NX_NULL))
109         return(NX_PTR_ERROR);
110 
111     /* Call actual server create function.  */
112     status =  _nx_telnet_server_create(server_ptr, server_name, ip_ptr, stack_ptr, stack_size, new_connection, receive_data, connection_end);
113 
114     /* Return completion status.  */
115     return(status);
116 }
117 
118 
119 /**************************************************************************/
120 /*                                                                        */
121 /*  FUNCTION                                               RELEASE        */
122 /*                                                                        */
123 /*    _nx_telnet_server_create                           PORTABLE C       */
124 /*                                                           6.1          */
125 /*  AUTHOR                                                                */
126 /*                                                                        */
127 /*    Yuxin Zhou, Microsoft Corporation                                   */
128 /*                                                                        */
129 /*  DESCRIPTION                                                           */
130 /*                                                                        */
131 /*    This function creates a TELNET server on the specified IP. In doing */
132 /*    so this function creates a TCP socket for subsequent TELNET         */
133 /*    transfers and a thread for the TELNET server.                       */
134 /*                                                                        */
135 /*                                                                        */
136 /*  INPUT                                                                 */
137 /*                                                                        */
138 /*    server_ptr                            Pointer to TELNET server      */
139 /*    server_name                           Name of TELNET server         */
140 /*    ip_ptr                                Pointer to IP instance        */
141 /*    stack_ptr                             Server thread's stack pointer */
142 /*    stack_size                            Server thread's stack size    */
143 /*    new_connection                        Pointer to user's new         */
144 /*                                            connection function         */
145 /*    receive_data                          Pointer to user's receive     */
146 /*                                            data function               */
147 /*    connection_end                        Pointer to user's end of      */
148 /*                                            connection function         */
149 /*                                                                        */
150 /*  OUTPUT                                                                */
151 /*                                                                        */
152 /*    status                                Completion status             */
153 /*                                                                        */
154 /*  CALLS                                                                 */
155 /*                                                                        */
156 /*    nx_tcp_socket_create                  Create sockets                */
157 /*    nx_tcp_socket_delete                  Delete sockets                */
158 /*    nx_tcp_socket_receive_notify          Register receive notify       */
159 /*                                            callback                    */
160 /*    tx_event_flags_create                 Create event flags            */
161 /*    tx_event_flags_delete                 Delete event flags            */
162 /*    tx_thread_create                      Create TELNET server thread   */
163 /*    tx_thread_delete                      Delete TELNET server thread   */
164 /*    tx_timer_create                       Create TELNET server timer    */
165 /*    tx_timer_delete                       Delete TELNET server timer    */
166 /*                                                                        */
167 /*  CALLED BY                                                             */
168 /*                                                                        */
169 /*    Application Code                                                    */
170 /*                                                                        */
171 /*  RELEASE HISTORY                                                       */
172 /*                                                                        */
173 /*    DATE              NAME                      DESCRIPTION             */
174 /*                                                                        */
175 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
176 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
177 /*                                            resulting in version 6.1    */
178 /*                                                                        */
179 /**************************************************************************/
_nx_telnet_server_create(NX_TELNET_SERVER * server_ptr,CHAR * server_name,NX_IP * ip_ptr,VOID * stack_ptr,ULONG stack_size,void (* new_connection)(struct NX_TELNET_SERVER_STRUCT * telnet_server_ptr,UINT logical_connection),void (* receive_data)(struct NX_TELNET_SERVER_STRUCT * telnet_server_ptr,UINT logical_connection,NX_PACKET * packet_ptr),void (* connection_end)(struct NX_TELNET_SERVER_STRUCT * telnet_server_ptr,UINT logical_connection))180 UINT  _nx_telnet_server_create(NX_TELNET_SERVER *server_ptr, CHAR *server_name, NX_IP *ip_ptr, VOID *stack_ptr, ULONG stack_size,
181             void (*new_connection)(struct NX_TELNET_SERVER_STRUCT *telnet_server_ptr, UINT logical_connection),
182             void (*receive_data)(struct NX_TELNET_SERVER_STRUCT *telnet_server_ptr, UINT logical_connection, NX_PACKET *packet_ptr),
183             void (*connection_end)(struct NX_TELNET_SERVER_STRUCT *telnet_server_ptr, UINT logical_connection))
184 {
185 
186 UINT            i;
187 UINT            status;
188 
189     /* Clear the TELNET server structure.  */
190     memset((void *) server_ptr, 0, sizeof(NX_TELNET_SERVER));
191 
192     /* Create the TELNET Server thread.  */
193     status =  tx_thread_create(&(server_ptr -> nx_telnet_server_thread), "TELNET Server Thread",
194                                _nx_telnet_server_thread_entry, (ULONG) server_ptr, stack_ptr,
195                                stack_size, NX_TELNET_SERVER_PRIORITY, NX_TELNET_SERVER_PRIORITY,
196                                TX_NO_TIME_SLICE, TX_DONT_START);
197 
198     /* Determine if an error occurred creating the thread.  */
199     if (status != TX_SUCCESS)
200     {
201 
202         /* Error creating the server thread.  */
203         return(status);
204     }
205 
206     /* Create the ThreadX event flags.  These will be used to driver the TELNET server thread.  */
207     status =  tx_event_flags_create(&(server_ptr -> nx_telnet_server_event_flags), "TELNET Server Thread Events");
208 
209     /* Determine if an error occurred creating the event flags.  */
210     if (status != TX_SUCCESS)
211     {
212 
213         /* Delete the server thread.  */
214         tx_thread_delete(&(server_ptr -> nx_telnet_server_thread));
215 
216         /* Error creating the server event flags.  */
217         return(status);
218     }
219 
220     /* Create the ThreadX activity timeout timer.  This will be used to periodically check to see if
221        a client connection has gone silent and needs to be terminated.  */
222     status =  tx_timer_create(&(server_ptr -> nx_telnet_server_timer), "TELNET Server Timer",
223                               _nx_telnet_server_timeout, (ULONG) server_ptr,
224                               (NX_IP_PERIODIC_RATE * NX_TELNET_TIMEOUT_PERIOD),
225                               (NX_IP_PERIODIC_RATE * NX_TELNET_TIMEOUT_PERIOD), TX_NO_ACTIVATE);
226 
227     /* Determine if an error occurred creating the timer.  */
228     if (status != TX_SUCCESS)
229     {
230 
231         /* Delete the server thread.  */
232         tx_thread_delete(&(server_ptr -> nx_telnet_server_thread));
233 
234         /* Delete the server event flags.  */
235         tx_event_flags_delete(&(server_ptr -> nx_telnet_server_event_flags));
236 
237         /* Error creating the server timer.  */
238         return(status);
239     }
240 
241     /* Loop to create all the TELNET client sockets.  */
242     for (i = 0; i < NX_TELNET_MAX_CLIENTS; i++)
243     {
244 
245         /* Setup the logical index for this client request structure.  */
246         server_ptr -> nx_telnet_server_client_list[i].nx_telnet_client_request_connection =  i;
247 
248         /* Create an TELNET client socket.  */
249         status +=  nx_tcp_socket_create(ip_ptr, &(server_ptr -> nx_telnet_server_client_list[i].nx_telnet_client_request_socket), "TELNET Server Control Socket",
250                         NX_TELNET_TOS, NX_TELNET_FRAGMENT_OPTION, NX_TELNET_TIME_TO_LIVE, NX_TELNET_SERVER_WINDOW_SIZE, NX_NULL, _nx_telnet_server_disconnect_present);
251 
252         /* If no error is present, register the receive notify function.  */
253         if (status == NX_SUCCESS)
254         {
255 
256             /* Register the receive function.  */
257             nx_tcp_socket_receive_notify(&(server_ptr -> nx_telnet_server_client_list[i].nx_telnet_client_request_socket),
258                                             _nx_telnet_server_data_present);
259         }
260 
261         /* Make sure each socket points to the TELNET server.  */
262         server_ptr -> nx_telnet_server_client_list[i].nx_telnet_client_request_socket.nx_tcp_socket_reserved_ptr =  server_ptr;
263     }
264 
265     /* Determine if an error has occurred.  */
266     if (status != NX_SUCCESS)
267     {
268 
269         /* Loop to delete any created sockets.  */
270         for (i = 0; i < NX_TELNET_MAX_CLIENTS; i++)
271         {
272 
273             /* Delete the TELNET socket.  */
274             nx_tcp_socket_delete(&(server_ptr -> nx_telnet_server_client_list[i].nx_telnet_client_request_socket));
275         }
276 
277         /* Delete the server thread.  */
278         tx_thread_delete(&(server_ptr -> nx_telnet_server_thread));
279 
280         /* Delete the event flag group.  */
281         tx_event_flags_delete(&(server_ptr -> nx_telnet_server_event_flags));
282 
283         /* Delete the timer.  */
284         tx_timer_delete(&(server_ptr -> nx_telnet_server_timer));
285 
286         /* Return the NetX error.  */
287         return(status);
288     }
289 
290 
291 #ifndef NX_TELNET_SERVER_OPTION_DISABLE
292 
293 #ifndef NX_TELNET_SERVER_USER_CREATE_PACKET_POOL
294 
295     /* Create the packet pool for negotiating telnet options, and check the status */
296     status =  nx_packet_pool_create(&(server_ptr -> nx_telnet_server_packet_pool), "Telnet Server Options",
297                                     NX_TELNET_SERVER_PACKET_PAYLOAD, &server_ptr -> nx_telnet_server_pool_area,
298                                     NX_TELNET_SERVER_PACKET_POOL_SIZE);
299 
300     /* Determine if it was successful.  */
301     if (status != NX_SUCCESS)
302     {
303         /* Loop to delete any created sockets.  */
304         for (i = 0; i < NX_TELNET_MAX_CLIENTS; i++)
305         {
306 
307             /* Delete the TELNET socket.  */
308             nx_tcp_socket_delete(&(server_ptr -> nx_telnet_server_client_list[i].nx_telnet_client_request_socket));
309         }
310 
311         /* Delete the server thread.  */
312         tx_thread_delete(&(server_ptr -> nx_telnet_server_thread));
313 
314         /* Delete the event flag group.  */
315         tx_event_flags_delete(&(server_ptr -> nx_telnet_server_event_flags));
316 
317         /* Delete the timer.  */
318         tx_timer_delete(&(server_ptr -> nx_telnet_server_timer));
319 
320         /* No, return error status.  */
321         return(status);
322     }
323 
324     server_ptr -> nx_telnet_server_packet_pool_ptr = &(server_ptr -> nx_telnet_server_packet_pool);
325 #endif /* NX_TELNET_SERVER_USER_CREATE_PACKET_POOL */
326 #endif /* NX_TELNET_SERVER_OPTION_DISABLE */
327 
328     /* Save the Server name.  */
329     server_ptr -> nx_telnet_server_name =  server_name;
330 
331     /* Save the IP pointer address.  */
332     server_ptr -> nx_telnet_server_ip_ptr =  ip_ptr;
333 
334     /* Save the user-supplied new connection and receive data functions.  */
335     server_ptr -> nx_telnet_new_connection =   new_connection;
336     server_ptr -> nx_telnet_receive_data =     receive_data;
337     server_ptr -> nx_telnet_connection_end =   connection_end;
338 
339     /* Set the server ID to indicate the TELNET server thread is ready.  */
340     server_ptr -> nx_telnet_server_id =  NX_TELNET_SERVER_ID;
341 
342     server_ptr -> nx_telnet_server_open_connections = 0;
343 
344 
345     /* Return successful completion.  */
346     return(NX_SUCCESS);
347 }
348 
349 
350 /**************************************************************************/
351 /*                                                                        */
352 /*  FUNCTION                                               RELEASE        */
353 /*                                                                        */
354 /*    _nxe_telnet_server_delete                           PORTABLE C      */
355 /*                                                           6.1          */
356 /*  AUTHOR                                                                */
357 /*                                                                        */
358 /*    Yuxin Zhou, Microsoft Corporation                                   */
359 /*                                                                        */
360 /*  DESCRIPTION                                                           */
361 /*                                                                        */
362 /*    This function checks for errors in the TELNET server delete call.   */
363 /*                                                                        */
364 /*                                                                        */
365 /*  INPUT                                                                 */
366 /*                                                                        */
367 /*    server_ptr                            Pointer to TELNET server      */
368 /*                                                                        */
369 /*  OUTPUT                                                                */
370 /*                                                                        */
371 /*    status                                Completion status             */
372 /*                                                                        */
373 /*  CALLS                                                                 */
374 /*                                                                        */
375 /*    _nx_telnet_server_delete              Actual server delete call     */
376 /*                                                                        */
377 /*  CALLED BY                                                             */
378 /*                                                                        */
379 /*    Application Code                                                    */
380 /*                                                                        */
381 /*  RELEASE HISTORY                                                       */
382 /*                                                                        */
383 /*    DATE              NAME                      DESCRIPTION             */
384 /*                                                                        */
385 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
386 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
387 /*                                            resulting in version 6.1    */
388 /*                                                                        */
389 /**************************************************************************/
_nxe_telnet_server_delete(NX_TELNET_SERVER * server_ptr)390 UINT  _nxe_telnet_server_delete(NX_TELNET_SERVER *server_ptr)
391 {
392 
393 UINT    status;
394 
395 
396     /* Check for invalid input pointers.  */
397     if ((server_ptr == NX_NULL) || (server_ptr -> nx_telnet_server_id != NX_TELNET_SERVER_ID))
398         return(NX_PTR_ERROR);
399 
400     /* Check for appropriate caller.  */
401     NX_THREADS_ONLY_CALLER_CHECKING
402 
403     /* Call actual server delete function.  */
404     status =  _nx_telnet_server_delete(server_ptr);
405 
406     /* Return completion status.  */
407     return(status);
408 }
409 
410 
411 
412 /**************************************************************************/
413 /*                                                                        */
414 /*  FUNCTION                                               RELEASE        */
415 /*                                                                        */
416 /*    _nx_telnet_server_delete                            PORTABLE C      */
417 /*                                                           6.1          */
418 /*  AUTHOR                                                                */
419 /*                                                                        */
420 /*    Yuxin Zhou, Microsoft Corporation                                   */
421 /*                                                                        */
422 /*  DESCRIPTION                                                           */
423 /*                                                                        */
424 /*    This function deletes a previously created TELNET server on the     */
425 /*    specified IP.                                                       */
426 /*                                                                        */
427 /*                                                                        */
428 /*  INPUT                                                                 */
429 /*                                                                        */
430 /*    server_ptr                            Pointer to TELNET server      */
431 /*                                                                        */
432 /*  OUTPUT                                                                */
433 /*                                                                        */
434 /*    status                                Completion status             */
435 /*                                                                        */
436 /*  CALLS                                                                 */
437 /*                                                                        */
438 /*    nx_tcp_server_socket_unaccept         Unaccept server socket        */
439 /*    nx_tcp_server_socket_unlisten         Unlisten on server            */
440 /*    nx_tcp_socket_delete                  Delete socket                 */
441 /*    nx_tcp_socket_disconnect              Disconnect socket             */
442 /*    tx_event_flags_delete                 Delete event flags            */
443 /*    tx_thread_delete                      Delete thread                 */
444 /*    tx_thread_suspend                     Suspend thread                */
445 /*    tx_thread_terminate                   Terminate thread              */
446 /*    tx_timer_deactivate                   Deactivate timer              */
447 /*    tx_timer_delete                       Delete timer                  */
448 /*                                                                        */
449 /*  CALLED BY                                                             */
450 /*                                                                        */
451 /*    Application Code                                                    */
452 /*                                                                        */
453 /*  RELEASE HISTORY                                                       */
454 /*                                                                        */
455 /*    DATE              NAME                      DESCRIPTION             */
456 /*                                                                        */
457 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
458 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
459 /*                                            resulting in version 6.1    */
460 /*                                                                        */
461 /**************************************************************************/
_nx_telnet_server_delete(NX_TELNET_SERVER * server_ptr)462 UINT  _nx_telnet_server_delete(NX_TELNET_SERVER *server_ptr)
463 {
464 
465 UINT                        i;
466 NX_TELNET_CLIENT_REQUEST   *client_request_ptr;
467 
468 
469     /* Clear the server ID to indicate the TELNET server is no longer ready.  */
470     server_ptr -> nx_telnet_server_id =  0;
471 
472     /* Suspend the TELNET server thread.  */
473     tx_thread_suspend(&(server_ptr -> nx_telnet_server_thread));
474 
475     /* Terminate server thread. */
476     tx_thread_terminate(&(server_ptr -> nx_telnet_server_thread));
477 
478     /* Delete server thread.  */
479     tx_thread_delete(&(server_ptr -> nx_telnet_server_thread));
480 
481     /* Delete the event flag group.  */
482     tx_event_flags_delete(&(server_ptr -> nx_telnet_server_event_flags));
483 
484     /* Deactivate and delete timer.  */
485     tx_timer_deactivate(&(server_ptr -> nx_telnet_server_timer));
486     tx_timer_delete(&(server_ptr -> nx_telnet_server_timer));
487 
488     /* If the Telnet Server is configured to send options and the packet
489        pool is created by  the internally (by the Telnet server task)
490        we need to delete it. */
491 #ifndef NX_TELNET_SERVER_OPTION_DISABLE
492 #ifndef NX_TELNET_SERVER_USER_CREATE_PACKET_POOL
493     nx_packet_pool_delete(&server_ptr -> nx_telnet_server_packet_pool);
494 #endif /* NX_TELNET_SERVER_USER_CREATE_PACKET_POOL */
495 #endif /* NX_TELNET_SERVER_OPTION_DISABLE */
496 
497     /* Walk through the server structure to close and delete any open sockets.  */
498     i =  0;
499     client_request_ptr =  &(server_ptr -> nx_telnet_server_client_list[0]);
500     while (i < NX_TELNET_MAX_CLIENTS)
501     {
502 
503         /* Disconnect the socket.  */
504         nx_tcp_socket_disconnect(&(client_request_ptr -> nx_telnet_client_request_socket), NX_NO_WAIT);
505 
506         /* Unaccept the socket.  */
507         nx_tcp_server_socket_unaccept(&(client_request_ptr -> nx_telnet_client_request_socket));
508 
509         /* Delete the socket.  */
510         nx_tcp_socket_delete(&(client_request_ptr -> nx_telnet_client_request_socket));
511 
512         /* Increment the pointer into the client request list.  */
513         client_request_ptr++;
514         i++;
515     }
516 
517     /* Unlisten on the TELNET port.  */
518     nx_tcp_server_socket_unlisten(server_ptr -> nx_telnet_server_ip_ptr, NX_TELNET_SERVER_PORT);
519 
520     /* Return successful completion.  */
521     return(NX_SUCCESS);
522 }
523 
524 
525 /**************************************************************************/
526 /*                                                                        */
527 /*  FUNCTION                                               RELEASE        */
528 /*                                                                        */
529 /*    _nxe_telnet_server_disconnect                       PORTABLE C      */
530 /*                                                           6.1          */
531 /*  AUTHOR                                                                */
532 /*                                                                        */
533 /*    Yuxin Zhou, Microsoft Corporation                                   */
534 /*                                                                        */
535 /*  DESCRIPTION                                                           */
536 /*                                                                        */
537 /*    This function checks for errors in the TELNET server disconnect     */
538 /*    call.                                                               */
539 /*                                                                        */
540 /*                                                                        */
541 /*  INPUT                                                                 */
542 /*                                                                        */
543 /*    server_ptr                            Pointer to TELNET server      */
544 /*    logical_connection                    Logical connection entry      */
545 /*                                                                        */
546 /*  OUTPUT                                                                */
547 /*                                                                        */
548 /*    status                                Completion status             */
549 /*                                                                        */
550 /*  CALLS                                                                 */
551 /*                                                                        */
552 /*    _nx_telnet_server_disconnect          Actual server disconnect call */
553 /*                                                                        */
554 /*  CALLED BY                                                             */
555 /*                                                                        */
556 /*    Application Code                                                    */
557 /*                                                                        */
558 /*  RELEASE HISTORY                                                       */
559 /*                                                                        */
560 /*    DATE              NAME                      DESCRIPTION             */
561 /*                                                                        */
562 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
563 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
564 /*                                            resulting in version 6.1    */
565 /*                                                                        */
566 /**************************************************************************/
_nxe_telnet_server_disconnect(NX_TELNET_SERVER * server_ptr,UINT logical_connection)567 UINT  _nxe_telnet_server_disconnect(NX_TELNET_SERVER *server_ptr, UINT logical_connection)
568 {
569 
570 UINT    status;
571 
572 
573     /* Check for invalid input pointers.  */
574     if ((server_ptr == NX_NULL) || (server_ptr -> nx_telnet_server_id != NX_TELNET_SERVER_ID))
575         return(NX_PTR_ERROR);
576 
577     /* Check for a valid logical connection.  */
578     if (logical_connection >= NX_TELNET_MAX_CLIENTS)
579         return(NX_OPTION_ERROR);
580 
581     /* Check for appropriate caller.  */
582     NX_THREADS_ONLY_CALLER_CHECKING
583 
584     /* Call actual server disconnect function.  */
585     status =  _nx_telnet_server_disconnect(server_ptr, logical_connection);
586 
587     /* Return completion status.  */
588     return(status);
589 }
590 
591 
592 /**************************************************************************/
593 /*                                                                        */
594 /*  FUNCTION                                               RELEASE        */
595 /*                                                                        */
596 /*    _nx_telnet_server_disconnect                        PORTABLE C      */
597 /*                                                           6.2.1        */
598 /*  AUTHOR                                                                */
599 /*                                                                        */
600 /*    Yuxin Zhou, Microsoft Corporation                                   */
601 /*                                                                        */
602 /*  DESCRIPTION                                                           */
603 /*                                                                        */
604 /*    This function processes server disconnect requests made by the      */
605 /*    application receive data callback function.                         */
606 /*                                                                        */
607 /*  INPUT                                                                 */
608 /*                                                                        */
609 /*    server_ptr                            Pointer to TELNET server      */
610 /*    logical_connection                    Logical connection entry      */
611 /*                                                                        */
612 /*  OUTPUT                                                                */
613 /*                                                                        */
614 /*    status                                Completion status             */
615 /*                                                                        */
616 /*  CALLS                                                                 */
617 /*                                                                        */
618 /*    nx_tcp_server_socket_relisten         Relisten on Telnet port       */
619 /*    nx_tcp_server_socket_unaccept         Socket unaccept               */
620 /*    nx_tcp_socket_disconnect              Socket disconnect             */
621 /*                                                                        */
622 /*  CALLED BY                                                             */
623 /*                                                                        */
624 /*    Application Code                                                    */
625 /*                                                                        */
626 /*  RELEASE HISTORY                                                       */
627 /*                                                                        */
628 /*    DATE              NAME                      DESCRIPTION             */
629 /*                                                                        */
630 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
631 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
632 /*                                            resulting in version 6.1    */
633 /*  03-08-2023     Wenhui Xie               Modified comment(s), and      */
634 /*                                            corrected the processing of */
635 /*                                            disconnection,              */
636 /*                                            resulting in version 6.2.1  */
637 /*                                                                        */
638 /**************************************************************************/
_nx_telnet_server_disconnect(NX_TELNET_SERVER * server_ptr,UINT logical_connection)639 UINT  _nx_telnet_server_disconnect(NX_TELNET_SERVER *server_ptr, UINT logical_connection)
640 {
641 
642 UINT                        i;
643 UINT                        status;
644 NX_TELNET_CLIENT_REQUEST   *client_ptr;
645 
646     /* Set a pointer to the indicated client connection.  */
647     client_ptr =  &(server_ptr -> nx_telnet_server_client_list[logical_connection]);
648 
649     /* Determine if the connection is alive.  */
650     if (client_ptr -> nx_telnet_client_request_socket.nx_tcp_socket_state >= NX_TCP_ESTABLISHED)
651     {
652 
653         /* Disconnect the socket.  */
654         nx_tcp_socket_disconnect(&(client_ptr -> nx_telnet_client_request_socket), NX_TELNET_SERVER_TIMEOUT);
655 
656         /* Unaccept this socket.  */
657         nx_tcp_server_socket_unaccept(&(client_ptr -> nx_telnet_client_request_socket));
658 
659         /* Update number of current open connections. */
660         if (server_ptr -> nx_telnet_server_open_connections > 0)
661             server_ptr -> nx_telnet_server_open_connections--;
662 
663         /* Clear the client request activity timeout.  */
664         client_ptr -> nx_telnet_client_request_activity_timeout =  0;
665 
666         /* Call the application's end connection callback routine.  */
667         if (server_ptr -> nx_telnet_connection_end)
668         {
669 
670             /* Yes, there is a connection end callback routine - call it!  */
671             (server_ptr -> nx_telnet_connection_end)(server_ptr, client_ptr -> nx_telnet_client_request_connection);
672         }
673     }
674     else
675     {
676 
677         /* Error, disconnecting an unconnected socket.  */
678         return(NX_TELNET_NOT_CONNECTED);
679     }
680 
681     /* Now look for a socket that is closed to relisten on.  */
682     for (i = 0; i < NX_TELNET_MAX_CLIENTS; i++)
683     {
684 
685         /* Set a pointer to client request structure.  */
686         client_ptr =  &(server_ptr -> nx_telnet_server_client_list[i]);
687 
688         /* Now see if this socket is closed.  */
689         if (client_ptr -> nx_telnet_client_request_socket.nx_tcp_socket_state == NX_TCP_CLOSED)
690         {
691 
692             /* Relisten on this socket.  */
693             status =  nx_tcp_server_socket_relisten(server_ptr -> nx_telnet_server_ip_ptr, NX_TELNET_SERVER_PORT,
694                                                     &(client_ptr -> nx_telnet_client_request_socket));
695             /* Check for bad status.  */
696             if ((status != NX_SUCCESS) && (status != NX_CONNECTION_PENDING))
697             {
698 
699                 /* Increment the error count and keep trying.  */
700                 server_ptr -> nx_telnet_server_relisten_errors++;
701                 continue;
702             }
703 
704             /* Break out of loop.  */
705             break;
706         }
707     }
708 
709     /* Return success.  */
710     return(NX_SUCCESS);
711 }
712 
713 
714 /**************************************************************************/
715 /*                                                                        */
716 /*  FUNCTION                                               RELEASE        */
717 /*                                                                        */
718 /*    _nxe_telnet_server_packet_send                      PORTABLE C      */
719 /*                                                           6.1          */
720 /*  AUTHOR                                                                */
721 /*                                                                        */
722 /*    Yuxin Zhou, Microsoft Corporation                                   */
723 /*                                                                        */
724 /*  DESCRIPTION                                                           */
725 /*                                                                        */
726 /*    This function checks for errors in the TELNET server packet send    */
727 /*    call.                                                               */
728 /*                                                                        */
729 /*                                                                        */
730 /*  INPUT                                                                 */
731 /*                                                                        */
732 /*    server_ptr                            Pointer to TELNET server      */
733 /*    logical_connection                    Logical connection entry      */
734 /*    packet_ptr                            Packet pointer to send        */
735 /*    wait_option                           Suspension option             */
736 /*                                                                        */
737 /*  OUTPUT                                                                */
738 /*                                                                        */
739 /*    status                                Completion status             */
740 /*                                                                        */
741 /*  CALLS                                                                 */
742 /*                                                                        */
743 /*    _nx_telnet_server_packet_send         Actual server packet send call*/
744 /*                                                                        */
745 /*  CALLED BY                                                             */
746 /*                                                                        */
747 /*    Application Code                                                    */
748 /*                                                                        */
749 /*  RELEASE HISTORY                                                       */
750 /*                                                                        */
751 /*    DATE              NAME                      DESCRIPTION             */
752 /*                                                                        */
753 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
754 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
755 /*                                            resulting in version 6.1    */
756 /*                                                                        */
757 /**************************************************************************/
_nxe_telnet_server_packet_send(NX_TELNET_SERVER * server_ptr,UINT logical_connection,NX_PACKET * packet_ptr,ULONG wait_option)758 UINT  _nxe_telnet_server_packet_send(NX_TELNET_SERVER *server_ptr, UINT logical_connection, NX_PACKET *packet_ptr, ULONG wait_option)
759 {
760 
761 UINT    status;
762 
763 
764     /* Check for invalid input pointers.  */
765     if ((server_ptr == NX_NULL) || (server_ptr -> nx_telnet_server_id != NX_TELNET_SERVER_ID) || (packet_ptr == NX_NULL))
766         return(NX_PTR_ERROR);
767 
768     /* Check for a valid logical connection.  */
769     if (logical_connection >= NX_TELNET_MAX_CLIENTS)
770         return(NX_OPTION_ERROR);
771 
772     /* Check for appropriate caller.  */
773     NX_THREADS_ONLY_CALLER_CHECKING
774 
775     /* Call actual server packet send function.  */
776     status =  _nx_telnet_server_packet_send(server_ptr, logical_connection, packet_ptr, wait_option);
777 
778     /* Return completion status.  */
779     return(status);
780 }
781 
782 
783 /**************************************************************************/
784 /*                                                                        */
785 /*  FUNCTION                                               RELEASE        */
786 /*                                                                        */
787 /*    _nx_telnet_server_packet_send                       PORTABLE C      */
788 /*                                                           6.1          */
789 /*  AUTHOR                                                                */
790 /*                                                                        */
791 /*    Yuxin Zhou, Microsoft Corporation                                   */
792 /*                                                                        */
793 /*  DESCRIPTION                                                           */
794 /*                                                                        */
795 /*    This function processes packet send requests made from the          */
796 /*    application's receive data callback function.                       */
797 /*                                                                        */
798 /*  INPUT                                                                 */
799 /*                                                                        */
800 /*    server_ptr                            Pointer to TELNET server      */
801 /*    logical_connection                    Logical connection entry      */
802 /*    packet_ptr                            Packet pointer to send        */
803 /*    wait_option                           Suspension option             */
804 /*                                                                        */
805 /*  OUTPUT                                                                */
806 /*                                                                        */
807 /*    status                                Completion status             */
808 /*                                                                        */
809 /*  CALLS                                                                 */
810 /*                                                                        */
811 /*    nx_tcp_socket_send                    Send packet                   */
812 /*                                                                        */
813 /*  CALLED BY                                                             */
814 /*                                                                        */
815 /*    Application Code                                                    */
816 /*                                                                        */
817 /*  RELEASE HISTORY                                                       */
818 /*                                                                        */
819 /*    DATE              NAME                      DESCRIPTION             */
820 /*                                                                        */
821 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
822 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
823 /*                                            resulting in version 6.1    */
824 /*                                                                        */
825 /**************************************************************************/
_nx_telnet_server_packet_send(NX_TELNET_SERVER * server_ptr,UINT logical_connection,NX_PACKET * packet_ptr,ULONG wait_option)826 UINT  _nx_telnet_server_packet_send(NX_TELNET_SERVER *server_ptr, UINT logical_connection, NX_PACKET *packet_ptr, ULONG wait_option)
827 {
828 
829 UINT                        status;
830 NX_TELNET_CLIENT_REQUEST    *client_ptr;
831 
832 
833     /* Derive the pointer to the appropriate client connection.  */
834     client_ptr =  &(server_ptr -> nx_telnet_server_client_list[logical_connection]);
835 
836     /* Send the packet to the client.  */
837     status =  nx_tcp_socket_send(&(client_ptr -> nx_telnet_client_request_socket), packet_ptr, wait_option);
838 
839     /* Determine if the send was successful.  */
840     if (status)
841     {
842 
843         /* Map to a generic error.  */
844         status =  NX_TELNET_FAILED;
845     }
846 
847     /* Return to caller.  */
848     return(status);
849 }
850 
851 
852 /**************************************************************************/
853 /*                                                                        */
854 /*  FUNCTION                                               RELEASE        */
855 /*                                                                        */
856 /*    _nxe_telnet_server_start                            PORTABLE C      */
857 /*                                                           6.1          */
858 /*  AUTHOR                                                                */
859 /*                                                                        */
860 /*    Yuxin Zhou, Microsoft Corporation                                   */
861 /*                                                                        */
862 /*  DESCRIPTION                                                           */
863 /*                                                                        */
864 /*    This function checks for errors in the TELNET server start call.    */
865 /*                                                                        */
866 /*                                                                        */
867 /*  INPUT                                                                 */
868 /*                                                                        */
869 /*    server_ptr                            Pointer to TELNET server      */
870 /*                                                                        */
871 /*  OUTPUT                                                                */
872 /*                                                                        */
873 /*    status                                Completion status             */
874 /*                                                                        */
875 /*  CALLS                                                                 */
876 /*                                                                        */
877 /*    _nx_telnet_server_start               Actual server start call      */
878 /*                                                                        */
879 /*  CALLED BY                                                             */
880 /*                                                                        */
881 /*    Application Code                                                    */
882 /*                                                                        */
883 /*  RELEASE HISTORY                                                       */
884 /*                                                                        */
885 /*    DATE              NAME                      DESCRIPTION             */
886 /*                                                                        */
887 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
888 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
889 /*                                            resulting in version 6.1    */
890 /*                                                                        */
891 /**************************************************************************/
_nxe_telnet_server_start(NX_TELNET_SERVER * server_ptr)892 UINT  _nxe_telnet_server_start(NX_TELNET_SERVER *server_ptr)
893 {
894 
895 UINT    status;
896 
897 
898     /* Check for invalid input pointers.  */
899     if ((server_ptr == NX_NULL) || (server_ptr -> nx_telnet_server_id != NX_TELNET_SERVER_ID))
900         return(NX_PTR_ERROR);
901 
902     /* Call actual server start function.  */
903     status =  _nx_telnet_server_start(server_ptr);
904 
905     /* Return completion status.  */
906     return(status);
907 }
908 
909 
910 /**************************************************************************/
911 /*                                                                        */
912 /*  FUNCTION                                               RELEASE        */
913 /*                                                                        */
914 /*    _nx_telnet_server_start                             PORTABLE C      */
915 /*                                                           6.1          */
916 /*  AUTHOR                                                                */
917 /*                                                                        */
918 /*    Yuxin Zhou, Microsoft Corporation                                   */
919 /*                                                                        */
920 /*  DESCRIPTION                                                           */
921 /*                                                                        */
922 /*    This function starts a previously created TELNET server on the      */
923 /*    specified IP.                                                       */
924 /*                                                                        */
925 /*                                                                        */
926 /*  INPUT                                                                 */
927 /*                                                                        */
928 /*    server_ptr                            Pointer to TELNET server      */
929 /*                                                                        */
930 /*  OUTPUT                                                                */
931 /*                                                                        */
932 /*    status                                Completion status             */
933 /*    NX_TELNET_NO_PACKET_POOL              Telnet server packet pool not */
934 /*                                             set yet                    */
935 /*                                                                        */
936 /*  CALLS                                                                 */
937 /*                                                                        */
938 /*    nx_tcp_server_socket_listen           Listen of TELNET clients      */
939 /*    tx_thread_resume                      Resume TELNET server thread   */
940 /*    tx_timer_activate                     Activate TELNET server timer  */
941 /*                                                                        */
942 /*  CALLED BY                                                             */
943 /*                                                                        */
944 /*    Application Code                                                    */
945 /*                                                                        */
946 /*  RELEASE HISTORY                                                       */
947 /*                                                                        */
948 /*    DATE              NAME                      DESCRIPTION             */
949 /*                                                                        */
950 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
951 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
952 /*                                            resulting in version 6.1    */
953 /*                                                                        */
954 /**************************************************************************/
_nx_telnet_server_start(NX_TELNET_SERVER * server_ptr)955 UINT  _nx_telnet_server_start(NX_TELNET_SERVER *server_ptr)
956 {
957 
958 UINT    status;
959 ULONG   events;
960 
961 #ifndef NX_TELNET_SERVER_OPTION_DISABLE
962 
963     /* Check for Telnet server packet pool we'll need to send options. */
964     if (server_ptr -> nx_telnet_server_packet_pool_ptr == NX_NULL)
965     {
966 
967         /* The Telnet server packet pool is not set. */
968         return NX_TELNET_NO_PACKET_POOL;
969     }
970 #endif
971 
972     /* Start listening on the TELNET socket.  */
973     status =  nx_tcp_server_socket_listen(server_ptr -> nx_telnet_server_ip_ptr, NX_TELNET_SERVER_PORT,
974                         &(server_ptr -> nx_telnet_server_client_list[0].nx_telnet_client_request_socket),
975                                     NX_TELNET_MAX_CLIENTS, _nx_telnet_server_connection_present);
976 
977     /* Determine if an error is present.  */
978     if (status != NX_SUCCESS)
979     {
980 
981         /* Error, return to caller.  */
982         return(status);
983     }
984 
985     /* Activate TELNET server timer.  */
986     tx_timer_activate(&(server_ptr -> nx_telnet_server_timer));
987 
988     /* Clear stop event. */
989     tx_event_flags_get(&(server_ptr -> nx_telnet_server_event_flags), NX_TELNET_STOP_EVENT, TX_OR_CLEAR, &events, TX_NO_WAIT);
990 
991     /* Start the TELNET server thread.  */
992     tx_thread_resume(&(server_ptr -> nx_telnet_server_thread));
993 
994     /* Return successful completion.  */
995     return(NX_SUCCESS);
996 }
997 
998 
999 /**************************************************************************/
1000 /*                                                                        */
1001 /*  FUNCTION                                               RELEASE        */
1002 /*                                                                        */
1003 /*    _nxe_telnet_server_stop                             PORTABLE C      */
1004 /*                                                           6.1          */
1005 /*  AUTHOR                                                                */
1006 /*                                                                        */
1007 /*    Yuxin Zhou, Microsoft Corporation                                   */
1008 /*                                                                        */
1009 /*  DESCRIPTION                                                           */
1010 /*                                                                        */
1011 /*    This function checks for errors in the TELNET server stop call.     */
1012 /*                                                                        */
1013 /*                                                                        */
1014 /*  INPUT                                                                 */
1015 /*                                                                        */
1016 /*    server_ptr                            Pointer to TELNET server      */
1017 /*                                                                        */
1018 /*  OUTPUT                                                                */
1019 /*                                                                        */
1020 /*    status                                Completion status             */
1021 /*                                                                        */
1022 /*  CALLS                                                                 */
1023 /*                                                                        */
1024 /*    _nx_telnet_server_stop                Actual server start call      */
1025 /*                                                                        */
1026 /*  CALLED BY                                                             */
1027 /*                                                                        */
1028 /*    Application Code                                                    */
1029 /*                                                                        */
1030 /*  RELEASE HISTORY                                                       */
1031 /*                                                                        */
1032 /*    DATE              NAME                      DESCRIPTION             */
1033 /*                                                                        */
1034 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
1035 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
1036 /*                                            resulting in version 6.1    */
1037 /*                                                                        */
1038 /**************************************************************************/
_nxe_telnet_server_stop(NX_TELNET_SERVER * server_ptr)1039 UINT  _nxe_telnet_server_stop(NX_TELNET_SERVER *server_ptr)
1040 {
1041 
1042 UINT    status;
1043 
1044 
1045     /* Check for invalid input pointers.  */
1046     if ((server_ptr == NX_NULL) || (server_ptr -> nx_telnet_server_id != NX_TELNET_SERVER_ID))
1047         return(NX_PTR_ERROR);
1048 
1049     /* Check for appropriate caller.  */
1050     NX_THREADS_ONLY_CALLER_CHECKING
1051 
1052     /* Call actual server delete function.  */
1053     status =  _nx_telnet_server_stop(server_ptr);
1054 
1055     /* Return completion status.  */
1056     return(status);
1057 }
1058 
1059 
1060 /**************************************************************************/
1061 /*                                                                        */
1062 /*  FUNCTION                                               RELEASE        */
1063 /*                                                                        */
1064 /*    _nx_telnet_server_stop                              PORTABLE C      */
1065 /*                                                           6.1          */
1066 /*  AUTHOR                                                                */
1067 /*                                                                        */
1068 /*    Yuxin Zhou, Microsoft Corporation                                   */
1069 /*                                                                        */
1070 /*  DESCRIPTION                                                           */
1071 /*                                                                        */
1072 /*    This function stops a previously started TELNET server on the       */
1073 /*    specified IP.                                                       */
1074 /*                                                                        */
1075 /*                                                                        */
1076 /*  INPUT                                                                 */
1077 /*                                                                        */
1078 /*    server_ptr                            Pointer to TELNET server      */
1079 /*                                                                        */
1080 /*  OUTPUT                                                                */
1081 /*                                                                        */
1082 /*    status                                Completion status             */
1083 /*                                                                        */
1084 /*  CALLS                                                                 */
1085 /*                                                                        */
1086 /*    tx_event_flags_set                    Set events for server thread  */
1087 /*    tx_timer_deactivate                   Deactivate TELNET server timer*/
1088 /*    nx_tcp_server_socket_unaccept         Unaccept server socket        */
1089 /*    nx_tcp_server_socket_unlisten         Unlisten on server            */
1090 /*    nx_tcp_socket_disconnect              Disconnect socket             */
1091 /*                                                                        */
1092 /*  CALLED BY                                                             */
1093 /*                                                                        */
1094 /*    Application Code                                                    */
1095 /*                                                                        */
1096 /*  RELEASE HISTORY                                                       */
1097 /*                                                                        */
1098 /*    DATE              NAME                      DESCRIPTION             */
1099 /*                                                                        */
1100 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
1101 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
1102 /*                                            resulting in version 6.1    */
1103 /*                                                                        */
1104 /**************************************************************************/
_nx_telnet_server_stop(NX_TELNET_SERVER * server_ptr)1105 UINT  _nx_telnet_server_stop(NX_TELNET_SERVER *server_ptr)
1106 {
1107 UINT                        i;
1108 NX_TELNET_CLIENT_REQUEST   *client_request_ptr;
1109 
1110     /* Deactivate TELNET server timer.  */
1111     tx_timer_deactivate(&(server_ptr -> nx_telnet_server_timer));
1112 
1113     /* Suspend the TELNET server thread.  */
1114     tx_event_flags_set(&(server_ptr -> nx_telnet_server_event_flags), NX_TELNET_STOP_EVENT, TX_OR);
1115 
1116     /* Walk through the server structure to close and delete any open sockets.  */
1117     i =  0;
1118     client_request_ptr =  &(server_ptr -> nx_telnet_server_client_list[0]);
1119     while (i < NX_TELNET_MAX_CLIENTS)
1120     {
1121 
1122         /* Disconnect the socket.  */
1123         nx_tcp_socket_disconnect(&(client_request_ptr -> nx_telnet_client_request_socket), NX_NO_WAIT);
1124 
1125         /* Unaccept the socket.  */
1126         nx_tcp_server_socket_unaccept(&(client_request_ptr -> nx_telnet_client_request_socket));
1127 
1128         /* Reset client request. */
1129         client_request_ptr -> nx_telnet_client_request_activity_timeout =  0;
1130 
1131         /* Increment the pointer into the client request list.  */
1132         client_request_ptr++;
1133         i++;
1134     }
1135 
1136     /* Unlisten on the TELNET port.  */
1137     nx_tcp_server_socket_unlisten(server_ptr -> nx_telnet_server_ip_ptr, NX_TELNET_SERVER_PORT);
1138 
1139     /* Return successful completion.  */
1140     return(NX_SUCCESS);
1141 }
1142 
1143 
1144 /**************************************************************************/
1145 /*                                                                        */
1146 /*  FUNCTION                                               RELEASE        */
1147 /*                                                                        */
1148 /*    _nxe_telnet_server_get_open_connection_count        PORTABLE C      */
1149 /*                                                           6.1          */
1150 /*  AUTHOR                                                                */
1151 /*                                                                        */
1152 /*    Yuxin Zhou, Microsoft Corporation                                   */
1153 /*                                                                        */
1154 /*  DESCRIPTION                                                           */
1155 /*                                                                        */
1156 /*    This function checks for errors in the TELNET server get open       */
1157 /*    connection count service.                                           */
1158 /*                                                                        */
1159 /*                                                                        */
1160 /*  INPUT                                                                 */
1161 /*                                                                        */
1162 /*    server_ptr                            Pointer to TELNET server      */
1163 /*    current_connections                   Pointer to # open connections */
1164 /*                                                                        */
1165 /*  OUTPUT                                                                */
1166 /*                                                                        */
1167 /*    status                                Completion status             */
1168 /*                                                                        */
1169 /*  CALLS                                                                 */
1170 /*                                                                        */
1171 /*    _nx_telnet_server_get_open_connection_count                         */
1172 /*                                          Actual server get count call  */
1173 /*                                                                        */
1174 /*  CALLED BY                                                             */
1175 /*                                                                        */
1176 /*    Application Code                                                    */
1177 /*                                                                        */
1178 /*  RELEASE HISTORY                                                       */
1179 /*                                                                        */
1180 /*    DATE              NAME                      DESCRIPTION             */
1181 /*                                                                        */
1182 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
1183 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
1184 /*                                            resulting in version 6.1    */
1185 /*                                                                        */
1186 /**************************************************************************/
_nxe_telnet_server_get_open_connection_count(NX_TELNET_SERVER * server_ptr,UINT * current_connections)1187 UINT  _nxe_telnet_server_get_open_connection_count(NX_TELNET_SERVER *server_ptr, UINT *current_connections)
1188 {
1189 
1190 UINT    status;
1191 
1192 
1193     /* Check for invalid input pointers.  */
1194     if ((server_ptr == NX_NULL) || (current_connections == NX_NULL))
1195         return(NX_PTR_ERROR);
1196 
1197     /* Check for appropriate caller.  */
1198     NX_THREADS_ONLY_CALLER_CHECKING
1199 
1200     /* Call actual server delete function.  */
1201     status =  _nx_telnet_server_get_open_connection_count(server_ptr, current_connections);
1202 
1203     /* Return completion status.  */
1204     return(status);
1205 }
1206 
1207 /**************************************************************************/
1208 /*                                                                        */
1209 /*  FUNCTION                                               RELEASE        */
1210 /*                                                                        */
1211 /*    _nx_telnet_server_get_open_connection_count         PORTABLE C      */
1212 /*                                                           6.1          */
1213 /*  AUTHOR                                                                */
1214 /*                                                                        */
1215 /*    Yuxin Zhou, Microsoft Corporation                                   */
1216 /*                                                                        */
1217 /*  DESCRIPTION                                                           */
1218 /*                                                                        */
1219 /*    This function returns the number of currently open connections.     */
1220 /*                                                                        */
1221 /*                                                                        */
1222 /*  INPUT                                                                 */
1223 /*                                                                        */
1224 /*    server_ptr                            Pointer to TELNET server      */
1225 /*    current_connections                   Pointer to # open connections */
1226 /*                                                                        */
1227 /*  OUTPUT                                                                */
1228 /*                                                                        */
1229 /*    NX_SUCCESS                            Successful completion status  */
1230 /*                                                                        */
1231 /*  CALLS                                                                 */
1232 /*                                                                        */
1233 /*    None                                                                */
1234 /*                                                                        */
1235 /*  CALLED BY                                                             */
1236 /*                                                                        */
1237 /*    Application Code                                                    */
1238 /*                                                                        */
1239 /*  RELEASE HISTORY                                                       */
1240 /*                                                                        */
1241 /*    DATE              NAME                      DESCRIPTION             */
1242 /*                                                                        */
1243 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
1244 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
1245 /*                                            resulting in version 6.1    */
1246 /*                                                                        */
1247 /**************************************************************************/
_nx_telnet_server_get_open_connection_count(NX_TELNET_SERVER * server_ptr,UINT * current_connections)1248 UINT  _nx_telnet_server_get_open_connection_count(NX_TELNET_SERVER *server_ptr, UINT *current_connections)
1249 {
1250 
1251     /* Retrieve server's record of open connections.  */
1252     *current_connections =  server_ptr -> nx_telnet_server_open_connections;
1253 
1254     /* Return completion status.  */
1255     return(NX_SUCCESS);
1256 }
1257 
1258 /**************************************************************************/
1259 /*                                                                        */
1260 /*  FUNCTION                                               RELEASE        */
1261 /*                                                                        */
1262 /*    _nx_telnet_server_thread_entry                      PORTABLE C      */
1263 /*                                                           6.1          */
1264 /*  AUTHOR                                                                */
1265 /*                                                                        */
1266 /*    Yuxin Zhou, Microsoft Corporation                                   */
1267 /*                                                                        */
1268 /*  DESCRIPTION                                                           */
1269 /*                                                                        */
1270 /*    This function is the entry of the TELNET server.  All basic         */
1271 /*    processing is initiated by this function.                           */
1272 /*                                                                        */
1273 /*                                                                        */
1274 /*  INPUT                                                                 */
1275 /*                                                                        */
1276 /*    telnet_server                             Pointer to TELNET server  */
1277 /*                                                                        */
1278 /*  OUTPUT                                                                */
1279 /*                                                                        */
1280 /*    None                                                                */
1281 /*                                                                        */
1282 /*  CALLS                                                                 */
1283 /*                                                                        */
1284 /*   _nx_telnet_server_connect_process          Process connection        */
1285 /*   _nx_telnet_server_data_process             Process received data     */
1286 /*   _nx_telnet_server_disconnect_process       Process disconnection     */
1287 /*   _nx_telnet_server_timeout_processing       Process activity timeout  */
1288 /*   tx_event_flags_get                         Get TELNET event(s)       */
1289 /*   tx_thread_suspend                          Suspend TELNET thread     */
1290 /*                                                                        */
1291 /*  CALLED BY                                                             */
1292 /*                                                                        */
1293 /*    ThreadX                                                             */
1294 /*                                                                        */
1295 /*  RELEASE HISTORY                                                       */
1296 /*                                                                        */
1297 /*    DATE              NAME                      DESCRIPTION             */
1298 /*                                                                        */
1299 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
1300 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
1301 /*                                            resulting in version 6.1    */
1302 /*                                                                        */
1303 /**************************************************************************/
_nx_telnet_server_thread_entry(ULONG telnet_server)1304 VOID  _nx_telnet_server_thread_entry(ULONG telnet_server)
1305 {
1306 
1307 NX_TELNET_SERVER        *server_ptr;
1308 UINT                    status;
1309 ULONG                   events;
1310 
1311 
1312     /* Setup the server pointer.  */
1313     server_ptr =  (NX_TELNET_SERVER *) telnet_server;
1314 
1315     /* Loop to process TELNET Server requests.  */
1316     while(1)
1317     {
1318 
1319         /* Wait for an TELNET client activity.  */
1320         status =  tx_event_flags_get(&(server_ptr -> nx_telnet_server_event_flags), NX_TELNET_ANY_EVENT, TX_OR_CLEAR, &events, TX_WAIT_FOREVER);
1321 
1322         /* Check the return status.  */
1323         if (status)
1324         {
1325 
1326             /* If an error occurs, simply continue the loop.  */
1327             continue;
1328         }
1329 
1330         /* Check whether service is started. */
1331         if (events & NX_TELNET_STOP_EVENT)
1332         {
1333 
1334             /* Suspend thread here. */
1335             tx_thread_suspend(&server_ptr -> nx_telnet_server_thread);
1336             continue;
1337         }
1338 
1339         /* Otherwise, an event is present.  Process according to the event.  */
1340 
1341         /* Check for a client connection event.  */
1342         if (events & NX_TELNET_SERVER_CONNECT)
1343         {
1344 
1345             /* Call the connect processing.  */
1346             _nx_telnet_server_connect_process(server_ptr);
1347         }
1348 
1349         /* Check for a TELNET client write data event.  */
1350         if  (events & NX_TELNET_SERVER_DATA)
1351         {
1352 
1353             /* Call processing to handle server data.  */
1354             _nx_telnet_server_data_process(server_ptr);
1355         }
1356 
1357         /* Check for a client disconnect event.  */
1358         if  (events & NX_TELNET_SERVER_DISCONNECT)
1359         {
1360 
1361             /* Call the disconnect processing.  */
1362             _nx_telnet_server_disconnect_process(server_ptr);
1363         }
1364 
1365         /* Check for a client activity timeout event.  */
1366         if  (events & NX_TELNET_SERVER_ACTIVITY_TIMEOUT)
1367         {
1368 
1369             /* Call the activity timeout processing.  */
1370             _nx_telnet_server_timeout_processing(server_ptr);
1371         }
1372     }
1373 }
1374 
1375 
1376 /**************************************************************************/
1377 /*                                                                        */
1378 /*  FUNCTION                                               RELEASE        */
1379 /*                                                                        */
1380 /*    _nx_telnet_server_connect_process                   PORTABLE C      */
1381 /*                                                           6.1          */
1382 /*  AUTHOR                                                                */
1383 /*                                                                        */
1384 /*    Yuxin Zhou, Microsoft Corporation                                   */
1385 /*                                                                        */
1386 /*  DESCRIPTION                                                           */
1387 /*                                                                        */
1388 /*    This function handles all TELNET client connections received.       */
1389 /*                                                                        */
1390 /*                                                                        */
1391 /*  INPUT                                                                 */
1392 /*                                                                        */
1393 /*    server_ptr                            Pointer to TELNET server      */
1394 /*                                                                        */
1395 /*  OUTPUT                                                                */
1396 /*                                                                        */
1397 /*    None                                                                */
1398 /*                                                                        */
1399 /*  CALLS                                                                 */
1400 /*                                                                        */
1401 /*    nx_tcp_server_socket_accept           Accept connection on socket   */
1402 /*    nx_tcp_server_socket_relisten         Relisten for connection       */
1403 /*    nx_tcp_server_socket_unaccept         Unaccept connection           */
1404 /*                                                                        */
1405 /*  CALLED BY                                                             */
1406 /*                                                                        */
1407 /*    _nx_telnet_server_thread_entry        TELNET server thread          */
1408 /*                                                                        */
1409 /*  RELEASE HISTORY                                                       */
1410 /*                                                                        */
1411 /*    DATE              NAME                      DESCRIPTION             */
1412 /*                                                                        */
1413 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
1414 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
1415 /*                                            resulting in version 6.1    */
1416 /*                                                                        */
1417 /**************************************************************************/
_nx_telnet_server_connect_process(NX_TELNET_SERVER * server_ptr)1418 VOID  _nx_telnet_server_connect_process(NX_TELNET_SERVER *server_ptr)
1419 {
1420 
1421 UINT                        i;
1422 UINT                        status;
1423 NX_TELNET_CLIENT_REQUEST    *client_req_ptr;
1424 
1425 
1426     /* One of the client request sockets is in the process of connection.  */
1427 
1428     /* Search the connections to see which one.  */
1429     for (i = 0; i < NX_TELNET_MAX_CLIENTS; i++)
1430     {
1431 
1432         /* Setup pointer to client request structure.  */
1433         client_req_ptr =  &(server_ptr -> nx_telnet_server_client_list[i]);
1434 
1435         /* Now see if this socket was the one that is in being connected.  */
1436         if ((client_req_ptr -> nx_telnet_client_request_socket.nx_tcp_socket_state > NX_TCP_CLOSED) &&
1437             (client_req_ptr -> nx_telnet_client_request_socket.nx_tcp_socket_state < NX_TCP_ESTABLISHED) &&
1438             (client_req_ptr -> nx_telnet_client_request_socket.nx_tcp_socket_connect_port))
1439         {
1440 
1441             /* Yes, we have found the socket being connected.  */
1442 
1443             /* Increment the number of connection requests.  */
1444             server_ptr -> nx_telnet_server_connection_requests++;
1445 
1446             /* Attempt to accept on this socket.  */
1447             status = nx_tcp_server_socket_accept(&(client_req_ptr -> nx_telnet_client_request_socket), NX_TELNET_SERVER_TIMEOUT);
1448 
1449             /* Determine if it is successful.  */
1450             if (status)
1451             {
1452 
1453                 /* Not successful, simply unaccept on this socket.  */
1454                 nx_tcp_server_socket_unaccept(&(client_req_ptr -> nx_telnet_client_request_socket));
1455             }
1456             else
1457             {
1458 
1459                 /* Reset the client request activity timeout.  */
1460                 client_req_ptr -> nx_telnet_client_request_activity_timeout =  NX_TELNET_ACTIVITY_TIMEOUT;
1461 
1462                 /* Update number of current open connections.  */
1463                 server_ptr -> nx_telnet_server_open_connections++;
1464 
1465                 /* Call the application's new connection callback routine.  */
1466                 if (server_ptr -> nx_telnet_new_connection)
1467                 {
1468                     /* Yes, there is a new connection callback routine - call it!  */
1469                     (server_ptr -> nx_telnet_new_connection)(server_ptr, client_req_ptr -> nx_telnet_client_request_connection);
1470                 }
1471 
1472                 /* Disable remote echo by default. */
1473                 if(server_ptr -> nx_telnet_set_echo)
1474                     server_ptr -> nx_telnet_set_echo(server_ptr, client_req_ptr -> nx_telnet_client_request_connection, NX_FALSE);
1475 
1476 #ifndef NX_TELNET_SERVER_OPTION_DISABLE
1477 
1478                 /* Yes, send out server echo option requests. */
1479                 status = _nx_telnet_server_send_option_requests(server_ptr, client_req_ptr);
1480                 if(status != NX_SUCCESS)
1481                     return;
1482 #endif /* NX_TELNET_SERVER_OPTION_DISABLE */
1483 
1484             }
1485         }
1486     }
1487 
1488     /* Now look for a socket that is closed to relisten on.  */
1489     for (i = 0; i < NX_TELNET_MAX_CLIENTS; i++)
1490     {
1491 
1492         /* Set a pointer to client request structure.  */
1493         client_req_ptr =  &(server_ptr -> nx_telnet_server_client_list[i]);
1494 
1495         /* Now see if this socket is closed.  */
1496         if (client_req_ptr -> nx_telnet_client_request_socket.nx_tcp_socket_state == NX_TCP_CLOSED)
1497         {
1498 
1499             /* Relisten on this socket.  */
1500             status =  nx_tcp_server_socket_relisten(server_ptr -> nx_telnet_server_ip_ptr, NX_TELNET_SERVER_PORT,
1501                                                     &(client_req_ptr -> nx_telnet_client_request_socket));
1502             /* Check for bad status.  */
1503             if ((status != NX_SUCCESS) && (status != NX_CONNECTION_PENDING))
1504             {
1505 
1506                 /* Increment the error count and keep trying.  */
1507                 server_ptr -> nx_telnet_server_relisten_errors++;
1508                 continue;
1509             }
1510 
1511             /* Break out of loop.  */
1512             break;
1513         }
1514     }
1515 }
1516 
1517 
1518 /**************************************************************************/
1519 /*                                                                        */
1520 /*  FUNCTION                                               RELEASE        */
1521 /*                                                                        */
1522 /*    _nx_telnet_server_connection_present                PORTABLE C      */
1523 /*                                                           6.1          */
1524 /*  AUTHOR                                                                */
1525 /*                                                                        */
1526 /*    Yuxin Zhou, Microsoft Corporation                                   */
1527 /*                                                                        */
1528 /*  DESCRIPTION                                                           */
1529 /*                                                                        */
1530 /*    This function handles all TELNET client connections received on     */
1531 /*    the socket.                                                         */
1532 /*                                                                        */
1533 /*                                                                        */
1534 /*  INPUT                                                                 */
1535 /*                                                                        */
1536 /*    socket_ptr                            Socket event occurred         */
1537 /*    port                                  Port the connection occurred  */
1538 /*                                                                        */
1539 /*  OUTPUT                                                                */
1540 /*                                                                        */
1541 /*    None                                                                */
1542 /*                                                                        */
1543 /*  CALLS                                                                 */
1544 /*                                                                        */
1545 /*    tx_event_flags_set                    Set events for server thread  */
1546 /*                                                                        */
1547 /*  CALLED BY                                                             */
1548 /*                                                                        */
1549 /*    NetX                                  NetX connect callback         */
1550 /*                                                                        */
1551 /*  RELEASE HISTORY                                                       */
1552 /*                                                                        */
1553 /*    DATE              NAME                      DESCRIPTION             */
1554 /*                                                                        */
1555 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
1556 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
1557 /*                                            resulting in version 6.1    */
1558 /*                                                                        */
1559 /**************************************************************************/
_nx_telnet_server_connection_present(NX_TCP_SOCKET * socket_ptr,UINT port)1560 VOID  _nx_telnet_server_connection_present(NX_TCP_SOCKET *socket_ptr, UINT port)
1561 {
1562 
1563 NX_TELNET_SERVER   *server_ptr;
1564 
1565     NX_PARAMETER_NOT_USED(port);
1566 
1567     /* Pickup server pointer.  This is setup in the reserved field of the TCP socket.  */
1568     server_ptr =  socket_ptr -> nx_tcp_socket_reserved_ptr;
1569 
1570     /* Set the connect event flag.  */
1571     tx_event_flags_set(&(server_ptr -> nx_telnet_server_event_flags), NX_TELNET_SERVER_CONNECT, TX_OR);
1572 }
1573 
1574 
1575 /**************************************************************************/
1576 /*                                                                        */
1577 /*  FUNCTION                                               RELEASE        */
1578 /*                                                                        */
1579 /*    _nx_telnet_server_disconnect_present                PORTABLE C      */
1580 /*                                                           6.1          */
1581 /*  AUTHOR                                                                */
1582 /*                                                                        */
1583 /*    Yuxin Zhou, Microsoft Corporation                                   */
1584 /*                                                                        */
1585 /*  DESCRIPTION                                                           */
1586 /*                                                                        */
1587 /*    This function handles all TELNET client disconnections received on  */
1588 /*    the socket.                                                         */
1589 /*                                                                        */
1590 /*                                                                        */
1591 /*  INPUT                                                                 */
1592 /*                                                                        */
1593 /*    socket_ptr                            Socket event occurred         */
1594 /*                                                                        */
1595 /*  OUTPUT                                                                */
1596 /*                                                                        */
1597 /*    None                                                                */
1598 /*                                                                        */
1599 /*  CALLS                                                                 */
1600 /*                                                                        */
1601 /*    tx_event_flags_set                    Set events for server thread  */
1602 /*                                                                        */
1603 /*  CALLED BY                                                             */
1604 /*                                                                        */
1605 /*    NetX                                  NetX connect callback         */
1606 /*                                                                        */
1607 /*  RELEASE HISTORY                                                       */
1608 /*                                                                        */
1609 /*    DATE              NAME                      DESCRIPTION             */
1610 /*                                                                        */
1611 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
1612 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
1613 /*                                            resulting in version 6.1    */
1614 /*                                                                        */
1615 /**************************************************************************/
_nx_telnet_server_disconnect_present(NX_TCP_SOCKET * socket_ptr)1616 VOID  _nx_telnet_server_disconnect_present(NX_TCP_SOCKET *socket_ptr)
1617 {
1618 
1619 NX_TELNET_SERVER   *server_ptr;
1620 
1621     /* Pickup server pointer.  This is setup in the reserved field of the TCP socket.  */
1622     server_ptr =  socket_ptr -> nx_tcp_socket_reserved_ptr;
1623 
1624     /* Set the disconnect event flag.  */
1625     tx_event_flags_set(&(server_ptr -> nx_telnet_server_event_flags), NX_TELNET_SERVER_DISCONNECT, TX_OR);
1626 }
1627 
1628 
1629 /**************************************************************************/
1630 /*                                                                        */
1631 /*  FUNCTION                                               RELEASE        */
1632 /*                                                                        */
1633 /*    _nx_telnet_server_disconnect_process                PORTABLE C      */
1634 /*                                                           6.1          */
1635 /*  AUTHOR                                                                */
1636 /*                                                                        */
1637 /*    Yuxin Zhou, Microsoft Corporation                                   */
1638 /*                                                                        */
1639 /*  DESCRIPTION                                                           */
1640 /*                                                                        */
1641 /*    This function processes all TELNET client disconnections received   */
1642 /*    on the socket.                                                      */
1643 /*                                                                        */
1644 /*                                                                        */
1645 /*  INPUT                                                                 */
1646 /*                                                                        */
1647 /*    server_ptr                            Pointer to TELNET server      */
1648 /*                                                                        */
1649 /*  OUTPUT                                                                */
1650 /*                                                                        */
1651 /*    None                                                                */
1652 /*                                                                        */
1653 /*  CALLS                                                                 */
1654 /*                                                                        */
1655 /*    nx_tcp_server_socket_relisten         Relisten on Telnet port       */
1656 /*    nx_tcp_server_socket_unaccept         Unaccept connection           */
1657 /*    nx_tcp_socket_disconnect              Disconnect socket             */
1658 /*                                                                        */
1659 /*  CALLED BY                                                             */
1660 /*                                                                        */
1661 /*    _nx_telnet_server_thread_entry        TELNET server thread          */
1662 /*                                                                        */
1663 /*  RELEASE HISTORY                                                       */
1664 /*                                                                        */
1665 /*    DATE              NAME                      DESCRIPTION             */
1666 /*                                                                        */
1667 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
1668 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
1669 /*                                            resulting in version 6.1    */
1670 /*                                                                        */
1671 /**************************************************************************/
_nx_telnet_server_disconnect_process(NX_TELNET_SERVER * server_ptr)1672 VOID  _nx_telnet_server_disconnect_process(NX_TELNET_SERVER *server_ptr)
1673 {
1674 
1675 UINT                        i;
1676 UINT                        status;
1677 NX_TELNET_CLIENT_REQUEST   *client_req_ptr;
1678 UINT                        reset_client_request;
1679 
1680 
1681     /* Now look for a socket that has a disconnect state.  */
1682     for (i = 0; i < NX_TELNET_MAX_CLIENTS; i++)
1683     {
1684 
1685         reset_client_request = NX_FALSE;
1686 
1687         /* Setup pointer to client request structure.  */
1688         client_req_ptr =  &(server_ptr -> nx_telnet_server_client_list[i]);
1689 
1690        /* Has the socket received a RST packet? If so NetX will put it in a CLOSED or LISTEN state
1691           and the socket activity timeout has not been reset yet.  */
1692        if (client_req_ptr -> nx_telnet_client_request_socket.nx_tcp_socket_state < NX_TCP_SYN_SENT)
1693        {
1694 
1695             if (client_req_ptr -> nx_telnet_client_request_activity_timeout > 0)
1696             {
1697 
1698                 reset_client_request = NX_TRUE;
1699             }
1700        }
1701        else
1702        {
1703 
1704             /* Now see if this socket has entered a disconnect state.  */
1705             while (client_req_ptr -> nx_telnet_client_request_socket.nx_tcp_socket_state > NX_TCP_ESTABLISHED)
1706             {
1707 
1708                 /* Yes, a disconnect is present, which signals an end of session for TELNET request.  */
1709 
1710                 /* First, cleanup this socket.  */
1711                 nx_tcp_socket_disconnect(&(client_req_ptr -> nx_telnet_client_request_socket), NX_TELNET_SERVER_TIMEOUT);
1712 
1713                 reset_client_request = NX_TRUE;
1714             }
1715        }
1716 
1717        /* If this connection is closed, update the telnet data and notify the application of a disconnect. */
1718        if (reset_client_request == NX_TRUE)
1719        {
1720 
1721            /* Unaccept this socket.  */
1722            nx_tcp_server_socket_unaccept(&(client_req_ptr -> nx_telnet_client_request_socket));
1723 
1724            /* Reset the client request activity timeout.  */
1725            client_req_ptr -> nx_telnet_client_request_activity_timeout =  0;
1726 
1727            /* Update number of current open connections. */
1728            if (server_ptr -> nx_telnet_server_open_connections > 0)
1729                server_ptr -> nx_telnet_server_open_connections--;
1730 
1731            /* Call the application's end connection callback routine.  */
1732            if (server_ptr -> nx_telnet_connection_end)
1733            {
1734 
1735                /* Yes, there is a connection end callback routine - call it!  */
1736                (server_ptr -> nx_telnet_connection_end)(server_ptr, client_req_ptr -> nx_telnet_client_request_connection);
1737            }
1738        }
1739     }
1740 
1741     /* Now look for a socket that is closed to relisten on.  */
1742     for (i = 0; i < NX_TELNET_MAX_CLIENTS; i++)
1743     {
1744 
1745         /* Setup pointer to client request structure.  */
1746         client_req_ptr =  &(server_ptr -> nx_telnet_server_client_list[i]);
1747 
1748         /* Now see if this socket is closed.  */
1749         if (client_req_ptr -> nx_telnet_client_request_socket.nx_tcp_socket_state == NX_TCP_CLOSED)
1750         {
1751 
1752             /* Relisten on this socket.  */
1753             status =  nx_tcp_server_socket_relisten(server_ptr -> nx_telnet_server_ip_ptr, NX_TELNET_SERVER_PORT,
1754                                                     &(client_req_ptr -> nx_telnet_client_request_socket));
1755             /* Check for bad status.  */
1756             if ((status != NX_SUCCESS) && (status != NX_CONNECTION_PENDING))
1757             {
1758 
1759                 /* Increment the error count and keep trying.  */
1760                 server_ptr -> nx_telnet_server_relisten_errors++;
1761                 continue;
1762             }
1763 
1764             /* Break out of loop.  */
1765             break;
1766         }
1767     }
1768 }
1769 
1770 
1771 /**************************************************************************/
1772 /*                                                                        */
1773 /*  FUNCTION                                               RELEASE        */
1774 /*                                                                        */
1775 /*    _nx_telnet_server_data_present                      PORTABLE C      */
1776 /*                                                           6.1          */
1777 /*  AUTHOR                                                                */
1778 /*                                                                        */
1779 /*    Yuxin Zhou, Microsoft Corporation                                   */
1780 /*                                                                        */
1781 /*  DESCRIPTION                                                           */
1782 /*                                                                        */
1783 /*    This function notifies the TELNET server thread of data received    */
1784 /*    from a client on the socket.                                        */
1785 /*                                                                        */
1786 /*                                                                        */
1787 /*  INPUT                                                                 */
1788 /*                                                                        */
1789 /*    socket_ptr                            Socket event occurred         */
1790 /*                                                                        */
1791 /*  OUTPUT                                                                */
1792 /*                                                                        */
1793 /*    None                                                                */
1794 /*                                                                        */
1795 /*  CALLS                                                                 */
1796 /*                                                                        */
1797 /*    tx_event_flags_set                    Set events for server thread  */
1798 /*                                                                        */
1799 /*  CALLED BY                                                             */
1800 /*                                                                        */
1801 /*    NetX                                  NetX connect callback         */
1802 /*                                                                        */
1803 /*  RELEASE HISTORY                                                       */
1804 /*                                                                        */
1805 /*    DATE              NAME                      DESCRIPTION             */
1806 /*                                                                        */
1807 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
1808 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
1809 /*                                            resulting in version 6.1    */
1810 /*                                                                        */
1811 /**************************************************************************/
_nx_telnet_server_data_present(NX_TCP_SOCKET * socket_ptr)1812 VOID  _nx_telnet_server_data_present(NX_TCP_SOCKET *socket_ptr)
1813 {
1814 
1815 NX_TELNET_SERVER   *server_ptr;
1816 
1817     /* Pickup server pointer.  This is setup in the reserved field of the TCP socket.  */
1818     server_ptr =  socket_ptr -> nx_tcp_socket_reserved_ptr;
1819 
1820     /* Set the data event flag.  */
1821     tx_event_flags_set(&(server_ptr -> nx_telnet_server_event_flags), NX_TELNET_SERVER_DATA, TX_OR);
1822 }
1823 
1824 
1825 /**************************************************************************/
1826 /*                                                                        */
1827 /*  FUNCTION                                               RELEASE        */
1828 /*                                                                        */
1829 /*    _nx_telnet_server_data_process                      PORTABLE C      */
1830 /*                                                           6.1          */
1831 /*  AUTHOR                                                                */
1832 /*                                                                        */
1833 /*    Yuxin Zhou, Microsoft Corporation                                   */
1834 /*                                                                        */
1835 /*  DESCRIPTION                                                           */
1836 /*                                                                        */
1837 /*    This function processes all TELNET client data packets received on  */
1838 /*    the request socket.                                                 */
1839 /*                                                                        */
1840 /*                                                                        */
1841 /*  INPUT                                                                 */
1842 /*                                                                        */
1843 /*    server_ptr                            Pointer to TELNET server      */
1844 /*                                                                        */
1845 /*  OUTPUT                                                                */
1846 /*                                                                        */
1847 /*    None                                                                */
1848 /*                                                                        */
1849 /*  CALLS                                                                 */
1850 /*                                                                        */
1851 /*    nx_packet_release                     Release packet                */
1852 /*    nx_tcp_socket_receive                 Receive from socket           */
1853 /*                                                                        */
1854 /*  CALLED BY                                                             */
1855 /*                                                                        */
1856 /*    _nx_telnet_server_thread_entry        TELNET server thread          */
1857 /*                                                                        */
1858 /*  RELEASE HISTORY                                                       */
1859 /*                                                                        */
1860 /*    DATE              NAME                      DESCRIPTION             */
1861 /*                                                                        */
1862 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
1863 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
1864 /*                                            resulting in version 6.1    */
1865 /*                                                                        */
1866 /**************************************************************************/
_nx_telnet_server_data_process(NX_TELNET_SERVER * server_ptr)1867 VOID  _nx_telnet_server_data_process(NX_TELNET_SERVER *server_ptr)
1868 {
1869 
1870 UINT                        i;
1871 UINT                        status;
1872 NX_PACKET                   *packet_ptr;
1873 NX_TELNET_CLIENT_REQUEST    *client_req_ptr;
1874 #ifndef NX_TELNET_SERVER_OPTION_DISABLE
1875 UCHAR                       data_char;
1876 UINT                        offset;
1877 #endif /* NX_TELNET_SERVER_OPTION_DISABLE */
1878 
1879     /* Now look for a socket that has receive data.  */
1880     for (i = 0; i < NX_TELNET_MAX_CLIENTS; i++)
1881     {
1882 
1883         /* Setup pointer to client request structure.  */
1884         client_req_ptr =  &(server_ptr -> nx_telnet_server_client_list[i]);
1885 
1886         /* Now see if this socket has data.  If so, process all of it now!  */
1887         while (client_req_ptr -> nx_telnet_client_request_socket.nx_tcp_socket_receive_queue_count)
1888         {
1889 
1890             /* Reset the client request activity timeout.  */
1891             client_req_ptr -> nx_telnet_client_request_activity_timeout =  NX_TELNET_ACTIVITY_TIMEOUT;
1892 
1893             /* Attempt to read a packet from this socket.  */
1894             status =  nx_tcp_socket_receive(&(client_req_ptr -> nx_telnet_client_request_socket), &packet_ptr, NX_NO_WAIT);
1895 
1896             /* Check for not data present.  */
1897             if (status != NX_SUCCESS)
1898             {
1899 
1900                 /* Break to look at the next socket.  */
1901                 break;
1902             }
1903 
1904 #ifndef NX_TELNET_SERVER_OPTION_DISABLE
1905 
1906             /* If the first byte of the packet data is the telnet "IAC" code,
1907             this is a telnet option packet.  */
1908             if (*packet_ptr -> nx_packet_prepend_ptr == NX_TELNET_IAC)
1909             {
1910 
1911 #ifndef NX_DISABLE_PACKET_CHAIN
1912                 if (packet_ptr -> nx_packet_next)
1913                 {
1914 
1915                     /* Chained packet is not supported. */
1916                     nx_packet_release(packet_ptr);
1917                     break;
1918                 }
1919 #endif /* NX_DISABLE_PACKET_CHAIN */
1920 
1921                 /* We will use an offset to mark the beginning of each telnet option, if there is more
1922                 than one, in the packet payload. */
1923                 offset = 0;
1924 
1925                 /* Validate the packet length.  */
1926                 if (packet_ptr -> nx_packet_length == 1)
1927                 {
1928                     nx_packet_release(packet_ptr);
1929                     break;
1930                 }
1931 
1932                 /* Set the work pointer to just past the telnet IAC tag. */
1933                 data_char = *(packet_ptr -> nx_packet_prepend_ptr + 1);
1934 
1935                 /* Verify the next byte is a valid Telnet option code. */
1936                 if ((data_char >= NX_TELNET_WILL) && (data_char <= NX_TELNET_DONT))
1937                 {
1938 
1939                     /* Process the entire packet for telnet options, ensuring we don't go off the end of the payload. */
1940                     while((offset < packet_ptr -> nx_packet_length) && (*(packet_ptr -> nx_packet_prepend_ptr + offset) == NX_TELNET_IAC))
1941                     {
1942 
1943                         /* Process this telnet option. The offset will be updated to the location
1944                         of the next option (if there is one) on return of this function. */
1945                         _nx_telnet_server_process_option(server_ptr, packet_ptr, &offset, client_req_ptr);
1946                     }
1947                 }
1948 
1949                 /* Are there any data left? */
1950                 if ((offset < packet_ptr -> nx_packet_length) && (server_ptr -> nx_telnet_receive_data))
1951                 {
1952 
1953                     /* Yes. Adjust packet. */
1954                     packet_ptr -> nx_packet_prepend_ptr += offset;
1955                     packet_ptr -> nx_packet_length -= offset;
1956 
1957                     /* Yes, there is a process data callback routine - call it!  */
1958                     (server_ptr -> nx_telnet_receive_data)(server_ptr, client_req_ptr -> nx_telnet_client_request_connection, packet_ptr);
1959                 }
1960                 else
1961                 {
1962 
1963                     /* We're done with this packet. */
1964                     nx_packet_release(packet_ptr);
1965                 }
1966 
1967                 /* Check if the echo negotiation is successful.  */
1968                 if((client_req_ptr -> nx_telnet_client_agree_server_will_SGA_success == NX_TRUE) &&
1969                     (client_req_ptr -> nx_telnet_client_agree_server_will_echo_success == NX_TRUE))
1970                 {
1971 
1972                     /* Enable remote echo. */
1973                     if(server_ptr -> nx_telnet_set_echo)
1974                         server_ptr -> nx_telnet_set_echo(server_ptr, client_req_ptr -> nx_telnet_client_request_connection, NX_TRUE);
1975                 }
1976             }
1977 
1978             /* It's not an option packet.  */
1979             else
1980             {
1981 
1982                 /* Check server receive callback.  */
1983                 if (server_ptr -> nx_telnet_receive_data)
1984                 {
1985 
1986                     /* Yes, there is a process data callback routine - call it!  */
1987                     (server_ptr -> nx_telnet_receive_data)(server_ptr, client_req_ptr -> nx_telnet_client_request_connection, packet_ptr);
1988                 }
1989                 else
1990                 {
1991 
1992                     /* Error, no application callback routine.  */
1993 
1994                     /* Release the packet and continue the loop.  */
1995                     nx_packet_release(packet_ptr);
1996                 }
1997             }
1998 #else
1999            if (*packet_ptr -> nx_packet_prepend_ptr == NX_TELNET_IAC)
2000            {
2001                 nx_packet_release(packet_ptr);
2002            }
2003            /* Call the server receive callback.  */
2004            else if (server_ptr -> nx_telnet_receive_data)
2005            {
2006 
2007                /* Yes, there is a process data callback routine - call it!  */
2008                (server_ptr -> nx_telnet_receive_data)(server_ptr, client_req_ptr -> nx_telnet_client_request_connection, packet_ptr);
2009            }
2010            else
2011            {
2012 
2013                /* Error, no application callback routine.  */
2014 
2015                /* Release the packet and continue the loop.  */
2016                nx_packet_release(packet_ptr);
2017            }
2018 
2019 #endif /* NX_TELNET_SERVER_OPTION_DISABLE */
2020         }
2021     }
2022 }
2023 
2024 
2025 /**************************************************************************/
2026 /*                                                                        */
2027 /*  FUNCTION                                               RELEASE        */
2028 /*                                                                        */
2029 /*    _nx_telnet_server_timeout                           PORTABLE C      */
2030 /*                                                           6.1          */
2031 /*  AUTHOR                                                                */
2032 /*                                                                        */
2033 /*    Yuxin Zhou, Microsoft Corporation                                   */
2034 /*                                                                        */
2035 /*  DESCRIPTION                                                           */
2036 /*                                                                        */
2037 /*    This function is the periodic timer for this TELNET server. Its     */
2038 /*    duty is to inform the TELNET server that it is time to check for    */
2039 /*    activity timeouts.                                                  */
2040 /*                                                                        */
2041 /*                                                                        */
2042 /*  INPUT                                                                 */
2043 /*                                                                        */
2044 /*    telnet_server_address                 TELNET server's address       */
2045 /*                                                                        */
2046 /*  OUTPUT                                                                */
2047 /*                                                                        */
2048 /*    None                                                                */
2049 /*                                                                        */
2050 /*  CALLS                                                                 */
2051 /*                                                                        */
2052 /*    tx_event_flags_set                    Set events for server thread  */
2053 /*                                                                        */
2054 /*  CALLED BY                                                             */
2055 /*                                                                        */
2056 /*    ThreadX                               ThreadX timer callback        */
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 /**************************************************************************/
_nx_telnet_server_timeout(ULONG telnet_server_address)2067 VOID  _nx_telnet_server_timeout(ULONG telnet_server_address)
2068 {
2069 
2070 NX_TELNET_SERVER   *server_ptr;
2071 
2072     /* Pickup server pointer.  */
2073     server_ptr =  (NX_TELNET_SERVER *) telnet_server_address;
2074 
2075     /* Set the data event flag.  */
2076     tx_event_flags_set(&(server_ptr -> nx_telnet_server_event_flags), NX_TELNET_SERVER_ACTIVITY_TIMEOUT, TX_OR);
2077 }
2078 
2079 
2080 /**************************************************************************/
2081 /*                                                                        */
2082 /*  FUNCTION                                               RELEASE        */
2083 /*                                                                        */
2084 /*    _nx_telnet_server_timeout_processing                PORTABLE C      */
2085 /*                                                           6.1          */
2086 /*  AUTHOR                                                                */
2087 /*                                                                        */
2088 /*    Yuxin Zhou, Microsoft Corporation                                   */
2089 /*                                                                        */
2090 /*  DESCRIPTION                                                           */
2091 /*                                                                        */
2092 /*    This function reviews all the active TELNET client connections and  */
2093 /*    looks for an activity timeout. If a connection has not had any      */
2094 /*    activity within NX_TELNET_ACTIVITY_TIMEOUT seconds, the connection  */
2095 /*    is deleted and its resources are made available to a new connection.*/
2096 /*                                                                        */
2097 /*                                                                        */
2098 /*  INPUT                                                                 */
2099 /*                                                                        */
2100 /*    server_ptr                            Pointer to TELNET server      */
2101 /*                                                                        */
2102 /*  OUTPUT                                                                */
2103 /*                                                                        */
2104 /*    None                                                                */
2105 /*                                                                        */
2106 /*  CALLS                                                                 */
2107 /*                                                                        */
2108 /*    nx_tcp_server_socket_relisten         Relisten for another connect  */
2109 /*    nx_tcp_server_socket_unaccept         Unaccept server connection    */
2110 /*    nx_tcp_socket_disconnect              Disconnect socket             */
2111 /*                                                                        */
2112 /*  CALLED BY                                                             */
2113 /*                                                                        */
2114 /*    _nx_telnet_server_thread_entry        TELNET server thread          */
2115 /*                                                                        */
2116 /*  RELEASE HISTORY                                                       */
2117 /*                                                                        */
2118 /*    DATE              NAME                      DESCRIPTION             */
2119 /*                                                                        */
2120 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
2121 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
2122 /*                                            resulting in version 6.1    */
2123 /*                                                                        */
2124 /**************************************************************************/
_nx_telnet_server_timeout_processing(NX_TELNET_SERVER * server_ptr)2125 VOID  _nx_telnet_server_timeout_processing(NX_TELNET_SERVER *server_ptr)
2126 {
2127 
2128 UINT                        i;
2129 NX_TELNET_CLIENT_REQUEST   *client_req_ptr;
2130 
2131 
2132     /* Now look through all the sockets.  */
2133     for (i = 0; i < NX_TELNET_MAX_CLIENTS; i++)
2134     {
2135 
2136         /* Set a pointer to client request structure.  */
2137         client_req_ptr =  &(server_ptr -> nx_telnet_server_client_list[i]);
2138 
2139         /* Now see if this socket has an activity timeout active.  */
2140         if (client_req_ptr -> nx_telnet_client_request_activity_timeout)
2141         {
2142 
2143             /* Decrement the activity timeout for this client request.  */
2144             if (client_req_ptr -> nx_telnet_client_request_activity_timeout > NX_TELNET_TIMEOUT_PERIOD)
2145                 client_req_ptr -> nx_telnet_client_request_activity_timeout =  client_req_ptr -> nx_telnet_client_request_activity_timeout - NX_TELNET_TIMEOUT_PERIOD;
2146             else
2147                 client_req_ptr -> nx_telnet_client_request_activity_timeout =  0;
2148 
2149             /* Determine if this entry has exceeded the activity timeout.  */
2150             if (client_req_ptr -> nx_telnet_client_request_activity_timeout == 0)
2151             {
2152 
2153                 /* Yes, the activity timeout has been exceeded.  Tear down and clean up the
2154                    entire client request structure.  */
2155 
2156                 /* Increment the activity timeout counter.  */
2157                 server_ptr -> nx_telnet_server_activity_timeouts++;
2158 
2159                 /* Now disconnect the command socket.  */
2160                 nx_tcp_socket_disconnect(&(client_req_ptr -> nx_telnet_client_request_socket), NX_NO_WAIT);
2161 
2162                 /* Unaccept the server socket.  */
2163                 nx_tcp_server_socket_unaccept(&(client_req_ptr -> nx_telnet_client_request_socket));
2164 
2165                 /* Relisten on this socket. This will probably fail, but it is needed just in case all available
2166                    clients were in use at the time of the last relisten.  */
2167                 nx_tcp_server_socket_relisten(server_ptr -> nx_telnet_server_ip_ptr, NX_TELNET_SERVER_PORT,
2168                                                     &(client_req_ptr -> nx_telnet_client_request_socket));
2169 
2170                 /* Update number of current open connections. */
2171                 if (server_ptr -> nx_telnet_server_open_connections > 0)
2172                     server_ptr -> nx_telnet_server_open_connections--;
2173 
2174                 /* Call the application's end connection callback routine.  */
2175                 if (server_ptr -> nx_telnet_connection_end)
2176                 {
2177 
2178                     /* Yes, there is a connection end callback routine - call it!  */
2179                     (server_ptr -> nx_telnet_connection_end)(server_ptr, client_req_ptr -> nx_telnet_client_request_connection);
2180                 }
2181             }
2182         }
2183     }
2184 }
2185 
2186 #ifndef NX_TELNET_SERVER_OPTION_DISABLE
2187 
2188 #ifdef NX_TELNET_SERVER_USER_CREATE_PACKET_POOL
2189 /**************************************************************************/
2190 /*                                                                        */
2191 /*  FUNCTION                                               RELEASE        */
2192 /*                                                                        */
2193 /*    _nxe_telnet_server_packet_pool_set                  PORTABLE C      */
2194 /*                                                           6.1          */
2195 /*  AUTHOR                                                                */
2196 /*                                                                        */
2197 /*    Yuxin Zhou, Microsoft Corporation                                   */
2198 /*                                                                        */
2199 /*  DESCRIPTION                                                           */
2200 /*                                                                        */
2201 /*    This function checks for errors in the TELNET server create packet  */
2202 /*    pool call.                                                          */
2203 /*                                                                        */
2204 /*                                                                        */
2205 /*  INPUT                                                                 */
2206 /*                                                                        */
2207 /*    server_ptr                            Pointer to TELNET server      */
2208 /*    pool_ptr                              Pointer to telnet packet pool */
2209 /*                                                                        */
2210 /*  OUTPUT                                                                */
2211 /*                                                                        */
2212 /*    status                                Completion status             */
2213 /*    NX_PTR_ERROR                          Invalid pointer input         */
2214 /*                                                                        */
2215 /*  CALLS                                                                 */
2216 /*                                                                        */
2217 /*    _nx_telnet_server_packet_pool_set     Actual set packet pool call   */
2218 /*                                                                        */
2219 /*  CALLED BY                                                             */
2220 /*                                                                        */
2221 /*    Application Code                                                    */
2222 /*                                                                        */
2223 /*  RELEASE HISTORY                                                       */
2224 /*                                                                        */
2225 /*    DATE              NAME                      DESCRIPTION             */
2226 /*                                                                        */
2227 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
2228 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
2229 /*                                            resulting in version 6.1    */
2230 /*                                                                        */
2231 /**************************************************************************/
2232 
_nxe_telnet_server_packet_pool_set(NX_TELNET_SERVER * server_ptr,NX_PACKET_POOL * pool_ptr)2233 UINT _nxe_telnet_server_packet_pool_set(NX_TELNET_SERVER *server_ptr, NX_PACKET_POOL *pool_ptr)
2234 {
2235 
2236 UINT status;
2237 
2238     /* Check for invalid pointer input. */
2239     if ((server_ptr == NX_NULL) || (pool_ptr == NX_NULL))
2240     {
2241         return NX_PTR_ERROR;
2242     }
2243 
2244     /* Actual set packet pool service. */
2245     status = _nx_telnet_server_packet_pool_set(server_ptr, pool_ptr);
2246 
2247     return status;
2248 }
2249 
2250 /**************************************************************************/
2251 /*                                                                        */
2252 /*  FUNCTION                                               RELEASE        */
2253 /*                                                                        */
2254 /*    _nxe_telnet_server_packet_pool_set                  PORTABLE C      */
2255 /*                                                           6.1          */
2256 /*  AUTHOR                                                                */
2257 /*                                                                        */
2258 /*    Yuxin Zhou, Microsoft Corporation                                   */
2259 /*                                                                        */
2260 /*  DESCRIPTION                                                           */
2261 /*                                                                        */
2262 /*    This function sets the Telnet Server packet pool to the packet pool */
2263 /*    created outside the Telnet Server domain. This permits the packet   */
2264 /*    pool memory to be in a different location from the Telnet Server.   */
2265 /*                                                                        */
2266 /*    The Telnet Server only uses this packet pool for sending Telnet     */
2267 /*    options (requires NX_TELNET_SERVER_OPTION_DISABLE not be defined).  */
2268 /*                                                                        */
2269 /*    Note: This will overwrite an existing Telnet Server packet pool if  */
2270 /*    one was previously set.                                             */
2271 /*                                                                        */
2272 /*  INPUT                                                                 */
2273 /*                                                                        */
2274 /*    server_ptr                            Pointer to TELNET server      */
2275 /*    pool_ptr                              Pointer to telnet packet pool */
2276 /*                                                                        */
2277 /*  OUTPUT                                                                */
2278 /*                                                                        */
2279 /*    NX_SUCCESS                            Telnet server packet pool     */
2280 /*                                            successfully set            */
2281 /*                                                                        */
2282 /*  CALLS                                                                 */
2283 /*                                                                        */
2284 /*    None                                                                */
2285 /*                                                                        */
2286 /*  CALLED BY                                                             */
2287 /*                                                                        */
2288 /*    Application Code                                                    */
2289 /*                                                                        */
2290 /*  RELEASE HISTORY                                                       */
2291 /*                                                                        */
2292 /*    DATE              NAME                      DESCRIPTION             */
2293 /*                                                                        */
2294 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
2295 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
2296 /*                                            resulting in version 6.1    */
2297 /*                                                                        */
2298 /**************************************************************************/
_nx_telnet_server_packet_pool_set(NX_TELNET_SERVER * server_ptr,NX_PACKET_POOL * pool_ptr)2299 UINT _nx_telnet_server_packet_pool_set(NX_TELNET_SERVER *server_ptr, NX_PACKET_POOL *pool_ptr)
2300 {
2301 
2302 
2303     server_ptr -> nx_telnet_server_packet_pool_ptr = pool_ptr;
2304 
2305     return NX_SUCCESS;
2306 }
2307 
2308 #endif /* NX_TELNET_SERVER_USER_CREATE_PACKET_POOL */
2309 /**************************************************************************/
2310 /*                                                                        */
2311 /*  FUNCTION                                               RELEASE        */
2312 /*                                                                        */
2313 /*    _nx_telnet_server_create_option_packet              PORTABLE C      */
2314 /*                                                           6.1          */
2315 /*  AUTHOR                                                                */
2316 /*                                                                        */
2317 /*    Yuxin Zhou, Microsoft Corporation                                   */
2318 /*                                                                        */
2319 /*  DESCRIPTION                                                           */
2320 /*                                                                        */
2321 /*   This function creates option packet for specified type and id.       */
2322 /*                                                                        */
2323 /*  INPUT                                                                 */
2324 /*                                                                        */
2325 /*    option_message_type                   Option type                   */
2326 /*    option_id                             Option_id                     */
2327 /*    stream                                Output buffer                 */
2328 /*                                                                        */
2329 /*  OUTPUT                                                                */
2330 /*                                                                        */
2331 /*    None                                                                */
2332 /*                                                                        */
2333 /*  CALLS                                                                 */
2334 /*                                                                        */
2335 /*    None                                                                */
2336 /*                                                                        */
2337 /*  CALLED BY                                                             */
2338 /*                                                                        */
2339 /*    _nx_telnet_server_send_option_requests       Send telnet option     */
2340 /*                                                                        */
2341 /*  RELEASE HISTORY                                                       */
2342 /*                                                                        */
2343 /*    DATE              NAME                      DESCRIPTION             */
2344 /*                                                                        */
2345 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
2346 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
2347 /*                                            resulting in version 6.1    */
2348 /*                                                                        */
2349 /**************************************************************************/
_nx_telnet_server_create_option_packet(UCHAR option_message_type,UCHAR option_id,UCHAR * stream)2350 VOID _nx_telnet_server_create_option_packet(UCHAR option_message_type, UCHAR option_id, UCHAR *stream)
2351 {
2352 
2353     *(stream++) = NX_TELNET_IAC;
2354     *(stream++) = option_message_type;
2355     *stream = option_id;
2356 }
2357 
2358 /**************************************************************************/
2359 /*                                                                        */
2360 /*  FUNCTION                                               RELEASE        */
2361 /*                                                                        */
2362 /*    _nx_telnet_server_send_option_requests              PORTABLE C      */
2363 /*                                                           6.1          */
2364 /*  AUTHOR                                                                */
2365 /*                                                                        */
2366 /*    Yuxin Zhou, Microsoft Corporation                                   */
2367 /*                                                                        */
2368 /*  DESCRIPTION                                                           */
2369 /*                                                                        */
2370 /*   This function is called if 1) the server is configured to send out   */
2371 /*   options without waiting to receive client option requests, or 2)after*/
2372 /*   receiving a client's initial option requests.  This will send out    */
2373 /*   those option requests the server did not receive from the client     */
2374 /*   based on the server session option list.                             */
2375 /*                                                                        */
2376 /*   This function obtains mutex protection on the client session record  */
2377 /*   to update the record with options sent out from the server.          */
2378 /*                                                                        */
2379 /*  INPUT                                                                 */
2380 /*                                                                        */
2381 /*    server_ptr                           Pointer to telnet server       */
2382 /*    client_req_ptr                       Pointer to client record       */
2383 /*                                                                        */
2384 /*  OUTPUT                                                                */
2385 /*                                                                        */
2386 /*    status                               Completion status              */
2387 /*                                                                        */
2388 /*  CALLS                                                                 */
2389 /*                                                                        */
2390 /*    nx_packet_allocate                   Allocate packet from pool      */
2391 /*    nx_packet_release                    Release packet back to pool    */
2392 /*    nx_packet_data_append                Append data to packet payload  */
2393 /*    _nx_telnet_server_create_option_packet                              */
2394 /*                                         Create telnet option message   */
2395 /*   _nx_telnet_server_packet_send         Send telnet option to client   */
2396 /*                                                                        */
2397 /*  CALLED BY                                                             */
2398 /*                                                                        */
2399 /*    _nx_telnet_server_data_process       Top level telnet packet handler*/
2400 /*    _nx_telnet_server_connect_process    Telnet connection handler      */
2401 /*                                                                        */
2402 /*  RELEASE HISTORY                                                       */
2403 /*                                                                        */
2404 /*    DATE              NAME                      DESCRIPTION             */
2405 /*                                                                        */
2406 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
2407 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
2408 /*                                            resulting in version 6.1    */
2409 /*                                                                        */
2410 /**************************************************************************/
_nx_telnet_server_send_option_requests(NX_TELNET_SERVER * server_ptr,NX_TELNET_CLIENT_REQUEST * client_req_ptr)2411 UINT _nx_telnet_server_send_option_requests(NX_TELNET_SERVER *server_ptr, NX_TELNET_CLIENT_REQUEST *client_req_ptr)
2412 {
2413 UINT        status;
2414 NX_PACKET   *packet_ptr;
2415 UINT        option_length;
2416 UINT        packet_available;
2417 UCHAR       option_stream[9];
2418 
2419     status = NX_SUCCESS;
2420 
2421     /* Indicate packet not available, nor needing to be released. */
2422     packet_available = NX_FALSE;
2423 
2424     /* Allocate a packet for replies to send to this telnet client. */
2425     status =  nx_packet_allocate(server_ptr -> nx_telnet_server_packet_pool_ptr, &packet_ptr, NX_TCP_PACKET, NX_NO_WAIT);
2426 
2427     if (status != NX_SUCCESS)
2428         return status;
2429 
2430     /* Now a packet is available, and if not used should be released. */
2431     packet_available = NX_TRUE;
2432 
2433     /* Initialize option data to zero bytes. */
2434     option_length = 0;
2435 
2436     client_req_ptr -> nx_telnet_client_agree_server_will_echo_success = NX_FALSE;
2437     client_req_ptr -> nx_telnet_client_agree_server_will_SGA_success = NX_FALSE;
2438 
2439     /* Yes, create will echo request (3 bytes). */
2440     _nx_telnet_server_create_option_packet(NX_TELNET_WILL, NX_TELNET_ECHO, &option_stream[0]);
2441 
2442     /* Yes, create dont echo request (3 bytes). */
2443     _nx_telnet_server_create_option_packet(NX_TELNET_DONT, NX_TELNET_ECHO, &option_stream[3]);
2444 
2445     /* Yes, create will SGA request (3 bytes). */
2446     _nx_telnet_server_create_option_packet(NX_TELNET_WILL, NX_TELNET_SGA, &option_stream[6]);
2447 
2448     /* Update the the packet payload for number of bytes for a telnet option request. */
2449     option_length = 9;
2450 
2451     /* Add to the packet payload. */
2452     status = nx_packet_data_append(packet_ptr, option_stream, 9, server_ptr -> nx_telnet_server_packet_pool_ptr, NX_WAIT_FOREVER);
2453 
2454     if (status)
2455     {
2456         nx_packet_release(packet_ptr);
2457         return(status);
2458     }
2459 
2460     /* Check if we have a packet started, but not sent yet.  */
2461     if (option_length > 0)
2462     {
2463 
2464         /* Send the telnet packet out to the client. */
2465         status =  _nx_telnet_server_packet_send(server_ptr, client_req_ptr -> nx_telnet_client_request_connection, packet_ptr, 100);
2466 
2467         /* If errors sending, we need to release the packet. */
2468         if (status != NX_SUCCESS)
2469         {
2470             nx_packet_release(packet_ptr);
2471             return status;
2472         }
2473 
2474         /* Indicate we need another packet, just sent out the last one. */
2475         packet_available = NX_FALSE;
2476     }
2477 
2478     /* Check for unused packet (needs to be released). */
2479     if (packet_available == NX_TRUE)
2480     {
2481 
2482         /* Release the packet we did not use. */
2483         nx_packet_release(packet_ptr);
2484     }
2485     return status;
2486 }
2487 
2488 /**************************************************************************/
2489 /*                                                                        */
2490 /*  FUNCTION                                               RELEASE        */
2491 /*                                                                        */
2492 /*    _nx_telnet_server_process_option                    PORTABLE C      */
2493 /*                                                           6.1          */
2494 /*  AUTHOR                                                                */
2495 /*                                                                        */
2496 /*    Yuxin Zhou, Microsoft Corporation                                   */
2497 /*                                                                        */
2498 /*  DESCRIPTION                                                           */
2499 /*                                                                        */
2500 /*    This function examines the telnet option in the current packet and  */
2501 /*    determines if it is a new client request, an option with            */
2502 /*    subnegotiation data for the server, or a response to a previously   */
2503 /*    sent server telnet option request to the client. It then forwards   */
2504 /*    the telnet option information to the appropriate telnet processor.  */
2505 /*                                                                        */
2506 /*                                                                        */
2507 /*  INPUT                                                                 */
2508 /*                                                                        */
2509 /*    server_ptr                            Pointer to TELNET server      */
2510 /*    packet_ptr                            Packet with telnet option     */
2511 /*    offset                                Option offset in packet       */
2512 /*    client_req_ptr                        Telnet client sending packet  */
2513 /*                                                                        */
2514 /*  OUTPUT                                                                */
2515 /*                                                                        */
2516 /*    NX_TELNET_SESSION_OPTIONS_FULL        Session option list is fill   */
2517 /*    NX_SUCCESS                            Option successfully processed */
2518 /*                                                                        */
2519 /*  CALLS                                                                 */
2520 /*    _nx_telnet_server_update_server_session_attributes                  */
2521 /*                                          Updates server telnet features*/
2522 /*    _nx_telnet_server_update_client_session_attributes                  */
2523 /*                                          Updates client telnet features*/
2524 /*    _nx_telnet_server_process_new_option  Add new option to session list*/
2525 /*    _nx_telnet_server_respond_to_pending_option                         */
2526 /*                                          Send server reply to option   */
2527 /*    _nx_telnet_server_process_subnegotiation_data                       */
2528 /*                                          Process received option specs */
2529 /*    _nx_telnet_server_validate_option_change                            */
2530 /*                                          Determine if option is dupe   */
2531 /*                                          Process received option specs */
2532 /*  CALLED BY                                                             */
2533 /*                                                                        */
2534 /*    _nx_telnet_server_data_process        Top level incoming telnet     */
2535 /*                                             packet handler             */
2536 /*                                                                        */
2537 /*  RELEASE HISTORY                                                       */
2538 /*                                                                        */
2539 /*    DATE              NAME                      DESCRIPTION             */
2540 /*                                                                        */
2541 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
2542 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
2543 /*                                            resulting in version 6.1    */
2544 /*                                                                        */
2545 /**************************************************************************/
2546 
_nx_telnet_server_process_option(NX_TELNET_SERVER * server_ptr,NX_PACKET * packet_ptr,UINT * offset,NX_TELNET_CLIENT_REQUEST * client_req_ptr)2547 VOID _nx_telnet_server_process_option(NX_TELNET_SERVER *server_ptr, NX_PACKET *packet_ptr, UINT *offset,
2548                                       NX_TELNET_CLIENT_REQUEST *client_req_ptr)
2549 {
2550 UCHAR   data_char;
2551 UCHAR   *work_ptr;
2552 
2553     NX_PARAMETER_NOT_USED(server_ptr);
2554 
2555     /* Set the work pointer to see what option received.  */
2556     work_ptr = (UCHAR *)(packet_ptr -> nx_packet_prepend_ptr + (*offset) + 2);
2557 
2558     /* This option isn't complete, just move to the end of the packet.  */
2559     if (work_ptr >= packet_ptr -> nx_packet_append_ptr)
2560     {
2561         *offset = packet_ptr -> nx_packet_length;
2562         return;
2563     }
2564 
2565     data_char = *work_ptr;
2566 
2567     /* If it is a echo option.  */
2568     if(data_char == NX_TELNET_ECHO)
2569     {
2570 
2571         /* Check whether the client replies with echo negotiation of the local echo disabled.  */
2572         work_ptr--;
2573         data_char = *work_ptr;
2574         if(data_char == NX_TELNET_DO)
2575         {
2576 
2577             /* Server will echo what received from the telnet connection.  */
2578             client_req_ptr -> nx_telnet_client_agree_server_will_echo_success = NX_TRUE;
2579 
2580             /* Move the offset to past the option.  */
2581             (*offset)+=3;
2582         }
2583         else
2584         {
2585 
2586             /* Move the offset to past the option.  */
2587             (*offset)+=3;
2588         }
2589     }
2590 
2591     /* If it is a SGA option.  */
2592     else if(data_char == NX_TELNET_SGA)
2593     {
2594 
2595         /* Check whether the client replies with SGA negotiation.  */
2596         work_ptr--;
2597         data_char = *work_ptr;
2598         if(data_char == NX_TELNET_DO)
2599         {
2600 
2601             /* Server will enable SGA option.  */
2602             client_req_ptr -> nx_telnet_client_agree_server_will_SGA_success = NX_TRUE;
2603 
2604             /* Move the offset to past the option.  */
2605             (*offset)+=3;
2606         }
2607         else
2608         {
2609             /* Move the offset to past the option.  */
2610             (*offset)+=3;
2611             return;
2612         }
2613     }
2614 
2615     /* We have not implemented this option, just return.  */
2616     else
2617     {
2618 
2619         /* See next three bytes.  */
2620         (*offset)+=3;
2621         return;
2622     }
2623 }
2624 #endif /* NX_TELNET_SERVER_OPTION_DISABLE */
2625