1 /***************************************************************************
2  * Copyright (c) 2024 Microsoft Corporation
3  *
4  * This program and the accompanying materials are made available under the
5  * terms of the MIT License which is available at
6  * https://opensource.org/licenses/MIT.
7  *
8  * SPDX-License-Identifier: MIT
9  **************************************************************************/
10 
11 
12 /**************************************************************************/
13 /**************************************************************************/
14 /**                                                                       */
15 /** NetX Component                                                        */
16 /**                                                                       */
17 /**   TELNET Server Protocol (TELNET Server)                              */
18 /**                                                                       */
19 /**************************************************************************/
20 /**************************************************************************/
21 
22 
23 /**************************************************************************/
24 /*                                                                        */
25 /*  APPLICATION INTERFACE DEFINITION                       RELEASE        */
26 /*                                                                        */
27 /*    nxd_telnet_server.h                                  PORTABLE C     */
28 /*                                                           6.1.9        */
29 /*  AUTHOR                                                                */
30 /*                                                                        */
31 /*    Yuxin Zhou, Microsoft Corporation                                   */
32 /*                                                                        */
33 /*  DESCRIPTION                                                           */
34 /*                                                                        */
35 /*    This file defines the NetX Duo TELNET Protocol (TELNET) component,  */
36 /*    including all data types and external references.                   */
37 /*    It is assumed that nx_api.h and nx_port.h have already been         */
38 /*    included.                                                           */
39 /*                                                                        */
40 /*  RELEASE HISTORY                                                       */
41 /*                                                                        */
42 /*    DATE              NAME                      DESCRIPTION             */
43 /*                                                                        */
44 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
45 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
46 /*                                            resulting in version 6.1    */
47 /*  10-15-2021     Yuxin Zhou               Modified comment(s), included */
48 /*                                            necessary header file,      */
49 /*                                            resulting in version 6.1.9  */
50 /*                                                                        */
51 /**************************************************************************/
52 
53 #ifndef NXD_TELNET_SERVER_H
54 #define NXD_TELNET_SERVER_H
55 
56 /* Determine if a C++ compiler is being used.  If so, ensure that standard
57    C is used to process the API information.  */
58 
59 #ifdef   __cplusplus
60 
61 /* Yes, C++ compiler is present.  Use standard C.  */
62 extern   "C" {
63 
64 #endif
65 
66 #include "nx_api.h"
67 
68 /* Define the Server TELNET ID.  */
69 
70 #define NX_TELNET_SERVER_ID                 0x54454C4EUL
71 
72 /* Defined, option negotiation is disabled.
73 #define NX_TELNET_SERVER_OPTION_DISABLE
74 */
75 
76 
77 #ifndef NX_TELNET_SERVER_OPTION_DISABLE
78 
79 /* If NX_TELNET_SERVER_OPTION_DISABLE is not defined, and Telnet Server
80    needs a packet pool, this option lets the application create the packet
81    pool instead of the Telnet Server.
82 #define NX_TELNET_SERVER_USER_CREATE_PACKET_POOL
83 */
84 
85 #endif /* NX_TELNET_SERVER_OPTION_DISABLE */
86 
87 /* Define the maximum number of clients the TELNET Server can accommodate.  */
88 
89 #ifndef NX_TELNET_MAX_CLIENTS
90 #define NX_TELNET_MAX_CLIENTS               4
91 #endif
92 
93 
94 /* Define TELNET TCP socket create options.  */
95 
96 #ifndef NX_TELNET_TOS
97 #define NX_TELNET_TOS                       NX_IP_NORMAL
98 #endif
99 
100 #ifndef NX_TELNET_FRAGMENT_OPTION
101 #define NX_TELNET_FRAGMENT_OPTION           NX_DONT_FRAGMENT
102 #endif
103 
104 #ifndef NX_TELNET_SERVER_WINDOW_SIZE
105 #define NX_TELNET_SERVER_WINDOW_SIZE        2048
106 #endif
107 
108 #ifndef NX_TELNET_TIME_TO_LIVE
109 #define NX_TELNET_TIME_TO_LIVE              0x80
110 #endif
111 
112 #ifndef NX_TELNET_SERVER_TIMEOUT
113 #define NX_TELNET_SERVER_TIMEOUT            (10 * NX_IP_PERIODIC_RATE)
114 #endif
115 
116 #ifndef NX_TELNET_SERVER_PRIORITY
117 #define NX_TELNET_SERVER_PRIORITY           16
118 #endif
119 
120 #ifndef NX_TELNET_ACTIVITY_TIMEOUT
121 #define NX_TELNET_ACTIVITY_TIMEOUT          600         /* Seconds allowed with no activity                     */
122 #endif
123 
124 #ifndef NX_TELNET_TIMEOUT_PERIOD
125 #define NX_TELNET_TIMEOUT_PERIOD            60          /* Number of seconds to check                           */
126 #endif
127 
128 
129 /* Define TELNET commands that are optionally included in the TELNET data.  The application is responsible for
130    recognizing and responding to the commands in accordance with the specification.  The TELNET option command
131    requires three bytes, as follows:
132 
133         IAC, COMMAND, OPTION ID
134 
135 */
136 
137 /* Define byte indicating TELNET command follows.  */
138 
139 #define NX_TELNET_IAC                       255         /* TELNET Command byte - two consecutive -> 255 data    */
140 
141 /* Define TELNET Negotiation Commands - Immediately follows IAC.  */
142 
143 #define NX_TELNET_WILL                      251         /* TELNET WILL - Sender wants to enable the option      */
144 #define NX_TELNET_WONT                      252         /* TELNET WONT - Sender wants to disable the option     */
145 #define NX_TELNET_DO                        253         /* TELNET DO -   Sender wants receiver to enable option */
146 #define NX_TELNET_DONT                      254         /* TELNET DONT - Sender wants receiver to disable option*/
147 
148 
149 /* Define the Telnet Server packet payload. */
150 
151 #ifndef NX_TELNET_SERVER_PACKET_PAYLOAD
152 #define NX_TELNET_SERVER_PACKET_PAYLOAD     300
153 #endif
154 
155 /* Define the size of the Telnet Server packet pool. This will allow room for about
156     5-6 packets of 300 byte payload. */
157 
158 #ifndef NX_TELNET_SERVER_PACKET_POOL_SIZE
159 #define NX_TELNET_SERVER_PACKET_POOL_SIZE   2048
160 #endif
161 
162 
163 #ifndef NX_TELNET_SERVER_OPTION_DISABLE
164 
165 /* Define TELNET Option IDs.  */
166 #define NX_TELNET_ECHO                      1           /* TELNET ECHO Option                                   */
167 #define NX_TELNET_SGA                       3           /* TELNET SGA Option                                    */
168 #endif /* NX_TELNET_SERVER_OPTION_DISABLE */
169 
170 /* Define Server thread events.  */
171 
172 #define NX_TELNET_SERVER_CONNECT            0x01        /* TELNET connection is present                         */
173 #define NX_TELNET_SERVER_DISCONNECT         0x02        /* TELNET disconnection is present                      */
174 #define NX_TELNET_SERVER_DATA               0x04        /* TELNET receive data is present                       */
175 #define NX_TELNET_SERVER_ACTIVITY_TIMEOUT   0x08        /* TELNET activity timeout check                        */
176 #define NX_TELNET_STOP_EVENT                0x10        /* TELNET stop service                                  */
177 #define NX_TELNET_ANY_EVENT                 0xFF        /* Any TELNET event                                     */
178 
179 
180 /* Define return code constants.  */
181 
182 #define NX_TELNET_ERROR                     0xF0        /* TELNET internal error                                */
183 #define NX_TELNET_TIMEOUT                   0xF1        /* TELNET timeout occurred                              */
184 #define NX_TELNET_FAILED                    0xF2        /* TELNET error                                         */
185 #define NX_TELNET_NOT_CONNECTED             0xF3        /* TELNET not connected error                           */
186 #define NX_TELNET_NOT_DISCONNECTED          0xF4        /* TELNET not disconnected error                        */
187 #define NX_TELNET_INVALID_PARAMETER         0xF5        /* Invalid non pointer input to Telnet function         */
188 #define NX_TELNET_NO_PACKET_POOL            0xF6        /* Telnet server packet pool not set                    */
189 
190 /* Define the TELNET Server TCP port numbers.  */
191 
192 #ifndef NX_TELNET_SERVER_PORT
193 #define NX_TELNET_SERVER_PORT               23          /* Default Port for TELNET server                       */
194 #endif
195 
196 
197 /* Define the per client request structure for the TELNET Server data structure.  */
198 
199 typedef struct NX_TELNET_CLIENT_REQUEST_STRUCT
200 {
201     UINT            nx_telnet_client_request_connection;                /* Logical connection number            */
202     ULONG           nx_telnet_client_request_activity_timeout;          /* Timeout for client activity          */
203     ULONG           nx_telnet_client_request_total_bytes;               /* Total bytes read or written          */
204     NX_TCP_SOCKET   nx_telnet_client_request_socket;                    /* Client request socket                */
205 #ifndef NX_TELNET_SERVER_OPTION_DISABLE
206     USHORT          nx_telnet_client_agree_server_will_echo_success;    /* True if server will echo negotiation success      */
207     USHORT          nx_telnet_client_agree_server_will_SGA_success;     /* True if server will SGA negotiation success      */
208 #endif /* NX_TELNET_SERVER_OPTION_DISABLE */
209 
210 } NX_TELNET_CLIENT_REQUEST;
211 
212 
213 /* Define the TELNET Server data structure.  */
214 
215 typedef struct NX_TELNET_SERVER_STRUCT
216 {
217     ULONG           nx_telnet_server_id;                               /* TELNET Server ID                      */
218     CHAR           *nx_telnet_server_name;                             /* Name of this TELNET server            */
219     NX_IP          *nx_telnet_server_ip_ptr;                           /* Pointer to associated IP structure    */
220     ULONG           nx_telnet_server_connection_requests;              /* Number of connection requests         */
221     ULONG           nx_telnet_server_disconnection_requests;           /* Number of disconnection requests      */
222     ULONG           nx_telnet_server_total_bytes_sent;                 /* Number of total bytes sent            */
223     ULONG           nx_telnet_server_total_bytes_received;             /* Number of total bytes received        */
224     ULONG           nx_telnet_server_relisten_errors;                  /* Number of relisten errors             */
225     ULONG           nx_telnet_server_activity_timeouts;                /* Number of activity timeouts           */
226     ULONG           nx_telnet_server_open_connections;                 /* Number of currently open connections  */
227 
228 #ifndef NX_TELNET_SERVER_OPTION_DISABLE
229 #ifndef NX_TELNET_SERVER_USER_CREATE_PACKET_POOL
230     UCHAR           nx_telnet_server_pool_area[NX_TELNET_SERVER_PACKET_POOL_SIZE];
231     NX_PACKET_POOL  nx_telnet_server_packet_pool;                       /* Server TCP packet pool
232                                                                            for telnet  option messages          */
233 #endif /* NX_TELNET_SERVER_USER_CREATE_PACKET_POOL */
234     NX_PACKET_POOL *nx_telnet_server_packet_pool_ptr;                   /* Pointer to packet pool               */
235 #endif /* NX_TELNET_SERVER_OPTION_DISABLE */
236     NX_TELNET_CLIENT_REQUEST                                           /* TELNET client request array           */
237                     nx_telnet_server_client_list[NX_TELNET_MAX_CLIENTS];
238     TX_EVENT_FLAGS_GROUP
239                     nx_telnet_server_event_flags;                      /* TELNET server thread events           */
240     TX_TIMER        nx_telnet_server_timer;                            /* TELNET server activity timeout timer  */
241     TX_THREAD       nx_telnet_server_thread;                           /* TELNET server thread                  */
242     void            (*nx_telnet_new_connection)(struct NX_TELNET_SERVER_STRUCT *telnet_server_ptr, UINT logical_connection);
243     void            (*nx_telnet_receive_data)(struct NX_TELNET_SERVER_STRUCT *telnet_server_ptr, UINT logical_connection, NX_PACKET *packet_ptr);
244     void            (*nx_telnet_connection_end)(struct NX_TELNET_SERVER_STRUCT *telnet_server_ptr, UINT logical_connection);
245     void            (*nx_telnet_set_echo)(struct NX_TELNET_SERVER_STRUCT *telnet_server_ptr, UINT logical_connection, UINT echo_flag);
246 } NX_TELNET_SERVER;
247 
248 #ifndef NX_TELNET_SOURCE_CODE
249 
250 /* Application caller is present, perform API mapping.  */
251 
252 /* Determine if error checking is desired.  If so, map API functions
253    to the appropriate error checking front-ends.  Otherwise, map API
254    functions to the core functions that actually perform the work.
255    Note: error checking is enabled by default.  */
256 
257 #ifdef NX_DISABLE_ERROR_CHECKING
258 
259 /* Services without error checking.  */
260 
261 #define nx_telnet_server_create                     _nx_telnet_server_create
262 #define nx_telnet_server_delete                     _nx_telnet_server_delete
263 #define nx_telnet_server_disconnect                 _nx_telnet_server_disconnect
264 #define nx_telnet_server_packet_send                _nx_telnet_server_packet_send
265 #ifdef NX_TELNET_SERVER_USER_CREATE_PACKET_POOL
266 #define nx_telnet_server_packet_pool_set            _nx_telnet_server_packet_pool_set
267 #endif /* NX_TELNET_SERVER_USER_CREATE_PACKET_POOL */
268 #define nx_telnet_server_start                      _nx_telnet_server_start
269 #define nx_telnet_server_stop                       _nx_telnet_server_stop
270 #define nx_telnet_server_get_open_connection_count  _nx_telnet_server_get_open_connection_count
271 
272 #else
273 
274 /* Services with error checking.  */
275 
276 #define nx_telnet_server_create                     _nxe_telnet_server_create
277 #define nx_telnet_server_delete                     _nxe_telnet_server_delete
278 #define nx_telnet_server_disconnect                 _nxe_telnet_server_disconnect
279 #define nx_telnet_server_packet_send                _nxe_telnet_server_packet_send
280 #ifdef NX_TELNET_SERVER_USER_CREATE_PACKET_POOL
281 #define nx_telnet_server_packet_pool_set            _nxe_telnet_server_packet_pool_set
282 #endif /* NX_TELNET_SERVER_USER_CREATE_PACKET_POOL */
283 #define nx_telnet_server_start                      _nxe_telnet_server_start
284 #define nx_telnet_server_stop                       _nxe_telnet_server_stop
285 #define nx_telnet_server_get_open_connection_count  _nxe_telnet_server_get_open_connection_count
286 
287 #endif
288 
289 /* Define the prototypes accessible to the application software.  */
290 
291 UINT    nx_telnet_server_create(NX_TELNET_SERVER *server_ptr, CHAR *server_name, NX_IP *ip_ptr, VOID *stack_ptr, ULONG stack_size,
292             void (*new_connection)(struct NX_TELNET_SERVER_STRUCT *telnet_server_ptr, UINT logical_connection),
293             void (*receive_data)(struct NX_TELNET_SERVER_STRUCT *telnet_server_ptr, UINT logical_connection, NX_PACKET *packet_ptr),
294             void (*connection_end)(struct NX_TELNET_SERVER_STRUCT *telnet_server_ptr, UINT logical_connection));
295 UINT    nx_telnet_server_delete(NX_TELNET_SERVER *server_ptr);
296 UINT    nx_telnet_server_disconnect(NX_TELNET_SERVER *server_ptr, UINT logical_connection);
297 UINT    nx_telnet_server_packet_send(NX_TELNET_SERVER *server_ptr, UINT logical_connection, NX_PACKET *packet_ptr, ULONG wait_option);
298 #ifdef NX_TELNET_SERVER_USER_CREATE_PACKET_POOL
299 UINT    nx_telnet_server_packet_pool_set(NX_TELNET_SERVER *server_ptr, NX_PACKET_POOL *pool_ptr);
300 #endif /* NX_TELNET_SERVER_USER_CREATE_PACKET_POOL */
301 UINT    nx_telnet_server_start(NX_TELNET_SERVER *server_ptr);
302 UINT    nx_telnet_server_stop(NX_TELNET_SERVER *server_ptr);
303 UINT    nx_telnet_server_get_open_connection_count(NX_TELNET_SERVER *server_ptr, UINT *current_connections);
304 
305 
306 #else
307 
308 /* TELNET source code is being compiled, do not perform any API mapping.  */
309 
310 UINT    _nxe_telnet_server_create(NX_TELNET_SERVER *server_ptr, CHAR *server_name, NX_IP *ip_ptr, VOID *stack_ptr, ULONG stack_size,
311             void (*new_connection)(struct NX_TELNET_SERVER_STRUCT *telnet_server_ptr, UINT logical_connection),
312             void (*receive_data)(struct NX_TELNET_SERVER_STRUCT *telnet_server_ptr, UINT logical_connection, NX_PACKET *packet_ptr),
313             void (*connection_end)(struct NX_TELNET_SERVER_STRUCT *telnet_server_ptr, UINT logical_connection));
314 UINT    _nx_telnet_server_create(NX_TELNET_SERVER *server_ptr, CHAR *server_name, NX_IP *ip_ptr, VOID *stack_ptr, ULONG stack_size,
315             void (*new_connection)(struct NX_TELNET_SERVER_STRUCT *telnet_server_ptr, UINT logical_connection),
316             void (*receive_data)(struct NX_TELNET_SERVER_STRUCT *telnet_server_ptr, UINT logical_connection, NX_PACKET *packet_ptr),
317             void (*connection_end)(struct NX_TELNET_SERVER_STRUCT *telnet_server_ptr, UINT logical_connection));
318 UINT    _nxe_telnet_server_delete(NX_TELNET_SERVER *server_ptr);
319 UINT    _nx_telnet_server_delete(NX_TELNET_SERVER *server_ptr);
320 UINT    _nxe_telnet_server_disconnect(NX_TELNET_SERVER *server_ptr, UINT logical_connection);
321 UINT    _nx_telnet_server_disconnect(NX_TELNET_SERVER *server_ptr, UINT logical_connection);
322 UINT    _nxe_telnet_server_packet_send(NX_TELNET_SERVER *server_ptr, UINT logical_connection, NX_PACKET *packet_ptr, ULONG wait_option);
323 UINT    _nx_telnet_server_packet_send(NX_TELNET_SERVER *server_ptr, UINT logical_connection, NX_PACKET *packet_ptr, ULONG wait_option);
324 #ifdef NX_TELNET_SERVER_USER_CREATE_PACKET_POOL
325 UINT    _nxe_telnet_server_packet_pool_set(NX_TELNET_SERVER *server_ptr, NX_PACKET_POOL *pool_ptr);
326 UINT    _nx_telnet_server_packet_pool_set(NX_TELNET_SERVER *server_ptr, NX_PACKET_POOL *pool_ptr);
327 #endif /* NX_TELNET_SERVER_USER_CREATE_PACKET_POOL */
328 UINT    _nxe_telnet_server_start(NX_TELNET_SERVER *server_ptr);
329 UINT    _nx_telnet_server_start(NX_TELNET_SERVER *server_ptr);
330 UINT    _nxe_telnet_server_stop(NX_TELNET_SERVER *server_ptr);
331 UINT    _nx_telnet_server_stop(NX_TELNET_SERVER *server_ptr);
332 UINT    _nxe_telnet_server_get_open_connection_count(NX_TELNET_SERVER *server_ptr, UINT *current_connections);
333 UINT    _nx_telnet_server_get_open_connection_count(NX_TELNET_SERVER *server_ptr, UINT *current_connections);
334 
335 /* Define internal TELNET functions.  */
336 
337 VOID    _nx_telnet_server_thread_entry(ULONG telnet_server);
338 VOID    _nx_telnet_server_connect_process(NX_TELNET_SERVER *server_ptr);
339 VOID    _nx_telnet_server_connection_present(NX_TCP_SOCKET *socket_ptr, UINT port);
340 VOID    _nx_telnet_server_disconnect_present(NX_TCP_SOCKET *socket_ptr);
341 VOID    _nx_telnet_server_disconnect_process(NX_TELNET_SERVER *server_ptr);
342 VOID    _nx_telnet_server_data_present(NX_TCP_SOCKET *socket_ptr);
343 VOID    _nx_telnet_server_data_process(NX_TELNET_SERVER *server_ptr);
344 VOID    _nx_telnet_server_timeout(ULONG telnet_server_address);
345 VOID    _nx_telnet_server_timeout_processing(NX_TELNET_SERVER *server_ptr);
346 
347 #ifndef NX_TELNET_SERVER_OPTION_DISABLE
348 UINT    _nx_telnet_server_send_option_requests(NX_TELNET_SERVER *server_ptr, NX_TELNET_CLIENT_REQUEST *client_req_ptr);
349 VOID    _nx_telnet_server_process_option(NX_TELNET_SERVER *server_ptr, NX_PACKET *packet_ptr, UINT *offset, NX_TELNET_CLIENT_REQUEST *client_request_ptr);
350 VOID    _nx_telnet_server_create_option_packet(UCHAR option_message_type, UCHAR option_id, UCHAR *stream);
351 #endif /* NX_TELNET_SERVER_OPTION_DISABLE */
352 #endif
353 
354 /* Determine if a C++ compiler is being used.  If so, complete the standard
355    C conditional started above.  */
356 #ifdef   __cplusplus
357         }
358 #endif
359 
360 #endif  /* NXD_TELNET_SERVER_H */
361